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