a946d2ed6d185aa402516fdfe30ddc66a3f9c386
[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         copy_id18_to_sam_passwd(pwd, id18);
3747
3748         return pdb_update_sam_account(pwd);
3749 }
3750
3751 /*******************************************************************
3752  set_user_info_20
3753  ********************************************************************/
3754
3755 static bool set_user_info_20(struct samr_UserInfo20 *id20,
3756                              struct samu *pwd)
3757 {
3758         if (id20 == NULL) {
3759                 DEBUG(5, ("set_user_info_20: NULL id20\n"));
3760                 return False;
3761         }
3762
3763         copy_id20_to_sam_passwd(pwd, id20);
3764
3765         /* write the change out */
3766         if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3767                 return False;
3768         }
3769
3770         return True;
3771 }
3772
3773 /*******************************************************************
3774  set_user_info_21
3775  ********************************************************************/
3776
3777 static NTSTATUS set_user_info_21(TALLOC_CTX *mem_ctx,
3778                                  struct samr_UserInfo21 *id21,
3779                                  struct samu *pwd)
3780 {
3781         NTSTATUS status;
3782
3783         if (id21 == NULL) {
3784                 DEBUG(5, ("set_user_info_21: NULL id21\n"));
3785                 return NT_STATUS_INVALID_PARAMETER;
3786         }
3787
3788         if (id21->fields_present == 0) {
3789                 return NT_STATUS_INVALID_PARAMETER;
3790         }
3791
3792         if (id21->fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
3793                 return NT_STATUS_ACCESS_DENIED;
3794         }
3795
3796         /* we need to separately check for an account rename first */
3797
3798         if (id21->account_name.string &&
3799             (!strequal(id21->account_name.string, pdb_get_username(pwd))))
3800         {
3801
3802                 /* check to see if the new username already exists.  Note: we can't
3803                    reliably lock all backends, so there is potentially the
3804                    possibility that a user can be created in between this check and
3805                    the rename.  The rename should fail, but may not get the
3806                    exact same failure status code.  I think this is small enough
3807                    of a window for this type of operation and the results are
3808                    simply that the rename fails with a slightly different status
3809                    code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
3810
3811                 status = can_create(mem_ctx, id21->account_name.string);
3812                 if (!NT_STATUS_IS_OK(status)) {
3813                         return status;
3814                 }
3815
3816                 status = pdb_rename_sam_account(pwd, id21->account_name.string);
3817
3818                 if (!NT_STATUS_IS_OK(status)) {
3819                         DEBUG(0,("set_user_info_21: failed to rename account: %s\n",
3820                                 nt_errstr(status)));
3821                         return status;
3822                 }
3823
3824                 /* set the new username so that later
3825                    functions can work on the new account */
3826                 pdb_set_username(pwd, id21->account_name.string, PDB_SET);
3827         }
3828
3829         copy_id21_to_sam_passwd("INFO_21", pwd, id21);
3830
3831         /*
3832          * The funny part about the previous two calls is
3833          * that pwd still has the password hashes from the
3834          * passdb entry.  These have not been updated from
3835          * id21.  I don't know if they need to be set.    --jerry
3836          */
3837
3838         if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
3839                 status = pdb_set_unix_primary_group(mem_ctx, pwd);
3840                 if ( !NT_STATUS_IS_OK(status) ) {
3841                         return status;
3842                 }
3843         }
3844
3845         /* Don't worry about writing out the user account since the
3846            primary group SID is generated solely from the user's Unix
3847            primary group. */
3848
3849         /* write the change out */
3850         if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
3851                 return status;
3852         }
3853
3854         return NT_STATUS_OK;
3855 }
3856
3857 /*******************************************************************
3858  set_user_info_23
3859  ********************************************************************/
3860
3861 static NTSTATUS set_user_info_23(TALLOC_CTX *mem_ctx,
3862                                  struct samr_UserInfo23 *id23,
3863                                  struct samu *pwd)
3864 {
3865         char *plaintext_buf = NULL;
3866         uint32 len = 0;
3867         uint32_t acct_ctrl;
3868         NTSTATUS status;
3869
3870         if (id23 == NULL) {
3871                 DEBUG(5, ("set_user_info_23: NULL id23\n"));
3872                 return NT_STATUS_INVALID_PARAMETER;
3873         }
3874
3875         if (id23->info.fields_present == 0) {
3876                 return NT_STATUS_INVALID_PARAMETER;
3877         }
3878
3879         if (id23->info.fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
3880                 return NT_STATUS_ACCESS_DENIED;
3881         }
3882
3883         if ((id23->info.fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3884             (id23->info.fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT)) {
3885
3886                 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
3887                           pdb_get_username(pwd)));
3888
3889                 if (!decode_pw_buffer(mem_ctx,
3890                                       id23->password.data,
3891                                       &plaintext_buf,
3892                                       &len,
3893                                       STR_UNICODE)) {
3894                         return NT_STATUS_WRONG_PASSWORD;
3895                 }
3896
3897                 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
3898                         return NT_STATUS_ACCESS_DENIED;
3899                 }
3900         }
3901
3902         copy_id23_to_sam_passwd(pwd, id23);
3903
3904         acct_ctrl = pdb_get_acct_ctrl(pwd);
3905
3906         /* if it's a trust account, don't update /etc/passwd */
3907         if (    ( (acct_ctrl &  ACB_DOMTRUST) == ACB_DOMTRUST ) ||
3908                 ( (acct_ctrl &  ACB_WSTRUST) ==  ACB_WSTRUST) ||
3909                 ( (acct_ctrl &  ACB_SVRTRUST) ==  ACB_SVRTRUST) ) {
3910                 DEBUG(5, ("Changing trust account.  Not updating /etc/passwd\n"));
3911         } else if (plaintext_buf) {
3912                 /* update the UNIX password */
3913                 if (lp_unix_password_sync() ) {
3914                         struct passwd *passwd;
3915                         if (pdb_get_username(pwd) == NULL) {
3916                                 DEBUG(1, ("chgpasswd: User without name???\n"));
3917                                 return NT_STATUS_ACCESS_DENIED;
3918                         }
3919
3920                         passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
3921                         if (passwd == NULL) {
3922                                 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
3923                         }
3924
3925                         if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
3926                                 return NT_STATUS_ACCESS_DENIED;
3927                         }
3928                         TALLOC_FREE(passwd);
3929                 }
3930         }
3931
3932         if (plaintext_buf) {
3933                 memset(plaintext_buf, '\0', strlen(plaintext_buf));
3934         }
3935
3936         if (IS_SAM_CHANGED(pwd, PDB_GROUPSID) &&
3937             (!NT_STATUS_IS_OK(status =  pdb_set_unix_primary_group(mem_ctx,
3938                                                                    pwd)))) {
3939                 return status;
3940         }
3941
3942         if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
3943                 return status;
3944         }
3945
3946         return NT_STATUS_OK;
3947 }
3948
3949 /*******************************************************************
3950  set_user_info_pw
3951  ********************************************************************/
3952
3953 static bool set_user_info_pw(uint8 *pass, struct samu *pwd)
3954 {
3955         uint32 len = 0;
3956         char *plaintext_buf = NULL;
3957         uint32 acct_ctrl;
3958
3959         DEBUG(5, ("Attempting administrator password change for user %s\n",
3960                   pdb_get_username(pwd)));
3961
3962         acct_ctrl = pdb_get_acct_ctrl(pwd);
3963
3964         if (!decode_pw_buffer(talloc_tos(),
3965                                 pass,
3966                                 &plaintext_buf,
3967                                 &len,
3968                                 STR_UNICODE)) {
3969                 return False;
3970         }
3971
3972         if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
3973                 return False;
3974         }
3975
3976         /* if it's a trust account, don't update /etc/passwd */
3977         if ( ( (acct_ctrl &  ACB_DOMTRUST) == ACB_DOMTRUST ) ||
3978                 ( (acct_ctrl &  ACB_WSTRUST) ==  ACB_WSTRUST) ||
3979                 ( (acct_ctrl &  ACB_SVRTRUST) ==  ACB_SVRTRUST) ) {
3980                 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
3981         } else {
3982                 /* update the UNIX password */
3983                 if (lp_unix_password_sync()) {
3984                         struct passwd *passwd;
3985
3986                         if (pdb_get_username(pwd) == NULL) {
3987                                 DEBUG(1, ("chgpasswd: User without name???\n"));
3988                                 return False;
3989                         }
3990
3991                         passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
3992                         if (passwd == NULL) {
3993                                 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
3994                         }
3995
3996                         if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
3997                                 return False;
3998                         }
3999                         TALLOC_FREE(passwd);
4000                 }
4001         }
4002
4003         memset(plaintext_buf, '\0', strlen(plaintext_buf));
4004
4005         DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
4006
4007         return True;
4008 }
4009
4010 /*******************************************************************
4011  set_user_info_24
4012  ********************************************************************/
4013
4014 static NTSTATUS set_user_info_24(TALLOC_CTX *mem_ctx,
4015                                  struct samr_UserInfo24 *id24,
4016                                  struct samu *pwd)
4017 {
4018         NTSTATUS status;
4019
4020         if (id24 == NULL) {
4021                 DEBUG(5, ("set_user_info_24: NULL id24\n"));
4022                 return NT_STATUS_INVALID_PARAMETER;
4023         }
4024
4025         if (!set_user_info_pw(id24->password.data, pwd)) {
4026                 return NT_STATUS_WRONG_PASSWORD;
4027         }
4028
4029         copy_id24_to_sam_passwd(pwd, id24);
4030
4031         status = pdb_update_sam_account(pwd);
4032         if (!NT_STATUS_IS_OK(status)) {
4033                 return status;
4034         }
4035
4036         return NT_STATUS_OK;
4037 }
4038
4039 /*******************************************************************
4040  set_user_info_25
4041  ********************************************************************/
4042
4043 static NTSTATUS set_user_info_25(TALLOC_CTX *mem_ctx,
4044                                  struct samr_UserInfo25 *id25,
4045                                  struct samu *pwd)
4046 {
4047         NTSTATUS status;
4048
4049         if (id25 == NULL) {
4050                 DEBUG(5, ("set_user_info_25: NULL id25\n"));
4051                 return NT_STATUS_INVALID_PARAMETER;
4052         }
4053
4054         if (id25->info.fields_present == 0) {
4055                 return NT_STATUS_INVALID_PARAMETER;
4056         }
4057
4058         if (id25->info.fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
4059                 return NT_STATUS_ACCESS_DENIED;
4060         }
4061
4062         if ((id25->info.fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
4063             (id25->info.fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT)) {
4064
4065                 if (!set_user_info_pw(id25->password.data, pwd)) {
4066                         return NT_STATUS_WRONG_PASSWORD;
4067                 }
4068         }
4069
4070         copy_id25_to_sam_passwd(pwd, id25);
4071
4072         /* write the change out */
4073         if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4074                 return status;
4075         }
4076
4077         /*
4078          * We need to "pdb_update_sam_account" before the unix primary group
4079          * is set, because the idealx scripts would also change the
4080          * sambaPrimaryGroupSid using the ldap replace method. pdb_ldap uses
4081          * the delete explicit / add explicit, which would then fail to find
4082          * the previous primaryGroupSid value.
4083          */
4084
4085         if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
4086                 status = pdb_set_unix_primary_group(mem_ctx, pwd);
4087                 if ( !NT_STATUS_IS_OK(status) ) {
4088                         return status;
4089                 }
4090         }
4091
4092         return NT_STATUS_OK;
4093 }
4094
4095 /*******************************************************************
4096  set_user_info_26
4097  ********************************************************************/
4098
4099 static NTSTATUS set_user_info_26(TALLOC_CTX *mem_ctx,
4100                                  struct samr_UserInfo26 *id26,
4101                                  struct samu *pwd)
4102 {
4103         NTSTATUS status;
4104
4105         if (id26 == NULL) {
4106                 DEBUG(5, ("set_user_info_26: NULL id26\n"));
4107                 return NT_STATUS_INVALID_PARAMETER;
4108         }
4109
4110         if (!set_user_info_pw(id26->password.data, pwd)) {
4111                 return NT_STATUS_WRONG_PASSWORD;
4112         }
4113
4114         copy_id26_to_sam_passwd(pwd, id26);
4115
4116         status = pdb_update_sam_account(pwd);
4117         if (!NT_STATUS_IS_OK(status)) {
4118                 return status;
4119         }
4120
4121         return NT_STATUS_OK;
4122 }
4123
4124
4125 /*******************************************************************
4126  samr_SetUserInfo
4127  ********************************************************************/
4128
4129 NTSTATUS _samr_SetUserInfo(pipes_struct *p,
4130                            struct samr_SetUserInfo *r)
4131 {
4132         NTSTATUS status;
4133         struct samu *pwd = NULL;
4134         DOM_SID sid;
4135         POLICY_HND *pol = r->in.user_handle;
4136         union samr_UserInfo *info = r->in.info;
4137         uint16_t switch_value = r->in.level;
4138         uint32_t acc_granted;
4139         uint32_t acc_required;
4140         bool ret;
4141         bool has_enough_rights = False;
4142         uint32_t acb_info;
4143         DISP_INFO *disp_info = NULL;
4144
4145         DEBUG(5,("_samr_SetUserInfo: %d\n", __LINE__));
4146
4147         /* find the policy handle.  open a policy on it. */
4148         if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted, &disp_info)) {
4149                 return NT_STATUS_INVALID_HANDLE;
4150         }
4151
4152         /* This is tricky.  A WinXP domain join sets
4153           (SAMR_USER_ACCESS_SET_PASSWORD|SAMR_USER_ACCESS_SET_ATTRIBUTES|SAMR_USER_ACCESS_GET_ATTRIBUTES)
4154           The MMC lusrmgr plugin includes these perms and more in the SamrOpenUser().  But the
4155           standard Win32 API calls just ask for SAMR_USER_ACCESS_SET_PASSWORD in the SamrOpenUser().
4156           This should be enough for levels 18, 24, 25,& 26.  Info level 23 can set more so
4157           we'll use the set from the WinXP join as the basis. */
4158
4159         switch (switch_value) {
4160         case 18:
4161         case 24:
4162         case 25:
4163         case 26:
4164                 acc_required = SAMR_USER_ACCESS_SET_PASSWORD;
4165                 break;
4166         default:
4167                 acc_required = SAMR_USER_ACCESS_SET_PASSWORD |
4168                                SAMR_USER_ACCESS_SET_ATTRIBUTES |
4169                                SAMR_USER_ACCESS_GET_ATTRIBUTES;
4170                 break;
4171         }
4172
4173         status = access_check_samr_function(acc_granted,
4174                                             acc_required,
4175                                             "_samr_SetUserInfo");
4176         if (!NT_STATUS_IS_OK(status)) {
4177                 return status;
4178         }
4179
4180         DEBUG(5, ("_samr_SetUserInfo: sid:%s, level:%d\n",
4181                   sid_string_dbg(&sid), switch_value));
4182
4183         if (info == NULL) {
4184                 DEBUG(5, ("_samr_SetUserInfo: NULL info level\n"));
4185                 return NT_STATUS_INVALID_INFO_CLASS;
4186         }
4187
4188         if (!(pwd = samu_new(NULL))) {
4189                 return NT_STATUS_NO_MEMORY;
4190         }
4191
4192         become_root();
4193         ret = pdb_getsampwsid(pwd, &sid);
4194         unbecome_root();
4195
4196         if (!ret) {
4197                 TALLOC_FREE(pwd);
4198                 return NT_STATUS_NO_SUCH_USER;
4199         }
4200
4201         /* deal with machine password changes differently from userinfo changes */
4202         /* check to see if we have the sufficient rights */
4203
4204         acb_info = pdb_get_acct_ctrl(pwd);
4205         if (acb_info & ACB_WSTRUST)
4206                 has_enough_rights = user_has_privileges(p->pipe_user.nt_user_token,
4207                                                         &se_machine_account);
4208         else if (acb_info & ACB_NORMAL)
4209                 has_enough_rights = user_has_privileges(p->pipe_user.nt_user_token,
4210                                                         &se_add_users);
4211         else if (acb_info & (ACB_SVRTRUST|ACB_DOMTRUST)) {
4212                 if (lp_enable_privileges()) {
4213                         has_enough_rights = nt_token_check_domain_rid(p->pipe_user.nt_user_token,
4214                                                                       DOMAIN_GROUP_RID_ADMINS);
4215                 }
4216         }
4217
4218         DEBUG(5, ("_samr_SetUserInfo: %s does%s possess sufficient rights\n",
4219                   uidtoname(p->pipe_user.ut.uid),
4220                   has_enough_rights ? "" : " not"));
4221
4222         /* ================ BEGIN SeMachineAccountPrivilege BLOCK ================ */
4223
4224         if (has_enough_rights) {
4225                 become_root();
4226         }
4227
4228         /* ok!  user info levels (lots: see MSDEV help), off we go... */
4229
4230         switch (switch_value) {
4231
4232                 case 7:
4233                         status = set_user_info_7(p->mem_ctx,
4234                                                  &info->info7, pwd);
4235                         break;
4236
4237                 case 16:
4238                         if (!set_user_info_16(&info->info16, pwd)) {
4239                                 status = NT_STATUS_ACCESS_DENIED;
4240                         }
4241                         break;
4242
4243                 case 18:
4244                         /* Used by AS/U JRA. */
4245                         status = set_user_info_18(&info->info18,
4246                                                   p->mem_ctx,
4247                                                   &p->server_info->user_session_key,
4248                                                   pwd);
4249                         break;
4250
4251                 case 20:
4252                         if (!set_user_info_20(&info->info20, pwd)) {
4253                                 status = NT_STATUS_ACCESS_DENIED;
4254                         }
4255                         break;
4256
4257                 case 21:
4258                         status = set_user_info_21(p->mem_ctx,
4259                                                   &info->info21, pwd);
4260                         break;
4261
4262                 case 23:
4263                         if (!p->server_info->user_session_key.length) {
4264                                 status = NT_STATUS_NO_USER_SESSION_KEY;
4265                         }
4266                         SamOEMhashBlob(info->info23.password.data, 516,
4267                                        &p->server_info->user_session_key);
4268
4269                         dump_data(100, info->info23.password.data, 516);
4270
4271                         status = set_user_info_23(p->mem_ctx,
4272                                                   &info->info23, pwd);
4273                         break;
4274
4275                 case 24:
4276                         if (!p->server_info->user_session_key.length) {
4277                                 status = NT_STATUS_NO_USER_SESSION_KEY;
4278                         }
4279                         SamOEMhashBlob(info->info24.password.data,
4280                                        516,
4281                                        &p->server_info->user_session_key);
4282
4283                         dump_data(100, info->info24.password.data, 516);
4284
4285                         status = set_user_info_24(p->mem_ctx,
4286                                                   &info->info24, pwd);
4287                         break;
4288
4289                 case 25:
4290                         if (!p->server_info->user_session_key.length) {
4291                                 status = NT_STATUS_NO_USER_SESSION_KEY;
4292                         }
4293                         encode_or_decode_arc4_passwd_buffer(
4294                                 info->info25.password.data,
4295                                 &p->server_info->user_session_key);
4296
4297                         dump_data(100, info->info25.password.data, 532);
4298
4299                         status = set_user_info_25(p->mem_ctx,
4300                                                   &info->info25, pwd);
4301                         break;
4302
4303                 case 26:
4304                         if (!p->server_info->user_session_key.length) {
4305                                 status = NT_STATUS_NO_USER_SESSION_KEY;
4306                         }
4307                         encode_or_decode_arc4_passwd_buffer(
4308                                 info->info26.password.data,
4309                                 &p->server_info->user_session_key);
4310
4311                         dump_data(100, info->info26.password.data, 516);
4312
4313                         status = set_user_info_26(p->mem_ctx,
4314                                                   &info->info26, pwd);
4315                         break;
4316
4317                 default:
4318                         status = NT_STATUS_INVALID_INFO_CLASS;
4319         }
4320
4321         TALLOC_FREE(pwd);
4322
4323         if (has_enough_rights) {
4324                 unbecome_root();
4325         }
4326
4327         /* ================ END SeMachineAccountPrivilege BLOCK ================ */
4328
4329         if (NT_STATUS_IS_OK(status)) {
4330                 force_flush_samr_cache(disp_info);
4331         }
4332
4333         return status;
4334 }
4335
4336 /*******************************************************************
4337  _samr_SetUserInfo2
4338  ********************************************************************/
4339
4340 NTSTATUS _samr_SetUserInfo2(pipes_struct *p,
4341                             struct samr_SetUserInfo2 *r)
4342 {
4343         struct samr_SetUserInfo q;
4344
4345         q.in.user_handle        = r->in.user_handle;
4346         q.in.level              = r->in.level;
4347         q.in.info               = r->in.info;
4348
4349         return _samr_SetUserInfo(p, &q);
4350 }
4351
4352 /*********************************************************************
4353  _samr_GetAliasMembership
4354 *********************************************************************/
4355
4356 NTSTATUS _samr_GetAliasMembership(pipes_struct *p,
4357                                   struct samr_GetAliasMembership *r)
4358 {
4359         size_t num_alias_rids;
4360         uint32 *alias_rids;
4361         struct samr_info *info = NULL;
4362         size_t i;
4363
4364         NTSTATUS ntstatus1;
4365         NTSTATUS ntstatus2;
4366
4367         DOM_SID *members;
4368
4369         DEBUG(5,("_samr_GetAliasMembership: %d\n", __LINE__));
4370
4371         /* find the policy handle.  open a policy on it. */
4372         if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
4373                 return NT_STATUS_INVALID_HANDLE;
4374
4375         ntstatus1 = access_check_samr_function(info->acc_granted,
4376                                                SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS,
4377                                                "_samr_GetAliasMembership");
4378         ntstatus2 = access_check_samr_function(info->acc_granted,
4379                                                SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
4380                                                "_samr_GetAliasMembership");
4381
4382         if (!NT_STATUS_IS_OK(ntstatus1) || !NT_STATUS_IS_OK(ntstatus2)) {
4383                 if (!(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus2)) &&
4384                     !(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus1))) {
4385                         return (NT_STATUS_IS_OK(ntstatus1)) ? ntstatus2 : ntstatus1;
4386                 }
4387         }
4388
4389         if (!sid_check_is_domain(&info->sid) &&
4390             !sid_check_is_builtin(&info->sid))
4391                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
4392
4393         if (r->in.sids->num_sids) {
4394                 members = TALLOC_ARRAY(p->mem_ctx, DOM_SID, r->in.sids->num_sids);
4395
4396                 if (members == NULL)
4397                         return NT_STATUS_NO_MEMORY;
4398         } else {
4399                 members = NULL;
4400         }
4401
4402         for (i=0; i<r->in.sids->num_sids; i++)
4403                 sid_copy(&members[i], r->in.sids->sids[i].sid);
4404
4405         alias_rids = NULL;
4406         num_alias_rids = 0;
4407
4408         become_root();
4409         ntstatus1 = pdb_enum_alias_memberships(p->mem_ctx, &info->sid, members,
4410                                                r->in.sids->num_sids,
4411                                                &alias_rids, &num_alias_rids);
4412         unbecome_root();
4413
4414         if (!NT_STATUS_IS_OK(ntstatus1)) {
4415                 return ntstatus1;
4416         }
4417
4418         r->out.rids->count = num_alias_rids;
4419         r->out.rids->ids = alias_rids;
4420
4421         return NT_STATUS_OK;
4422 }
4423
4424 /*********************************************************************
4425  _samr_GetMembersInAlias
4426 *********************************************************************/
4427
4428 NTSTATUS _samr_GetMembersInAlias(pipes_struct *p,
4429                                  struct samr_GetMembersInAlias *r)
4430 {
4431         NTSTATUS status;
4432         size_t i;
4433         size_t num_sids = 0;
4434         struct lsa_SidPtr *sids = NULL;
4435         DOM_SID *pdb_sids = NULL;
4436
4437         DOM_SID alias_sid;
4438
4439         uint32 acc_granted;
4440
4441         /* find the policy handle.  open a policy on it. */
4442         if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, NULL))
4443                 return NT_STATUS_INVALID_HANDLE;
4444
4445         status = access_check_samr_function(acc_granted,
4446                                             SAMR_ALIAS_ACCESS_GET_MEMBERS,
4447                                             "_samr_GetMembersInAlias");
4448         if (!NT_STATUS_IS_OK(status)) {
4449                 return status;
4450         }
4451
4452         DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
4453
4454         become_root();
4455         status = pdb_enum_aliasmem(&alias_sid, &pdb_sids, &num_sids);
4456         unbecome_root();
4457
4458         if (!NT_STATUS_IS_OK(status)) {
4459                 return status;
4460         }
4461
4462         if (num_sids) {
4463                 sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_SidPtr, num_sids);
4464                 if (sids == NULL) {
4465                         TALLOC_FREE(pdb_sids);
4466                         return NT_STATUS_NO_MEMORY;
4467                 }
4468         }
4469
4470         for (i = 0; i < num_sids; i++) {
4471                 sids[i].sid = sid_dup_talloc(p->mem_ctx, &pdb_sids[i]);
4472                 if (!sids[i].sid) {
4473                         TALLOC_FREE(pdb_sids);
4474                         return NT_STATUS_NO_MEMORY;
4475                 }
4476         }
4477
4478         r->out.sids->num_sids = num_sids;
4479         r->out.sids->sids = sids;
4480
4481         TALLOC_FREE(pdb_sids);
4482
4483         return NT_STATUS_OK;
4484 }
4485
4486 /*********************************************************************
4487  _samr_QueryGroupMember
4488 *********************************************************************/
4489
4490 NTSTATUS _samr_QueryGroupMember(pipes_struct *p,
4491                                 struct samr_QueryGroupMember *r)
4492 {
4493         DOM_SID group_sid;
4494         size_t i, num_members;
4495
4496         uint32 *rid=NULL;
4497         uint32 *attr=NULL;
4498
4499         uint32 acc_granted;
4500
4501         NTSTATUS status;
4502         struct samr_RidTypeArray *rids = NULL;
4503
4504         rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidTypeArray);
4505         if (!rids) {
4506                 return NT_STATUS_NO_MEMORY;
4507         }
4508
4509         /* find the policy handle.  open a policy on it. */
4510         if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, NULL))
4511                 return NT_STATUS_INVALID_HANDLE;
4512
4513         status = access_check_samr_function(acc_granted,
4514                                             SAMR_GROUP_ACCESS_GET_MEMBERS,
4515                                             "_samr_QueryGroupMember");
4516         if (!NT_STATUS_IS_OK(status)) {
4517                 return status;
4518         }
4519
4520         DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
4521
4522         if (!sid_check_is_in_our_domain(&group_sid)) {
4523                 DEBUG(3, ("sid %s is not in our domain\n",
4524                           sid_string_dbg(&group_sid)));
4525                 return NT_STATUS_NO_SUCH_GROUP;
4526         }
4527
4528         DEBUG(10, ("lookup on Domain SID\n"));
4529
4530         become_root();
4531         status = pdb_enum_group_members(p->mem_ctx, &group_sid,
4532                                         &rid, &num_members);
4533         unbecome_root();
4534
4535         if (!NT_STATUS_IS_OK(status))
4536                 return status;
4537
4538         if (num_members) {
4539                 attr=TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_members);
4540                 if (attr == NULL) {
4541                         return NT_STATUS_NO_MEMORY;
4542                 }
4543         } else {
4544                 attr = NULL;
4545         }
4546
4547         for (i=0; i<num_members; i++)
4548                 attr[i] = SID_NAME_USER;
4549
4550         rids->count = num_members;
4551         rids->types = attr;
4552         rids->rids = rid;
4553
4554         *r->out.rids = rids;
4555
4556         return NT_STATUS_OK;
4557 }
4558
4559 /*********************************************************************
4560  _samr_AddAliasMember
4561 *********************************************************************/
4562
4563 NTSTATUS _samr_AddAliasMember(pipes_struct *p,
4564                               struct samr_AddAliasMember *r)
4565 {
4566         DOM_SID alias_sid;
4567         uint32 acc_granted;
4568         SE_PRIV se_rights;
4569         bool can_add_accounts;
4570         NTSTATUS status;
4571         DISP_INFO *disp_info = NULL;
4572
4573         /* Find the policy handle. Open a policy on it. */
4574         if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
4575                 return NT_STATUS_INVALID_HANDLE;
4576
4577         status = access_check_samr_function(acc_granted,
4578                                             SAMR_ALIAS_ACCESS_ADD_MEMBER,
4579                                             "_samr_AddAliasMember");
4580         if (!NT_STATUS_IS_OK(status)) {
4581                 return status;
4582         }
4583
4584         DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
4585
4586         se_priv_copy( &se_rights, &se_add_users );
4587         can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4588
4589         /******** BEGIN SeAddUsers BLOCK *********/
4590
4591         if ( can_add_accounts )
4592                 become_root();
4593
4594         status = pdb_add_aliasmem(&alias_sid, r->in.sid);
4595
4596         if ( can_add_accounts )
4597                 unbecome_root();
4598
4599         /******** END SeAddUsers BLOCK *********/
4600
4601         if (NT_STATUS_IS_OK(status)) {
4602                 force_flush_samr_cache(disp_info);
4603         }
4604
4605         return status;
4606 }
4607
4608 /*********************************************************************
4609  _samr_DeleteAliasMember
4610 *********************************************************************/
4611
4612 NTSTATUS _samr_DeleteAliasMember(pipes_struct *p,
4613                                  struct samr_DeleteAliasMember *r)
4614 {
4615         DOM_SID alias_sid;
4616         uint32 acc_granted;
4617         SE_PRIV se_rights;
4618         bool can_add_accounts;
4619         NTSTATUS status;
4620         DISP_INFO *disp_info = NULL;
4621
4622         /* Find the policy handle. Open a policy on it. */
4623         if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
4624                 return NT_STATUS_INVALID_HANDLE;
4625
4626         status = access_check_samr_function(acc_granted,
4627                                             SAMR_ALIAS_ACCESS_REMOVE_MEMBER,
4628                                             "_samr_DeleteAliasMember");
4629         if (!NT_STATUS_IS_OK(status)) {
4630                 return status;
4631         }
4632
4633         DEBUG(10, ("_samr_del_aliasmem:sid is %s\n",
4634                    sid_string_dbg(&alias_sid)));
4635
4636         se_priv_copy( &se_rights, &se_add_users );
4637         can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4638
4639         /******** BEGIN SeAddUsers BLOCK *********/
4640
4641         if ( can_add_accounts )
4642                 become_root();
4643
4644         status = pdb_del_aliasmem(&alias_sid, r->in.sid);
4645
4646         if ( can_add_accounts )
4647                 unbecome_root();
4648
4649         /******** END SeAddUsers BLOCK *********/
4650
4651         if (NT_STATUS_IS_OK(status)) {
4652                 force_flush_samr_cache(disp_info);
4653         }
4654
4655         return status;
4656 }
4657
4658 /*********************************************************************
4659  _samr_AddGroupMember
4660 *********************************************************************/
4661
4662 NTSTATUS _samr_AddGroupMember(pipes_struct *p,
4663                               struct samr_AddGroupMember *r)
4664 {
4665         NTSTATUS status;
4666         DOM_SID group_sid;
4667         uint32 group_rid;
4668         uint32 acc_granted;
4669         SE_PRIV se_rights;
4670         bool can_add_accounts;
4671         DISP_INFO *disp_info = NULL;
4672
4673         /* Find the policy handle. Open a policy on it. */
4674         if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
4675                 return NT_STATUS_INVALID_HANDLE;
4676
4677         status = access_check_samr_function(acc_granted,
4678                                             SAMR_GROUP_ACCESS_ADD_MEMBER,
4679                                             "_samr_AddGroupMember");
4680         if (!NT_STATUS_IS_OK(status)) {
4681                 return status;
4682         }
4683
4684         DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
4685
4686         if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
4687                                 &group_rid)) {
4688                 return NT_STATUS_INVALID_HANDLE;
4689         }
4690
4691         se_priv_copy( &se_rights, &se_add_users );
4692         can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4693
4694         /******** BEGIN SeAddUsers BLOCK *********/
4695
4696         if ( can_add_accounts )
4697                 become_root();
4698
4699         status = pdb_add_groupmem(p->mem_ctx, group_rid, r->in.rid);
4700
4701         if ( can_add_accounts )
4702                 unbecome_root();
4703
4704         /******** END SeAddUsers BLOCK *********/
4705
4706         force_flush_samr_cache(disp_info);
4707
4708         return status;
4709 }
4710
4711 /*********************************************************************
4712  _samr_DeleteGroupMember
4713 *********************************************************************/
4714
4715 NTSTATUS _samr_DeleteGroupMember(pipes_struct *p,
4716                                  struct samr_DeleteGroupMember *r)
4717
4718 {
4719         NTSTATUS status;
4720         DOM_SID group_sid;
4721         uint32 group_rid;
4722         uint32 acc_granted;
4723         SE_PRIV se_rights;
4724         bool can_add_accounts;
4725         DISP_INFO *disp_info = NULL;
4726
4727         /*
4728          * delete the group member named r->in.rid
4729          * who is a member of the sid associated with the handle
4730          * the rid is a user's rid as the group is a domain group.
4731          */
4732
4733         /* Find the policy handle. Open a policy on it. */
4734         if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
4735                 return NT_STATUS_INVALID_HANDLE;
4736
4737         status = access_check_samr_function(acc_granted,
4738                                             SAMR_GROUP_ACCESS_REMOVE_MEMBER,
4739                                             "_samr_DeleteGroupMember");
4740         if (!NT_STATUS_IS_OK(status)) {
4741                 return status;
4742         }
4743
4744         if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
4745                                 &group_rid)) {
4746                 return NT_STATUS_INVALID_HANDLE;
4747         }
4748
4749         se_priv_copy( &se_rights, &se_add_users );
4750         can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4751
4752         /******** BEGIN SeAddUsers BLOCK *********/
4753
4754         if ( can_add_accounts )
4755                 become_root();
4756
4757         status = pdb_del_groupmem(p->mem_ctx, group_rid, r->in.rid);
4758
4759         if ( can_add_accounts )
4760                 unbecome_root();
4761
4762         /******** END SeAddUsers BLOCK *********/
4763
4764         force_flush_samr_cache(disp_info);
4765
4766         return status;
4767 }
4768
4769 /*********************************************************************
4770  _samr_DeleteUser
4771 *********************************************************************/
4772
4773 NTSTATUS _samr_DeleteUser(pipes_struct *p,
4774                           struct samr_DeleteUser *r)
4775 {
4776         NTSTATUS status;
4777         DOM_SID user_sid;
4778         struct samu *sam_pass=NULL;
4779         uint32 acc_granted;
4780         bool can_add_accounts;
4781         uint32 acb_info;
4782         DISP_INFO *disp_info = NULL;
4783         bool ret;
4784
4785         DEBUG(5, ("_samr_DeleteUser: %d\n", __LINE__));
4786
4787         /* Find the policy handle. Open a policy on it. */
4788         if (!get_lsa_policy_samr_sid(p, r->in.user_handle, &user_sid, &acc_granted, &disp_info))
4789                 return NT_STATUS_INVALID_HANDLE;
4790
4791         status = access_check_samr_function(acc_granted,
4792                                             STD_RIGHT_DELETE_ACCESS,
4793                                             "_samr_DeleteUser");
4794         if (!NT_STATUS_IS_OK(status)) {
4795                 return status;
4796         }
4797
4798         if (!sid_check_is_in_our_domain(&user_sid))
4799                 return NT_STATUS_CANNOT_DELETE;
4800
4801         /* check if the user exists before trying to delete */
4802         if ( !(sam_pass = samu_new( NULL )) ) {
4803                 return NT_STATUS_NO_MEMORY;
4804         }
4805
4806         become_root();
4807         ret = pdb_getsampwsid(sam_pass, &user_sid);
4808         unbecome_root();
4809
4810         if( !ret ) {
4811                 DEBUG(5,("_samr_DeleteUser: User %s doesn't exist.\n",
4812                         sid_string_dbg(&user_sid)));
4813                 TALLOC_FREE(sam_pass);
4814                 return NT_STATUS_NO_SUCH_USER;
4815         }
4816
4817         acb_info = pdb_get_acct_ctrl(sam_pass);
4818
4819         /* For machine accounts it's the SeMachineAccountPrivilege that counts. */
4820         if ( acb_info & ACB_WSTRUST ) {
4821                 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_machine_account );
4822         } else {
4823                 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_add_users );
4824         }
4825
4826         /******** BEGIN SeAddUsers BLOCK *********/
4827
4828         if ( can_add_accounts )
4829                 become_root();
4830
4831         status = pdb_delete_user(p->mem_ctx, sam_pass);
4832
4833         if ( can_add_accounts )
4834                 unbecome_root();
4835
4836         /******** END SeAddUsers BLOCK *********/
4837
4838         if ( !NT_STATUS_IS_OK(status) ) {
4839                 DEBUG(5,("_samr_DeleteUser: Failed to delete entry for "
4840                          "user %s: %s.\n", pdb_get_username(sam_pass),
4841                          nt_errstr(status)));
4842                 TALLOC_FREE(sam_pass);
4843                 return status;
4844         }
4845
4846
4847         TALLOC_FREE(sam_pass);
4848
4849         if (!close_policy_hnd(p, r->in.user_handle))
4850                 return NT_STATUS_OBJECT_NAME_INVALID;
4851
4852         ZERO_STRUCTP(r->out.user_handle);
4853
4854         force_flush_samr_cache(disp_info);
4855
4856         return NT_STATUS_OK;
4857 }
4858
4859 /*********************************************************************
4860  _samr_DeleteDomainGroup
4861 *********************************************************************/
4862
4863 NTSTATUS _samr_DeleteDomainGroup(pipes_struct *p,
4864                                  struct samr_DeleteDomainGroup *r)
4865 {
4866         NTSTATUS status;
4867         DOM_SID group_sid;
4868         uint32 group_rid;
4869         uint32 acc_granted;
4870         SE_PRIV se_rights;
4871         bool can_add_accounts;
4872         DISP_INFO *disp_info = NULL;
4873
4874         DEBUG(5, ("samr_DeleteDomainGroup: %d\n", __LINE__));
4875
4876         /* Find the policy handle. Open a policy on it. */
4877         if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
4878                 return NT_STATUS_INVALID_HANDLE;
4879
4880         status = access_check_samr_function(acc_granted,
4881                                             STD_RIGHT_DELETE_ACCESS,
4882                                             "_samr_DeleteDomainGroup");
4883         if (!NT_STATUS_IS_OK(status)) {
4884                 return status;
4885         }
4886
4887         DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
4888
4889         if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
4890                                 &group_rid)) {
4891                 return NT_STATUS_NO_SUCH_GROUP;
4892         }
4893
4894         se_priv_copy( &se_rights, &se_add_users );
4895         can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4896
4897         /******** BEGIN SeAddUsers BLOCK *********/
4898
4899         if ( can_add_accounts )
4900                 become_root();
4901
4902         status = pdb_delete_dom_group(p->mem_ctx, group_rid);
4903
4904         if ( can_add_accounts )
4905                 unbecome_root();
4906
4907         /******** END SeAddUsers BLOCK *********/
4908
4909         if ( !NT_STATUS_IS_OK(status) ) {
4910                 DEBUG(5,("_samr_DeleteDomainGroup: Failed to delete mapping "
4911                          "entry for group %s: %s\n",
4912                          sid_string_dbg(&group_sid),
4913                          nt_errstr(status)));
4914                 return status;
4915         }
4916
4917         if (!close_policy_hnd(p, r->in.group_handle))
4918                 return NT_STATUS_OBJECT_NAME_INVALID;
4919
4920         force_flush_samr_cache(disp_info);
4921
4922         return NT_STATUS_OK;
4923 }
4924
4925 /*********************************************************************
4926  _samr_DeleteDomAlias
4927 *********************************************************************/
4928
4929 NTSTATUS _samr_DeleteDomAlias(pipes_struct *p,
4930                               struct samr_DeleteDomAlias *r)
4931 {
4932         DOM_SID alias_sid;
4933         uint32 acc_granted;
4934         SE_PRIV se_rights;
4935         bool can_add_accounts;
4936         NTSTATUS status;
4937         DISP_INFO *disp_info = NULL;
4938
4939         DEBUG(5, ("_samr_DeleteDomAlias: %d\n", __LINE__));
4940
4941         /* Find the policy handle. Open a policy on it. */
4942         if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
4943                 return NT_STATUS_INVALID_HANDLE;
4944
4945         /* copy the handle to the outgoing reply */
4946
4947         memcpy(r->out.alias_handle, r->in.alias_handle, sizeof(r->out.alias_handle));
4948
4949         status = access_check_samr_function(acc_granted,
4950                                             STD_RIGHT_DELETE_ACCESS,
4951                                             "_samr_DeleteDomAlias");
4952         if (!NT_STATUS_IS_OK(status)) {
4953                 return status;
4954         }
4955
4956         DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
4957
4958         /* Don't let Windows delete builtin groups */
4959
4960         if ( sid_check_is_in_builtin( &alias_sid ) ) {
4961                 return NT_STATUS_SPECIAL_ACCOUNT;
4962         }
4963
4964         if (!sid_check_is_in_our_domain(&alias_sid))
4965                 return NT_STATUS_NO_SUCH_ALIAS;
4966
4967         DEBUG(10, ("lookup on Local SID\n"));
4968
4969         se_priv_copy( &se_rights, &se_add_users );
4970         can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4971
4972         /******** BEGIN SeAddUsers BLOCK *********/
4973
4974         if ( can_add_accounts )
4975                 become_root();
4976
4977         /* Have passdb delete the alias */
4978         status = pdb_delete_alias(&alias_sid);
4979
4980         if ( can_add_accounts )
4981                 unbecome_root();
4982
4983         /******** END SeAddUsers BLOCK *********/
4984
4985         if ( !NT_STATUS_IS_OK(status))
4986                 return status;
4987
4988         if (!close_policy_hnd(p, r->in.alias_handle))
4989                 return NT_STATUS_OBJECT_NAME_INVALID;
4990
4991         force_flush_samr_cache(disp_info);
4992
4993         return NT_STATUS_OK;
4994 }
4995
4996 /*********************************************************************
4997  _samr_CreateDomainGroup
4998 *********************************************************************/
4999
5000 NTSTATUS _samr_CreateDomainGroup(pipes_struct *p,
5001                                  struct samr_CreateDomainGroup *r)
5002
5003 {
5004         NTSTATUS status;
5005         DOM_SID dom_sid;
5006         DOM_SID info_sid;
5007         const char *name;
5008         struct samr_info *info;
5009         uint32 acc_granted;
5010         SE_PRIV se_rights;
5011         bool can_add_accounts;
5012         DISP_INFO *disp_info = NULL;
5013
5014         /* Find the policy handle. Open a policy on it. */
5015         if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &dom_sid, &acc_granted, &disp_info))
5016                 return NT_STATUS_INVALID_HANDLE;
5017
5018         status = access_check_samr_function(acc_granted,
5019                                             SAMR_DOMAIN_ACCESS_CREATE_GROUP,
5020                                             "_samr_CreateDomainGroup");
5021         if (!NT_STATUS_IS_OK(status)) {
5022                 return status;
5023         }
5024
5025         if (!sid_equal(&dom_sid, get_global_sam_sid()))
5026                 return NT_STATUS_ACCESS_DENIED;
5027
5028         name = r->in.name->string;
5029         if (name == NULL) {
5030                 return NT_STATUS_NO_MEMORY;
5031         }
5032
5033         status = can_create(p->mem_ctx, name);
5034         if (!NT_STATUS_IS_OK(status)) {
5035                 return status;
5036         }
5037
5038         se_priv_copy( &se_rights, &se_add_users );
5039         can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
5040
5041         /******** BEGIN SeAddUsers BLOCK *********/
5042
5043         if ( can_add_accounts )
5044                 become_root();
5045
5046         /* check that we successfully create the UNIX group */
5047
5048         status = pdb_create_dom_group(p->mem_ctx, name, r->out.rid);
5049
5050         if ( can_add_accounts )
5051                 unbecome_root();
5052
5053         /******** END SeAddUsers BLOCK *********/
5054
5055         /* check if we should bail out here */
5056
5057         if ( !NT_STATUS_IS_OK(status) )
5058                 return status;
5059
5060         sid_compose(&info_sid, get_global_sam_sid(), *r->out.rid);
5061
5062         if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
5063                 return NT_STATUS_NO_MEMORY;
5064
5065         /* they created it; let the user do what he wants with it */
5066
5067         info->acc_granted = GENERIC_RIGHTS_GROUP_ALL_ACCESS;
5068
5069         /* get a (unique) handle.  open a policy on it. */
5070         if (!create_policy_hnd(p, r->out.group_handle, free_samr_info, (void *)info))
5071                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5072
5073         force_flush_samr_cache(disp_info);
5074
5075         return NT_STATUS_OK;
5076 }
5077
5078 /*********************************************************************
5079  _samr_CreateDomAlias
5080 *********************************************************************/
5081
5082 NTSTATUS _samr_CreateDomAlias(pipes_struct *p,
5083                               struct samr_CreateDomAlias *r)
5084 {
5085         DOM_SID dom_sid;
5086         DOM_SID info_sid;
5087         const char *name = NULL;
5088         struct samr_info *info;
5089         uint32 acc_granted;
5090         gid_t gid;
5091         NTSTATUS result;
5092         SE_PRIV se_rights;
5093         bool can_add_accounts;
5094         DISP_INFO *disp_info = NULL;
5095
5096         /* Find the policy handle. Open a policy on it. */
5097         if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &dom_sid, &acc_granted, &disp_info))
5098                 return NT_STATUS_INVALID_HANDLE;
5099
5100         result = access_check_samr_function(acc_granted,
5101                                             SAMR_DOMAIN_ACCESS_CREATE_ALIAS,
5102                                             "_samr_CreateDomAlias");
5103         if (!NT_STATUS_IS_OK(result)) {
5104                 return result;
5105         }
5106
5107         if (!sid_equal(&dom_sid, get_global_sam_sid()))
5108                 return NT_STATUS_ACCESS_DENIED;
5109
5110         name = r->in.alias_name->string;
5111
5112         se_priv_copy( &se_rights, &se_add_users );
5113         can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
5114
5115         result = can_create(p->mem_ctx, name);
5116         if (!NT_STATUS_IS_OK(result)) {
5117                 return result;
5118         }
5119
5120         /******** BEGIN SeAddUsers BLOCK *********/
5121
5122         if ( can_add_accounts )
5123                 become_root();
5124
5125         /* Have passdb create the alias */
5126         result = pdb_create_alias(name, r->out.rid);
5127
5128         if ( can_add_accounts )
5129                 unbecome_root();
5130
5131         /******** END SeAddUsers BLOCK *********/
5132
5133         if (!NT_STATUS_IS_OK(result)) {
5134                 DEBUG(10, ("pdb_create_alias failed: %s\n",
5135                            nt_errstr(result)));
5136                 return result;
5137         }
5138
5139         sid_copy(&info_sid, get_global_sam_sid());
5140         sid_append_rid(&info_sid, *r->out.rid);
5141
5142         if (!sid_to_gid(&info_sid, &gid)) {
5143                 DEBUG(10, ("Could not find alias just created\n"));
5144                 return NT_STATUS_ACCESS_DENIED;
5145         }
5146
5147         /* check if the group has been successfully created */
5148         if ( getgrgid(gid) == NULL ) {
5149                 DEBUG(10, ("getgrgid(%d) of just created alias failed\n",
5150                            gid));
5151                 return NT_STATUS_ACCESS_DENIED;
5152         }
5153
5154         if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
5155                 return NT_STATUS_NO_MEMORY;
5156
5157         /* they created it; let the user do what he wants with it */
5158
5159         info->acc_granted = GENERIC_RIGHTS_ALIAS_ALL_ACCESS;
5160
5161         /* get a (unique) handle.  open a policy on it. */
5162         if (!create_policy_hnd(p, r->out.alias_handle, free_samr_info, (void *)info))
5163                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5164
5165         force_flush_samr_cache(disp_info);
5166
5167         return NT_STATUS_OK;
5168 }
5169
5170 /*********************************************************************
5171  _samr_QueryGroupInfo
5172 *********************************************************************/
5173
5174 NTSTATUS _samr_QueryGroupInfo(pipes_struct *p,
5175                               struct samr_QueryGroupInfo *r)
5176 {
5177         NTSTATUS status;
5178         DOM_SID group_sid;
5179         GROUP_MAP map;
5180         union samr_GroupInfo *info = NULL;
5181         uint32 acc_granted;
5182         bool ret;
5183         uint32_t attributes = SE_GROUP_MANDATORY |
5184                               SE_GROUP_ENABLED_BY_DEFAULT |
5185                               SE_GROUP_ENABLED;
5186         const char *group_name = NULL;
5187         const char *group_description = NULL;
5188
5189         if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, NULL))
5190                 return NT_STATUS_INVALID_HANDLE;
5191
5192         status = access_check_samr_function(acc_granted,
5193                                             SAMR_GROUP_ACCESS_LOOKUP_INFO,
5194                                             "_samr_QueryGroupInfo");
5195         if (!NT_STATUS_IS_OK(status)) {
5196                 return status;
5197         }
5198
5199         become_root();
5200         ret = get_domain_group_from_sid(group_sid, &map);
5201         unbecome_root();
5202         if (!ret)
5203                 return NT_STATUS_INVALID_HANDLE;
5204
5205         /* FIXME: map contains fstrings */
5206         group_name = talloc_strdup(r, map.nt_name);
5207         group_description = talloc_strdup(r, map.comment);
5208
5209         info = TALLOC_ZERO_P(p->mem_ctx, union samr_GroupInfo);
5210         if (!info) {
5211                 return NT_STATUS_NO_MEMORY;
5212         }
5213
5214         switch (r->in.level) {
5215                 case 1: {
5216                         uint32 *members;
5217                         size_t num_members;
5218
5219                         become_root();
5220                         status = pdb_enum_group_members(
5221                                 p->mem_ctx, &group_sid, &members, &num_members);
5222                         unbecome_root();
5223
5224                         if (!NT_STATUS_IS_OK(status)) {
5225                                 return status;
5226                         }
5227
5228                         init_samr_group_info1(&info->all,
5229                                               group_name,
5230                                               attributes,
5231                                               num_members,
5232                                               group_description);
5233                         break;
5234                 }
5235                 case 2:
5236                         init_samr_group_info2(&info->name,
5237                                               group_name);
5238                         break;
5239                 case 3:
5240                         init_samr_group_info3(&info->attributes,
5241                                               attributes);
5242                         break;
5243                 case 4:
5244                         init_samr_group_info4(&info->description,
5245                                               group_description);
5246                         break;
5247                 case 5: {
5248                         /*
5249                         uint32 *members;
5250                         size_t num_members;
5251                         */
5252
5253                         /*
5254                         become_root();
5255                         status = pdb_enum_group_members(
5256                                 p->mem_ctx, &group_sid, &members, &num_members);
5257                         unbecome_root();
5258
5259                         if (!NT_STATUS_IS_OK(status)) {
5260                                 return status;
5261                         }
5262                         */
5263                         init_samr_group_info5(&info->all2,
5264                                               group_name,
5265                                               attributes,
5266                                               0, /* num_members - in w2k3 this is always 0 */
5267                                               group_description);
5268
5269                         break;
5270                 }
5271                 default:
5272                         return NT_STATUS_INVALID_INFO_CLASS;
5273         }
5274
5275         *r->out.info = info;
5276
5277         return NT_STATUS_OK;
5278 }
5279
5280 /*********************************************************************
5281  _samr_SetGroupInfo
5282 *********************************************************************/
5283
5284 NTSTATUS _samr_SetGroupInfo(pipes_struct *p,
5285                             struct samr_SetGroupInfo *r)
5286 {
5287         DOM_SID group_sid;
5288         GROUP_MAP map;
5289         uint32 acc_granted;
5290         NTSTATUS status;
5291         bool ret;
5292         bool can_mod_accounts;
5293         DISP_INFO *disp_info = NULL;
5294
5295         if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
5296                 return NT_STATUS_INVALID_HANDLE;
5297
5298         status = access_check_samr_function(acc_granted,
5299                                             SAMR_GROUP_ACCESS_SET_INFO,
5300                                             "_samr_SetGroupInfo");
5301         if (!NT_STATUS_IS_OK(status)) {
5302                 return status;
5303         }
5304
5305         become_root();
5306         ret = get_domain_group_from_sid(group_sid, &map);
5307         unbecome_root();
5308         if (!ret)
5309                 return NT_STATUS_NO_SUCH_GROUP;
5310
5311         switch (r->in.level) {
5312                 case 1:
5313                         fstrcpy(map.comment, r->in.info->all.description.string);
5314                         break;
5315                 case 4:
5316                         fstrcpy(map.comment, r->in.info->description.string);
5317                         break;
5318                 default:
5319                         return NT_STATUS_INVALID_INFO_CLASS;
5320         }
5321
5322         can_mod_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_add_users );
5323
5324         /******** BEGIN SeAddUsers BLOCK *********/
5325
5326         if ( can_mod_accounts )
5327                 become_root();
5328
5329         status = pdb_update_group_mapping_entry(&map);
5330
5331         if ( can_mod_accounts )
5332                 unbecome_root();
5333
5334         /******** End SeAddUsers BLOCK *********/
5335
5336         if (NT_STATUS_IS_OK(status)) {
5337                 force_flush_samr_cache(disp_info);
5338         }
5339
5340         return status;
5341 }
5342
5343 /*********************************************************************
5344  _samr_SetAliasInfo
5345 *********************************************************************/
5346
5347 NTSTATUS _samr_SetAliasInfo(pipes_struct *p,
5348                             struct samr_SetAliasInfo *r)
5349 {
5350         DOM_SID group_sid;
5351         struct acct_info info;
5352         uint32 acc_granted;
5353         bool can_mod_accounts;
5354         NTSTATUS status;
5355         DISP_INFO *disp_info = NULL;
5356
5357         if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &group_sid, &acc_granted, &disp_info))
5358                 return NT_STATUS_INVALID_HANDLE;
5359
5360         status = access_check_samr_function(acc_granted,
5361                                             SAMR_ALIAS_ACCESS_SET_INFO,
5362                                             "_samr_SetAliasInfo");
5363         if (!NT_STATUS_IS_OK(status)) {
5364                 return status;
5365         }
5366
5367         /* get the current group information */
5368
5369         become_root();
5370         status = pdb_get_aliasinfo( &group_sid, &info );
5371         unbecome_root();
5372
5373         if ( !NT_STATUS_IS_OK(status))
5374                 return status;
5375
5376         switch (r->in.level) {
5377                 case ALIASINFONAME:
5378                 {
5379                         fstring group_name;
5380
5381                         /* We currently do not support renaming groups in the
5382                            the BUILTIN domain.  Refer to util_builtin.c to understand
5383                            why.  The eventually needs to be fixed to be like Windows
5384                            where you can rename builtin groups, just not delete them */
5385
5386                         if ( sid_check_is_in_builtin( &group_sid ) ) {
5387                                 return NT_STATUS_SPECIAL_ACCOUNT;
5388                         }
5389
5390                         /* There has to be a valid name (and it has to be different) */
5391
5392                         if ( !r->in.info->name.string )
5393                                 return NT_STATUS_INVALID_PARAMETER;
5394
5395                         /* If the name is the same just reply "ok".  Yes this
5396                            doesn't allow you to change the case of a group name. */
5397
5398                         if ( strequal( r->in.info->name.string, info.acct_name ) )
5399                                 return NT_STATUS_OK;
5400
5401                         fstrcpy( info.acct_name, r->in.info->name.string);
5402
5403                         /* make sure the name doesn't already exist as a user
5404                            or local group */
5405
5406                         fstr_sprintf( group_name, "%s\\%s", global_myname(), info.acct_name );
5407                         status = can_create( p->mem_ctx, group_name );
5408                         if ( !NT_STATUS_IS_OK( status ) )
5409                                 return status;
5410                         break;
5411                 }
5412                 case ALIASINFODESCRIPTION:
5413                         if (r->in.info->description.string) {
5414                                 fstrcpy(info.acct_desc,
5415                                         r->in.info->description.string);
5416                         } else {
5417                                 fstrcpy( info.acct_desc, "" );
5418                         }
5419                         break;
5420                 default:
5421                         return NT_STATUS_INVALID_INFO_CLASS;
5422         }
5423
5424         can_mod_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_add_users );
5425
5426         /******** BEGIN SeAddUsers BLOCK *********/
5427
5428         if ( can_mod_accounts )
5429                 become_root();
5430
5431         status = pdb_set_aliasinfo( &group_sid, &info );
5432
5433         if ( can_mod_accounts )
5434                 unbecome_root();
5435
5436         /******** End SeAddUsers BLOCK *********/
5437
5438         if (NT_STATUS_IS_OK(status))
5439                 force_flush_samr_cache(disp_info);
5440
5441         return status;
5442 }
5443
5444 /****************************************************************
5445  _samr_GetDomPwInfo
5446 ****************************************************************/
5447
5448 NTSTATUS _samr_GetDomPwInfo(pipes_struct *p,
5449                             struct samr_GetDomPwInfo *r)
5450 {
5451         uint32_t min_password_length = 0;
5452         uint32_t password_properties = 0;
5453
5454         /* Perform access check.  Since this rpc does not require a
5455            policy handle it will not be caught by the access checks on
5456            SAMR_CONNECT or SAMR_CONNECT_ANON. */
5457
5458         if (!pipe_access_check(p)) {
5459                 DEBUG(3, ("access denied to _samr_GetDomPwInfo\n"));
5460                 return NT_STATUS_ACCESS_DENIED;
5461         }
5462
5463         become_root();
5464         pdb_get_account_policy(AP_MIN_PASSWORD_LEN,
5465                                &min_password_length);
5466         pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
5467                                &password_properties);
5468         unbecome_root();
5469
5470         if (lp_check_password_script() && *lp_check_password_script()) {
5471                 password_properties |= DOMAIN_PASSWORD_COMPLEX;
5472         }
5473
5474         r->out.info->min_password_length = min_password_length;
5475         r->out.info->password_properties = password_properties;
5476
5477         return NT_STATUS_OK;
5478 }
5479
5480 /*********************************************************************
5481  _samr_OpenGroup
5482 *********************************************************************/
5483
5484 NTSTATUS _samr_OpenGroup(pipes_struct *p,
5485                          struct samr_OpenGroup *r)
5486
5487 {
5488         DOM_SID sid;
5489         DOM_SID info_sid;
5490         GROUP_MAP map;
5491         struct samr_info *info;
5492         SEC_DESC         *psd = NULL;
5493         uint32            acc_granted;
5494         uint32            des_access = r->in.access_mask;
5495         size_t            sd_size;
5496         NTSTATUS          status;
5497         fstring sid_string;
5498         bool ret;
5499         SE_PRIV se_rights;
5500
5501         if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &sid, &acc_granted, NULL))
5502                 return NT_STATUS_INVALID_HANDLE;
5503
5504         status = access_check_samr_function(acc_granted,
5505                                             SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
5506                                             "_samr_OpenGroup");
5507
5508         if ( !NT_STATUS_IS_OK(status) )
5509                 return status;
5510
5511         /*check if access can be granted as requested by client. */
5512         map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
5513
5514         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &grp_generic_mapping, NULL, 0);
5515         se_map_generic(&des_access,&grp_generic_mapping);
5516
5517         se_priv_copy( &se_rights, &se_add_users );
5518
5519         status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
5520                 &se_rights, GENERIC_RIGHTS_GROUP_WRITE, des_access,
5521                 &acc_granted, "_samr_OpenGroup");
5522
5523         if ( !NT_STATUS_IS_OK(status) )
5524                 return status;
5525
5526         /* this should not be hard-coded like this */
5527
5528         if (!sid_equal(&sid, get_global_sam_sid()))
5529                 return NT_STATUS_ACCESS_DENIED;
5530
5531         sid_copy(&info_sid, get_global_sam_sid());
5532         sid_append_rid(&info_sid, r->in.rid);
5533         sid_to_fstring(sid_string, &info_sid);
5534
5535         if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
5536                 return NT_STATUS_NO_MEMORY;
5537
5538         info->acc_granted = acc_granted;
5539
5540         DEBUG(10, ("_samr_OpenGroup:Opening SID: %s\n", sid_string));
5541
5542         /* check if that group really exists */
5543         become_root();
5544         ret = get_domain_group_from_sid(info->sid, &map);
5545         unbecome_root();
5546         if (!ret)
5547                 return NT_STATUS_NO_SUCH_GROUP;
5548
5549         /* get a (unique) handle.  open a policy on it. */
5550         if (!create_policy_hnd(p, r->out.group_handle, free_samr_info, (void *)info))
5551                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5552
5553         return NT_STATUS_OK;
5554 }
5555
5556 /*********************************************************************
5557  _samr_RemoveMemberFromForeignDomain
5558 *********************************************************************/
5559
5560 NTSTATUS _samr_RemoveMemberFromForeignDomain(pipes_struct *p,
5561                                              struct samr_RemoveMemberFromForeignDomain *r)
5562 {
5563         DOM_SID                 delete_sid, domain_sid;
5564         uint32                  acc_granted;
5565         NTSTATUS                result;
5566         DISP_INFO *disp_info = NULL;
5567
5568         sid_copy( &delete_sid, r->in.sid );
5569
5570         DEBUG(5,("_samr_RemoveMemberFromForeignDomain: removing SID [%s]\n",
5571                 sid_string_dbg(&delete_sid)));
5572
5573         /* Find the policy handle. Open a policy on it. */
5574
5575         if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &domain_sid,
5576                                      &acc_granted, &disp_info))
5577                 return NT_STATUS_INVALID_HANDLE;
5578
5579         result = access_check_samr_function(acc_granted,
5580                                             STD_RIGHT_DELETE_ACCESS,
5581                                             "_samr_RemoveMemberFromForeignDomain");
5582
5583         if (!NT_STATUS_IS_OK(result))
5584                 return result;
5585
5586         DEBUG(8, ("_samr_RemoveMemberFromForeignDomain: sid is %s\n",
5587                   sid_string_dbg(&domain_sid)));
5588
5589         /* we can only delete a user from a group since we don't have
5590            nested groups anyways.  So in the latter case, just say OK */
5591
5592         /* TODO: The above comment nowadays is bogus. Since we have nested
5593          * groups now, and aliases members are never reported out of the unix
5594          * group membership, the "just say OK" makes this call a no-op. For
5595          * us. This needs fixing however. */
5596
5597         /* I've only ever seen this in the wild when deleting a user from
5598          * usrmgr.exe. domain_sid is the builtin domain, and the sid to delete
5599          * is the user about to be deleted. I very much suspect this is the
5600          * only application of this call. To verify this, let people report
5601          * other cases. */
5602
5603         if (!sid_check_is_builtin(&domain_sid)) {
5604                 DEBUG(1,("_samr_RemoveMemberFromForeignDomain: domain_sid = %s, "
5605                          "global_sam_sid() = %s\n",
5606                          sid_string_dbg(&domain_sid),
5607                          sid_string_dbg(get_global_sam_sid())));
5608                 DEBUGADD(1,("please report to samba-technical@samba.org!\n"));
5609                 return NT_STATUS_OK;
5610         }
5611
5612         force_flush_samr_cache(disp_info);
5613
5614         result = NT_STATUS_OK;
5615
5616         return result;
5617 }
5618
5619 /*******************************************************************
5620  _samr_QueryDomainInfo2
5621  ********************************************************************/
5622
5623 NTSTATUS _samr_QueryDomainInfo2(pipes_struct *p,
5624                                 struct samr_QueryDomainInfo2 *r)
5625 {
5626         struct samr_QueryDomainInfo q;
5627
5628         q.in.domain_handle      = r->in.domain_handle;
5629         q.in.level              = r->in.level;
5630
5631         q.out.info              = r->out.info;
5632
5633         return _samr_QueryDomainInfo(p, &q);
5634 }
5635
5636 /*******************************************************************
5637  _samr_SetDomainInfo
5638  ********************************************************************/
5639
5640 NTSTATUS _samr_SetDomainInfo(pipes_struct *p,
5641                              struct samr_SetDomainInfo *r)
5642 {
5643         struct samr_info *info = NULL;
5644         time_t u_expire, u_min_age;
5645         time_t u_logout;
5646         time_t u_lock_duration, u_reset_time;
5647         NTSTATUS result;
5648
5649         DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
5650
5651         /* find the policy handle.  open a policy on it. */
5652         if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
5653                 return NT_STATUS_INVALID_HANDLE;
5654
5655         /* We do have different access bits for info
5656          * levels here, but we're really just looking for
5657          * GENERIC_RIGHTS_DOMAIN_WRITE access. Unfortunately
5658          * this maps to different specific bits. So
5659          * assume if we have SAMR_DOMAIN_ACCESS_SET_INFO_1
5660          * set we are ok. */
5661
5662         result = access_check_samr_function(info->acc_granted,
5663                                             SAMR_DOMAIN_ACCESS_SET_INFO_1,
5664                                             "_samr_SetDomainInfo");
5665
5666         if (!NT_STATUS_IS_OK(result))
5667                 return result;
5668
5669         DEBUG(5,("_samr_SetDomainInfo: level: %d\n", r->in.level));
5670
5671         switch (r->in.level) {
5672                 case 0x01:
5673                         u_expire=nt_time_to_unix_abs((NTTIME *)&r->in.info->info1.max_password_age);
5674                         u_min_age=nt_time_to_unix_abs((NTTIME *)&r->in.info->info1.min_password_age);
5675                         pdb_set_account_policy(AP_MIN_PASSWORD_LEN, (uint32)r->in.info->info1.min_password_length);
5676                         pdb_set_account_policy(AP_PASSWORD_HISTORY, (uint32)r->in.info->info1.password_history_length);
5677                         pdb_set_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, (uint32)r->in.info->info1.password_properties);
5678                         pdb_set_account_policy(AP_MAX_PASSWORD_AGE, (int)u_expire);
5679                         pdb_set_account_policy(AP_MIN_PASSWORD_AGE, (int)u_min_age);
5680                         break;
5681                 case 0x02:
5682                         break;
5683                 case 0x03:
5684                         u_logout=nt_time_to_unix_abs((NTTIME *)&r->in.info->info3.force_logoff_time);
5685                         pdb_set_account_policy(AP_TIME_TO_LOGOUT, (int)u_logout);
5686                         break;
5687                 case 0x05:
5688                         break;
5689                 case 0x06:
5690                         break;
5691                 case 0x07:
5692                         break;
5693                 case 0x0c:
5694                         u_lock_duration=nt_time_to_unix_abs((NTTIME *)&r->in.info->info12.lockout_duration);
5695                         if (u_lock_duration != -1)
5696                                 u_lock_duration /= 60;
5697
5698                         u_reset_time=nt_time_to_unix_abs((NTTIME *)&r->in.info->info12.lockout_window)/60;
5699
5700                         pdb_set_account_policy(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
5701                         pdb_set_account_policy(AP_RESET_COUNT_TIME, (int)u_reset_time);
5702                         pdb_set_account_policy(AP_BAD_ATTEMPT_LOCKOUT, (uint32)r->in.info->info12.lockout_threshold);
5703                         break;
5704                 default:
5705                         return NT_STATUS_INVALID_INFO_CLASS;
5706         }
5707
5708         DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
5709
5710         return NT_STATUS_OK;
5711 }
5712
5713 /****************************************************************
5714  _samr_GetDisplayEnumerationIndex
5715 ****************************************************************/
5716
5717 NTSTATUS _samr_GetDisplayEnumerationIndex(pipes_struct *p,
5718                                           struct samr_GetDisplayEnumerationIndex *r)
5719 {
5720         struct samr_info *info = NULL;
5721         uint32_t max_entries = (uint32_t) -1;
5722         uint32_t enum_context = 0;
5723         int i;
5724         uint32_t num_account = 0;
5725         struct samr_displayentry *entries = NULL;
5726         NTSTATUS status;
5727
5728         DEBUG(5,("_samr_GetDisplayEnumerationIndex: %d\n", __LINE__));
5729
5730         /* find the policy handle.  open a policy on it. */
5731         if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info)) {
5732                 return NT_STATUS_INVALID_HANDLE;
5733         }
5734
5735         status = access_check_samr_function(info->acc_granted,
5736                                             SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
5737                                             "_samr_GetDisplayEnumerationIndex");
5738         if (!NT_STATUS_IS_OK(status)) {
5739                 return status;
5740         }
5741
5742         if ((r->in.level < 1) || (r->in.level > 3)) {
5743                 DEBUG(0,("_samr_GetDisplayEnumerationIndex: "
5744                         "Unknown info level (%u)\n",
5745                         r->in.level));
5746                 return NT_STATUS_INVALID_INFO_CLASS;
5747         }
5748
5749         become_root();
5750
5751         /* The following done as ROOT. Don't return without unbecome_root(). */
5752
5753         switch (r->in.level) {
5754         case 1:
5755                 if (info->disp_info->users == NULL) {
5756                         info->disp_info->users = pdb_search_users(ACB_NORMAL);
5757                         if (info->disp_info->users == NULL) {
5758                                 unbecome_root();
5759                                 return NT_STATUS_ACCESS_DENIED;
5760                         }
5761                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5762                                 "starting user enumeration at index %u\n",
5763                                 (unsigned int)enum_context));
5764                 } else {
5765                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5766                                 "using cached user enumeration at index %u\n",
5767                                 (unsigned int)enum_context));
5768                 }
5769                 num_account = pdb_search_entries(info->disp_info->users,
5770                                                  enum_context, max_entries,
5771                                                  &entries);
5772                 break;
5773         case 2:
5774                 if (info->disp_info->machines == NULL) {
5775                         info->disp_info->machines =
5776                                 pdb_search_users(ACB_WSTRUST|ACB_SVRTRUST);
5777                         if (info->disp_info->machines == NULL) {
5778                                 unbecome_root();
5779                                 return NT_STATUS_ACCESS_DENIED;
5780                         }
5781                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5782                                 "starting machine enumeration at index %u\n",
5783                                 (unsigned int)enum_context));
5784                 } else {
5785                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5786                                 "using cached machine enumeration at index %u\n",
5787                                 (unsigned int)enum_context));
5788                 }
5789                 num_account = pdb_search_entries(info->disp_info->machines,
5790                                                  enum_context, max_entries,
5791                                                  &entries);
5792                 break;
5793         case 3:
5794                 if (info->disp_info->groups == NULL) {
5795                         info->disp_info->groups = pdb_search_groups();
5796                         if (info->disp_info->groups == NULL) {
5797                                 unbecome_root();
5798                                 return NT_STATUS_ACCESS_DENIED;
5799                         }
5800                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5801                                 "starting group enumeration at index %u\n",
5802                                 (unsigned int)enum_context));
5803                 } else {
5804                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5805                                 "using cached group enumeration at index %u\n",
5806                                 (unsigned int)enum_context));
5807                 }
5808                 num_account = pdb_search_entries(info->disp_info->groups,
5809                                                  enum_context, max_entries,
5810                                                  &entries);
5811                 break;
5812         default:
5813                 unbecome_root();
5814                 smb_panic("info class changed");
5815                 break;
5816         }
5817
5818         unbecome_root();
5819
5820         /* Ensure we cache this enumeration. */
5821         set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
5822
5823         DEBUG(10,("_samr_GetDisplayEnumerationIndex: looking for :%s\n",
5824                 r->in.name->string));
5825
5826         for (i=0; i<num_account; i++) {
5827                 if (strequal(entries[i].account_name, r->in.name->string)) {
5828                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5829                                 "found %s at idx %d\n",
5830                                 r->in.name->string, i));
5831                         *r->out.idx = i;
5832                         return NT_STATUS_OK;
5833                 }
5834         }
5835
5836         /* assuming account_name lives at the very end */
5837         *r->out.idx = num_account;
5838
5839         return NT_STATUS_NO_MORE_ENTRIES;
5840 }
5841
5842 /****************************************************************
5843  _samr_GetDisplayEnumerationIndex2
5844 ****************************************************************/
5845
5846 NTSTATUS _samr_GetDisplayEnumerationIndex2(pipes_struct *p,
5847                                            struct samr_GetDisplayEnumerationIndex2 *r)
5848 {
5849         struct samr_GetDisplayEnumerationIndex q;
5850
5851         q.in.domain_handle      = r->in.domain_handle;
5852         q.in.level              = r->in.level;
5853         q.in.name               = r->in.name;
5854
5855         q.out.idx               = r->out.idx;
5856
5857         return _samr_GetDisplayEnumerationIndex(p, &q);
5858 }
5859
5860 /****************************************************************
5861 ****************************************************************/
5862
5863 NTSTATUS _samr_Shutdown(pipes_struct *p,
5864                         struct samr_Shutdown *r)
5865 {
5866         p->rng_fault_state = true;
5867         return NT_STATUS_NOT_IMPLEMENTED;
5868 }
5869
5870 /****************************************************************
5871 ****************************************************************/
5872
5873 NTSTATUS _samr_SetMemberAttributesOfGroup(pipes_struct *p,
5874                                           struct samr_SetMemberAttributesOfGroup *r)
5875 {
5876         p->rng_fault_state = true;
5877         return NT_STATUS_NOT_IMPLEMENTED;
5878 }
5879
5880 /****************************************************************
5881 ****************************************************************/
5882
5883 NTSTATUS _samr_ChangePasswordUser(pipes_struct *p,
5884                                   struct samr_ChangePasswordUser *r)
5885 {
5886         p->rng_fault_state = true;
5887         return NT_STATUS_NOT_IMPLEMENTED;
5888 }
5889
5890 /****************************************************************
5891 ****************************************************************/
5892
5893 NTSTATUS _samr_TestPrivateFunctionsDomain(pipes_struct *p,
5894                                           struct samr_TestPrivateFunctionsDomain *r)
5895 {
5896         p->rng_fault_state = true;
5897         return NT_STATUS_NOT_IMPLEMENTED;
5898 }
5899
5900 /****************************************************************
5901 ****************************************************************/
5902
5903 NTSTATUS _samr_TestPrivateFunctionsUser(pipes_struct *p,
5904                                         struct samr_TestPrivateFunctionsUser *r)
5905 {
5906         p->rng_fault_state = true;
5907         return NT_STATUS_NOT_IMPLEMENTED;
5908 }
5909
5910 /****************************************************************
5911 ****************************************************************/
5912
5913 NTSTATUS _samr_AddMultipleMembersToAlias(pipes_struct *p,
5914                                          struct samr_AddMultipleMembersToAlias *r)
5915 {
5916         p->rng_fault_state = true;
5917         return NT_STATUS_NOT_IMPLEMENTED;
5918 }
5919
5920 /****************************************************************
5921 ****************************************************************/
5922
5923 NTSTATUS _samr_RemoveMultipleMembersFromAlias(pipes_struct *p,
5924                                               struct samr_RemoveMultipleMembersFromAlias *r)
5925 {
5926         p->rng_fault_state = true;
5927         return NT_STATUS_NOT_IMPLEMENTED;
5928 }
5929
5930 /****************************************************************
5931 ****************************************************************/
5932
5933 NTSTATUS _samr_OemChangePasswordUser2(pipes_struct *p,
5934                                       struct samr_OemChangePasswordUser2 *r)
5935 {
5936         p->rng_fault_state = true;
5937         return NT_STATUS_NOT_IMPLEMENTED;
5938 }
5939
5940 /****************************************************************
5941 ****************************************************************/
5942
5943 NTSTATUS _samr_SetBootKeyInformation(pipes_struct *p,
5944                                      struct samr_SetBootKeyInformation *r)
5945 {
5946         p->rng_fault_state = true;
5947         return NT_STATUS_NOT_IMPLEMENTED;
5948 }
5949
5950 /****************************************************************
5951 ****************************************************************/
5952
5953 NTSTATUS _samr_GetBootKeyInformation(pipes_struct *p,
5954                                      struct samr_GetBootKeyInformation *r)
5955 {
5956         p->rng_fault_state = true;
5957         return NT_STATUS_NOT_IMPLEMENTED;
5958 }
5959
5960 /****************************************************************
5961 ****************************************************************/
5962
5963 NTSTATUS _samr_Connect3(pipes_struct *p,
5964                         struct samr_Connect3 *r)
5965 {
5966         p->rng_fault_state = true;
5967         return NT_STATUS_NOT_IMPLEMENTED;
5968 }
5969
5970 /****************************************************************
5971 ****************************************************************/
5972
5973 NTSTATUS _samr_RidToSid(pipes_struct *p,
5974                         struct samr_RidToSid *r)
5975 {
5976         p->rng_fault_state = true;
5977         return NT_STATUS_NOT_IMPLEMENTED;
5978 }
5979
5980 /****************************************************************
5981 ****************************************************************/
5982
5983 NTSTATUS _samr_SetDsrmPassword(pipes_struct *p,
5984                                struct samr_SetDsrmPassword *r)
5985 {
5986         p->rng_fault_state = true;
5987         return NT_STATUS_NOT_IMPLEMENTED;
5988 }
5989
5990 /****************************************************************
5991 ****************************************************************/
5992
5993 NTSTATUS _samr_ValidatePassword(pipes_struct *p,
5994                                 struct samr_ValidatePassword *r)
5995 {
5996         p->rng_fault_state = true;
5997         return NT_STATUS_NOT_IMPLEMENTED;
5998 }