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