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