100a1762c78ac7e0ee7131505fec24f30d1d306b
[idra/samba.git] / source3 / rpc_server / srv_samr_nt.c
1 /*
2  *  Unix SMB/CIFS implementation.
3  *  RPC Pipe client / server routines
4  *  Copyright (C) Andrew Tridgell                   1992-1997,
5  *  Copyright (C) Luke Kenneth Casson Leighton      1996-1997,
6  *  Copyright (C) Paul Ashton                       1997,
7  *  Copyright (C) Marc Jacobsen                     1999,
8  *  Copyright (C) Jeremy Allison                    2001-2008,
9  *  Copyright (C) Jean François Micouleau           1998-2001,
10  *  Copyright (C) Jim McDonough <jmcd@us.ibm.com>   2002,
11  *  Copyright (C) Gerald (Jerry) Carter             2003-2004,
12  *  Copyright (C) Simo Sorce                        2003.
13  *  Copyright (C) Volker Lendecke                   2005.
14  *  Copyright (C) Guenther Deschner                 2008.
15  *
16  *  This program is free software; you can redistribute it and/or modify
17  *  it under the terms of the GNU General Public License as published by
18  *  the Free Software Foundation; either version 3 of the License, or
19  *  (at your option) any later version.
20  *
21  *  This program is distributed in the hope that it will be useful,
22  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
23  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24  *  GNU General Public License for more details.
25  *
26  *  You should have received a copy of the GNU General Public License
27  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
28  */
29
30 /*
31  * This is the implementation of the SAMR code.
32  */
33
34 #include "includes.h"
35 #include "smbd/globals.h"
36 #include "../libcli/auth/libcli_auth.h"
37 #include "../librpc/gen_ndr/srv_samr.h"
38 #include "rpc_server/srv_samr_util.h"
39 #include "../lib/crypto/arcfour.h"
40
41 #undef DBGC_CLASS
42 #define DBGC_CLASS DBGC_RPC_SRV
43
44 #define SAMR_USR_RIGHTS_WRITE_PW \
45                 ( READ_CONTROL_ACCESS           | \
46                   SAMR_USER_ACCESS_CHANGE_PASSWORD      | \
47                   SAMR_USER_ACCESS_SET_LOC_COM)
48 #define SAMR_USR_RIGHTS_CANT_WRITE_PW \
49                 ( READ_CONTROL_ACCESS | SAMR_USER_ACCESS_SET_LOC_COM )
50
51 #define DISP_INFO_CACHE_TIMEOUT 10
52
53 #define MAX_SAM_ENTRIES_W2K 0x400 /* 1024 */
54 #define MAX_SAM_ENTRIES_W95 50
55
56 struct samr_connect_info {
57         uint8_t dummy;
58 };
59
60 struct samr_domain_info {
61         struct dom_sid sid;
62         struct disp_info *disp_info;
63 };
64
65 struct samr_user_info {
66         struct dom_sid sid;
67 };
68
69 struct samr_group_info {
70         struct dom_sid sid;
71 };
72
73 struct samr_alias_info {
74         struct dom_sid sid;
75 };
76
77 typedef struct disp_info {
78         DOM_SID sid; /* identify which domain this is. */
79         struct pdb_search *users; /* querydispinfo 1 and 4 */
80         struct pdb_search *machines; /* querydispinfo 2 */
81         struct pdb_search *groups; /* querydispinfo 3 and 5, enumgroups */
82         struct pdb_search *aliases; /* enumaliases */
83
84         uint32_t enum_acb_mask;
85         struct pdb_search *enum_users; /* enumusers with a mask */
86
87         struct timed_event *cache_timeout_event; /* cache idle timeout
88                                                   * handler. */
89 } DISP_INFO;
90
91 static const struct generic_mapping sam_generic_mapping = {
92         GENERIC_RIGHTS_SAM_READ,
93         GENERIC_RIGHTS_SAM_WRITE,
94         GENERIC_RIGHTS_SAM_EXECUTE,
95         GENERIC_RIGHTS_SAM_ALL_ACCESS};
96 static const struct generic_mapping dom_generic_mapping = {
97         GENERIC_RIGHTS_DOMAIN_READ,
98         GENERIC_RIGHTS_DOMAIN_WRITE,
99         GENERIC_RIGHTS_DOMAIN_EXECUTE,
100         GENERIC_RIGHTS_DOMAIN_ALL_ACCESS};
101 static const struct generic_mapping usr_generic_mapping = {
102         GENERIC_RIGHTS_USER_READ,
103         GENERIC_RIGHTS_USER_WRITE,
104         GENERIC_RIGHTS_USER_EXECUTE,
105         GENERIC_RIGHTS_USER_ALL_ACCESS};
106 static const struct generic_mapping usr_nopwchange_generic_mapping = {
107         GENERIC_RIGHTS_USER_READ,
108         GENERIC_RIGHTS_USER_WRITE,
109         GENERIC_RIGHTS_USER_EXECUTE & ~SAMR_USER_ACCESS_CHANGE_PASSWORD,
110         GENERIC_RIGHTS_USER_ALL_ACCESS};
111 static const struct generic_mapping grp_generic_mapping = {
112         GENERIC_RIGHTS_GROUP_READ,
113         GENERIC_RIGHTS_GROUP_WRITE,
114         GENERIC_RIGHTS_GROUP_EXECUTE,
115         GENERIC_RIGHTS_GROUP_ALL_ACCESS};
116 static const struct generic_mapping ali_generic_mapping = {
117         GENERIC_RIGHTS_ALIAS_READ,
118         GENERIC_RIGHTS_ALIAS_WRITE,
119         GENERIC_RIGHTS_ALIAS_EXECUTE,
120         GENERIC_RIGHTS_ALIAS_ALL_ACCESS};
121
122 /*******************************************************************
123 *******************************************************************/
124
125 static NTSTATUS make_samr_object_sd( TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size,
126                                      const struct generic_mapping *map,
127                                      DOM_SID *sid, uint32 sid_access )
128 {
129         DOM_SID domadmin_sid;
130         struct security_ace ace[5];             /* at most 5 entries */
131         size_t i = 0;
132
133         struct security_acl *psa = NULL;
134
135         /* basic access for Everyone */
136
137         init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
138                         map->generic_execute | map->generic_read, 0);
139
140         /* add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
141
142         init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
143                         SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
144         init_sec_ace(&ace[i++], &global_sid_Builtin_Account_Operators,
145                         SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
146
147         /* Add Full Access for Domain Admins if we are a DC */
148
149         if ( IS_DC ) {
150                 sid_compose(&domadmin_sid, get_global_sam_sid(),
151                             DOMAIN_RID_ADMINS);
152                 init_sec_ace(&ace[i++], &domadmin_sid,
153                         SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
154         }
155
156         /* if we have a sid, give it some special access */
157
158         if ( sid ) {
159                 init_sec_ace(&ace[i++], sid, SEC_ACE_TYPE_ACCESS_ALLOWED, sid_access, 0);
160         }
161
162         /* create the security descriptor */
163
164         if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) == NULL)
165                 return NT_STATUS_NO_MEMORY;
166
167         if ((*psd = make_sec_desc(ctx, SECURITY_DESCRIPTOR_REVISION_1,
168                                   SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL,
169                                   psa, sd_size)) == NULL)
170                 return NT_STATUS_NO_MEMORY;
171
172         return NT_STATUS_OK;
173 }
174
175 /*******************************************************************
176  Checks if access to an object should be granted, and returns that
177  level of access for further checks.
178 ********************************************************************/
179
180 NTSTATUS access_check_object( SEC_DESC *psd, NT_USER_TOKEN *token,
181                                           SE_PRIV *rights, uint32 rights_mask,
182                                           uint32 des_access, uint32 *acc_granted,
183                                           const char *debug )
184 {
185         NTSTATUS status = NT_STATUS_ACCESS_DENIED;
186         uint32 saved_mask = 0;
187
188         /* check privileges; certain SAM access bits should be overridden
189            by privileges (mostly having to do with creating/modifying/deleting
190            users and groups) */
191
192         if (rights && !se_priv_equal(rights, &se_priv_none) &&
193                         user_has_any_privilege(token, rights)) {
194
195                 saved_mask = (des_access & rights_mask);
196                 des_access &= ~saved_mask;
197
198                 DEBUG(4,("access_check_object: user rights access mask [0x%x]\n",
199                         rights_mask));
200         }
201
202
203         /* check the security descriptor first */
204
205         status = se_access_check(psd, token, des_access, acc_granted);
206         if (NT_STATUS_IS_OK(status)) {
207                 goto done;
208         }
209
210         /* give root a free pass */
211
212         if ( geteuid() == sec_initial_uid() ) {
213
214                 DEBUG(4,("%s: ACCESS should be DENIED  (requested: %#010x)\n", debug, des_access));
215                 DEBUGADD(4,("but overritten by euid == sec_initial_uid()\n"));
216
217                 *acc_granted = des_access;
218
219                 status = NT_STATUS_OK;
220                 goto done;
221         }
222
223
224 done:
225         /* add in any bits saved during the privilege check (only
226            matters is status is ok) */
227
228         *acc_granted |= rights_mask;
229
230         DEBUG(4,("%s: access %s (requested: 0x%08x, granted: 0x%08x)\n",
231                 debug, NT_STATUS_IS_OK(status) ? "GRANTED" : "DENIED",
232                 des_access, *acc_granted));
233
234         return status;
235 }
236
237
238 /*******************************************************************
239  Map any MAXIMUM_ALLOWED_ACCESS request to a valid access set.
240 ********************************************************************/
241
242 void map_max_allowed_access(const NT_USER_TOKEN *nt_token,
243                             const struct unix_user_token *unix_token,
244                             uint32_t *pacc_requested)
245 {
246         if (!((*pacc_requested) & MAXIMUM_ALLOWED_ACCESS)) {
247                 return;
248         }
249         *pacc_requested &= ~MAXIMUM_ALLOWED_ACCESS;
250
251         /* At least try for generic read|execute - Everyone gets that. */
252         *pacc_requested = GENERIC_READ_ACCESS|GENERIC_EXECUTE_ACCESS;
253
254         /* root gets anything. */
255         if (unix_token->uid == sec_initial_uid()) {
256                 *pacc_requested |= GENERIC_ALL_ACCESS;
257                 return;
258         }
259
260         /* Full Access for 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
261
262         if (is_sid_in_token(nt_token, &global_sid_Builtin_Administrators) ||
263                         is_sid_in_token(nt_token, &global_sid_Builtin_Account_Operators)) {
264                 *pacc_requested |= GENERIC_ALL_ACCESS;
265                 return;
266         }
267
268         /* Full access for DOMAIN\Domain Admins. */
269         if ( IS_DC ) {
270                 DOM_SID domadmin_sid;
271                 sid_compose(&domadmin_sid, get_global_sam_sid(),
272                             DOMAIN_RID_ADMINS);
273                 if (is_sid_in_token(nt_token, &domadmin_sid)) {
274                         *pacc_requested |= GENERIC_ALL_ACCESS;
275                         return;
276                 }
277         }
278         /* TODO ! Check privileges. */
279 }
280
281 /*******************************************************************
282  Fetch or create a dispinfo struct.
283 ********************************************************************/
284
285 static DISP_INFO *get_samr_dispinfo_by_sid(const struct dom_sid *psid)
286 {
287         /*
288          * We do a static cache for DISP_INFO's here. Explanation can be found
289          * in Jeremy's checkin message to r11793:
290          *
291          * Fix the SAMR cache so it works across completely insane
292          * client behaviour (ie.:
293          * open pipe/open SAMR handle/enumerate 0 - 1024
294          * close SAMR handle, close pipe.
295          * open pipe/open SAMR handle/enumerate 1024 - 2048...
296          * close SAMR handle, close pipe.
297          * And on ad-nausium. Amazing.... probably object-oriented
298          * client side programming in action yet again.
299          * This change should *massively* improve performance when
300          * enumerating users from an LDAP database.
301          * Jeremy.
302          *
303          * "Our" and the builtin domain are the only ones where we ever
304          * enumerate stuff, so just cache 2 entries.
305          */
306
307         static struct disp_info *builtin_dispinfo;
308         static struct disp_info *domain_dispinfo;
309
310         /* There are two cases to consider here:
311            1) The SID is a domain SID and we look for an equality match, or
312            2) This is an account SID and so we return the DISP_INFO* for our
313               domain */
314
315         if (psid == NULL) {
316                 return NULL;
317         }
318
319         if (sid_check_is_builtin(psid) || sid_check_is_in_builtin(psid)) {
320                 /*
321                  * Necessary only once, but it does not really hurt.
322                  */
323                 if (builtin_dispinfo == NULL) {
324                         builtin_dispinfo = talloc_zero(
325                                 talloc_autofree_context(), struct disp_info);
326                         if (builtin_dispinfo == NULL) {
327                                 return NULL;
328                         }
329                 }
330                 sid_copy(&builtin_dispinfo->sid, &global_sid_Builtin);
331
332                 return builtin_dispinfo;
333         }
334
335         if (sid_check_is_domain(psid) || sid_check_is_in_our_domain(psid)) {
336                 /*
337                  * Necessary only once, but it does not really hurt.
338                  */
339                 if (domain_dispinfo == NULL) {
340                         domain_dispinfo = talloc_zero(
341                                 talloc_autofree_context(), struct disp_info);
342                         if (domain_dispinfo == NULL) {
343                                 return NULL;
344                         }
345                 }
346                 sid_copy(&domain_dispinfo->sid, get_global_sam_sid());
347
348                 return domain_dispinfo;
349         }
350
351         return NULL;
352 }
353
354 /*******************************************************************
355  Function to free the per SID data.
356  ********************************************************************/
357
358 static void free_samr_cache(DISP_INFO *disp_info)
359 {
360         DEBUG(10, ("free_samr_cache: deleting cache for SID %s\n",
361                    sid_string_dbg(&disp_info->sid)));
362
363         /* We need to become root here because the paged search might have to
364          * tell the LDAP server we're not interested in the rest anymore. */
365
366         become_root();
367
368         TALLOC_FREE(disp_info->users);
369         TALLOC_FREE(disp_info->machines);
370         TALLOC_FREE(disp_info->groups);
371         TALLOC_FREE(disp_info->aliases);
372         TALLOC_FREE(disp_info->enum_users);
373
374         unbecome_root();
375 }
376
377 /*******************************************************************
378  Idle event handler. Throw away the disp info cache.
379  ********************************************************************/
380
381 static void disp_info_cache_idle_timeout_handler(struct event_context *ev_ctx,
382                                                  struct timed_event *te,
383                                                  struct timeval now,
384                                                  void *private_data)
385 {
386         DISP_INFO *disp_info = (DISP_INFO *)private_data;
387
388         TALLOC_FREE(disp_info->cache_timeout_event);
389
390         DEBUG(10, ("disp_info_cache_idle_timeout_handler: caching timed "
391                    "out\n"));
392         free_samr_cache(disp_info);
393 }
394
395 /*******************************************************************
396  Setup cache removal idle event handler.
397  ********************************************************************/
398
399 static void set_disp_info_cache_timeout(DISP_INFO *disp_info, time_t secs_fromnow)
400 {
401         /* Remove any pending timeout and update. */
402
403         TALLOC_FREE(disp_info->cache_timeout_event);
404
405         DEBUG(10,("set_disp_info_cache_timeout: caching enumeration for "
406                   "SID %s for %u seconds\n", sid_string_dbg(&disp_info->sid),
407                   (unsigned int)secs_fromnow ));
408
409         disp_info->cache_timeout_event = event_add_timed(
410                 smbd_event_context(), NULL,
411                 timeval_current_ofs(secs_fromnow, 0),
412                 disp_info_cache_idle_timeout_handler, (void *)disp_info);
413 }
414
415 /*******************************************************************
416  Force flush any cache. We do this on any samr_set_xxx call.
417  We must also remove the timeout handler.
418  ********************************************************************/
419
420 static void force_flush_samr_cache(const struct dom_sid *sid)
421 {
422         struct disp_info *disp_info = get_samr_dispinfo_by_sid(sid);
423
424         if ((disp_info == NULL) || (disp_info->cache_timeout_event == NULL)) {
425                 return;
426         }
427
428         DEBUG(10,("force_flush_samr_cache: clearing idle event\n"));
429         TALLOC_FREE(disp_info->cache_timeout_event);
430         free_samr_cache(disp_info);
431 }
432
433 /*******************************************************************
434  Ensure password info is never given out. Paranioa... JRA.
435  ********************************************************************/
436
437 static void samr_clear_sam_passwd(struct samu *sam_pass)
438 {
439
440         if (!sam_pass)
441                 return;
442
443         /* These now zero out the old password */
444
445         pdb_set_lanman_passwd(sam_pass, NULL, PDB_DEFAULT);
446         pdb_set_nt_passwd(sam_pass, NULL, PDB_DEFAULT);
447 }
448
449 static uint32 count_sam_users(struct disp_info *info, uint32 acct_flags)
450 {
451         struct samr_displayentry *entry;
452
453         if (sid_check_is_builtin(&info->sid)) {
454                 /* No users in builtin. */
455                 return 0;
456         }
457
458         if (info->users == NULL) {
459                 info->users = pdb_search_users(info, acct_flags);
460                 if (info->users == NULL) {
461                         return 0;
462                 }
463         }
464         /* Fetch the last possible entry, thus trigger an enumeration */
465         pdb_search_entries(info->users, 0xffffffff, 1, &entry);
466
467         /* Ensure we cache this enumeration. */
468         set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
469
470         return info->users->num_entries;
471 }
472
473 static uint32 count_sam_groups(struct disp_info *info)
474 {
475         struct samr_displayentry *entry;
476
477         if (sid_check_is_builtin(&info->sid)) {
478                 /* No groups in builtin. */
479                 return 0;
480         }
481
482         if (info->groups == NULL) {
483                 info->groups = pdb_search_groups(info);
484                 if (info->groups == NULL) {
485                         return 0;
486                 }
487         }
488         /* Fetch the last possible entry, thus trigger an enumeration */
489         pdb_search_entries(info->groups, 0xffffffff, 1, &entry);
490
491         /* Ensure we cache this enumeration. */
492         set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
493
494         return info->groups->num_entries;
495 }
496
497 static uint32 count_sam_aliases(struct disp_info *info)
498 {
499         struct samr_displayentry *entry;
500
501         if (info->aliases == NULL) {
502                 info->aliases = pdb_search_aliases(info, &info->sid);
503                 if (info->aliases == NULL) {
504                         return 0;
505                 }
506         }
507         /* Fetch the last possible entry, thus trigger an enumeration */
508         pdb_search_entries(info->aliases, 0xffffffff, 1, &entry);
509
510         /* Ensure we cache this enumeration. */
511         set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
512
513         return info->aliases->num_entries;
514 }
515
516 /*******************************************************************
517  _samr_Close
518  ********************************************************************/
519
520 NTSTATUS _samr_Close(pipes_struct *p, struct samr_Close *r)
521 {
522         if (!close_policy_hnd(p, r->in.handle)) {
523                 return NT_STATUS_INVALID_HANDLE;
524         }
525
526         ZERO_STRUCTP(r->out.handle);
527
528         return NT_STATUS_OK;
529 }
530
531 /*******************************************************************
532  _samr_OpenDomain
533  ********************************************************************/
534
535 NTSTATUS _samr_OpenDomain(pipes_struct *p,
536                           struct samr_OpenDomain *r)
537 {
538         struct samr_connect_info *cinfo;
539         struct samr_domain_info *dinfo;
540         SEC_DESC *psd = NULL;
541         uint32    acc_granted;
542         uint32    des_access = r->in.access_mask;
543         NTSTATUS  status;
544         size_t    sd_size;
545         uint32_t extra_access = SAMR_DOMAIN_ACCESS_CREATE_USER;
546         SE_PRIV se_rights;
547
548         /* find the connection policy handle. */
549
550         cinfo = policy_handle_find(p, r->in.connect_handle, 0, NULL,
551                                    struct samr_connect_info, &status);
552         if (!NT_STATUS_IS_OK(status)) {
553                 return status;
554         }
555
556         /*check if access can be granted as requested by client. */
557         map_max_allowed_access(p->server_info->ptok,
558                                &p->server_info->utok,
559                                &des_access);
560
561         make_samr_object_sd( p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0 );
562         se_map_generic( &des_access, &dom_generic_mapping );
563
564         /*
565          * Users with SeMachineAccount or SeAddUser get additional
566          * SAMR_DOMAIN_ACCESS_CREATE_USER access.
567          */
568         se_priv_copy( &se_rights, &se_machine_account );
569         se_priv_add( &se_rights, &se_add_users );
570
571         /*
572          * Users with SeAddUser get the ability to manipulate groups
573          * and aliases.
574          */
575         if (user_has_any_privilege(p->server_info->ptok, &se_add_users)) {
576                 extra_access |= (SAMR_DOMAIN_ACCESS_CREATE_GROUP |
577                                 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS |
578                                 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
579                                 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS |
580                                 SAMR_DOMAIN_ACCESS_CREATE_ALIAS);
581         }
582
583         status = access_check_object( psd, p->server_info->ptok,
584                 &se_rights, extra_access, des_access,
585                 &acc_granted, "_samr_OpenDomain" );
586
587         if ( !NT_STATUS_IS_OK(status) )
588                 return status;
589
590         if (!sid_check_is_domain(r->in.sid) &&
591             !sid_check_is_builtin(r->in.sid)) {
592                 return NT_STATUS_NO_SUCH_DOMAIN;
593         }
594
595         dinfo = policy_handle_create(p, r->out.domain_handle, acc_granted,
596                                      struct samr_domain_info, &status);
597         if (!NT_STATUS_IS_OK(status)) {
598                 return status;
599         }
600         dinfo->sid = *r->in.sid;
601         dinfo->disp_info = get_samr_dispinfo_by_sid(r->in.sid);
602
603         DEBUG(5,("_samr_OpenDomain: %d\n", __LINE__));
604
605         return NT_STATUS_OK;
606 }
607
608 /*******************************************************************
609  _samr_GetUserPwInfo
610  ********************************************************************/
611
612 NTSTATUS _samr_GetUserPwInfo(pipes_struct *p,
613                              struct samr_GetUserPwInfo *r)
614 {
615         struct samr_user_info *uinfo;
616         enum lsa_SidType sid_type;
617         uint32_t min_password_length = 0;
618         uint32_t password_properties = 0;
619         bool ret = false;
620         NTSTATUS status;
621
622         DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__));
623
624         uinfo = policy_handle_find(p, r->in.user_handle,
625                                    SAMR_USER_ACCESS_GET_ATTRIBUTES, NULL,
626                                    struct samr_user_info, &status);
627         if (!NT_STATUS_IS_OK(status)) {
628                 return status;
629         }
630
631         if (!sid_check_is_in_our_domain(&uinfo->sid)) {
632                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
633         }
634
635         become_root();
636         ret = lookup_sid(p->mem_ctx, &uinfo->sid, NULL, NULL, &sid_type);
637         unbecome_root();
638         if (ret == false) {
639                 return NT_STATUS_NO_SUCH_USER;
640         }
641
642         switch (sid_type) {
643                 case SID_NAME_USER:
644                         become_root();
645                         pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN,
646                                                &min_password_length);
647                         pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
648                                                &password_properties);
649                         unbecome_root();
650
651                         if (lp_check_password_script() && *lp_check_password_script()) {
652                                 password_properties |= DOMAIN_PASSWORD_COMPLEX;
653                         }
654
655                         break;
656                 default:
657                         break;
658         }
659
660         r->out.info->min_password_length = min_password_length;
661         r->out.info->password_properties = password_properties;
662
663         DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__));
664
665         return NT_STATUS_OK;
666 }
667
668 /*******************************************************************
669  _samr_SetSecurity
670  ********************************************************************/
671
672 NTSTATUS _samr_SetSecurity(pipes_struct *p,
673                            struct samr_SetSecurity *r)
674 {
675         struct samr_user_info *uinfo;
676         uint32 i;
677         struct security_acl *dacl;
678         bool ret;
679         struct samu *sampass=NULL;
680         NTSTATUS status;
681
682         uinfo = policy_handle_find(p, r->in.handle,
683                                    SAMR_USER_ACCESS_SET_ATTRIBUTES, NULL,
684                                    struct samr_user_info, &status);
685         if (!NT_STATUS_IS_OK(status)) {
686                 return status;
687         }
688
689         if (!(sampass = samu_new( p->mem_ctx))) {
690                 DEBUG(0,("No memory!\n"));
691                 return NT_STATUS_NO_MEMORY;
692         }
693
694         /* get the user record */
695         become_root();
696         ret = pdb_getsampwsid(sampass, &uinfo->sid);
697         unbecome_root();
698
699         if (!ret) {
700                 DEBUG(4, ("User %s not found\n",
701                           sid_string_dbg(&uinfo->sid)));
702                 TALLOC_FREE(sampass);
703                 return NT_STATUS_INVALID_HANDLE;
704         }
705
706         dacl = r->in.sdbuf->sd->dacl;
707         for (i=0; i < dacl->num_aces; i++) {
708                 if (sid_equal(&uinfo->sid, &dacl->aces[i].trustee)) {
709                         ret = pdb_set_pass_can_change(sampass,
710                                 (dacl->aces[i].access_mask &
711                                  SAMR_USER_ACCESS_CHANGE_PASSWORD) ?
712                                                       True: False);
713                         break;
714                 }
715         }
716
717         if (!ret) {
718                 TALLOC_FREE(sampass);
719                 return NT_STATUS_ACCESS_DENIED;
720         }
721
722         become_root();
723         status = pdb_update_sam_account(sampass);
724         unbecome_root();
725
726         TALLOC_FREE(sampass);
727
728         return status;
729 }
730
731 /*******************************************************************
732   build correct perms based on policies and password times for _samr_query_sec_obj
733 *******************************************************************/
734 static bool check_change_pw_access(TALLOC_CTX *mem_ctx, DOM_SID *user_sid)
735 {
736         struct samu *sampass=NULL;
737         bool ret;
738
739         if ( !(sampass = samu_new( mem_ctx )) ) {
740                 DEBUG(0,("No memory!\n"));
741                 return False;
742         }
743
744         become_root();
745         ret = pdb_getsampwsid(sampass, user_sid);
746         unbecome_root();
747
748         if (ret == False) {
749                 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
750                 TALLOC_FREE(sampass);
751                 return False;
752         }
753
754         DEBUG(3,("User:[%s]\n",  pdb_get_username(sampass) ));
755
756         if (pdb_get_pass_can_change(sampass)) {
757                 TALLOC_FREE(sampass);
758                 return True;
759         }
760         TALLOC_FREE(sampass);
761         return False;
762 }
763
764
765 /*******************************************************************
766  _samr_QuerySecurity
767  ********************************************************************/
768
769 NTSTATUS _samr_QuerySecurity(pipes_struct *p,
770                              struct samr_QuerySecurity *r)
771 {
772         struct samr_connect_info *cinfo;
773         struct samr_domain_info *dinfo;
774         struct samr_user_info *uinfo;
775         struct samr_group_info *ginfo;
776         struct samr_alias_info *ainfo;
777         NTSTATUS status;
778         SEC_DESC * psd = NULL;
779         size_t sd_size = 0;
780
781         cinfo = policy_handle_find(p, r->in.handle,
782                                    STD_RIGHT_READ_CONTROL_ACCESS, NULL,
783                                    struct samr_connect_info, &status);
784         if (NT_STATUS_IS_OK(status)) {
785                 DEBUG(5,("_samr_QuerySecurity: querying security on SAM\n"));
786                 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size,
787                                              &sam_generic_mapping, NULL, 0);
788                 goto done;
789         }
790
791         dinfo = policy_handle_find(p, r->in.handle,
792                                    STD_RIGHT_READ_CONTROL_ACCESS, NULL,
793                                    struct samr_domain_info, &status);
794         if (NT_STATUS_IS_OK(status)) {
795                 DEBUG(5,("_samr_QuerySecurity: querying security on Domain "
796                          "with SID: %s\n", sid_string_dbg(&dinfo->sid)));
797                 /*
798                  * TODO: Builtin probably needs a different SD with restricted
799                  * write access
800                  */
801                 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size,
802                                              &dom_generic_mapping, NULL, 0);
803                 goto done;
804         }
805
806         uinfo = policy_handle_find(p, r->in.handle,
807                                    STD_RIGHT_READ_CONTROL_ACCESS, NULL,
808                                    struct samr_user_info, &status);
809         if (NT_STATUS_IS_OK(status)) {
810                 DEBUG(10,("_samr_QuerySecurity: querying security on user "
811                           "Object with SID: %s\n",
812                           sid_string_dbg(&uinfo->sid)));
813                 if (check_change_pw_access(p->mem_ctx, &uinfo->sid)) {
814                         status = make_samr_object_sd(
815                                 p->mem_ctx, &psd, &sd_size,
816                                 &usr_generic_mapping,
817                                 &uinfo->sid, SAMR_USR_RIGHTS_WRITE_PW);
818                 } else {
819                         status = make_samr_object_sd(
820                                 p->mem_ctx, &psd, &sd_size,
821                                 &usr_nopwchange_generic_mapping,
822                                 &uinfo->sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
823                 }
824                 goto done;
825         }
826
827         ginfo = policy_handle_find(p, r->in.handle,
828                                    STD_RIGHT_READ_CONTROL_ACCESS, NULL,
829                                    struct samr_group_info, &status);
830         if (NT_STATUS_IS_OK(status)) {
831                 /*
832                  * TODO: different SDs have to be generated for aliases groups
833                  * and users.  Currently all three get a default user SD
834                  */
835                 DEBUG(10,("_samr_QuerySecurity: querying security on group "
836                           "Object with SID: %s\n",
837                           sid_string_dbg(&ginfo->sid)));
838                 status = make_samr_object_sd(
839                         p->mem_ctx, &psd, &sd_size,
840                         &usr_nopwchange_generic_mapping,
841                         &ginfo->sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
842                 goto done;
843         }
844
845         ainfo = policy_handle_find(p, r->in.handle,
846                                    STD_RIGHT_READ_CONTROL_ACCESS, NULL,
847                                    struct samr_alias_info, &status);
848         if (NT_STATUS_IS_OK(status)) {
849                 /*
850                  * TODO: different SDs have to be generated for aliases groups
851                  * and users.  Currently all three get a default user SD
852                  */
853                 DEBUG(10,("_samr_QuerySecurity: querying security on alias "
854                           "Object with SID: %s\n",
855                           sid_string_dbg(&ainfo->sid)));
856                 status = make_samr_object_sd(
857                         p->mem_ctx, &psd, &sd_size,
858                         &usr_nopwchange_generic_mapping,
859                         &ainfo->sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
860                 goto done;
861         }
862
863         return NT_STATUS_OBJECT_TYPE_MISMATCH;
864 done:
865         if ((*r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
866                 return NT_STATUS_NO_MEMORY;
867
868         return status;
869 }
870
871 /*******************************************************************
872 makes a SAM_ENTRY / UNISTR2* structure from a user list.
873 ********************************************************************/
874
875 static NTSTATUS make_user_sam_entry_list(TALLOC_CTX *ctx,
876                                          struct samr_SamEntry **sam_pp,
877                                          uint32_t num_entries,
878                                          uint32_t start_idx,
879                                          struct samr_displayentry *entries)
880 {
881         uint32_t i;
882         struct samr_SamEntry *sam;
883
884         *sam_pp = NULL;
885
886         if (num_entries == 0) {
887                 return NT_STATUS_OK;
888         }
889
890         sam = TALLOC_ZERO_ARRAY(ctx, struct samr_SamEntry, num_entries);
891         if (sam == NULL) {
892                 DEBUG(0, ("make_user_sam_entry_list: TALLOC_ZERO failed!\n"));
893                 return NT_STATUS_NO_MEMORY;
894         }
895
896         for (i = 0; i < num_entries; i++) {
897 #if 0
898                 /*
899                  * usrmgr expects a non-NULL terminated string with
900                  * trust relationships
901                  */
902                 if (entries[i].acct_flags & ACB_DOMTRUST) {
903                         init_unistr2(&uni_temp_name, entries[i].account_name,
904                                      UNI_FLAGS_NONE);
905                 } else {
906                         init_unistr2(&uni_temp_name, entries[i].account_name,
907                                      UNI_STR_TERMINATE);
908                 }
909 #endif
910                 init_lsa_String(&sam[i].name, entries[i].account_name);
911                 sam[i].idx = entries[i].rid;
912         }
913
914         *sam_pp = sam;
915
916         return NT_STATUS_OK;
917 }
918
919 #define MAX_SAM_ENTRIES MAX_SAM_ENTRIES_W2K
920
921 /*******************************************************************
922  _samr_EnumDomainUsers
923  ********************************************************************/
924
925 NTSTATUS _samr_EnumDomainUsers(pipes_struct *p,
926                                struct samr_EnumDomainUsers *r)
927 {
928         NTSTATUS status;
929         struct samr_domain_info *dinfo;
930         int num_account;
931         uint32 enum_context = *r->in.resume_handle;
932         enum remote_arch_types ra_type = get_remote_arch();
933         int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
934         uint32 max_entries = max_sam_entries;
935         struct samr_displayentry *entries = NULL;
936         struct samr_SamArray *samr_array = NULL;
937         struct samr_SamEntry *samr_entries = NULL;
938
939         DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
940
941         dinfo = policy_handle_find(p, r->in.domain_handle,
942                                    SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
943                                    struct samr_domain_info, &status);
944         if (!NT_STATUS_IS_OK(status)) {
945                 return status;
946         }
947
948         samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
949         if (!samr_array) {
950                 return NT_STATUS_NO_MEMORY;
951         }
952         *r->out.sam = samr_array;
953
954         if (sid_check_is_builtin(&dinfo->sid)) {
955                 /* No users in builtin. */
956                 *r->out.resume_handle = *r->in.resume_handle;
957                 DEBUG(5,("_samr_EnumDomainUsers: No users in BUILTIN\n"));
958                 return status;
959         }
960
961         become_root();
962
963         /* AS ROOT !!!! */
964
965         if ((dinfo->disp_info->enum_users != NULL) &&
966             (dinfo->disp_info->enum_acb_mask != r->in.acct_flags)) {
967                 TALLOC_FREE(dinfo->disp_info->enum_users);
968         }
969
970         if (dinfo->disp_info->enum_users == NULL) {
971                 dinfo->disp_info->enum_users = pdb_search_users(
972                         dinfo->disp_info, r->in.acct_flags);
973                 dinfo->disp_info->enum_acb_mask = r->in.acct_flags;
974         }
975
976         if (dinfo->disp_info->enum_users == NULL) {
977                 /* END AS ROOT !!!! */
978                 unbecome_root();
979                 return NT_STATUS_ACCESS_DENIED;
980         }
981
982         num_account = pdb_search_entries(dinfo->disp_info->enum_users,
983                                          enum_context, max_entries,
984                                          &entries);
985
986         /* END AS ROOT !!!! */
987
988         unbecome_root();
989
990         if (num_account == 0) {
991                 DEBUG(5, ("_samr_EnumDomainUsers: enumeration handle over "
992                           "total entries\n"));
993                 *r->out.resume_handle = *r->in.resume_handle;
994                 return NT_STATUS_OK;
995         }
996
997         status = make_user_sam_entry_list(p->mem_ctx, &samr_entries,
998                                           num_account, enum_context,
999                                           entries);
1000         if (!NT_STATUS_IS_OK(status)) {
1001                 return status;
1002         }
1003
1004         if (max_entries <= num_account) {
1005                 status = STATUS_MORE_ENTRIES;
1006         } else {
1007                 status = NT_STATUS_OK;
1008         }
1009
1010         /* Ensure we cache this enumeration. */
1011         set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
1012
1013         DEBUG(5, ("_samr_EnumDomainUsers: %d\n", __LINE__));
1014
1015         samr_array->count = num_account;
1016         samr_array->entries = samr_entries;
1017
1018         *r->out.resume_handle = *r->in.resume_handle + num_account;
1019         *r->out.num_entries = num_account;
1020
1021         DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
1022
1023         return status;
1024 }
1025
1026 /*******************************************************************
1027 makes a SAM_ENTRY / UNISTR2* structure from a group list.
1028 ********************************************************************/
1029
1030 static void make_group_sam_entry_list(TALLOC_CTX *ctx,
1031                                       struct samr_SamEntry **sam_pp,
1032                                       uint32_t num_sam_entries,
1033                                       struct samr_displayentry *entries)
1034 {
1035         struct samr_SamEntry *sam;
1036         uint32_t i;
1037
1038         *sam_pp = NULL;
1039
1040         if (num_sam_entries == 0) {
1041                 return;
1042         }
1043
1044         sam = TALLOC_ZERO_ARRAY(ctx, struct samr_SamEntry, num_sam_entries);
1045         if (sam == NULL) {
1046                 return;
1047         }
1048
1049         for (i = 0; i < num_sam_entries; i++) {
1050                 /*
1051                  * JRA. I think this should include the null. TNG does not.
1052                  */
1053                 init_lsa_String(&sam[i].name, entries[i].account_name);
1054                 sam[i].idx = entries[i].rid;
1055         }
1056
1057         *sam_pp = sam;
1058 }
1059
1060 /*******************************************************************
1061  _samr_EnumDomainGroups
1062  ********************************************************************/
1063
1064 NTSTATUS _samr_EnumDomainGroups(pipes_struct *p,
1065                                 struct samr_EnumDomainGroups *r)
1066 {
1067         NTSTATUS status;
1068         struct samr_domain_info *dinfo;
1069         struct samr_displayentry *groups;
1070         uint32 num_groups;
1071         struct samr_SamArray *samr_array = NULL;
1072         struct samr_SamEntry *samr_entries = NULL;
1073
1074         dinfo = policy_handle_find(p, r->in.domain_handle,
1075                                    SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
1076                                    struct samr_domain_info, &status);
1077         if (!NT_STATUS_IS_OK(status)) {
1078                 return status;
1079         }
1080
1081         DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
1082
1083         samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
1084         if (!samr_array) {
1085                 return NT_STATUS_NO_MEMORY;
1086         }
1087         *r->out.sam = samr_array;
1088
1089         if (sid_check_is_builtin(&dinfo->sid)) {
1090                 /* No groups in builtin. */
1091                 *r->out.resume_handle = *r->in.resume_handle;
1092                 DEBUG(5,("_samr_EnumDomainGroups: No groups in BUILTIN\n"));
1093                 return status;
1094         }
1095
1096         /* the domain group array is being allocated in the function below */
1097
1098         become_root();
1099
1100         if (dinfo->disp_info->groups == NULL) {
1101                 dinfo->disp_info->groups = pdb_search_groups(dinfo->disp_info);
1102
1103                 if (dinfo->disp_info->groups == NULL) {
1104                         unbecome_root();
1105                         return NT_STATUS_ACCESS_DENIED;
1106                 }
1107         }
1108
1109         num_groups = pdb_search_entries(dinfo->disp_info->groups,
1110                                         *r->in.resume_handle,
1111                                         MAX_SAM_ENTRIES, &groups);
1112         unbecome_root();
1113
1114         /* Ensure we cache this enumeration. */
1115         set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
1116
1117         make_group_sam_entry_list(p->mem_ctx, &samr_entries,
1118                                   num_groups, groups);
1119
1120         if (MAX_SAM_ENTRIES <= num_groups) {
1121                 status = STATUS_MORE_ENTRIES;
1122         } else {
1123                 status = NT_STATUS_OK;
1124         }
1125
1126         samr_array->count = num_groups;
1127         samr_array->entries = samr_entries;
1128
1129         *r->out.num_entries = num_groups;
1130         *r->out.resume_handle = num_groups + *r->in.resume_handle;
1131
1132         DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
1133
1134         return status;
1135 }
1136
1137 /*******************************************************************
1138  _samr_EnumDomainAliases
1139  ********************************************************************/
1140
1141 NTSTATUS _samr_EnumDomainAliases(pipes_struct *p,
1142                                  struct samr_EnumDomainAliases *r)
1143 {
1144         NTSTATUS status;
1145         struct samr_domain_info *dinfo;
1146         struct samr_displayentry *aliases;
1147         uint32 num_aliases = 0;
1148         struct samr_SamArray *samr_array = NULL;
1149         struct samr_SamEntry *samr_entries = NULL;
1150
1151         dinfo = policy_handle_find(p, r->in.domain_handle,
1152                                    SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
1153                                    struct samr_domain_info, &status);
1154         if (!NT_STATUS_IS_OK(status)) {
1155                 return status;
1156         }
1157
1158         DEBUG(5,("_samr_EnumDomainAliases: sid %s\n",
1159                  sid_string_dbg(&dinfo->sid)));
1160
1161         samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
1162         if (!samr_array) {
1163                 return NT_STATUS_NO_MEMORY;
1164         }
1165
1166         become_root();
1167
1168         if (dinfo->disp_info->aliases == NULL) {
1169                 dinfo->disp_info->aliases = pdb_search_aliases(
1170                         dinfo->disp_info, &dinfo->sid);
1171                 if (dinfo->disp_info->aliases == NULL) {
1172                         unbecome_root();
1173                         return NT_STATUS_ACCESS_DENIED;
1174                 }
1175         }
1176
1177         num_aliases = pdb_search_entries(dinfo->disp_info->aliases,
1178                                          *r->in.resume_handle,
1179                                          MAX_SAM_ENTRIES, &aliases);
1180         unbecome_root();
1181
1182         /* Ensure we cache this enumeration. */
1183         set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
1184
1185         make_group_sam_entry_list(p->mem_ctx, &samr_entries,
1186                                   num_aliases, aliases);
1187
1188         DEBUG(5,("_samr_EnumDomainAliases: %d\n", __LINE__));
1189
1190         if (MAX_SAM_ENTRIES <= num_aliases) {
1191                 status = STATUS_MORE_ENTRIES;
1192         } else {
1193                 status = NT_STATUS_OK;
1194         }
1195
1196         samr_array->count = num_aliases;
1197         samr_array->entries = samr_entries;
1198
1199         *r->out.sam = samr_array;
1200         *r->out.num_entries = num_aliases;
1201         *r->out.resume_handle = num_aliases + *r->in.resume_handle;
1202
1203         return status;
1204 }
1205
1206 /*******************************************************************
1207  inits a samr_DispInfoGeneral structure.
1208 ********************************************************************/
1209
1210 static NTSTATUS init_samr_dispinfo_1(TALLOC_CTX *ctx,
1211                                      struct samr_DispInfoGeneral *r,
1212                                      uint32_t num_entries,
1213                                      uint32_t start_idx,
1214                                      struct samr_displayentry *entries)
1215 {
1216         uint32 i;
1217
1218         DEBUG(10, ("init_samr_dispinfo_1: num_entries: %d\n", num_entries));
1219
1220         if (num_entries == 0) {
1221                 return NT_STATUS_OK;
1222         }
1223
1224         r->count = num_entries;
1225
1226         r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryGeneral, num_entries);
1227         if (!r->entries) {
1228                 return NT_STATUS_NO_MEMORY;
1229         }
1230
1231         for (i = 0; i < num_entries ; i++) {
1232
1233                 init_lsa_String(&r->entries[i].account_name,
1234                                 entries[i].account_name);
1235
1236                 init_lsa_String(&r->entries[i].description,
1237                                 entries[i].description);
1238
1239                 init_lsa_String(&r->entries[i].full_name,
1240                                 entries[i].fullname);
1241
1242                 r->entries[i].rid = entries[i].rid;
1243                 r->entries[i].acct_flags = entries[i].acct_flags;
1244                 r->entries[i].idx = start_idx+i+1;
1245         }
1246
1247         return NT_STATUS_OK;
1248 }
1249
1250 /*******************************************************************
1251  inits a samr_DispInfoFull structure.
1252 ********************************************************************/
1253
1254 static NTSTATUS init_samr_dispinfo_2(TALLOC_CTX *ctx,
1255                                      struct samr_DispInfoFull *r,
1256                                      uint32_t num_entries,
1257                                      uint32_t start_idx,
1258                                      struct samr_displayentry *entries)
1259 {
1260         uint32_t i;
1261
1262         DEBUG(10, ("init_samr_dispinfo_2: num_entries: %d\n", num_entries));
1263
1264         if (num_entries == 0) {
1265                 return NT_STATUS_OK;
1266         }
1267
1268         r->count = num_entries;
1269
1270         r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryFull, num_entries);
1271         if (!r->entries) {
1272                 return NT_STATUS_NO_MEMORY;
1273         }
1274
1275         for (i = 0; i < num_entries ; i++) {
1276
1277                 init_lsa_String(&r->entries[i].account_name,
1278                                 entries[i].account_name);
1279
1280                 init_lsa_String(&r->entries[i].description,
1281                                 entries[i].description);
1282
1283                 r->entries[i].rid = entries[i].rid;
1284                 r->entries[i].acct_flags = entries[i].acct_flags;
1285                 r->entries[i].idx = start_idx+i+1;
1286         }
1287
1288         return NT_STATUS_OK;
1289 }
1290
1291 /*******************************************************************
1292  inits a samr_DispInfoFullGroups structure.
1293 ********************************************************************/
1294
1295 static NTSTATUS init_samr_dispinfo_3(TALLOC_CTX *ctx,
1296                                      struct samr_DispInfoFullGroups *r,
1297                                      uint32_t num_entries,
1298                                      uint32_t start_idx,
1299                                      struct samr_displayentry *entries)
1300 {
1301         uint32_t i;
1302
1303         DEBUG(5, ("init_samr_dispinfo_3: num_entries: %d\n", num_entries));
1304
1305         if (num_entries == 0) {
1306                 return NT_STATUS_OK;
1307         }
1308
1309         r->count = num_entries;
1310
1311         r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryFullGroup, num_entries);
1312         if (!r->entries) {
1313                 return NT_STATUS_NO_MEMORY;
1314         }
1315
1316         for (i = 0; i < num_entries ; i++) {
1317
1318                 init_lsa_String(&r->entries[i].account_name,
1319                                 entries[i].account_name);
1320
1321                 init_lsa_String(&r->entries[i].description,
1322                                 entries[i].description);
1323
1324                 r->entries[i].rid = entries[i].rid;
1325                 r->entries[i].acct_flags = entries[i].acct_flags;
1326                 r->entries[i].idx = start_idx+i+1;
1327         }
1328
1329         return NT_STATUS_OK;
1330 }
1331
1332 /*******************************************************************
1333  inits a samr_DispInfoAscii structure.
1334 ********************************************************************/
1335
1336 static NTSTATUS init_samr_dispinfo_4(TALLOC_CTX *ctx,
1337                                      struct samr_DispInfoAscii *r,
1338                                      uint32_t num_entries,
1339                                      uint32_t start_idx,
1340                                      struct samr_displayentry *entries)
1341 {
1342         uint32_t i;
1343
1344         DEBUG(5, ("init_samr_dispinfo_4: num_entries: %d\n", num_entries));
1345
1346         if (num_entries == 0) {
1347                 return NT_STATUS_OK;
1348         }
1349
1350         r->count = num_entries;
1351
1352         r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryAscii, num_entries);
1353         if (!r->entries) {
1354                 return NT_STATUS_NO_MEMORY;
1355         }
1356
1357         for (i = 0; i < num_entries ; i++) {
1358
1359                 init_lsa_AsciiStringLarge(&r->entries[i].account_name,
1360                                           entries[i].account_name);
1361
1362                 r->entries[i].idx = start_idx+i+1;
1363         }
1364
1365         return NT_STATUS_OK;
1366 }
1367
1368 /*******************************************************************
1369  inits a samr_DispInfoAscii structure.
1370 ********************************************************************/
1371
1372 static NTSTATUS init_samr_dispinfo_5(TALLOC_CTX *ctx,
1373                                      struct samr_DispInfoAscii *r,
1374                                      uint32_t num_entries,
1375                                      uint32_t start_idx,
1376                                      struct samr_displayentry *entries)
1377 {
1378         uint32_t i;
1379
1380         DEBUG(5, ("init_samr_dispinfo_5: num_entries: %d\n", num_entries));
1381
1382         if (num_entries == 0) {
1383                 return NT_STATUS_OK;
1384         }
1385
1386         r->count = num_entries;
1387
1388         r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryAscii, num_entries);
1389         if (!r->entries) {
1390                 return NT_STATUS_NO_MEMORY;
1391         }
1392
1393         for (i = 0; i < num_entries ; i++) {
1394
1395                 init_lsa_AsciiStringLarge(&r->entries[i].account_name,
1396                                           entries[i].account_name);
1397
1398                 r->entries[i].idx = start_idx+i+1;
1399         }
1400
1401         return NT_STATUS_OK;
1402 }
1403
1404 /*******************************************************************
1405  _samr_QueryDisplayInfo
1406  ********************************************************************/
1407
1408 NTSTATUS _samr_QueryDisplayInfo(pipes_struct *p,
1409                                 struct samr_QueryDisplayInfo *r)
1410 {
1411         NTSTATUS status;
1412         struct samr_domain_info *dinfo;
1413         uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
1414
1415         uint32 max_entries = r->in.max_entries;
1416
1417         union samr_DispInfo *disp_info = r->out.info;
1418
1419         uint32 temp_size=0;
1420         NTSTATUS disp_ret = NT_STATUS_UNSUCCESSFUL;
1421         uint32 num_account = 0;
1422         enum remote_arch_types ra_type = get_remote_arch();
1423         int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
1424         struct samr_displayentry *entries = NULL;
1425
1426         DEBUG(5,("_samr_QueryDisplayInfo: %d\n", __LINE__));
1427
1428         dinfo = policy_handle_find(p, r->in.domain_handle,
1429                                    SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
1430                                    struct samr_domain_info, &status);
1431         if (!NT_STATUS_IS_OK(status)) {
1432                 return status;
1433         }
1434
1435         if (sid_check_is_builtin(&dinfo->sid)) {
1436                 DEBUG(5,("_samr_QueryDisplayInfo: no users in BUILTIN\n"));
1437                 return NT_STATUS_OK;
1438         }
1439
1440         /*
1441          * calculate how many entries we will return.
1442          * based on
1443          * - the number of entries the client asked
1444          * - our limit on that
1445          * - the starting point (enumeration context)
1446          * - the buffer size the client will accept
1447          */
1448
1449         /*
1450          * We are a lot more like W2K. Instead of reading the SAM
1451          * each time to find the records we need to send back,
1452          * we read it once and link that copy to the sam handle.
1453          * For large user list (over the MAX_SAM_ENTRIES)
1454          * it's a definitive win.
1455          * second point to notice: between enumerations
1456          * our sam is now the same as it's a snapshoot.
1457          * third point: got rid of the static SAM_USER_21 struct
1458          * no more intermediate.
1459          * con: it uses much more memory, as a full copy is stored
1460          * in memory.
1461          *
1462          * If you want to change it, think twice and think
1463          * of the second point , that's really important.
1464          *
1465          * JFM, 12/20/2001
1466          */
1467
1468         if ((r->in.level < 1) || (r->in.level > 5)) {
1469                 DEBUG(0,("_samr_QueryDisplayInfo: Unknown info level (%u)\n",
1470                          (unsigned int)r->in.level ));
1471                 return NT_STATUS_INVALID_INFO_CLASS;
1472         }
1473
1474         /* first limit the number of entries we will return */
1475         if (r->in.max_entries > max_sam_entries) {
1476                 DEBUG(5, ("_samr_QueryDisplayInfo: client requested %d "
1477                           "entries, limiting to %d\n", r->in.max_entries,
1478                           max_sam_entries));
1479                 max_entries = max_sam_entries;
1480         }
1481
1482         /* calculate the size and limit on the number of entries we will
1483          * return */
1484
1485         temp_size=max_entries*struct_size;
1486
1487         if (temp_size > r->in.buf_size) {
1488                 max_entries = MIN((r->in.buf_size / struct_size),max_entries);;
1489                 DEBUG(5, ("_samr_QueryDisplayInfo: buffer size limits to "
1490                           "only %d entries\n", max_entries));
1491         }
1492
1493         become_root();
1494
1495         /* THe following done as ROOT. Don't return without unbecome_root(). */
1496
1497         switch (r->in.level) {
1498         case 1:
1499         case 4:
1500                 if (dinfo->disp_info->users == NULL) {
1501                         dinfo->disp_info->users = pdb_search_users(
1502                                 dinfo->disp_info, ACB_NORMAL);
1503                         if (dinfo->disp_info->users == NULL) {
1504                                 unbecome_root();
1505                                 return NT_STATUS_ACCESS_DENIED;
1506                         }
1507                         DEBUG(10,("_samr_QueryDisplayInfo: starting user enumeration at index %u\n",
1508                                 (unsigned  int)r->in.start_idx));
1509                 } else {
1510                         DEBUG(10,("_samr_QueryDisplayInfo: using cached user enumeration at index %u\n",
1511                                 (unsigned  int)r->in.start_idx));
1512                 }
1513
1514                 num_account = pdb_search_entries(dinfo->disp_info->users,
1515                                                  r->in.start_idx, max_entries,
1516                                                  &entries);
1517                 break;
1518         case 2:
1519                 if (dinfo->disp_info->machines == NULL) {
1520                         dinfo->disp_info->machines = pdb_search_users(
1521                                 dinfo->disp_info, ACB_WSTRUST|ACB_SVRTRUST);
1522                         if (dinfo->disp_info->machines == NULL) {
1523                                 unbecome_root();
1524                                 return NT_STATUS_ACCESS_DENIED;
1525                         }
1526                         DEBUG(10,("_samr_QueryDisplayInfo: starting machine enumeration at index %u\n",
1527                                 (unsigned  int)r->in.start_idx));
1528                 } else {
1529                         DEBUG(10,("_samr_QueryDisplayInfo: using cached machine enumeration at index %u\n",
1530                                 (unsigned  int)r->in.start_idx));
1531                 }
1532
1533                 num_account = pdb_search_entries(dinfo->disp_info->machines,
1534                                                  r->in.start_idx, max_entries,
1535                                                  &entries);
1536                 break;
1537         case 3:
1538         case 5:
1539                 if (dinfo->disp_info->groups == NULL) {
1540                         dinfo->disp_info->groups = pdb_search_groups(
1541                                 dinfo->disp_info);
1542                         if (dinfo->disp_info->groups == NULL) {
1543                                 unbecome_root();
1544                                 return NT_STATUS_ACCESS_DENIED;
1545                         }
1546                         DEBUG(10,("_samr_QueryDisplayInfo: starting group enumeration at index %u\n",
1547                                 (unsigned  int)r->in.start_idx));
1548                 } else {
1549                         DEBUG(10,("_samr_QueryDisplayInfo: using cached group enumeration at index %u\n",
1550                                 (unsigned  int)r->in.start_idx));
1551                 }
1552
1553                 num_account = pdb_search_entries(dinfo->disp_info->groups,
1554                                                  r->in.start_idx, max_entries,
1555                                                  &entries);
1556                 break;
1557         default:
1558                 unbecome_root();
1559                 smb_panic("info class changed");
1560                 break;
1561         }
1562         unbecome_root();
1563
1564
1565         /* Now create reply structure */
1566         switch (r->in.level) {
1567         case 1:
1568                 disp_ret = init_samr_dispinfo_1(p->mem_ctx, &disp_info->info1,
1569                                                 num_account, r->in.start_idx,
1570                                                 entries);
1571                 break;
1572         case 2:
1573                 disp_ret = init_samr_dispinfo_2(p->mem_ctx, &disp_info->info2,
1574                                                 num_account, r->in.start_idx,
1575                                                 entries);
1576                 break;
1577         case 3:
1578                 disp_ret = init_samr_dispinfo_3(p->mem_ctx, &disp_info->info3,
1579                                                 num_account, r->in.start_idx,
1580                                                 entries);
1581                 break;
1582         case 4:
1583                 disp_ret = init_samr_dispinfo_4(p->mem_ctx, &disp_info->info4,
1584                                                 num_account, r->in.start_idx,
1585                                                 entries);
1586                 break;
1587         case 5:
1588                 disp_ret = init_samr_dispinfo_5(p->mem_ctx, &disp_info->info5,
1589                                                 num_account, r->in.start_idx,
1590                                                 entries);
1591                 break;
1592         default:
1593                 smb_panic("info class changed");
1594                 break;
1595         }
1596
1597         if (!NT_STATUS_IS_OK(disp_ret))
1598                 return disp_ret;
1599
1600         if (max_entries <= num_account) {
1601                 status = STATUS_MORE_ENTRIES;
1602         } else {
1603                 status = NT_STATUS_OK;
1604         }
1605
1606         /* Ensure we cache this enumeration. */
1607         set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
1608
1609         DEBUG(5, ("_samr_QueryDisplayInfo: %d\n", __LINE__));
1610
1611         *r->out.total_size = num_account * struct_size;
1612         *r->out.returned_size = num_account ? temp_size : 0;
1613
1614         return status;
1615 }
1616
1617 /****************************************************************
1618  _samr_QueryDisplayInfo2
1619 ****************************************************************/
1620
1621 NTSTATUS _samr_QueryDisplayInfo2(pipes_struct *p,
1622                                  struct samr_QueryDisplayInfo2 *r)
1623 {
1624         struct samr_QueryDisplayInfo q;
1625
1626         q.in.domain_handle      = r->in.domain_handle;
1627         q.in.level              = r->in.level;
1628         q.in.start_idx          = r->in.start_idx;
1629         q.in.max_entries        = r->in.max_entries;
1630         q.in.buf_size           = r->in.buf_size;
1631
1632         q.out.total_size        = r->out.total_size;
1633         q.out.returned_size     = r->out.returned_size;
1634         q.out.info              = r->out.info;
1635
1636         return _samr_QueryDisplayInfo(p, &q);
1637 }
1638
1639 /****************************************************************
1640  _samr_QueryDisplayInfo3
1641 ****************************************************************/
1642
1643 NTSTATUS _samr_QueryDisplayInfo3(pipes_struct *p,
1644                                  struct samr_QueryDisplayInfo3 *r)
1645 {
1646         struct samr_QueryDisplayInfo q;
1647
1648         q.in.domain_handle      = r->in.domain_handle;
1649         q.in.level              = r->in.level;
1650         q.in.start_idx          = r->in.start_idx;
1651         q.in.max_entries        = r->in.max_entries;
1652         q.in.buf_size           = r->in.buf_size;
1653
1654         q.out.total_size        = r->out.total_size;
1655         q.out.returned_size     = r->out.returned_size;
1656         q.out.info              = r->out.info;
1657
1658         return _samr_QueryDisplayInfo(p, &q);
1659 }
1660
1661 /*******************************************************************
1662  _samr_QueryAliasInfo
1663  ********************************************************************/
1664
1665 NTSTATUS _samr_QueryAliasInfo(pipes_struct *p,
1666                               struct samr_QueryAliasInfo *r)
1667 {
1668         struct samr_alias_info *ainfo;
1669         struct acct_info info;
1670         NTSTATUS status;
1671         union samr_AliasInfo *alias_info = NULL;
1672         const char *alias_name = NULL;
1673         const char *alias_description = NULL;
1674
1675         DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1676
1677         ainfo = policy_handle_find(p, r->in.alias_handle,
1678                                    SAMR_ALIAS_ACCESS_LOOKUP_INFO, NULL,
1679                                    struct samr_alias_info, &status);
1680         if (!NT_STATUS_IS_OK(status)) {
1681                 return status;
1682         }
1683
1684         alias_info = TALLOC_ZERO_P(p->mem_ctx, union samr_AliasInfo);
1685         if (!alias_info) {
1686                 return NT_STATUS_NO_MEMORY;
1687         }
1688
1689         become_root();
1690         status = pdb_get_aliasinfo(&ainfo->sid, &info);
1691         unbecome_root();
1692
1693         if ( !NT_STATUS_IS_OK(status))
1694                 return status;
1695
1696         /* FIXME: info contains fstrings */
1697         alias_name = talloc_strdup(r, info.acct_name);
1698         alias_description = talloc_strdup(r, info.acct_desc);
1699
1700         switch (r->in.level) {
1701         case ALIASINFOALL:
1702                 alias_info->all.name.string             = alias_name;
1703                 alias_info->all.num_members             = 1; /* ??? */
1704                 alias_info->all.description.string      = alias_description;
1705                 break;
1706         case ALIASINFONAME:
1707                 alias_info->name.string                 = alias_name;
1708                 break;
1709         case ALIASINFODESCRIPTION:
1710                 alias_info->description.string          = alias_description;
1711                 break;
1712         default:
1713                 return NT_STATUS_INVALID_INFO_CLASS;
1714         }
1715
1716         *r->out.info = alias_info;
1717
1718         DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1719
1720         return NT_STATUS_OK;
1721 }
1722
1723 /*******************************************************************
1724  _samr_LookupNames
1725  ********************************************************************/
1726
1727 NTSTATUS _samr_LookupNames(pipes_struct *p,
1728                            struct samr_LookupNames *r)
1729 {
1730         struct samr_domain_info *dinfo;
1731         NTSTATUS status;
1732         uint32 *rid;
1733         enum lsa_SidType *type;
1734         int i;
1735         int num_rids = r->in.num_names;
1736         struct samr_Ids rids, types;
1737         uint32_t num_mapped = 0;
1738
1739         DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1740
1741         dinfo = policy_handle_find(p, r->in.domain_handle,
1742                                    0 /* Don't know the acc_bits yet */, NULL,
1743                                    struct samr_domain_info, &status);
1744         if (!NT_STATUS_IS_OK(status)) {
1745                 return status;
1746         }
1747
1748         if (num_rids > MAX_SAM_ENTRIES) {
1749                 num_rids = MAX_SAM_ENTRIES;
1750                 DEBUG(5,("_samr_LookupNames: truncating entries to %d\n", num_rids));
1751         }
1752
1753         rid = talloc_array(p->mem_ctx, uint32, num_rids);
1754         NT_STATUS_HAVE_NO_MEMORY(rid);
1755
1756         type = talloc_array(p->mem_ctx, enum lsa_SidType, num_rids);
1757         NT_STATUS_HAVE_NO_MEMORY(type);
1758
1759         DEBUG(5,("_samr_LookupNames: looking name on SID %s\n",
1760                  sid_string_dbg(&dinfo->sid)));
1761
1762         for (i = 0; i < num_rids; i++) {
1763
1764                 status = NT_STATUS_NONE_MAPPED;
1765                 type[i] = SID_NAME_UNKNOWN;
1766
1767                 rid[i] = 0xffffffff;
1768
1769                 if (sid_check_is_builtin(&dinfo->sid)) {
1770                         if (lookup_builtin_name(r->in.names[i].string,
1771                                                 &rid[i]))
1772                         {
1773                                 type[i] = SID_NAME_ALIAS;
1774                         }
1775                 } else {
1776                         lookup_global_sam_name(r->in.names[i].string, 0,
1777                                                &rid[i], &type[i]);
1778                 }
1779
1780                 if (type[i] != SID_NAME_UNKNOWN) {
1781                         num_mapped++;
1782                 }
1783         }
1784
1785         if (num_mapped == num_rids) {
1786                 status = NT_STATUS_OK;
1787         } else if (num_mapped == 0) {
1788                 status = NT_STATUS_NONE_MAPPED;
1789         } else {
1790                 status = STATUS_SOME_UNMAPPED;
1791         }
1792
1793         rids.count = num_rids;
1794         rids.ids = rid;
1795
1796         types.count = num_rids;
1797         types.ids = type;
1798
1799         *r->out.rids = rids;
1800         *r->out.types = types;
1801
1802         DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1803
1804         return status;
1805 }
1806
1807 /****************************************************************
1808  _samr_ChangePasswordUser
1809 ****************************************************************/
1810
1811 NTSTATUS _samr_ChangePasswordUser(pipes_struct *p,
1812                                   struct samr_ChangePasswordUser *r)
1813 {
1814         NTSTATUS status;
1815         bool ret = false;
1816         struct samr_user_info *uinfo;
1817         struct samu *pwd;
1818         struct samr_Password new_lmPwdHash, new_ntPwdHash, checkHash;
1819         struct samr_Password lm_pwd, nt_pwd;
1820
1821         uinfo = policy_handle_find(p, r->in.user_handle,
1822                                    SAMR_USER_ACCESS_SET_PASSWORD, NULL,
1823                                    struct samr_user_info, &status);
1824         if (!NT_STATUS_IS_OK(status)) {
1825                 return status;
1826         }
1827
1828         DEBUG(5,("_samr_ChangePasswordUser: sid:%s\n",
1829                   sid_string_dbg(&uinfo->sid)));
1830
1831         if (!(pwd = samu_new(NULL))) {
1832                 return NT_STATUS_NO_MEMORY;
1833         }
1834
1835         become_root();
1836         ret = pdb_getsampwsid(pwd, &uinfo->sid);
1837         unbecome_root();
1838
1839         if (!ret) {
1840                 TALLOC_FREE(pwd);
1841                 return NT_STATUS_WRONG_PASSWORD;
1842         }
1843
1844         {
1845                 const uint8_t *lm_pass, *nt_pass;
1846
1847                 lm_pass = pdb_get_lanman_passwd(pwd);
1848                 nt_pass = pdb_get_nt_passwd(pwd);
1849
1850                 if (!lm_pass || !nt_pass) {
1851                         status = NT_STATUS_WRONG_PASSWORD;
1852                         goto out;
1853                 }
1854
1855                 memcpy(&lm_pwd.hash, lm_pass, sizeof(lm_pwd.hash));
1856                 memcpy(&nt_pwd.hash, nt_pass, sizeof(nt_pwd.hash));
1857         }
1858
1859         /* basic sanity checking on parameters.  Do this before any database ops */
1860         if (!r->in.lm_present || !r->in.nt_present ||
1861             !r->in.old_lm_crypted || !r->in.new_lm_crypted ||
1862             !r->in.old_nt_crypted || !r->in.new_nt_crypted) {
1863                 /* we should really handle a change with lm not
1864                    present */
1865                 status = NT_STATUS_INVALID_PARAMETER_MIX;
1866                 goto out;
1867         }
1868
1869         /* decrypt and check the new lm hash */
1870         D_P16(lm_pwd.hash, r->in.new_lm_crypted->hash, new_lmPwdHash.hash);
1871         D_P16(new_lmPwdHash.hash, r->in.old_lm_crypted->hash, checkHash.hash);
1872         if (memcmp(checkHash.hash, lm_pwd.hash, 16) != 0) {
1873                 status = NT_STATUS_WRONG_PASSWORD;
1874                 goto out;
1875         }
1876
1877         /* decrypt and check the new nt hash */
1878         D_P16(nt_pwd.hash, r->in.new_nt_crypted->hash, new_ntPwdHash.hash);
1879         D_P16(new_ntPwdHash.hash, r->in.old_nt_crypted->hash, checkHash.hash);
1880         if (memcmp(checkHash.hash, nt_pwd.hash, 16) != 0) {
1881                 status = NT_STATUS_WRONG_PASSWORD;
1882                 goto out;
1883         }
1884
1885         /* The NT Cross is not required by Win2k3 R2, but if present
1886            check the nt cross hash */
1887         if (r->in.cross1_present && r->in.nt_cross) {
1888                 D_P16(lm_pwd.hash, r->in.nt_cross->hash, checkHash.hash);
1889                 if (memcmp(checkHash.hash, new_ntPwdHash.hash, 16) != 0) {
1890                         status = NT_STATUS_WRONG_PASSWORD;
1891                         goto out;
1892                 }
1893         }
1894
1895         /* The LM Cross is not required by Win2k3 R2, but if present
1896            check the lm cross hash */
1897         if (r->in.cross2_present && r->in.lm_cross) {
1898                 D_P16(nt_pwd.hash, r->in.lm_cross->hash, checkHash.hash);
1899                 if (memcmp(checkHash.hash, new_lmPwdHash.hash, 16) != 0) {
1900                         status = NT_STATUS_WRONG_PASSWORD;
1901                         goto out;
1902                 }
1903         }
1904
1905         if (!pdb_set_nt_passwd(pwd, new_ntPwdHash.hash, PDB_CHANGED) ||
1906             !pdb_set_lanman_passwd(pwd, new_lmPwdHash.hash, PDB_CHANGED)) {
1907                 status = NT_STATUS_ACCESS_DENIED;
1908                 goto out;
1909         }
1910
1911         status = pdb_update_sam_account(pwd);
1912  out:
1913         TALLOC_FREE(pwd);
1914
1915         return status;
1916 }
1917
1918 /*******************************************************************
1919  _samr_ChangePasswordUser2
1920  ********************************************************************/
1921
1922 NTSTATUS _samr_ChangePasswordUser2(pipes_struct *p,
1923                                    struct samr_ChangePasswordUser2 *r)
1924 {
1925         struct smbd_server_connection *sconn = smbd_server_conn;
1926         NTSTATUS status;
1927         fstring user_name;
1928         fstring wks;
1929
1930         DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1931
1932         fstrcpy(user_name, r->in.account->string);
1933         fstrcpy(wks, r->in.server->string);
1934
1935         DEBUG(5,("_samr_ChangePasswordUser2: user: %s wks: %s\n", user_name, wks));
1936
1937         /*
1938          * Pass the user through the NT -> unix user mapping
1939          * function.
1940          */
1941
1942         (void)map_username(sconn, user_name);
1943
1944         /*
1945          * UNIX username case mangling not required, pass_oem_change
1946          * is case insensitive.
1947          */
1948
1949         status = pass_oem_change(user_name,
1950                                  r->in.lm_password->data,
1951                                  r->in.lm_verifier->hash,
1952                                  r->in.nt_password->data,
1953                                  r->in.nt_verifier->hash,
1954                                  NULL);
1955
1956         DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1957
1958         if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
1959                 return NT_STATUS_WRONG_PASSWORD;
1960         }
1961
1962         return status;
1963 }
1964
1965 /****************************************************************
1966  _samr_OemChangePasswordUser2
1967 ****************************************************************/
1968
1969 NTSTATUS _samr_OemChangePasswordUser2(pipes_struct *p,
1970                                       struct samr_OemChangePasswordUser2 *r)
1971 {
1972         struct smbd_server_connection *sconn = smbd_server_conn;
1973         NTSTATUS status;
1974         fstring user_name;
1975         const char *wks = NULL;
1976
1977         DEBUG(5,("_samr_OemChangePasswordUser2: %d\n", __LINE__));
1978
1979         fstrcpy(user_name, r->in.account->string);
1980         if (r->in.server && r->in.server->string) {
1981                 wks = r->in.server->string;
1982         }
1983
1984         DEBUG(5,("_samr_OemChangePasswordUser2: user: %s wks: %s\n", user_name, wks));
1985
1986         /*
1987          * Pass the user through the NT -> unix user mapping
1988          * function.
1989          */
1990
1991         (void)map_username(sconn, user_name);
1992
1993         /*
1994          * UNIX username case mangling not required, pass_oem_change
1995          * is case insensitive.
1996          */
1997
1998         if (!r->in.hash || !r->in.password) {
1999                 return NT_STATUS_INVALID_PARAMETER;
2000         }
2001
2002         status = pass_oem_change(user_name,
2003                                  r->in.password->data,
2004                                  r->in.hash->hash,
2005                                  0,
2006                                  0,
2007                                  NULL);
2008
2009         if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
2010                 return NT_STATUS_WRONG_PASSWORD;
2011         }
2012
2013         DEBUG(5,("_samr_OemChangePasswordUser2: %d\n", __LINE__));
2014
2015         return status;
2016 }
2017
2018 /*******************************************************************
2019  _samr_ChangePasswordUser3
2020  ********************************************************************/
2021
2022 NTSTATUS _samr_ChangePasswordUser3(pipes_struct *p,
2023                                    struct samr_ChangePasswordUser3 *r)
2024 {
2025         struct smbd_server_connection *sconn = smbd_server_conn;
2026         NTSTATUS status;
2027         fstring user_name;
2028         const char *wks = NULL;
2029         enum samPwdChangeReason reject_reason;
2030         struct samr_DomInfo1 *dominfo = NULL;
2031         struct userPwdChangeFailureInformation *reject = NULL;
2032         uint32_t tmp;
2033
2034         DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
2035
2036         fstrcpy(user_name, r->in.account->string);
2037         if (r->in.server && r->in.server->string) {
2038                 wks = r->in.server->string;
2039         }
2040
2041         DEBUG(5,("_samr_ChangePasswordUser3: user: %s wks: %s\n", user_name, wks));
2042
2043         /*
2044          * Pass the user through the NT -> unix user mapping
2045          * function.
2046          */
2047
2048         (void)map_username(sconn, user_name);
2049
2050         /*
2051          * UNIX username case mangling not required, pass_oem_change
2052          * is case insensitive.
2053          */
2054
2055         status = pass_oem_change(user_name,
2056                                  r->in.lm_password->data,
2057                                  r->in.lm_verifier->hash,
2058                                  r->in.nt_password->data,
2059                                  r->in.nt_verifier->hash,
2060                                  &reject_reason);
2061         if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
2062                 return NT_STATUS_WRONG_PASSWORD;
2063         }
2064
2065         if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) ||
2066             NT_STATUS_EQUAL(status, NT_STATUS_ACCOUNT_RESTRICTION)) {
2067
2068                 time_t u_expire, u_min_age;
2069                 uint32 account_policy_temp;
2070
2071                 dominfo = TALLOC_ZERO_P(p->mem_ctx, struct samr_DomInfo1);
2072                 if (!dominfo) {
2073                         return NT_STATUS_NO_MEMORY;
2074                 }
2075
2076                 reject = TALLOC_ZERO_P(p->mem_ctx,
2077                                 struct userPwdChangeFailureInformation);
2078                 if (!reject) {
2079                         return NT_STATUS_NO_MEMORY;
2080                 }
2081
2082                 become_root();
2083
2084                 /* AS ROOT !!! */
2085
2086                 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN, &tmp);
2087                 dominfo->min_password_length = tmp;
2088
2089                 pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &tmp);
2090                 dominfo->password_history_length = tmp;
2091
2092                 pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
2093                                        &dominfo->password_properties);
2094
2095                 pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, &account_policy_temp);
2096                 u_expire = account_policy_temp;
2097
2098                 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, &account_policy_temp);
2099                 u_min_age = account_policy_temp;
2100
2101                 /* !AS ROOT */
2102
2103                 unbecome_root();
2104
2105                 unix_to_nt_time_abs((NTTIME *)&dominfo->max_password_age, u_expire);
2106                 unix_to_nt_time_abs((NTTIME *)&dominfo->min_password_age, u_min_age);
2107
2108                 if (lp_check_password_script() && *lp_check_password_script()) {
2109                         dominfo->password_properties |= DOMAIN_PASSWORD_COMPLEX;
2110                 }
2111
2112                 reject->extendedFailureReason = reject_reason;
2113
2114                 *r->out.dominfo = dominfo;
2115                 *r->out.reject = reject;
2116         }
2117
2118         DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
2119
2120         return status;
2121 }
2122
2123 /*******************************************************************
2124 makes a SAMR_R_LOOKUP_RIDS structure.
2125 ********************************************************************/
2126
2127 static bool make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names,
2128                                   const char **names,
2129                                   struct lsa_String **lsa_name_array_p)
2130 {
2131         struct lsa_String *lsa_name_array = NULL;
2132         uint32_t i;
2133
2134         *lsa_name_array_p = NULL;
2135
2136         if (num_names != 0) {
2137                 lsa_name_array = TALLOC_ZERO_ARRAY(ctx, struct lsa_String, num_names);
2138                 if (!lsa_name_array) {
2139                         return false;
2140                 }
2141         }
2142
2143         for (i = 0; i < num_names; i++) {
2144                 DEBUG(10, ("names[%d]:%s\n", i, names[i] && *names[i] ? names[i] : ""));
2145                 init_lsa_String(&lsa_name_array[i], names[i]);
2146         }
2147
2148         *lsa_name_array_p = lsa_name_array;
2149
2150         return true;
2151 }
2152
2153 /*******************************************************************
2154  _samr_LookupRids
2155  ********************************************************************/
2156
2157 NTSTATUS _samr_LookupRids(pipes_struct *p,
2158                           struct samr_LookupRids *r)
2159 {
2160         struct samr_domain_info *dinfo;
2161         NTSTATUS status;
2162         const char **names;
2163         enum lsa_SidType *attrs = NULL;
2164         uint32 *wire_attrs = NULL;
2165         int num_rids = (int)r->in.num_rids;
2166         int i;
2167         struct lsa_Strings names_array;
2168         struct samr_Ids types_array;
2169         struct lsa_String *lsa_names = NULL;
2170
2171         DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2172
2173         dinfo = policy_handle_find(p, r->in.domain_handle,
2174                                    0 /* Don't know the acc_bits yet */, NULL,
2175                                    struct samr_domain_info, &status);
2176         if (!NT_STATUS_IS_OK(status)) {
2177                 return status;
2178         }
2179
2180         if (num_rids > 1000) {
2181                 DEBUG(0, ("Got asked for %d rids (more than 1000) -- according "
2182                           "to samba4 idl this is not possible\n", num_rids));
2183                 return NT_STATUS_UNSUCCESSFUL;
2184         }
2185
2186         if (num_rids) {
2187                 names = TALLOC_ZERO_ARRAY(p->mem_ctx, const char *, num_rids);
2188                 attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, enum lsa_SidType, num_rids);
2189                 wire_attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_rids);
2190
2191                 if ((names == NULL) || (attrs == NULL) || (wire_attrs==NULL))
2192                         return NT_STATUS_NO_MEMORY;
2193         } else {
2194                 names = NULL;
2195                 attrs = NULL;
2196                 wire_attrs = NULL;
2197         }
2198
2199         become_root();  /* lookup_sid can require root privs */
2200         status = pdb_lookup_rids(&dinfo->sid, num_rids, r->in.rids,
2201                                  names, attrs);
2202         unbecome_root();
2203
2204         if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED) && (num_rids == 0)) {
2205                 status = NT_STATUS_OK;
2206         }
2207
2208         if (!make_samr_lookup_rids(p->mem_ctx, num_rids, names,
2209                                    &lsa_names)) {
2210                 return NT_STATUS_NO_MEMORY;
2211         }
2212
2213         /* Convert from enum lsa_SidType to uint32 for wire format. */
2214         for (i = 0; i < num_rids; i++) {
2215                 wire_attrs[i] = (uint32)attrs[i];
2216         }
2217
2218         names_array.count = num_rids;
2219         names_array.names = lsa_names;
2220
2221         types_array.count = num_rids;
2222         types_array.ids = wire_attrs;
2223
2224         *r->out.names = names_array;
2225         *r->out.types = types_array;
2226
2227         DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2228
2229         return status;
2230 }
2231
2232 /*******************************************************************
2233  _samr_OpenUser
2234 ********************************************************************/
2235
2236 NTSTATUS _samr_OpenUser(pipes_struct *p,
2237                         struct samr_OpenUser *r)
2238 {
2239         struct samu *sampass=NULL;
2240         DOM_SID sid;
2241         struct samr_domain_info *dinfo;
2242         struct samr_user_info *uinfo;
2243         SEC_DESC *psd = NULL;
2244         uint32    acc_granted;
2245         uint32    des_access = r->in.access_mask;
2246         uint32_t extra_access = 0;
2247         size_t    sd_size;
2248         bool ret;
2249         NTSTATUS nt_status;
2250         SE_PRIV se_rights;
2251         NTSTATUS status;
2252
2253         dinfo = policy_handle_find(p, r->in.domain_handle,
2254                                    SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
2255                                    struct samr_domain_info, &status);
2256         if (!NT_STATUS_IS_OK(status)) {
2257                 return status;
2258         }
2259
2260         if ( !(sampass = samu_new( p->mem_ctx )) ) {
2261                 return NT_STATUS_NO_MEMORY;
2262         }
2263
2264         /* append the user's RID to it */
2265
2266         if (!sid_compose(&sid, &dinfo->sid, r->in.rid))
2267                 return NT_STATUS_NO_SUCH_USER;
2268
2269         /* check if access can be granted as requested by client. */
2270         map_max_allowed_access(p->server_info->ptok,
2271                                &p->server_info->utok,
2272                                &des_access);
2273
2274         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &sid, SAMR_USR_RIGHTS_WRITE_PW);
2275         se_map_generic(&des_access, &usr_generic_mapping);
2276
2277         /*
2278          * Get the sampass first as we need to check privileges
2279          * based on what kind of user object this is.
2280          * But don't reveal info too early if it didn't exist.
2281          */
2282
2283         become_root();
2284         ret=pdb_getsampwsid(sampass, &sid);
2285         unbecome_root();
2286
2287         se_priv_copy(&se_rights, &se_priv_none);
2288
2289         /*
2290          * We do the override access checks on *open*, not at
2291          * SetUserInfo time.
2292          */
2293         if (ret) {
2294                 uint32_t acb_info = pdb_get_acct_ctrl(sampass);
2295
2296                 if ((acb_info & ACB_WSTRUST) &&
2297                                 user_has_any_privilege(p->server_info->ptok,
2298                                                 &se_machine_account)) {
2299                         /*
2300                          * SeMachineAccount is needed to add
2301                          * GENERIC_RIGHTS_USER_WRITE to a machine
2302                          * account.
2303                          */
2304                         se_priv_add(&se_rights, &se_machine_account);
2305                         DEBUG(10,("_samr_OpenUser: adding machine account "
2306                                 "rights to handle for user %s\n",
2307                                 pdb_get_username(sampass) ));
2308                 }
2309                 if ((acb_info & ACB_NORMAL) &&
2310                                 user_has_any_privilege(p->server_info->ptok,
2311                                                 &se_add_users)) {
2312                         /*
2313                          * SeAddUsers is needed to add
2314                          * GENERIC_RIGHTS_USER_WRITE to a normal
2315                          * account.
2316                          */
2317                         se_priv_add(&se_rights, &se_add_users);
2318                         DEBUG(10,("_samr_OpenUser: adding add user "
2319                                 "rights to handle for user %s\n",
2320                                 pdb_get_username(sampass) ));
2321                 }
2322                 /*
2323                  * Cheat - allow GENERIC_RIGHTS_USER_WRITE if pipe user is
2324                  * in DOMAIN_RID_ADMINS. This is almost certainly not
2325                  * what Windows does but is a hack for people who haven't
2326                  * set up privileges on groups in Samba.
2327                  */
2328                 if (acb_info & (ACB_SVRTRUST|ACB_DOMTRUST)) {
2329                         if (lp_enable_privileges() && nt_token_check_domain_rid(p->server_info->ptok,
2330                                                         DOMAIN_RID_ADMINS)) {
2331                                 des_access &= ~GENERIC_RIGHTS_USER_WRITE;
2332                                 extra_access = GENERIC_RIGHTS_USER_WRITE;
2333                                 DEBUG(4,("_samr_OpenUser: Allowing "
2334                                         "GENERIC_RIGHTS_USER_WRITE for "
2335                                         "rid admins\n"));
2336                         }
2337                 }
2338         }
2339
2340         TALLOC_FREE(sampass);
2341
2342         nt_status = access_check_object(psd, p->server_info->ptok,
2343                 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
2344                 &acc_granted, "_samr_OpenUser");
2345
2346         if ( !NT_STATUS_IS_OK(nt_status) )
2347                 return nt_status;
2348
2349         /* check that the SID exists in our domain. */
2350         if (ret == False) {
2351                 return NT_STATUS_NO_SUCH_USER;
2352         }
2353
2354         /* If we did the rid admins hack above, allow access. */
2355         acc_granted |= extra_access;
2356
2357         uinfo = policy_handle_create(p, r->out.user_handle, acc_granted,
2358                                      struct samr_user_info, &nt_status);
2359         if (!NT_STATUS_IS_OK(nt_status)) {
2360                 return nt_status;
2361         }
2362         uinfo->sid = sid;
2363
2364         return NT_STATUS_OK;
2365 }
2366
2367 /*************************************************************************
2368  *************************************************************************/
2369
2370 static NTSTATUS init_samr_parameters_string(TALLOC_CTX *mem_ctx,
2371                                             DATA_BLOB *blob,
2372                                             struct lsa_BinaryString **_r)
2373 {
2374         struct lsa_BinaryString *r;
2375
2376         if (!blob || !_r) {
2377                 return NT_STATUS_INVALID_PARAMETER;
2378         }
2379
2380         r = TALLOC_ZERO_P(mem_ctx, struct lsa_BinaryString);
2381         if (!r) {
2382                 return NT_STATUS_NO_MEMORY;
2383         }
2384
2385         r->array = TALLOC_ZERO_ARRAY(mem_ctx, uint16_t, blob->length/2);
2386         if (!r->array) {
2387                 return NT_STATUS_NO_MEMORY;
2388         }
2389         memcpy(r->array, blob->data, blob->length);
2390         r->size = blob->length;
2391         r->length = blob->length;
2392
2393         if (!r->array) {
2394                 return NT_STATUS_NO_MEMORY;
2395         }
2396
2397         *_r = r;
2398
2399         return NT_STATUS_OK;
2400 }
2401
2402 /*************************************************************************
2403  get_user_info_1.
2404  *************************************************************************/
2405
2406 static NTSTATUS get_user_info_1(TALLOC_CTX *mem_ctx,
2407                                 struct samr_UserInfo1 *r,
2408                                 struct samu *pw,
2409                                 DOM_SID *domain_sid)
2410 {
2411         const DOM_SID *sid_group;
2412         uint32_t primary_gid;
2413
2414         become_root();
2415         sid_group = pdb_get_group_sid(pw);
2416         unbecome_root();
2417
2418         if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2419                 DEBUG(0, ("get_user_info_1: User %s has Primary Group SID %s, \n"
2420                           "which conflicts with the domain sid %s.  Failing operation.\n",
2421                           pdb_get_username(pw), sid_string_dbg(sid_group),
2422                           sid_string_dbg(domain_sid)));
2423                 return NT_STATUS_UNSUCCESSFUL;
2424         }
2425
2426         r->account_name.string          = talloc_strdup(mem_ctx, pdb_get_username(pw));
2427         r->full_name.string             = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2428         r->primary_gid                  = primary_gid;
2429         r->description.string           = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2430         r->comment.string               = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2431
2432         return NT_STATUS_OK;
2433 }
2434
2435 /*************************************************************************
2436  get_user_info_2.
2437  *************************************************************************/
2438
2439 static NTSTATUS get_user_info_2(TALLOC_CTX *mem_ctx,
2440                                 struct samr_UserInfo2 *r,
2441                                 struct samu *pw)
2442 {
2443         r->comment.string               = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2444         r->unknown.string               = NULL;
2445         r->country_code                 = 0;
2446         r->code_page                    = 0;
2447
2448         return NT_STATUS_OK;
2449 }
2450
2451 /*************************************************************************
2452  get_user_info_3.
2453  *************************************************************************/
2454
2455 static NTSTATUS get_user_info_3(TALLOC_CTX *mem_ctx,
2456                                 struct samr_UserInfo3 *r,
2457                                 struct samu *pw,
2458                                 DOM_SID *domain_sid)
2459 {
2460         const DOM_SID *sid_user, *sid_group;
2461         uint32_t rid, primary_gid;
2462
2463         sid_user = pdb_get_user_sid(pw);
2464
2465         if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2466                 DEBUG(0, ("get_user_info_3: User %s has SID %s, \nwhich conflicts with "
2467                           "the domain sid %s.  Failing operation.\n",
2468                           pdb_get_username(pw), sid_string_dbg(sid_user),
2469                           sid_string_dbg(domain_sid)));
2470                 return NT_STATUS_UNSUCCESSFUL;
2471         }
2472
2473         become_root();
2474         sid_group = pdb_get_group_sid(pw);
2475         unbecome_root();
2476
2477         if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2478                 DEBUG(0, ("get_user_info_3: User %s has Primary Group SID %s, \n"
2479                           "which conflicts with the domain sid %s.  Failing operation.\n",
2480                           pdb_get_username(pw), sid_string_dbg(sid_group),
2481                           sid_string_dbg(domain_sid)));
2482                 return NT_STATUS_UNSUCCESSFUL;
2483         }
2484
2485         unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2486         unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2487         unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2488         unix_to_nt_time(&r->allow_password_change, pdb_get_pass_can_change_time(pw));
2489         unix_to_nt_time(&r->force_password_change, pdb_get_pass_must_change_time(pw));
2490
2491         r->account_name.string  = talloc_strdup(mem_ctx, pdb_get_username(pw));
2492         r->full_name.string     = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2493         r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2494         r->home_drive.string    = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2495         r->logon_script.string  = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2496         r->profile_path.string  = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2497         r->workstations.string  = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2498
2499         r->logon_hours          = get_logon_hours_from_pdb(mem_ctx, pw);
2500         r->rid                  = rid;
2501         r->primary_gid          = primary_gid;
2502         r->acct_flags           = pdb_get_acct_ctrl(pw);
2503         r->bad_password_count   = pdb_get_bad_password_count(pw);
2504         r->logon_count          = pdb_get_logon_count(pw);
2505
2506         return NT_STATUS_OK;
2507 }
2508
2509 /*************************************************************************
2510  get_user_info_4.
2511  *************************************************************************/
2512
2513 static NTSTATUS get_user_info_4(TALLOC_CTX *mem_ctx,
2514                                 struct samr_UserInfo4 *r,
2515                                 struct samu *pw)
2516 {
2517         r->logon_hours          = get_logon_hours_from_pdb(mem_ctx, pw);
2518
2519         return NT_STATUS_OK;
2520 }
2521
2522 /*************************************************************************
2523  get_user_info_5.
2524  *************************************************************************/
2525
2526 static NTSTATUS get_user_info_5(TALLOC_CTX *mem_ctx,
2527                                 struct samr_UserInfo5 *r,
2528                                 struct samu *pw,
2529                                 DOM_SID *domain_sid)
2530 {
2531         const DOM_SID *sid_user, *sid_group;
2532         uint32_t rid, primary_gid;
2533
2534         sid_user = pdb_get_user_sid(pw);
2535
2536         if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2537                 DEBUG(0, ("get_user_info_5: User %s has SID %s, \nwhich conflicts with "
2538                           "the domain sid %s.  Failing operation.\n",
2539                           pdb_get_username(pw), sid_string_dbg(sid_user),
2540                           sid_string_dbg(domain_sid)));
2541                 return NT_STATUS_UNSUCCESSFUL;
2542         }
2543
2544         become_root();
2545         sid_group = pdb_get_group_sid(pw);
2546         unbecome_root();
2547
2548         if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2549                 DEBUG(0, ("get_user_info_5: User %s has Primary Group SID %s, \n"
2550                           "which conflicts with the domain sid %s.  Failing operation.\n",
2551                           pdb_get_username(pw), sid_string_dbg(sid_group),
2552                           sid_string_dbg(domain_sid)));
2553                 return NT_STATUS_UNSUCCESSFUL;
2554         }
2555
2556         unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2557         unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2558         unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2559         unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2560
2561         r->account_name.string  = talloc_strdup(mem_ctx, pdb_get_username(pw));
2562         r->full_name.string     = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2563         r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2564         r->home_drive.string    = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2565         r->logon_script.string  = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2566         r->profile_path.string  = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2567         r->description.string   = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2568         r->workstations.string  = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2569
2570         r->logon_hours          = get_logon_hours_from_pdb(mem_ctx, pw);
2571         r->rid                  = rid;
2572         r->primary_gid          = primary_gid;
2573         r->acct_flags           = pdb_get_acct_ctrl(pw);
2574         r->bad_password_count   = pdb_get_bad_password_count(pw);
2575         r->logon_count          = pdb_get_logon_count(pw);
2576
2577         return NT_STATUS_OK;
2578 }
2579
2580 /*************************************************************************
2581  get_user_info_6.
2582  *************************************************************************/
2583
2584 static NTSTATUS get_user_info_6(TALLOC_CTX *mem_ctx,
2585                                 struct samr_UserInfo6 *r,
2586                                 struct samu *pw)
2587 {
2588         r->account_name.string  = talloc_strdup(mem_ctx, pdb_get_username(pw));
2589         r->full_name.string     = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2590
2591         return NT_STATUS_OK;
2592 }
2593
2594 /*************************************************************************
2595  get_user_info_7. Safe. Only gives out account_name.
2596  *************************************************************************/
2597
2598 static NTSTATUS get_user_info_7(TALLOC_CTX *mem_ctx,
2599                                 struct samr_UserInfo7 *r,
2600                                 struct samu *smbpass)
2601 {
2602         r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(smbpass));
2603         if (!r->account_name.string) {
2604                 return NT_STATUS_NO_MEMORY;
2605         }
2606
2607         return NT_STATUS_OK;
2608 }
2609
2610 /*************************************************************************
2611  get_user_info_8.
2612  *************************************************************************/
2613
2614 static NTSTATUS get_user_info_8(TALLOC_CTX *mem_ctx,
2615                                 struct samr_UserInfo8 *r,
2616                                 struct samu *pw)
2617 {
2618         r->full_name.string     = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2619
2620         return NT_STATUS_OK;
2621 }
2622
2623 /*************************************************************************
2624  get_user_info_9. Only gives out primary group SID.
2625  *************************************************************************/
2626
2627 static NTSTATUS get_user_info_9(TALLOC_CTX *mem_ctx,
2628                                 struct samr_UserInfo9 *r,
2629                                 struct samu *smbpass)
2630 {
2631         r->primary_gid = pdb_get_group_rid(smbpass);
2632
2633         return NT_STATUS_OK;
2634 }
2635
2636 /*************************************************************************
2637  get_user_info_10.
2638  *************************************************************************/
2639
2640 static NTSTATUS get_user_info_10(TALLOC_CTX *mem_ctx,
2641                                  struct samr_UserInfo10 *r,
2642                                  struct samu *pw)
2643 {
2644         r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2645         r->home_drive.string    = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2646
2647         return NT_STATUS_OK;
2648 }
2649
2650 /*************************************************************************
2651  get_user_info_11.
2652  *************************************************************************/
2653
2654 static NTSTATUS get_user_info_11(TALLOC_CTX *mem_ctx,
2655                                  struct samr_UserInfo11 *r,
2656                                  struct samu *pw)
2657 {
2658         r->logon_script.string  = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2659
2660         return NT_STATUS_OK;
2661 }
2662
2663 /*************************************************************************
2664  get_user_info_12.
2665  *************************************************************************/
2666
2667 static NTSTATUS get_user_info_12(TALLOC_CTX *mem_ctx,
2668                                  struct samr_UserInfo12 *r,
2669                                  struct samu *pw)
2670 {
2671         r->profile_path.string  = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2672
2673         return NT_STATUS_OK;
2674 }
2675
2676 /*************************************************************************
2677  get_user_info_13.
2678  *************************************************************************/
2679
2680 static NTSTATUS get_user_info_13(TALLOC_CTX *mem_ctx,
2681                                  struct samr_UserInfo13 *r,
2682                                  struct samu *pw)
2683 {
2684         r->description.string   = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2685
2686         return NT_STATUS_OK;
2687 }
2688
2689 /*************************************************************************
2690  get_user_info_14.
2691  *************************************************************************/
2692
2693 static NTSTATUS get_user_info_14(TALLOC_CTX *mem_ctx,
2694                                  struct samr_UserInfo14 *r,
2695                                  struct samu *pw)
2696 {
2697         r->workstations.string  = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2698
2699         return NT_STATUS_OK;
2700 }
2701
2702 /*************************************************************************
2703  get_user_info_16. Safe. Only gives out acb bits.
2704  *************************************************************************/
2705
2706 static NTSTATUS get_user_info_16(TALLOC_CTX *mem_ctx,
2707                                  struct samr_UserInfo16 *r,
2708                                  struct samu *smbpass)
2709 {
2710         r->acct_flags = pdb_get_acct_ctrl(smbpass);
2711
2712         return NT_STATUS_OK;
2713 }
2714
2715 /*************************************************************************
2716  get_user_info_17.
2717  *************************************************************************/
2718
2719 static NTSTATUS get_user_info_17(TALLOC_CTX *mem_ctx,
2720                                  struct samr_UserInfo17 *r,
2721                                  struct samu *pw)
2722 {
2723         unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2724
2725         return NT_STATUS_OK;
2726 }
2727
2728 /*************************************************************************
2729  get_user_info_18. OK - this is the killer as it gives out password info.
2730  Ensure that this is only allowed on an encrypted connection with a root
2731  user. JRA.
2732  *************************************************************************/
2733
2734 static NTSTATUS get_user_info_18(pipes_struct *p,
2735                                  TALLOC_CTX *mem_ctx,
2736                                  struct samr_UserInfo18 *r,
2737                                  DOM_SID *user_sid)
2738 {
2739         struct samu *smbpass=NULL;
2740         bool ret;
2741
2742         ZERO_STRUCTP(r);
2743
2744         if (p->auth.auth_type != PIPE_AUTH_TYPE_NTLMSSP || p->auth.auth_type != PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) {
2745                 return NT_STATUS_ACCESS_DENIED;
2746         }
2747
2748         if (p->auth.auth_level != DCERPC_AUTH_LEVEL_PRIVACY) {
2749                 return NT_STATUS_ACCESS_DENIED;
2750         }
2751
2752         /*
2753          * Do *NOT* do become_root()/unbecome_root() here ! JRA.
2754          */
2755
2756         if ( !(smbpass = samu_new( mem_ctx )) ) {
2757                 return NT_STATUS_NO_MEMORY;
2758         }
2759
2760         ret = pdb_getsampwsid(smbpass, user_sid);
2761
2762         if (ret == False) {
2763                 DEBUG(4, ("User %s not found\n", sid_string_dbg(user_sid)));
2764                 TALLOC_FREE(smbpass);
2765                 return (geteuid() == sec_initial_uid()) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
2766         }
2767
2768         DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
2769
2770         if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
2771                 TALLOC_FREE(smbpass);
2772                 return NT_STATUS_ACCOUNT_DISABLED;
2773         }
2774
2775         r->lm_pwd_active = true;
2776         r->nt_pwd_active = true;
2777         memcpy(r->lm_pwd.hash, pdb_get_lanman_passwd(smbpass), 16);
2778         memcpy(r->nt_pwd.hash, pdb_get_nt_passwd(smbpass), 16);
2779         r->password_expired = 0; /* FIXME */
2780
2781         TALLOC_FREE(smbpass);
2782
2783         return NT_STATUS_OK;
2784 }
2785
2786 /*************************************************************************
2787  get_user_info_20
2788  *************************************************************************/
2789
2790 static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx,
2791                                  struct samr_UserInfo20 *r,
2792                                  struct samu *sampass)
2793 {
2794         const char *munged_dial = NULL;
2795         DATA_BLOB blob;
2796         NTSTATUS status;
2797         struct lsa_BinaryString *parameters = NULL;
2798
2799         ZERO_STRUCTP(r);
2800
2801         munged_dial = pdb_get_munged_dial(sampass);
2802
2803         DEBUG(3,("User:[%s] has [%s] (length: %d)\n", pdb_get_username(sampass),
2804                 munged_dial, (int)strlen(munged_dial)));
2805
2806         if (munged_dial) {
2807                 blob = base64_decode_data_blob(munged_dial);
2808         } else {
2809                 blob = data_blob_string_const_null("");
2810         }
2811
2812         status = init_samr_parameters_string(mem_ctx, &blob, &parameters);
2813         data_blob_free(&blob);
2814         if (!NT_STATUS_IS_OK(status)) {
2815                 return status;
2816         }
2817
2818         r->parameters = *parameters;
2819
2820         return NT_STATUS_OK;
2821 }
2822
2823
2824 /*************************************************************************
2825  get_user_info_21
2826  *************************************************************************/
2827
2828 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx,
2829                                  struct samr_UserInfo21 *r,
2830                                  struct samu *pw,
2831                                  DOM_SID *domain_sid,
2832                                  uint32_t acc_granted)
2833 {
2834         NTSTATUS status;
2835         const DOM_SID *sid_user, *sid_group;
2836         uint32_t rid, primary_gid;
2837         NTTIME force_password_change;
2838         time_t must_change_time;
2839         struct lsa_BinaryString *parameters = NULL;
2840         const char *munged_dial = NULL;
2841         DATA_BLOB blob;
2842
2843         ZERO_STRUCTP(r);
2844
2845         sid_user = pdb_get_user_sid(pw);
2846
2847         if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2848                 DEBUG(0, ("get_user_info_21: User %s has SID %s, \nwhich conflicts with "
2849                           "the domain sid %s.  Failing operation.\n",
2850                           pdb_get_username(pw), sid_string_dbg(sid_user),
2851                           sid_string_dbg(domain_sid)));
2852                 return NT_STATUS_UNSUCCESSFUL;
2853         }
2854
2855         become_root();
2856         sid_group = pdb_get_group_sid(pw);
2857         unbecome_root();
2858
2859         if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2860                 DEBUG(0, ("get_user_info_21: User %s has Primary Group SID %s, \n"
2861                           "which conflicts with the domain sid %s.  Failing operation.\n",
2862                           pdb_get_username(pw), sid_string_dbg(sid_group),
2863                           sid_string_dbg(domain_sid)));
2864                 return NT_STATUS_UNSUCCESSFUL;
2865         }
2866
2867         unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2868         unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2869         unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2870         unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2871         unix_to_nt_time(&r->allow_password_change, pdb_get_pass_can_change_time(pw));
2872
2873         must_change_time = pdb_get_pass_must_change_time(pw);
2874         if (must_change_time == get_time_t_max()) {
2875                 unix_to_nt_time_abs(&force_password_change, must_change_time);
2876         } else {
2877                 unix_to_nt_time(&force_password_change, must_change_time);
2878         }
2879
2880         munged_dial = pdb_get_munged_dial(pw);
2881         if (munged_dial) {
2882                 blob = base64_decode_data_blob(munged_dial);
2883         } else {
2884                 blob = data_blob_string_const_null("");
2885         }
2886
2887         status = init_samr_parameters_string(mem_ctx, &blob, &parameters);
2888         data_blob_free(&blob);
2889         if (!NT_STATUS_IS_OK(status)) {
2890                 return status;
2891         }
2892
2893         r->force_password_change        = force_password_change;
2894
2895         r->account_name.string          = talloc_strdup(mem_ctx, pdb_get_username(pw));
2896         r->full_name.string             = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2897         r->home_directory.string        = talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2898         r->home_drive.string            = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2899         r->logon_script.string          = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2900         r->profile_path.string          = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2901         r->description.string           = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2902         r->workstations.string          = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2903         r->comment.string               = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2904
2905         r->logon_hours                  = get_logon_hours_from_pdb(mem_ctx, pw);
2906         r->parameters                   = *parameters;
2907         r->rid                          = rid;
2908         r->primary_gid                  = primary_gid;
2909         r->acct_flags                   = pdb_get_acct_ctrl(pw);
2910         r->bad_password_count           = pdb_get_bad_password_count(pw);
2911         r->logon_count                  = pdb_get_logon_count(pw);
2912         r->fields_present               = pdb_build_fields_present(pw);
2913         r->password_expired             = (pdb_get_pass_must_change_time(pw) == 0) ?
2914                                                 PASS_MUST_CHANGE_AT_NEXT_LOGON : 0;
2915         r->country_code                 = 0;
2916         r->code_page                    = 0;
2917         r->lm_password_set              = 0;
2918         r->nt_password_set              = 0;
2919
2920 #if 0
2921
2922         /*
2923           Look at a user on a real NT4 PDC with usrmgr, press
2924           'ok'. Then you will see that fields_present is set to
2925           0x08f827fa. Look at the user immediately after that again,
2926           and you will see that 0x00fffff is returned. This solves
2927           the problem that you get access denied after having looked
2928           at the user.
2929           -- Volker
2930         */
2931
2932 #endif
2933
2934
2935         return NT_STATUS_OK;
2936 }
2937
2938 /*******************************************************************
2939  _samr_QueryUserInfo
2940  ********************************************************************/
2941
2942 NTSTATUS _samr_QueryUserInfo(pipes_struct *p,
2943                              struct samr_QueryUserInfo *r)
2944 {
2945         NTSTATUS status;
2946         union samr_UserInfo *user_info = NULL;
2947         struct samr_user_info *uinfo;
2948         DOM_SID domain_sid;
2949         uint32 rid;
2950         bool ret = false;
2951         struct samu *pwd = NULL;
2952         uint32_t acc_required, acc_granted;
2953
2954         switch (r->in.level) {
2955         case 1: /* UserGeneralInformation */
2956                 /* USER_READ_GENERAL */
2957                 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC;
2958                 break;
2959         case 2: /* UserPreferencesInformation */
2960                 /* USER_READ_PREFERENCES | USER_READ_GENERAL */
2961                 acc_required = SAMR_USER_ACCESS_GET_LOCALE |
2962                                SAMR_USER_ACCESS_GET_NAME_ETC;
2963                 break;
2964         case 3: /* UserLogonInformation */
2965                 /* USER_READ_GENERAL | USER_READ_PREFERENCES | USER_READ_LOGON | USER_READ_ACCOUNT */
2966                 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC |
2967                                SAMR_USER_ACCESS_GET_LOCALE |
2968                                SAMR_USER_ACCESS_GET_LOGONINFO |
2969                                SAMR_USER_ACCESS_GET_ATTRIBUTES;
2970                 break;
2971         case 4: /* UserLogonHoursInformation */
2972                 /* USER_READ_LOGON */
2973                 acc_required = SAMR_USER_ACCESS_GET_LOGONINFO;
2974                 break;
2975         case 5: /* UserAccountInformation */
2976                 /* USER_READ_GENERAL | USER_READ_PREFERENCES | USER_READ_LOGON | USER_READ_ACCOUNT */
2977                 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC |
2978                                SAMR_USER_ACCESS_GET_LOCALE |
2979                                SAMR_USER_ACCESS_GET_LOGONINFO |
2980                                SAMR_USER_ACCESS_GET_ATTRIBUTES;
2981                 break;
2982         case 6: /* UserNameInformation */
2983         case 7: /* UserAccountNameInformation */
2984         case 8: /* UserFullNameInformation */
2985         case 9: /* UserPrimaryGroupInformation */
2986         case 13: /* UserAdminCommentInformation */
2987                 /* USER_READ_GENERAL */
2988                 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC;
2989                 break;
2990         case 10: /* UserHomeInformation */
2991         case 11: /* UserScriptInformation */
2992         case 12: /* UserProfileInformation */
2993         case 14: /* UserWorkStationsInformation */
2994                 /* USER_READ_LOGON */
2995                 acc_required = SAMR_USER_ACCESS_GET_LOGONINFO;
2996                 break;
2997         case 16: /* UserControlInformation */
2998         case 17: /* UserExpiresInformation */
2999         case 20: /* UserParametersInformation */
3000                 /* USER_READ_ACCOUNT */
3001                 acc_required = SAMR_USER_ACCESS_GET_ATTRIBUTES;
3002                 break;
3003         case 21: /* UserAllInformation */
3004                 /* FIXME! - gd */
3005                 acc_required = SAMR_USER_ACCESS_GET_ATTRIBUTES;
3006                 break;
3007         case 18: /* UserInternal1Information */
3008                 /* FIXME! - gd */
3009                 acc_required = SAMR_USER_ACCESS_GET_ATTRIBUTES;
3010                 break;
3011         case 23: /* UserInternal4Information */
3012         case 24: /* UserInternal4InformationNew */
3013         case 25: /* UserInternal4InformationNew */
3014         case 26: /* UserInternal5InformationNew */
3015         default:
3016                 return NT_STATUS_INVALID_INFO_CLASS;
3017                 break;
3018         }
3019
3020         uinfo = policy_handle_find(p, r->in.user_handle,
3021                                    acc_required, &acc_granted,
3022                                    struct samr_user_info, &status);
3023         if (!NT_STATUS_IS_OK(status)) {
3024                 return status;
3025         }
3026
3027         domain_sid = uinfo->sid;
3028
3029         sid_split_rid(&domain_sid, &rid);
3030
3031         if (!sid_check_is_in_our_domain(&uinfo->sid))
3032                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
3033
3034         DEBUG(5,("_samr_QueryUserInfo: sid:%s\n",
3035                  sid_string_dbg(&uinfo->sid)));
3036
3037         user_info = TALLOC_ZERO_P(p->mem_ctx, union samr_UserInfo);
3038         if (!user_info) {
3039                 return NT_STATUS_NO_MEMORY;
3040         }
3041
3042         DEBUG(5,("_samr_QueryUserInfo: user info level: %d\n", r->in.level));
3043
3044         if (!(pwd = samu_new(p->mem_ctx))) {
3045                 return NT_STATUS_NO_MEMORY;
3046         }
3047
3048         become_root();
3049         ret = pdb_getsampwsid(pwd, &uinfo->sid);
3050         unbecome_root();
3051
3052         if (ret == false) {
3053                 DEBUG(4,("User %s not found\n", sid_string_dbg(&uinfo->sid)));
3054                 TALLOC_FREE(pwd);
3055                 return NT_STATUS_NO_SUCH_USER;
3056         }
3057
3058         DEBUG(3,("User:[%s]\n", pdb_get_username(pwd)));
3059
3060         samr_clear_sam_passwd(pwd);
3061
3062         switch (r->in.level) {
3063         case 1:
3064                 status = get_user_info_1(p->mem_ctx, &user_info->info1, pwd, &domain_sid);
3065                 break;
3066         case 2:
3067                 status = get_user_info_2(p->mem_ctx, &user_info->info2, pwd);
3068                 break;
3069         case 3:
3070                 status = get_user_info_3(p->mem_ctx, &user_info->info3, pwd, &domain_sid);
3071                 break;
3072         case 4:
3073                 status = get_user_info_4(p->mem_ctx, &user_info->info4, pwd);
3074                 break;
3075         case 5:
3076                 status = get_user_info_5(p->mem_ctx, &user_info->info5, pwd, &domain_sid);
3077                 break;
3078         case 6:
3079                 status = get_user_info_6(p->mem_ctx, &user_info->info6, pwd);
3080                 break;
3081         case 7:
3082                 status = get_user_info_7(p->mem_ctx, &user_info->info7, pwd);
3083                 break;
3084         case 8:
3085                 status = get_user_info_8(p->mem_ctx, &user_info->info8, pwd);
3086                 break;
3087         case 9:
3088                 status = get_user_info_9(p->mem_ctx, &user_info->info9, pwd);
3089                 break;
3090         case 10:
3091                 status = get_user_info_10(p->mem_ctx, &user_info->info10, pwd);
3092                 break;
3093         case 11:
3094                 status = get_user_info_11(p->mem_ctx, &user_info->info11, pwd);
3095                 break;
3096         case 12:
3097                 status = get_user_info_12(p->mem_ctx, &user_info->info12, pwd);
3098                 break;
3099         case 13:
3100                 status = get_user_info_13(p->mem_ctx, &user_info->info13, pwd);
3101                 break;
3102         case 14:
3103                 status = get_user_info_14(p->mem_ctx, &user_info->info14, pwd);
3104                 break;
3105         case 16:
3106                 status = get_user_info_16(p->mem_ctx, &user_info->info16, pwd);
3107                 break;
3108         case 17:
3109                 status = get_user_info_17(p->mem_ctx, &user_info->info17, pwd);
3110                 break;
3111         case 18:
3112                 /* level 18 is special */
3113                 status = get_user_info_18(p, p->mem_ctx, &user_info->info18,
3114                                           &uinfo->sid);
3115                 break;
3116         case 20:
3117                 status = get_user_info_20(p->mem_ctx, &user_info->info20, pwd);
3118                 break;
3119         case 21:
3120                 status = get_user_info_21(p->mem_ctx, &user_info->info21, pwd, &domain_sid, acc_granted);
3121                 break;
3122         default:
3123                 status = NT_STATUS_INVALID_INFO_CLASS;
3124                 break;
3125         }
3126
3127         if (!NT_STATUS_IS_OK(status)) {
3128                 goto done;
3129         }
3130
3131         *r->out.info = user_info;
3132
3133  done:
3134         TALLOC_FREE(pwd);
3135
3136         DEBUG(5,("_samr_QueryUserInfo: %d\n", __LINE__));
3137
3138         return status;
3139 }
3140
3141 /****************************************************************
3142 ****************************************************************/
3143
3144 NTSTATUS _samr_QueryUserInfo2(pipes_struct *p,
3145                               struct samr_QueryUserInfo2 *r)
3146 {
3147         struct samr_QueryUserInfo u;
3148
3149         u.in.user_handle        = r->in.user_handle;
3150         u.in.level              = r->in.level;
3151         u.out.info              = r->out.info;
3152
3153         return _samr_QueryUserInfo(p, &u);
3154 }
3155
3156 /*******************************************************************
3157  _samr_GetGroupsForUser
3158  ********************************************************************/
3159
3160 NTSTATUS _samr_GetGroupsForUser(pipes_struct *p,
3161                                 struct samr_GetGroupsForUser *r)
3162 {
3163         struct samr_user_info *uinfo;
3164         struct samu *sam_pass=NULL;
3165         DOM_SID *sids;
3166         struct samr_RidWithAttribute dom_gid;
3167         struct samr_RidWithAttribute *gids = NULL;
3168         uint32 primary_group_rid;
3169         size_t num_groups = 0;
3170         gid_t *unix_gids;
3171         size_t i, num_gids;
3172         bool ret;
3173         NTSTATUS result;
3174         bool success = False;
3175
3176         struct samr_RidWithAttributeArray *rids = NULL;
3177
3178         /*
3179          * from the SID in the request:
3180          * we should send back the list of DOMAIN GROUPS
3181          * the user is a member of
3182          *
3183          * and only the DOMAIN GROUPS
3184          * no ALIASES !!! neither aliases of the domain
3185          * nor aliases of the builtin SID
3186          *
3187          * JFM, 12/2/2001
3188          */
3189
3190         DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
3191
3192         uinfo = policy_handle_find(p, r->in.user_handle,
3193                                    SAMR_USER_ACCESS_GET_GROUPS, NULL,
3194                                    struct samr_user_info, &result);
3195         if (!NT_STATUS_IS_OK(result)) {
3196                 return result;
3197         }
3198
3199         rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidWithAttributeArray);
3200         if (!rids) {
3201                 return NT_STATUS_NO_MEMORY;
3202         }
3203
3204         if (!sid_check_is_in_our_domain(&uinfo->sid))
3205                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
3206
3207         if ( !(sam_pass = samu_new( p->mem_ctx )) ) {
3208                 return NT_STATUS_NO_MEMORY;
3209         }
3210
3211         become_root();
3212         ret = pdb_getsampwsid(sam_pass, &uinfo->sid);
3213         unbecome_root();
3214
3215         if (!ret) {
3216                 DEBUG(10, ("pdb_getsampwsid failed for %s\n",
3217                            sid_string_dbg(&uinfo->sid)));
3218                 return NT_STATUS_NO_SUCH_USER;
3219         }
3220
3221         sids = NULL;
3222
3223         /* make both calls inside the root block */
3224         become_root();
3225         result = pdb_enum_group_memberships(p->mem_ctx, sam_pass,
3226                                             &sids, &unix_gids, &num_groups);
3227         if ( NT_STATUS_IS_OK(result) ) {
3228                 success = sid_peek_check_rid(get_global_sam_sid(),
3229                                              pdb_get_group_sid(sam_pass),
3230                                              &primary_group_rid);
3231         }
3232         unbecome_root();
3233
3234         if (!NT_STATUS_IS_OK(result)) {
3235                 DEBUG(10, ("pdb_enum_group_memberships failed for %s\n",
3236                            sid_string_dbg(&uinfo->sid)));
3237                 return result;
3238         }
3239
3240         if ( !success ) {
3241                 DEBUG(5, ("Group sid %s for user %s not in our domain\n",
3242                           sid_string_dbg(pdb_get_group_sid(sam_pass)),
3243                           pdb_get_username(sam_pass)));
3244                 TALLOC_FREE(sam_pass);
3245                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
3246         }
3247
3248         gids = NULL;
3249         num_gids = 0;
3250
3251         dom_gid.attributes = (SE_GROUP_MANDATORY|SE_GROUP_ENABLED_BY_DEFAULT|
3252                               SE_GROUP_ENABLED);
3253         dom_gid.rid = primary_group_rid;
3254         ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
3255
3256         for (i=0; i<num_groups; i++) {
3257
3258                 if (!sid_peek_check_rid(get_global_sam_sid(),
3259                                         &(sids[i]), &dom_gid.rid)) {
3260                         DEBUG(10, ("Found sid %s not in our domain\n",
3261                                    sid_string_dbg(&sids[i])));
3262                         continue;
3263                 }
3264
3265                 if (dom_gid.rid == primary_group_rid) {
3266                         /* We added the primary group directly from the
3267                          * sam_account. The other SIDs are unique from
3268                          * enum_group_memberships */
3269                         continue;
3270                 }
3271
3272                 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
3273         }
3274
3275         rids->count = num_gids;
3276         rids->rids = gids;
3277
3278         *r->out.rids = rids;
3279
3280         DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
3281
3282         return result;
3283 }
3284
3285 /*******************************************************************
3286  ********************************************************************/
3287
3288 static uint32_t samr_get_server_role(void)
3289 {
3290         uint32_t role = ROLE_DOMAIN_PDC;
3291
3292         if (lp_server_role() == ROLE_DOMAIN_BDC) {
3293                 role = ROLE_DOMAIN_BDC;
3294         }
3295
3296         return role;
3297 }
3298
3299 /*******************************************************************
3300  ********************************************************************/
3301
3302 static NTSTATUS query_dom_info_1(TALLOC_CTX *mem_ctx,
3303                                  struct samr_DomInfo1 *r)
3304 {
3305         uint32_t account_policy_temp;
3306         time_t u_expire, u_min_age;
3307
3308         become_root();
3309
3310         /* AS ROOT !!! */
3311
3312         pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN, &account_policy_temp);
3313         r->min_password_length = account_policy_temp;
3314
3315         pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &account_policy_temp);
3316         r->password_history_length = account_policy_temp;
3317
3318         pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
3319                                &r->password_properties);
3320
3321         pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, &account_policy_temp);
3322         u_expire = account_policy_temp;
3323
3324         pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, &account_policy_temp);
3325         u_min_age = account_policy_temp;
3326
3327         /* !AS ROOT */
3328
3329         unbecome_root();
3330
3331         unix_to_nt_time_abs((NTTIME *)&r->max_password_age, u_expire);
3332         unix_to_nt_time_abs((NTTIME *)&r->min_password_age, u_min_age);
3333
3334         if (lp_check_password_script() && *lp_check_password_script()) {
3335                 r->password_properties |= DOMAIN_PASSWORD_COMPLEX;
3336         }
3337
3338         return NT_STATUS_OK;
3339 }
3340
3341 /*******************************************************************
3342  ********************************************************************/
3343
3344 static NTSTATUS query_dom_info_2(TALLOC_CTX *mem_ctx,
3345                                  struct samr_DomGeneralInformation *r,
3346                                  struct samr_domain_info *dinfo)
3347 {
3348         uint32_t u_logout;
3349         time_t seq_num;
3350
3351         become_root();
3352
3353         /* AS ROOT !!! */
3354
3355         r->num_users    = count_sam_users(dinfo->disp_info, ACB_NORMAL);
3356         r->num_groups   = count_sam_groups(dinfo->disp_info);
3357         r->num_aliases  = count_sam_aliases(dinfo->disp_info);
3358
3359         pdb_get_account_policy(PDB_POLICY_TIME_TO_LOGOUT, &u_logout);
3360
3361         unix_to_nt_time_abs(&r->force_logoff_time, u_logout);
3362
3363         if (!pdb_get_seq_num(&seq_num)) {
3364                 seq_num = time(NULL);
3365         }
3366
3367         /* !AS ROOT */
3368
3369         unbecome_root();
3370
3371         r->oem_information.string       = lp_serverstring();
3372         r->domain_name.string           = lp_workgroup();
3373         r->primary.string               = global_myname();
3374         r->sequence_num                 = seq_num;
3375         r->domain_server_state          = DOMAIN_SERVER_ENABLED;
3376         r->role                         = samr_get_server_role();
3377         r->unknown3                     = 1;
3378
3379         return NT_STATUS_OK;
3380 }
3381
3382 /*******************************************************************
3383  ********************************************************************/
3384
3385 static NTSTATUS query_dom_info_3(TALLOC_CTX *mem_ctx,
3386                                  struct samr_DomInfo3 *r)
3387 {
3388         uint32_t u_logout;
3389
3390         become_root();
3391
3392         /* AS ROOT !!! */
3393
3394         {
3395                 uint32_t ul;
3396                 pdb_get_account_policy(PDB_POLICY_TIME_TO_LOGOUT, &ul);
3397                 u_logout = (time_t)ul;
3398         }
3399
3400         /* !AS ROOT */
3401
3402         unbecome_root();
3403
3404         unix_to_nt_time_abs(&r->force_logoff_time, u_logout);
3405
3406         return NT_STATUS_OK;
3407 }
3408
3409 /*******************************************************************
3410  ********************************************************************/
3411
3412 static NTSTATUS query_dom_info_4(TALLOC_CTX *mem_ctx,
3413                                  struct samr_DomOEMInformation *r)
3414 {
3415         r->oem_information.string = lp_serverstring();
3416
3417         return NT_STATUS_OK;
3418 }
3419
3420 /*******************************************************************
3421  ********************************************************************/
3422
3423 static NTSTATUS query_dom_info_5(TALLOC_CTX *mem_ctx,
3424                                  struct samr_DomInfo5 *r)
3425 {
3426         r->domain_name.string = get_global_sam_name();
3427
3428         return NT_STATUS_OK;
3429 }
3430
3431 /*******************************************************************
3432  ********************************************************************/
3433
3434 static NTSTATUS query_dom_info_6(TALLOC_CTX *mem_ctx,
3435                                  struct samr_DomInfo6 *r)
3436 {
3437         /* NT returns its own name when a PDC. win2k and later
3438          * only the name of the PDC if itself is a BDC (samba4
3439          * idl) */
3440         r->primary.string = global_myname();
3441
3442         return NT_STATUS_OK;
3443 }
3444
3445 /*******************************************************************
3446  ********************************************************************/
3447
3448 static NTSTATUS query_dom_info_7(TALLOC_CTX *mem_ctx,
3449                                  struct samr_DomInfo7 *r)
3450 {
3451         r->role = samr_get_server_role();
3452
3453         return NT_STATUS_OK;
3454 }
3455
3456 /*******************************************************************
3457  ********************************************************************/
3458
3459 static NTSTATUS query_dom_info_8(TALLOC_CTX *mem_ctx,
3460                                  struct samr_DomInfo8 *r)
3461 {
3462         time_t seq_num;
3463
3464         become_root();
3465
3466         /* AS ROOT !!! */
3467
3468         if (!pdb_get_seq_num(&seq_num)) {
3469                 seq_num = time(NULL);
3470         }
3471
3472         /* !AS ROOT */
3473
3474         unbecome_root();
3475
3476         r->sequence_num = seq_num;
3477         r->domain_create_time = 0;
3478
3479         return NT_STATUS_OK;
3480 }
3481
3482 /*******************************************************************
3483  ********************************************************************/
3484
3485 static NTSTATUS query_dom_info_9(TALLOC_CTX *mem_ctx,
3486                                  struct samr_DomInfo9 *r)
3487 {
3488         r->domain_server_state = DOMAIN_SERVER_ENABLED;
3489
3490         return NT_STATUS_OK;
3491 }
3492
3493 /*******************************************************************
3494  ********************************************************************/
3495
3496 static NTSTATUS query_dom_info_11(TALLOC_CTX *mem_ctx,
3497                                   struct samr_DomGeneralInformation2 *r,
3498                                   struct samr_domain_info *dinfo)
3499 {
3500         NTSTATUS status;
3501         uint32_t account_policy_temp;
3502         time_t u_lock_duration, u_reset_time;
3503
3504         status = query_dom_info_2(mem_ctx, &r->general, dinfo);
3505         if (!NT_STATUS_IS_OK(status)) {
3506                 return status;
3507         }
3508
3509         /* AS ROOT !!! */
3510
3511         become_root();
3512
3513         pdb_get_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, &account_policy_temp);
3514         u_lock_duration = account_policy_temp;
3515         if (u_lock_duration != -1) {
3516                 u_lock_duration *= 60;
3517         }
3518
3519         pdb_get_account_policy(PDB_POLICY_RESET_COUNT_TIME, &account_policy_temp);
3520         u_reset_time = account_policy_temp * 60;
3521
3522         pdb_get_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
3523         r->lockout_threshold = account_policy_temp;
3524
3525         /* !AS ROOT */
3526
3527         unbecome_root();
3528
3529         unix_to_nt_time_abs(&r->lockout_duration, u_lock_duration);
3530         unix_to_nt_time_abs(&r->lockout_window, u_reset_time);
3531
3532         return NT_STATUS_OK;
3533 }
3534
3535 /*******************************************************************
3536  ********************************************************************/
3537
3538 static NTSTATUS query_dom_info_12(TALLOC_CTX *mem_ctx,
3539                                   struct samr_DomInfo12 *r)
3540 {
3541         uint32_t account_policy_temp;
3542         time_t u_lock_duration, u_reset_time;
3543
3544         become_root();
3545
3546         /* AS ROOT !!! */
3547
3548         pdb_get_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, &account_policy_temp);
3549         u_lock_duration = account_policy_temp;
3550         if (u_lock_duration != -1) {
3551                 u_lock_duration *= 60;
3552         }
3553
3554         pdb_get_account_policy(PDB_POLICY_RESET_COUNT_TIME, &account_policy_temp);
3555         u_reset_time = account_policy_temp * 60;
3556
3557         pdb_get_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
3558         r->lockout_threshold = account_policy_temp;
3559
3560         /* !AS ROOT */
3561
3562         unbecome_root();
3563
3564         unix_to_nt_time_abs(&r->lockout_duration, u_lock_duration);
3565         unix_to_nt_time_abs(&r->lockout_window, u_reset_time);
3566
3567         return NT_STATUS_OK;
3568 }
3569
3570 /*******************************************************************
3571  ********************************************************************/
3572
3573 static NTSTATUS query_dom_info_13(TALLOC_CTX *mem_ctx,
3574                                   struct samr_DomInfo13 *r)
3575 {
3576         time_t seq_num;
3577
3578         become_root();
3579
3580         /* AS ROOT !!! */
3581
3582         if (!pdb_get_seq_num(&seq_num)) {
3583                 seq_num = time(NULL);
3584         }
3585
3586         /* !AS ROOT */
3587
3588         unbecome_root();
3589
3590         r->sequence_num = seq_num;
3591         r->domain_create_time = 0;
3592         r->modified_count_at_last_promotion = 0;
3593
3594         return NT_STATUS_OK;
3595 }
3596
3597 /*******************************************************************
3598  _samr_QueryDomainInfo
3599  ********************************************************************/
3600
3601 NTSTATUS _samr_QueryDomainInfo(pipes_struct *p,
3602                                struct samr_QueryDomainInfo *r)
3603 {
3604         NTSTATUS status = NT_STATUS_OK;
3605         struct samr_domain_info *dinfo;
3606         union samr_DomainInfo *dom_info;
3607
3608         uint32_t acc_required;
3609
3610         DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__));
3611
3612         switch (r->in.level) {
3613         case 1: /* DomainPasswordInformation */
3614         case 12: /* DomainLockoutInformation */
3615                 /* DOMAIN_READ_PASSWORD_PARAMETERS */
3616                 acc_required = SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1;
3617                 break;
3618         case 11: /* DomainGeneralInformation2 */
3619                 /* DOMAIN_READ_PASSWORD_PARAMETERS |
3620                  * DOMAIN_READ_OTHER_PARAMETERS */
3621                 acc_required = SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
3622                                SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2;
3623                 break;
3624         case 2: /* DomainGeneralInformation */
3625         case 3: /* DomainLogoffInformation */
3626         case 4: /* DomainOemInformation */
3627         case 5: /* DomainReplicationInformation */
3628         case 6: /* DomainReplicationInformation */
3629         case 7: /* DomainServerRoleInformation */
3630         case 8: /* DomainModifiedInformation */
3631         case 9: /* DomainStateInformation */
3632         case 10: /* DomainUasInformation */
3633         case 13: /* DomainModifiedInformation2 */
3634                 /* DOMAIN_READ_OTHER_PARAMETERS */
3635                 acc_required = SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2;
3636                 break;
3637         default:
3638                 return NT_STATUS_INVALID_INFO_CLASS;
3639         }
3640
3641         dinfo = policy_handle_find(p, r->in.domain_handle,
3642                                    acc_required, NULL,
3643                                    struct samr_domain_info, &status);
3644         if (!NT_STATUS_IS_OK(status)) {
3645                 return status;
3646         }
3647
3648         dom_info = TALLOC_ZERO_P(p->mem_ctx, union samr_DomainInfo);
3649         if (!dom_info) {
3650                 return NT_STATUS_NO_MEMORY;
3651         }
3652
3653         switch (r->in.level) {
3654                 case 1:
3655                         status = query_dom_info_1(p->mem_ctx, &dom_info->info1);
3656                         break;
3657                 case 2:
3658                         status = query_dom_info_2(p->mem_ctx, &dom_info->general, dinfo);
3659                         break;
3660                 case 3:
3661                         status = query_dom_info_3(p->mem_ctx, &dom_info->info3);
3662                         break;
3663                 case 4:
3664                         status = query_dom_info_4(p->mem_ctx, &dom_info->oem);
3665                         break;
3666                 case 5:
3667                         status = query_dom_info_5(p->mem_ctx, &dom_info->info5);
3668                         break;
3669                 case 6:
3670                         status = query_dom_info_6(p->mem_ctx, &dom_info->info6);
3671                         break;
3672                 case 7:
3673                         status = query_dom_info_7(p->mem_ctx, &dom_info->info7);
3674                         break;
3675                 case 8:
3676                         status = query_dom_info_8(p->mem_ctx, &dom_info->info8);
3677                         break;
3678                 case 9:
3679                         status = query_dom_info_9(p->mem_ctx, &dom_info->info9);
3680                         break;
3681                 case 11:
3682                         status = query_dom_info_11(p->mem_ctx, &dom_info->general2, dinfo);
3683                         break;
3684                 case 12:
3685                         status = query_dom_info_12(p->mem_ctx, &dom_info->info12);
3686                         break;
3687                 case 13:
3688                         status = query_dom_info_13(p->mem_ctx, &dom_info->info13);
3689                         break;
3690                 default:
3691                         return NT_STATUS_INVALID_INFO_CLASS;
3692         }
3693
3694         if (!NT_STATUS_IS_OK(status)) {
3695                 return status;
3696         }
3697
3698         *r->out.info = dom_info;
3699
3700         DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__));
3701
3702         return status;
3703 }
3704
3705 /* W2k3 seems to use the same check for all 3 objects that can be created via
3706  * SAMR, if you try to create for example "Dialup" as an alias it says
3707  * "NT_STATUS_USER_EXISTS". This is racy, but we can't really lock the user
3708  * database. */
3709
3710 static NTSTATUS can_create(TALLOC_CTX *mem_ctx, const char *new_name)
3711 {
3712         enum lsa_SidType type;
3713         bool result;
3714
3715         DEBUG(10, ("Checking whether [%s] can be created\n", new_name));
3716
3717         become_root();
3718         /* Lookup in our local databases (LOOKUP_NAME_REMOTE not set)
3719          * whether the name already exists */
3720         result = lookup_name(mem_ctx, new_name, LOOKUP_NAME_LOCAL,
3721                              NULL, NULL, NULL, &type);
3722         unbecome_root();
3723
3724         if (!result) {
3725                 DEBUG(10, ("%s does not exist, can create it\n", new_name));
3726                 return NT_STATUS_OK;
3727         }
3728
3729         DEBUG(5, ("trying to create %s, exists as %s\n",
3730                   new_name, sid_type_lookup(type)));
3731
3732         if (type == SID_NAME_DOM_GRP) {
3733                 return NT_STATUS_GROUP_EXISTS;
3734         }
3735         if (type == SID_NAME_ALIAS) {
3736                 return NT_STATUS_ALIAS_EXISTS;
3737         }
3738
3739         /* Yes, the default is NT_STATUS_USER_EXISTS */
3740         return NT_STATUS_USER_EXISTS;
3741 }
3742
3743 /*******************************************************************
3744  _samr_CreateUser2
3745  ********************************************************************/
3746
3747 NTSTATUS _samr_CreateUser2(pipes_struct *p,
3748                            struct samr_CreateUser2 *r)
3749 {
3750         const char *account = NULL;
3751         DOM_SID sid;
3752         uint32_t acb_info = r->in.acct_flags;
3753         struct samr_domain_info *dinfo;
3754         struct samr_user_info *uinfo;
3755         NTSTATUS nt_status;
3756         uint32 acc_granted;
3757         SEC_DESC *psd;
3758         size_t    sd_size;
3759         /* check this, when giving away 'add computer to domain' privs */
3760         uint32    des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
3761         bool can_add_account = False;
3762         SE_PRIV se_rights;
3763
3764         dinfo = policy_handle_find(p, r->in.domain_handle,
3765                                    SAMR_DOMAIN_ACCESS_CREATE_USER, NULL,
3766                                    struct samr_domain_info, &nt_status);
3767         if (!NT_STATUS_IS_OK(nt_status)) {
3768                 return nt_status;
3769         }
3770
3771         if (sid_check_is_builtin(&dinfo->sid)) {
3772                 DEBUG(5,("_samr_CreateUser2: Refusing user create in BUILTIN\n"));
3773                 return NT_STATUS_ACCESS_DENIED;
3774         }
3775
3776         if (!(acb_info == ACB_NORMAL || acb_info == ACB_DOMTRUST ||
3777               acb_info == ACB_WSTRUST || acb_info == ACB_SVRTRUST)) {
3778                 /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if
3779                    this parameter is not an account type */
3780                 return NT_STATUS_INVALID_PARAMETER;
3781         }
3782
3783         account = r->in.account_name->string;
3784         if (account == NULL) {
3785                 return NT_STATUS_NO_MEMORY;
3786         }
3787
3788         nt_status = can_create(p->mem_ctx, account);
3789         if (!NT_STATUS_IS_OK(nt_status)) {
3790                 return nt_status;
3791         }
3792
3793         /* determine which user right we need to check based on the acb_info */
3794
3795         if (geteuid() == sec_initial_uid()) {
3796                 se_priv_copy(&se_rights, &se_priv_none);
3797                 can_add_account = true;
3798         } else if (acb_info & ACB_WSTRUST) {
3799                 se_priv_copy(&se_rights, &se_machine_account);
3800                 can_add_account = user_has_privileges(
3801                         p->server_info->ptok, &se_rights );
3802         } else if (acb_info & ACB_NORMAL &&
3803                   (account[strlen(account)-1] != '$')) {
3804                 /* usrmgr.exe (and net rpc trustdom grant) creates a normal user
3805                    account for domain trusts and changes the ACB flags later */
3806                 se_priv_copy(&se_rights, &se_add_users);
3807                 can_add_account = user_has_privileges(
3808                         p->server_info->ptok, &se_rights );
3809         } else if (lp_enable_privileges()) {
3810                 /* implicit assumption of a BDC or domain trust account here
3811                  * (we already check the flags earlier) */
3812                 /* only Domain Admins can add a BDC or domain trust */
3813                 se_priv_copy(&se_rights, &se_priv_none);
3814                 can_add_account = nt_token_check_domain_rid(
3815                         p->server_info->ptok,
3816                         DOMAIN_RID_ADMINS );
3817         }
3818
3819         DEBUG(5, ("_samr_CreateUser2: %s can add this account : %s\n",
3820                   uidtoname(p->server_info->utok.uid),
3821                   can_add_account ? "True":"False" ));
3822
3823         if (!can_add_account) {
3824                 return NT_STATUS_ACCESS_DENIED;
3825         }
3826
3827         /********** BEGIN Admin BLOCK **********/
3828
3829         become_root();
3830         nt_status = pdb_create_user(p->mem_ctx, account, acb_info,
3831                                     r->out.rid);
3832         unbecome_root();
3833
3834         /********** END Admin BLOCK **********/
3835
3836         /* now check for failure */
3837
3838         if ( !NT_STATUS_IS_OK(nt_status) )
3839                 return nt_status;
3840
3841         /* Get the user's SID */
3842
3843         sid_compose(&sid, get_global_sam_sid(), *r->out.rid);
3844
3845         map_max_allowed_access(p->server_info->ptok,
3846                                &p->server_info->utok,
3847                                &des_access);
3848
3849         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping,
3850                             &sid, SAMR_USR_RIGHTS_WRITE_PW);
3851         se_map_generic(&des_access, &usr_generic_mapping);
3852
3853         /*
3854          * JRA - TESTME. We just created this user so we
3855          * had rights to create them. Do we need to check
3856          * any further access on this object ? Can't we
3857          * just assume we have all the rights we need ?
3858          */
3859
3860         nt_status = access_check_object(psd, p->server_info->ptok,
3861                 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
3862                 &acc_granted, "_samr_CreateUser2");
3863
3864         if ( !NT_STATUS_IS_OK(nt_status) ) {
3865                 return nt_status;
3866         }
3867
3868         uinfo = policy_handle_create(p, r->out.user_handle, acc_granted,
3869                                      struct samr_user_info, &nt_status);
3870         if (!NT_STATUS_IS_OK(nt_status)) {
3871                 return nt_status;
3872         }
3873         uinfo->sid = sid;
3874
3875         /* After a "set" ensure we have no cached display info. */
3876         force_flush_samr_cache(&sid);
3877
3878         *r->out.access_granted = acc_granted;
3879
3880         return NT_STATUS_OK;
3881 }
3882
3883 /****************************************************************
3884 ****************************************************************/
3885
3886 NTSTATUS _samr_CreateUser(pipes_struct *p,
3887                           struct samr_CreateUser *r)
3888 {
3889         struct samr_CreateUser2 c;
3890         uint32_t access_granted;
3891
3892         c.in.domain_handle      = r->in.domain_handle;
3893         c.in.account_name       = r->in.account_name;
3894         c.in.acct_flags         = ACB_NORMAL;
3895         c.in.access_mask        = r->in.access_mask;
3896         c.out.user_handle       = r->out.user_handle;
3897         c.out.access_granted    = &access_granted;
3898         c.out.rid               = r->out.rid;
3899
3900         return _samr_CreateUser2(p, &c);
3901 }
3902
3903 /*******************************************************************
3904  _samr_Connect
3905  ********************************************************************/
3906
3907 NTSTATUS _samr_Connect(pipes_struct *p,
3908                        struct samr_Connect *r)
3909 {
3910         struct samr_connect_info *info;
3911         uint32_t acc_granted;
3912         struct policy_handle hnd;
3913         uint32    des_access = r->in.access_mask;
3914         NTSTATUS status;
3915
3916         /* Access check */
3917
3918         if (!pipe_access_check(p)) {
3919                 DEBUG(3, ("access denied to _samr_Connect\n"));
3920                 return NT_STATUS_ACCESS_DENIED;
3921         }
3922
3923         /* don't give away the farm but this is probably ok.  The SAMR_ACCESS_ENUM_DOMAINS
3924            was observed from a win98 client trying to enumerate users (when configured
3925            user level access control on shares)   --jerry */
3926
3927         map_max_allowed_access(p->server_info->ptok,
3928                                &p->server_info->utok,
3929                                &des_access);
3930
3931         se_map_generic( &des_access, &sam_generic_mapping );
3932
3933         acc_granted = des_access & (SAMR_ACCESS_ENUM_DOMAINS
3934                                     |SAMR_ACCESS_LOOKUP_DOMAIN);
3935
3936         /* set up the SAMR connect_anon response */
3937
3938         info = policy_handle_create(p, &hnd, acc_granted,
3939                                     struct samr_connect_info,
3940                                     &status);
3941         if (!NT_STATUS_IS_OK(status)) {
3942                 return status;
3943         }
3944
3945         *r->out.connect_handle = hnd;
3946         return NT_STATUS_OK;
3947 }
3948
3949 /*******************************************************************
3950  _samr_Connect2
3951  ********************************************************************/
3952
3953 NTSTATUS _samr_Connect2(pipes_struct *p,
3954                         struct samr_Connect2 *r)
3955 {
3956         struct samr_connect_info *info = NULL;
3957         struct policy_handle hnd;
3958         SEC_DESC *psd = NULL;
3959         uint32    acc_granted;
3960         uint32    des_access = r->in.access_mask;
3961         NTSTATUS  nt_status;
3962         size_t    sd_size;
3963         const char *fn = "_samr_Connect2";
3964
3965         switch (p->hdr_req.opnum) {
3966         case NDR_SAMR_CONNECT2:
3967                 fn = "_samr_Connect2";
3968                 break;
3969         case NDR_SAMR_CONNECT3:
3970                 fn = "_samr_Connect3";
3971                 break;
3972         case NDR_SAMR_CONNECT4:
3973                 fn = "_samr_Connect4";
3974                 break;
3975         case NDR_SAMR_CONNECT5:
3976                 fn = "_samr_Connect5";
3977                 break;
3978         }
3979
3980         DEBUG(5,("%s: %d\n", fn, __LINE__));
3981
3982         /* Access check */
3983
3984         if (!pipe_access_check(p)) {
3985                 DEBUG(3, ("access denied to %s\n", fn));
3986                 return NT_STATUS_ACCESS_DENIED;
3987         }
3988
3989         map_max_allowed_access(p->server_info->ptok,
3990                                &p->server_info->utok,
3991                                &des_access);
3992
3993         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
3994         se_map_generic(&des_access, &sam_generic_mapping);
3995
3996         nt_status = access_check_object(psd, p->server_info->ptok,
3997                 NULL, 0, des_access, &acc_granted, fn);
3998
3999         if ( !NT_STATUS_IS_OK(nt_status) )
4000                 return nt_status;
4001
4002         info = policy_handle_create(p, &hnd, acc_granted,
4003                                     struct samr_connect_info, &nt_status);
4004         if (!NT_STATUS_IS_OK(nt_status)) {
4005                 return nt_status;
4006         }
4007
4008         DEBUG(5,("%s: %d\n", fn, __LINE__));
4009
4010         *r->out.connect_handle = hnd;
4011         return NT_STATUS_OK;
4012 }
4013
4014 /****************************************************************
4015  _samr_Connect3
4016 ****************************************************************/
4017
4018 NTSTATUS _samr_Connect3(pipes_struct *p,
4019                         struct samr_Connect3 *r)
4020 {
4021         struct samr_Connect2 c;
4022
4023         c.in.system_name        = r->in.system_name;
4024         c.in.access_mask        = r->in.access_mask;
4025         c.out.connect_handle    = r->out.connect_handle;
4026
4027         return _samr_Connect2(p, &c);
4028 }
4029
4030 /*******************************************************************
4031  _samr_Connect4
4032  ********************************************************************/
4033
4034 NTSTATUS _samr_Connect4(pipes_struct *p,
4035                         struct samr_Connect4 *r)
4036 {
4037         struct samr_Connect2 c;
4038
4039         c.in.system_name        = r->in.system_name;
4040         c.in.access_mask        = r->in.access_mask;
4041         c.out.connect_handle    = r->out.connect_handle;
4042
4043         return _samr_Connect2(p, &c);
4044 }
4045
4046 /*******************************************************************
4047  _samr_Connect5
4048  ********************************************************************/
4049
4050 NTSTATUS _samr_Connect5(pipes_struct *p,
4051                         struct samr_Connect5 *r)
4052 {
4053         NTSTATUS status;
4054         struct samr_Connect2 c;
4055         struct samr_ConnectInfo1 info1;
4056
4057         info1.client_version = SAMR_CONNECT_AFTER_W2K;
4058         info1.unknown2 = 0;
4059
4060         c.in.system_name        = r->in.system_name;
4061         c.in.access_mask        = r->in.access_mask;
4062         c.out.connect_handle    = r->out.connect_handle;
4063
4064         *r->out.level_out = 1;
4065
4066         status = _samr_Connect2(p, &c);
4067         if (!NT_STATUS_IS_OK(status)) {
4068                 return status;
4069         }
4070
4071         r->out.info_out->info1 = info1;
4072
4073         return NT_STATUS_OK;
4074 }
4075
4076 /**********************************************************************
4077  _samr_LookupDomain
4078  **********************************************************************/
4079
4080 NTSTATUS _samr_LookupDomain(pipes_struct *p,
4081                             struct samr_LookupDomain *r)
4082 {
4083         NTSTATUS status;
4084         struct samr_connect_info *info;
4085         const char *domain_name;
4086         DOM_SID *sid = NULL;
4087
4088         /* win9x user manager likes to use SAMR_ACCESS_ENUM_DOMAINS here.
4089            Reverted that change so we will work with RAS servers again */
4090
4091         info = policy_handle_find(p, r->in.connect_handle,
4092                                   SAMR_ACCESS_LOOKUP_DOMAIN, NULL,
4093                                   struct samr_connect_info,
4094                                   &status);
4095         if (!NT_STATUS_IS_OK(status)) {
4096                 return status;
4097         }
4098
4099         domain_name = r->in.domain_name->string;
4100         if (!domain_name) {
4101                 return NT_STATUS_INVALID_PARAMETER;
4102         }
4103
4104         sid = TALLOC_ZERO_P(p->mem_ctx, struct dom_sid2);
4105         if (!sid) {
4106                 return NT_STATUS_NO_MEMORY;
4107         }
4108
4109         if (strequal(domain_name, builtin_domain_name())) {
4110                 sid_copy(sid, &global_sid_Builtin);
4111         } else {
4112                 if (!secrets_fetch_domain_sid(domain_name, sid)) {
4113                         status = NT_STATUS_NO_SUCH_DOMAIN;
4114                 }
4115         }
4116
4117         DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name,
4118                  sid_string_dbg(sid)));
4119
4120         *r->out.sid = sid;
4121
4122         return status;
4123 }
4124
4125 /**********************************************************************
4126  _samr_EnumDomains
4127  **********************************************************************/
4128
4129 NTSTATUS _samr_EnumDomains(pipes_struct *p,
4130                            struct samr_EnumDomains *r)
4131 {
4132         NTSTATUS status;
4133         struct samr_connect_info *info;
4134         uint32_t num_entries = 2;
4135         struct samr_SamEntry *entry_array = NULL;
4136         struct samr_SamArray *sam;
4137
4138         info = policy_handle_find(p, r->in.connect_handle,
4139                                   SAMR_ACCESS_ENUM_DOMAINS, NULL,
4140                                   struct samr_connect_info, &status);
4141         if (!NT_STATUS_IS_OK(status)) {
4142                 return status;
4143         }
4144
4145         sam = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
4146         if (!sam) {
4147                 return NT_STATUS_NO_MEMORY;
4148         }
4149
4150         entry_array = TALLOC_ZERO_ARRAY(p->mem_ctx,
4151                                         struct samr_SamEntry,
4152                                         num_entries);
4153         if (!entry_array) {
4154                 return NT_STATUS_NO_MEMORY;
4155         }
4156
4157         entry_array[0].idx = 0;
4158         init_lsa_String(&entry_array[0].name, get_global_sam_name());
4159
4160         entry_array[1].idx = 1;
4161         init_lsa_String(&entry_array[1].name, "Builtin");
4162
4163         sam->count = num_entries;
4164         sam->entries = entry_array;
4165
4166         *r->out.sam = sam;
4167         *r->out.num_entries = num_entries;
4168
4169         return status;
4170 }
4171
4172 /*******************************************************************
4173  _samr_OpenAlias
4174  ********************************************************************/
4175
4176 NTSTATUS _samr_OpenAlias(pipes_struct *p,
4177                          struct samr_OpenAlias *r)
4178 {
4179         DOM_SID sid;
4180         uint32 alias_rid = r->in.rid;
4181         struct samr_alias_info *ainfo;
4182         struct samr_domain_info *dinfo;
4183         SEC_DESC *psd = NULL;
4184         uint32    acc_granted;
4185         uint32    des_access = r->in.access_mask;
4186         size_t    sd_size;
4187         NTSTATUS  status;
4188         SE_PRIV se_rights;
4189
4190         dinfo = policy_handle_find(p, r->in.domain_handle,
4191                                    SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
4192                                    struct samr_domain_info, &status);
4193         if (!NT_STATUS_IS_OK(status)) {
4194                 return status;
4195         }
4196
4197         /* append the alias' RID to it */
4198
4199         if (!sid_compose(&sid, &dinfo->sid, alias_rid))
4200                 return NT_STATUS_NO_SUCH_ALIAS;
4201
4202         /*check if access can be granted as requested by client. */
4203
4204         map_max_allowed_access(p->server_info->ptok,
4205                                &p->server_info->utok,
4206                                &des_access);
4207
4208         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &ali_generic_mapping, NULL, 0);
4209         se_map_generic(&des_access,&ali_generic_mapping);
4210
4211         se_priv_copy( &se_rights, &se_add_users );
4212
4213         status = access_check_object(psd, p->server_info->ptok,
4214                 &se_rights, GENERIC_RIGHTS_ALIAS_ALL_ACCESS,
4215                 des_access, &acc_granted, "_samr_OpenAlias");
4216
4217         if ( !NT_STATUS_IS_OK(status) )
4218                 return status;
4219
4220         {
4221                 /* Check we actually have the requested alias */
4222                 enum lsa_SidType type;
4223                 bool result;
4224                 gid_t gid;
4225
4226                 become_root();
4227                 result = lookup_sid(NULL, &sid, NULL, NULL, &type);
4228                 unbecome_root();
4229
4230                 if (!result || (type != SID_NAME_ALIAS)) {
4231                         return NT_STATUS_NO_SUCH_ALIAS;
4232                 }
4233
4234                 /* make sure there is a mapping */
4235
4236                 if ( !sid_to_gid( &sid, &gid ) ) {
4237                         return NT_STATUS_NO_SUCH_ALIAS;
4238                 }
4239
4240         }
4241
4242         ainfo = policy_handle_create(p, r->out.alias_handle, acc_granted,
4243                                      struct samr_alias_info, &status);
4244         if (!NT_STATUS_IS_OK(status)) {
4245                 return status;
4246         }
4247         ainfo->sid = sid;
4248
4249         return NT_STATUS_OK;
4250 }
4251
4252 /*******************************************************************
4253  set_user_info_2
4254  ********************************************************************/
4255
4256 static NTSTATUS set_user_info_2(TALLOC_CTX *mem_ctx,
4257                                 struct samr_UserInfo2 *id2,
4258                                 struct samu *pwd)
4259 {
4260         if (id2 == NULL) {
4261                 DEBUG(5,("set_user_info_2: NULL id2\n"));
4262                 return NT_STATUS_ACCESS_DENIED;
4263         }
4264
4265         copy_id2_to_sam_passwd(pwd, id2);
4266
4267         return pdb_update_sam_account(pwd);
4268 }
4269
4270 /*******************************************************************
4271  set_user_info_4
4272  ********************************************************************/
4273
4274 static NTSTATUS set_user_info_4(TALLOC_CTX *mem_ctx,
4275                                 struct samr_UserInfo4 *id4,
4276                                 struct samu *pwd)
4277 {
4278         if (id4 == NULL) {
4279                 DEBUG(5,("set_user_info_2: NULL id4\n"));
4280                 return NT_STATUS_ACCESS_DENIED;
4281         }
4282
4283         copy_id4_to_sam_passwd(pwd, id4);
4284
4285         return pdb_update_sam_account(pwd);
4286 }
4287
4288 /*******************************************************************
4289  set_user_info_6
4290  ********************************************************************/
4291
4292 static NTSTATUS set_user_info_6(TALLOC_CTX *mem_ctx,
4293                                 struct samr_UserInfo6 *id6,
4294                                 struct samu *pwd)
4295 {
4296         if (id6 == NULL) {
4297                 DEBUG(5,("set_user_info_6: NULL id6\n"));
4298                 return NT_STATUS_ACCESS_DENIED;
4299         }
4300
4301         copy_id6_to_sam_passwd(pwd, id6);
4302
4303         return pdb_update_sam_account(pwd);
4304 }
4305
4306 /*******************************************************************
4307  set_user_info_7
4308  ********************************************************************/
4309
4310 static NTSTATUS set_user_info_7(TALLOC_CTX *mem_ctx,
4311                                 struct samr_UserInfo7 *id7,
4312                                 struct samu *pwd)
4313 {
4314         NTSTATUS rc;
4315
4316         if (id7 == NULL) {
4317                 DEBUG(5, ("set_user_info_7: NULL id7\n"));
4318                 return NT_STATUS_ACCESS_DENIED;
4319         }
4320
4321         if (!id7->account_name.string) {
4322                 DEBUG(5, ("set_user_info_7: failed to get new username\n"));
4323                 return NT_STATUS_ACCESS_DENIED;
4324         }
4325
4326         /* check to see if the new username already exists.  Note: we can't
4327            reliably lock all backends, so there is potentially the
4328            possibility that a user can be created in between this check and
4329            the rename.  The rename should fail, but may not get the
4330            exact same failure status code.  I think this is small enough
4331            of a window for this type of operation and the results are
4332            simply that the rename fails with a slightly different status
4333            code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
4334
4335         rc = can_create(mem_ctx, id7->account_name.string);
4336
4337         /* when there is nothing to change, we're done here */
4338         if (NT_STATUS_EQUAL(rc, NT_STATUS_USER_EXISTS) &&
4339             strequal(id7->account_name.string, pdb_get_username(pwd))) {
4340                 return NT_STATUS_OK;
4341         }
4342         if (!NT_STATUS_IS_OK(rc)) {
4343                 return rc;
4344         }
4345
4346         rc = pdb_rename_sam_account(pwd, id7->account_name.string);
4347
4348         return rc;
4349 }
4350
4351 /*******************************************************************
4352  set_user_info_8
4353  ********************************************************************/
4354
4355 static NTSTATUS set_user_info_8(TALLOC_CTX *mem_ctx,
4356                                 struct samr_UserInfo8 *id8,
4357                                 struct samu *pwd)
4358 {
4359         if (id8 == NULL) {
4360                 DEBUG(5,("set_user_info_8: NULL id8\n"));
4361                 return NT_STATUS_ACCESS_DENIED;
4362         }
4363
4364         copy_id8_to_sam_passwd(pwd, id8);
4365
4366         return pdb_update_sam_account(pwd);
4367 }
4368
4369 /*******************************************************************
4370  set_user_info_10
4371  ********************************************************************/
4372
4373 static NTSTATUS set_user_info_10(TALLOC_CTX *mem_ctx,
4374                                  struct samr_UserInfo10 *id10,
4375                                  struct samu *pwd)
4376 {
4377         if (id10 == NULL) {
4378                 DEBUG(5,("set_user_info_8: NULL id10\n"));
4379                 return NT_STATUS_ACCESS_DENIED;
4380         }
4381
4382         copy_id10_to_sam_passwd(pwd, id10);
4383
4384         return pdb_update_sam_account(pwd);
4385 }
4386
4387 /*******************************************************************
4388  set_user_info_11
4389  ********************************************************************/
4390
4391 static NTSTATUS set_user_info_11(TALLOC_CTX *mem_ctx,
4392                                  struct samr_UserInfo11 *id11,
4393                                  struct samu *pwd)
4394 {
4395         if (id11 == NULL) {
4396                 DEBUG(5,("set_user_info_11: NULL id11\n"));
4397                 return NT_STATUS_ACCESS_DENIED;
4398         }
4399
4400         copy_id11_to_sam_passwd(pwd, id11);
4401
4402         return pdb_update_sam_account(pwd);
4403 }
4404
4405 /*******************************************************************
4406  set_user_info_12
4407  ********************************************************************/
4408
4409 static NTSTATUS set_user_info_12(TALLOC_CTX *mem_ctx,
4410                                  struct samr_UserInfo12 *id12,
4411                                  struct samu *pwd)
4412 {
4413         if (id12 == NULL) {
4414                 DEBUG(5,("set_user_info_12: NULL id12\n"));
4415                 return NT_STATUS_ACCESS_DENIED;
4416         }
4417
4418         copy_id12_to_sam_passwd(pwd, id12);
4419
4420         return pdb_update_sam_account(pwd);
4421 }
4422
4423 /*******************************************************************
4424  set_user_info_13
4425  ********************************************************************/
4426
4427 static NTSTATUS set_user_info_13(TALLOC_CTX *mem_ctx,
4428                                  struct samr_UserInfo13 *id13,
4429                                  struct samu *pwd)
4430 {
4431         if (id13 == NULL) {
4432                 DEBUG(5,("set_user_info_13: NULL id13\n"));
4433                 return NT_STATUS_ACCESS_DENIED;
4434         }
4435
4436         copy_id13_to_sam_passwd(pwd, id13);
4437
4438         return pdb_update_sam_account(pwd);
4439 }
4440
4441 /*******************************************************************
4442  set_user_info_14
4443  ********************************************************************/
4444
4445 static NTSTATUS set_user_info_14(TALLOC_CTX *mem_ctx,
4446                                  struct samr_UserInfo14 *id14,
4447                                  struct samu *pwd)
4448 {
4449         if (id14 == NULL) {
4450                 DEBUG(5,("set_user_info_14: NULL id14\n"));
4451                 return NT_STATUS_ACCESS_DENIED;
4452         }
4453
4454         copy_id14_to_sam_passwd(pwd, id14);
4455
4456         return pdb_update_sam_account(pwd);
4457 }
4458
4459 /*******************************************************************
4460  set_user_info_16
4461  ********************************************************************/
4462
4463 static NTSTATUS set_user_info_16(TALLOC_CTX *mem_ctx,
4464                                  struct samr_UserInfo16 *id16,
4465                                  struct samu *pwd)
4466 {
4467         if (id16 == NULL) {
4468                 DEBUG(5,("set_user_info_16: NULL id16\n"));
4469                 return NT_STATUS_ACCESS_DENIED;
4470         }
4471
4472         copy_id16_to_sam_passwd(pwd, id16);
4473
4474         return pdb_update_sam_account(pwd);
4475 }
4476
4477 /*******************************************************************
4478  set_user_info_17
4479  ********************************************************************/
4480
4481 static NTSTATUS set_user_info_17(TALLOC_CTX *mem_ctx,
4482                                  struct samr_UserInfo17 *id17,
4483                                  struct samu *pwd)
4484 {
4485         if (id17 == NULL) {
4486                 DEBUG(5,("set_user_info_17: NULL id17\n"));
4487                 return NT_STATUS_ACCESS_DENIED;
4488         }
4489
4490         copy_id17_to_sam_passwd(pwd, id17);
4491
4492         return pdb_update_sam_account(pwd);
4493 }
4494
4495 /*******************************************************************
4496  set_user_info_18
4497  ********************************************************************/
4498
4499 static NTSTATUS set_user_info_18(struct samr_UserInfo18 *id18,
4500                                  TALLOC_CTX *mem_ctx,
4501                                  DATA_BLOB *session_key,
4502                                  struct samu *pwd)
4503 {
4504         if (id18 == NULL) {
4505                 DEBUG(2, ("set_user_info_18: id18 is NULL\n"));
4506                 return NT_STATUS_INVALID_PARAMETER;
4507         }
4508
4509         if (id18->nt_pwd_active || id18->lm_pwd_active) {
4510                 if (!session_key->length) {
4511                         return NT_STATUS_NO_USER_SESSION_KEY;
4512                 }
4513         }
4514
4515         if (id18->nt_pwd_active) {
4516
4517                 DATA_BLOB in, out;
4518
4519                 in = data_blob_const(id18->nt_pwd.hash, 16);
4520                 out = data_blob_talloc_zero(mem_ctx, 16);
4521
4522                 sess_crypt_blob(&out, &in, session_key, false);
4523
4524                 if (!pdb_set_nt_passwd(pwd, out.data, PDB_CHANGED)) {
4525                         return NT_STATUS_ACCESS_DENIED;
4526                 }
4527
4528                 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4529         }
4530
4531         if (id18->lm_pwd_active) {
4532
4533                 DATA_BLOB in, out;
4534
4535                 in = data_blob_const(id18->lm_pwd.hash, 16);
4536                 out = data_blob_talloc_zero(mem_ctx, 16);
4537
4538                 sess_crypt_blob(&out, &in, session_key, false);
4539
4540                 if (!pdb_set_lanman_passwd(pwd, out.data, PDB_CHANGED)) {
4541                         return NT_STATUS_ACCESS_DENIED;
4542                 }
4543
4544                 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4545         }
4546
4547         copy_id18_to_sam_passwd(pwd, id18);
4548
4549         return pdb_update_sam_account(pwd);
4550 }
4551
4552 /*******************************************************************
4553  set_user_info_20
4554  ********************************************************************/
4555
4556 static NTSTATUS set_user_info_20(TALLOC_CTX *mem_ctx,
4557                                  struct samr_UserInfo20 *id20,
4558                                  struct samu *pwd)
4559 {
4560         if (id20 == NULL) {
4561                 DEBUG(5,("set_user_info_20: NULL id20\n"));
4562                 return NT_STATUS_ACCESS_DENIED;
4563         }
4564
4565         copy_id20_to_sam_passwd(pwd, id20);
4566
4567         return pdb_update_sam_account(pwd);
4568 }
4569
4570 /*******************************************************************
4571  set_user_info_21
4572  ********************************************************************/
4573
4574 static NTSTATUS set_user_info_21(struct samr_UserInfo21 *id21,
4575                                  TALLOC_CTX *mem_ctx,
4576                                  DATA_BLOB *session_key,
4577                                  struct samu *pwd)
4578 {
4579         NTSTATUS status;
4580
4581         if (id21 == NULL) {
4582                 DEBUG(5, ("set_user_info_21: NULL id21\n"));
4583                 return NT_STATUS_INVALID_PARAMETER;
4584         }
4585
4586         if (id21->fields_present == 0) {
4587                 return NT_STATUS_INVALID_PARAMETER;
4588         }
4589
4590         if (id21->fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
4591                 return NT_STATUS_ACCESS_DENIED;
4592         }
4593
4594         if (id21->fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
4595                 if (id21->nt_password_set) {
4596                         DATA_BLOB in, out;
4597
4598                         if ((id21->nt_owf_password.length != 16) ||
4599                             (id21->nt_owf_password.size != 16)) {
4600                                 return NT_STATUS_INVALID_PARAMETER;
4601                         }
4602
4603                         if (!session_key->length) {
4604                                 return NT_STATUS_NO_USER_SESSION_KEY;
4605                         }
4606
4607                         in = data_blob_const(id21->nt_owf_password.array, 16);
4608                         out = data_blob_talloc_zero(mem_ctx, 16);
4609
4610                         sess_crypt_blob(&out, &in, session_key, false);
4611
4612                         pdb_set_nt_passwd(pwd, out.data, PDB_CHANGED);
4613                         pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4614                 }
4615         }
4616
4617         if (id21->fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
4618                 if (id21->lm_password_set) {
4619                         DATA_BLOB in, out;
4620
4621                         if ((id21->lm_owf_password.length != 16) ||
4622                             (id21->lm_owf_password.size != 16)) {
4623                                 return NT_STATUS_INVALID_PARAMETER;
4624                         }
4625
4626                         if (!session_key->length) {
4627                                 return NT_STATUS_NO_USER_SESSION_KEY;
4628                         }
4629
4630                         in = data_blob_const(id21->lm_owf_password.array, 16);
4631                         out = data_blob_talloc_zero(mem_ctx, 16);
4632
4633                         sess_crypt_blob(&out, &in, session_key, false);
4634
4635                         pdb_set_lanman_passwd(pwd, out.data, PDB_CHANGED);
4636                         pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4637                 }
4638         }
4639
4640         /* we need to separately check for an account rename first */
4641
4642         if (id21->account_name.string &&
4643             (!strequal(id21->account_name.string, pdb_get_username(pwd))))
4644         {
4645
4646                 /* check to see if the new username already exists.  Note: we can't
4647                    reliably lock all backends, so there is potentially the
4648                    possibility that a user can be created in between this check and
4649                    the rename.  The rename should fail, but may not get the
4650                    exact same failure status code.  I think this is small enough
4651                    of a window for this type of operation and the results are
4652                    simply that the rename fails with a slightly different status
4653                    code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
4654
4655                 status = can_create(mem_ctx, id21->account_name.string);
4656                 if (!NT_STATUS_IS_OK(status)) {
4657                         return status;
4658                 }
4659
4660                 status = pdb_rename_sam_account(pwd, id21->account_name.string);
4661
4662                 if (!NT_STATUS_IS_OK(status)) {
4663                         DEBUG(0,("set_user_info_21: failed to rename account: %s\n",
4664                                 nt_errstr(status)));
4665                         return status;
4666                 }
4667
4668                 /* set the new username so that later
4669                    functions can work on the new account */
4670                 pdb_set_username(pwd, id21->account_name.string, PDB_SET);
4671         }
4672
4673         copy_id21_to_sam_passwd("INFO_21", pwd, id21);
4674
4675         /*
4676          * The funny part about the previous two calls is
4677          * that pwd still has the password hashes from the
4678          * passdb entry.  These have not been updated from
4679          * id21.  I don't know if they need to be set.    --jerry
4680          */
4681
4682         if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
4683                 status = pdb_set_unix_primary_group(mem_ctx, pwd);
4684                 if ( !NT_STATUS_IS_OK(status) ) {
4685                         return status;
4686                 }
4687         }
4688
4689         /* Don't worry about writing out the user account since the
4690            primary group SID is generated solely from the user's Unix
4691            primary group. */
4692
4693         /* write the change out */
4694         if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4695                 return status;
4696         }
4697
4698         return NT_STATUS_OK;
4699 }
4700
4701 /*******************************************************************
4702  set_user_info_23
4703  ********************************************************************/
4704
4705 static NTSTATUS set_user_info_23(TALLOC_CTX *mem_ctx,
4706                                  struct samr_UserInfo23 *id23,
4707                                  struct samu *pwd)
4708 {
4709         char *plaintext_buf = NULL;
4710         size_t len = 0;
4711         uint32_t acct_ctrl;
4712         NTSTATUS status;
4713
4714         if (id23 == NULL) {
4715                 DEBUG(5, ("set_user_info_23: NULL id23\n"));
4716                 return NT_STATUS_INVALID_PARAMETER;
4717         }
4718
4719         if (id23->info.fields_present == 0) {
4720                 return NT_STATUS_INVALID_PARAMETER;
4721         }
4722
4723         if (id23->info.fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
4724                 return NT_STATUS_ACCESS_DENIED;
4725         }
4726
4727         if ((id23->info.fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
4728             (id23->info.fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT)) {
4729
4730                 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
4731                           pdb_get_username(pwd)));
4732
4733                 if (!decode_pw_buffer(mem_ctx,
4734                                       id23->password.data,
4735                                       &plaintext_buf,
4736                                       &len,
4737                                       CH_UTF16)) {
4738                         return NT_STATUS_WRONG_PASSWORD;
4739                 }
4740
4741                 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
4742                         return NT_STATUS_ACCESS_DENIED;
4743                 }
4744         }
4745
4746         copy_id23_to_sam_passwd(pwd, id23);
4747
4748         acct_ctrl = pdb_get_acct_ctrl(pwd);
4749
4750         /* if it's a trust account, don't update /etc/passwd */
4751         if (    ( (acct_ctrl &  ACB_DOMTRUST) == ACB_DOMTRUST ) ||
4752                 ( (acct_ctrl &  ACB_WSTRUST) ==  ACB_WSTRUST) ||
4753                 ( (acct_ctrl &  ACB_SVRTRUST) ==  ACB_SVRTRUST) ) {
4754                 DEBUG(5, ("Changing trust account.  Not updating /etc/passwd\n"));
4755         } else if (plaintext_buf) {
4756                 /* update the UNIX password */
4757                 if (lp_unix_password_sync() ) {
4758                         struct passwd *passwd;
4759                         if (pdb_get_username(pwd) == NULL) {
4760                                 DEBUG(1, ("chgpasswd: User without name???\n"));
4761                                 return NT_STATUS_ACCESS_DENIED;
4762                         }
4763
4764                         passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
4765                         if (passwd == NULL) {
4766                                 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
4767                         }
4768
4769                         if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
4770                                 return NT_STATUS_ACCESS_DENIED;
4771                         }
4772                         TALLOC_FREE(passwd);
4773                 }
4774         }
4775
4776         if (plaintext_buf) {
4777                 memset(plaintext_buf, '\0', strlen(plaintext_buf));
4778         }
4779
4780         if (IS_SAM_CHANGED(pwd, PDB_GROUPSID) &&
4781             (!NT_STATUS_IS_OK(status =  pdb_set_unix_primary_group(mem_ctx,
4782                                                                    pwd)))) {
4783                 return status;
4784         }
4785
4786         if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4787                 return status;
4788         }
4789
4790         return NT_STATUS_OK;
4791 }
4792
4793 /*******************************************************************
4794  set_user_info_pw
4795  ********************************************************************/
4796
4797 static bool set_user_info_pw(uint8 *pass, struct samu *pwd)
4798 {
4799         size_t len = 0;
4800         char *plaintext_buf = NULL;
4801         uint32 acct_ctrl;
4802
4803         DEBUG(5, ("Attempting administrator password change for user %s\n",
4804                   pdb_get_username(pwd)));
4805
4806         acct_ctrl = pdb_get_acct_ctrl(pwd);
4807
4808         if (!decode_pw_buffer(talloc_tos(),
4809                                 pass,
4810                                 &plaintext_buf,
4811                                 &len,
4812                                 CH_UTF16)) {
4813                 return False;
4814         }
4815
4816         if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
4817                 return False;
4818         }
4819
4820         /* if it's a trust account, don't update /etc/passwd */
4821         if ( ( (acct_ctrl &  ACB_DOMTRUST) == ACB_DOMTRUST ) ||
4822                 ( (acct_ctrl &  ACB_WSTRUST) ==  ACB_WSTRUST) ||
4823                 ( (acct_ctrl &  ACB_SVRTRUST) ==  ACB_SVRTRUST) ) {
4824                 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
4825         } else {
4826                 /* update the UNIX password */
4827                 if (lp_unix_password_sync()) {
4828                         struct passwd *passwd;
4829
4830                         if (pdb_get_username(pwd) == NULL) {
4831                                 DEBUG(1, ("chgpasswd: User without name???\n"));
4832                                 return False;
4833                         }
4834
4835                         passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
4836                         if (passwd == NULL) {
4837                                 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
4838                         }
4839
4840                         if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
4841                                 return False;
4842                         }
4843                         TALLOC_FREE(passwd);
4844                 }
4845         }
4846
4847         memset(plaintext_buf, '\0', strlen(plaintext_buf));
4848
4849         DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
4850
4851         return True;
4852 }
4853
4854 /*******************************************************************
4855  set_user_info_24
4856  ********************************************************************/
4857
4858 static NTSTATUS set_user_info_24(TALLOC_CTX *mem_ctx,
4859                                  struct samr_UserInfo24 *id24,
4860                                  struct samu *pwd)
4861 {
4862         NTSTATUS status;
4863
4864         if (id24 == NULL) {
4865                 DEBUG(5, ("set_user_info_24: NULL id24\n"));
4866                 return NT_STATUS_INVALID_PARAMETER;
4867         }
4868
4869         if (!set_user_info_pw(id24->password.data, pwd)) {
4870                 return NT_STATUS_WRONG_PASSWORD;
4871         }
4872
4873         copy_id24_to_sam_passwd(pwd, id24);
4874
4875         status = pdb_update_sam_account(pwd);
4876         if (!NT_STATUS_IS_OK(status)) {
4877                 return status;
4878         }
4879
4880         return NT_STATUS_OK;
4881 }
4882
4883 /*******************************************************************
4884  set_user_info_25
4885  ********************************************************************/
4886
4887 static NTSTATUS set_user_info_25(TALLOC_CTX *mem_ctx,
4888                                  struct samr_UserInfo25 *id25,
4889                                  struct samu *pwd)
4890 {
4891         NTSTATUS status;
4892
4893         if (id25 == NULL) {
4894                 DEBUG(5, ("set_user_info_25: NULL id25\n"));
4895                 return NT_STATUS_INVALID_PARAMETER;
4896         }
4897
4898         if (id25->info.fields_present == 0) {
4899                 return NT_STATUS_INVALID_PARAMETER;
4900         }
4901
4902         if (id25->info.fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
4903                 return NT_STATUS_ACCESS_DENIED;
4904         }
4905
4906         if ((id25->info.fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
4907             (id25->info.fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT)) {
4908
4909                 if (!set_user_info_pw(id25->password.data, pwd)) {
4910                         return NT_STATUS_WRONG_PASSWORD;
4911                 }
4912         }
4913
4914         copy_id25_to_sam_passwd(pwd, id25);
4915
4916         /* write the change out */
4917         if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4918                 return status;
4919         }
4920
4921         /*
4922          * We need to "pdb_update_sam_account" before the unix primary group
4923          * is set, because the idealx scripts would also change the
4924          * sambaPrimaryGroupSid using the ldap replace method. pdb_ldap uses
4925          * the delete explicit / add explicit, which would then fail to find
4926          * the previous primaryGroupSid value.
4927          */
4928
4929         if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
4930                 status = pdb_set_unix_primary_group(mem_ctx, pwd);
4931                 if ( !NT_STATUS_IS_OK(status) ) {
4932                         return status;
4933                 }
4934         }
4935
4936         return NT_STATUS_OK;
4937 }
4938
4939 /*******************************************************************
4940  set_user_info_26
4941  ********************************************************************/
4942
4943 static NTSTATUS set_user_info_26(TALLOC_CTX *mem_ctx,
4944                                  struct samr_UserInfo26 *id26,
4945                                  struct samu *pwd)
4946 {
4947         NTSTATUS status;
4948
4949         if (id26 == NULL) {
4950                 DEBUG(5, ("set_user_info_26: NULL id26\n"));
4951                 return NT_STATUS_INVALID_PARAMETER;
4952         }
4953
4954         if (!set_user_info_pw(id26->password.data, pwd)) {
4955                 return NT_STATUS_WRONG_PASSWORD;
4956         }
4957
4958         copy_id26_to_sam_passwd(pwd, id26);
4959
4960         status = pdb_update_sam_account(pwd);
4961         if (!NT_STATUS_IS_OK(status)) {
4962                 return status;
4963         }
4964
4965         return NT_STATUS_OK;
4966 }
4967
4968 /*************************************************************
4969 **************************************************************/
4970
4971 static uint32_t samr_set_user_info_map_fields_to_access_mask(uint32_t fields)
4972 {
4973         uint32_t acc_required = 0;
4974
4975         /* USER_ALL_USERNAME */
4976         if (fields & SAMR_FIELD_ACCOUNT_NAME)
4977                 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4978         /* USER_ALL_FULLNAME */
4979         if (fields & SAMR_FIELD_FULL_NAME)
4980                 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4981         /* USER_ALL_PRIMARYGROUPID */
4982         if (fields & SAMR_FIELD_PRIMARY_GID)
4983                 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4984         /* USER_ALL_HOMEDIRECTORY */
4985         if (fields & SAMR_FIELD_HOME_DIRECTORY)
4986                 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4987         /* USER_ALL_HOMEDIRECTORYDRIVE */
4988         if (fields & SAMR_FIELD_HOME_DRIVE)
4989                 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4990         /* USER_ALL_SCRIPTPATH */
4991         if (fields & SAMR_FIELD_LOGON_SCRIPT)
4992                 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4993         /* USER_ALL_PROFILEPATH */
4994         if (fields & SAMR_FIELD_PROFILE_PATH)
4995                 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4996         /* USER_ALL_ADMINCOMMENT */
4997         if (fields & SAMR_FIELD_COMMENT)
4998                 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4999         /* USER_ALL_WORKSTATIONS */
5000         if (fields & SAMR_FIELD_WORKSTATIONS)
5001                 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5002         /* USER_ALL_LOGONHOURS */
5003         if (fields & SAMR_FIELD_LOGON_HOURS)
5004                 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5005         /* USER_ALL_ACCOUNTEXPIRES */
5006         if (fields & SAMR_FIELD_ACCT_EXPIRY)
5007                 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5008         /* USER_ALL_USERACCOUNTCONTROL */
5009         if (fields & SAMR_FIELD_ACCT_FLAGS)
5010                 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5011         /* USER_ALL_PARAMETERS */
5012         if (fields & SAMR_FIELD_PARAMETERS)
5013                 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5014         /* USER_ALL_USERCOMMENT */
5015         if (fields & SAMR_FIELD_COMMENT)
5016                 acc_required |= SAMR_USER_ACCESS_SET_LOC_COM;
5017         /* USER_ALL_COUNTRYCODE */
5018         if (fields & SAMR_FIELD_COUNTRY_CODE)
5019                 acc_required |= SAMR_USER_ACCESS_SET_LOC_COM;
5020         /* USER_ALL_CODEPAGE */
5021         if (fields & SAMR_FIELD_CODE_PAGE)
5022                 acc_required |= SAMR_USER_ACCESS_SET_LOC_COM;
5023         /* USER_ALL_NTPASSWORDPRESENT */
5024         if (fields & SAMR_FIELD_NT_PASSWORD_PRESENT)
5025                 acc_required |= SAMR_USER_ACCESS_SET_PASSWORD;
5026         /* USER_ALL_LMPASSWORDPRESENT */
5027         if (fields & SAMR_FIELD_LM_PASSWORD_PRESENT)
5028                 acc_required |= SAMR_USER_ACCESS_SET_PASSWORD;
5029         /* USER_ALL_PASSWORDEXPIRED */
5030         if (fields & SAMR_FIELD_EXPIRED_FLAG)
5031                 acc_required |= SAMR_USER_ACCESS_SET_PASSWORD;
5032
5033         return acc_required;
5034 }
5035
5036 /*******************************************************************
5037  samr_SetUserInfo
5038  ********************************************************************/
5039
5040 NTSTATUS _samr_SetUserInfo(pipes_struct *p,
5041                            struct samr_SetUserInfo *r)
5042 {
5043         struct samr_user_info *uinfo;
5044         NTSTATUS status;
5045         struct samu *pwd = NULL;
5046         union samr_UserInfo *info = r->in.info;
5047         uint32_t acc_required = 0;
5048         uint32_t fields = 0;
5049         bool ret;
5050
5051         DEBUG(5,("_samr_SetUserInfo: %d\n", __LINE__));
5052
5053         /* This is tricky.  A WinXP domain join sets
5054           (SAMR_USER_ACCESS_SET_PASSWORD|SAMR_USER_ACCESS_SET_ATTRIBUTES|SAMR_USER_ACCESS_GET_ATTRIBUTES)
5055           The MMC lusrmgr plugin includes these perms and more in the SamrOpenUser().  But the
5056           standard Win32 API calls just ask for SAMR_USER_ACCESS_SET_PASSWORD in the SamrOpenUser().
5057           This should be enough for levels 18, 24, 25,& 26.  Info level 23 can set more so
5058           we'll use the set from the WinXP join as the basis. */
5059
5060         switch (r->in.level) {
5061         case 2: /* UserPreferencesInformation */
5062                 /* USER_WRITE_ACCOUNT | USER_WRITE_PREFERENCES */
5063                 acc_required = SAMR_USER_ACCESS_SET_ATTRIBUTES | SAMR_USER_ACCESS_SET_LOC_COM;
5064                 break;
5065         case 4: /* UserLogonHoursInformation */
5066         case 6: /* UserNameInformation */
5067         case 7: /* UserAccountNameInformation */
5068         case 8: /* UserFullNameInformation */
5069         case 9: /* UserPrimaryGroupInformation */
5070         case 10: /* UserHomeInformation */
5071         case 11: /* UserScriptInformation */
5072         case 12: /* UserProfileInformation */
5073         case 13: /* UserAdminCommentInformation */
5074         case 14: /* UserWorkStationsInformation */
5075         case 16: /* UserControlInformation */
5076         case 17: /* UserExpiresInformation */
5077         case 20: /* UserParametersInformation */
5078                 /* USER_WRITE_ACCOUNT */
5079                 acc_required = SAMR_USER_ACCESS_SET_ATTRIBUTES;
5080                 break;
5081         case 18: /* UserInternal1Information */
5082                 /* FIXME: gd, this is a guess */
5083                 acc_required = SAMR_USER_ACCESS_SET_PASSWORD;
5084                 break;
5085         case 21: /* UserAllInformation */
5086                 fields = info->info21.fields_present;
5087                 acc_required = samr_set_user_info_map_fields_to_access_mask(fields);
5088                 break;
5089         case 23: /* UserInternal4Information */
5090                 fields = info->info23.info.fields_present;
5091                 acc_required = samr_set_user_info_map_fields_to_access_mask(fields);
5092                 break;
5093         case 25: /* UserInternal4InformationNew */
5094                 fields = info->info25.info.fields_present;
5095                 acc_required = samr_set_user_info_map_fields_to_access_mask(fields);
5096                 break;
5097         case 24: /* UserInternal5Information */
5098         case 26: /* UserInternal5InformationNew */
5099                 acc_required = SAMR_USER_ACCESS_SET_PASSWORD;
5100                 break;
5101         default:
5102                 return NT_STATUS_INVALID_INFO_CLASS;
5103         }
5104
5105         uinfo = policy_handle_find(p, r->in.user_handle, acc_required, NULL,
5106                                    struct samr_user_info, &status);
5107         if (!NT_STATUS_IS_OK(status)) {
5108                 return status;
5109         }
5110
5111         DEBUG(5, ("_samr_SetUserInfo: sid:%s, level:%d\n",
5112                   sid_string_dbg(&uinfo->sid), r->in.level));
5113
5114         if (info == NULL) {
5115                 DEBUG(5, ("_samr_SetUserInfo: NULL info level\n"));
5116                 return NT_STATUS_INVALID_INFO_CLASS;
5117         }
5118
5119         if (!(pwd = samu_new(NULL))) {
5120                 return NT_STATUS_NO_MEMORY;
5121         }
5122
5123         become_root();
5124         ret = pdb_getsampwsid(pwd, &uinfo->sid);
5125         unbecome_root();
5126
5127         if (!ret) {
5128                 TALLOC_FREE(pwd);
5129                 return NT_STATUS_NO_SUCH_USER;
5130         }
5131
5132         /* ================ BEGIN Privilege BLOCK ================ */
5133
5134         become_root();
5135
5136         /* ok!  user info levels (lots: see MSDEV help), off we go... */
5137
5138         switch (r->in.level) {
5139
5140                 case 2:
5141                         status = set_user_info_2(p->mem_ctx,
5142                                                  &info->info2, pwd);
5143                         break;
5144
5145                 case 4:
5146                         status = set_user_info_4(p->mem_ctx,
5147                                                  &info->info4, pwd);
5148                         break;
5149
5150                 case 6:
5151                         status = set_user_info_6(p->mem_ctx,
5152                                                  &info->info6, pwd);
5153                         break;
5154
5155                 case 7:
5156                         status = set_user_info_7(p->mem_ctx,
5157                                                  &info->info7, pwd);
5158                         break;
5159
5160                 case 8:
5161                         status = set_user_info_8(p->mem_ctx,
5162                                                  &info->info8, pwd);
5163                         break;
5164
5165                 case 10:
5166                         status = set_user_info_10(p->mem_ctx,
5167                                                   &info->info10, pwd);
5168                         break;
5169
5170                 case 11:
5171                         status = set_user_info_11(p->mem_ctx,
5172                                                   &info->info11, pwd);
5173                         break;
5174
5175                 case 12:
5176                         status = set_user_info_12(p->mem_ctx,
5177                                                   &info->info12, pwd);
5178                         break;
5179
5180                 case 13:
5181                         status = set_user_info_13(p->mem_ctx,
5182                                                   &info->info13, pwd);
5183                         break;
5184
5185                 case 14:
5186                         status = set_user_info_14(p->mem_ctx,
5187                                                   &info->info14, pwd);
5188                         break;
5189
5190                 case 16:
5191                         status = set_user_info_16(p->mem_ctx,
5192                                                   &info->info16, pwd);
5193                         break;
5194
5195                 case 17:
5196                         status = set_user_info_17(p->mem_ctx,
5197                                                   &info->info17, pwd);
5198                         break;
5199
5200                 case 18:
5201                         /* Used by AS/U JRA. */
5202                         status = set_user_info_18(&info->info18,
5203                                                   p->mem_ctx,
5204                                                   &p->server_info->user_session_key,
5205                                                   pwd);
5206                         break;
5207
5208                 case 20:
5209                         status = set_user_info_20(p->mem_ctx,
5210                                                   &info->info20, pwd);
5211                         break;
5212
5213                 case 21:
5214                         status = set_user_info_21(&info->info21,
5215                                                   p->mem_ctx,
5216                                                   &p->server_info->user_session_key,
5217                                                   pwd);
5218                         break;
5219
5220                 case 23:
5221                         if (!p->server_info->user_session_key.length) {
5222                                 status = NT_STATUS_NO_USER_SESSION_KEY;
5223                         }
5224                         arcfour_crypt_blob(info->info23.password.data, 516,
5225                                            &p->server_info->user_session_key);
5226
5227                         dump_data(100, info->info23.password.data, 516);
5228
5229                         status = set_user_info_23(p->mem_ctx,
5230                                                   &info->info23, pwd);
5231                         break;
5232
5233                 case 24:
5234                         if (!p->server_info->user_session_key.length) {
5235                                 status = NT_STATUS_NO_USER_SESSION_KEY;
5236                         }
5237                         arcfour_crypt_blob(info->info24.password.data,
5238                                            516,
5239                                            &p->server_info->user_session_key);
5240
5241                         dump_data(100, info->info24.password.data, 516);
5242
5243                         status = set_user_info_24(p->mem_ctx,
5244                                                   &info->info24, pwd);
5245                         break;
5246
5247                 case 25:
5248                         if (!p->server_info->user_session_key.length) {
5249                                 status = NT_STATUS_NO_USER_SESSION_KEY;
5250                         }
5251                         encode_or_decode_arc4_passwd_buffer(
5252                                 info->info25.password.data,
5253                                 &p->server_info->user_session_key);
5254
5255                         dump_data(100, info->info25.password.data, 532);
5256
5257                         status = set_user_info_25(p->mem_ctx,
5258                                                   &info->info25, pwd);
5259                         break;
5260
5261                 case 26:
5262                         if (!p->server_info->user_session_key.length) {
5263                                 status = NT_STATUS_NO_USER_SESSION_KEY;
5264                         }
5265                         encode_or_decode_arc4_passwd_buffer(
5266                                 info->info26.password.data,
5267                                 &p->server_info->user_session_key);
5268
5269                         dump_data(100, info->info26.password.data, 516);
5270
5271                         status = set_user_info_26(p->mem_ctx,
5272                                                   &info->info26, pwd);
5273                         break;
5274
5275                 default:
5276                         status = NT_STATUS_INVALID_INFO_CLASS;
5277         }
5278
5279         TALLOC_FREE(pwd);
5280
5281         unbecome_root();
5282
5283         /* ================ END Privilege BLOCK ================ */
5284
5285         if (NT_STATUS_IS_OK(status)) {
5286                 force_flush_samr_cache(&uinfo->sid);
5287         }
5288
5289         return status;
5290 }
5291
5292 /*******************************************************************
5293  _samr_SetUserInfo2
5294  ********************************************************************/
5295
5296 NTSTATUS _samr_SetUserInfo2(pipes_struct *p,
5297                             struct samr_SetUserInfo2 *r)
5298 {
5299         struct samr_SetUserInfo q;
5300
5301         q.in.user_handle        = r->in.user_handle;
5302         q.in.level              = r->in.level;
5303         q.in.info               = r->in.info;
5304
5305         return _samr_SetUserInfo(p, &q);
5306 }
5307
5308 /*********************************************************************
5309  _samr_GetAliasMembership
5310 *********************************************************************/
5311
5312 NTSTATUS _samr_GetAliasMembership(pipes_struct *p,
5313                                   struct samr_GetAliasMembership *r)
5314 {
5315         size_t num_alias_rids;
5316         uint32 *alias_rids;
5317         struct samr_domain_info *dinfo;
5318         size_t i;
5319
5320         NTSTATUS status;
5321
5322         DOM_SID *members;
5323
5324         DEBUG(5,("_samr_GetAliasMembership: %d\n", __LINE__));
5325
5326         dinfo = policy_handle_find(p, r->in.domain_handle,
5327                                    SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS
5328                                    | SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
5329                                    struct samr_domain_info, &status);
5330         if (!NT_STATUS_IS_OK(status)) {
5331                 return status;
5332         }
5333
5334         if (!sid_check_is_domain(&dinfo->sid) &&
5335             !sid_check_is_builtin(&dinfo->sid))
5336                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
5337
5338         if (r->in.sids->num_sids) {
5339                 members = TALLOC_ARRAY(p->mem_ctx, DOM_SID, r->in.sids->num_sids);
5340
5341                 if (members == NULL)
5342                         return NT_STATUS_NO_MEMORY;
5343         } else {
5344                 members = NULL;
5345         }
5346
5347         for (i=0; i<r->in.sids->num_sids; i++)
5348                 sid_copy(&members[i], r->in.sids->sids[i].sid);
5349
5350         alias_rids = NULL;
5351         num_alias_rids = 0;
5352
5353         become_root();
5354         status = pdb_enum_alias_memberships(p->mem_ctx, &dinfo->sid, members,
5355                                             r->in.sids->num_sids,
5356                                             &alias_rids, &num_alias_rids);
5357         unbecome_root();
5358
5359         if (!NT_STATUS_IS_OK(status)) {
5360                 return status;
5361         }
5362
5363         r->out.rids->count = num_alias_rids;
5364         r->out.rids->ids = alias_rids;
5365
5366         if (r->out.rids->ids == NULL) {
5367                 /* Windows domain clients don't accept a NULL ptr here */
5368                 r->out.rids->ids = talloc_zero(p->mem_ctx, uint32_t);
5369         }
5370         if (r->out.rids->ids == NULL) {
5371                 return NT_STATUS_NO_MEMORY;
5372         }
5373
5374         return NT_STATUS_OK;
5375 }
5376
5377 /*********************************************************************
5378  _samr_GetMembersInAlias
5379 *********************************************************************/
5380
5381 NTSTATUS _samr_GetMembersInAlias(pipes_struct *p,
5382                                  struct samr_GetMembersInAlias *r)
5383 {
5384         struct samr_alias_info *ainfo;
5385         NTSTATUS status;
5386         size_t i;
5387         size_t num_sids = 0;
5388         struct lsa_SidPtr *sids = NULL;
5389         DOM_SID *pdb_sids = NULL;
5390
5391         ainfo = policy_handle_find(p, r->in.alias_handle,
5392                                    SAMR_ALIAS_ACCESS_GET_MEMBERS, NULL,
5393                                    struct samr_alias_info, &status);
5394         if (!NT_STATUS_IS_OK(status)) {
5395                 return status;
5396         }
5397
5398         DEBUG(10, ("sid is %s\n", sid_string_dbg(&ainfo->sid)));
5399
5400         become_root();
5401         status = pdb_enum_aliasmem(&ainfo->sid, talloc_tos(), &pdb_sids,
5402                                    &num_sids);
5403         unbecome_root();
5404
5405         if (!NT_STATUS_IS_OK(status)) {
5406                 return status;
5407         }
5408
5409         if (num_sids) {
5410                 sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_SidPtr, num_sids);
5411                 if (sids == NULL) {
5412                         TALLOC_FREE(pdb_sids);
5413                         return NT_STATUS_NO_MEMORY;
5414                 }
5415         }
5416
5417         for (i = 0; i < num_sids; i++) {
5418                 sids[i].sid = sid_dup_talloc(p->mem_ctx, &pdb_sids[i]);
5419                 if (!sids[i].sid) {
5420                         TALLOC_FREE(pdb_sids);
5421                         return NT_STATUS_NO_MEMORY;
5422                 }
5423         }
5424
5425         r->out.sids->num_sids = num_sids;
5426         r->out.sids->sids = sids;
5427
5428         TALLOC_FREE(pdb_sids);
5429
5430         return NT_STATUS_OK;
5431 }
5432
5433 /*********************************************************************
5434  _samr_QueryGroupMember
5435 *********************************************************************/
5436
5437 NTSTATUS _samr_QueryGroupMember(pipes_struct *p,
5438                                 struct samr_QueryGroupMember *r)
5439 {
5440         struct samr_group_info *ginfo;
5441         size_t i, num_members;
5442
5443         uint32 *rid=NULL;
5444         uint32 *attr=NULL;
5445
5446         NTSTATUS status;
5447         struct samr_RidTypeArray *rids = NULL;
5448
5449         ginfo = policy_handle_find(p, r->in.group_handle,
5450                                    SAMR_GROUP_ACCESS_GET_MEMBERS, NULL,
5451                                    struct samr_group_info, &status);
5452         if (!NT_STATUS_IS_OK(status)) {
5453                 return status;
5454         }
5455
5456         rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidTypeArray);
5457         if (!rids) {
5458                 return NT_STATUS_NO_MEMORY;
5459         }
5460
5461         DEBUG(10, ("sid is %s\n", sid_string_dbg(&ginfo->sid)));
5462
5463         if (!sid_check_is_in_our_domain(&ginfo->sid)) {
5464                 DEBUG(3, ("sid %s is not in our domain\n",
5465                           sid_string_dbg(&ginfo->sid)));
5466                 return NT_STATUS_NO_SUCH_GROUP;
5467         }
5468
5469         DEBUG(10, ("lookup on Domain SID\n"));
5470
5471         become_root();
5472         status = pdb_enum_group_members(p->mem_ctx, &ginfo->sid,
5473                                         &rid, &num_members);
5474         unbecome_root();
5475
5476         if (!NT_STATUS_IS_OK(status))
5477                 return status;
5478
5479         if (num_members) {
5480                 attr=TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_members);
5481                 if (attr == NULL) {
5482                         return NT_STATUS_NO_MEMORY;
5483                 }
5484         } else {
5485                 attr = NULL;
5486         }
5487
5488         for (i=0; i<num_members; i++)
5489                 attr[i] = SID_NAME_USER;
5490
5491         rids->count = num_members;
5492         rids->types = attr;
5493         rids->rids = rid;
5494
5495         *r->out.rids = rids;
5496
5497         return NT_STATUS_OK;
5498 }
5499
5500 /*********************************************************************
5501  _samr_AddAliasMember
5502 *********************************************************************/
5503
5504 NTSTATUS _samr_AddAliasMember(pipes_struct *p,
5505                               struct samr_AddAliasMember *r)
5506 {
5507         struct samr_alias_info *ainfo;
5508         NTSTATUS status;
5509
5510         ainfo = policy_handle_find(p, r->in.alias_handle,
5511                                    SAMR_ALIAS_ACCESS_ADD_MEMBER, NULL,
5512                                    struct samr_alias_info, &status);
5513         if (!NT_STATUS_IS_OK(status)) {
5514                 return status;
5515         }
5516
5517         DEBUG(10, ("sid is %s\n", sid_string_dbg(&ainfo->sid)));
5518
5519         /******** BEGIN SeAddUsers BLOCK *********/
5520
5521         become_root();
5522         status = pdb_add_aliasmem(&ainfo->sid, r->in.sid);
5523         unbecome_root();
5524
5525         /******** END SeAddUsers BLOCK *********/
5526
5527         if (NT_STATUS_IS_OK(status)) {
5528                 force_flush_samr_cache(&ainfo->sid);
5529         }
5530
5531         return status;
5532 }
5533
5534 /*********************************************************************
5535  _samr_DeleteAliasMember
5536 *********************************************************************/
5537
5538 NTSTATUS _samr_DeleteAliasMember(pipes_struct *p,
5539                                  struct samr_DeleteAliasMember *r)
5540 {
5541         struct samr_alias_info *ainfo;
5542         NTSTATUS status;
5543
5544         ainfo = policy_handle_find(p, r->in.alias_handle,
5545                                    SAMR_ALIAS_ACCESS_REMOVE_MEMBER, NULL,
5546                                    struct samr_alias_info, &status);
5547         if (!NT_STATUS_IS_OK(status)) {
5548                 return status;
5549         }
5550
5551         DEBUG(10, ("_samr_del_aliasmem:sid is %s\n",
5552                    sid_string_dbg(&ainfo->sid)));
5553
5554         /******** BEGIN SeAddUsers BLOCK *********/
5555
5556         become_root();
5557         status = pdb_del_aliasmem(&ainfo->sid, r->in.sid);
5558         unbecome_root();
5559
5560         /******** END SeAddUsers BLOCK *********/
5561
5562         if (NT_STATUS_IS_OK(status)) {
5563                 force_flush_samr_cache(&ainfo->sid);
5564         }
5565
5566         return status;
5567 }
5568
5569 /*********************************************************************
5570  _samr_AddGroupMember
5571 *********************************************************************/
5572
5573 NTSTATUS _samr_AddGroupMember(pipes_struct *p,
5574                               struct samr_AddGroupMember *r)
5575 {
5576         struct samr_group_info *ginfo;
5577         NTSTATUS status;
5578         uint32 group_rid;
5579
5580         ginfo = policy_handle_find(p, r->in.group_handle,
5581                                    SAMR_GROUP_ACCESS_ADD_MEMBER, NULL,
5582                                    struct samr_group_info, &status);
5583         if (!NT_STATUS_IS_OK(status)) {
5584                 return status;
5585         }
5586
5587         DEBUG(10, ("sid is %s\n", sid_string_dbg(&ginfo->sid)));
5588
5589         if (!sid_peek_check_rid(get_global_sam_sid(), &ginfo->sid,
5590                                 &group_rid)) {
5591                 return NT_STATUS_INVALID_HANDLE;
5592         }
5593
5594         /******** BEGIN SeAddUsers BLOCK *********/
5595
5596         become_root();
5597         status = pdb_add_groupmem(p->mem_ctx, group_rid, r->in.rid);
5598         unbecome_root();
5599
5600         /******** END SeAddUsers BLOCK *********/
5601
5602         force_flush_samr_cache(&ginfo->sid);
5603
5604         return status;
5605 }
5606
5607 /*********************************************************************
5608  _samr_DeleteGroupMember
5609 *********************************************************************/
5610
5611 NTSTATUS _samr_DeleteGroupMember(pipes_struct *p,
5612                                  struct samr_DeleteGroupMember *r)
5613
5614 {
5615         struct samr_group_info *ginfo;
5616         NTSTATUS status;
5617         uint32 group_rid;
5618
5619         /*
5620          * delete the group member named r->in.rid
5621          * who is a member of the sid associated with the handle
5622          * the rid is a user's rid as the group is a domain group.
5623          */
5624
5625         ginfo = policy_handle_find(p, r->in.group_handle,
5626                                    SAMR_GROUP_ACCESS_REMOVE_MEMBER, NULL,
5627                                    struct samr_group_info, &status);
5628         if (!NT_STATUS_IS_OK(status)) {
5629                 return status;
5630         }
5631
5632         if (!sid_peek_check_rid(get_global_sam_sid(), &ginfo->sid,
5633                                 &group_rid)) {
5634                 return NT_STATUS_INVALID_HANDLE;
5635         }
5636
5637         /******** BEGIN SeAddUsers BLOCK *********/
5638
5639         become_root();
5640         status = pdb_del_groupmem(p->mem_ctx, group_rid, r->in.rid);
5641         unbecome_root();
5642
5643         /******** END SeAddUsers BLOCK *********/
5644
5645         force_flush_samr_cache(&ginfo->sid);
5646
5647         return status;
5648 }
5649
5650 /*********************************************************************
5651  _samr_DeleteUser
5652 *********************************************************************/
5653
5654 NTSTATUS _samr_DeleteUser(pipes_struct *p,
5655                           struct samr_DeleteUser *r)
5656 {
5657         struct samr_user_info *uinfo;
5658         NTSTATUS status;
5659         struct samu *sam_pass=NULL;
5660         bool ret;
5661
5662         DEBUG(5, ("_samr_DeleteUser: %d\n", __LINE__));
5663
5664         uinfo = policy_handle_find(p, r->in.user_handle,
5665                                    STD_RIGHT_DELETE_ACCESS, NULL,
5666                                    struct samr_user_info, &status);
5667         if (!NT_STATUS_IS_OK(status)) {
5668                 return status;
5669         }
5670
5671         if (!sid_check_is_in_our_domain(&uinfo->sid))
5672                 return NT_STATUS_CANNOT_DELETE;
5673
5674         /* check if the user exists before trying to delete */
5675         if ( !(sam_pass = samu_new( NULL )) ) {
5676                 return NT_STATUS_NO_MEMORY;
5677         }
5678
5679         become_root();
5680         ret = pdb_getsampwsid(sam_pass, &uinfo->sid);
5681         unbecome_root();
5682
5683         if(!ret) {
5684                 DEBUG(5,("_samr_DeleteUser: User %s doesn't exist.\n",
5685                         sid_string_dbg(&uinfo->sid)));
5686                 TALLOC_FREE(sam_pass);
5687                 return NT_STATUS_NO_SUCH_USER;
5688         }
5689
5690         /******** BEGIN SeAddUsers BLOCK *********/
5691
5692         become_root();
5693         status = pdb_delete_user(p->mem_ctx, sam_pass);
5694         unbecome_root();
5695
5696         /******** END SeAddUsers BLOCK *********/
5697
5698         if ( !NT_STATUS_IS_OK(status) ) {
5699                 DEBUG(5,("_samr_DeleteUser: Failed to delete entry for "
5700                          "user %s: %s.\n", pdb_get_username(sam_pass),
5701                          nt_errstr(status)));
5702                 TALLOC_FREE(sam_pass);
5703                 return status;
5704         }
5705
5706
5707         TALLOC_FREE(sam_pass);
5708
5709         force_flush_samr_cache(&uinfo->sid);
5710
5711         if (!close_policy_hnd(p, r->in.user_handle))
5712                 return NT_STATUS_OBJECT_NAME_INVALID;
5713
5714         ZERO_STRUCTP(r->out.user_handle);
5715
5716         return NT_STATUS_OK;
5717 }
5718
5719 /*********************************************************************
5720  _samr_DeleteDomainGroup
5721 *********************************************************************/
5722
5723 NTSTATUS _samr_DeleteDomainGroup(pipes_struct *p,
5724                                  struct samr_DeleteDomainGroup *r)
5725 {
5726         struct samr_group_info *ginfo;
5727         NTSTATUS status;
5728         uint32 group_rid;
5729
5730         DEBUG(5, ("samr_DeleteDomainGroup: %d\n", __LINE__));
5731
5732         ginfo = policy_handle_find(p, r->in.group_handle,
5733                                    STD_RIGHT_DELETE_ACCESS, NULL,
5734                                    struct samr_group_info, &status);
5735         if (!NT_STATUS_IS_OK(status)) {
5736                 return status;
5737         }
5738
5739         DEBUG(10, ("sid is %s\n", sid_string_dbg(&ginfo->sid)));
5740
5741         if (!sid_peek_check_rid(get_global_sam_sid(), &ginfo->sid,
5742                                 &group_rid)) {
5743                 return NT_STATUS_NO_SUCH_GROUP;
5744         }
5745
5746         /******** BEGIN SeAddUsers BLOCK *********/
5747
5748         become_root();
5749         status = pdb_delete_dom_group(p->mem_ctx, group_rid);
5750         unbecome_root();
5751
5752         /******** END SeAddUsers BLOCK *********/
5753
5754         if ( !NT_STATUS_IS_OK(status) ) {
5755                 DEBUG(5,("_samr_DeleteDomainGroup: Failed to delete mapping "
5756                          "entry for group %s: %s\n",
5757                          sid_string_dbg(&ginfo->sid),
5758                          nt_errstr(status)));
5759                 return status;
5760         }
5761
5762         force_flush_samr_cache(&ginfo->sid);
5763
5764         if (!close_policy_hnd(p, r->in.group_handle))
5765                 return NT_STATUS_OBJECT_NAME_INVALID;
5766
5767         return NT_STATUS_OK;
5768 }
5769
5770 /*********************************************************************
5771  _samr_DeleteDomAlias
5772 *********************************************************************/
5773
5774 NTSTATUS _samr_DeleteDomAlias(pipes_struct *p,
5775                               struct samr_DeleteDomAlias *r)
5776 {
5777         struct samr_alias_info *ainfo;
5778         NTSTATUS status;
5779
5780         DEBUG(5, ("_samr_DeleteDomAlias: %d\n", __LINE__));
5781
5782         ainfo = policy_handle_find(p, r->in.alias_handle,
5783                                    STD_RIGHT_DELETE_ACCESS, NULL,
5784                                    struct samr_alias_info, &status);
5785         if (!NT_STATUS_IS_OK(status)) {
5786                 return status;
5787         }
5788
5789         DEBUG(10, ("sid is %s\n", sid_string_dbg(&ainfo->sid)));
5790
5791         /* Don't let Windows delete builtin groups */
5792
5793         if ( sid_check_is_in_builtin( &ainfo->sid ) ) {
5794                 return NT_STATUS_SPECIAL_ACCOUNT;
5795         }
5796
5797         if (!sid_check_is_in_our_domain(&ainfo->sid))
5798                 return NT_STATUS_NO_SUCH_ALIAS;
5799
5800         DEBUG(10, ("lookup on Local SID\n"));
5801
5802         /******** BEGIN SeAddUsers BLOCK *********/
5803
5804         become_root();
5805         /* Have passdb delete the alias */
5806         status = pdb_delete_alias(&ainfo->sid);
5807         unbecome_root();
5808
5809         /******** END SeAddUsers BLOCK *********/
5810
5811         if ( !NT_STATUS_IS_OK(status))
5812                 return status;
5813
5814         force_flush_samr_cache(&ainfo->sid);
5815
5816         if (!close_policy_hnd(p, r->in.alias_handle))
5817                 return NT_STATUS_OBJECT_NAME_INVALID;
5818
5819         return NT_STATUS_OK;
5820 }
5821
5822 /*********************************************************************
5823  _samr_CreateDomainGroup
5824 *********************************************************************/
5825
5826 NTSTATUS _samr_CreateDomainGroup(pipes_struct *p,
5827                                  struct samr_CreateDomainGroup *r)
5828
5829 {
5830         NTSTATUS status;
5831         const char *name;
5832         struct samr_domain_info *dinfo;
5833         struct samr_group_info *ginfo;
5834
5835         dinfo = policy_handle_find(p, r->in.domain_handle,
5836                                    SAMR_DOMAIN_ACCESS_CREATE_GROUP, NULL,
5837                                    struct samr_domain_info, &status);
5838         if (!NT_STATUS_IS_OK(status)) {
5839                 return status;
5840         }
5841
5842         if (!sid_check_is_domain(&dinfo->sid)) {
5843                 return NT_STATUS_ACCESS_DENIED;
5844         }
5845
5846         name = r->in.name->string;
5847         if (name == NULL) {
5848                 return NT_STATUS_NO_MEMORY;
5849         }
5850
5851         status = can_create(p->mem_ctx, name);
5852         if (!NT_STATUS_IS_OK(status)) {
5853                 return status;
5854         }
5855
5856         /******** BEGIN SeAddUsers BLOCK *********/
5857
5858         become_root();
5859         /* check that we successfully create the UNIX group */
5860         status = pdb_create_dom_group(p->mem_ctx, name, r->out.rid);
5861         unbecome_root();
5862
5863         /******** END SeAddUsers BLOCK *********/
5864
5865         /* check if we should bail out here */
5866
5867         if ( !NT_STATUS_IS_OK(status) )
5868                 return status;
5869
5870         ginfo = policy_handle_create(p, r->out.group_handle,
5871                                      GENERIC_RIGHTS_GROUP_ALL_ACCESS,
5872                                      struct samr_group_info, &status);
5873         if (!NT_STATUS_IS_OK(status)) {
5874                 return status;
5875         }
5876         sid_compose(&ginfo->sid, &dinfo->sid, *r->out.rid);
5877
5878         force_flush_samr_cache(&dinfo->sid);
5879
5880         return NT_STATUS_OK;
5881 }
5882
5883 /*********************************************************************
5884  _samr_CreateDomAlias
5885 *********************************************************************/
5886
5887 NTSTATUS _samr_CreateDomAlias(pipes_struct *p,
5888                               struct samr_CreateDomAlias *r)
5889 {
5890         DOM_SID info_sid;
5891         const char *name = NULL;
5892         struct samr_domain_info *dinfo;
5893         struct samr_alias_info *ainfo;
5894         gid_t gid;
5895         NTSTATUS result;
5896
5897         dinfo = policy_handle_find(p, r->in.domain_handle,
5898                                    SAMR_DOMAIN_ACCESS_CREATE_ALIAS, NULL,
5899                                    struct samr_domain_info, &result);
5900         if (!NT_STATUS_IS_OK(result)) {
5901                 return result;
5902         }
5903
5904         if (!sid_check_is_domain(&dinfo->sid)) {
5905                 return NT_STATUS_ACCESS_DENIED;
5906         }
5907
5908         name = r->in.alias_name->string;
5909
5910         result = can_create(p->mem_ctx, name);
5911         if (!NT_STATUS_IS_OK(result)) {
5912                 return result;
5913         }
5914
5915         /******** BEGIN SeAddUsers BLOCK *********/
5916
5917         become_root();
5918         /* Have passdb create the alias */
5919         result = pdb_create_alias(name, r->out.rid);
5920         unbecome_root();
5921
5922         /******** END SeAddUsers BLOCK *********/
5923
5924         if (!NT_STATUS_IS_OK(result)) {
5925                 DEBUG(10, ("pdb_create_alias failed: %s\n",
5926                            nt_errstr(result)));
5927                 return result;
5928         }
5929
5930         sid_compose(&info_sid, &dinfo->sid, *r->out.rid);
5931
5932         if (!sid_to_gid(&info_sid, &gid)) {
5933                 DEBUG(10, ("Could not find alias just created\n"));
5934                 return NT_STATUS_ACCESS_DENIED;
5935         }
5936
5937         /* check if the group has been successfully created */
5938         if ( getgrgid(gid) == NULL ) {
5939                 DEBUG(10, ("getgrgid(%u) of just created alias failed\n",
5940                            (unsigned int)gid));
5941                 return NT_STATUS_ACCESS_DENIED;
5942         }
5943
5944         ainfo = policy_handle_create(p, r->out.alias_handle,
5945                                      GENERIC_RIGHTS_ALIAS_ALL_ACCESS,
5946                                      struct samr_alias_info, &result);
5947         if (!NT_STATUS_IS_OK(result)) {
5948                 return result;
5949         }
5950         ainfo->sid = info_sid;
5951
5952         force_flush_samr_cache(&info_sid);
5953
5954         return NT_STATUS_OK;
5955 }
5956
5957 /*********************************************************************
5958  _samr_QueryGroupInfo
5959 *********************************************************************/
5960
5961 NTSTATUS _samr_QueryGroupInfo(pipes_struct *p,
5962                               struct samr_QueryGroupInfo *r)
5963 {
5964         struct samr_group_info *ginfo;
5965         NTSTATUS status;
5966         GROUP_MAP map;
5967         union samr_GroupInfo *info = NULL;
5968         bool ret;
5969         uint32_t attributes = SE_GROUP_MANDATORY |
5970                               SE_GROUP_ENABLED_BY_DEFAULT |
5971                               SE_GROUP_ENABLED;
5972         const char *group_name = NULL;
5973         const char *group_description = NULL;
5974
5975         ginfo = policy_handle_find(p, r->in.group_handle,
5976                                    SAMR_GROUP_ACCESS_LOOKUP_INFO, NULL,
5977                                    struct samr_group_info, &status);
5978         if (!NT_STATUS_IS_OK(status)) {
5979                 return status;
5980         }
5981
5982         become_root();
5983         ret = get_domain_group_from_sid(ginfo->sid, &map);
5984         unbecome_root();
5985         if (!ret)
5986                 return NT_STATUS_INVALID_HANDLE;
5987
5988         /* FIXME: map contains fstrings */
5989         group_name = talloc_strdup(r, map.nt_name);
5990         group_description = talloc_strdup(r, map.comment);
5991
5992         info = TALLOC_ZERO_P(p->mem_ctx, union samr_GroupInfo);
5993         if (!info) {
5994                 return NT_STATUS_NO_MEMORY;
5995         }
5996
5997         switch (r->in.level) {
5998                 case 1: {
5999                         uint32 *members;
6000                         size_t num_members;
6001
6002                         become_root();
6003                         status = pdb_enum_group_members(
6004                                 p->mem_ctx, &ginfo->sid, &members,
6005                                 &num_members);
6006                         unbecome_root();
6007
6008                         if (!NT_STATUS_IS_OK(status)) {
6009                                 return status;
6010                         }
6011
6012                         info->all.name.string           = group_name;
6013                         info->all.attributes            = attributes;
6014                         info->all.num_members           = num_members;
6015                         info->all.description.string    = group_description;
6016                         break;
6017                 }
6018                 case 2:
6019                         info->name.string = group_name;
6020                         break;
6021                 case 3:
6022                         info->attributes.attributes = attributes;
6023                         break;
6024                 case 4:
6025                         info->description.string = group_description;
6026                         break;
6027                 case 5: {
6028                         /*
6029                         uint32 *members;
6030                         size_t num_members;
6031                         */
6032
6033                         /*
6034                         become_root();
6035                         status = pdb_enum_group_members(
6036                                 p->mem_ctx, &ginfo->sid, &members,
6037                                 &num_members);
6038                         unbecome_root();
6039
6040                         if (!NT_STATUS_IS_OK(status)) {
6041                                 return status;
6042                         }
6043                         */
6044                         info->all2.name.string          = group_name;
6045                         info->all2.attributes           = attributes;
6046                         info->all2.num_members          = 0; /* num_members - in w2k3 this is always 0 */
6047                         info->all2.description.string   = group_description;
6048
6049                         break;
6050                 }
6051                 default:
6052                         return NT_STATUS_INVALID_INFO_CLASS;
6053         }
6054
6055         *r->out.info = info;
6056
6057         return NT_STATUS_OK;
6058 }
6059
6060 /*********************************************************************
6061  _samr_SetGroupInfo
6062 *********************************************************************/
6063
6064 NTSTATUS _samr_SetGroupInfo(pipes_struct *p,
6065                             struct samr_SetGroupInfo *r)
6066 {
6067         struct samr_group_info *ginfo;
6068         GROUP_MAP map;
6069         NTSTATUS status;
6070         bool ret;
6071
6072         ginfo = policy_handle_find(p, r->in.group_handle,
6073                                    SAMR_GROUP_ACCESS_SET_INFO, NULL,
6074                                    struct samr_group_info, &status);
6075         if (!NT_STATUS_IS_OK(status)) {
6076                 return status;
6077         }
6078
6079         become_root();
6080         ret = get_domain_group_from_sid(ginfo->sid, &map);
6081         unbecome_root();
6082         if (!ret)
6083                 return NT_STATUS_NO_SUCH_GROUP;
6084
6085         switch (r->in.level) {
6086                 case 2:
6087                         fstrcpy(map.nt_name, r->in.info->name.string);
6088                         break;
6089                 case 3:
6090                         break;
6091                 case 4:
6092                         fstrcpy(map.comment, r->in.info->description.string);
6093                         break;
6094                 default:
6095                         return NT_STATUS_INVALID_INFO_CLASS;
6096         }
6097
6098         /******** BEGIN SeAddUsers BLOCK *********/
6099
6100         become_root();
6101         status = pdb_update_group_mapping_entry(&map);
6102         unbecome_root();
6103
6104         /******** End SeAddUsers BLOCK *********/
6105
6106         if (NT_STATUS_IS_OK(status)) {
6107                 force_flush_samr_cache(&ginfo->sid);
6108         }
6109
6110         return status;
6111 }
6112
6113 /*********************************************************************
6114  _samr_SetAliasInfo
6115 *********************************************************************/
6116
6117 NTSTATUS _samr_SetAliasInfo(pipes_struct *p,
6118                             struct samr_SetAliasInfo *r)
6119 {
6120         struct samr_alias_info *ainfo;
6121         struct acct_info info;
6122         NTSTATUS status;
6123
6124         ainfo = policy_handle_find(p, r->in.alias_handle,
6125                                    SAMR_ALIAS_ACCESS_SET_INFO, NULL,
6126                                    struct samr_alias_info, &status);
6127         if (!NT_STATUS_IS_OK(status)) {
6128                 return status;
6129         }
6130
6131         /* get the current group information */
6132
6133         become_root();
6134         status = pdb_get_aliasinfo( &ainfo->sid, &info );
6135         unbecome_root();
6136
6137         if ( !NT_STATUS_IS_OK(status))
6138                 return status;
6139
6140         switch (r->in.level) {
6141                 case ALIASINFONAME:
6142                 {
6143                         fstring group_name;
6144
6145                         /* We currently do not support renaming groups in the
6146                            the BUILTIN domain.  Refer to util_builtin.c to understand
6147                            why.  The eventually needs to be fixed to be like Windows
6148                            where you can rename builtin groups, just not delete them */
6149
6150                         if ( sid_check_is_in_builtin( &ainfo->sid ) ) {
6151                                 return NT_STATUS_SPECIAL_ACCOUNT;
6152                         }
6153
6154                         /* There has to be a valid name (and it has to be different) */
6155
6156                         if ( !r->in.info->name.string )
6157                                 return NT_STATUS_INVALID_PARAMETER;
6158
6159                         /* If the name is the same just reply "ok".  Yes this
6160                            doesn't allow you to change the case of a group name. */
6161
6162                         if ( strequal( r->in.info->name.string, info.acct_name ) )
6163                                 return NT_STATUS_OK;
6164
6165                         fstrcpy( info.acct_name, r->in.info->name.string);
6166
6167                         /* make sure the name doesn't already exist as a user
6168                            or local group */
6169
6170                         fstr_sprintf( group_name, "%s\\%s", global_myname(), info.acct_name );
6171                         status = can_create( p->mem_ctx, group_name );
6172                         if ( !NT_STATUS_IS_OK( status ) )
6173                                 return status;
6174                         break;
6175                 }
6176                 case ALIASINFODESCRIPTION:
6177                         if (r->in.info->description.string) {
6178                                 fstrcpy(info.acct_desc,
6179                                         r->in.info->description.string);
6180                         } else {
6181                                 fstrcpy( info.acct_desc, "" );
6182                         }
6183                         break;
6184                 default:
6185                         return NT_STATUS_INVALID_INFO_CLASS;
6186         }
6187
6188         /******** BEGIN SeAddUsers BLOCK *********/
6189
6190         become_root();
6191         status = pdb_set_aliasinfo( &ainfo->sid, &info );
6192         unbecome_root();
6193
6194         /******** End SeAddUsers BLOCK *********/
6195
6196         if (NT_STATUS_IS_OK(status))
6197                 force_flush_samr_cache(&ainfo->sid);
6198
6199         return status;
6200 }
6201
6202 /****************************************************************
6203  _samr_GetDomPwInfo
6204 ****************************************************************/
6205
6206 NTSTATUS _samr_GetDomPwInfo(pipes_struct *p,
6207                             struct samr_GetDomPwInfo *r)
6208 {
6209         uint32_t min_password_length = 0;
6210         uint32_t password_properties = 0;
6211
6212         /* Perform access check.  Since this rpc does not require a
6213            policy handle it will not be caught by the access checks on
6214            SAMR_CONNECT or SAMR_CONNECT_ANON. */
6215
6216         if (!pipe_access_check(p)) {
6217                 DEBUG(3, ("access denied to _samr_GetDomPwInfo\n"));
6218                 return NT_STATUS_ACCESS_DENIED;
6219         }
6220
6221         become_root();
6222         pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN,
6223                                &min_password_length);
6224         pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
6225                                &password_properties);
6226         unbecome_root();
6227
6228         if (lp_check_password_script() && *lp_check_password_script()) {
6229                 password_properties |= DOMAIN_PASSWORD_COMPLEX;
6230         }
6231
6232         r->out.info->min_password_length = min_password_length;
6233         r->out.info->password_properties = password_properties;
6234
6235         return NT_STATUS_OK;
6236 }
6237
6238 /*********************************************************************
6239  _samr_OpenGroup
6240 *********************************************************************/
6241
6242 NTSTATUS _samr_OpenGroup(pipes_struct *p,
6243                          struct samr_OpenGroup *r)
6244
6245 {
6246         DOM_SID info_sid;
6247         GROUP_MAP map;
6248         struct samr_domain_info *dinfo;
6249         struct samr_group_info *ginfo;
6250         SEC_DESC         *psd = NULL;
6251         uint32            acc_granted;
6252         uint32            des_access = r->in.access_mask;
6253         size_t            sd_size;
6254         NTSTATUS          status;
6255         bool ret;
6256         SE_PRIV se_rights;
6257
6258         dinfo = policy_handle_find(p, r->in.domain_handle,
6259                                    SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
6260                                    struct samr_domain_info, &status);
6261         if (!NT_STATUS_IS_OK(status)) {
6262                 return status;
6263         }
6264
6265         /*check if access can be granted as requested by client. */
6266         map_max_allowed_access(p->server_info->ptok,
6267                                &p->server_info->utok,
6268                                &des_access);
6269
6270         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &grp_generic_mapping, NULL, 0);
6271         se_map_generic(&des_access,&grp_generic_mapping);
6272
6273         se_priv_copy( &se_rights, &se_add_users );
6274
6275         status = access_check_object(psd, p->server_info->ptok,
6276                 &se_rights, GENERIC_RIGHTS_GROUP_ALL_ACCESS,
6277                 des_access, &acc_granted, "_samr_OpenGroup");
6278
6279         if ( !NT_STATUS_IS_OK(status) )
6280                 return status;
6281
6282         /* this should not be hard-coded like this */
6283
6284         if (!sid_check_is_domain(&dinfo->sid)) {
6285                 return NT_STATUS_ACCESS_DENIED;
6286         }
6287
6288         sid_compose(&info_sid, &dinfo->sid, r->in.rid);
6289
6290         DEBUG(10, ("_samr_OpenGroup:Opening SID: %s\n",
6291                    sid_string_dbg(&info_sid)));
6292
6293         /* check if that group really exists */
6294         become_root();
6295         ret = get_domain_group_from_sid(info_sid, &map);
6296         unbecome_root();
6297         if (!ret)
6298                 return NT_STATUS_NO_SUCH_GROUP;
6299
6300         ginfo = policy_handle_create(p, r->out.group_handle,
6301                                      acc_granted,
6302                                      struct samr_group_info, &status);
6303         if (!NT_STATUS_IS_OK(status)) {
6304                 return status;
6305         }
6306         ginfo->sid = info_sid;
6307
6308         return NT_STATUS_OK;
6309 }
6310
6311 /*********************************************************************
6312  _samr_RemoveMemberFromForeignDomain
6313 *********************************************************************/
6314
6315 NTSTATUS _samr_RemoveMemberFromForeignDomain(pipes_struct *p,
6316                                              struct samr_RemoveMemberFromForeignDomain *r)
6317 {
6318         struct samr_domain_info *dinfo;
6319         NTSTATUS                result;
6320
6321         DEBUG(5,("_samr_RemoveMemberFromForeignDomain: removing SID [%s]\n",
6322                  sid_string_dbg(r->in.sid)));
6323
6324         /* Find the policy handle. Open a policy on it. */
6325
6326         dinfo = policy_handle_find(p, r->in.domain_handle,
6327                                    SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
6328                                    struct samr_domain_info, &result);
6329         if (!NT_STATUS_IS_OK(result)) {
6330                 return result;
6331         }
6332
6333         DEBUG(8, ("_samr_RemoveMemberFromForeignDomain: sid is %s\n",
6334                   sid_string_dbg(&dinfo->sid)));
6335
6336         /* we can only delete a user from a group since we don't have
6337            nested groups anyways.  So in the latter case, just say OK */
6338
6339         /* TODO: The above comment nowadays is bogus. Since we have nested
6340          * groups now, and aliases members are never reported out of the unix
6341          * group membership, the "just say OK" makes this call a no-op. For
6342          * us. This needs fixing however. */
6343
6344         /* I've only ever seen this in the wild when deleting a user from
6345          * usrmgr.exe. domain_sid is the builtin domain, and the sid to delete
6346          * is the user about to be deleted. I very much suspect this is the
6347          * only application of this call. To verify this, let people report
6348          * other cases. */
6349
6350         if (!sid_check_is_builtin(&dinfo->sid)) {
6351                 DEBUG(1,("_samr_RemoveMemberFromForeignDomain: domain_sid = %s, "
6352                          "global_sam_sid() = %s\n",
6353                          sid_string_dbg(&dinfo->sid),
6354                          sid_string_dbg(get_global_sam_sid())));
6355                 DEBUGADD(1,("please report to samba-technical@samba.org!\n"));
6356                 return NT_STATUS_OK;
6357         }
6358
6359         force_flush_samr_cache(&dinfo->sid);
6360
6361         result = NT_STATUS_OK;
6362
6363         return result;
6364 }
6365
6366 /*******************************************************************
6367  _samr_QueryDomainInfo2
6368  ********************************************************************/
6369
6370 NTSTATUS _samr_QueryDomainInfo2(pipes_struct *p,
6371                                 struct samr_QueryDomainInfo2 *r)
6372 {
6373         struct samr_QueryDomainInfo q;
6374
6375         q.in.domain_handle      = r->in.domain_handle;
6376         q.in.level              = r->in.level;
6377
6378         q.out.info              = r->out.info;
6379
6380         return _samr_QueryDomainInfo(p, &q);
6381 }
6382
6383 /*******************************************************************
6384  ********************************************************************/
6385
6386 static NTSTATUS set_dom_info_1(TALLOC_CTX *mem_ctx,
6387                                struct samr_DomInfo1 *r)
6388 {
6389         time_t u_expire, u_min_age;
6390
6391         u_expire = nt_time_to_unix_abs((NTTIME *)&r->max_password_age);
6392         u_min_age = nt_time_to_unix_abs((NTTIME *)&r->min_password_age);
6393
6394         pdb_set_account_policy(PDB_POLICY_MIN_PASSWORD_LEN,
6395                                (uint32_t)r->min_password_length);
6396         pdb_set_account_policy(PDB_POLICY_PASSWORD_HISTORY,
6397                                (uint32_t)r->password_history_length);
6398         pdb_set_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
6399                                (uint32_t)r->password_properties);
6400         pdb_set_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, (int)u_expire);
6401         pdb_set_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, (int)u_min_age);
6402
6403         return NT_STATUS_OK;
6404 }
6405
6406 /*******************************************************************
6407  ********************************************************************/
6408
6409 static NTSTATUS set_dom_info_3(TALLOC_CTX *mem_ctx,
6410                                struct samr_DomInfo3 *r)
6411 {
6412         time_t u_logout;
6413
6414         u_logout = nt_time_to_unix_abs((NTTIME *)&r->force_logoff_time);
6415
6416         pdb_set_account_policy(PDB_POLICY_TIME_TO_LOGOUT, (int)u_logout);
6417
6418         return NT_STATUS_OK;
6419 }
6420
6421 /*******************************************************************
6422  ********************************************************************/
6423
6424 static NTSTATUS set_dom_info_12(TALLOC_CTX *mem_ctx,
6425                                 struct samr_DomInfo12 *r)
6426 {
6427         time_t u_lock_duration, u_reset_time;
6428
6429         u_lock_duration = nt_time_to_unix_abs((NTTIME *)&r->lockout_duration);
6430         if (u_lock_duration != -1) {
6431                 u_lock_duration /= 60;
6432         }
6433
6434         u_reset_time = nt_time_to_unix_abs((NTTIME *)&r->lockout_window)/60;
6435
6436         pdb_set_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
6437         pdb_set_account_policy(PDB_POLICY_RESET_COUNT_TIME, (int)u_reset_time);
6438         pdb_set_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT,
6439                                (uint32_t)r->lockout_threshold);
6440
6441         return NT_STATUS_OK;
6442 }
6443
6444 /*******************************************************************
6445  _samr_SetDomainInfo
6446  ********************************************************************/
6447
6448 NTSTATUS _samr_SetDomainInfo(pipes_struct *p,
6449                              struct samr_SetDomainInfo *r)
6450 {
6451         struct samr_domain_info *dinfo;
6452         NTSTATUS status;
6453         uint32_t acc_required = 0;
6454
6455         DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
6456
6457         switch (r->in.level) {
6458         case 1: /* DomainPasswordInformation */
6459         case 12: /* DomainLockoutInformation */
6460                 /* DOMAIN_WRITE_PASSWORD_PARAMETERS */
6461                 acc_required = SAMR_DOMAIN_ACCESS_SET_INFO_1;
6462                 break;
6463         case 3: /* DomainLogoffInformation */
6464         case 4: /* DomainOemInformation */
6465                 /* DOMAIN_WRITE_OTHER_PARAMETERS */
6466                 acc_required = SAMR_DOMAIN_ACCESS_SET_INFO_2;
6467                 break;
6468         case 6: /* DomainReplicationInformation */
6469         case 9: /* DomainStateInformation */
6470         case 7: /* DomainServerRoleInformation */
6471                 /* DOMAIN_ADMINISTER_SERVER */
6472                 acc_required = SAMR_DOMAIN_ACCESS_SET_INFO_3;
6473                 break;
6474         default:
6475                 return NT_STATUS_INVALID_INFO_CLASS;
6476         }
6477
6478         dinfo = policy_handle_find(p, r->in.domain_handle,
6479                                    acc_required, NULL,
6480                                    struct samr_domain_info, &status);
6481         if (!NT_STATUS_IS_OK(status)) {
6482                 return status;
6483         }
6484
6485         DEBUG(5,("_samr_SetDomainInfo: level: %d\n", r->in.level));
6486
6487         switch (r->in.level) {
6488                 case 1:
6489                         status = set_dom_info_1(p->mem_ctx, &r->in.info->info1);
6490                         break;
6491                 case 3:
6492                         status = set_dom_info_3(p->mem_ctx, &r->in.info->info3);
6493                         break;
6494                 case 4:
6495                         break;
6496                 case 6:
6497                         break;
6498                 case 7:
6499                         break;
6500                 case 9:
6501                         break;
6502                 case 12:
6503                         status = set_dom_info_12(p->mem_ctx, &r->in.info->info12);
6504                         break;
6505                 default:
6506                         return NT_STATUS_INVALID_INFO_CLASS;
6507         }
6508
6509         if (!NT_STATUS_IS_OK(status)) {
6510                 return status;
6511         }
6512
6513         DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
6514
6515         return NT_STATUS_OK;
6516 }
6517
6518 /****************************************************************
6519  _samr_GetDisplayEnumerationIndex
6520 ****************************************************************/
6521
6522 NTSTATUS _samr_GetDisplayEnumerationIndex(pipes_struct *p,
6523                                           struct samr_GetDisplayEnumerationIndex *r)
6524 {
6525         struct samr_domain_info *dinfo;
6526         uint32_t max_entries = (uint32_t) -1;
6527         uint32_t enum_context = 0;
6528         int i;
6529         uint32_t num_account = 0;
6530         struct samr_displayentry *entries = NULL;
6531         NTSTATUS status;
6532
6533         DEBUG(5,("_samr_GetDisplayEnumerationIndex: %d\n", __LINE__));
6534
6535         dinfo = policy_handle_find(p, r->in.domain_handle,
6536                                    SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
6537                                    struct samr_domain_info, &status);
6538         if (!NT_STATUS_IS_OK(status)) {
6539                 return status;
6540         }
6541
6542         if ((r->in.level < 1) || (r->in.level > 3)) {
6543                 DEBUG(0,("_samr_GetDisplayEnumerationIndex: "
6544                         "Unknown info level (%u)\n",
6545                         r->in.level));
6546                 return NT_STATUS_INVALID_INFO_CLASS;
6547         }
6548
6549         become_root();
6550
6551         /* The following done as ROOT. Don't return without unbecome_root(). */
6552
6553         switch (r->in.level) {
6554         case 1:
6555                 if (dinfo->disp_info->users == NULL) {
6556                         dinfo->disp_info->users = pdb_search_users(
6557                                 dinfo->disp_info, ACB_NORMAL);
6558                         if (dinfo->disp_info->users == NULL) {
6559                                 unbecome_root();
6560                                 return NT_STATUS_ACCESS_DENIED;
6561                         }
6562                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6563                                 "starting user enumeration at index %u\n",
6564                                 (unsigned int)enum_context));
6565                 } else {
6566                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6567                                 "using cached user enumeration at index %u\n",
6568                                 (unsigned int)enum_context));
6569                 }
6570                 num_account = pdb_search_entries(dinfo->disp_info->users,
6571                                                  enum_context, max_entries,
6572                                                  &entries);
6573                 break;
6574         case 2:
6575                 if (dinfo->disp_info->machines == NULL) {
6576                         dinfo->disp_info->machines = pdb_search_users(
6577                                 dinfo->disp_info, ACB_WSTRUST|ACB_SVRTRUST);
6578                         if (dinfo->disp_info->machines == NULL) {
6579                                 unbecome_root();
6580                                 return NT_STATUS_ACCESS_DENIED;
6581                         }
6582                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6583                                 "starting machine enumeration at index %u\n",
6584                                 (unsigned int)enum_context));
6585                 } else {
6586                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6587                                 "using cached machine enumeration at index %u\n",
6588                                 (unsigned int)enum_context));
6589                 }
6590                 num_account = pdb_search_entries(dinfo->disp_info->machines,
6591                                                  enum_context, max_entries,
6592                                                  &entries);
6593                 break;
6594         case 3:
6595                 if (dinfo->disp_info->groups == NULL) {
6596                         dinfo->disp_info->groups = pdb_search_groups(
6597                                 dinfo->disp_info);
6598                         if (dinfo->disp_info->groups == NULL) {
6599                                 unbecome_root();
6600                                 return NT_STATUS_ACCESS_DENIED;
6601                         }
6602                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6603                                 "starting group enumeration at index %u\n",
6604                                 (unsigned int)enum_context));
6605                 } else {
6606                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6607                                 "using cached group enumeration at index %u\n",
6608                                 (unsigned int)enum_context));
6609                 }
6610                 num_account = pdb_search_entries(dinfo->disp_info->groups,
6611                                                  enum_context, max_entries,
6612                                                  &entries);
6613                 break;
6614         default:
6615                 unbecome_root();
6616                 smb_panic("info class changed");
6617                 break;
6618         }
6619
6620         unbecome_root();
6621
6622         /* Ensure we cache this enumeration. */
6623         set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
6624
6625         DEBUG(10,("_samr_GetDisplayEnumerationIndex: looking for :%s\n",
6626                 r->in.name->string));
6627
6628         for (i=0; i<num_account; i++) {
6629                 if (strequal(entries[i].account_name, r->in.name->string)) {
6630                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6631                                 "found %s at idx %d\n",
6632                                 r->in.name->string, i));
6633                         *r->out.idx = i;
6634                         return NT_STATUS_OK;
6635                 }
6636         }
6637
6638         /* assuming account_name lives at the very end */
6639         *r->out.idx = num_account;
6640
6641         return NT_STATUS_NO_MORE_ENTRIES;
6642 }
6643
6644 /****************************************************************
6645  _samr_GetDisplayEnumerationIndex2
6646 ****************************************************************/
6647
6648 NTSTATUS _samr_GetDisplayEnumerationIndex2(pipes_struct *p,
6649                                            struct samr_GetDisplayEnumerationIndex2 *r)
6650 {
6651         struct samr_GetDisplayEnumerationIndex q;
6652
6653         q.in.domain_handle      = r->in.domain_handle;
6654         q.in.level              = r->in.level;
6655         q.in.name               = r->in.name;
6656
6657         q.out.idx               = r->out.idx;
6658
6659         return _samr_GetDisplayEnumerationIndex(p, &q);
6660 }
6661
6662 /****************************************************************
6663  _samr_RidToSid
6664 ****************************************************************/
6665
6666 NTSTATUS _samr_RidToSid(pipes_struct *p,
6667                         struct samr_RidToSid *r)
6668 {
6669         struct samr_domain_info *dinfo;
6670         NTSTATUS status;
6671         struct dom_sid sid;
6672
6673         dinfo = policy_handle_find(p, r->in.domain_handle,
6674                                    0, NULL,
6675                                    struct samr_domain_info, &status);
6676         if (!NT_STATUS_IS_OK(status)) {
6677                 return status;
6678         }
6679
6680         if (!sid_compose(&sid, &dinfo->sid, r->in.rid)) {
6681                 return NT_STATUS_NO_MEMORY;
6682         }
6683
6684         *r->out.sid = sid_dup_talloc(p->mem_ctx, &sid);
6685         if (!*r->out.sid) {
6686                 return NT_STATUS_NO_MEMORY;
6687         }
6688
6689         return NT_STATUS_OK;
6690 }
6691
6692 /****************************************************************
6693 ****************************************************************/
6694
6695 static enum samr_ValidationStatus samr_ValidatePassword_Change(TALLOC_CTX *mem_ctx,
6696                                                                const struct samr_PwInfo *dom_pw_info,
6697                                                                const struct samr_ValidatePasswordReq2 *req,
6698                                                                struct samr_ValidatePasswordRepCtr *rep)
6699 {
6700         NTSTATUS status;
6701
6702         if (req->password.string == NULL) {
6703                 return SAMR_VALIDATION_STATUS_SUCCESS;
6704         }
6705         if (strlen(req->password.string) < dom_pw_info->min_password_length) {
6706                 ZERO_STRUCT(rep->info);
6707                 return SAMR_VALIDATION_STATUS_PWD_TOO_SHORT;
6708         }
6709         if (dom_pw_info->password_properties & DOMAIN_PASSWORD_COMPLEX) {
6710                 status = check_password_complexity(req->account.string,
6711                                                    req->password.string,
6712                                                    NULL);
6713                 if (!NT_STATUS_IS_OK(status)) {
6714                         ZERO_STRUCT(rep->info);
6715                         return SAMR_VALIDATION_STATUS_NOT_COMPLEX_ENOUGH;
6716                 }
6717         }
6718
6719         return SAMR_VALIDATION_STATUS_SUCCESS;
6720 }
6721
6722 /****************************************************************
6723 ****************************************************************/
6724
6725 static enum samr_ValidationStatus samr_ValidatePassword_Reset(TALLOC_CTX *mem_ctx,
6726                                                               const struct samr_PwInfo *dom_pw_info,
6727                                                               const struct samr_ValidatePasswordReq3 *req,
6728                                                               struct samr_ValidatePasswordRepCtr *rep)
6729 {
6730         NTSTATUS status;
6731
6732         if (req->password.string == NULL) {
6733                 return SAMR_VALIDATION_STATUS_SUCCESS;
6734         }
6735         if (strlen(req->password.string) < dom_pw_info->min_password_length) {
6736                 ZERO_STRUCT(rep->info);
6737                 return SAMR_VALIDATION_STATUS_PWD_TOO_SHORT;
6738         }
6739         if (dom_pw_info->password_properties & DOMAIN_PASSWORD_COMPLEX) {
6740                 status = check_password_complexity(req->account.string,
6741                                                    req->password.string,
6742                                                    NULL);
6743                 if (!NT_STATUS_IS_OK(status)) {
6744                         ZERO_STRUCT(rep->info);
6745                         return SAMR_VALIDATION_STATUS_NOT_COMPLEX_ENOUGH;
6746                 }
6747         }
6748
6749         return SAMR_VALIDATION_STATUS_SUCCESS;
6750 }
6751
6752 /****************************************************************
6753  _samr_ValidatePassword
6754 ****************************************************************/
6755
6756 NTSTATUS _samr_ValidatePassword(pipes_struct *p,
6757                                 struct samr_ValidatePassword *r)
6758 {
6759         union samr_ValidatePasswordRep *rep;
6760         NTSTATUS status;
6761         struct samr_GetDomPwInfo pw;
6762         struct samr_PwInfo dom_pw_info;
6763
6764         if (r->in.level < 1 || r->in.level > 3) {
6765                 return NT_STATUS_INVALID_INFO_CLASS;
6766         }
6767
6768         pw.in.domain_name = NULL;
6769         pw.out.info = &dom_pw_info;
6770
6771         status = _samr_GetDomPwInfo(p, &pw);
6772         if (!NT_STATUS_IS_OK(status)) {
6773                 return status;
6774         }
6775
6776         rep = talloc_zero(p->mem_ctx, union samr_ValidatePasswordRep);
6777         if (!rep) {
6778                 return NT_STATUS_NO_MEMORY;
6779         }
6780
6781         switch (r->in.level) {
6782         case 1:
6783                 status = NT_STATUS_NOT_SUPPORTED;
6784                 break;
6785         case 2:
6786                 rep->ctr2.status = samr_ValidatePassword_Change(p->mem_ctx,
6787                                                                 &dom_pw_info,
6788                                                                 &r->in.req->req2,
6789                                                                 &rep->ctr2);
6790                 break;
6791         case 3:
6792                 rep->ctr3.status = samr_ValidatePassword_Reset(p->mem_ctx,
6793                                                                &dom_pw_info,
6794                                                                &r->in.req->req3,
6795                                                                &rep->ctr3);
6796                 break;
6797         default:
6798                 status = NT_STATUS_INVALID_INFO_CLASS;
6799                 break;
6800         }
6801
6802         if (!NT_STATUS_IS_OK(status)) {
6803                 talloc_free(rep);
6804                 return status;
6805         }
6806
6807         *r->out.rep = rep;
6808
6809         return NT_STATUS_OK;
6810 }
6811
6812 /****************************************************************
6813 ****************************************************************/
6814
6815 NTSTATUS _samr_Shutdown(pipes_struct *p,
6816                         struct samr_Shutdown *r)
6817 {
6818         p->rng_fault_state = true;
6819         return NT_STATUS_NOT_IMPLEMENTED;
6820 }
6821
6822 /****************************************************************
6823 ****************************************************************/
6824
6825 NTSTATUS _samr_SetMemberAttributesOfGroup(pipes_struct *p,
6826                                           struct samr_SetMemberAttributesOfGroup *r)
6827 {
6828         p->rng_fault_state = true;
6829         return NT_STATUS_NOT_IMPLEMENTED;
6830 }
6831
6832 /****************************************************************
6833 ****************************************************************/
6834
6835 NTSTATUS _samr_TestPrivateFunctionsDomain(pipes_struct *p,
6836                                           struct samr_TestPrivateFunctionsDomain *r)
6837 {
6838         return NT_STATUS_NOT_IMPLEMENTED;
6839 }
6840
6841 /****************************************************************
6842 ****************************************************************/
6843
6844 NTSTATUS _samr_TestPrivateFunctionsUser(pipes_struct *p,
6845                                         struct samr_TestPrivateFunctionsUser *r)
6846 {
6847         return NT_STATUS_NOT_IMPLEMENTED;
6848 }
6849
6850 /****************************************************************
6851 ****************************************************************/
6852
6853 NTSTATUS _samr_AddMultipleMembersToAlias(pipes_struct *p,
6854                                          struct samr_AddMultipleMembersToAlias *r)
6855 {
6856         p->rng_fault_state = true;
6857         return NT_STATUS_NOT_IMPLEMENTED;
6858 }
6859
6860 /****************************************************************
6861 ****************************************************************/
6862
6863 NTSTATUS _samr_RemoveMultipleMembersFromAlias(pipes_struct *p,
6864                                               struct samr_RemoveMultipleMembersFromAlias *r)
6865 {
6866         p->rng_fault_state = true;
6867         return NT_STATUS_NOT_IMPLEMENTED;
6868 }
6869
6870 /****************************************************************
6871 ****************************************************************/
6872
6873 NTSTATUS _samr_SetBootKeyInformation(pipes_struct *p,
6874                                      struct samr_SetBootKeyInformation *r)
6875 {
6876         p->rng_fault_state = true;
6877         return NT_STATUS_NOT_IMPLEMENTED;
6878 }
6879
6880 /****************************************************************
6881 ****************************************************************/
6882
6883 NTSTATUS _samr_GetBootKeyInformation(pipes_struct *p,
6884                                      struct samr_GetBootKeyInformation *r)
6885 {
6886         p->rng_fault_state = true;
6887         return NT_STATUS_NOT_IMPLEMENTED;
6888 }
6889
6890 /****************************************************************
6891 ****************************************************************/
6892
6893 NTSTATUS _samr_SetDsrmPassword(pipes_struct *p,
6894                                struct samr_SetDsrmPassword *r)
6895 {
6896         p->rng_fault_state = true;
6897         return NT_STATUS_NOT_IMPLEMENTED;
6898 }