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