s3-samr: fix return code for invalid name in _samr_LookupDomain.
[sfrench/samba-autobuild/.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         if (info->builtin_domain) {
1488                 DEBUG(5,("_samr_QueryDisplayInfo: Nothing in BUILTIN\n"));
1489                 return NT_STATUS_OK;
1490         }
1491
1492         status = access_check_samr_function(info->acc_granted,
1493                                             SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
1494                                             "_samr_QueryDisplayInfo");
1495         if (!NT_STATUS_IS_OK(status)) {
1496                 return status;
1497         }
1498
1499         /*
1500          * calculate how many entries we will return.
1501          * based on
1502          * - the number of entries the client asked
1503          * - our limit on that
1504          * - the starting point (enumeration context)
1505          * - the buffer size the client will accept
1506          */
1507
1508         /*
1509          * We are a lot more like W2K. Instead of reading the SAM
1510          * each time to find the records we need to send back,
1511          * we read it once and link that copy to the sam handle.
1512          * For large user list (over the MAX_SAM_ENTRIES)
1513          * it's a definitive win.
1514          * second point to notice: between enumerations
1515          * our sam is now the same as it's a snapshoot.
1516          * third point: got rid of the static SAM_USER_21 struct
1517          * no more intermediate.
1518          * con: it uses much more memory, as a full copy is stored
1519          * in memory.
1520          *
1521          * If you want to change it, think twice and think
1522          * of the second point , that's really important.
1523          *
1524          * JFM, 12/20/2001
1525          */
1526
1527         if ((r->in.level < 1) || (r->in.level > 5)) {
1528                 DEBUG(0,("_samr_QueryDisplayInfo: Unknown info level (%u)\n",
1529                          (unsigned int)r->in.level ));
1530                 return NT_STATUS_INVALID_INFO_CLASS;
1531         }
1532
1533         /* first limit the number of entries we will return */
1534         if(max_entries > max_sam_entries) {
1535                 DEBUG(5, ("_samr_QueryDisplayInfo: client requested %d "
1536                           "entries, limiting to %d\n", max_entries,
1537                           max_sam_entries));
1538                 max_entries = max_sam_entries;
1539         }
1540
1541         /* calculate the size and limit on the number of entries we will
1542          * return */
1543
1544         temp_size=max_entries*struct_size;
1545
1546         if (temp_size>max_size) {
1547                 max_entries=MIN((max_size/struct_size),max_entries);;
1548                 DEBUG(5, ("_samr_QueryDisplayInfo: buffer size limits to "
1549                           "only %d entries\n", max_entries));
1550         }
1551
1552         become_root();
1553
1554         /* THe following done as ROOT. Don't return without unbecome_root(). */
1555
1556         switch (r->in.level) {
1557         case 0x1:
1558         case 0x4:
1559                 if (info->disp_info->users == NULL) {
1560                         info->disp_info->users = pdb_search_users(ACB_NORMAL);
1561                         if (info->disp_info->users == NULL) {
1562                                 unbecome_root();
1563                                 return NT_STATUS_ACCESS_DENIED;
1564                         }
1565                         DEBUG(10,("_samr_QueryDisplayInfo: starting user enumeration at index %u\n",
1566                                 (unsigned  int)enum_context ));
1567                 } else {
1568                         DEBUG(10,("_samr_QueryDisplayInfo: using cached user enumeration at index %u\n",
1569                                 (unsigned  int)enum_context ));
1570                 }
1571
1572                 num_account = pdb_search_entries(info->disp_info->users,
1573                                                  enum_context, max_entries,
1574                                                  &entries);
1575                 break;
1576         case 0x2:
1577                 if (info->disp_info->machines == NULL) {
1578                         info->disp_info->machines =
1579                                 pdb_search_users(ACB_WSTRUST|ACB_SVRTRUST);
1580                         if (info->disp_info->machines == NULL) {
1581                                 unbecome_root();
1582                                 return NT_STATUS_ACCESS_DENIED;
1583                         }
1584                         DEBUG(10,("_samr_QueryDisplayInfo: starting machine enumeration at index %u\n",
1585                                 (unsigned  int)enum_context ));
1586                 } else {
1587                         DEBUG(10,("_samr_QueryDisplayInfo: using cached machine enumeration at index %u\n",
1588                                 (unsigned  int)enum_context ));
1589                 }
1590
1591                 num_account = pdb_search_entries(info->disp_info->machines,
1592                                                  enum_context, max_entries,
1593                                                  &entries);
1594                 break;
1595         case 0x3:
1596         case 0x5:
1597                 if (info->disp_info->groups == NULL) {
1598                         info->disp_info->groups = pdb_search_groups();
1599                         if (info->disp_info->groups == NULL) {
1600                                 unbecome_root();
1601                                 return NT_STATUS_ACCESS_DENIED;
1602                         }
1603                         DEBUG(10,("_samr_QueryDisplayInfo: starting group enumeration at index %u\n",
1604                                 (unsigned  int)enum_context ));
1605                 } else {
1606                         DEBUG(10,("_samr_QueryDisplayInfo: using cached group enumeration at index %u\n",
1607                                 (unsigned  int)enum_context ));
1608                 }
1609
1610                 num_account = pdb_search_entries(info->disp_info->groups,
1611                                                  enum_context, max_entries,
1612                                                  &entries);
1613                 break;
1614         default:
1615                 unbecome_root();
1616                 smb_panic("info class changed");
1617                 break;
1618         }
1619         unbecome_root();
1620
1621
1622         /* Now create reply structure */
1623         switch (r->in.level) {
1624         case 0x1:
1625                 disp_ret = init_samr_dispinfo_1(p->mem_ctx, &disp_info->info1,
1626                                                 num_account, enum_context,
1627                                                 entries);
1628                 break;
1629         case 0x2:
1630                 disp_ret = init_samr_dispinfo_2(p->mem_ctx, &disp_info->info2,
1631                                                 num_account, enum_context,
1632                                                 entries);
1633                 break;
1634         case 0x3:
1635                 disp_ret = init_samr_dispinfo_3(p->mem_ctx, &disp_info->info3,
1636                                                 num_account, enum_context,
1637                                                 entries);
1638                 break;
1639         case 0x4:
1640                 disp_ret = init_samr_dispinfo_4(p->mem_ctx, &disp_info->info4,
1641                                                 num_account, enum_context,
1642                                                 entries);
1643                 break;
1644         case 0x5:
1645                 disp_ret = init_samr_dispinfo_5(p->mem_ctx, &disp_info->info5,
1646                                                 num_account, enum_context,
1647                                                 entries);
1648                 break;
1649         default:
1650                 smb_panic("info class changed");
1651                 break;
1652         }
1653
1654         if (!NT_STATUS_IS_OK(disp_ret))
1655                 return disp_ret;
1656
1657         /* calculate the total size */
1658         total_data_size=num_account*struct_size;
1659
1660         if (max_entries <= num_account) {
1661                 status = STATUS_MORE_ENTRIES;
1662         } else {
1663                 status = NT_STATUS_OK;
1664         }
1665
1666         /* Ensure we cache this enumeration. */
1667         set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1668
1669         DEBUG(5, ("_samr_QueryDisplayInfo: %d\n", __LINE__));
1670
1671         *r->out.total_size = total_data_size;
1672         *r->out.returned_size = temp_size;
1673
1674         return status;
1675 }
1676
1677 /****************************************************************
1678  _samr_QueryDisplayInfo2
1679 ****************************************************************/
1680
1681 NTSTATUS _samr_QueryDisplayInfo2(pipes_struct *p,
1682                                  struct samr_QueryDisplayInfo2 *r)
1683 {
1684         struct samr_QueryDisplayInfo q;
1685
1686         q.in.domain_handle      = r->in.domain_handle;
1687         q.in.level              = r->in.level;
1688         q.in.start_idx          = r->in.start_idx;
1689         q.in.max_entries        = r->in.max_entries;
1690         q.in.buf_size           = r->in.buf_size;
1691
1692         q.out.total_size        = r->out.total_size;
1693         q.out.returned_size     = r->out.returned_size;
1694         q.out.info              = r->out.info;
1695
1696         return _samr_QueryDisplayInfo(p, &q);
1697 }
1698
1699 /****************************************************************
1700  _samr_QueryDisplayInfo3
1701 ****************************************************************/
1702
1703 NTSTATUS _samr_QueryDisplayInfo3(pipes_struct *p,
1704                                  struct samr_QueryDisplayInfo3 *r)
1705 {
1706         struct samr_QueryDisplayInfo q;
1707
1708         q.in.domain_handle      = r->in.domain_handle;
1709         q.in.level              = r->in.level;
1710         q.in.start_idx          = r->in.start_idx;
1711         q.in.max_entries        = r->in.max_entries;
1712         q.in.buf_size           = r->in.buf_size;
1713
1714         q.out.total_size        = r->out.total_size;
1715         q.out.returned_size     = r->out.returned_size;
1716         q.out.info              = r->out.info;
1717
1718         return _samr_QueryDisplayInfo(p, &q);
1719 }
1720
1721 /*******************************************************************
1722  _samr_QueryAliasInfo
1723  ********************************************************************/
1724
1725 NTSTATUS _samr_QueryAliasInfo(pipes_struct *p,
1726                               struct samr_QueryAliasInfo *r)
1727 {
1728         DOM_SID   sid;
1729         struct acct_info info;
1730         uint32    acc_granted;
1731         NTSTATUS status;
1732         union samr_AliasInfo *alias_info = NULL;
1733         const char *alias_name = NULL;
1734         const char *alias_description = NULL;
1735
1736         DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1737
1738         alias_info = TALLOC_ZERO_P(p->mem_ctx, union samr_AliasInfo);
1739         if (!alias_info) {
1740                 return NT_STATUS_NO_MEMORY;
1741         }
1742
1743         /* find the policy handle.  open a policy on it. */
1744         if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &sid, &acc_granted, NULL))
1745                 return NT_STATUS_INVALID_HANDLE;
1746
1747         status = access_check_samr_function(acc_granted,
1748                                             SAMR_ALIAS_ACCESS_LOOKUP_INFO,
1749                                             "_samr_QueryAliasInfo");
1750         if (!NT_STATUS_IS_OK(status)) {
1751                 return status;
1752         }
1753
1754         become_root();
1755         status = pdb_get_aliasinfo(&sid, &info);
1756         unbecome_root();
1757
1758         if ( !NT_STATUS_IS_OK(status))
1759                 return status;
1760
1761         /* FIXME: info contains fstrings */
1762         alias_name = talloc_strdup(r, info.acct_name);
1763         alias_description = talloc_strdup(r, info.acct_desc);
1764
1765         switch (r->in.level) {
1766         case ALIASINFOALL:
1767                 init_samr_alias_info1(&alias_info->all,
1768                                       alias_name,
1769                                       1,
1770                                       alias_description);
1771                 break;
1772         case ALIASINFODESCRIPTION:
1773                 init_samr_alias_info3(&alias_info->description,
1774                                       alias_description);
1775                 break;
1776         default:
1777                 return NT_STATUS_INVALID_INFO_CLASS;
1778         }
1779
1780         *r->out.info = alias_info;
1781
1782         DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1783
1784         return NT_STATUS_OK;
1785 }
1786
1787 /*******************************************************************
1788  _samr_LookupNames
1789  ********************************************************************/
1790
1791 NTSTATUS _samr_LookupNames(pipes_struct *p,
1792                            struct samr_LookupNames *r)
1793 {
1794         NTSTATUS status;
1795         uint32 *rid;
1796         enum lsa_SidType *type;
1797         int i;
1798         int num_rids = r->in.num_names;
1799         DOM_SID pol_sid;
1800         uint32  acc_granted;
1801         struct samr_Ids rids, types;
1802         uint32_t num_mapped = 0;
1803
1804         DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1805
1806         if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &pol_sid, &acc_granted, NULL)) {
1807                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1808         }
1809
1810         status = access_check_samr_function(acc_granted,
1811                                             0, /* Don't know the acc_bits yet */
1812                                             "_samr_LookupNames");
1813         if (!NT_STATUS_IS_OK(status)) {
1814                 return status;
1815         }
1816
1817         if (num_rids > MAX_SAM_ENTRIES) {
1818                 num_rids = MAX_SAM_ENTRIES;
1819                 DEBUG(5,("_samr_LookupNames: truncating entries to %d\n", num_rids));
1820         }
1821
1822         rid = talloc_array(p->mem_ctx, uint32, num_rids);
1823         NT_STATUS_HAVE_NO_MEMORY(rid);
1824
1825         type = talloc_array(p->mem_ctx, enum lsa_SidType, num_rids);
1826         NT_STATUS_HAVE_NO_MEMORY(type);
1827
1828         DEBUG(5,("_samr_LookupNames: looking name on SID %s\n",
1829                  sid_string_dbg(&pol_sid)));
1830
1831         for (i = 0; i < num_rids; i++) {
1832
1833                 status = NT_STATUS_NONE_MAPPED;
1834                 type[i] = SID_NAME_UNKNOWN;
1835
1836                 rid[i] = 0xffffffff;
1837
1838                 if (sid_check_is_builtin(&pol_sid)) {
1839                         if (lookup_builtin_name(r->in.names[i].string,
1840                                                 &rid[i]))
1841                         {
1842                                 type[i] = SID_NAME_ALIAS;
1843                         }
1844                 } else {
1845                         lookup_global_sam_name(r->in.names[i].string, 0,
1846                                                &rid[i], &type[i]);
1847                 }
1848
1849                 if (type[i] != SID_NAME_UNKNOWN) {
1850                         num_mapped++;
1851                 }
1852         }
1853
1854         if (num_mapped == num_rids) {
1855                 status = NT_STATUS_OK;
1856         } else if (num_mapped == 0) {
1857                 status = NT_STATUS_NONE_MAPPED;
1858         } else {
1859                 status = STATUS_SOME_UNMAPPED;
1860         }
1861
1862         rids.count = num_rids;
1863         rids.ids = rid;
1864
1865         types.count = num_rids;
1866         types.ids = type;
1867
1868         *r->out.rids = rids;
1869         *r->out.types = types;
1870
1871         DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1872
1873         return status;
1874 }
1875
1876 /*******************************************************************
1877  _samr_ChangePasswordUser2
1878  ********************************************************************/
1879
1880 NTSTATUS _samr_ChangePasswordUser2(pipes_struct *p,
1881                                    struct samr_ChangePasswordUser2 *r)
1882 {
1883         NTSTATUS status;
1884         fstring user_name;
1885         fstring wks;
1886
1887         DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1888
1889         fstrcpy(user_name, r->in.account->string);
1890         fstrcpy(wks, r->in.server->string);
1891
1892         DEBUG(5,("_samr_ChangePasswordUser2: user: %s wks: %s\n", user_name, wks));
1893
1894         /*
1895          * Pass the user through the NT -> unix user mapping
1896          * function.
1897          */
1898
1899         (void)map_username(user_name);
1900
1901         /*
1902          * UNIX username case mangling not required, pass_oem_change
1903          * is case insensitive.
1904          */
1905
1906         status = pass_oem_change(user_name,
1907                                  r->in.lm_password->data,
1908                                  r->in.lm_verifier->hash,
1909                                  r->in.nt_password->data,
1910                                  r->in.nt_verifier->hash,
1911                                  NULL);
1912
1913         DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1914
1915         return status;
1916 }
1917
1918 /*******************************************************************
1919  _samr_ChangePasswordUser3
1920  ********************************************************************/
1921
1922 NTSTATUS _samr_ChangePasswordUser3(pipes_struct *p,
1923                                    struct samr_ChangePasswordUser3 *r)
1924 {
1925         NTSTATUS status;
1926         fstring user_name;
1927         const char *wks = NULL;
1928         uint32 reject_reason;
1929         struct samr_DomInfo1 *dominfo = NULL;
1930         struct samr_ChangeReject *reject = NULL;
1931
1932         DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
1933
1934         fstrcpy(user_name, r->in.account->string);
1935         if (r->in.server && r->in.server->string) {
1936                 wks = r->in.server->string;
1937         }
1938
1939         DEBUG(5,("_samr_ChangePasswordUser3: user: %s wks: %s\n", user_name, wks));
1940
1941         /*
1942          * Pass the user through the NT -> unix user mapping
1943          * function.
1944          */
1945
1946         (void)map_username(user_name);
1947
1948         /*
1949          * UNIX username case mangling not required, pass_oem_change
1950          * is case insensitive.
1951          */
1952
1953         status = pass_oem_change(user_name,
1954                                  r->in.lm_password->data,
1955                                  r->in.lm_verifier->hash,
1956                                  r->in.nt_password->data,
1957                                  r->in.nt_verifier->hash,
1958                                  &reject_reason);
1959
1960         if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) ||
1961             NT_STATUS_EQUAL(status, NT_STATUS_ACCOUNT_RESTRICTION)) {
1962
1963                 uint32 min_pass_len,pass_hist,password_properties;
1964                 time_t u_expire, u_min_age;
1965                 NTTIME nt_expire, nt_min_age;
1966                 uint32 account_policy_temp;
1967
1968                 dominfo = TALLOC_ZERO_P(p->mem_ctx, struct samr_DomInfo1);
1969                 if (!dominfo) {
1970                         return NT_STATUS_NO_MEMORY;
1971                 }
1972
1973                 reject = TALLOC_ZERO_P(p->mem_ctx, struct samr_ChangeReject);
1974                 if (!reject) {
1975                         return NT_STATUS_NO_MEMORY;
1976                 }
1977
1978                 become_root();
1979
1980                 /* AS ROOT !!! */
1981
1982                 pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &account_policy_temp);
1983                 min_pass_len = account_policy_temp;
1984
1985                 pdb_get_account_policy(AP_PASSWORD_HISTORY, &account_policy_temp);
1986                 pass_hist = account_policy_temp;
1987
1988                 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
1989                 password_properties = account_policy_temp;
1990
1991                 pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
1992                 u_expire = account_policy_temp;
1993
1994                 pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
1995                 u_min_age = account_policy_temp;
1996
1997                 /* !AS ROOT */
1998
1999                 unbecome_root();
2000
2001                 unix_to_nt_time_abs(&nt_expire, u_expire);
2002                 unix_to_nt_time_abs(&nt_min_age, u_min_age);
2003
2004                 if (lp_check_password_script() && *lp_check_password_script()) {
2005                         password_properties |= DOMAIN_PASSWORD_COMPLEX;
2006                 }
2007
2008                 init_samr_DomInfo1(dominfo,
2009                                    min_pass_len,
2010                                    pass_hist,
2011                                    password_properties,
2012                                    u_expire,
2013                                    u_min_age);
2014
2015                 reject->reason = reject_reason;
2016
2017                 *r->out.dominfo = dominfo;
2018                 *r->out.reject = reject;
2019         }
2020
2021         DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
2022
2023         return status;
2024 }
2025
2026 /*******************************************************************
2027 makes a SAMR_R_LOOKUP_RIDS structure.
2028 ********************************************************************/
2029
2030 static bool make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names,
2031                                   const char **names,
2032                                   struct lsa_String **lsa_name_array_p)
2033 {
2034         struct lsa_String *lsa_name_array = NULL;
2035         uint32_t i;
2036
2037         *lsa_name_array_p = NULL;
2038
2039         if (num_names != 0) {
2040                 lsa_name_array = TALLOC_ZERO_ARRAY(ctx, struct lsa_String, num_names);
2041                 if (!lsa_name_array) {
2042                         return false;
2043                 }
2044         }
2045
2046         for (i = 0; i < num_names; i++) {
2047                 DEBUG(10, ("names[%d]:%s\n", i, names[i] && *names[i] ? names[i] : ""));
2048                 init_lsa_String(&lsa_name_array[i], names[i]);
2049         }
2050
2051         *lsa_name_array_p = lsa_name_array;
2052
2053         return true;
2054 }
2055
2056 /*******************************************************************
2057  _samr_LookupRids
2058  ********************************************************************/
2059
2060 NTSTATUS _samr_LookupRids(pipes_struct *p,
2061                           struct samr_LookupRids *r)
2062 {
2063         NTSTATUS status;
2064         const char **names;
2065         enum lsa_SidType *attrs = NULL;
2066         uint32 *wire_attrs = NULL;
2067         DOM_SID pol_sid;
2068         int num_rids = (int)r->in.num_rids;
2069         uint32 acc_granted;
2070         int i;
2071         struct lsa_Strings names_array;
2072         struct samr_Ids types_array;
2073         struct lsa_String *lsa_names = NULL;
2074
2075         DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2076
2077         /* find the policy handle.  open a policy on it. */
2078         if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &pol_sid, &acc_granted, NULL))
2079                 return NT_STATUS_INVALID_HANDLE;
2080
2081         status = access_check_samr_function(acc_granted,
2082                                             SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
2083                                             "_samr_LookupRids");
2084         if (!NT_STATUS_IS_OK(status)) {
2085                 return status;
2086         }
2087
2088         if (num_rids > 1000) {
2089                 DEBUG(0, ("Got asked for %d rids (more than 1000) -- according "
2090                           "to samba4 idl this is not possible\n", num_rids));
2091                 return NT_STATUS_UNSUCCESSFUL;
2092         }
2093
2094         if (num_rids) {
2095                 names = TALLOC_ZERO_ARRAY(p->mem_ctx, const char *, num_rids);
2096                 attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, enum lsa_SidType, num_rids);
2097                 wire_attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_rids);
2098
2099                 if ((names == NULL) || (attrs == NULL) || (wire_attrs==NULL))
2100                         return NT_STATUS_NO_MEMORY;
2101         } else {
2102                 names = NULL;
2103                 attrs = NULL;
2104                 wire_attrs = NULL;
2105         }
2106
2107         become_root();  /* lookup_sid can require root privs */
2108         status = pdb_lookup_rids(&pol_sid, num_rids, r->in.rids,
2109                                  names, attrs);
2110         unbecome_root();
2111
2112         if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED) && (num_rids == 0)) {
2113                 status = NT_STATUS_OK;
2114         }
2115
2116         if (!make_samr_lookup_rids(p->mem_ctx, num_rids, names,
2117                                    &lsa_names)) {
2118                 return NT_STATUS_NO_MEMORY;
2119         }
2120
2121         /* Convert from enum lsa_SidType to uint32 for wire format. */
2122         for (i = 0; i < num_rids; i++) {
2123                 wire_attrs[i] = (uint32)attrs[i];
2124         }
2125
2126         names_array.count = num_rids;
2127         names_array.names = lsa_names;
2128
2129         types_array.count = num_rids;
2130         types_array.ids = wire_attrs;
2131
2132         *r->out.names = names_array;
2133         *r->out.types = types_array;
2134
2135         DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2136
2137         return status;
2138 }
2139
2140 /*******************************************************************
2141  _samr_OpenUser
2142 ********************************************************************/
2143
2144 NTSTATUS _samr_OpenUser(pipes_struct *p,
2145                         struct samr_OpenUser *r)
2146 {
2147         struct samu *sampass=NULL;
2148         DOM_SID sid;
2149         POLICY_HND domain_pol = *r->in.domain_handle;
2150         POLICY_HND *user_pol = r->out.user_handle;
2151         struct samr_info *info = NULL;
2152         SEC_DESC *psd = NULL;
2153         uint32    acc_granted;
2154         uint32    des_access = r->in.access_mask;
2155         size_t    sd_size;
2156         bool ret;
2157         NTSTATUS nt_status;
2158         SE_PRIV se_rights;
2159
2160         /* find the domain policy handle and get domain SID / access bits in the domain policy. */
2161
2162         if ( !get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted, NULL) )
2163                 return NT_STATUS_INVALID_HANDLE;
2164
2165         nt_status = access_check_samr_function(acc_granted,
2166                                                SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
2167                                                "_samr_OpenUser" );
2168
2169         if ( !NT_STATUS_IS_OK(nt_status) )
2170                 return nt_status;
2171
2172         if ( !(sampass = samu_new( p->mem_ctx )) ) {
2173                 return NT_STATUS_NO_MEMORY;
2174         }
2175
2176         /* append the user's RID to it */
2177
2178         if (!sid_append_rid(&sid, r->in.rid))
2179                 return NT_STATUS_NO_SUCH_USER;
2180
2181         /* check if access can be granted as requested by client. */
2182
2183         map_max_allowed_access(p->server_info->ptok, &des_access);
2184
2185         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &sid, SAMR_USR_RIGHTS_WRITE_PW);
2186         se_map_generic(&des_access, &usr_generic_mapping);
2187
2188         se_priv_copy( &se_rights, &se_machine_account );
2189         se_priv_add( &se_rights, &se_add_users );
2190
2191         nt_status = access_check_samr_object(psd, p->server_info->ptok,
2192                 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
2193                 &acc_granted, "_samr_OpenUser");
2194
2195         if ( !NT_STATUS_IS_OK(nt_status) )
2196                 return nt_status;
2197
2198         become_root();
2199         ret=pdb_getsampwsid(sampass, &sid);
2200         unbecome_root();
2201
2202         /* check that the SID exists in our domain. */
2203         if (ret == False) {
2204                 return NT_STATUS_NO_SUCH_USER;
2205         }
2206
2207         TALLOC_FREE(sampass);
2208
2209         /* associate the user's SID and access bits with the new handle. */
2210         if ((info = get_samr_info_by_sid(&sid)) == NULL)
2211                 return NT_STATUS_NO_MEMORY;
2212         info->acc_granted = acc_granted;
2213
2214         /* get a (unique) handle.  open a policy on it. */
2215         if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info))
2216                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2217
2218         return NT_STATUS_OK;
2219 }
2220
2221 /*************************************************************************
2222  *************************************************************************/
2223
2224 static NTSTATUS init_samr_parameters_string(TALLOC_CTX *mem_ctx,
2225                                             DATA_BLOB *blob,
2226                                             struct lsa_BinaryString **_r)
2227 {
2228         struct lsa_BinaryString *r;
2229
2230         if (!blob || !_r) {
2231                 return NT_STATUS_INVALID_PARAMETER;
2232         }
2233
2234         r = TALLOC_ZERO_P(mem_ctx, struct lsa_BinaryString);
2235         if (!r) {
2236                 return NT_STATUS_NO_MEMORY;
2237         }
2238
2239         r->array = TALLOC_ZERO_ARRAY(mem_ctx, uint16_t, blob->length/2);
2240         if (!r->array) {
2241                 return NT_STATUS_NO_MEMORY;
2242         }
2243         memcpy(r->array, blob->data, blob->length);
2244         r->size = blob->length;
2245         r->length = blob->length;
2246
2247         if (!r->array) {
2248                 return NT_STATUS_NO_MEMORY;
2249         }
2250
2251         *_r = r;
2252
2253         return NT_STATUS_OK;
2254 }
2255
2256 static NTSTATUS get_user_info_5(TALLOC_CTX *mem_ctx,
2257                                 struct samr_UserInfo5 *r,
2258                                 DOM_SID *user_sid,
2259                                 DOM_SID *domain_sid)
2260 {
2261         struct samu *pw = NULL;
2262         bool ret;
2263         const DOM_SID *sid_user, *sid_group;
2264         uint32_t rid, primary_gid;
2265         NTTIME last_logon, last_logoff, last_password_change,
2266                acct_expiry;
2267         const char *account_name, *full_name, *home_directory, *home_drive,
2268                    *logon_script, *profile_path, *description,
2269                    *workstations, *comment;
2270         struct samr_LogonHours logon_hours;
2271
2272         ZERO_STRUCTP(r);
2273
2274         if (!(pw = samu_new(mem_ctx))) {
2275                 return NT_STATUS_NO_MEMORY;
2276         }
2277
2278         become_root();
2279         ret = pdb_getsampwsid(pw, user_sid);
2280         unbecome_root();
2281
2282         if (ret == False) {
2283                 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
2284                 TALLOC_FREE(pw);
2285                 return NT_STATUS_NO_SUCH_USER;
2286         }
2287
2288         samr_clear_sam_passwd(pw);
2289
2290         DEBUG(3,("User:[%s]\n", pdb_get_username(pw)));
2291
2292         sid_user = pdb_get_user_sid(pw);
2293
2294         if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2295                 DEBUG(0, ("get_user_info_5: User %s has SID %s, \nwhich conflicts with "
2296                           "the domain sid %s.  Failing operation.\n",
2297                           pdb_get_username(pw), sid_string_dbg(sid_user),
2298                           sid_string_dbg(domain_sid)));
2299                 TALLOC_FREE(pw);
2300                 return NT_STATUS_UNSUCCESSFUL;
2301         }
2302
2303         become_root();
2304         sid_group = pdb_get_group_sid(pw);
2305         unbecome_root();
2306
2307         if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2308                 DEBUG(0, ("get_user_info_5: User %s has Primary Group SID %s, \n"
2309                           "which conflicts with the domain sid %s.  Failing operation.\n",
2310                           pdb_get_username(pw), sid_string_dbg(sid_group),
2311                           sid_string_dbg(domain_sid)));
2312                 TALLOC_FREE(pw);
2313                 return NT_STATUS_UNSUCCESSFUL;
2314         }
2315
2316         unix_to_nt_time(&last_logon, pdb_get_logon_time(pw));
2317         unix_to_nt_time(&last_logoff, pdb_get_logoff_time(pw));
2318         unix_to_nt_time(&acct_expiry, pdb_get_kickoff_time(pw));
2319         unix_to_nt_time(&last_password_change, pdb_get_pass_last_set_time(pw));
2320
2321         account_name = talloc_strdup(mem_ctx, pdb_get_username(pw));
2322         full_name = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2323         home_directory = talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2324         home_drive = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2325         logon_script = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2326         profile_path = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2327         description = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2328         workstations = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2329         comment = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2330
2331         logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2332
2333         init_samr_user_info5(r,
2334                              account_name,
2335                              full_name,
2336                              rid,
2337                              primary_gid,
2338                              home_directory,
2339                              home_drive,
2340                              logon_script,
2341                              profile_path,
2342                              description,
2343                              workstations,
2344                              last_logon,
2345                              last_logoff,
2346                              logon_hours,
2347                              pdb_get_bad_password_count(pw),
2348                              pdb_get_logon_count(pw),
2349                              last_password_change,
2350                              acct_expiry,
2351                              pdb_get_acct_ctrl(pw));
2352
2353         TALLOC_FREE(pw);
2354
2355         return NT_STATUS_OK;
2356 }
2357
2358 /*************************************************************************
2359  get_user_info_7. Safe. Only gives out account_name.
2360  *************************************************************************/
2361
2362 static NTSTATUS get_user_info_7(TALLOC_CTX *mem_ctx,
2363                                 struct samr_UserInfo7 *r,
2364                                 DOM_SID *user_sid)
2365 {
2366         struct samu *smbpass=NULL;
2367         bool ret;
2368         const char *account_name = NULL;
2369
2370         ZERO_STRUCTP(r);
2371
2372         if ( !(smbpass = samu_new( mem_ctx )) ) {
2373                 return NT_STATUS_NO_MEMORY;
2374         }
2375
2376         become_root();
2377         ret = pdb_getsampwsid(smbpass, user_sid);
2378         unbecome_root();
2379
2380         if ( !ret ) {
2381                 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
2382                 return NT_STATUS_NO_SUCH_USER;
2383         }
2384
2385         account_name = talloc_strdup(mem_ctx, pdb_get_username(smbpass));
2386         if (!account_name) {
2387                 TALLOC_FREE(smbpass);
2388                 return NT_STATUS_NO_MEMORY;
2389         }
2390         TALLOC_FREE(smbpass);
2391
2392         DEBUG(3,("User:[%s]\n", account_name));
2393
2394         init_samr_user_info7(r, account_name);
2395
2396         return NT_STATUS_OK;
2397 }
2398
2399 /*************************************************************************
2400  get_user_info_9. Only gives out primary group SID.
2401  *************************************************************************/
2402
2403 static NTSTATUS get_user_info_9(TALLOC_CTX *mem_ctx,
2404                                 struct samr_UserInfo9 *r,
2405                                 DOM_SID *user_sid)
2406 {
2407         struct samu *smbpass=NULL;
2408         bool ret;
2409
2410         ZERO_STRUCTP(r);
2411
2412         if ( !(smbpass = samu_new( mem_ctx )) ) {
2413                 return NT_STATUS_NO_MEMORY;
2414         }
2415
2416         become_root();
2417         ret = pdb_getsampwsid(smbpass, user_sid);
2418         unbecome_root();
2419
2420         if (ret==False) {
2421                 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
2422                 TALLOC_FREE(smbpass);
2423                 return NT_STATUS_NO_SUCH_USER;
2424         }
2425
2426         DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
2427
2428         init_samr_user_info9(r, pdb_get_group_rid(smbpass));
2429
2430         TALLOC_FREE(smbpass);
2431
2432         return NT_STATUS_OK;
2433 }
2434
2435 /*************************************************************************
2436  get_user_info_16. Safe. Only gives out acb bits.
2437  *************************************************************************/
2438
2439 static NTSTATUS get_user_info_16(TALLOC_CTX *mem_ctx,
2440                                  struct samr_UserInfo16 *r,
2441                                  DOM_SID *user_sid)
2442 {
2443         struct samu *smbpass=NULL;
2444         bool ret;
2445
2446         ZERO_STRUCTP(r);
2447
2448         if ( !(smbpass = samu_new( mem_ctx )) ) {
2449                 return NT_STATUS_NO_MEMORY;
2450         }
2451
2452         become_root();
2453         ret = pdb_getsampwsid(smbpass, user_sid);
2454         unbecome_root();
2455
2456         if (ret==False) {
2457                 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
2458                 TALLOC_FREE(smbpass);
2459                 return NT_STATUS_NO_SUCH_USER;
2460         }
2461
2462         DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
2463
2464         init_samr_user_info16(r, pdb_get_acct_ctrl(smbpass));
2465
2466         TALLOC_FREE(smbpass);
2467
2468         return NT_STATUS_OK;
2469 }
2470
2471 /*************************************************************************
2472  get_user_info_18. OK - this is the killer as it gives out password info.
2473  Ensure that this is only allowed on an encrypted connection with a root
2474  user. JRA.
2475  *************************************************************************/
2476
2477 static NTSTATUS get_user_info_18(pipes_struct *p,
2478                                  TALLOC_CTX *mem_ctx,
2479                                  struct samr_UserInfo18 *r,
2480                                  DOM_SID *user_sid)
2481 {
2482         struct samu *smbpass=NULL;
2483         bool ret;
2484
2485         ZERO_STRUCTP(r);
2486
2487         if (p->auth.auth_type != PIPE_AUTH_TYPE_NTLMSSP || p->auth.auth_type != PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) {
2488                 return NT_STATUS_ACCESS_DENIED;
2489         }
2490
2491         if (p->auth.auth_level != PIPE_AUTH_LEVEL_PRIVACY) {
2492                 return NT_STATUS_ACCESS_DENIED;
2493         }
2494
2495         /*
2496          * Do *NOT* do become_root()/unbecome_root() here ! JRA.
2497          */
2498
2499         if ( !(smbpass = samu_new( mem_ctx )) ) {
2500                 return NT_STATUS_NO_MEMORY;
2501         }
2502
2503         ret = pdb_getsampwsid(smbpass, user_sid);
2504
2505         if (ret == False) {
2506                 DEBUG(4, ("User %s not found\n", sid_string_dbg(user_sid)));
2507                 TALLOC_FREE(smbpass);
2508                 return (geteuid() == (uid_t)0) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
2509         }
2510
2511         DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
2512
2513         if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
2514                 TALLOC_FREE(smbpass);
2515                 return NT_STATUS_ACCOUNT_DISABLED;
2516         }
2517
2518         init_samr_user_info18(r, pdb_get_lanman_passwd(smbpass),
2519                               pdb_get_nt_passwd(smbpass));
2520
2521         TALLOC_FREE(smbpass);
2522
2523         return NT_STATUS_OK;
2524 }
2525
2526 /*************************************************************************
2527  get_user_info_20
2528  *************************************************************************/
2529
2530 static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx,
2531                                  struct samr_UserInfo20 *r,
2532                                  DOM_SID *user_sid)
2533 {
2534         struct samu *sampass=NULL;
2535         bool ret;
2536         const char *munged_dial = NULL;
2537         DATA_BLOB blob;
2538         NTSTATUS status;
2539         struct lsa_BinaryString *parameters = NULL;
2540
2541         ZERO_STRUCTP(r);
2542
2543         if ( !(sampass = samu_new( mem_ctx )) ) {
2544                 return NT_STATUS_NO_MEMORY;
2545         }
2546
2547         become_root();
2548         ret = pdb_getsampwsid(sampass, user_sid);
2549         unbecome_root();
2550
2551         if (ret == False) {
2552                 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
2553                 TALLOC_FREE(sampass);
2554                 return NT_STATUS_NO_SUCH_USER;
2555         }
2556
2557         munged_dial = pdb_get_munged_dial(sampass);
2558
2559         samr_clear_sam_passwd(sampass);
2560
2561         DEBUG(3,("User:[%s] has [%s] (length: %d)\n", pdb_get_username(sampass),
2562                 munged_dial, (int)strlen(munged_dial)));
2563
2564         if (munged_dial) {
2565                 blob = base64_decode_data_blob(munged_dial);
2566         } else {
2567                 blob = data_blob_string_const_null("");
2568         }
2569
2570         status = init_samr_parameters_string(mem_ctx, &blob, &parameters);
2571         data_blob_free(&blob);
2572         TALLOC_FREE(sampass);
2573         if (!NT_STATUS_IS_OK(status)) {
2574                 return status;
2575         }
2576
2577         init_samr_user_info20(r, parameters);
2578
2579         return NT_STATUS_OK;
2580 }
2581
2582
2583 /*************************************************************************
2584  get_user_info_21
2585  *************************************************************************/
2586
2587 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx,
2588                                  struct samr_UserInfo21 *r,
2589                                  DOM_SID *user_sid,
2590                                  DOM_SID *domain_sid)
2591 {
2592         NTSTATUS status;
2593         struct samu *pw = NULL;
2594         bool ret;
2595         const DOM_SID *sid_user, *sid_group;
2596         uint32_t rid, primary_gid;
2597         NTTIME last_logon, last_logoff, last_password_change,
2598                acct_expiry, allow_password_change, force_password_change;
2599         time_t must_change_time;
2600         uint8_t password_expired;
2601         const char *account_name, *full_name, *home_directory, *home_drive,
2602                    *logon_script, *profile_path, *description,
2603                    *workstations, *comment;
2604         struct samr_LogonHours logon_hours;
2605         struct lsa_BinaryString *parameters = NULL;
2606         const char *munged_dial = NULL;
2607         DATA_BLOB blob;
2608
2609         ZERO_STRUCTP(r);
2610
2611         if (!(pw = samu_new(mem_ctx))) {
2612                 return NT_STATUS_NO_MEMORY;
2613         }
2614
2615         become_root();
2616         ret = pdb_getsampwsid(pw, user_sid);
2617         unbecome_root();
2618
2619         if (ret == False) {
2620                 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
2621                 TALLOC_FREE(pw);
2622                 return NT_STATUS_NO_SUCH_USER;
2623         }
2624
2625         samr_clear_sam_passwd(pw);
2626
2627         DEBUG(3,("User:[%s]\n", pdb_get_username(pw)));
2628
2629         sid_user = pdb_get_user_sid(pw);
2630
2631         if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2632                 DEBUG(0, ("get_user_info_21: User %s has SID %s, \nwhich conflicts with "
2633                           "the domain sid %s.  Failing operation.\n",
2634                           pdb_get_username(pw), sid_string_dbg(sid_user),
2635                           sid_string_dbg(domain_sid)));
2636                 TALLOC_FREE(pw);
2637                 return NT_STATUS_UNSUCCESSFUL;
2638         }
2639
2640         become_root();
2641         sid_group = pdb_get_group_sid(pw);
2642         unbecome_root();
2643
2644         if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2645                 DEBUG(0, ("get_user_info_21: User %s has Primary Group SID %s, \n"
2646                           "which conflicts with the domain sid %s.  Failing operation.\n",
2647                           pdb_get_username(pw), sid_string_dbg(sid_group),
2648                           sid_string_dbg(domain_sid)));
2649                 TALLOC_FREE(pw);
2650                 return NT_STATUS_UNSUCCESSFUL;
2651         }
2652
2653         unix_to_nt_time(&last_logon, pdb_get_logon_time(pw));
2654         unix_to_nt_time(&last_logoff, pdb_get_logoff_time(pw));
2655         unix_to_nt_time(&acct_expiry, pdb_get_kickoff_time(pw));
2656         unix_to_nt_time(&last_password_change, pdb_get_pass_last_set_time(pw));
2657         unix_to_nt_time(&allow_password_change, pdb_get_pass_can_change_time(pw));
2658
2659         must_change_time = pdb_get_pass_must_change_time(pw);
2660         if (must_change_time == get_time_t_max()) {
2661                 unix_to_nt_time_abs(&force_password_change, must_change_time);
2662         } else {
2663                 unix_to_nt_time(&force_password_change, must_change_time);
2664         }
2665
2666         if (pdb_get_pass_must_change_time(pw) == 0) {
2667                 password_expired = PASS_MUST_CHANGE_AT_NEXT_LOGON;
2668         } else {
2669                 password_expired = 0;
2670         }
2671
2672         munged_dial = pdb_get_munged_dial(pw);
2673         if (munged_dial) {
2674                 blob = base64_decode_data_blob(munged_dial);
2675         } else {
2676                 blob = data_blob_string_const_null("");
2677         }
2678
2679         status = init_samr_parameters_string(mem_ctx, &blob, &parameters);
2680         data_blob_free(&blob);
2681         if (!NT_STATUS_IS_OK(status)) {
2682                 TALLOC_FREE(pw);
2683                 return status;
2684         }
2685
2686         account_name = talloc_strdup(mem_ctx, pdb_get_username(pw));
2687         full_name = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2688         home_directory = talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2689         home_drive = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2690         logon_script = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2691         profile_path = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2692         description = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2693         workstations = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2694         comment = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2695
2696         logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2697 #if 0
2698
2699         /*
2700           Look at a user on a real NT4 PDC with usrmgr, press
2701           'ok'. Then you will see that fields_present is set to
2702           0x08f827fa. Look at the user immediately after that again,
2703           and you will see that 0x00fffff is returned. This solves
2704           the problem that you get access denied after having looked
2705           at the user.
2706           -- Volker
2707         */
2708
2709 #endif
2710
2711         init_samr_user_info21(r,
2712                               last_logon,
2713                               last_logoff,
2714                               last_password_change,
2715                               acct_expiry,
2716                               allow_password_change,
2717                               force_password_change,
2718                               account_name,
2719                               full_name,
2720                               home_directory,
2721                               home_drive,
2722                               logon_script,
2723                               profile_path,
2724                               description,
2725                               workstations,
2726                               comment,
2727                               parameters,
2728                               rid,
2729                               primary_gid,
2730                               pdb_get_acct_ctrl(pw),
2731                               pdb_build_fields_present(pw),
2732                               logon_hours,
2733                               pdb_get_bad_password_count(pw),
2734                               pdb_get_logon_count(pw),
2735                               0, /* country_code */
2736                               0, /* code_page */
2737                               0, /* nt_password_set */
2738                               0, /* lm_password_set */
2739                               password_expired);
2740         TALLOC_FREE(pw);
2741
2742         return NT_STATUS_OK;
2743 }
2744
2745 /*******************************************************************
2746  _samr_QueryUserInfo
2747  ********************************************************************/
2748
2749 NTSTATUS _samr_QueryUserInfo(pipes_struct *p,
2750                              struct samr_QueryUserInfo *r)
2751 {
2752         NTSTATUS status;
2753         union samr_UserInfo *user_info = NULL;
2754         struct samr_info *info = NULL;
2755         DOM_SID domain_sid;
2756         uint32 rid;
2757
2758         /* search for the handle */
2759         if (!find_policy_by_hnd(p, r->in.user_handle, (void **)(void *)&info))
2760                 return NT_STATUS_INVALID_HANDLE;
2761
2762         status = access_check_samr_function(info->acc_granted,
2763                                             SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
2764                                             "_samr_QueryUserInfo");
2765         if (!NT_STATUS_IS_OK(status)) {
2766                 return status;
2767         }
2768
2769         domain_sid = info->sid;
2770
2771         sid_split_rid(&domain_sid, &rid);
2772
2773         if (!sid_check_is_in_our_domain(&info->sid))
2774                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2775
2776         DEBUG(5,("_samr_QueryUserInfo: sid:%s\n",
2777                  sid_string_dbg(&info->sid)));
2778
2779         user_info = TALLOC_ZERO_P(p->mem_ctx, union samr_UserInfo);
2780         if (!user_info) {
2781                 return NT_STATUS_NO_MEMORY;
2782         }
2783
2784         DEBUG(5,("_samr_QueryUserInfo: user info level: %d\n", r->in.level));
2785
2786         switch (r->in.level) {
2787         case 5:
2788                 status = get_user_info_5(p->mem_ctx, &user_info->info5, &info->sid, &domain_sid);
2789                 if (!NT_STATUS_IS_OK(status)) {
2790                         return status;
2791                 }
2792                 break;
2793         case 7:
2794                 status = get_user_info_7(p->mem_ctx, &user_info->info7, &info->sid);
2795                 if (!NT_STATUS_IS_OK(status)) {
2796                         return status;
2797                 }
2798                 break;
2799         case 9:
2800                 status = get_user_info_9(p->mem_ctx, &user_info->info9, &info->sid);
2801                 if (!NT_STATUS_IS_OK(status)) {
2802                         return status;
2803                 }
2804                 break;
2805         case 16:
2806                 status = get_user_info_16(p->mem_ctx, &user_info->info16, &info->sid);
2807                 if (!NT_STATUS_IS_OK(status)) {
2808                         return status;
2809                 }
2810                 break;
2811
2812         case 18:
2813                 status = get_user_info_18(p, p->mem_ctx, &user_info->info18, &info->sid);
2814                 if (!NT_STATUS_IS_OK(status)) {
2815                         return status;
2816                 }
2817                 break;
2818
2819         case 20:
2820                 status = get_user_info_20(p->mem_ctx, &user_info->info20, &info->sid);
2821                 if (!NT_STATUS_IS_OK(status)) {
2822                         return status;
2823                 }
2824                 break;
2825
2826         case 21:
2827                 status = get_user_info_21(p->mem_ctx, &user_info->info21,
2828                                           &info->sid, &domain_sid);
2829                 if (!NT_STATUS_IS_OK(status)) {
2830                         return status;
2831                 }
2832                 break;
2833
2834         default:
2835                 return NT_STATUS_INVALID_INFO_CLASS;
2836         }
2837
2838         *r->out.info = user_info;
2839
2840         DEBUG(5,("_samr_QueryUserInfo: %d\n", __LINE__));
2841
2842         return status;
2843 }
2844
2845 /****************************************************************
2846 ****************************************************************/
2847
2848 NTSTATUS _samr_QueryUserInfo2(pipes_struct *p,
2849                               struct samr_QueryUserInfo2 *r)
2850 {
2851         struct samr_QueryUserInfo u;
2852
2853         u.in.user_handle        = r->in.user_handle;
2854         u.in.level              = r->in.level;
2855         u.out.info              = r->out.info;
2856
2857         return _samr_QueryUserInfo(p, &u);
2858 }
2859
2860 /*******************************************************************
2861  _samr_GetGroupsForUser
2862  ********************************************************************/
2863
2864 NTSTATUS _samr_GetGroupsForUser(pipes_struct *p,
2865                                 struct samr_GetGroupsForUser *r)
2866 {
2867         struct samu *sam_pass=NULL;
2868         DOM_SID  sid;
2869         DOM_SID *sids;
2870         struct samr_RidWithAttribute dom_gid;
2871         struct samr_RidWithAttribute *gids = NULL;
2872         uint32 primary_group_rid;
2873         size_t num_groups = 0;
2874         gid_t *unix_gids;
2875         size_t i, num_gids;
2876         uint32 acc_granted;
2877         bool ret;
2878         NTSTATUS result;
2879         bool success = False;
2880
2881         struct samr_RidWithAttributeArray *rids = NULL;
2882
2883         /*
2884          * from the SID in the request:
2885          * we should send back the list of DOMAIN GROUPS
2886          * the user is a member of
2887          *
2888          * and only the DOMAIN GROUPS
2889          * no ALIASES !!! neither aliases of the domain
2890          * nor aliases of the builtin SID
2891          *
2892          * JFM, 12/2/2001
2893          */
2894
2895         DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
2896
2897         rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidWithAttributeArray);
2898         if (!rids) {
2899                 return NT_STATUS_NO_MEMORY;
2900         }
2901
2902         /* find the policy handle.  open a policy on it. */
2903         if (!get_lsa_policy_samr_sid(p, r->in.user_handle, &sid, &acc_granted, NULL))
2904                 return NT_STATUS_INVALID_HANDLE;
2905
2906         result = access_check_samr_function(acc_granted,
2907                                             SAMR_USER_ACCESS_GET_GROUPS,
2908                                             "_samr_GetGroupsForUser");
2909         if (!NT_STATUS_IS_OK(result)) {
2910                 return result;
2911         }
2912
2913         if (!sid_check_is_in_our_domain(&sid))
2914                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2915
2916         if ( !(sam_pass = samu_new( p->mem_ctx )) ) {
2917                 return NT_STATUS_NO_MEMORY;
2918         }
2919
2920         become_root();
2921         ret = pdb_getsampwsid(sam_pass, &sid);
2922         unbecome_root();
2923
2924         if (!ret) {
2925                 DEBUG(10, ("pdb_getsampwsid failed for %s\n",
2926                            sid_string_dbg(&sid)));
2927                 return NT_STATUS_NO_SUCH_USER;
2928         }
2929
2930         sids = NULL;
2931
2932         /* make both calls inside the root block */
2933         become_root();
2934         result = pdb_enum_group_memberships(p->mem_ctx, sam_pass,
2935                                             &sids, &unix_gids, &num_groups);
2936         if ( NT_STATUS_IS_OK(result) ) {
2937                 success = sid_peek_check_rid(get_global_sam_sid(),
2938                                              pdb_get_group_sid(sam_pass),
2939                                              &primary_group_rid);
2940         }
2941         unbecome_root();
2942
2943         if (!NT_STATUS_IS_OK(result)) {
2944                 DEBUG(10, ("pdb_enum_group_memberships failed for %s\n",
2945                            sid_string_dbg(&sid)));
2946                 return result;
2947         }
2948
2949         if ( !success ) {
2950                 DEBUG(5, ("Group sid %s for user %s not in our domain\n",
2951                           sid_string_dbg(pdb_get_group_sid(sam_pass)),
2952                           pdb_get_username(sam_pass)));
2953                 TALLOC_FREE(sam_pass);
2954                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2955         }
2956
2957         gids = NULL;
2958         num_gids = 0;
2959
2960         dom_gid.attributes = (SE_GROUP_MANDATORY|SE_GROUP_ENABLED_BY_DEFAULT|
2961                               SE_GROUP_ENABLED);
2962         dom_gid.rid = primary_group_rid;
2963         ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
2964
2965         for (i=0; i<num_groups; i++) {
2966
2967                 if (!sid_peek_check_rid(get_global_sam_sid(),
2968                                         &(sids[i]), &dom_gid.rid)) {
2969                         DEBUG(10, ("Found sid %s not in our domain\n",
2970                                    sid_string_dbg(&sids[i])));
2971                         continue;
2972                 }
2973
2974                 if (dom_gid.rid == primary_group_rid) {
2975                         /* We added the primary group directly from the
2976                          * sam_account. The other SIDs are unique from
2977                          * enum_group_memberships */
2978                         continue;
2979                 }
2980
2981                 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
2982         }
2983
2984         rids->count = num_gids;
2985         rids->rids = gids;
2986
2987         *r->out.rids = rids;
2988
2989         DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
2990
2991         return result;
2992 }
2993
2994 /*******************************************************************
2995  _samr_QueryDomainInfo
2996  ********************************************************************/
2997
2998 NTSTATUS _samr_QueryDomainInfo(pipes_struct *p,
2999                                struct samr_QueryDomainInfo *r)
3000 {
3001         NTSTATUS status = NT_STATUS_OK;
3002         struct samr_info *info = NULL;
3003         union samr_DomainInfo *dom_info;
3004         uint32 min_pass_len,pass_hist,password_properties;
3005         time_t u_expire, u_min_age;
3006         NTTIME nt_expire, nt_min_age;
3007
3008         time_t u_lock_duration, u_reset_time;
3009         NTTIME nt_lock_duration, nt_reset_time;
3010         uint32 lockout;
3011         time_t u_logout;
3012         NTTIME nt_logout;
3013
3014         uint32 account_policy_temp;
3015
3016         time_t seq_num;
3017         uint32 server_role;
3018
3019         uint32 num_users=0, num_groups=0, num_aliases=0;
3020
3021         DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__));
3022
3023         dom_info = TALLOC_ZERO_P(p->mem_ctx, union samr_DomainInfo);
3024         if (!dom_info) {
3025                 return NT_STATUS_NO_MEMORY;
3026         }
3027
3028         /* find the policy handle.  open a policy on it. */
3029         if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info)) {
3030                 return NT_STATUS_INVALID_HANDLE;
3031         }
3032
3033         status = access_check_samr_function(info->acc_granted,
3034                                             SAMR_ACCESS_OPEN_DOMAIN,
3035                                             "_samr_QueryDomainInfo" );
3036
3037         if ( !NT_STATUS_IS_OK(status) )
3038                 return status;
3039
3040         switch (r->in.level) {
3041                 case 0x01:
3042
3043                         become_root();
3044
3045                         /* AS ROOT !!! */
3046
3047                         pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &account_policy_temp);
3048                         min_pass_len = account_policy_temp;
3049
3050                         pdb_get_account_policy(AP_PASSWORD_HISTORY, &account_policy_temp);
3051                         pass_hist = account_policy_temp;
3052
3053                         pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
3054                         password_properties = account_policy_temp;
3055
3056                         pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
3057                         u_expire = account_policy_temp;
3058
3059                         pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
3060                         u_min_age = account_policy_temp;
3061
3062                         /* !AS ROOT */
3063
3064                         unbecome_root();
3065
3066                         unix_to_nt_time_abs(&nt_expire, u_expire);
3067                         unix_to_nt_time_abs(&nt_min_age, u_min_age);
3068
3069                         if (lp_check_password_script() && *lp_check_password_script()) {
3070                                 password_properties |= DOMAIN_PASSWORD_COMPLEX;
3071                         }
3072
3073                         init_samr_DomInfo1(&dom_info->info1,
3074                                            (uint16)min_pass_len,
3075                                            (uint16)pass_hist,
3076                                            password_properties,
3077                                            nt_expire,
3078                                            nt_min_age);
3079                         break;
3080                 case 0x02:
3081
3082                         become_root();
3083
3084                         /* AS ROOT !!! */
3085
3086                         num_users = count_sam_users(info->disp_info, ACB_NORMAL);
3087                         num_groups = count_sam_groups(info->disp_info);
3088                         num_aliases = count_sam_aliases(info->disp_info);
3089
3090                         pdb_get_account_policy(AP_TIME_TO_LOGOUT, &account_policy_temp);
3091                         u_logout = account_policy_temp;
3092
3093                         unix_to_nt_time_abs(&nt_logout, u_logout);
3094
3095                         if (!pdb_get_seq_num(&seq_num))
3096                                 seq_num = time(NULL);
3097
3098                         /* !AS ROOT */
3099
3100                         unbecome_root();
3101
3102                         server_role = ROLE_DOMAIN_PDC;
3103                         if (lp_server_role() == ROLE_DOMAIN_BDC)
3104                                 server_role = ROLE_DOMAIN_BDC;
3105
3106                         init_samr_DomGeneralInformation(&dom_info->general,
3107                                                         nt_logout,
3108                                                         lp_serverstring(),
3109                                                         lp_workgroup(),
3110                                                         global_myname(),
3111                                                         seq_num,
3112                                                         1,
3113                                                         server_role,
3114                                                         1,
3115                                                         num_users,
3116                                                         num_groups,
3117                                                         num_aliases);
3118                         break;
3119                 case 0x03:
3120
3121                         become_root();
3122
3123                         /* AS ROOT !!! */
3124
3125                         {
3126                                 uint32 ul;
3127                                 pdb_get_account_policy(AP_TIME_TO_LOGOUT, &ul);
3128                                 u_logout = (time_t)ul;
3129                         }
3130
3131                         /* !AS ROOT */
3132
3133                         unbecome_root();
3134
3135                         unix_to_nt_time_abs(&nt_logout, u_logout);
3136
3137                         init_samr_DomInfo3(&dom_info->info3,
3138                                            nt_logout);
3139
3140                         break;
3141                 case 0x04:
3142                         init_samr_DomOEMInformation(&dom_info->oem,
3143                                                     lp_serverstring());
3144                         break;
3145                 case 0x05:
3146                         init_samr_DomInfo5(&dom_info->info5,
3147                                            get_global_sam_name());
3148                         break;
3149                 case 0x06:
3150                         /* NT returns its own name when a PDC. win2k and later
3151                          * only the name of the PDC if itself is a BDC (samba4
3152                          * idl) */
3153                         init_samr_DomInfo6(&dom_info->info6,
3154                                            global_myname());
3155                         break;
3156                 case 0x07:
3157                         server_role = ROLE_DOMAIN_PDC;
3158                         if (lp_server_role() == ROLE_DOMAIN_BDC)
3159                                 server_role = ROLE_DOMAIN_BDC;
3160
3161                         init_samr_DomInfo7(&dom_info->info7,
3162                                            server_role);
3163                         break;
3164                 case 0x08:
3165
3166                         become_root();
3167
3168                         /* AS ROOT !!! */
3169
3170                         if (!pdb_get_seq_num(&seq_num)) {
3171                                 seq_num = time(NULL);
3172                         }
3173
3174                         /* !AS ROOT */
3175
3176                         unbecome_root();
3177
3178                         init_samr_DomInfo8(&dom_info->info8,
3179                                            seq_num,
3180                                            0);
3181                         break;
3182                 case 0x0c:
3183
3184                         become_root();
3185
3186                         /* AS ROOT !!! */
3187
3188                         pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
3189                         u_lock_duration = account_policy_temp;
3190                         if (u_lock_duration != -1) {
3191                                 u_lock_duration *= 60;
3192                         }
3193
3194                         pdb_get_account_policy(AP_RESET_COUNT_TIME, &account_policy_temp);
3195                         u_reset_time = account_policy_temp * 60;
3196
3197                         pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
3198                         lockout = account_policy_temp;
3199
3200                         /* !AS ROOT */
3201
3202                         unbecome_root();
3203
3204                         unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
3205                         unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
3206
3207                         init_samr_DomInfo12(&dom_info->info12,
3208                                             nt_lock_duration,
3209                                             nt_reset_time,
3210                                             (uint16)lockout);
3211                         break;
3212                 default:
3213                         return NT_STATUS_INVALID_INFO_CLASS;
3214         }
3215
3216         *r->out.info = dom_info;
3217
3218         DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__));
3219
3220         return status;
3221 }
3222
3223 /* W2k3 seems to use the same check for all 3 objects that can be created via
3224  * SAMR, if you try to create for example "Dialup" as an alias it says
3225  * "NT_STATUS_USER_EXISTS". This is racy, but we can't really lock the user
3226  * database. */
3227
3228 static NTSTATUS can_create(TALLOC_CTX *mem_ctx, const char *new_name)
3229 {
3230         enum lsa_SidType type;
3231         bool result;
3232
3233         DEBUG(10, ("Checking whether [%s] can be created\n", new_name));
3234
3235         become_root();
3236         /* Lookup in our local databases (LOOKUP_NAME_REMOTE not set)
3237          * whether the name already exists */
3238         result = lookup_name(mem_ctx, new_name, LOOKUP_NAME_LOCAL,
3239                              NULL, NULL, NULL, &type);
3240         unbecome_root();
3241
3242         if (!result) {
3243                 DEBUG(10, ("%s does not exist, can create it\n", new_name));
3244                 return NT_STATUS_OK;
3245         }
3246
3247         DEBUG(5, ("trying to create %s, exists as %s\n",
3248                   new_name, sid_type_lookup(type)));
3249
3250         if (type == SID_NAME_DOM_GRP) {
3251                 return NT_STATUS_GROUP_EXISTS;
3252         }
3253         if (type == SID_NAME_ALIAS) {
3254                 return NT_STATUS_ALIAS_EXISTS;
3255         }
3256
3257         /* Yes, the default is NT_STATUS_USER_EXISTS */
3258         return NT_STATUS_USER_EXISTS;
3259 }
3260
3261 /*******************************************************************
3262  _samr_CreateUser2
3263  ********************************************************************/
3264
3265 NTSTATUS _samr_CreateUser2(pipes_struct *p,
3266                            struct samr_CreateUser2 *r)
3267 {
3268         const char *account = NULL;
3269         DOM_SID sid;
3270         POLICY_HND dom_pol = *r->in.domain_handle;
3271         uint32_t acb_info = r->in.acct_flags;
3272         POLICY_HND *user_pol = r->out.user_handle;
3273         struct samr_info *info = NULL;
3274         NTSTATUS nt_status;
3275         uint32 acc_granted;
3276         SEC_DESC *psd;
3277         size_t    sd_size;
3278         /* check this, when giving away 'add computer to domain' privs */
3279         uint32    des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
3280         bool can_add_account = False;
3281         SE_PRIV se_rights;
3282         DISP_INFO *disp_info = NULL;
3283
3284         /* Get the domain SID stored in the domain policy */
3285         if (!get_lsa_policy_samr_sid(p, &dom_pol, &sid, &acc_granted,
3286                                      &disp_info))
3287                 return NT_STATUS_INVALID_HANDLE;
3288
3289         if (disp_info->builtin_domain) {
3290                 DEBUG(5,("_samr_CreateUser2: Refusing user create in BUILTIN\n"));
3291                 return NT_STATUS_ACCESS_DENIED;
3292         }
3293
3294         nt_status = access_check_samr_function(acc_granted,
3295                                                SAMR_DOMAIN_ACCESS_CREATE_USER,
3296                                                "_samr_CreateUser2");
3297         if (!NT_STATUS_IS_OK(nt_status)) {
3298                 return nt_status;
3299         }
3300
3301         if (!(acb_info == ACB_NORMAL || acb_info == ACB_DOMTRUST ||
3302               acb_info == ACB_WSTRUST || acb_info == ACB_SVRTRUST)) {
3303                 /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if
3304                    this parameter is not an account type */
3305                 return NT_STATUS_INVALID_PARAMETER;
3306         }
3307
3308         account = r->in.account_name->string;
3309         if (account == NULL) {
3310                 return NT_STATUS_NO_MEMORY;
3311         }
3312
3313         nt_status = can_create(p->mem_ctx, account);
3314         if (!NT_STATUS_IS_OK(nt_status)) {
3315                 return nt_status;
3316         }
3317
3318         /* determine which user right we need to check based on the acb_info */
3319
3320         if ( acb_info & ACB_WSTRUST )
3321         {
3322                 se_priv_copy( &se_rights, &se_machine_account );
3323                 can_add_account = user_has_privileges(
3324                         p->server_info->ptok, &se_rights );
3325         }
3326         /* usrmgr.exe (and net rpc trustdom grant) creates a normal user
3327            account for domain trusts and changes the ACB flags later */
3328         else if ( acb_info & ACB_NORMAL &&
3329                   (account[strlen(account)-1] != '$') )
3330         {
3331                 se_priv_copy( &se_rights, &se_add_users );
3332                 can_add_account = user_has_privileges(
3333                         p->server_info->ptok, &se_rights );
3334         }
3335         else    /* implicit assumption of a BDC or domain trust account here
3336                  * (we already check the flags earlier) */
3337         {
3338                 if ( lp_enable_privileges() ) {
3339                         /* only Domain Admins can add a BDC or domain trust */
3340                         se_priv_copy( &se_rights, &se_priv_none );
3341                         can_add_account = nt_token_check_domain_rid(
3342                                 p->server_info->ptok,
3343                                 DOMAIN_GROUP_RID_ADMINS );
3344                 }
3345         }
3346
3347         DEBUG(5, ("_samr_CreateUser2: %s can add this account : %s\n",
3348                   uidtoname(p->server_info->utok.uid),
3349                   can_add_account ? "True":"False" ));
3350
3351         /********** BEGIN Admin BLOCK **********/
3352
3353         if ( can_add_account )
3354                 become_root();
3355
3356         nt_status = pdb_create_user(p->mem_ctx, account, acb_info,
3357                                     r->out.rid);
3358
3359         if ( can_add_account )
3360                 unbecome_root();
3361
3362         /********** END Admin BLOCK **********/
3363
3364         /* now check for failure */
3365
3366         if ( !NT_STATUS_IS_OK(nt_status) )
3367                 return nt_status;
3368
3369         /* Get the user's SID */
3370
3371         sid_compose(&sid, get_global_sam_sid(), *r->out.rid);
3372
3373         map_max_allowed_access(p->server_info->ptok, &des_access);
3374
3375         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping,
3376                             &sid, SAMR_USR_RIGHTS_WRITE_PW);
3377         se_map_generic(&des_access, &usr_generic_mapping);
3378
3379         nt_status = access_check_samr_object(psd, p->server_info->ptok,
3380                 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
3381                 &acc_granted, "_samr_CreateUser2");
3382
3383         if ( !NT_STATUS_IS_OK(nt_status) ) {
3384                 return nt_status;
3385         }
3386
3387         /* associate the user's SID with the new handle. */
3388         if ((info = get_samr_info_by_sid(&sid)) == NULL) {
3389                 return NT_STATUS_NO_MEMORY;
3390         }
3391
3392         ZERO_STRUCTP(info);
3393         info->sid = sid;
3394         info->acc_granted = acc_granted;
3395
3396         /* get a (unique) handle.  open a policy on it. */
3397         if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info)) {
3398                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3399         }
3400
3401         /* After a "set" ensure we have no cached display info. */
3402         force_flush_samr_cache(info->disp_info);
3403
3404         *r->out.access_granted = acc_granted;
3405
3406         return NT_STATUS_OK;
3407 }
3408
3409 /****************************************************************
3410 ****************************************************************/
3411
3412 NTSTATUS _samr_CreateUser(pipes_struct *p,
3413                           struct samr_CreateUser *r)
3414 {
3415         struct samr_CreateUser2 c;
3416         uint32_t access_granted;
3417
3418         c.in.domain_handle      = r->in.domain_handle;
3419         c.in.account_name       = r->in.account_name;
3420         c.in.acct_flags         = ACB_NORMAL;
3421         c.in.access_mask        = r->in.access_mask;
3422         c.out.user_handle       = r->out.user_handle;
3423         c.out.access_granted    = &access_granted;
3424         c.out.rid               = r->out.rid;
3425
3426         return _samr_CreateUser2(p, &c);
3427 }
3428
3429 /*******************************************************************
3430  _samr_Connect
3431  ********************************************************************/
3432
3433 NTSTATUS _samr_Connect(pipes_struct *p,
3434                        struct samr_Connect *r)
3435 {
3436         struct samr_info *info = NULL;
3437         uint32    des_access = r->in.access_mask;
3438
3439         /* Access check */
3440
3441         if (!pipe_access_check(p)) {
3442                 DEBUG(3, ("access denied to _samr_Connect\n"));
3443                 return NT_STATUS_ACCESS_DENIED;
3444         }
3445
3446         /* set up the SAMR connect_anon response */
3447
3448         /* associate the user's SID with the new handle. */
3449         if ((info = get_samr_info_by_sid(NULL)) == NULL)
3450                 return NT_STATUS_NO_MEMORY;
3451
3452         /* don't give away the farm but this is probably ok.  The SAMR_ACCESS_ENUM_DOMAINS
3453            was observed from a win98 client trying to enumerate users (when configured
3454            user level access control on shares)   --jerry */
3455
3456         map_max_allowed_access(p->server_info->ptok, &des_access);
3457
3458         se_map_generic( &des_access, &sam_generic_mapping );
3459         info->acc_granted = des_access & (SAMR_ACCESS_ENUM_DOMAINS|SAMR_ACCESS_OPEN_DOMAIN);
3460
3461         /* get a (unique) handle.  open a policy on it. */
3462         if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info))
3463                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3464
3465         return NT_STATUS_OK;
3466 }
3467
3468 /*******************************************************************
3469  _samr_Connect2
3470  ********************************************************************/
3471
3472 NTSTATUS _samr_Connect2(pipes_struct *p,
3473                         struct samr_Connect2 *r)
3474 {
3475         struct samr_info *info = NULL;
3476         SEC_DESC *psd = NULL;
3477         uint32    acc_granted;
3478         uint32    des_access = r->in.access_mask;
3479         NTSTATUS  nt_status;
3480         size_t    sd_size;
3481
3482
3483         DEBUG(5,("_samr_Connect2: %d\n", __LINE__));
3484
3485         /* Access check */
3486
3487         if (!pipe_access_check(p)) {
3488                 DEBUG(3, ("access denied to _samr_Connect2\n"));
3489                 return NT_STATUS_ACCESS_DENIED;
3490         }
3491
3492         map_max_allowed_access(p->server_info->ptok, &des_access);
3493
3494         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
3495         se_map_generic(&des_access, &sam_generic_mapping);
3496
3497         nt_status = access_check_samr_object(psd, p->server_info->ptok,
3498                 NULL, 0, des_access, &acc_granted, "_samr_Connect2");
3499
3500         if ( !NT_STATUS_IS_OK(nt_status) )
3501                 return nt_status;
3502
3503         /* associate the user's SID and access granted with the new handle. */
3504         if ((info = get_samr_info_by_sid(NULL)) == NULL)
3505                 return NT_STATUS_NO_MEMORY;
3506
3507         info->acc_granted = acc_granted;
3508         info->status = r->in.access_mask; /* this looks so wrong... - gd */
3509
3510         /* get a (unique) handle.  open a policy on it. */
3511         if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info))
3512                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3513
3514         DEBUG(5,("_samr_Connect2: %d\n", __LINE__));
3515
3516         return nt_status;
3517 }
3518
3519 /*******************************************************************
3520  _samr_Connect4
3521  ********************************************************************/
3522
3523 NTSTATUS _samr_Connect4(pipes_struct *p,
3524                         struct samr_Connect4 *r)
3525 {
3526         struct samr_info *info = NULL;
3527         SEC_DESC *psd = NULL;
3528         uint32    acc_granted;
3529         uint32    des_access = r->in.access_mask;
3530         NTSTATUS  nt_status;
3531         size_t    sd_size;
3532
3533
3534         DEBUG(5,("_samr_Connect4: %d\n", __LINE__));
3535
3536         /* Access check */
3537
3538         if (!pipe_access_check(p)) {
3539                 DEBUG(3, ("access denied to samr_Connect4\n"));
3540                 return NT_STATUS_ACCESS_DENIED;
3541         }
3542
3543         map_max_allowed_access(p->server_info->ptok, &des_access);
3544
3545         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
3546         se_map_generic(&des_access, &sam_generic_mapping);
3547
3548         nt_status = access_check_samr_object(psd, p->server_info->ptok,
3549                 NULL, 0, des_access, &acc_granted, "_samr_Connect4");
3550
3551         if ( !NT_STATUS_IS_OK(nt_status) )
3552                 return nt_status;
3553
3554         /* associate the user's SID and access granted with the new handle. */
3555         if ((info = get_samr_info_by_sid(NULL)) == NULL)
3556                 return NT_STATUS_NO_MEMORY;
3557
3558         info->acc_granted = acc_granted;
3559         info->status = r->in.access_mask; /* ??? */
3560
3561         /* get a (unique) handle.  open a policy on it. */
3562         if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info))
3563                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3564
3565         DEBUG(5,("_samr_Connect4: %d\n", __LINE__));
3566
3567         return NT_STATUS_OK;
3568 }
3569
3570 /*******************************************************************
3571  _samr_Connect5
3572  ********************************************************************/
3573
3574 NTSTATUS _samr_Connect5(pipes_struct *p,
3575                         struct samr_Connect5 *r)
3576 {
3577         struct samr_info *info = NULL;
3578         SEC_DESC *psd = NULL;
3579         uint32    acc_granted;
3580         uint32    des_access = r->in.access_mask;
3581         NTSTATUS  nt_status;
3582         size_t    sd_size;
3583         struct samr_ConnectInfo1 info1;
3584
3585         DEBUG(5,("_samr_Connect5: %d\n", __LINE__));
3586
3587         /* Access check */
3588
3589         if (!pipe_access_check(p)) {
3590                 DEBUG(3, ("access denied to samr_Connect5\n"));
3591                 return NT_STATUS_ACCESS_DENIED;
3592         }
3593
3594         map_max_allowed_access(p->server_info->ptok, &des_access);
3595
3596         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
3597         se_map_generic(&des_access, &sam_generic_mapping);
3598
3599         nt_status = access_check_samr_object(psd, p->server_info->ptok,
3600                 NULL, 0, des_access, &acc_granted, "_samr_Connect5");
3601
3602         if ( !NT_STATUS_IS_OK(nt_status) )
3603                 return nt_status;
3604
3605         /* associate the user's SID and access granted with the new handle. */
3606         if ((info = get_samr_info_by_sid(NULL)) == NULL)
3607                 return NT_STATUS_NO_MEMORY;
3608
3609         info->acc_granted = acc_granted;
3610         info->status = r->in.access_mask; /* ??? */
3611
3612         /* get a (unique) handle.  open a policy on it. */
3613         if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info))
3614                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3615
3616         DEBUG(5,("_samr_Connect5: %d\n", __LINE__));
3617
3618         info1.client_version = SAMR_CONNECT_AFTER_W2K;
3619         info1.unknown2 = 0;
3620
3621         *r->out.level_out = 1;
3622         r->out.info_out->info1 = info1;
3623
3624         return NT_STATUS_OK;
3625 }
3626
3627 /**********************************************************************
3628  _samr_LookupDomain
3629  **********************************************************************/
3630
3631 NTSTATUS _samr_LookupDomain(pipes_struct *p,
3632                             struct samr_LookupDomain *r)
3633 {
3634         NTSTATUS status = NT_STATUS_OK;
3635         struct samr_info *info;
3636         const char *domain_name;
3637         DOM_SID *sid = NULL;
3638
3639         if (!find_policy_by_hnd(p, r->in.connect_handle, (void**)(void *)&info))
3640                 return NT_STATUS_INVALID_HANDLE;
3641
3642         /* win9x user manager likes to use SAMR_ACCESS_ENUM_DOMAINS here.
3643            Reverted that change so we will work with RAS servers again */
3644
3645         status = access_check_samr_function(info->acc_granted,
3646                                             SAMR_ACCESS_OPEN_DOMAIN,
3647                                             "_samr_LookupDomain");
3648         if (!NT_STATUS_IS_OK(status)) {
3649                 return status;
3650         }
3651
3652         domain_name = r->in.domain_name->string;
3653         if (!domain_name) {
3654                 return NT_STATUS_INVALID_PARAMETER;
3655         }
3656
3657         sid = TALLOC_ZERO_P(p->mem_ctx, struct dom_sid2);
3658         if (!sid) {
3659                 return NT_STATUS_NO_MEMORY;
3660         }
3661
3662         if (strequal(domain_name, builtin_domain_name())) {
3663                 sid_copy(sid, &global_sid_Builtin);
3664         } else {
3665                 if (!secrets_fetch_domain_sid(domain_name, sid)) {
3666                         status = NT_STATUS_NO_SUCH_DOMAIN;
3667                 }
3668         }
3669
3670         DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name,
3671                  sid_string_dbg(sid)));
3672
3673         *r->out.sid = sid;
3674
3675         return status;
3676 }
3677
3678 /**********************************************************************
3679  _samr_EnumDomains
3680  **********************************************************************/
3681
3682 NTSTATUS _samr_EnumDomains(pipes_struct *p,
3683                            struct samr_EnumDomains *r)
3684 {
3685         NTSTATUS status;
3686         struct samr_info *info;
3687         uint32_t num_entries = 2;
3688         struct samr_SamEntry *entry_array = NULL;
3689         struct samr_SamArray *sam;
3690
3691         if (!find_policy_by_hnd(p, r->in.connect_handle, (void**)(void *)&info))
3692                 return NT_STATUS_INVALID_HANDLE;
3693
3694         status = access_check_samr_function(info->acc_granted,
3695                                             SAMR_ACCESS_ENUM_DOMAINS,
3696                                             "_samr_EnumDomains");
3697         if (!NT_STATUS_IS_OK(status)) {
3698                 return status;
3699         }
3700
3701         sam = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
3702         if (!sam) {
3703                 return NT_STATUS_NO_MEMORY;
3704         }
3705
3706         entry_array = TALLOC_ZERO_ARRAY(p->mem_ctx,
3707                                         struct samr_SamEntry,
3708                                         num_entries);
3709         if (!entry_array) {
3710                 return NT_STATUS_NO_MEMORY;
3711         }
3712
3713         entry_array[0].idx = 0;
3714         init_lsa_String(&entry_array[0].name, get_global_sam_name());
3715
3716         entry_array[1].idx = 1;
3717         init_lsa_String(&entry_array[1].name, "Builtin");
3718
3719         sam->count = num_entries;
3720         sam->entries = entry_array;
3721
3722         *r->out.sam = sam;
3723         *r->out.num_entries = num_entries;
3724
3725         return status;
3726 }
3727
3728 /*******************************************************************
3729  _samr_OpenAlias
3730  ********************************************************************/
3731
3732 NTSTATUS _samr_OpenAlias(pipes_struct *p,
3733                          struct samr_OpenAlias *r)
3734 {
3735         DOM_SID sid;
3736         POLICY_HND domain_pol = *r->in.domain_handle;
3737         uint32 alias_rid = r->in.rid;
3738         POLICY_HND *alias_pol = r->out.alias_handle;
3739         struct    samr_info *info = NULL;
3740         SEC_DESC *psd = NULL;
3741         uint32    acc_granted;
3742         uint32    des_access = r->in.access_mask;
3743         size_t    sd_size;
3744         NTSTATUS  status;
3745         SE_PRIV se_rights;
3746
3747         /* find the domain policy and get the SID / access bits stored in the domain policy */
3748
3749         if ( !get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted, NULL) )
3750                 return NT_STATUS_INVALID_HANDLE;
3751
3752         status = access_check_samr_function(acc_granted,
3753                                             SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
3754                                             "_samr_OpenAlias");
3755
3756         if ( !NT_STATUS_IS_OK(status) )
3757                 return status;
3758
3759         /* append the alias' RID to it */
3760
3761         if (!sid_append_rid(&sid, alias_rid))
3762                 return NT_STATUS_NO_SUCH_ALIAS;
3763
3764         /*check if access can be granted as requested by client. */
3765
3766         map_max_allowed_access(p->server_info->ptok, &des_access);
3767
3768         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &ali_generic_mapping, NULL, 0);
3769         se_map_generic(&des_access,&ali_generic_mapping);
3770
3771         se_priv_copy( &se_rights, &se_add_users );
3772
3773
3774         status = access_check_samr_object(psd, p->server_info->ptok,
3775                 &se_rights, GENERIC_RIGHTS_ALIAS_WRITE, des_access,
3776                 &acc_granted, "_samr_OpenAlias");
3777
3778         if ( !NT_STATUS_IS_OK(status) )
3779                 return status;
3780
3781         {
3782                 /* Check we actually have the requested alias */
3783                 enum lsa_SidType type;
3784                 bool result;
3785                 gid_t gid;
3786
3787                 become_root();
3788                 result = lookup_sid(NULL, &sid, NULL, NULL, &type);
3789                 unbecome_root();
3790
3791                 if (!result || (type != SID_NAME_ALIAS)) {
3792                         return NT_STATUS_NO_SUCH_ALIAS;
3793                 }
3794
3795                 /* make sure there is a mapping */
3796
3797                 if ( !sid_to_gid( &sid, &gid ) ) {
3798                         return NT_STATUS_NO_SUCH_ALIAS;
3799                 }
3800
3801         }
3802
3803         /* associate the alias SID with the new handle. */
3804         if ((info = get_samr_info_by_sid(&sid)) == NULL)
3805                 return NT_STATUS_NO_MEMORY;
3806
3807         info->acc_granted = acc_granted;
3808
3809         /* get a (unique) handle.  open a policy on it. */
3810         if (!create_policy_hnd(p, alias_pol, free_samr_info, (void *)info))
3811                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3812
3813         return NT_STATUS_OK;
3814 }
3815
3816 /*******************************************************************
3817  set_user_info_7
3818  ********************************************************************/
3819
3820 static NTSTATUS set_user_info_7(TALLOC_CTX *mem_ctx,
3821                                 struct samr_UserInfo7 *id7,
3822                                 struct samu *pwd)
3823 {
3824         NTSTATUS rc;
3825
3826         if (id7 == NULL) {
3827                 DEBUG(5, ("set_user_info_7: NULL id7\n"));
3828                 TALLOC_FREE(pwd);
3829                 return NT_STATUS_ACCESS_DENIED;
3830         }
3831
3832         if (!id7->account_name.string) {
3833                 DEBUG(5, ("set_user_info_7: failed to get new username\n"));
3834                 TALLOC_FREE(pwd);
3835                 return NT_STATUS_ACCESS_DENIED;
3836         }
3837
3838         /* check to see if the new username already exists.  Note: we can't
3839            reliably lock all backends, so there is potentially the
3840            possibility that a user can be created in between this check and
3841            the rename.  The rename should fail, but may not get the
3842            exact same failure status code.  I think this is small enough
3843            of a window for this type of operation and the results are
3844            simply that the rename fails with a slightly different status
3845            code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
3846
3847         rc = can_create(mem_ctx, id7->account_name.string);
3848         if (!NT_STATUS_IS_OK(rc)) {
3849                 return rc;
3850         }
3851
3852         rc = pdb_rename_sam_account(pwd, id7->account_name.string);
3853
3854         TALLOC_FREE(pwd);
3855         return rc;
3856 }
3857
3858 /*******************************************************************
3859  set_user_info_16
3860  ********************************************************************/
3861
3862 static bool set_user_info_16(struct samr_UserInfo16 *id16,
3863                              struct samu *pwd)
3864 {
3865         if (id16 == NULL) {
3866                 DEBUG(5, ("set_user_info_16: NULL id16\n"));
3867                 TALLOC_FREE(pwd);
3868                 return False;
3869         }
3870
3871         /* FIX ME: check if the value is really changed --metze */
3872         if (!pdb_set_acct_ctrl(pwd, id16->acct_flags, PDB_CHANGED)) {
3873                 TALLOC_FREE(pwd);
3874                 return False;
3875         }
3876
3877         if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3878                 TALLOC_FREE(pwd);
3879                 return False;
3880         }
3881
3882         TALLOC_FREE(pwd);
3883
3884         return True;
3885 }
3886
3887 /*******************************************************************
3888  set_user_info_18
3889  ********************************************************************/
3890
3891 static bool set_user_info_18(struct samr_UserInfo18 *id18,
3892                              struct samu *pwd)
3893 {
3894         if (id18 == NULL) {
3895                 DEBUG(2, ("set_user_info_18: id18 is NULL\n"));
3896                 TALLOC_FREE(pwd);
3897                 return False;
3898         }
3899
3900         if (!pdb_set_lanman_passwd (pwd, id18->lm_pwd.hash, PDB_CHANGED)) {
3901                 TALLOC_FREE(pwd);
3902                 return False;
3903         }
3904         if (!pdb_set_nt_passwd     (pwd, id18->nt_pwd.hash, PDB_CHANGED)) {
3905                 TALLOC_FREE(pwd);
3906                 return False;
3907         }
3908         if (!pdb_set_pass_last_set_time (pwd, time(NULL), PDB_CHANGED)) {
3909                 TALLOC_FREE(pwd);
3910                 return False;
3911         }
3912
3913         if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3914                 TALLOC_FREE(pwd);
3915                 return False;
3916         }
3917
3918         TALLOC_FREE(pwd);
3919         return True;
3920 }
3921
3922 /*******************************************************************
3923  set_user_info_20
3924  ********************************************************************/
3925
3926 static bool set_user_info_20(struct samr_UserInfo20 *id20,
3927                              struct samu *pwd)
3928 {
3929         if (id20 == NULL) {
3930                 DEBUG(5, ("set_user_info_20: NULL id20\n"));
3931                 return False;
3932         }
3933
3934         copy_id20_to_sam_passwd(pwd, id20);
3935
3936         /* write the change out */
3937         if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3938                 TALLOC_FREE(pwd);
3939                 return False;
3940         }
3941
3942         TALLOC_FREE(pwd);
3943
3944         return True;
3945 }
3946
3947 /*******************************************************************
3948  set_user_info_21
3949  ********************************************************************/
3950
3951 static NTSTATUS set_user_info_21(TALLOC_CTX *mem_ctx,
3952                                  struct samr_UserInfo21 *id21,
3953                                  struct samu *pwd)
3954 {
3955         NTSTATUS status;
3956
3957         if (id21 == NULL) {
3958                 DEBUG(5, ("set_user_info_21: NULL id21\n"));
3959                 return NT_STATUS_INVALID_PARAMETER;
3960         }
3961
3962         /* we need to separately check for an account rename first */
3963
3964         if (id21->account_name.string &&
3965             (!strequal(id21->account_name.string, pdb_get_username(pwd))))
3966         {
3967
3968                 /* check to see if the new username already exists.  Note: we can't
3969                    reliably lock all backends, so there is potentially the
3970                    possibility that a user can be created in between this check and
3971                    the rename.  The rename should fail, but may not get the
3972                    exact same failure status code.  I think this is small enough
3973                    of a window for this type of operation and the results are
3974                    simply that the rename fails with a slightly different status
3975                    code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
3976
3977                 status = can_create(mem_ctx, id21->account_name.string);
3978                 if (!NT_STATUS_IS_OK(status)) {
3979                         return status;
3980                 }
3981
3982                 status = pdb_rename_sam_account(pwd, id21->account_name.string);
3983
3984                 if (!NT_STATUS_IS_OK(status)) {
3985                         DEBUG(0,("set_user_info_21: failed to rename account: %s\n",
3986                                 nt_errstr(status)));
3987                         TALLOC_FREE(pwd);
3988                         return status;
3989                 }
3990
3991                 /* set the new username so that later
3992                    functions can work on the new account */
3993                 pdb_set_username(pwd, id21->account_name.string, PDB_SET);
3994         }
3995
3996         copy_id21_to_sam_passwd("INFO_21", pwd, id21);
3997
3998         /*
3999          * The funny part about the previous two calls is
4000          * that pwd still has the password hashes from the
4001          * passdb entry.  These have not been updated from
4002          * id21.  I don't know if they need to be set.    --jerry
4003          */
4004
4005         if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
4006                 status = pdb_set_unix_primary_group(mem_ctx, pwd);
4007                 if ( !NT_STATUS_IS_OK(status) ) {
4008                         return status;
4009                 }
4010         }
4011
4012         /* Don't worry about writing out the user account since the
4013            primary group SID is generated solely from the user's Unix
4014            primary group. */
4015
4016         /* write the change out */
4017         if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4018                 TALLOC_FREE(pwd);
4019                 return status;
4020         }
4021
4022         TALLOC_FREE(pwd);
4023
4024         return NT_STATUS_OK;
4025 }
4026
4027 /*******************************************************************
4028  set_user_info_23
4029  ********************************************************************/
4030
4031 static NTSTATUS set_user_info_23(TALLOC_CTX *mem_ctx,
4032                                  struct samr_UserInfo23 *id23,
4033                                  struct samu *pwd)
4034 {
4035         char *plaintext_buf = NULL;
4036         uint32 len = 0;
4037         uint16 acct_ctrl;
4038         NTSTATUS status;
4039
4040         if (id23 == NULL) {
4041                 DEBUG(5, ("set_user_info_23: NULL id23\n"));
4042                 return NT_STATUS_INVALID_PARAMETER;
4043         }
4044
4045         DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
4046                   pdb_get_username(pwd)));
4047
4048         acct_ctrl = pdb_get_acct_ctrl(pwd);
4049
4050         if (!decode_pw_buffer(mem_ctx,
4051                                 id23->password.data,
4052                                 &plaintext_buf,
4053                                 &len,
4054                                 STR_UNICODE)) {
4055                 TALLOC_FREE(pwd);
4056                 return NT_STATUS_INVALID_PARAMETER;
4057         }
4058
4059         if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
4060                 TALLOC_FREE(pwd);
4061                 return NT_STATUS_ACCESS_DENIED;
4062         }
4063
4064         copy_id23_to_sam_passwd(pwd, id23);
4065
4066         /* if it's a trust account, don't update /etc/passwd */
4067         if (    ( (acct_ctrl &  ACB_DOMTRUST) == ACB_DOMTRUST ) ||
4068                 ( (acct_ctrl &  ACB_WSTRUST) ==  ACB_WSTRUST) ||
4069                 ( (acct_ctrl &  ACB_SVRTRUST) ==  ACB_SVRTRUST) ) {
4070                 DEBUG(5, ("Changing trust account.  Not updating /etc/passwd\n"));
4071         } else  {
4072                 /* update the UNIX password */
4073                 if (lp_unix_password_sync() ) {
4074                         struct passwd *passwd;
4075                         if (pdb_get_username(pwd) == NULL) {
4076                                 DEBUG(1, ("chgpasswd: User without name???\n"));
4077                                 TALLOC_FREE(pwd);
4078                                 return NT_STATUS_ACCESS_DENIED;
4079                         }
4080
4081                         passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
4082                         if (passwd == NULL) {
4083                                 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
4084                         }
4085
4086                         if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
4087                                 TALLOC_FREE(pwd);
4088                                 return NT_STATUS_ACCESS_DENIED;
4089                         }
4090                         TALLOC_FREE(passwd);
4091                 }
4092         }
4093
4094         memset(plaintext_buf, '\0', strlen(plaintext_buf));
4095
4096         if (IS_SAM_CHANGED(pwd, PDB_GROUPSID) &&
4097             (!NT_STATUS_IS_OK(status =  pdb_set_unix_primary_group(mem_ctx,
4098                                                                    pwd)))) {
4099                 TALLOC_FREE(pwd);
4100                 return status;
4101         }
4102
4103         if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4104                 TALLOC_FREE(pwd);
4105                 return status;
4106         }
4107
4108         TALLOC_FREE(pwd);
4109
4110         return NT_STATUS_OK;
4111 }
4112
4113 /*******************************************************************
4114  set_user_info_pw
4115  ********************************************************************/
4116
4117 static bool set_user_info_pw(uint8 *pass, struct samu *pwd,
4118                              int level)
4119 {
4120         uint32 len = 0;
4121         char *plaintext_buf = NULL;
4122         uint32 acct_ctrl;
4123         time_t last_set_time;
4124         enum pdb_value_state last_set_state;
4125
4126         DEBUG(5, ("Attempting administrator password change for user %s\n",
4127                   pdb_get_username(pwd)));
4128
4129         acct_ctrl = pdb_get_acct_ctrl(pwd);
4130         /* we need to know if it's expired, because this is an admin change, not a
4131            user change, so it's still expired when we're done */
4132         last_set_state = pdb_get_init_flags(pwd, PDB_PASSLASTSET);
4133         last_set_time = pdb_get_pass_last_set_time(pwd);
4134
4135         if (!decode_pw_buffer(talloc_tos(),
4136                                 pass,
4137                                 &plaintext_buf,
4138                                 &len,
4139                                 STR_UNICODE)) {
4140                 TALLOC_FREE(pwd);
4141                 return False;
4142         }
4143
4144         if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
4145                 TALLOC_FREE(pwd);
4146                 return False;
4147         }
4148
4149         /* if it's a trust account, don't update /etc/passwd */
4150         if ( ( (acct_ctrl &  ACB_DOMTRUST) == ACB_DOMTRUST ) ||
4151                 ( (acct_ctrl &  ACB_WSTRUST) ==  ACB_WSTRUST) ||
4152                 ( (acct_ctrl &  ACB_SVRTRUST) ==  ACB_SVRTRUST) ) {
4153                 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
4154         } else {
4155                 /* update the UNIX password */
4156                 if (lp_unix_password_sync()) {
4157                         struct passwd *passwd;
4158
4159                         if (pdb_get_username(pwd) == NULL) {
4160                                 DEBUG(1, ("chgpasswd: User without name???\n"));
4161                                 TALLOC_FREE(pwd);
4162                                 return False;
4163                         }
4164
4165                         passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
4166                         if (passwd == NULL) {
4167                                 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
4168                         }
4169
4170                         if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
4171                                 TALLOC_FREE(pwd);
4172                                 return False;
4173                         }
4174                         TALLOC_FREE(passwd);
4175                 }
4176         }
4177
4178         memset(plaintext_buf, '\0', strlen(plaintext_buf));
4179
4180         /*
4181          * A level 25 change does reset the pwdlastset field, a level 24
4182          * change does not. I know this is probably not the full story, but
4183          * it is needed to make XP join LDAP correctly, without it the later
4184          * auth2 check can fail with PWD_MUST_CHANGE.
4185          */
4186         if (level != 25) {
4187                 /*
4188                  * restore last set time as this is an admin change, not a
4189                  * user pw change
4190                  */
4191                 pdb_set_pass_last_set_time (pwd, last_set_time,
4192                                             last_set_state);
4193         }
4194
4195         DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
4196
4197         /* update the SAMBA password */
4198         if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
4199                 TALLOC_FREE(pwd);
4200                 return False;
4201         }
4202
4203         TALLOC_FREE(pwd);
4204
4205         return True;
4206 }
4207
4208 /*******************************************************************
4209  set_user_info_25
4210  ********************************************************************/
4211
4212 static NTSTATUS set_user_info_25(TALLOC_CTX *mem_ctx,
4213                                  struct samr_UserInfo25 *id25,
4214                                  struct samu *pwd)
4215 {
4216         NTSTATUS status;
4217
4218         if (id25 == NULL) {
4219                 DEBUG(5, ("set_user_info_25: NULL id25\n"));
4220                 return NT_STATUS_INVALID_PARAMETER;
4221         }
4222
4223         copy_id25_to_sam_passwd(pwd, id25);
4224
4225         /* write the change out */
4226         if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4227                 TALLOC_FREE(pwd);
4228                 return status;
4229         }
4230
4231         /*
4232          * We need to "pdb_update_sam_account" before the unix primary group
4233          * is set, because the idealx scripts would also change the
4234          * sambaPrimaryGroupSid using the ldap replace method. pdb_ldap uses
4235          * the delete explicit / add explicit, which would then fail to find
4236          * the previous primaryGroupSid value.
4237          */
4238
4239         if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
4240                 status = pdb_set_unix_primary_group(mem_ctx, pwd);
4241                 if ( !NT_STATUS_IS_OK(status) ) {
4242                         return status;
4243                 }
4244         }
4245
4246         /* WARNING: No TALLOC_FREE(pwd), we are about to set the password
4247          * hereafter! */
4248
4249         return NT_STATUS_OK;
4250 }
4251
4252 /*******************************************************************
4253  samr_SetUserInfo
4254  ********************************************************************/
4255
4256 NTSTATUS _samr_SetUserInfo(pipes_struct *p,
4257                            struct samr_SetUserInfo *r)
4258 {
4259         NTSTATUS status;
4260         struct samu *pwd = NULL;
4261         DOM_SID sid;
4262         POLICY_HND *pol = r->in.user_handle;
4263         union samr_UserInfo *info = r->in.info;
4264         uint16_t switch_value = r->in.level;
4265         uint32_t acc_granted;
4266         uint32_t acc_required;
4267         bool ret;
4268         bool has_enough_rights = False;
4269         uint32_t acb_info;
4270         DISP_INFO *disp_info = NULL;
4271
4272         DEBUG(5,("_samr_SetUserInfo: %d\n", __LINE__));
4273
4274         /* find the policy handle.  open a policy on it. */
4275         if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted, &disp_info)) {
4276                 return NT_STATUS_INVALID_HANDLE;
4277         }
4278
4279         /* This is tricky.  A WinXP domain join sets
4280           (SAMR_USER_ACCESS_SET_PASSWORD|SAMR_USER_ACCESS_SET_ATTRIBUTES|SAMR_USER_ACCESS_GET_ATTRIBUTES)
4281           The MMC lusrmgr plugin includes these perms and more in the SamrOpenUser().  But the
4282           standard Win32 API calls just ask for SAMR_USER_ACCESS_SET_PASSWORD in the SamrOpenUser().
4283           This should be enough for levels 18, 24, 25,& 26.  Info level 23 can set more so
4284           we'll use the set from the WinXP join as the basis. */
4285
4286         switch (switch_value) {
4287         case 18:
4288         case 24:
4289         case 25:
4290         case 26:
4291                 acc_required = SAMR_USER_ACCESS_SET_PASSWORD;
4292                 break;
4293         default:
4294                 acc_required = SAMR_USER_ACCESS_SET_PASSWORD |
4295                                SAMR_USER_ACCESS_SET_ATTRIBUTES |
4296                                SAMR_USER_ACCESS_GET_ATTRIBUTES;
4297                 break;
4298         }
4299
4300         status = access_check_samr_function(acc_granted,
4301                                             acc_required,
4302                                             "_samr_SetUserInfo");
4303         if (!NT_STATUS_IS_OK(status)) {
4304                 return status;
4305         }
4306
4307         DEBUG(5, ("_samr_SetUserInfo: sid:%s, level:%d\n",
4308                   sid_string_dbg(&sid), switch_value));
4309
4310         if (info == NULL) {
4311                 DEBUG(5, ("_samr_SetUserInfo: NULL info level\n"));
4312                 return NT_STATUS_INVALID_INFO_CLASS;
4313         }
4314
4315         if (!(pwd = samu_new(NULL))) {
4316                 return NT_STATUS_NO_MEMORY;
4317         }
4318
4319         become_root();
4320         ret = pdb_getsampwsid(pwd, &sid);
4321         unbecome_root();
4322
4323         if (!ret) {
4324                 TALLOC_FREE(pwd);
4325                 return NT_STATUS_NO_SUCH_USER;
4326         }
4327
4328         /* deal with machine password changes differently from userinfo changes */
4329         /* check to see if we have the sufficient rights */
4330
4331         acb_info = pdb_get_acct_ctrl(pwd);
4332         if (acb_info & ACB_WSTRUST)
4333                 has_enough_rights = user_has_privileges(p->server_info->ptok,
4334                                                         &se_machine_account);
4335         else if (acb_info & ACB_NORMAL)
4336                 has_enough_rights = user_has_privileges(p->server_info->ptok,
4337                                                         &se_add_users);
4338         else if (acb_info & (ACB_SVRTRUST|ACB_DOMTRUST)) {
4339                 if (lp_enable_privileges()) {
4340                         has_enough_rights = nt_token_check_domain_rid(p->server_info->ptok,
4341                                                                       DOMAIN_GROUP_RID_ADMINS);
4342                 }
4343         }
4344
4345         DEBUG(5, ("_samr_SetUserInfo: %s does%s possess sufficient rights\n",
4346                   uidtoname(p->server_info->utok.uid),
4347                   has_enough_rights ? "" : " not"));
4348
4349         /* ================ BEGIN SeMachineAccountPrivilege BLOCK ================ */
4350
4351         if (has_enough_rights) {
4352                 become_root();
4353         }
4354
4355         /* ok!  user info levels (lots: see MSDEV help), off we go... */
4356
4357         switch (switch_value) {
4358
4359                 case 7:
4360                         status = set_user_info_7(p->mem_ctx,
4361                                                  &info->info7, pwd);
4362                         break;
4363
4364                 case 16:
4365                         if (!set_user_info_16(&info->info16, pwd)) {
4366                                 status = NT_STATUS_ACCESS_DENIED;
4367                         }
4368                         break;
4369
4370                 case 18:
4371                         /* Used by AS/U JRA. */
4372                         if (!set_user_info_18(&info->info18, pwd)) {
4373                                 status = NT_STATUS_ACCESS_DENIED;
4374                         }
4375                         break;
4376
4377                 case 20:
4378                         if (!set_user_info_20(&info->info20, pwd)) {
4379                                 status = NT_STATUS_ACCESS_DENIED;
4380                         }
4381                         break;
4382
4383                 case 21:
4384                         status = set_user_info_21(p->mem_ctx,
4385                                                   &info->info21, pwd);
4386                         break;
4387
4388                 case 23:
4389                         if (!p->server_info->user_session_key.length) {
4390                                 status = NT_STATUS_NO_USER_SESSION_KEY;
4391                         }
4392                         SamOEMhashBlob(info->info23.password.data, 516,
4393                                        &p->server_info->user_session_key);
4394
4395                         dump_data(100, info->info23.password.data, 516);
4396
4397                         status = set_user_info_23(p->mem_ctx,
4398                                                   &info->info23, pwd);
4399                         break;
4400
4401                 case 24:
4402                         if (!p->server_info->user_session_key.length) {
4403                                 status = NT_STATUS_NO_USER_SESSION_KEY;
4404                         }
4405                         SamOEMhashBlob(info->info24.password.data,
4406                                        516,
4407                                        &p->server_info->user_session_key);
4408
4409                         dump_data(100, info->info24.password.data, 516);
4410
4411                         if (!set_user_info_pw(info->info24.password.data, pwd,
4412                                               switch_value)) {
4413                                 status = NT_STATUS_ACCESS_DENIED;
4414                         }
4415                         break;
4416
4417                 case 25:
4418                         if (!p->server_info->user_session_key.length) {
4419                                 status = NT_STATUS_NO_USER_SESSION_KEY;
4420                         }
4421                         encode_or_decode_arc4_passwd_buffer(
4422                                 info->info25.password.data,
4423                                 &p->server_info->user_session_key);
4424
4425                         dump_data(100, info->info25.password.data, 532);
4426
4427                         status = set_user_info_25(p->mem_ctx,
4428                                                   &info->info25, pwd);
4429                         if (!NT_STATUS_IS_OK(status)) {
4430                                 goto done;
4431                         }
4432                         if (!set_user_info_pw(info->info25.password.data, pwd,
4433                                               switch_value)) {
4434                                 status = NT_STATUS_ACCESS_DENIED;
4435                         }
4436                         break;
4437
4438                 case 26:
4439                         if (!p->server_info->user_session_key.length) {
4440                                 status = NT_STATUS_NO_USER_SESSION_KEY;
4441                         }
4442                         encode_or_decode_arc4_passwd_buffer(
4443                                 info->info26.password.data,
4444                                 &p->server_info->user_session_key);
4445
4446                         dump_data(100, info->info26.password.data, 516);
4447
4448                         if (!set_user_info_pw(info->info26.password.data, pwd,
4449                                               switch_value)) {
4450                                 status = NT_STATUS_ACCESS_DENIED;
4451                         }
4452                         break;
4453
4454                 default:
4455                         status = NT_STATUS_INVALID_INFO_CLASS;
4456         }
4457
4458  done:
4459
4460         if (has_enough_rights) {
4461                 unbecome_root();
4462         }
4463
4464         /* ================ END SeMachineAccountPrivilege BLOCK ================ */
4465
4466         if (NT_STATUS_IS_OK(status)) {
4467                 force_flush_samr_cache(disp_info);
4468         }
4469
4470         return status;
4471 }
4472
4473 /*******************************************************************
4474  _samr_SetUserInfo2
4475  ********************************************************************/
4476
4477 NTSTATUS _samr_SetUserInfo2(pipes_struct *p,
4478                             struct samr_SetUserInfo2 *r)
4479 {
4480         struct samr_SetUserInfo q;
4481
4482         q.in.user_handle        = r->in.user_handle;
4483         q.in.level              = r->in.level;
4484         q.in.info               = r->in.info;
4485
4486         return _samr_SetUserInfo(p, &q);
4487 }
4488
4489 /*********************************************************************
4490  _samr_GetAliasMembership
4491 *********************************************************************/
4492
4493 NTSTATUS _samr_GetAliasMembership(pipes_struct *p,
4494                                   struct samr_GetAliasMembership *r)
4495 {
4496         size_t num_alias_rids;
4497         uint32 *alias_rids;
4498         struct samr_info *info = NULL;
4499         size_t i;
4500
4501         NTSTATUS ntstatus1;
4502         NTSTATUS ntstatus2;
4503
4504         DOM_SID *members;
4505
4506         DEBUG(5,("_samr_GetAliasMembership: %d\n", __LINE__));
4507
4508         /* find the policy handle.  open a policy on it. */
4509         if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
4510                 return NT_STATUS_INVALID_HANDLE;
4511
4512         ntstatus1 = access_check_samr_function(info->acc_granted,
4513                                                SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS,
4514                                                "_samr_GetAliasMembership");
4515         ntstatus2 = access_check_samr_function(info->acc_granted,
4516                                                SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
4517                                                "_samr_GetAliasMembership");
4518
4519         if (!NT_STATUS_IS_OK(ntstatus1) || !NT_STATUS_IS_OK(ntstatus2)) {
4520                 if (!(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus2)) &&
4521                     !(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus1))) {
4522                         return (NT_STATUS_IS_OK(ntstatus1)) ? ntstatus2 : ntstatus1;
4523                 }
4524         }
4525
4526         if (!sid_check_is_domain(&info->sid) &&
4527             !sid_check_is_builtin(&info->sid))
4528                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
4529
4530         if (r->in.sids->num_sids) {
4531                 members = TALLOC_ARRAY(p->mem_ctx, DOM_SID, r->in.sids->num_sids);
4532
4533                 if (members == NULL)
4534                         return NT_STATUS_NO_MEMORY;
4535         } else {
4536                 members = NULL;
4537         }
4538
4539         for (i=0; i<r->in.sids->num_sids; i++)
4540                 sid_copy(&members[i], r->in.sids->sids[i].sid);
4541
4542         alias_rids = NULL;
4543         num_alias_rids = 0;
4544
4545         become_root();
4546         ntstatus1 = pdb_enum_alias_memberships(p->mem_ctx, &info->sid, members,
4547                                                r->in.sids->num_sids,
4548                                                &alias_rids, &num_alias_rids);
4549         unbecome_root();
4550
4551         if (!NT_STATUS_IS_OK(ntstatus1)) {
4552                 return ntstatus1;
4553         }
4554
4555         r->out.rids->count = num_alias_rids;
4556         r->out.rids->ids = alias_rids;
4557
4558         return NT_STATUS_OK;
4559 }
4560
4561 /*********************************************************************
4562  _samr_GetMembersInAlias
4563 *********************************************************************/
4564
4565 NTSTATUS _samr_GetMembersInAlias(pipes_struct *p,
4566                                  struct samr_GetMembersInAlias *r)
4567 {
4568         NTSTATUS status;
4569         size_t i;
4570         size_t num_sids = 0;
4571         struct lsa_SidPtr *sids = NULL;
4572         DOM_SID *pdb_sids = NULL;
4573
4574         DOM_SID alias_sid;
4575
4576         uint32 acc_granted;
4577
4578         /* find the policy handle.  open a policy on it. */
4579         if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, NULL))
4580                 return NT_STATUS_INVALID_HANDLE;
4581
4582         status = access_check_samr_function(acc_granted,
4583                                             SAMR_ALIAS_ACCESS_GET_MEMBERS,
4584                                             "_samr_GetMembersInAlias");
4585         if (!NT_STATUS_IS_OK(status)) {
4586                 return status;
4587         }
4588
4589         DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
4590
4591         become_root();
4592         status = pdb_enum_aliasmem(&alias_sid, &pdb_sids, &num_sids);
4593         unbecome_root();
4594
4595         if (!NT_STATUS_IS_OK(status)) {
4596                 return status;
4597         }
4598
4599         if (num_sids) {
4600                 sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_SidPtr, num_sids);
4601                 if (sids == NULL) {
4602                         TALLOC_FREE(pdb_sids);
4603                         return NT_STATUS_NO_MEMORY;
4604                 }
4605         }
4606
4607         for (i = 0; i < num_sids; i++) {
4608                 sids[i].sid = sid_dup_talloc(p->mem_ctx, &pdb_sids[i]);
4609                 if (!sids[i].sid) {
4610                         TALLOC_FREE(pdb_sids);
4611                         return NT_STATUS_NO_MEMORY;
4612                 }
4613         }
4614
4615         r->out.sids->num_sids = num_sids;
4616         r->out.sids->sids = sids;
4617
4618         TALLOC_FREE(pdb_sids);
4619
4620         return NT_STATUS_OK;
4621 }
4622
4623 /*********************************************************************
4624  _samr_QueryGroupMember
4625 *********************************************************************/
4626
4627 NTSTATUS _samr_QueryGroupMember(pipes_struct *p,
4628                                 struct samr_QueryGroupMember *r)
4629 {
4630         DOM_SID group_sid;
4631         size_t i, num_members;
4632
4633         uint32 *rid=NULL;
4634         uint32 *attr=NULL;
4635
4636         uint32 acc_granted;
4637
4638         NTSTATUS status;
4639         struct samr_RidTypeArray *rids = NULL;
4640
4641         rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidTypeArray);
4642         if (!rids) {
4643                 return NT_STATUS_NO_MEMORY;
4644         }
4645
4646         /* find the policy handle.  open a policy on it. */
4647         if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, NULL))
4648                 return NT_STATUS_INVALID_HANDLE;
4649
4650         status = access_check_samr_function(acc_granted,
4651                                             SAMR_GROUP_ACCESS_GET_MEMBERS,
4652                                             "_samr_QueryGroupMember");
4653         if (!NT_STATUS_IS_OK(status)) {
4654                 return status;
4655         }
4656
4657         DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
4658
4659         if (!sid_check_is_in_our_domain(&group_sid)) {
4660                 DEBUG(3, ("sid %s is not in our domain\n",
4661                           sid_string_dbg(&group_sid)));
4662                 return NT_STATUS_NO_SUCH_GROUP;
4663         }
4664
4665         DEBUG(10, ("lookup on Domain SID\n"));
4666
4667         become_root();
4668         status = pdb_enum_group_members(p->mem_ctx, &group_sid,
4669                                         &rid, &num_members);
4670         unbecome_root();
4671
4672         if (!NT_STATUS_IS_OK(status))
4673                 return status;
4674
4675         if (num_members) {
4676                 attr=TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_members);
4677                 if (attr == NULL) {
4678                         return NT_STATUS_NO_MEMORY;
4679                 }
4680         } else {
4681                 attr = NULL;
4682         }
4683
4684         for (i=0; i<num_members; i++)
4685                 attr[i] = SID_NAME_USER;
4686
4687         rids->count = num_members;
4688         rids->types = attr;
4689         rids->rids = rid;
4690
4691         *r->out.rids = rids;
4692
4693         return NT_STATUS_OK;
4694 }
4695
4696 /*********************************************************************
4697  _samr_AddAliasMember
4698 *********************************************************************/
4699
4700 NTSTATUS _samr_AddAliasMember(pipes_struct *p,
4701                               struct samr_AddAliasMember *r)
4702 {
4703         DOM_SID alias_sid;
4704         uint32 acc_granted;
4705         SE_PRIV se_rights;
4706         bool can_add_accounts;
4707         NTSTATUS status;
4708         DISP_INFO *disp_info = NULL;
4709
4710         /* Find the policy handle. Open a policy on it. */
4711         if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
4712                 return NT_STATUS_INVALID_HANDLE;
4713
4714         status = access_check_samr_function(acc_granted,
4715                                             SAMR_ALIAS_ACCESS_ADD_MEMBER,
4716                                             "_samr_AddAliasMember");
4717         if (!NT_STATUS_IS_OK(status)) {
4718                 return status;
4719         }
4720
4721         DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
4722
4723         se_priv_copy( &se_rights, &se_add_users );
4724         can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
4725
4726         /******** BEGIN SeAddUsers BLOCK *********/
4727
4728         if ( can_add_accounts )
4729                 become_root();
4730
4731         status = pdb_add_aliasmem(&alias_sid, r->in.sid);
4732
4733         if ( can_add_accounts )
4734                 unbecome_root();
4735
4736         /******** END SeAddUsers BLOCK *********/
4737
4738         if (NT_STATUS_IS_OK(status)) {
4739                 force_flush_samr_cache(disp_info);
4740         }
4741
4742         return status;
4743 }
4744
4745 /*********************************************************************
4746  _samr_DeleteAliasMember
4747 *********************************************************************/
4748
4749 NTSTATUS _samr_DeleteAliasMember(pipes_struct *p,
4750                                  struct samr_DeleteAliasMember *r)
4751 {
4752         DOM_SID alias_sid;
4753         uint32 acc_granted;
4754         SE_PRIV se_rights;
4755         bool can_add_accounts;
4756         NTSTATUS status;
4757         DISP_INFO *disp_info = NULL;
4758
4759         /* Find the policy handle. Open a policy on it. */
4760         if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
4761                 return NT_STATUS_INVALID_HANDLE;
4762
4763         status = access_check_samr_function(acc_granted,
4764                                             SAMR_ALIAS_ACCESS_REMOVE_MEMBER,
4765                                             "_samr_DeleteAliasMember");
4766         if (!NT_STATUS_IS_OK(status)) {
4767                 return status;
4768         }
4769
4770         DEBUG(10, ("_samr_del_aliasmem:sid is %s\n",
4771                    sid_string_dbg(&alias_sid)));
4772
4773         se_priv_copy( &se_rights, &se_add_users );
4774         can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
4775
4776         /******** BEGIN SeAddUsers BLOCK *********/
4777
4778         if ( can_add_accounts )
4779                 become_root();
4780
4781         status = pdb_del_aliasmem(&alias_sid, r->in.sid);
4782
4783         if ( can_add_accounts )
4784                 unbecome_root();
4785
4786         /******** END SeAddUsers BLOCK *********/
4787
4788         if (NT_STATUS_IS_OK(status)) {
4789                 force_flush_samr_cache(disp_info);
4790         }
4791
4792         return status;
4793 }
4794
4795 /*********************************************************************
4796  _samr_AddGroupMember
4797 *********************************************************************/
4798
4799 NTSTATUS _samr_AddGroupMember(pipes_struct *p,
4800                               struct samr_AddGroupMember *r)
4801 {
4802         NTSTATUS status;
4803         DOM_SID group_sid;
4804         uint32 group_rid;
4805         uint32 acc_granted;
4806         SE_PRIV se_rights;
4807         bool can_add_accounts;
4808         DISP_INFO *disp_info = NULL;
4809
4810         /* Find the policy handle. Open a policy on it. */
4811         if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
4812                 return NT_STATUS_INVALID_HANDLE;
4813
4814         status = access_check_samr_function(acc_granted,
4815                                             SAMR_GROUP_ACCESS_ADD_MEMBER,
4816                                             "_samr_AddGroupMember");
4817         if (!NT_STATUS_IS_OK(status)) {
4818                 return status;
4819         }
4820
4821         DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
4822
4823         if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
4824                                 &group_rid)) {
4825                 return NT_STATUS_INVALID_HANDLE;
4826         }
4827
4828         se_priv_copy( &se_rights, &se_add_users );
4829         can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
4830
4831         /******** BEGIN SeAddUsers BLOCK *********/
4832
4833         if ( can_add_accounts )
4834                 become_root();
4835
4836         status = pdb_add_groupmem(p->mem_ctx, group_rid, r->in.rid);
4837
4838         if ( can_add_accounts )
4839                 unbecome_root();
4840
4841         /******** END SeAddUsers BLOCK *********/
4842
4843         force_flush_samr_cache(disp_info);
4844
4845         return status;
4846 }
4847
4848 /*********************************************************************
4849  _samr_DeleteGroupMember
4850 *********************************************************************/
4851
4852 NTSTATUS _samr_DeleteGroupMember(pipes_struct *p,
4853                                  struct samr_DeleteGroupMember *r)
4854
4855 {
4856         NTSTATUS status;
4857         DOM_SID group_sid;
4858         uint32 group_rid;
4859         uint32 acc_granted;
4860         SE_PRIV se_rights;
4861         bool can_add_accounts;
4862         DISP_INFO *disp_info = NULL;
4863
4864         /*
4865          * delete the group member named r->in.rid
4866          * who is a member of the sid associated with the handle
4867          * the rid is a user's rid as the group is a domain group.
4868          */
4869
4870         /* Find the policy handle. Open a policy on it. */
4871         if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
4872                 return NT_STATUS_INVALID_HANDLE;
4873
4874         status = access_check_samr_function(acc_granted,
4875                                             SAMR_GROUP_ACCESS_REMOVE_MEMBER,
4876                                             "_samr_DeleteGroupMember");
4877         if (!NT_STATUS_IS_OK(status)) {
4878                 return status;
4879         }
4880
4881         if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
4882                                 &group_rid)) {
4883                 return NT_STATUS_INVALID_HANDLE;
4884         }
4885
4886         se_priv_copy( &se_rights, &se_add_users );
4887         can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
4888
4889         /******** BEGIN SeAddUsers BLOCK *********/
4890
4891         if ( can_add_accounts )
4892                 become_root();
4893
4894         status = pdb_del_groupmem(p->mem_ctx, group_rid, r->in.rid);
4895
4896         if ( can_add_accounts )
4897                 unbecome_root();
4898
4899         /******** END SeAddUsers BLOCK *********/
4900
4901         force_flush_samr_cache(disp_info);
4902
4903         return status;
4904 }
4905
4906 /*********************************************************************
4907  _samr_DeleteUser
4908 *********************************************************************/
4909
4910 NTSTATUS _samr_DeleteUser(pipes_struct *p,
4911                           struct samr_DeleteUser *r)
4912 {
4913         NTSTATUS status;
4914         DOM_SID user_sid;
4915         struct samu *sam_pass=NULL;
4916         uint32 acc_granted;
4917         bool can_add_accounts;
4918         uint32 acb_info;
4919         DISP_INFO *disp_info = NULL;
4920         bool ret;
4921
4922         DEBUG(5, ("_samr_DeleteUser: %d\n", __LINE__));
4923
4924         /* Find the policy handle. Open a policy on it. */
4925         if (!get_lsa_policy_samr_sid(p, r->in.user_handle, &user_sid, &acc_granted, &disp_info))
4926                 return NT_STATUS_INVALID_HANDLE;
4927
4928         status = access_check_samr_function(acc_granted,
4929                                             STD_RIGHT_DELETE_ACCESS,
4930                                             "_samr_DeleteUser");
4931         if (!NT_STATUS_IS_OK(status)) {
4932                 return status;
4933         }
4934
4935         if (!sid_check_is_in_our_domain(&user_sid))
4936                 return NT_STATUS_CANNOT_DELETE;
4937
4938         /* check if the user exists before trying to delete */
4939         if ( !(sam_pass = samu_new( NULL )) ) {
4940                 return NT_STATUS_NO_MEMORY;
4941         }
4942
4943         become_root();
4944         ret = pdb_getsampwsid(sam_pass, &user_sid);
4945         unbecome_root();
4946
4947         if( !ret ) {
4948                 DEBUG(5,("_samr_DeleteUser: User %s doesn't exist.\n",
4949                         sid_string_dbg(&user_sid)));
4950                 TALLOC_FREE(sam_pass);
4951                 return NT_STATUS_NO_SUCH_USER;
4952         }
4953
4954         acb_info = pdb_get_acct_ctrl(sam_pass);
4955
4956         /* For machine accounts it's the SeMachineAccountPrivilege that counts. */
4957         if ( acb_info & ACB_WSTRUST ) {
4958                 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_machine_account );
4959         } else {
4960                 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_add_users );
4961         }
4962
4963         /******** BEGIN SeAddUsers BLOCK *********/
4964
4965         if ( can_add_accounts )
4966                 become_root();
4967
4968         status = pdb_delete_user(p->mem_ctx, sam_pass);
4969
4970         if ( can_add_accounts )
4971                 unbecome_root();
4972
4973         /******** END SeAddUsers BLOCK *********/
4974
4975         if ( !NT_STATUS_IS_OK(status) ) {
4976                 DEBUG(5,("_samr_DeleteUser: Failed to delete entry for "
4977                          "user %s: %s.\n", pdb_get_username(sam_pass),
4978                          nt_errstr(status)));
4979                 TALLOC_FREE(sam_pass);
4980                 return status;
4981         }
4982
4983
4984         TALLOC_FREE(sam_pass);
4985
4986         if (!close_policy_hnd(p, r->in.user_handle))
4987                 return NT_STATUS_OBJECT_NAME_INVALID;
4988
4989         ZERO_STRUCTP(r->out.user_handle);
4990
4991         force_flush_samr_cache(disp_info);
4992
4993         return NT_STATUS_OK;
4994 }
4995
4996 /*********************************************************************
4997  _samr_DeleteDomainGroup
4998 *********************************************************************/
4999
5000 NTSTATUS _samr_DeleteDomainGroup(pipes_struct *p,
5001                                  struct samr_DeleteDomainGroup *r)
5002 {
5003         NTSTATUS status;
5004         DOM_SID group_sid;
5005         uint32 group_rid;
5006         uint32 acc_granted;
5007         SE_PRIV se_rights;
5008         bool can_add_accounts;
5009         DISP_INFO *disp_info = NULL;
5010
5011         DEBUG(5, ("samr_DeleteDomainGroup: %d\n", __LINE__));
5012
5013         /* Find the policy handle. Open a policy on it. */
5014         if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
5015                 return NT_STATUS_INVALID_HANDLE;
5016
5017         status = access_check_samr_function(acc_granted,
5018                                             STD_RIGHT_DELETE_ACCESS,
5019                                             "_samr_DeleteDomainGroup");
5020         if (!NT_STATUS_IS_OK(status)) {
5021                 return status;
5022         }
5023
5024         DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
5025
5026         if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
5027                                 &group_rid)) {
5028                 return NT_STATUS_NO_SUCH_GROUP;
5029         }
5030
5031         se_priv_copy( &se_rights, &se_add_users );
5032         can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
5033
5034         /******** BEGIN SeAddUsers BLOCK *********/
5035
5036         if ( can_add_accounts )
5037                 become_root();
5038
5039         status = pdb_delete_dom_group(p->mem_ctx, group_rid);
5040
5041         if ( can_add_accounts )
5042                 unbecome_root();
5043
5044         /******** END SeAddUsers BLOCK *********/
5045
5046         if ( !NT_STATUS_IS_OK(status) ) {
5047                 DEBUG(5,("_samr_DeleteDomainGroup: Failed to delete mapping "
5048                          "entry for group %s: %s\n",
5049                          sid_string_dbg(&group_sid),
5050                          nt_errstr(status)));
5051                 return status;
5052         }
5053
5054         if (!close_policy_hnd(p, r->in.group_handle))
5055                 return NT_STATUS_OBJECT_NAME_INVALID;
5056
5057         force_flush_samr_cache(disp_info);
5058
5059         return NT_STATUS_OK;
5060 }
5061
5062 /*********************************************************************
5063  _samr_DeleteDomAlias
5064 *********************************************************************/
5065
5066 NTSTATUS _samr_DeleteDomAlias(pipes_struct *p,
5067                               struct samr_DeleteDomAlias *r)
5068 {
5069         DOM_SID alias_sid;
5070         uint32 acc_granted;
5071         SE_PRIV se_rights;
5072         bool can_add_accounts;
5073         NTSTATUS status;
5074         DISP_INFO *disp_info = NULL;
5075
5076         DEBUG(5, ("_samr_DeleteDomAlias: %d\n", __LINE__));
5077
5078         /* Find the policy handle. Open a policy on it. */
5079         if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
5080                 return NT_STATUS_INVALID_HANDLE;
5081
5082         /* copy the handle to the outgoing reply */
5083
5084         memcpy(r->out.alias_handle, r->in.alias_handle, sizeof(r->out.alias_handle));
5085
5086         status = access_check_samr_function(acc_granted,
5087                                             STD_RIGHT_DELETE_ACCESS,
5088                                             "_samr_DeleteDomAlias");
5089         if (!NT_STATUS_IS_OK(status)) {
5090                 return status;
5091         }
5092
5093         DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
5094
5095         /* Don't let Windows delete builtin groups */
5096
5097         if ( sid_check_is_in_builtin( &alias_sid ) ) {
5098                 return NT_STATUS_SPECIAL_ACCOUNT;
5099         }
5100
5101         if (!sid_check_is_in_our_domain(&alias_sid))
5102                 return NT_STATUS_NO_SUCH_ALIAS;
5103
5104         DEBUG(10, ("lookup on Local SID\n"));
5105
5106         se_priv_copy( &se_rights, &se_add_users );
5107         can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
5108
5109         /******** BEGIN SeAddUsers BLOCK *********/
5110
5111         if ( can_add_accounts )
5112                 become_root();
5113
5114         /* Have passdb delete the alias */
5115         status = pdb_delete_alias(&alias_sid);
5116
5117         if ( can_add_accounts )
5118                 unbecome_root();
5119
5120         /******** END SeAddUsers BLOCK *********/
5121
5122         if ( !NT_STATUS_IS_OK(status))
5123                 return status;
5124
5125         if (!close_policy_hnd(p, r->in.alias_handle))
5126                 return NT_STATUS_OBJECT_NAME_INVALID;
5127
5128         force_flush_samr_cache(disp_info);
5129
5130         return NT_STATUS_OK;
5131 }
5132
5133 /*********************************************************************
5134  _samr_CreateDomainGroup
5135 *********************************************************************/
5136
5137 NTSTATUS _samr_CreateDomainGroup(pipes_struct *p,
5138                                  struct samr_CreateDomainGroup *r)
5139
5140 {
5141         NTSTATUS status;
5142         DOM_SID dom_sid;
5143         DOM_SID info_sid;
5144         const char *name;
5145         struct samr_info *info;
5146         uint32 acc_granted;
5147         SE_PRIV se_rights;
5148         bool can_add_accounts;
5149         DISP_INFO *disp_info = NULL;
5150
5151         /* Find the policy handle. Open a policy on it. */
5152         if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &dom_sid, &acc_granted, &disp_info))
5153                 return NT_STATUS_INVALID_HANDLE;
5154
5155         status = access_check_samr_function(acc_granted,
5156                                             SAMR_DOMAIN_ACCESS_CREATE_GROUP,
5157                                             "_samr_CreateDomainGroup");
5158         if (!NT_STATUS_IS_OK(status)) {
5159                 return status;
5160         }
5161
5162         if (!sid_equal(&dom_sid, get_global_sam_sid()))
5163                 return NT_STATUS_ACCESS_DENIED;
5164
5165         name = r->in.name->string;
5166         if (name == NULL) {
5167                 return NT_STATUS_NO_MEMORY;
5168         }
5169
5170         status = can_create(p->mem_ctx, name);
5171         if (!NT_STATUS_IS_OK(status)) {
5172                 return status;
5173         }
5174
5175         se_priv_copy( &se_rights, &se_add_users );
5176         can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
5177
5178         /******** BEGIN SeAddUsers BLOCK *********/
5179
5180         if ( can_add_accounts )
5181                 become_root();
5182
5183         /* check that we successfully create the UNIX group */
5184
5185         status = pdb_create_dom_group(p->mem_ctx, name, r->out.rid);
5186
5187         if ( can_add_accounts )
5188                 unbecome_root();
5189
5190         /******** END SeAddUsers BLOCK *********/
5191
5192         /* check if we should bail out here */
5193
5194         if ( !NT_STATUS_IS_OK(status) )
5195                 return status;
5196
5197         sid_compose(&info_sid, get_global_sam_sid(), *r->out.rid);
5198
5199         if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
5200                 return NT_STATUS_NO_MEMORY;
5201
5202         /* they created it; let the user do what he wants with it */
5203
5204         info->acc_granted = GENERIC_RIGHTS_GROUP_ALL_ACCESS;
5205
5206         /* get a (unique) handle.  open a policy on it. */
5207         if (!create_policy_hnd(p, r->out.group_handle, free_samr_info, (void *)info))
5208                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5209
5210         force_flush_samr_cache(disp_info);
5211
5212         return NT_STATUS_OK;
5213 }
5214
5215 /*********************************************************************
5216  _samr_CreateDomAlias
5217 *********************************************************************/
5218
5219 NTSTATUS _samr_CreateDomAlias(pipes_struct *p,
5220                               struct samr_CreateDomAlias *r)
5221 {
5222         DOM_SID dom_sid;
5223         DOM_SID info_sid;
5224         const char *name = NULL;
5225         struct samr_info *info;
5226         uint32 acc_granted;
5227         gid_t gid;
5228         NTSTATUS result;
5229         SE_PRIV se_rights;
5230         bool can_add_accounts;
5231         DISP_INFO *disp_info = NULL;
5232
5233         /* Find the policy handle. Open a policy on it. */
5234         if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &dom_sid, &acc_granted, &disp_info))
5235                 return NT_STATUS_INVALID_HANDLE;
5236
5237         result = access_check_samr_function(acc_granted,
5238                                             SAMR_DOMAIN_ACCESS_CREATE_ALIAS,
5239                                             "_samr_CreateDomAlias");
5240         if (!NT_STATUS_IS_OK(result)) {
5241                 return result;
5242         }
5243
5244         if (!sid_equal(&dom_sid, get_global_sam_sid()))
5245                 return NT_STATUS_ACCESS_DENIED;
5246
5247         name = r->in.alias_name->string;
5248
5249         se_priv_copy( &se_rights, &se_add_users );
5250         can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
5251
5252         result = can_create(p->mem_ctx, name);
5253         if (!NT_STATUS_IS_OK(result)) {
5254                 return result;
5255         }
5256
5257         /******** BEGIN SeAddUsers BLOCK *********/
5258
5259         if ( can_add_accounts )
5260                 become_root();
5261
5262         /* Have passdb create the alias */
5263         result = pdb_create_alias(name, r->out.rid);
5264
5265         if ( can_add_accounts )
5266                 unbecome_root();
5267
5268         /******** END SeAddUsers BLOCK *********/
5269
5270         if (!NT_STATUS_IS_OK(result)) {
5271                 DEBUG(10, ("pdb_create_alias failed: %s\n",
5272                            nt_errstr(result)));
5273                 return result;
5274         }
5275
5276         sid_copy(&info_sid, get_global_sam_sid());
5277         sid_append_rid(&info_sid, *r->out.rid);
5278
5279         if (!sid_to_gid(&info_sid, &gid)) {
5280                 DEBUG(10, ("Could not find alias just created\n"));
5281                 return NT_STATUS_ACCESS_DENIED;
5282         }
5283
5284         /* check if the group has been successfully created */
5285         if ( getgrgid(gid) == NULL ) {
5286                 DEBUG(10, ("getgrgid(%d) of just created alias failed\n",
5287                            gid));
5288                 return NT_STATUS_ACCESS_DENIED;
5289         }
5290
5291         if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
5292                 return NT_STATUS_NO_MEMORY;
5293
5294         /* they created it; let the user do what he wants with it */
5295
5296         info->acc_granted = GENERIC_RIGHTS_ALIAS_ALL_ACCESS;
5297
5298         /* get a (unique) handle.  open a policy on it. */
5299         if (!create_policy_hnd(p, r->out.alias_handle, free_samr_info, (void *)info))
5300                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5301
5302         force_flush_samr_cache(disp_info);
5303
5304         return NT_STATUS_OK;
5305 }
5306
5307 /*********************************************************************
5308  _samr_QueryGroupInfo
5309 *********************************************************************/
5310
5311 NTSTATUS _samr_QueryGroupInfo(pipes_struct *p,
5312                               struct samr_QueryGroupInfo *r)
5313 {
5314         NTSTATUS status;
5315         DOM_SID group_sid;
5316         GROUP_MAP map;
5317         union samr_GroupInfo *info = NULL;
5318         uint32 acc_granted;
5319         bool ret;
5320         uint32_t attributes = SE_GROUP_MANDATORY |
5321                               SE_GROUP_ENABLED_BY_DEFAULT |
5322                               SE_GROUP_ENABLED;
5323         const char *group_name = NULL;
5324         const char *group_description = NULL;
5325
5326         if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, NULL))
5327                 return NT_STATUS_INVALID_HANDLE;
5328
5329         status = access_check_samr_function(acc_granted,
5330                                             SAMR_GROUP_ACCESS_LOOKUP_INFO,
5331                                             "_samr_QueryGroupInfo");
5332         if (!NT_STATUS_IS_OK(status)) {
5333                 return status;
5334         }
5335
5336         become_root();
5337         ret = get_domain_group_from_sid(group_sid, &map);
5338         unbecome_root();
5339         if (!ret)
5340                 return NT_STATUS_INVALID_HANDLE;
5341
5342         /* FIXME: map contains fstrings */
5343         group_name = talloc_strdup(r, map.nt_name);
5344         group_description = talloc_strdup(r, map.comment);
5345
5346         info = TALLOC_ZERO_P(p->mem_ctx, union samr_GroupInfo);
5347         if (!info) {
5348                 return NT_STATUS_NO_MEMORY;
5349         }
5350
5351         switch (r->in.level) {
5352                 case 1: {
5353                         uint32 *members;
5354                         size_t num_members;
5355
5356                         become_root();
5357                         status = pdb_enum_group_members(
5358                                 p->mem_ctx, &group_sid, &members, &num_members);
5359                         unbecome_root();
5360
5361                         if (!NT_STATUS_IS_OK(status)) {
5362                                 return status;
5363                         }
5364
5365                         init_samr_group_info1(&info->all,
5366                                               group_name,
5367                                               attributes,
5368                                               num_members,
5369                                               group_description);
5370                         break;
5371                 }
5372                 case 2:
5373                         init_samr_group_info2(&info->name,
5374                                               group_name);
5375                         break;
5376                 case 3:
5377                         init_samr_group_info3(&info->attributes,
5378                                               attributes);
5379                         break;
5380                 case 4:
5381                         init_samr_group_info4(&info->description,
5382                                               group_description);
5383                         break;
5384                 case 5: {
5385                         /*
5386                         uint32 *members;
5387                         size_t num_members;
5388                         */
5389
5390                         /*
5391                         become_root();
5392                         status = pdb_enum_group_members(
5393                                 p->mem_ctx, &group_sid, &members, &num_members);
5394                         unbecome_root();
5395
5396                         if (!NT_STATUS_IS_OK(status)) {
5397                                 return status;
5398                         }
5399                         */
5400                         init_samr_group_info5(&info->all2,
5401                                               group_name,
5402                                               attributes,
5403                                               0, /* num_members - in w2k3 this is always 0 */
5404                                               group_description);
5405
5406                         break;
5407                 }
5408                 default:
5409                         return NT_STATUS_INVALID_INFO_CLASS;
5410         }
5411
5412         *r->out.info = info;
5413
5414         return NT_STATUS_OK;
5415 }
5416
5417 /*********************************************************************
5418  _samr_SetGroupInfo
5419 *********************************************************************/
5420
5421 NTSTATUS _samr_SetGroupInfo(pipes_struct *p,
5422                             struct samr_SetGroupInfo *r)
5423 {
5424         DOM_SID group_sid;
5425         GROUP_MAP map;
5426         uint32 acc_granted;
5427         NTSTATUS status;
5428         bool ret;
5429         bool can_mod_accounts;
5430         DISP_INFO *disp_info = NULL;
5431
5432         if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
5433                 return NT_STATUS_INVALID_HANDLE;
5434
5435         status = access_check_samr_function(acc_granted,
5436                                             SAMR_GROUP_ACCESS_SET_INFO,
5437                                             "_samr_SetGroupInfo");
5438         if (!NT_STATUS_IS_OK(status)) {
5439                 return status;
5440         }
5441
5442         become_root();
5443         ret = get_domain_group_from_sid(group_sid, &map);
5444         unbecome_root();
5445         if (!ret)
5446                 return NT_STATUS_NO_SUCH_GROUP;
5447
5448         switch (r->in.level) {
5449                 case 1:
5450                         fstrcpy(map.comment, r->in.info->all.description.string);
5451                         break;
5452                 case 2:
5453                         /* group rename is not supported yet */
5454                         return NT_STATUS_NOT_SUPPORTED;
5455                 case 4:
5456                         fstrcpy(map.comment, r->in.info->description.string);
5457                         break;
5458                 default:
5459                         return NT_STATUS_INVALID_INFO_CLASS;
5460         }
5461
5462         can_mod_accounts = user_has_privileges( p->server_info->ptok, &se_add_users );
5463
5464         /******** BEGIN SeAddUsers BLOCK *********/
5465
5466         if ( can_mod_accounts )
5467                 become_root();
5468
5469         status = pdb_update_group_mapping_entry(&map);
5470
5471         if ( can_mod_accounts )
5472                 unbecome_root();
5473
5474         /******** End SeAddUsers BLOCK *********/
5475
5476         if (NT_STATUS_IS_OK(status)) {
5477                 force_flush_samr_cache(disp_info);
5478         }
5479
5480         return status;
5481 }
5482
5483 /*********************************************************************
5484  _samr_SetAliasInfo
5485 *********************************************************************/
5486
5487 NTSTATUS _samr_SetAliasInfo(pipes_struct *p,
5488                             struct samr_SetAliasInfo *r)
5489 {
5490         DOM_SID group_sid;
5491         struct acct_info info;
5492         uint32 acc_granted;
5493         bool can_mod_accounts;
5494         NTSTATUS status;
5495         DISP_INFO *disp_info = NULL;
5496
5497         if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &group_sid, &acc_granted, &disp_info))
5498                 return NT_STATUS_INVALID_HANDLE;
5499
5500         status = access_check_samr_function(acc_granted,
5501                                             SAMR_ALIAS_ACCESS_SET_INFO,
5502                                             "_samr_SetAliasInfo");
5503         if (!NT_STATUS_IS_OK(status)) {
5504                 return status;
5505         }
5506
5507         /* get the current group information */
5508
5509         become_root();
5510         status = pdb_get_aliasinfo( &group_sid, &info );
5511         unbecome_root();
5512
5513         if ( !NT_STATUS_IS_OK(status))
5514                 return status;
5515
5516         switch (r->in.level) {
5517                 case ALIASINFONAME:
5518                 {
5519                         fstring group_name;
5520
5521                         /* We currently do not support renaming groups in the
5522                            the BUILTIN domain.  Refer to util_builtin.c to understand
5523                            why.  The eventually needs to be fixed to be like Windows
5524                            where you can rename builtin groups, just not delete them */
5525
5526                         if ( sid_check_is_in_builtin( &group_sid ) ) {
5527                                 return NT_STATUS_SPECIAL_ACCOUNT;
5528                         }
5529
5530                         /* There has to be a valid name (and it has to be different) */
5531
5532                         if ( !r->in.info->name.string )
5533                                 return NT_STATUS_INVALID_PARAMETER;
5534
5535                         /* If the name is the same just reply "ok".  Yes this
5536                            doesn't allow you to change the case of a group name. */
5537
5538                         if ( strequal( r->in.info->name.string, info.acct_name ) )
5539                                 return NT_STATUS_OK;
5540
5541                         fstrcpy( info.acct_name, r->in.info->name.string);
5542
5543                         /* make sure the name doesn't already exist as a user
5544                            or local group */
5545
5546                         fstr_sprintf( group_name, "%s\\%s", global_myname(), info.acct_name );
5547                         status = can_create( p->mem_ctx, group_name );
5548                         if ( !NT_STATUS_IS_OK( status ) )
5549                                 return status;
5550                         break;
5551                 }
5552                 case ALIASINFODESCRIPTION:
5553                         if (r->in.info->description.string) {
5554                                 fstrcpy(info.acct_desc,
5555                                         r->in.info->description.string);
5556                         } else {
5557                                 fstrcpy( info.acct_desc, "" );
5558                         }
5559                         break;
5560                 default:
5561                         return NT_STATUS_INVALID_INFO_CLASS;
5562         }
5563
5564         can_mod_accounts = user_has_privileges( p->server_info->ptok, &se_add_users );
5565
5566         /******** BEGIN SeAddUsers BLOCK *********/
5567
5568         if ( can_mod_accounts )
5569                 become_root();
5570
5571         status = pdb_set_aliasinfo( &group_sid, &info );
5572
5573         if ( can_mod_accounts )
5574                 unbecome_root();
5575
5576         /******** End SeAddUsers BLOCK *********/
5577
5578         if (NT_STATUS_IS_OK(status))
5579                 force_flush_samr_cache(disp_info);
5580
5581         return status;
5582 }
5583
5584 /****************************************************************
5585  _samr_GetDomPwInfo
5586 ****************************************************************/
5587
5588 NTSTATUS _samr_GetDomPwInfo(pipes_struct *p,
5589                             struct samr_GetDomPwInfo *r)
5590 {
5591         uint32_t min_password_length = 0;
5592         uint32_t password_properties = 0;
5593
5594         /* Perform access check.  Since this rpc does not require a
5595            policy handle it will not be caught by the access checks on
5596            SAMR_CONNECT or SAMR_CONNECT_ANON. */
5597
5598         if (!pipe_access_check(p)) {
5599                 DEBUG(3, ("access denied to _samr_GetDomPwInfo\n"));
5600                 return NT_STATUS_ACCESS_DENIED;
5601         }
5602
5603         become_root();
5604         pdb_get_account_policy(AP_MIN_PASSWORD_LEN,
5605                                &min_password_length);
5606         pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
5607                                &password_properties);
5608         unbecome_root();
5609
5610         if (lp_check_password_script() && *lp_check_password_script()) {
5611                 password_properties |= DOMAIN_PASSWORD_COMPLEX;
5612         }
5613
5614         r->out.info->min_password_length = min_password_length;
5615         r->out.info->password_properties = password_properties;
5616
5617         return NT_STATUS_OK;
5618 }
5619
5620 /*********************************************************************
5621  _samr_OpenGroup
5622 *********************************************************************/
5623
5624 NTSTATUS _samr_OpenGroup(pipes_struct *p,
5625                          struct samr_OpenGroup *r)
5626
5627 {
5628         DOM_SID sid;
5629         DOM_SID info_sid;
5630         GROUP_MAP map;
5631         struct samr_info *info;
5632         SEC_DESC         *psd = NULL;
5633         uint32            acc_granted;
5634         uint32            des_access = r->in.access_mask;
5635         size_t            sd_size;
5636         NTSTATUS          status;
5637         fstring sid_string;
5638         bool ret;
5639         SE_PRIV se_rights;
5640
5641         if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &sid, &acc_granted, NULL))
5642                 return NT_STATUS_INVALID_HANDLE;
5643
5644         status = access_check_samr_function(acc_granted,
5645                                             SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
5646                                             "_samr_OpenGroup");
5647
5648         if ( !NT_STATUS_IS_OK(status) )
5649                 return status;
5650
5651         /*check if access can be granted as requested by client. */
5652         map_max_allowed_access(p->server_info->ptok, &des_access);
5653
5654         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &grp_generic_mapping, NULL, 0);
5655         se_map_generic(&des_access,&grp_generic_mapping);
5656
5657         se_priv_copy( &se_rights, &se_add_users );
5658
5659         status = access_check_samr_object(psd, p->server_info->ptok,
5660                 &se_rights, GENERIC_RIGHTS_GROUP_WRITE, des_access,
5661                 &acc_granted, "_samr_OpenGroup");
5662
5663         if ( !NT_STATUS_IS_OK(status) )
5664                 return status;
5665
5666         /* this should not be hard-coded like this */
5667
5668         if (!sid_equal(&sid, get_global_sam_sid()))
5669                 return NT_STATUS_ACCESS_DENIED;
5670
5671         sid_copy(&info_sid, get_global_sam_sid());
5672         sid_append_rid(&info_sid, r->in.rid);
5673         sid_to_fstring(sid_string, &info_sid);
5674
5675         if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
5676                 return NT_STATUS_NO_MEMORY;
5677
5678         info->acc_granted = acc_granted;
5679
5680         DEBUG(10, ("_samr_OpenGroup:Opening SID: %s\n", sid_string));
5681
5682         /* check if that group really exists */
5683         become_root();
5684         ret = get_domain_group_from_sid(info->sid, &map);
5685         unbecome_root();
5686         if (!ret)
5687                 return NT_STATUS_NO_SUCH_GROUP;
5688
5689         /* get a (unique) handle.  open a policy on it. */
5690         if (!create_policy_hnd(p, r->out.group_handle, free_samr_info, (void *)info))
5691                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5692
5693         return NT_STATUS_OK;
5694 }
5695
5696 /*********************************************************************
5697  _samr_RemoveMemberFromForeignDomain
5698 *********************************************************************/
5699
5700 NTSTATUS _samr_RemoveMemberFromForeignDomain(pipes_struct *p,
5701                                              struct samr_RemoveMemberFromForeignDomain *r)
5702 {
5703         DOM_SID                 delete_sid, domain_sid;
5704         uint32                  acc_granted;
5705         NTSTATUS                result;
5706         DISP_INFO *disp_info = NULL;
5707
5708         sid_copy( &delete_sid, r->in.sid );
5709
5710         DEBUG(5,("_samr_RemoveMemberFromForeignDomain: removing SID [%s]\n",
5711                 sid_string_dbg(&delete_sid)));
5712
5713         /* Find the policy handle. Open a policy on it. */
5714
5715         if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &domain_sid,
5716                                      &acc_granted, &disp_info))
5717                 return NT_STATUS_INVALID_HANDLE;
5718
5719         result = access_check_samr_function(acc_granted,
5720                                             STD_RIGHT_DELETE_ACCESS,
5721                                             "_samr_RemoveMemberFromForeignDomain");
5722
5723         if (!NT_STATUS_IS_OK(result))
5724                 return result;
5725
5726         DEBUG(8, ("_samr_RemoveMemberFromForeignDomain: sid is %s\n",
5727                   sid_string_dbg(&domain_sid)));
5728
5729         /* we can only delete a user from a group since we don't have
5730            nested groups anyways.  So in the latter case, just say OK */
5731
5732         /* TODO: The above comment nowadays is bogus. Since we have nested
5733          * groups now, and aliases members are never reported out of the unix
5734          * group membership, the "just say OK" makes this call a no-op. For
5735          * us. This needs fixing however. */
5736
5737         /* I've only ever seen this in the wild when deleting a user from
5738          * usrmgr.exe. domain_sid is the builtin domain, and the sid to delete
5739          * is the user about to be deleted. I very much suspect this is the
5740          * only application of this call. To verify this, let people report
5741          * other cases. */
5742
5743         if (!sid_check_is_builtin(&domain_sid)) {
5744                 DEBUG(1,("_samr_RemoveMemberFromForeignDomain: domain_sid = %s, "
5745                          "global_sam_sid() = %s\n",
5746                          sid_string_dbg(&domain_sid),
5747                          sid_string_dbg(get_global_sam_sid())));
5748                 DEBUGADD(1,("please report to samba-technical@samba.org!\n"));
5749                 return NT_STATUS_OK;
5750         }
5751
5752         force_flush_samr_cache(disp_info);
5753
5754         result = NT_STATUS_OK;
5755
5756         return result;
5757 }
5758
5759 /*******************************************************************
5760  _samr_QueryDomainInfo2
5761  ********************************************************************/
5762
5763 NTSTATUS _samr_QueryDomainInfo2(pipes_struct *p,
5764                                 struct samr_QueryDomainInfo2 *r)
5765 {
5766         struct samr_QueryDomainInfo q;
5767
5768         q.in.domain_handle      = r->in.domain_handle;
5769         q.in.level              = r->in.level;
5770
5771         q.out.info              = r->out.info;
5772
5773         return _samr_QueryDomainInfo(p, &q);
5774 }
5775
5776 /*******************************************************************
5777  _samr_SetDomainInfo
5778  ********************************************************************/
5779
5780 NTSTATUS _samr_SetDomainInfo(pipes_struct *p,
5781                              struct samr_SetDomainInfo *r)
5782 {
5783         struct samr_info *info = NULL;
5784         time_t u_expire, u_min_age;
5785         time_t u_logout;
5786         time_t u_lock_duration, u_reset_time;
5787         NTSTATUS result;
5788
5789         DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
5790
5791         /* find the policy handle.  open a policy on it. */
5792         if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
5793                 return NT_STATUS_INVALID_HANDLE;
5794
5795         /* We do have different access bits for info
5796          * levels here, but we're really just looking for
5797          * GENERIC_RIGHTS_DOMAIN_WRITE access. Unfortunately
5798          * this maps to different specific bits. So
5799          * assume if we have SAMR_DOMAIN_ACCESS_SET_INFO_1
5800          * set we are ok. */
5801
5802         result = access_check_samr_function(info->acc_granted,
5803                                             SAMR_DOMAIN_ACCESS_SET_INFO_1,
5804                                             "_samr_SetDomainInfo");
5805
5806         if (!NT_STATUS_IS_OK(result))
5807                 return result;
5808
5809         DEBUG(5,("_samr_SetDomainInfo: level: %d\n", r->in.level));
5810
5811         switch (r->in.level) {
5812                 case 0x01:
5813                         u_expire=nt_time_to_unix_abs((NTTIME *)&r->in.info->info1.max_password_age);
5814                         u_min_age=nt_time_to_unix_abs((NTTIME *)&r->in.info->info1.min_password_age);
5815                         pdb_set_account_policy(AP_MIN_PASSWORD_LEN, (uint32)r->in.info->info1.min_password_length);
5816                         pdb_set_account_policy(AP_PASSWORD_HISTORY, (uint32)r->in.info->info1.password_history_length);
5817                         pdb_set_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, (uint32)r->in.info->info1.password_properties);
5818                         pdb_set_account_policy(AP_MAX_PASSWORD_AGE, (int)u_expire);
5819                         pdb_set_account_policy(AP_MIN_PASSWORD_AGE, (int)u_min_age);
5820                         break;
5821                 case 0x02:
5822                         break;
5823                 case 0x03:
5824                         u_logout=nt_time_to_unix_abs((NTTIME *)&r->in.info->info3.force_logoff_time);
5825                         pdb_set_account_policy(AP_TIME_TO_LOGOUT, (int)u_logout);
5826                         break;
5827                 case 0x05:
5828                         break;
5829                 case 0x06:
5830                         break;
5831                 case 0x07:
5832                         break;
5833                 case 0x0c:
5834                         u_lock_duration=nt_time_to_unix_abs((NTTIME *)&r->in.info->info12.lockout_duration);
5835                         if (u_lock_duration != -1)
5836                                 u_lock_duration /= 60;
5837
5838                         u_reset_time=nt_time_to_unix_abs((NTTIME *)&r->in.info->info12.lockout_window)/60;
5839
5840                         pdb_set_account_policy(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
5841                         pdb_set_account_policy(AP_RESET_COUNT_TIME, (int)u_reset_time);
5842                         pdb_set_account_policy(AP_BAD_ATTEMPT_LOCKOUT, (uint32)r->in.info->info12.lockout_threshold);
5843                         break;
5844                 default:
5845                         return NT_STATUS_INVALID_INFO_CLASS;
5846         }
5847
5848         DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
5849
5850         return NT_STATUS_OK;
5851 }
5852
5853 /****************************************************************
5854  _samr_GetDisplayEnumerationIndex
5855 ****************************************************************/
5856
5857 NTSTATUS _samr_GetDisplayEnumerationIndex(pipes_struct *p,
5858                                           struct samr_GetDisplayEnumerationIndex *r)
5859 {
5860         struct samr_info *info = NULL;
5861         uint32_t max_entries = (uint32_t) -1;
5862         uint32_t enum_context = 0;
5863         int i;
5864         uint32_t num_account = 0;
5865         struct samr_displayentry *entries = NULL;
5866         NTSTATUS status;
5867
5868         DEBUG(5,("_samr_GetDisplayEnumerationIndex: %d\n", __LINE__));
5869
5870         /* find the policy handle.  open a policy on it. */
5871         if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info)) {
5872                 return NT_STATUS_INVALID_HANDLE;
5873         }
5874
5875         status = access_check_samr_function(info->acc_granted,
5876                                             SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
5877                                             "_samr_GetDisplayEnumerationIndex");
5878         if (!NT_STATUS_IS_OK(status)) {
5879                 return status;
5880         }
5881
5882         if ((r->in.level < 1) || (r->in.level > 3)) {
5883                 DEBUG(0,("_samr_GetDisplayEnumerationIndex: "
5884                         "Unknown info level (%u)\n",
5885                         r->in.level));
5886                 return NT_STATUS_INVALID_INFO_CLASS;
5887         }
5888
5889         become_root();
5890
5891         /* The following done as ROOT. Don't return without unbecome_root(). */
5892
5893         switch (r->in.level) {
5894         case 1:
5895                 if (info->disp_info->users == NULL) {
5896                         info->disp_info->users = pdb_search_users(ACB_NORMAL);
5897                         if (info->disp_info->users == NULL) {
5898                                 unbecome_root();
5899                                 return NT_STATUS_ACCESS_DENIED;
5900                         }
5901                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5902                                 "starting user enumeration at index %u\n",
5903                                 (unsigned int)enum_context));
5904                 } else {
5905                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5906                                 "using cached user enumeration at index %u\n",
5907                                 (unsigned int)enum_context));
5908                 }
5909                 num_account = pdb_search_entries(info->disp_info->users,
5910                                                  enum_context, max_entries,
5911                                                  &entries);
5912                 break;
5913         case 2:
5914                 if (info->disp_info->machines == NULL) {
5915                         info->disp_info->machines =
5916                                 pdb_search_users(ACB_WSTRUST|ACB_SVRTRUST);
5917                         if (info->disp_info->machines == NULL) {
5918                                 unbecome_root();
5919                                 return NT_STATUS_ACCESS_DENIED;
5920                         }
5921                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5922                                 "starting machine enumeration at index %u\n",
5923                                 (unsigned int)enum_context));
5924                 } else {
5925                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5926                                 "using cached machine enumeration at index %u\n",
5927                                 (unsigned int)enum_context));
5928                 }
5929                 num_account = pdb_search_entries(info->disp_info->machines,
5930                                                  enum_context, max_entries,
5931                                                  &entries);
5932                 break;
5933         case 3:
5934                 if (info->disp_info->groups == NULL) {
5935                         info->disp_info->groups = pdb_search_groups();
5936                         if (info->disp_info->groups == NULL) {
5937                                 unbecome_root();
5938                                 return NT_STATUS_ACCESS_DENIED;
5939                         }
5940                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5941                                 "starting group enumeration at index %u\n",
5942                                 (unsigned int)enum_context));
5943                 } else {
5944                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5945                                 "using cached group enumeration at index %u\n",
5946                                 (unsigned int)enum_context));
5947                 }
5948                 num_account = pdb_search_entries(info->disp_info->groups,
5949                                                  enum_context, max_entries,
5950                                                  &entries);
5951                 break;
5952         default:
5953                 unbecome_root();
5954                 smb_panic("info class changed");
5955                 break;
5956         }
5957
5958         unbecome_root();
5959
5960         /* Ensure we cache this enumeration. */
5961         set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
5962
5963         DEBUG(10,("_samr_GetDisplayEnumerationIndex: looking for :%s\n",
5964                 r->in.name->string));
5965
5966         for (i=0; i<num_account; i++) {
5967                 if (strequal(entries[i].account_name, r->in.name->string)) {
5968                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5969                                 "found %s at idx %d\n",
5970                                 r->in.name->string, i));
5971                         *r->out.idx = i;
5972                         return NT_STATUS_OK;
5973                 }
5974         }
5975
5976         /* assuming account_name lives at the very end */
5977         *r->out.idx = num_account;
5978
5979         return NT_STATUS_NO_MORE_ENTRIES;
5980 }
5981
5982 /****************************************************************
5983  _samr_GetDisplayEnumerationIndex2
5984 ****************************************************************/
5985
5986 NTSTATUS _samr_GetDisplayEnumerationIndex2(pipes_struct *p,
5987                                            struct samr_GetDisplayEnumerationIndex2 *r)
5988 {
5989         struct samr_GetDisplayEnumerationIndex q;
5990
5991         q.in.domain_handle      = r->in.domain_handle;
5992         q.in.level              = r->in.level;
5993         q.in.name               = r->in.name;
5994
5995         q.out.idx               = r->out.idx;
5996
5997         return _samr_GetDisplayEnumerationIndex(p, &q);
5998 }
5999
6000 /****************************************************************
6001 ****************************************************************/
6002
6003 NTSTATUS _samr_Shutdown(pipes_struct *p,
6004                         struct samr_Shutdown *r)
6005 {
6006         p->rng_fault_state = true;
6007         return NT_STATUS_NOT_IMPLEMENTED;
6008 }
6009
6010 /****************************************************************
6011 ****************************************************************/
6012
6013 NTSTATUS _samr_SetMemberAttributesOfGroup(pipes_struct *p,
6014                                           struct samr_SetMemberAttributesOfGroup *r)
6015 {
6016         p->rng_fault_state = true;
6017         return NT_STATUS_NOT_IMPLEMENTED;
6018 }
6019
6020 /****************************************************************
6021 ****************************************************************/
6022
6023 NTSTATUS _samr_ChangePasswordUser(pipes_struct *p,
6024                                   struct samr_ChangePasswordUser *r)
6025 {
6026         p->rng_fault_state = true;
6027         return NT_STATUS_NOT_IMPLEMENTED;
6028 }
6029
6030 /****************************************************************
6031 ****************************************************************/
6032
6033 NTSTATUS _samr_TestPrivateFunctionsDomain(pipes_struct *p,
6034                                           struct samr_TestPrivateFunctionsDomain *r)
6035 {
6036         p->rng_fault_state = true;
6037         return NT_STATUS_NOT_IMPLEMENTED;
6038 }
6039
6040 /****************************************************************
6041 ****************************************************************/
6042
6043 NTSTATUS _samr_TestPrivateFunctionsUser(pipes_struct *p,
6044                                         struct samr_TestPrivateFunctionsUser *r)
6045 {
6046         p->rng_fault_state = true;
6047         return NT_STATUS_NOT_IMPLEMENTED;
6048 }
6049
6050 /****************************************************************
6051 ****************************************************************/
6052
6053 NTSTATUS _samr_AddMultipleMembersToAlias(pipes_struct *p,
6054                                          struct samr_AddMultipleMembersToAlias *r)
6055 {
6056         p->rng_fault_state = true;
6057         return NT_STATUS_NOT_IMPLEMENTED;
6058 }
6059
6060 /****************************************************************
6061 ****************************************************************/
6062
6063 NTSTATUS _samr_RemoveMultipleMembersFromAlias(pipes_struct *p,
6064                                               struct samr_RemoveMultipleMembersFromAlias *r)
6065 {
6066         p->rng_fault_state = true;
6067         return NT_STATUS_NOT_IMPLEMENTED;
6068 }
6069
6070 /****************************************************************
6071 ****************************************************************/
6072
6073 NTSTATUS _samr_OemChangePasswordUser2(pipes_struct *p,
6074                                       struct samr_OemChangePasswordUser2 *r)
6075 {
6076         p->rng_fault_state = true;
6077         return NT_STATUS_NOT_IMPLEMENTED;
6078 }
6079
6080 /****************************************************************
6081 ****************************************************************/
6082
6083 NTSTATUS _samr_SetBootKeyInformation(pipes_struct *p,
6084                                      struct samr_SetBootKeyInformation *r)
6085 {
6086         p->rng_fault_state = true;
6087         return NT_STATUS_NOT_IMPLEMENTED;
6088 }
6089
6090 /****************************************************************
6091 ****************************************************************/
6092
6093 NTSTATUS _samr_GetBootKeyInformation(pipes_struct *p,
6094                                      struct samr_GetBootKeyInformation *r)
6095 {
6096         p->rng_fault_state = true;
6097         return NT_STATUS_NOT_IMPLEMENTED;
6098 }
6099
6100 /****************************************************************
6101 ****************************************************************/
6102
6103 NTSTATUS _samr_Connect3(pipes_struct *p,
6104                         struct samr_Connect3 *r)
6105 {
6106         p->rng_fault_state = true;
6107         return NT_STATUS_NOT_IMPLEMENTED;
6108 }
6109
6110 /****************************************************************
6111 ****************************************************************/
6112
6113 NTSTATUS _samr_RidToSid(pipes_struct *p,
6114                         struct samr_RidToSid *r)
6115 {
6116         p->rng_fault_state = true;
6117         return NT_STATUS_NOT_IMPLEMENTED;
6118 }
6119
6120 /****************************************************************
6121 ****************************************************************/
6122
6123 NTSTATUS _samr_SetDsrmPassword(pipes_struct *p,
6124                                struct samr_SetDsrmPassword *r)
6125 {
6126         p->rng_fault_state = true;
6127         return NT_STATUS_NOT_IMPLEMENTED;
6128 }
6129
6130 /****************************************************************
6131 ****************************************************************/
6132
6133 NTSTATUS _samr_ValidatePassword(pipes_struct *p,
6134                                 struct samr_ValidatePassword *r)
6135 {
6136         p->rng_fault_state = true;
6137         return NT_STATUS_NOT_IMPLEMENTED;
6138 }