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