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