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