e656e6c456958d9acefa23dc9b56d19139103726
[ira/wip.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         if (sid_check_is_builtin(&dinfo->sid)) {
1401                 DEBUG(5,("_samr_QueryDisplayInfo: no users in BUILTIN\n"));
1402                 return NT_STATUS_OK;
1403         }
1404
1405         /*
1406          * calculate how many entries we will return.
1407          * based on
1408          * - the number of entries the client asked
1409          * - our limit on that
1410          * - the starting point (enumeration context)
1411          * - the buffer size the client will accept
1412          */
1413
1414         /*
1415          * We are a lot more like W2K. Instead of reading the SAM
1416          * each time to find the records we need to send back,
1417          * we read it once and link that copy to the sam handle.
1418          * For large user list (over the MAX_SAM_ENTRIES)
1419          * it's a definitive win.
1420          * second point to notice: between enumerations
1421          * our sam is now the same as it's a snapshoot.
1422          * third point: got rid of the static SAM_USER_21 struct
1423          * no more intermediate.
1424          * con: it uses much more memory, as a full copy is stored
1425          * in memory.
1426          *
1427          * If you want to change it, think twice and think
1428          * of the second point , that's really important.
1429          *
1430          * JFM, 12/20/2001
1431          */
1432
1433         if ((r->in.level < 1) || (r->in.level > 5)) {
1434                 DEBUG(0,("_samr_QueryDisplayInfo: Unknown info level (%u)\n",
1435                          (unsigned int)r->in.level ));
1436                 return NT_STATUS_INVALID_INFO_CLASS;
1437         }
1438
1439         /* first limit the number of entries we will return */
1440         if(max_entries > max_sam_entries) {
1441                 DEBUG(5, ("_samr_QueryDisplayInfo: client requested %d "
1442                           "entries, limiting to %d\n", max_entries,
1443                           max_sam_entries));
1444                 max_entries = max_sam_entries;
1445         }
1446
1447         /* calculate the size and limit on the number of entries we will
1448          * return */
1449
1450         temp_size=max_entries*struct_size;
1451
1452         if (temp_size>max_size) {
1453                 max_entries=MIN((max_size/struct_size),max_entries);;
1454                 DEBUG(5, ("_samr_QueryDisplayInfo: buffer size limits to "
1455                           "only %d entries\n", max_entries));
1456         }
1457
1458         become_root();
1459
1460         /* THe following done as ROOT. Don't return without unbecome_root(). */
1461
1462         switch (r->in.level) {
1463         case 0x1:
1464         case 0x4:
1465                 if (dinfo->disp_info->users == NULL) {
1466                         dinfo->disp_info->users = pdb_search_users(
1467                                 dinfo->disp_info, ACB_NORMAL);
1468                         if (dinfo->disp_info->users == NULL) {
1469                                 unbecome_root();
1470                                 return NT_STATUS_ACCESS_DENIED;
1471                         }
1472                         DEBUG(10,("_samr_QueryDisplayInfo: starting user enumeration at index %u\n",
1473                                 (unsigned  int)enum_context ));
1474                 } else {
1475                         DEBUG(10,("_samr_QueryDisplayInfo: using cached user enumeration at index %u\n",
1476                                 (unsigned  int)enum_context ));
1477                 }
1478
1479                 num_account = pdb_search_entries(dinfo->disp_info->users,
1480                                                  enum_context, max_entries,
1481                                                  &entries);
1482                 break;
1483         case 0x2:
1484                 if (dinfo->disp_info->machines == NULL) {
1485                         dinfo->disp_info->machines = pdb_search_users(
1486                                 dinfo->disp_info, ACB_WSTRUST|ACB_SVRTRUST);
1487                         if (dinfo->disp_info->machines == NULL) {
1488                                 unbecome_root();
1489                                 return NT_STATUS_ACCESS_DENIED;
1490                         }
1491                         DEBUG(10,("_samr_QueryDisplayInfo: starting machine enumeration at index %u\n",
1492                                 (unsigned  int)enum_context ));
1493                 } else {
1494                         DEBUG(10,("_samr_QueryDisplayInfo: using cached machine enumeration at index %u\n",
1495                                 (unsigned  int)enum_context ));
1496                 }
1497
1498                 num_account = pdb_search_entries(dinfo->disp_info->machines,
1499                                                  enum_context, max_entries,
1500                                                  &entries);
1501                 break;
1502         case 0x3:
1503         case 0x5:
1504                 if (dinfo->disp_info->groups == NULL) {
1505                         dinfo->disp_info->groups = pdb_search_groups(
1506                                 dinfo->disp_info);
1507                         if (dinfo->disp_info->groups == NULL) {
1508                                 unbecome_root();
1509                                 return NT_STATUS_ACCESS_DENIED;
1510                         }
1511                         DEBUG(10,("_samr_QueryDisplayInfo: starting group enumeration at index %u\n",
1512                                 (unsigned  int)enum_context ));
1513                 } else {
1514                         DEBUG(10,("_samr_QueryDisplayInfo: using cached group enumeration at index %u\n",
1515                                 (unsigned  int)enum_context ));
1516                 }
1517
1518                 num_account = pdb_search_entries(dinfo->disp_info->groups,
1519                                                  enum_context, max_entries,
1520                                                  &entries);
1521                 break;
1522         default:
1523                 unbecome_root();
1524                 smb_panic("info class changed");
1525                 break;
1526         }
1527         unbecome_root();
1528
1529
1530         /* Now create reply structure */
1531         switch (r->in.level) {
1532         case 0x1:
1533                 disp_ret = init_samr_dispinfo_1(p->mem_ctx, &disp_info->info1,
1534                                                 num_account, enum_context,
1535                                                 entries);
1536                 break;
1537         case 0x2:
1538                 disp_ret = init_samr_dispinfo_2(p->mem_ctx, &disp_info->info2,
1539                                                 num_account, enum_context,
1540                                                 entries);
1541                 break;
1542         case 0x3:
1543                 disp_ret = init_samr_dispinfo_3(p->mem_ctx, &disp_info->info3,
1544                                                 num_account, enum_context,
1545                                                 entries);
1546                 break;
1547         case 0x4:
1548                 disp_ret = init_samr_dispinfo_4(p->mem_ctx, &disp_info->info4,
1549                                                 num_account, enum_context,
1550                                                 entries);
1551                 break;
1552         case 0x5:
1553                 disp_ret = init_samr_dispinfo_5(p->mem_ctx, &disp_info->info5,
1554                                                 num_account, enum_context,
1555                                                 entries);
1556                 break;
1557         default:
1558                 smb_panic("info class changed");
1559                 break;
1560         }
1561
1562         if (!NT_STATUS_IS_OK(disp_ret))
1563                 return disp_ret;
1564
1565         /* calculate the total size */
1566         total_data_size=num_account*struct_size;
1567
1568         if (max_entries <= num_account) {
1569                 status = STATUS_MORE_ENTRIES;
1570         } else {
1571                 status = NT_STATUS_OK;
1572         }
1573
1574         /* Ensure we cache this enumeration. */
1575         set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
1576
1577         DEBUG(5, ("_samr_QueryDisplayInfo: %d\n", __LINE__));
1578
1579         *r->out.total_size = total_data_size;
1580         *r->out.returned_size = temp_size;
1581
1582         return status;
1583 }
1584
1585 /****************************************************************
1586  _samr_QueryDisplayInfo2
1587 ****************************************************************/
1588
1589 NTSTATUS _samr_QueryDisplayInfo2(pipes_struct *p,
1590                                  struct samr_QueryDisplayInfo2 *r)
1591 {
1592         struct samr_QueryDisplayInfo q;
1593
1594         q.in.domain_handle      = r->in.domain_handle;
1595         q.in.level              = r->in.level;
1596         q.in.start_idx          = r->in.start_idx;
1597         q.in.max_entries        = r->in.max_entries;
1598         q.in.buf_size           = r->in.buf_size;
1599
1600         q.out.total_size        = r->out.total_size;
1601         q.out.returned_size     = r->out.returned_size;
1602         q.out.info              = r->out.info;
1603
1604         return _samr_QueryDisplayInfo(p, &q);
1605 }
1606
1607 /****************************************************************
1608  _samr_QueryDisplayInfo3
1609 ****************************************************************/
1610
1611 NTSTATUS _samr_QueryDisplayInfo3(pipes_struct *p,
1612                                  struct samr_QueryDisplayInfo3 *r)
1613 {
1614         struct samr_QueryDisplayInfo q;
1615
1616         q.in.domain_handle      = r->in.domain_handle;
1617         q.in.level              = r->in.level;
1618         q.in.start_idx          = r->in.start_idx;
1619         q.in.max_entries        = r->in.max_entries;
1620         q.in.buf_size           = r->in.buf_size;
1621
1622         q.out.total_size        = r->out.total_size;
1623         q.out.returned_size     = r->out.returned_size;
1624         q.out.info              = r->out.info;
1625
1626         return _samr_QueryDisplayInfo(p, &q);
1627 }
1628
1629 /*******************************************************************
1630  _samr_QueryAliasInfo
1631  ********************************************************************/
1632
1633 NTSTATUS _samr_QueryAliasInfo(pipes_struct *p,
1634                               struct samr_QueryAliasInfo *r)
1635 {
1636         struct samr_alias_info *ainfo;
1637         struct acct_info info;
1638         NTSTATUS status;
1639         union samr_AliasInfo *alias_info = NULL;
1640         const char *alias_name = NULL;
1641         const char *alias_description = NULL;
1642
1643         DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1644
1645         ainfo = policy_handle_find(p, r->in.alias_handle,
1646                                    SAMR_ALIAS_ACCESS_LOOKUP_INFO, NULL,
1647                                    struct samr_alias_info, &status);
1648         if (!NT_STATUS_IS_OK(status)) {
1649                 return status;
1650         }
1651
1652         alias_info = TALLOC_ZERO_P(p->mem_ctx, union samr_AliasInfo);
1653         if (!alias_info) {
1654                 return NT_STATUS_NO_MEMORY;
1655         }
1656
1657         become_root();
1658         status = pdb_get_aliasinfo(&ainfo->sid, &info);
1659         unbecome_root();
1660
1661         if ( !NT_STATUS_IS_OK(status))
1662                 return status;
1663
1664         /* FIXME: info contains fstrings */
1665         alias_name = talloc_strdup(r, info.acct_name);
1666         alias_description = talloc_strdup(r, info.acct_desc);
1667
1668         switch (r->in.level) {
1669         case ALIASINFOALL:
1670                 alias_info->all.name.string             = alias_name;
1671                 alias_info->all.num_members             = 1; /* ??? */
1672                 alias_info->all.description.string      = alias_description;
1673                 break;
1674         case ALIASINFODESCRIPTION:
1675                 alias_info->description.string          = alias_description;
1676                 break;
1677         default:
1678                 return NT_STATUS_INVALID_INFO_CLASS;
1679         }
1680
1681         *r->out.info = alias_info;
1682
1683         DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1684
1685         return NT_STATUS_OK;
1686 }
1687
1688 /*******************************************************************
1689  _samr_LookupNames
1690  ********************************************************************/
1691
1692 NTSTATUS _samr_LookupNames(pipes_struct *p,
1693                            struct samr_LookupNames *r)
1694 {
1695         struct samr_domain_info *dinfo;
1696         NTSTATUS status;
1697         uint32 *rid;
1698         enum lsa_SidType *type;
1699         int i;
1700         int num_rids = r->in.num_names;
1701         struct samr_Ids rids, types;
1702         uint32_t num_mapped = 0;
1703
1704         DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1705
1706         dinfo = policy_handle_find(p, r->in.domain_handle,
1707                                    0 /* Don't know the acc_bits yet */, NULL,
1708                                    struct samr_domain_info, &status);
1709         if (!NT_STATUS_IS_OK(status)) {
1710                 return status;
1711         }
1712
1713         if (num_rids > MAX_SAM_ENTRIES) {
1714                 num_rids = MAX_SAM_ENTRIES;
1715                 DEBUG(5,("_samr_LookupNames: truncating entries to %d\n", num_rids));
1716         }
1717
1718         rid = talloc_array(p->mem_ctx, uint32, num_rids);
1719         NT_STATUS_HAVE_NO_MEMORY(rid);
1720
1721         type = talloc_array(p->mem_ctx, enum lsa_SidType, num_rids);
1722         NT_STATUS_HAVE_NO_MEMORY(type);
1723
1724         DEBUG(5,("_samr_LookupNames: looking name on SID %s\n",
1725                  sid_string_dbg(&dinfo->sid)));
1726
1727         for (i = 0; i < num_rids; i++) {
1728
1729                 status = NT_STATUS_NONE_MAPPED;
1730                 type[i] = SID_NAME_UNKNOWN;
1731
1732                 rid[i] = 0xffffffff;
1733
1734                 if (sid_check_is_builtin(&dinfo->sid)) {
1735                         if (lookup_builtin_name(r->in.names[i].string,
1736                                                 &rid[i]))
1737                         {
1738                                 type[i] = SID_NAME_ALIAS;
1739                         }
1740                 } else {
1741                         lookup_global_sam_name(r->in.names[i].string, 0,
1742                                                &rid[i], &type[i]);
1743                 }
1744
1745                 if (type[i] != SID_NAME_UNKNOWN) {
1746                         num_mapped++;
1747                 }
1748         }
1749
1750         if (num_mapped == num_rids) {
1751                 status = NT_STATUS_OK;
1752         } else if (num_mapped == 0) {
1753                 status = NT_STATUS_NONE_MAPPED;
1754         } else {
1755                 status = STATUS_SOME_UNMAPPED;
1756         }
1757
1758         rids.count = num_rids;
1759         rids.ids = rid;
1760
1761         types.count = num_rids;
1762         types.ids = type;
1763
1764         *r->out.rids = rids;
1765         *r->out.types = types;
1766
1767         DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1768
1769         return status;
1770 }
1771
1772 /*******************************************************************
1773  _samr_ChangePasswordUser2
1774  ********************************************************************/
1775
1776 NTSTATUS _samr_ChangePasswordUser2(pipes_struct *p,
1777                                    struct samr_ChangePasswordUser2 *r)
1778 {
1779         NTSTATUS status;
1780         fstring user_name;
1781         fstring wks;
1782
1783         DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1784
1785         fstrcpy(user_name, r->in.account->string);
1786         fstrcpy(wks, r->in.server->string);
1787
1788         DEBUG(5,("_samr_ChangePasswordUser2: user: %s wks: %s\n", user_name, wks));
1789
1790         /*
1791          * Pass the user through the NT -> unix user mapping
1792          * function.
1793          */
1794
1795         (void)map_username(user_name);
1796
1797         /*
1798          * UNIX username case mangling not required, pass_oem_change
1799          * is case insensitive.
1800          */
1801
1802         status = pass_oem_change(user_name,
1803                                  r->in.lm_password->data,
1804                                  r->in.lm_verifier->hash,
1805                                  r->in.nt_password->data,
1806                                  r->in.nt_verifier->hash,
1807                                  NULL);
1808
1809         DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1810
1811         return status;
1812 }
1813
1814 /*******************************************************************
1815  _samr_ChangePasswordUser3
1816  ********************************************************************/
1817
1818 NTSTATUS _samr_ChangePasswordUser3(pipes_struct *p,
1819                                    struct samr_ChangePasswordUser3 *r)
1820 {
1821         NTSTATUS status;
1822         fstring user_name;
1823         const char *wks = NULL;
1824         uint32 reject_reason;
1825         struct samr_DomInfo1 *dominfo = NULL;
1826         struct samr_ChangeReject *reject = NULL;
1827         uint32_t tmp;
1828
1829         DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
1830
1831         fstrcpy(user_name, r->in.account->string);
1832         if (r->in.server && r->in.server->string) {
1833                 wks = r->in.server->string;
1834         }
1835
1836         DEBUG(5,("_samr_ChangePasswordUser3: user: %s wks: %s\n", user_name, wks));
1837
1838         /*
1839          * Pass the user through the NT -> unix user mapping
1840          * function.
1841          */
1842
1843         (void)map_username(user_name);
1844
1845         /*
1846          * UNIX username case mangling not required, pass_oem_change
1847          * is case insensitive.
1848          */
1849
1850         status = pass_oem_change(user_name,
1851                                  r->in.lm_password->data,
1852                                  r->in.lm_verifier->hash,
1853                                  r->in.nt_password->data,
1854                                  r->in.nt_verifier->hash,
1855                                  &reject_reason);
1856
1857         if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) ||
1858             NT_STATUS_EQUAL(status, NT_STATUS_ACCOUNT_RESTRICTION)) {
1859
1860                 time_t u_expire, u_min_age;
1861                 uint32 account_policy_temp;
1862
1863                 dominfo = TALLOC_ZERO_P(p->mem_ctx, struct samr_DomInfo1);
1864                 if (!dominfo) {
1865                         return NT_STATUS_NO_MEMORY;
1866                 }
1867
1868                 reject = TALLOC_ZERO_P(p->mem_ctx, struct samr_ChangeReject);
1869                 if (!reject) {
1870                         return NT_STATUS_NO_MEMORY;
1871                 }
1872
1873                 become_root();
1874
1875                 /* AS ROOT !!! */
1876
1877                 pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &tmp);
1878                 dominfo->min_password_length = tmp;
1879
1880                 pdb_get_account_policy(AP_PASSWORD_HISTORY, &tmp);
1881                 dominfo->password_history_length = tmp;
1882
1883                 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
1884                                        &dominfo->password_properties);
1885
1886                 pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
1887                 u_expire = account_policy_temp;
1888
1889                 pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
1890                 u_min_age = account_policy_temp;
1891
1892                 /* !AS ROOT */
1893
1894                 unbecome_root();
1895
1896                 unix_to_nt_time_abs((NTTIME *)&dominfo->max_password_age, u_expire);
1897                 unix_to_nt_time_abs((NTTIME *)&dominfo->min_password_age, u_min_age);
1898
1899                 if (lp_check_password_script() && *lp_check_password_script()) {
1900                         dominfo->password_properties |= DOMAIN_PASSWORD_COMPLEX;
1901                 }
1902
1903                 reject->reason = reject_reason;
1904
1905                 *r->out.dominfo = dominfo;
1906                 *r->out.reject = reject;
1907         }
1908
1909         DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
1910
1911         return status;
1912 }
1913
1914 /*******************************************************************
1915 makes a SAMR_R_LOOKUP_RIDS structure.
1916 ********************************************************************/
1917
1918 static bool make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names,
1919                                   const char **names,
1920                                   struct lsa_String **lsa_name_array_p)
1921 {
1922         struct lsa_String *lsa_name_array = NULL;
1923         uint32_t i;
1924
1925         *lsa_name_array_p = NULL;
1926
1927         if (num_names != 0) {
1928                 lsa_name_array = TALLOC_ZERO_ARRAY(ctx, struct lsa_String, num_names);
1929                 if (!lsa_name_array) {
1930                         return false;
1931                 }
1932         }
1933
1934         for (i = 0; i < num_names; i++) {
1935                 DEBUG(10, ("names[%d]:%s\n", i, names[i] && *names[i] ? names[i] : ""));
1936                 init_lsa_String(&lsa_name_array[i], names[i]);
1937         }
1938
1939         *lsa_name_array_p = lsa_name_array;
1940
1941         return true;
1942 }
1943
1944 /*******************************************************************
1945  _samr_LookupRids
1946  ********************************************************************/
1947
1948 NTSTATUS _samr_LookupRids(pipes_struct *p,
1949                           struct samr_LookupRids *r)
1950 {
1951         struct samr_domain_info *dinfo;
1952         NTSTATUS status;
1953         const char **names;
1954         enum lsa_SidType *attrs = NULL;
1955         uint32 *wire_attrs = NULL;
1956         int num_rids = (int)r->in.num_rids;
1957         int i;
1958         struct lsa_Strings names_array;
1959         struct samr_Ids types_array;
1960         struct lsa_String *lsa_names = NULL;
1961
1962         DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
1963
1964         dinfo = policy_handle_find(p, r->in.domain_handle,
1965                                    0 /* Don't know the acc_bits yet */, NULL,
1966                                    struct samr_domain_info, &status);
1967         if (!NT_STATUS_IS_OK(status)) {
1968                 return status;
1969         }
1970
1971         if (num_rids > 1000) {
1972                 DEBUG(0, ("Got asked for %d rids (more than 1000) -- according "
1973                           "to samba4 idl this is not possible\n", num_rids));
1974                 return NT_STATUS_UNSUCCESSFUL;
1975         }
1976
1977         if (num_rids) {
1978                 names = TALLOC_ZERO_ARRAY(p->mem_ctx, const char *, num_rids);
1979                 attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, enum lsa_SidType, num_rids);
1980                 wire_attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_rids);
1981
1982                 if ((names == NULL) || (attrs == NULL) || (wire_attrs==NULL))
1983                         return NT_STATUS_NO_MEMORY;
1984         } else {
1985                 names = NULL;
1986                 attrs = NULL;
1987                 wire_attrs = NULL;
1988         }
1989
1990         become_root();  /* lookup_sid can require root privs */
1991         status = pdb_lookup_rids(&dinfo->sid, num_rids, r->in.rids,
1992                                  names, attrs);
1993         unbecome_root();
1994
1995         if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED) && (num_rids == 0)) {
1996                 status = NT_STATUS_OK;
1997         }
1998
1999         if (!make_samr_lookup_rids(p->mem_ctx, num_rids, names,
2000                                    &lsa_names)) {
2001                 return NT_STATUS_NO_MEMORY;
2002         }
2003
2004         /* Convert from enum lsa_SidType to uint32 for wire format. */
2005         for (i = 0; i < num_rids; i++) {
2006                 wire_attrs[i] = (uint32)attrs[i];
2007         }
2008
2009         names_array.count = num_rids;
2010         names_array.names = lsa_names;
2011
2012         types_array.count = num_rids;
2013         types_array.ids = wire_attrs;
2014
2015         *r->out.names = names_array;
2016         *r->out.types = types_array;
2017
2018         DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2019
2020         return status;
2021 }
2022
2023 /*******************************************************************
2024  _samr_OpenUser
2025 ********************************************************************/
2026
2027 NTSTATUS _samr_OpenUser(pipes_struct *p,
2028                         struct samr_OpenUser *r)
2029 {
2030         struct samu *sampass=NULL;
2031         DOM_SID sid;
2032         struct samr_domain_info *dinfo;
2033         struct samr_user_info *uinfo;
2034         SEC_DESC *psd = NULL;
2035         uint32    acc_granted;
2036         uint32    des_access = r->in.access_mask;
2037         size_t    sd_size;
2038         bool ret;
2039         NTSTATUS nt_status;
2040         SE_PRIV se_rights;
2041         NTSTATUS status;
2042
2043         dinfo = policy_handle_find(p, r->in.domain_handle,
2044                                    SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
2045                                    struct samr_domain_info, &status);
2046         if (!NT_STATUS_IS_OK(status)) {
2047                 return status;
2048         }
2049
2050         if ( !(sampass = samu_new( p->mem_ctx )) ) {
2051                 return NT_STATUS_NO_MEMORY;
2052         }
2053
2054         /* append the user's RID to it */
2055
2056         if (!sid_compose(&sid, &dinfo->sid, r->in.rid))
2057                 return NT_STATUS_NO_SUCH_USER;
2058
2059         /* check if access can be granted as requested by client. */
2060
2061         map_max_allowed_access(p->server_info->ptok, &des_access);
2062
2063         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &sid, SAMR_USR_RIGHTS_WRITE_PW);
2064         se_map_generic(&des_access, &usr_generic_mapping);
2065
2066         se_priv_copy( &se_rights, &se_machine_account );
2067         se_priv_add( &se_rights, &se_add_users );
2068
2069         nt_status = access_check_samr_object(psd, p->server_info->ptok,
2070                 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
2071                 &acc_granted, "_samr_OpenUser");
2072
2073         if ( !NT_STATUS_IS_OK(nt_status) )
2074                 return nt_status;
2075
2076         become_root();
2077         ret=pdb_getsampwsid(sampass, &sid);
2078         unbecome_root();
2079
2080         /* check that the SID exists in our domain. */
2081         if (ret == False) {
2082                 return NT_STATUS_NO_SUCH_USER;
2083         }
2084
2085         TALLOC_FREE(sampass);
2086
2087         uinfo = policy_handle_create(p, r->out.user_handle, acc_granted,
2088                                      struct samr_user_info, &nt_status);
2089         if (!NT_STATUS_IS_OK(nt_status)) {
2090                 return nt_status;
2091         }
2092         uinfo->sid = sid;
2093
2094         return NT_STATUS_OK;
2095 }
2096
2097 /*************************************************************************
2098  *************************************************************************/
2099
2100 static NTSTATUS init_samr_parameters_string(TALLOC_CTX *mem_ctx,
2101                                             DATA_BLOB *blob,
2102                                             struct lsa_BinaryString **_r)
2103 {
2104         struct lsa_BinaryString *r;
2105
2106         if (!blob || !_r) {
2107                 return NT_STATUS_INVALID_PARAMETER;
2108         }
2109
2110         r = TALLOC_ZERO_P(mem_ctx, struct lsa_BinaryString);
2111         if (!r) {
2112                 return NT_STATUS_NO_MEMORY;
2113         }
2114
2115         r->array = TALLOC_ZERO_ARRAY(mem_ctx, uint16_t, blob->length/2);
2116         if (!r->array) {
2117                 return NT_STATUS_NO_MEMORY;
2118         }
2119         memcpy(r->array, blob->data, blob->length);
2120         r->size = blob->length;
2121         r->length = blob->length;
2122
2123         if (!r->array) {
2124                 return NT_STATUS_NO_MEMORY;
2125         }
2126
2127         *_r = r;
2128
2129         return NT_STATUS_OK;
2130 }
2131
2132 /*************************************************************************
2133  get_user_info_1.
2134  *************************************************************************/
2135
2136 static NTSTATUS get_user_info_1(TALLOC_CTX *mem_ctx,
2137                                 struct samr_UserInfo1 *r,
2138                                 struct samu *pw,
2139                                 DOM_SID *domain_sid)
2140 {
2141         const DOM_SID *sid_group;
2142         uint32_t primary_gid;
2143
2144         become_root();
2145         sid_group = pdb_get_group_sid(pw);
2146         unbecome_root();
2147
2148         if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2149                 DEBUG(0, ("get_user_info_1: User %s has Primary Group SID %s, \n"
2150                           "which conflicts with the domain sid %s.  Failing operation.\n",
2151                           pdb_get_username(pw), sid_string_dbg(sid_group),
2152                           sid_string_dbg(domain_sid)));
2153                 return NT_STATUS_UNSUCCESSFUL;
2154         }
2155
2156         r->account_name.string          = talloc_strdup(mem_ctx, pdb_get_username(pw));
2157         r->full_name.string             = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2158         r->primary_gid                  = primary_gid;
2159         r->description.string           = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2160         r->comment.string               = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2161
2162         return NT_STATUS_OK;
2163 }
2164
2165 /*************************************************************************
2166  get_user_info_2.
2167  *************************************************************************/
2168
2169 static NTSTATUS get_user_info_2(TALLOC_CTX *mem_ctx,
2170                                 struct samr_UserInfo2 *r,
2171                                 struct samu *pw)
2172 {
2173         r->comment.string               = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2174         r->unknown.string               = NULL;
2175         r->country_code                 = 0;
2176         r->code_page                    = 0;
2177
2178         return NT_STATUS_OK;
2179 }
2180
2181 /*************************************************************************
2182  get_user_info_3.
2183  *************************************************************************/
2184
2185 static NTSTATUS get_user_info_3(TALLOC_CTX *mem_ctx,
2186                                 struct samr_UserInfo3 *r,
2187                                 struct samu *pw,
2188                                 DOM_SID *domain_sid)
2189 {
2190         const DOM_SID *sid_user, *sid_group;
2191         uint32_t rid, primary_gid;
2192
2193         sid_user = pdb_get_user_sid(pw);
2194
2195         if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2196                 DEBUG(0, ("get_user_info_3: User %s has SID %s, \nwhich conflicts with "
2197                           "the domain sid %s.  Failing operation.\n",
2198                           pdb_get_username(pw), sid_string_dbg(sid_user),
2199                           sid_string_dbg(domain_sid)));
2200                 return NT_STATUS_UNSUCCESSFUL;
2201         }
2202
2203         become_root();
2204         sid_group = pdb_get_group_sid(pw);
2205         unbecome_root();
2206
2207         if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2208                 DEBUG(0, ("get_user_info_3: User %s has Primary Group SID %s, \n"
2209                           "which conflicts with the domain sid %s.  Failing operation.\n",
2210                           pdb_get_username(pw), sid_string_dbg(sid_group),
2211                           sid_string_dbg(domain_sid)));
2212                 return NT_STATUS_UNSUCCESSFUL;
2213         }
2214
2215         unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2216         unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2217         unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2218         unix_to_nt_time(&r->allow_password_change, pdb_get_pass_can_change_time(pw));
2219         unix_to_nt_time(&r->force_password_change, pdb_get_pass_must_change_time(pw));
2220
2221         r->account_name.string  = talloc_strdup(mem_ctx, pdb_get_username(pw));
2222         r->full_name.string     = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2223         r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2224         r->home_drive.string    = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2225         r->logon_script.string  = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2226         r->profile_path.string  = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2227         r->workstations.string  = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2228
2229         r->logon_hours          = get_logon_hours_from_pdb(mem_ctx, pw);
2230         r->rid                  = rid;
2231         r->primary_gid          = primary_gid;
2232         r->acct_flags           = pdb_get_acct_ctrl(pw);
2233         r->bad_password_count   = pdb_get_bad_password_count(pw);
2234         r->logon_count          = pdb_get_logon_count(pw);
2235
2236         return NT_STATUS_OK;
2237 }
2238
2239 /*************************************************************************
2240  get_user_info_4.
2241  *************************************************************************/
2242
2243 static NTSTATUS get_user_info_4(TALLOC_CTX *mem_ctx,
2244                                 struct samr_UserInfo4 *r,
2245                                 struct samu *pw)
2246 {
2247         r->logon_hours          = get_logon_hours_from_pdb(mem_ctx, pw);
2248
2249         return NT_STATUS_OK;
2250 }
2251
2252 /*************************************************************************
2253  get_user_info_5.
2254  *************************************************************************/
2255
2256 static NTSTATUS get_user_info_5(TALLOC_CTX *mem_ctx,
2257                                 struct samr_UserInfo5 *r,
2258                                 struct samu *pw,
2259                                 DOM_SID *domain_sid)
2260 {
2261         const DOM_SID *sid_user, *sid_group;
2262         uint32_t rid, primary_gid;
2263
2264         sid_user = pdb_get_user_sid(pw);
2265
2266         if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2267                 DEBUG(0, ("get_user_info_5: User %s has SID %s, \nwhich conflicts with "
2268                           "the domain sid %s.  Failing operation.\n",
2269                           pdb_get_username(pw), sid_string_dbg(sid_user),
2270                           sid_string_dbg(domain_sid)));
2271                 return NT_STATUS_UNSUCCESSFUL;
2272         }
2273
2274         become_root();
2275         sid_group = pdb_get_group_sid(pw);
2276         unbecome_root();
2277
2278         if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2279                 DEBUG(0, ("get_user_info_5: User %s has Primary Group SID %s, \n"
2280                           "which conflicts with the domain sid %s.  Failing operation.\n",
2281                           pdb_get_username(pw), sid_string_dbg(sid_group),
2282                           sid_string_dbg(domain_sid)));
2283                 return NT_STATUS_UNSUCCESSFUL;
2284         }
2285
2286         unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2287         unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2288         unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2289         unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2290
2291         r->account_name.string  = talloc_strdup(mem_ctx, pdb_get_username(pw));
2292         r->full_name.string     = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2293         r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2294         r->home_drive.string    = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2295         r->logon_script.string  = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2296         r->profile_path.string  = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2297         r->description.string   = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2298         r->workstations.string  = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2299
2300         r->logon_hours          = get_logon_hours_from_pdb(mem_ctx, pw);
2301         r->rid                  = rid;
2302         r->primary_gid          = primary_gid;
2303         r->acct_flags           = pdb_get_acct_ctrl(pw);
2304         r->bad_password_count   = pdb_get_bad_password_count(pw);
2305         r->logon_count          = pdb_get_logon_count(pw);
2306
2307         return NT_STATUS_OK;
2308 }
2309
2310 /*************************************************************************
2311  get_user_info_6.
2312  *************************************************************************/
2313
2314 static NTSTATUS get_user_info_6(TALLOC_CTX *mem_ctx,
2315                                 struct samr_UserInfo6 *r,
2316                                 struct samu *pw)
2317 {
2318         r->account_name.string  = talloc_strdup(mem_ctx, pdb_get_username(pw));
2319         r->full_name.string     = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2320
2321         return NT_STATUS_OK;
2322 }
2323
2324 /*************************************************************************
2325  get_user_info_7. Safe. Only gives out account_name.
2326  *************************************************************************/
2327
2328 static NTSTATUS get_user_info_7(TALLOC_CTX *mem_ctx,
2329                                 struct samr_UserInfo7 *r,
2330                                 struct samu *smbpass)
2331 {
2332         r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(smbpass));
2333         if (!r->account_name.string) {
2334                 return NT_STATUS_NO_MEMORY;
2335         }
2336
2337         return NT_STATUS_OK;
2338 }
2339
2340 /*************************************************************************
2341  get_user_info_8.
2342  *************************************************************************/
2343
2344 static NTSTATUS get_user_info_8(TALLOC_CTX *mem_ctx,
2345                                 struct samr_UserInfo8 *r,
2346                                 struct samu *pw)
2347 {
2348         r->full_name.string     = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2349
2350         return NT_STATUS_OK;
2351 }
2352
2353 /*************************************************************************
2354  get_user_info_9. Only gives out primary group SID.
2355  *************************************************************************/
2356
2357 static NTSTATUS get_user_info_9(TALLOC_CTX *mem_ctx,
2358                                 struct samr_UserInfo9 *r,
2359                                 struct samu *smbpass)
2360 {
2361         r->primary_gid = pdb_get_group_rid(smbpass);
2362
2363         return NT_STATUS_OK;
2364 }
2365
2366 /*************************************************************************
2367  get_user_info_10.
2368  *************************************************************************/
2369
2370 static NTSTATUS get_user_info_10(TALLOC_CTX *mem_ctx,
2371                                  struct samr_UserInfo10 *r,
2372                                  struct samu *pw)
2373 {
2374         r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2375         r->home_drive.string    = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2376
2377         return NT_STATUS_OK;
2378 }
2379
2380 /*************************************************************************
2381  get_user_info_11.
2382  *************************************************************************/
2383
2384 static NTSTATUS get_user_info_11(TALLOC_CTX *mem_ctx,
2385                                  struct samr_UserInfo11 *r,
2386                                  struct samu *pw)
2387 {
2388         r->logon_script.string  = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2389
2390         return NT_STATUS_OK;
2391 }
2392
2393 /*************************************************************************
2394  get_user_info_12.
2395  *************************************************************************/
2396
2397 static NTSTATUS get_user_info_12(TALLOC_CTX *mem_ctx,
2398                                  struct samr_UserInfo12 *r,
2399                                  struct samu *pw)
2400 {
2401         r->profile_path.string  = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2402
2403         return NT_STATUS_OK;
2404 }
2405
2406 /*************************************************************************
2407  get_user_info_13.
2408  *************************************************************************/
2409
2410 static NTSTATUS get_user_info_13(TALLOC_CTX *mem_ctx,
2411                                  struct samr_UserInfo13 *r,
2412                                  struct samu *pw)
2413 {
2414         r->description.string   = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2415
2416         return NT_STATUS_OK;
2417 }
2418
2419 /*************************************************************************
2420  get_user_info_14.
2421  *************************************************************************/
2422
2423 static NTSTATUS get_user_info_14(TALLOC_CTX *mem_ctx,
2424                                  struct samr_UserInfo14 *r,
2425                                  struct samu *pw)
2426 {
2427         r->workstations.string  = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2428
2429         return NT_STATUS_OK;
2430 }
2431
2432 /*************************************************************************
2433  get_user_info_16. Safe. Only gives out acb bits.
2434  *************************************************************************/
2435
2436 static NTSTATUS get_user_info_16(TALLOC_CTX *mem_ctx,
2437                                  struct samr_UserInfo16 *r,
2438                                  struct samu *smbpass)
2439 {
2440         r->acct_flags = pdb_get_acct_ctrl(smbpass);
2441
2442         return NT_STATUS_OK;
2443 }
2444
2445 /*************************************************************************
2446  get_user_info_17.
2447  *************************************************************************/
2448
2449 static NTSTATUS get_user_info_17(TALLOC_CTX *mem_ctx,
2450                                  struct samr_UserInfo17 *r,
2451                                  struct samu *pw)
2452 {
2453         unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2454
2455         return NT_STATUS_OK;
2456 }
2457
2458 /*************************************************************************
2459  get_user_info_18. OK - this is the killer as it gives out password info.
2460  Ensure that this is only allowed on an encrypted connection with a root
2461  user. JRA.
2462  *************************************************************************/
2463
2464 static NTSTATUS get_user_info_18(pipes_struct *p,
2465                                  TALLOC_CTX *mem_ctx,
2466                                  struct samr_UserInfo18 *r,
2467                                  DOM_SID *user_sid)
2468 {
2469         struct samu *smbpass=NULL;
2470         bool ret;
2471
2472         ZERO_STRUCTP(r);
2473
2474         if (p->auth.auth_type != PIPE_AUTH_TYPE_NTLMSSP || p->auth.auth_type != PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) {
2475                 return NT_STATUS_ACCESS_DENIED;
2476         }
2477
2478         if (p->auth.auth_level != PIPE_AUTH_LEVEL_PRIVACY) {
2479                 return NT_STATUS_ACCESS_DENIED;
2480         }
2481
2482         /*
2483          * Do *NOT* do become_root()/unbecome_root() here ! JRA.
2484          */
2485
2486         if ( !(smbpass = samu_new( mem_ctx )) ) {
2487                 return NT_STATUS_NO_MEMORY;
2488         }
2489
2490         ret = pdb_getsampwsid(smbpass, user_sid);
2491
2492         if (ret == False) {
2493                 DEBUG(4, ("User %s not found\n", sid_string_dbg(user_sid)));
2494                 TALLOC_FREE(smbpass);
2495                 return (geteuid() == (uid_t)0) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
2496         }
2497
2498         DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
2499
2500         if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
2501                 TALLOC_FREE(smbpass);
2502                 return NT_STATUS_ACCOUNT_DISABLED;
2503         }
2504
2505         r->lm_pwd_active = true;
2506         r->nt_pwd_active = true;
2507         memcpy(r->lm_pwd.hash, pdb_get_lanman_passwd(smbpass), 16);
2508         memcpy(r->nt_pwd.hash, pdb_get_nt_passwd(smbpass), 16);
2509         r->password_expired = 0; /* FIXME */
2510
2511         TALLOC_FREE(smbpass);
2512
2513         return NT_STATUS_OK;
2514 }
2515
2516 /*************************************************************************
2517  get_user_info_20
2518  *************************************************************************/
2519
2520 static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx,
2521                                  struct samr_UserInfo20 *r,
2522                                  struct samu *sampass)
2523 {
2524         const char *munged_dial = NULL;
2525         DATA_BLOB blob;
2526         NTSTATUS status;
2527         struct lsa_BinaryString *parameters = NULL;
2528
2529         ZERO_STRUCTP(r);
2530
2531         munged_dial = pdb_get_munged_dial(sampass);
2532
2533         DEBUG(3,("User:[%s] has [%s] (length: %d)\n", pdb_get_username(sampass),
2534                 munged_dial, (int)strlen(munged_dial)));
2535
2536         if (munged_dial) {
2537                 blob = base64_decode_data_blob(munged_dial);
2538         } else {
2539                 blob = data_blob_string_const_null("");
2540         }
2541
2542         status = init_samr_parameters_string(mem_ctx, &blob, &parameters);
2543         data_blob_free(&blob);
2544         if (!NT_STATUS_IS_OK(status)) {
2545                 return status;
2546         }
2547
2548         r->parameters = *parameters;
2549
2550         return NT_STATUS_OK;
2551 }
2552
2553
2554 /*************************************************************************
2555  get_user_info_21
2556  *************************************************************************/
2557
2558 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx,
2559                                  struct samr_UserInfo21 *r,
2560                                  struct samu *pw,
2561                                  DOM_SID *domain_sid)
2562 {
2563         NTSTATUS status;
2564         const DOM_SID *sid_user, *sid_group;
2565         uint32_t rid, primary_gid;
2566         NTTIME force_password_change;
2567         time_t must_change_time;
2568         struct lsa_BinaryString *parameters = NULL;
2569         const char *munged_dial = NULL;
2570         DATA_BLOB blob;
2571
2572         ZERO_STRUCTP(r);
2573
2574         sid_user = pdb_get_user_sid(pw);
2575
2576         if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2577                 DEBUG(0, ("get_user_info_21: User %s has SID %s, \nwhich conflicts with "
2578                           "the domain sid %s.  Failing operation.\n",
2579                           pdb_get_username(pw), sid_string_dbg(sid_user),
2580                           sid_string_dbg(domain_sid)));
2581                 return NT_STATUS_UNSUCCESSFUL;
2582         }
2583
2584         become_root();
2585         sid_group = pdb_get_group_sid(pw);
2586         unbecome_root();
2587
2588         if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2589                 DEBUG(0, ("get_user_info_21: User %s has Primary Group SID %s, \n"
2590                           "which conflicts with the domain sid %s.  Failing operation.\n",
2591                           pdb_get_username(pw), sid_string_dbg(sid_group),
2592                           sid_string_dbg(domain_sid)));
2593                 return NT_STATUS_UNSUCCESSFUL;
2594         }
2595
2596         unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2597         unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2598         unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2599         unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2600         unix_to_nt_time(&r->allow_password_change, pdb_get_pass_can_change_time(pw));
2601
2602         must_change_time = pdb_get_pass_must_change_time(pw);
2603         if (must_change_time == get_time_t_max()) {
2604                 unix_to_nt_time_abs(&force_password_change, must_change_time);
2605         } else {
2606                 unix_to_nt_time(&force_password_change, must_change_time);
2607         }
2608
2609         munged_dial = pdb_get_munged_dial(pw);
2610         if (munged_dial) {
2611                 blob = base64_decode_data_blob(munged_dial);
2612         } else {
2613                 blob = data_blob_string_const_null("");
2614         }
2615
2616         status = init_samr_parameters_string(mem_ctx, &blob, &parameters);
2617         data_blob_free(&blob);
2618         if (!NT_STATUS_IS_OK(status)) {
2619                 return status;
2620         }
2621
2622         r->force_password_change        = force_password_change;
2623
2624         r->account_name.string          = talloc_strdup(mem_ctx, pdb_get_username(pw));
2625         r->full_name.string             = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2626         r->home_directory.string        = talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2627         r->home_drive.string            = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2628         r->logon_script.string          = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2629         r->profile_path.string          = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2630         r->description.string           = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2631         r->workstations.string          = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2632         r->comment.string               = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2633
2634         r->logon_hours                  = get_logon_hours_from_pdb(mem_ctx, pw);
2635         r->parameters                   = *parameters;
2636         r->rid                          = rid;
2637         r->primary_gid                  = primary_gid;
2638         r->acct_flags                   = pdb_get_acct_ctrl(pw);
2639         r->bad_password_count           = pdb_get_bad_password_count(pw);
2640         r->logon_count                  = pdb_get_logon_count(pw);
2641         r->fields_present               = pdb_build_fields_present(pw);
2642         r->password_expired             = (pdb_get_pass_must_change_time(pw) == 0) ?
2643                                                 PASS_MUST_CHANGE_AT_NEXT_LOGON : 0;
2644         r->country_code                 = 0;
2645         r->code_page                    = 0;
2646         r->lm_password_set              = 0;
2647         r->nt_password_set              = 0;
2648
2649 #if 0
2650
2651         /*
2652           Look at a user on a real NT4 PDC with usrmgr, press
2653           'ok'. Then you will see that fields_present is set to
2654           0x08f827fa. Look at the user immediately after that again,
2655           and you will see that 0x00fffff is returned. This solves
2656           the problem that you get access denied after having looked
2657           at the user.
2658           -- Volker
2659         */
2660
2661 #endif
2662
2663
2664         return NT_STATUS_OK;
2665 }
2666
2667 /*******************************************************************
2668  _samr_QueryUserInfo
2669  ********************************************************************/
2670
2671 NTSTATUS _samr_QueryUserInfo(pipes_struct *p,
2672                              struct samr_QueryUserInfo *r)
2673 {
2674         NTSTATUS status;
2675         union samr_UserInfo *user_info = NULL;
2676         struct samr_user_info *uinfo;
2677         DOM_SID domain_sid;
2678         uint32 rid;
2679         bool ret = false;
2680         struct samu *pwd = NULL;
2681
2682         uinfo = policy_handle_find(p, r->in.user_handle,
2683                                    SAMR_USER_ACCESS_GET_ATTRIBUTES, NULL,
2684                                    struct samr_user_info, &status);
2685         if (!NT_STATUS_IS_OK(status)) {
2686                 return status;
2687         }
2688
2689         domain_sid = uinfo->sid;
2690
2691         sid_split_rid(&domain_sid, &rid);
2692
2693         if (!sid_check_is_in_our_domain(&uinfo->sid))
2694                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2695
2696         DEBUG(5,("_samr_QueryUserInfo: sid:%s\n",
2697                  sid_string_dbg(&uinfo->sid)));
2698
2699         user_info = TALLOC_ZERO_P(p->mem_ctx, union samr_UserInfo);
2700         if (!user_info) {
2701                 return NT_STATUS_NO_MEMORY;
2702         }
2703
2704         DEBUG(5,("_samr_QueryUserInfo: user info level: %d\n", r->in.level));
2705
2706         if (!(pwd = samu_new(p->mem_ctx))) {
2707                 return NT_STATUS_NO_MEMORY;
2708         }
2709
2710         become_root();
2711         ret = pdb_getsampwsid(pwd, &uinfo->sid);
2712         unbecome_root();
2713
2714         if (ret == false) {
2715                 DEBUG(4,("User %s not found\n", sid_string_dbg(&uinfo->sid)));
2716                 TALLOC_FREE(pwd);
2717                 return NT_STATUS_NO_SUCH_USER;
2718         }
2719
2720         DEBUG(3,("User:[%s]\n", pdb_get_username(pwd)));
2721
2722         samr_clear_sam_passwd(pwd);
2723
2724         switch (r->in.level) {
2725         case 1:
2726                 status = get_user_info_1(p->mem_ctx, &user_info->info1, pwd, &domain_sid);
2727                 break;
2728         case 2:
2729                 status = get_user_info_2(p->mem_ctx, &user_info->info2, pwd);
2730                 break;
2731         case 3:
2732                 status = get_user_info_3(p->mem_ctx, &user_info->info3, pwd, &domain_sid);
2733                 break;
2734         case 4:
2735                 status = get_user_info_4(p->mem_ctx, &user_info->info4, pwd);
2736                 break;
2737         case 5:
2738                 status = get_user_info_5(p->mem_ctx, &user_info->info5, pwd, &domain_sid);
2739                 break;
2740         case 6:
2741                 status = get_user_info_6(p->mem_ctx, &user_info->info6, pwd);
2742                 break;
2743         case 7:
2744                 status = get_user_info_7(p->mem_ctx, &user_info->info7, pwd);
2745                 break;
2746         case 8:
2747                 status = get_user_info_8(p->mem_ctx, &user_info->info8, pwd);
2748                 break;
2749         case 9:
2750                 status = get_user_info_9(p->mem_ctx, &user_info->info9, pwd);
2751                 break;
2752         case 10:
2753                 status = get_user_info_10(p->mem_ctx, &user_info->info10, pwd);
2754                 break;
2755         case 11:
2756                 status = get_user_info_11(p->mem_ctx, &user_info->info11, pwd);
2757                 break;
2758         case 12:
2759                 status = get_user_info_12(p->mem_ctx, &user_info->info12, pwd);
2760                 break;
2761         case 13:
2762                 status = get_user_info_13(p->mem_ctx, &user_info->info13, pwd);
2763                 break;
2764         case 14:
2765                 status = get_user_info_14(p->mem_ctx, &user_info->info14, pwd);
2766                 break;
2767         case 16:
2768                 status = get_user_info_16(p->mem_ctx, &user_info->info16, pwd);
2769                 break;
2770         case 17:
2771                 status = get_user_info_17(p->mem_ctx, &user_info->info17, pwd);
2772                 break;
2773         case 18:
2774                 /* level 18 is special */
2775                 status = get_user_info_18(p, p->mem_ctx, &user_info->info18,
2776                                           &uinfo->sid);
2777                 break;
2778         case 20:
2779                 status = get_user_info_20(p->mem_ctx, &user_info->info20, pwd);
2780                 break;
2781         case 21:
2782                 status = get_user_info_21(p->mem_ctx, &user_info->info21, pwd, &domain_sid);
2783                 break;
2784         default:
2785                 status = NT_STATUS_INVALID_INFO_CLASS;
2786                 break;
2787         }
2788
2789         TALLOC_FREE(pwd);
2790
2791         *r->out.info = user_info;
2792
2793         DEBUG(5,("_samr_QueryUserInfo: %d\n", __LINE__));
2794
2795         return status;
2796 }
2797
2798 /****************************************************************
2799 ****************************************************************/
2800
2801 NTSTATUS _samr_QueryUserInfo2(pipes_struct *p,
2802                               struct samr_QueryUserInfo2 *r)
2803 {
2804         struct samr_QueryUserInfo u;
2805
2806         u.in.user_handle        = r->in.user_handle;
2807         u.in.level              = r->in.level;
2808         u.out.info              = r->out.info;
2809
2810         return _samr_QueryUserInfo(p, &u);
2811 }
2812
2813 /*******************************************************************
2814  _samr_GetGroupsForUser
2815  ********************************************************************/
2816
2817 NTSTATUS _samr_GetGroupsForUser(pipes_struct *p,
2818                                 struct samr_GetGroupsForUser *r)
2819 {
2820         struct samr_user_info *uinfo;
2821         struct samu *sam_pass=NULL;
2822         DOM_SID *sids;
2823         struct samr_RidWithAttribute dom_gid;
2824         struct samr_RidWithAttribute *gids = NULL;
2825         uint32 primary_group_rid;
2826         size_t num_groups = 0;
2827         gid_t *unix_gids;
2828         size_t i, num_gids;
2829         bool ret;
2830         NTSTATUS result;
2831         bool success = False;
2832
2833         struct samr_RidWithAttributeArray *rids = NULL;
2834
2835         /*
2836          * from the SID in the request:
2837          * we should send back the list of DOMAIN GROUPS
2838          * the user is a member of
2839          *
2840          * and only the DOMAIN GROUPS
2841          * no ALIASES !!! neither aliases of the domain
2842          * nor aliases of the builtin SID
2843          *
2844          * JFM, 12/2/2001
2845          */
2846
2847         DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
2848
2849         uinfo = policy_handle_find(p, r->in.user_handle,
2850                                    SAMR_USER_ACCESS_GET_GROUPS, NULL,
2851                                    struct samr_user_info, &result);
2852         if (!NT_STATUS_IS_OK(result)) {
2853                 return result;
2854         }
2855
2856         rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidWithAttributeArray);
2857         if (!rids) {
2858                 return NT_STATUS_NO_MEMORY;
2859         }
2860
2861         if (!sid_check_is_in_our_domain(&uinfo->sid))
2862                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2863
2864         if ( !(sam_pass = samu_new( p->mem_ctx )) ) {
2865                 return NT_STATUS_NO_MEMORY;
2866         }
2867
2868         become_root();
2869         ret = pdb_getsampwsid(sam_pass, &uinfo->sid);
2870         unbecome_root();
2871
2872         if (!ret) {
2873                 DEBUG(10, ("pdb_getsampwsid failed for %s\n",
2874                            sid_string_dbg(&uinfo->sid)));
2875                 return NT_STATUS_NO_SUCH_USER;
2876         }
2877
2878         sids = NULL;
2879
2880         /* make both calls inside the root block */
2881         become_root();
2882         result = pdb_enum_group_memberships(p->mem_ctx, sam_pass,
2883                                             &sids, &unix_gids, &num_groups);
2884         if ( NT_STATUS_IS_OK(result) ) {
2885                 success = sid_peek_check_rid(get_global_sam_sid(),
2886                                              pdb_get_group_sid(sam_pass),
2887                                              &primary_group_rid);
2888         }
2889         unbecome_root();
2890
2891         if (!NT_STATUS_IS_OK(result)) {
2892                 DEBUG(10, ("pdb_enum_group_memberships failed for %s\n",
2893                            sid_string_dbg(&uinfo->sid)));
2894                 return result;
2895         }
2896
2897         if ( !success ) {
2898                 DEBUG(5, ("Group sid %s for user %s not in our domain\n",
2899                           sid_string_dbg(pdb_get_group_sid(sam_pass)),
2900                           pdb_get_username(sam_pass)));
2901                 TALLOC_FREE(sam_pass);
2902                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2903         }
2904
2905         gids = NULL;
2906         num_gids = 0;
2907
2908         dom_gid.attributes = (SE_GROUP_MANDATORY|SE_GROUP_ENABLED_BY_DEFAULT|
2909                               SE_GROUP_ENABLED);
2910         dom_gid.rid = primary_group_rid;
2911         ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
2912
2913         for (i=0; i<num_groups; i++) {
2914
2915                 if (!sid_peek_check_rid(get_global_sam_sid(),
2916                                         &(sids[i]), &dom_gid.rid)) {
2917                         DEBUG(10, ("Found sid %s not in our domain\n",
2918                                    sid_string_dbg(&sids[i])));
2919                         continue;
2920                 }
2921
2922                 if (dom_gid.rid == primary_group_rid) {
2923                         /* We added the primary group directly from the
2924                          * sam_account. The other SIDs are unique from
2925                          * enum_group_memberships */
2926                         continue;
2927                 }
2928
2929                 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
2930         }
2931
2932         rids->count = num_gids;
2933         rids->rids = gids;
2934
2935         *r->out.rids = rids;
2936
2937         DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
2938
2939         return result;
2940 }
2941
2942 /*******************************************************************
2943  _samr_QueryDomainInfo
2944  ********************************************************************/
2945
2946 NTSTATUS _samr_QueryDomainInfo(pipes_struct *p,
2947                                struct samr_QueryDomainInfo *r)
2948 {
2949         NTSTATUS status = NT_STATUS_OK;
2950         struct samr_domain_info *dinfo;
2951         union samr_DomainInfo *dom_info;
2952         time_t u_expire, u_min_age;
2953
2954         time_t u_lock_duration, u_reset_time;
2955         uint32_t u_logout;
2956
2957         uint32 account_policy_temp;
2958
2959         time_t seq_num;
2960         uint32 server_role;
2961
2962         DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__));
2963
2964         dinfo = policy_handle_find(p, r->in.domain_handle,
2965                                    SAMR_ACCESS_LOOKUP_DOMAIN, NULL,
2966                                    struct samr_domain_info, &status);
2967         if (!NT_STATUS_IS_OK(status)) {
2968                 return status;
2969         }
2970
2971         dom_info = TALLOC_ZERO_P(p->mem_ctx, union samr_DomainInfo);
2972         if (!dom_info) {
2973                 return NT_STATUS_NO_MEMORY;
2974         }
2975
2976         switch (r->in.level) {
2977                 case 0x01:
2978
2979                         become_root();
2980
2981                         /* AS ROOT !!! */
2982
2983                         pdb_get_account_policy(AP_MIN_PASSWORD_LEN,
2984                                                &account_policy_temp);
2985                         dom_info->info1.min_password_length = account_policy_temp;
2986
2987                         pdb_get_account_policy(AP_PASSWORD_HISTORY, &account_policy_temp);
2988                         dom_info->info1.password_history_length = account_policy_temp;
2989
2990                         pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
2991                                 &dom_info->info1.password_properties);
2992
2993                         pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
2994                         u_expire = account_policy_temp;
2995
2996                         pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
2997                         u_min_age = account_policy_temp;
2998
2999                         /* !AS ROOT */
3000
3001                         unbecome_root();
3002
3003                         unix_to_nt_time_abs((NTTIME *)&dom_info->info1.max_password_age, u_expire);
3004                         unix_to_nt_time_abs((NTTIME *)&dom_info->info1.min_password_age, u_min_age);
3005
3006                         if (lp_check_password_script() && *lp_check_password_script()) {
3007                                 dom_info->info1.password_properties |= DOMAIN_PASSWORD_COMPLEX;
3008                         }
3009
3010                         break;
3011                 case 0x02:
3012
3013                         become_root();
3014
3015                         /* AS ROOT !!! */
3016
3017                         dom_info->general.num_users     = count_sam_users(
3018                                 dinfo->disp_info, ACB_NORMAL);
3019                         dom_info->general.num_groups    = count_sam_groups(
3020                                 dinfo->disp_info);
3021                         dom_info->general.num_aliases   = count_sam_aliases(
3022                                 dinfo->disp_info);
3023
3024                         pdb_get_account_policy(AP_TIME_TO_LOGOUT, &u_logout);
3025
3026                         unix_to_nt_time_abs(&dom_info->general.force_logoff_time, u_logout);
3027
3028                         if (!pdb_get_seq_num(&seq_num))
3029                                 seq_num = time(NULL);
3030
3031                         /* !AS ROOT */
3032
3033                         unbecome_root();
3034
3035                         server_role = ROLE_DOMAIN_PDC;
3036                         if (lp_server_role() == ROLE_DOMAIN_BDC)
3037                                 server_role = ROLE_DOMAIN_BDC;
3038
3039                         dom_info->general.oem_information.string        = lp_serverstring();
3040                         dom_info->general.domain_name.string            = lp_workgroup();
3041                         dom_info->general.primary.string                = global_myname();
3042                         dom_info->general.sequence_num                  = seq_num;
3043                         dom_info->general.domain_server_state           = DOMAIN_SERVER_ENABLED;
3044                         dom_info->general.role                          = server_role;
3045                         dom_info->general.unknown3                      = 1;
3046
3047                         break;
3048                 case 0x03:
3049
3050                         become_root();
3051
3052                         /* AS ROOT !!! */
3053
3054                         {
3055                                 uint32 ul;
3056                                 pdb_get_account_policy(AP_TIME_TO_LOGOUT, &ul);
3057                                 u_logout = (time_t)ul;
3058                         }
3059
3060                         /* !AS ROOT */
3061
3062                         unbecome_root();
3063
3064                         unix_to_nt_time_abs(&dom_info->info3.force_logoff_time, u_logout);
3065
3066                         break;
3067                 case 0x04:
3068                         dom_info->oem.oem_information.string = lp_serverstring();
3069                         break;
3070                 case 0x05:
3071                         dom_info->info5.domain_name.string = get_global_sam_name();
3072                         break;
3073                 case 0x06:
3074                         /* NT returns its own name when a PDC. win2k and later
3075                          * only the name of the PDC if itself is a BDC (samba4
3076                          * idl) */
3077                         dom_info->info6.primary.string = global_myname();
3078                         break;
3079                 case 0x07:
3080                         server_role = ROLE_DOMAIN_PDC;
3081                         if (lp_server_role() == ROLE_DOMAIN_BDC)
3082                                 server_role = ROLE_DOMAIN_BDC;
3083
3084                         dom_info->info7.role = server_role;
3085                         break;
3086                 case 0x08:
3087
3088                         become_root();
3089
3090                         /* AS ROOT !!! */
3091
3092                         if (!pdb_get_seq_num(&seq_num)) {
3093                                 seq_num = time(NULL);
3094                         }
3095
3096                         /* !AS ROOT */
3097
3098                         unbecome_root();
3099
3100                         dom_info->info8.sequence_num = seq_num;
3101                         dom_info->info8.domain_create_time = 0;
3102
3103                         break;
3104                 case 0x0c:
3105
3106                         become_root();
3107
3108                         /* AS ROOT !!! */
3109
3110                         pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
3111                         u_lock_duration = account_policy_temp;
3112                         if (u_lock_duration != -1) {
3113                                 u_lock_duration *= 60;
3114                         }
3115
3116                         pdb_get_account_policy(AP_RESET_COUNT_TIME, &account_policy_temp);
3117                         u_reset_time = account_policy_temp * 60;
3118
3119                         pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT,
3120                                                &account_policy_temp);
3121                         dom_info->info12.lockout_threshold = account_policy_temp;
3122
3123                         /* !AS ROOT */
3124
3125                         unbecome_root();
3126
3127                         unix_to_nt_time_abs(&dom_info->info12.lockout_duration,
3128                                             u_lock_duration);
3129                         unix_to_nt_time_abs(&dom_info->info12.lockout_window,
3130                                             u_reset_time);
3131
3132                         break;
3133                 default:
3134                         return NT_STATUS_INVALID_INFO_CLASS;
3135         }
3136
3137         *r->out.info = dom_info;
3138
3139         DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__));
3140
3141         return status;
3142 }
3143
3144 /* W2k3 seems to use the same check for all 3 objects that can be created via
3145  * SAMR, if you try to create for example "Dialup" as an alias it says
3146  * "NT_STATUS_USER_EXISTS". This is racy, but we can't really lock the user
3147  * database. */
3148
3149 static NTSTATUS can_create(TALLOC_CTX *mem_ctx, const char *new_name)
3150 {
3151         enum lsa_SidType type;
3152         bool result;
3153
3154         DEBUG(10, ("Checking whether [%s] can be created\n", new_name));
3155
3156         become_root();
3157         /* Lookup in our local databases (LOOKUP_NAME_REMOTE not set)
3158          * whether the name already exists */
3159         result = lookup_name(mem_ctx, new_name, LOOKUP_NAME_LOCAL,
3160                              NULL, NULL, NULL, &type);
3161         unbecome_root();
3162
3163         if (!result) {
3164                 DEBUG(10, ("%s does not exist, can create it\n", new_name));
3165                 return NT_STATUS_OK;
3166         }
3167
3168         DEBUG(5, ("trying to create %s, exists as %s\n",
3169                   new_name, sid_type_lookup(type)));
3170
3171         if (type == SID_NAME_DOM_GRP) {
3172                 return NT_STATUS_GROUP_EXISTS;
3173         }
3174         if (type == SID_NAME_ALIAS) {
3175                 return NT_STATUS_ALIAS_EXISTS;
3176         }
3177
3178         /* Yes, the default is NT_STATUS_USER_EXISTS */
3179         return NT_STATUS_USER_EXISTS;
3180 }
3181
3182 /*******************************************************************
3183  _samr_CreateUser2
3184  ********************************************************************/
3185
3186 NTSTATUS _samr_CreateUser2(pipes_struct *p,
3187                            struct samr_CreateUser2 *r)
3188 {
3189         const char *account = NULL;
3190         DOM_SID sid;
3191         uint32_t acb_info = r->in.acct_flags;
3192         struct samr_domain_info *dinfo;
3193         struct samr_user_info *uinfo;
3194         NTSTATUS nt_status;
3195         uint32 acc_granted;
3196         SEC_DESC *psd;
3197         size_t    sd_size;
3198         /* check this, when giving away 'add computer to domain' privs */
3199         uint32    des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
3200         bool can_add_account = False;
3201         SE_PRIV se_rights;
3202
3203         dinfo = policy_handle_find(p, r->in.domain_handle,
3204                                    SAMR_DOMAIN_ACCESS_CREATE_USER, NULL,
3205                                    struct samr_domain_info, &nt_status);
3206         if (!NT_STATUS_IS_OK(nt_status)) {
3207                 return nt_status;
3208         }
3209
3210         if (sid_check_is_builtin(&dinfo->sid)) {
3211                 DEBUG(5,("_samr_CreateUser2: Refusing user create in BUILTIN\n"));
3212                 return NT_STATUS_ACCESS_DENIED;
3213         }
3214
3215         if (!(acb_info == ACB_NORMAL || acb_info == ACB_DOMTRUST ||
3216               acb_info == ACB_WSTRUST || acb_info == ACB_SVRTRUST)) {
3217                 /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if
3218                    this parameter is not an account type */
3219                 return NT_STATUS_INVALID_PARAMETER;
3220         }
3221
3222         account = r->in.account_name->string;
3223         if (account == NULL) {
3224                 return NT_STATUS_NO_MEMORY;
3225         }
3226
3227         nt_status = can_create(p->mem_ctx, account);
3228         if (!NT_STATUS_IS_OK(nt_status)) {
3229                 return nt_status;
3230         }
3231
3232         /* determine which user right we need to check based on the acb_info */
3233
3234         if ( acb_info & ACB_WSTRUST )
3235         {
3236                 se_priv_copy( &se_rights, &se_machine_account );
3237                 can_add_account = user_has_privileges(
3238                         p->server_info->ptok, &se_rights );
3239         }
3240         /* usrmgr.exe (and net rpc trustdom grant) creates a normal user
3241            account for domain trusts and changes the ACB flags later */
3242         else if ( acb_info & ACB_NORMAL &&
3243                   (account[strlen(account)-1] != '$') )
3244         {
3245                 se_priv_copy( &se_rights, &se_add_users );
3246                 can_add_account = user_has_privileges(
3247                         p->server_info->ptok, &se_rights );
3248         }
3249         else    /* implicit assumption of a BDC or domain trust account here
3250                  * (we already check the flags earlier) */
3251         {
3252                 if ( lp_enable_privileges() ) {
3253                         /* only Domain Admins can add a BDC or domain trust */
3254                         se_priv_copy( &se_rights, &se_priv_none );
3255                         can_add_account = nt_token_check_domain_rid(
3256                                 p->server_info->ptok,
3257                                 DOMAIN_GROUP_RID_ADMINS );
3258                 }
3259         }
3260
3261         DEBUG(5, ("_samr_CreateUser2: %s can add this account : %s\n",
3262                   uidtoname(p->server_info->utok.uid),
3263                   can_add_account ? "True":"False" ));
3264
3265         /********** BEGIN Admin BLOCK **********/
3266
3267         if ( can_add_account )
3268                 become_root();
3269
3270         nt_status = pdb_create_user(p->mem_ctx, account, acb_info,
3271                                     r->out.rid);
3272
3273         if ( can_add_account )
3274                 unbecome_root();
3275
3276         /********** END Admin BLOCK **********/
3277
3278         /* now check for failure */
3279
3280         if ( !NT_STATUS_IS_OK(nt_status) )
3281                 return nt_status;
3282
3283         /* Get the user's SID */
3284
3285         sid_compose(&sid, get_global_sam_sid(), *r->out.rid);
3286
3287         map_max_allowed_access(p->server_info->ptok, &des_access);
3288
3289         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping,
3290                             &sid, SAMR_USR_RIGHTS_WRITE_PW);
3291         se_map_generic(&des_access, &usr_generic_mapping);
3292
3293         nt_status = access_check_samr_object(psd, p->server_info->ptok,
3294                 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
3295                 &acc_granted, "_samr_CreateUser2");
3296
3297         if ( !NT_STATUS_IS_OK(nt_status) ) {
3298                 return nt_status;
3299         }
3300
3301         uinfo = policy_handle_create(p, r->out.user_handle, acc_granted,
3302                                      struct samr_user_info, &nt_status);
3303         if (!NT_STATUS_IS_OK(nt_status)) {
3304                 return nt_status;
3305         }
3306         uinfo->sid = sid;
3307
3308         /* After a "set" ensure we have no cached display info. */
3309         force_flush_samr_cache(&sid);
3310
3311         *r->out.access_granted = acc_granted;
3312
3313         return NT_STATUS_OK;
3314 }
3315
3316 /****************************************************************
3317 ****************************************************************/
3318
3319 NTSTATUS _samr_CreateUser(pipes_struct *p,
3320                           struct samr_CreateUser *r)
3321 {
3322         struct samr_CreateUser2 c;
3323         uint32_t access_granted;
3324
3325         c.in.domain_handle      = r->in.domain_handle;
3326         c.in.account_name       = r->in.account_name;
3327         c.in.acct_flags         = ACB_NORMAL;
3328         c.in.access_mask        = r->in.access_mask;
3329         c.out.user_handle       = r->out.user_handle;
3330         c.out.access_granted    = &access_granted;
3331         c.out.rid               = r->out.rid;
3332
3333         return _samr_CreateUser2(p, &c);
3334 }
3335
3336 /*******************************************************************
3337  _samr_Connect
3338  ********************************************************************/
3339
3340 NTSTATUS _samr_Connect(pipes_struct *p,
3341                        struct samr_Connect *r)
3342 {
3343         struct samr_connect_info *info;
3344         uint32_t acc_granted;
3345         struct policy_handle hnd;
3346         uint32    des_access = r->in.access_mask;
3347         NTSTATUS status;
3348
3349         /* Access check */
3350
3351         if (!pipe_access_check(p)) {
3352                 DEBUG(3, ("access denied to _samr_Connect\n"));
3353                 return NT_STATUS_ACCESS_DENIED;
3354         }
3355
3356         /* don't give away the farm but this is probably ok.  The SAMR_ACCESS_ENUM_DOMAINS
3357            was observed from a win98 client trying to enumerate users (when configured
3358            user level access control on shares)   --jerry */
3359
3360         map_max_allowed_access(p->server_info->ptok, &des_access);
3361
3362         se_map_generic( &des_access, &sam_generic_mapping );
3363
3364         acc_granted = des_access & (SAMR_ACCESS_ENUM_DOMAINS
3365                                     |SAMR_ACCESS_LOOKUP_DOMAIN);
3366
3367         /* set up the SAMR connect_anon response */
3368
3369         info = policy_handle_create(p, &hnd, acc_granted,
3370                                     struct samr_connect_info,
3371                                     &status);
3372         if (!NT_STATUS_IS_OK(status)) {
3373                 return status;
3374         }
3375
3376         *r->out.connect_handle = hnd;
3377         return NT_STATUS_OK;
3378 }
3379
3380 /*******************************************************************
3381  _samr_Connect2
3382  ********************************************************************/
3383
3384 NTSTATUS _samr_Connect2(pipes_struct *p,
3385                         struct samr_Connect2 *r)
3386 {
3387         struct samr_connect_info *info = NULL;
3388         struct policy_handle hnd;
3389         SEC_DESC *psd = NULL;
3390         uint32    acc_granted;
3391         uint32    des_access = r->in.access_mask;
3392         NTSTATUS  nt_status;
3393         size_t    sd_size;
3394         const char *fn = "_samr_Connect2";
3395
3396         switch (p->hdr_req.opnum) {
3397         case NDR_SAMR_CONNECT2:
3398                 fn = "_samr_Connect2";
3399                 break;
3400         case NDR_SAMR_CONNECT3:
3401                 fn = "_samr_Connect3";
3402                 break;
3403         case NDR_SAMR_CONNECT4:
3404                 fn = "_samr_Connect4";
3405                 break;
3406         case NDR_SAMR_CONNECT5:
3407                 fn = "_samr_Connect5";
3408                 break;
3409         }
3410
3411         DEBUG(5,("%s: %d\n", fn, __LINE__));
3412
3413         /* Access check */
3414
3415         if (!pipe_access_check(p)) {
3416                 DEBUG(3, ("access denied to %s\n", fn));
3417                 return NT_STATUS_ACCESS_DENIED;
3418         }
3419
3420         map_max_allowed_access(p->server_info->ptok, &des_access);
3421
3422         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
3423         se_map_generic(&des_access, &sam_generic_mapping);
3424
3425         nt_status = access_check_samr_object(psd, p->server_info->ptok,
3426                 NULL, 0, des_access, &acc_granted, fn);
3427
3428         if ( !NT_STATUS_IS_OK(nt_status) )
3429                 return nt_status;
3430
3431         info = policy_handle_create(p, &hnd, acc_granted,
3432                                     struct samr_connect_info, &nt_status);
3433         if (!NT_STATUS_IS_OK(nt_status)) {
3434                 return nt_status;
3435         }
3436
3437         DEBUG(5,("%s: %d\n", fn, __LINE__));
3438
3439         *r->out.connect_handle = hnd;
3440         return NT_STATUS_OK;
3441 }
3442
3443 /****************************************************************
3444  _samr_Connect3
3445 ****************************************************************/
3446
3447 NTSTATUS _samr_Connect3(pipes_struct *p,
3448                         struct samr_Connect3 *r)
3449 {
3450         struct samr_Connect2 c;
3451
3452         c.in.system_name        = r->in.system_name;
3453         c.in.access_mask        = r->in.access_mask;
3454         c.out.connect_handle    = r->out.connect_handle;
3455
3456         return _samr_Connect2(p, &c);
3457 }
3458
3459 /*******************************************************************
3460  _samr_Connect4
3461  ********************************************************************/
3462
3463 NTSTATUS _samr_Connect4(pipes_struct *p,
3464                         struct samr_Connect4 *r)
3465 {
3466         struct samr_Connect2 c;
3467
3468         c.in.system_name        = r->in.system_name;
3469         c.in.access_mask        = r->in.access_mask;
3470         c.out.connect_handle    = r->out.connect_handle;
3471
3472         return _samr_Connect2(p, &c);
3473 }
3474
3475 /*******************************************************************
3476  _samr_Connect5
3477  ********************************************************************/
3478
3479 NTSTATUS _samr_Connect5(pipes_struct *p,
3480                         struct samr_Connect5 *r)
3481 {
3482         NTSTATUS status;
3483         struct samr_Connect2 c;
3484         struct samr_ConnectInfo1 info1;
3485
3486         info1.client_version = SAMR_CONNECT_AFTER_W2K;
3487         info1.unknown2 = 0;
3488
3489         c.in.system_name        = r->in.system_name;
3490         c.in.access_mask        = r->in.access_mask;
3491         c.out.connect_handle    = r->out.connect_handle;
3492
3493         *r->out.level_out = 1;
3494
3495         status = _samr_Connect2(p, &c);
3496         if (!NT_STATUS_IS_OK(status)) {
3497                 return status;
3498         }
3499
3500         r->out.info_out->info1 = info1;
3501
3502         return NT_STATUS_OK;
3503 }
3504
3505 /**********************************************************************
3506  _samr_LookupDomain
3507  **********************************************************************/
3508
3509 NTSTATUS _samr_LookupDomain(pipes_struct *p,
3510                             struct samr_LookupDomain *r)
3511 {
3512         NTSTATUS status;
3513         struct samr_connect_info *info;
3514         const char *domain_name;
3515         DOM_SID *sid = NULL;
3516
3517         /* win9x user manager likes to use SAMR_ACCESS_ENUM_DOMAINS here.
3518            Reverted that change so we will work with RAS servers again */
3519
3520         info = policy_handle_find(p, r->in.connect_handle,
3521                                   SAMR_ACCESS_LOOKUP_DOMAIN, NULL,
3522                                   struct samr_connect_info,
3523                                   &status);
3524         if (!NT_STATUS_IS_OK(status)) {
3525                 return status;
3526         }
3527
3528         domain_name = r->in.domain_name->string;
3529         if (!domain_name) {
3530                 return NT_STATUS_INVALID_PARAMETER;
3531         }
3532
3533         sid = TALLOC_ZERO_P(p->mem_ctx, struct dom_sid2);
3534         if (!sid) {
3535                 return NT_STATUS_NO_MEMORY;
3536         }
3537
3538         if (strequal(domain_name, builtin_domain_name())) {
3539                 sid_copy(sid, &global_sid_Builtin);
3540         } else {
3541                 if (!secrets_fetch_domain_sid(domain_name, sid)) {
3542                         status = NT_STATUS_NO_SUCH_DOMAIN;
3543                 }
3544         }
3545
3546         DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name,
3547                  sid_string_dbg(sid)));
3548
3549         *r->out.sid = sid;
3550
3551         return status;
3552 }
3553
3554 /**********************************************************************
3555  _samr_EnumDomains
3556  **********************************************************************/
3557
3558 NTSTATUS _samr_EnumDomains(pipes_struct *p,
3559                            struct samr_EnumDomains *r)
3560 {
3561         NTSTATUS status;
3562         struct samr_connect_info *info;
3563         uint32_t num_entries = 2;
3564         struct samr_SamEntry *entry_array = NULL;
3565         struct samr_SamArray *sam;
3566
3567         info = policy_handle_find(p, r->in.connect_handle,
3568                                   SAMR_ACCESS_ENUM_DOMAINS, NULL,
3569                                   struct samr_connect_info, &status);
3570         if (!NT_STATUS_IS_OK(status)) {
3571                 return status;
3572         }
3573
3574         sam = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
3575         if (!sam) {
3576                 return NT_STATUS_NO_MEMORY;
3577         }
3578
3579         entry_array = TALLOC_ZERO_ARRAY(p->mem_ctx,
3580                                         struct samr_SamEntry,
3581                                         num_entries);
3582         if (!entry_array) {
3583                 return NT_STATUS_NO_MEMORY;
3584         }
3585
3586         entry_array[0].idx = 0;
3587         init_lsa_String(&entry_array[0].name, get_global_sam_name());
3588
3589         entry_array[1].idx = 1;
3590         init_lsa_String(&entry_array[1].name, "Builtin");
3591
3592         sam->count = num_entries;
3593         sam->entries = entry_array;
3594
3595         *r->out.sam = sam;
3596         *r->out.num_entries = num_entries;
3597
3598         return status;
3599 }
3600
3601 /*******************************************************************
3602  _samr_OpenAlias
3603  ********************************************************************/
3604
3605 NTSTATUS _samr_OpenAlias(pipes_struct *p,
3606                          struct samr_OpenAlias *r)
3607 {
3608         DOM_SID sid;
3609         uint32 alias_rid = r->in.rid;
3610         struct samr_alias_info *ainfo;
3611         struct samr_domain_info *dinfo;
3612         SEC_DESC *psd = NULL;
3613         uint32    acc_granted;
3614         uint32    des_access = r->in.access_mask;
3615         size_t    sd_size;
3616         NTSTATUS  status;
3617         SE_PRIV se_rights;
3618
3619         dinfo = policy_handle_find(p, r->in.domain_handle,
3620                                    SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
3621                                    struct samr_domain_info, &status);
3622         if (!NT_STATUS_IS_OK(status)) {
3623                 return status;
3624         }
3625
3626         /* append the alias' RID to it */
3627
3628         if (!sid_compose(&sid, &dinfo->sid, alias_rid))
3629                 return NT_STATUS_NO_SUCH_ALIAS;
3630
3631         /*check if access can be granted as requested by client. */
3632
3633         map_max_allowed_access(p->server_info->ptok, &des_access);
3634
3635         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &ali_generic_mapping, NULL, 0);
3636         se_map_generic(&des_access,&ali_generic_mapping);
3637
3638         se_priv_copy( &se_rights, &se_add_users );
3639
3640
3641         status = access_check_samr_object(psd, p->server_info->ptok,
3642                 &se_rights, GENERIC_RIGHTS_ALIAS_WRITE, des_access,
3643                 &acc_granted, "_samr_OpenAlias");
3644
3645         if ( !NT_STATUS_IS_OK(status) )
3646                 return status;
3647
3648         {
3649                 /* Check we actually have the requested alias */
3650                 enum lsa_SidType type;
3651                 bool result;
3652                 gid_t gid;
3653
3654                 become_root();
3655                 result = lookup_sid(NULL, &sid, NULL, NULL, &type);
3656                 unbecome_root();
3657
3658                 if (!result || (type != SID_NAME_ALIAS)) {
3659                         return NT_STATUS_NO_SUCH_ALIAS;
3660                 }
3661
3662                 /* make sure there is a mapping */
3663
3664                 if ( !sid_to_gid( &sid, &gid ) ) {
3665                         return NT_STATUS_NO_SUCH_ALIAS;
3666                 }
3667
3668         }
3669
3670         ainfo = policy_handle_create(p, r->out.alias_handle, acc_granted,
3671                                      struct samr_alias_info, &status);
3672         if (!NT_STATUS_IS_OK(status)) {
3673                 return status;
3674         }
3675         ainfo->sid = sid;
3676
3677         return NT_STATUS_OK;
3678 }
3679
3680 /*******************************************************************
3681  set_user_info_2
3682  ********************************************************************/
3683
3684 static NTSTATUS set_user_info_2(TALLOC_CTX *mem_ctx,
3685                                 struct samr_UserInfo2 *id2,
3686                                 struct samu *pwd)
3687 {
3688         if (id2 == NULL) {
3689                 DEBUG(5,("set_user_info_2: NULL id2\n"));
3690                 return NT_STATUS_ACCESS_DENIED;
3691         }
3692
3693         copy_id2_to_sam_passwd(pwd, id2);
3694
3695         return pdb_update_sam_account(pwd);
3696 }
3697
3698 /*******************************************************************
3699  set_user_info_4
3700  ********************************************************************/
3701
3702 static NTSTATUS set_user_info_4(TALLOC_CTX *mem_ctx,
3703                                 struct samr_UserInfo4 *id4,
3704                                 struct samu *pwd)
3705 {
3706         if (id4 == NULL) {
3707                 DEBUG(5,("set_user_info_2: NULL id4\n"));
3708                 return NT_STATUS_ACCESS_DENIED;
3709         }
3710
3711         copy_id4_to_sam_passwd(pwd, id4);
3712
3713         return pdb_update_sam_account(pwd);
3714 }
3715
3716 /*******************************************************************
3717  set_user_info_6
3718  ********************************************************************/
3719
3720 static NTSTATUS set_user_info_6(TALLOC_CTX *mem_ctx,
3721                                 struct samr_UserInfo6 *id6,
3722                                 struct samu *pwd)
3723 {
3724         if (id6 == NULL) {
3725                 DEBUG(5,("set_user_info_6: NULL id6\n"));
3726                 return NT_STATUS_ACCESS_DENIED;
3727         }
3728
3729         copy_id6_to_sam_passwd(pwd, id6);
3730
3731         return pdb_update_sam_account(pwd);
3732 }
3733
3734 /*******************************************************************
3735  set_user_info_7
3736  ********************************************************************/
3737
3738 static NTSTATUS set_user_info_7(TALLOC_CTX *mem_ctx,
3739                                 struct samr_UserInfo7 *id7,
3740                                 struct samu *pwd)
3741 {
3742         NTSTATUS rc;
3743
3744         if (id7 == NULL) {
3745                 DEBUG(5, ("set_user_info_7: NULL id7\n"));
3746                 return NT_STATUS_ACCESS_DENIED;
3747         }
3748
3749         if (!id7->account_name.string) {
3750                 DEBUG(5, ("set_user_info_7: failed to get new username\n"));
3751                 return NT_STATUS_ACCESS_DENIED;
3752         }
3753
3754         /* check to see if the new username already exists.  Note: we can't
3755            reliably lock all backends, so there is potentially the
3756            possibility that a user can be created in between this check and
3757            the rename.  The rename should fail, but may not get the
3758            exact same failure status code.  I think this is small enough
3759            of a window for this type of operation and the results are
3760            simply that the rename fails with a slightly different status
3761            code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
3762
3763         rc = can_create(mem_ctx, id7->account_name.string);
3764         if (!NT_STATUS_IS_OK(rc)) {
3765                 return rc;
3766         }
3767
3768         rc = pdb_rename_sam_account(pwd, id7->account_name.string);
3769
3770         return rc;
3771 }
3772
3773 /*******************************************************************
3774  set_user_info_8
3775  ********************************************************************/
3776
3777 static NTSTATUS set_user_info_8(TALLOC_CTX *mem_ctx,
3778                                 struct samr_UserInfo8 *id8,
3779                                 struct samu *pwd)
3780 {
3781         if (id8 == NULL) {
3782                 DEBUG(5,("set_user_info_8: NULL id8\n"));
3783                 return NT_STATUS_ACCESS_DENIED;
3784         }
3785
3786         copy_id8_to_sam_passwd(pwd, id8);
3787
3788         return pdb_update_sam_account(pwd);
3789 }
3790
3791 /*******************************************************************
3792  set_user_info_10
3793  ********************************************************************/
3794
3795 static NTSTATUS set_user_info_10(TALLOC_CTX *mem_ctx,
3796                                  struct samr_UserInfo10 *id10,
3797                                  struct samu *pwd)
3798 {
3799         if (id10 == NULL) {
3800                 DEBUG(5,("set_user_info_8: NULL id10\n"));
3801                 return NT_STATUS_ACCESS_DENIED;
3802         }
3803
3804         copy_id10_to_sam_passwd(pwd, id10);
3805
3806         return pdb_update_sam_account(pwd);
3807 }
3808
3809 /*******************************************************************
3810  set_user_info_11
3811  ********************************************************************/
3812
3813 static NTSTATUS set_user_info_11(TALLOC_CTX *mem_ctx,
3814                                  struct samr_UserInfo11 *id11,
3815                                  struct samu *pwd)
3816 {
3817         if (id11 == NULL) {
3818                 DEBUG(5,("set_user_info_11: NULL id11\n"));
3819                 return NT_STATUS_ACCESS_DENIED;
3820         }
3821
3822         copy_id11_to_sam_passwd(pwd, id11);
3823
3824         return pdb_update_sam_account(pwd);
3825 }
3826
3827 /*******************************************************************
3828  set_user_info_12
3829  ********************************************************************/
3830
3831 static NTSTATUS set_user_info_12(TALLOC_CTX *mem_ctx,
3832                                  struct samr_UserInfo12 *id12,
3833                                  struct samu *pwd)
3834 {
3835         if (id12 == NULL) {
3836                 DEBUG(5,("set_user_info_12: NULL id12\n"));
3837                 return NT_STATUS_ACCESS_DENIED;
3838         }
3839
3840         copy_id12_to_sam_passwd(pwd, id12);
3841
3842         return pdb_update_sam_account(pwd);
3843 }
3844
3845 /*******************************************************************
3846  set_user_info_13
3847  ********************************************************************/
3848
3849 static NTSTATUS set_user_info_13(TALLOC_CTX *mem_ctx,
3850                                  struct samr_UserInfo13 *id13,
3851                                  struct samu *pwd)
3852 {
3853         if (id13 == NULL) {
3854                 DEBUG(5,("set_user_info_13: NULL id13\n"));
3855                 return NT_STATUS_ACCESS_DENIED;
3856         }
3857
3858         copy_id13_to_sam_passwd(pwd, id13);
3859
3860         return pdb_update_sam_account(pwd);
3861 }
3862
3863 /*******************************************************************
3864  set_user_info_14
3865  ********************************************************************/
3866
3867 static NTSTATUS set_user_info_14(TALLOC_CTX *mem_ctx,
3868                                  struct samr_UserInfo14 *id14,
3869                                  struct samu *pwd)
3870 {
3871         if (id14 == NULL) {
3872                 DEBUG(5,("set_user_info_14: NULL id14\n"));
3873                 return NT_STATUS_ACCESS_DENIED;
3874         }
3875
3876         copy_id14_to_sam_passwd(pwd, id14);
3877
3878         return pdb_update_sam_account(pwd);
3879 }
3880
3881 /*******************************************************************
3882  set_user_info_16
3883  ********************************************************************/
3884
3885 static NTSTATUS set_user_info_16(TALLOC_CTX *mem_ctx,
3886                                  struct samr_UserInfo16 *id16,
3887                                  struct samu *pwd)
3888 {
3889         if (id16 == NULL) {
3890                 DEBUG(5,("set_user_info_16: NULL id16\n"));
3891                 return NT_STATUS_ACCESS_DENIED;
3892         }
3893
3894         copy_id16_to_sam_passwd(pwd, id16);
3895
3896         return pdb_update_sam_account(pwd);
3897 }
3898
3899 /*******************************************************************
3900  set_user_info_17
3901  ********************************************************************/
3902
3903 static NTSTATUS set_user_info_17(TALLOC_CTX *mem_ctx,
3904                                  struct samr_UserInfo17 *id17,
3905                                  struct samu *pwd)
3906 {
3907         if (id17 == NULL) {
3908                 DEBUG(5,("set_user_info_17: NULL id17\n"));
3909                 return NT_STATUS_ACCESS_DENIED;
3910         }
3911
3912         copy_id17_to_sam_passwd(pwd, id17);
3913
3914         return pdb_update_sam_account(pwd);
3915 }
3916
3917 /*******************************************************************
3918  set_user_info_18
3919  ********************************************************************/
3920
3921 static NTSTATUS set_user_info_18(struct samr_UserInfo18 *id18,
3922                                  TALLOC_CTX *mem_ctx,
3923                                  DATA_BLOB *session_key,
3924                                  struct samu *pwd)
3925 {
3926         if (id18 == NULL) {
3927                 DEBUG(2, ("set_user_info_18: id18 is NULL\n"));
3928                 return NT_STATUS_INVALID_PARAMETER;
3929         }
3930
3931         if (id18->nt_pwd_active || id18->lm_pwd_active) {
3932                 if (!session_key->length) {
3933                         return NT_STATUS_NO_USER_SESSION_KEY;
3934                 }
3935         }
3936
3937         if (id18->nt_pwd_active) {
3938
3939                 DATA_BLOB in, out;
3940
3941                 in = data_blob_const(id18->nt_pwd.hash, 16);
3942                 out = data_blob_talloc_zero(mem_ctx, 16);
3943
3944                 sess_crypt_blob(&out, &in, session_key, false);
3945
3946                 if (!pdb_set_nt_passwd(pwd, out.data, PDB_CHANGED)) {
3947                         return NT_STATUS_ACCESS_DENIED;
3948                 }
3949
3950                 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
3951         }
3952
3953         if (id18->lm_pwd_active) {
3954
3955                 DATA_BLOB in, out;
3956
3957                 in = data_blob_const(id18->lm_pwd.hash, 16);
3958                 out = data_blob_talloc_zero(mem_ctx, 16);
3959
3960                 sess_crypt_blob(&out, &in, session_key, false);
3961
3962                 if (!pdb_set_lanman_passwd(pwd, out.data, PDB_CHANGED)) {
3963                         return NT_STATUS_ACCESS_DENIED;
3964                 }
3965
3966                 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
3967         }
3968
3969         copy_id18_to_sam_passwd(pwd, id18);
3970
3971         return pdb_update_sam_account(pwd);
3972 }
3973
3974 /*******************************************************************
3975  set_user_info_20
3976  ********************************************************************/
3977
3978 static NTSTATUS set_user_info_20(TALLOC_CTX *mem_ctx,
3979                                  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 NT_STATUS_ACCESS_DENIED;
3985         }
3986
3987         copy_id20_to_sam_passwd(pwd, id20);
3988
3989         return pdb_update_sam_account(pwd);
3990 }
3991
3992 /*******************************************************************
3993  set_user_info_21
3994  ********************************************************************/
3995
3996 static NTSTATUS set_user_info_21(struct samr_UserInfo21 *id21,
3997                                  TALLOC_CTX *mem_ctx,
3998                                  DATA_BLOB *session_key,
3999                                  struct samu *pwd)
4000 {
4001         NTSTATUS status;
4002
4003         if (id21 == NULL) {
4004                 DEBUG(5, ("set_user_info_21: NULL id21\n"));
4005                 return NT_STATUS_INVALID_PARAMETER;
4006         }
4007
4008         if (id21->fields_present == 0) {
4009                 return NT_STATUS_INVALID_PARAMETER;
4010         }
4011
4012         if (id21->fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
4013                 return NT_STATUS_ACCESS_DENIED;
4014         }
4015
4016         if (id21->fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
4017                 if (id21->nt_password_set) {
4018                         DATA_BLOB in, out;
4019
4020                         if ((id21->nt_owf_password.length != 16) ||
4021                             (id21->nt_owf_password.size != 16)) {
4022                                 return NT_STATUS_INVALID_PARAMETER;
4023                         }
4024
4025                         if (!session_key->length) {
4026                                 return NT_STATUS_NO_USER_SESSION_KEY;
4027                         }
4028
4029                         in = data_blob_const(id21->nt_owf_password.array, 16);
4030                         out = data_blob_talloc_zero(mem_ctx, 16);
4031
4032                         sess_crypt_blob(&out, &in, session_key, false);
4033
4034                         pdb_set_nt_passwd(pwd, out.data, PDB_CHANGED);
4035                         pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4036                 }
4037         }
4038
4039         if (id21->fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
4040                 if (id21->lm_password_set) {
4041                         DATA_BLOB in, out;
4042
4043                         if ((id21->lm_owf_password.length != 16) ||
4044                             (id21->lm_owf_password.size != 16)) {
4045                                 return NT_STATUS_INVALID_PARAMETER;
4046                         }
4047
4048                         if (!session_key->length) {
4049                                 return NT_STATUS_NO_USER_SESSION_KEY;
4050                         }
4051
4052                         in = data_blob_const(id21->lm_owf_password.array, 16);
4053                         out = data_blob_talloc_zero(mem_ctx, 16);
4054
4055                         sess_crypt_blob(&out, &in, session_key, false);
4056
4057                         pdb_set_lanman_passwd(pwd, out.data, PDB_CHANGED);
4058                         pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4059                 }
4060         }
4061
4062         /* we need to separately check for an account rename first */
4063
4064         if (id21->account_name.string &&
4065             (!strequal(id21->account_name.string, pdb_get_username(pwd))))
4066         {
4067
4068                 /* check to see if the new username already exists.  Note: we can't
4069                    reliably lock all backends, so there is potentially the
4070                    possibility that a user can be created in between this check and
4071                    the rename.  The rename should fail, but may not get the
4072                    exact same failure status code.  I think this is small enough
4073                    of a window for this type of operation and the results are
4074                    simply that the rename fails with a slightly different status
4075                    code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
4076
4077                 status = can_create(mem_ctx, id21->account_name.string);
4078                 if (!NT_STATUS_IS_OK(status)) {
4079                         return status;
4080                 }
4081
4082                 status = pdb_rename_sam_account(pwd, id21->account_name.string);
4083
4084                 if (!NT_STATUS_IS_OK(status)) {
4085                         DEBUG(0,("set_user_info_21: failed to rename account: %s\n",
4086                                 nt_errstr(status)));
4087                         return status;
4088                 }
4089
4090                 /* set the new username so that later
4091                    functions can work on the new account */
4092                 pdb_set_username(pwd, id21->account_name.string, PDB_SET);
4093         }
4094
4095         copy_id21_to_sam_passwd("INFO_21", pwd, id21);
4096
4097         /*
4098          * The funny part about the previous two calls is
4099          * that pwd still has the password hashes from the
4100          * passdb entry.  These have not been updated from
4101          * id21.  I don't know if they need to be set.    --jerry
4102          */
4103
4104         if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
4105                 status = pdb_set_unix_primary_group(mem_ctx, pwd);
4106                 if ( !NT_STATUS_IS_OK(status) ) {
4107                         return status;
4108                 }
4109         }
4110
4111         /* Don't worry about writing out the user account since the
4112            primary group SID is generated solely from the user's Unix
4113            primary group. */
4114
4115         /* write the change out */
4116         if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4117                 return status;
4118         }
4119
4120         return NT_STATUS_OK;
4121 }
4122
4123 /*******************************************************************
4124  set_user_info_23
4125  ********************************************************************/
4126
4127 static NTSTATUS set_user_info_23(TALLOC_CTX *mem_ctx,
4128                                  struct samr_UserInfo23 *id23,
4129                                  struct samu *pwd)
4130 {
4131         char *plaintext_buf = NULL;
4132         size_t len = 0;
4133         uint32_t acct_ctrl;
4134         NTSTATUS status;
4135
4136         if (id23 == NULL) {
4137                 DEBUG(5, ("set_user_info_23: NULL id23\n"));
4138                 return NT_STATUS_INVALID_PARAMETER;
4139         }
4140
4141         if (id23->info.fields_present == 0) {
4142                 return NT_STATUS_INVALID_PARAMETER;
4143         }
4144
4145         if (id23->info.fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
4146                 return NT_STATUS_ACCESS_DENIED;
4147         }
4148
4149         if ((id23->info.fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
4150             (id23->info.fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT)) {
4151
4152                 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
4153                           pdb_get_username(pwd)));
4154
4155                 if (!decode_pw_buffer(mem_ctx,
4156                                       id23->password.data,
4157                                       &plaintext_buf,
4158                                       &len,
4159                                       CH_UTF16)) {
4160                         return NT_STATUS_WRONG_PASSWORD;
4161                 }
4162
4163                 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
4164                         return NT_STATUS_ACCESS_DENIED;
4165                 }
4166         }
4167
4168         copy_id23_to_sam_passwd(pwd, id23);
4169
4170         acct_ctrl = pdb_get_acct_ctrl(pwd);
4171
4172         /* if it's a trust account, don't update /etc/passwd */
4173         if (    ( (acct_ctrl &  ACB_DOMTRUST) == ACB_DOMTRUST ) ||
4174                 ( (acct_ctrl &  ACB_WSTRUST) ==  ACB_WSTRUST) ||
4175                 ( (acct_ctrl &  ACB_SVRTRUST) ==  ACB_SVRTRUST) ) {
4176                 DEBUG(5, ("Changing trust account.  Not updating /etc/passwd\n"));
4177         } else if (plaintext_buf) {
4178                 /* update the UNIX password */
4179                 if (lp_unix_password_sync() ) {
4180                         struct passwd *passwd;
4181                         if (pdb_get_username(pwd) == NULL) {
4182                                 DEBUG(1, ("chgpasswd: User without name???\n"));
4183                                 return NT_STATUS_ACCESS_DENIED;
4184                         }
4185
4186                         passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
4187                         if (passwd == NULL) {
4188                                 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
4189                         }
4190
4191                         if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
4192                                 return NT_STATUS_ACCESS_DENIED;
4193                         }
4194                         TALLOC_FREE(passwd);
4195                 }
4196         }
4197
4198         if (plaintext_buf) {
4199                 memset(plaintext_buf, '\0', strlen(plaintext_buf));
4200         }
4201
4202         if (IS_SAM_CHANGED(pwd, PDB_GROUPSID) &&
4203             (!NT_STATUS_IS_OK(status =  pdb_set_unix_primary_group(mem_ctx,
4204                                                                    pwd)))) {
4205                 return status;
4206         }
4207
4208         if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4209                 return status;
4210         }
4211
4212         return NT_STATUS_OK;
4213 }
4214
4215 /*******************************************************************
4216  set_user_info_pw
4217  ********************************************************************/
4218
4219 static bool set_user_info_pw(uint8 *pass, struct samu *pwd)
4220 {
4221         size_t len = 0;
4222         char *plaintext_buf = NULL;
4223         uint32 acct_ctrl;
4224
4225         DEBUG(5, ("Attempting administrator password change for user %s\n",
4226                   pdb_get_username(pwd)));
4227
4228         acct_ctrl = pdb_get_acct_ctrl(pwd);
4229
4230         if (!decode_pw_buffer(talloc_tos(),
4231                                 pass,
4232                                 &plaintext_buf,
4233                                 &len,
4234                                 CH_UTF16)) {
4235                 return False;
4236         }
4237
4238         if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
4239                 return False;
4240         }
4241
4242         /* if it's a trust account, don't update /etc/passwd */
4243         if ( ( (acct_ctrl &  ACB_DOMTRUST) == ACB_DOMTRUST ) ||
4244                 ( (acct_ctrl &  ACB_WSTRUST) ==  ACB_WSTRUST) ||
4245                 ( (acct_ctrl &  ACB_SVRTRUST) ==  ACB_SVRTRUST) ) {
4246                 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
4247         } else {
4248                 /* update the UNIX password */
4249                 if (lp_unix_password_sync()) {
4250                         struct passwd *passwd;
4251
4252                         if (pdb_get_username(pwd) == NULL) {
4253                                 DEBUG(1, ("chgpasswd: User without name???\n"));
4254                                 return False;
4255                         }
4256
4257                         passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
4258                         if (passwd == NULL) {
4259                                 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
4260                         }
4261
4262                         if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
4263                                 return False;
4264                         }
4265                         TALLOC_FREE(passwd);
4266                 }
4267         }
4268
4269         memset(plaintext_buf, '\0', strlen(plaintext_buf));
4270
4271         DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
4272
4273         return True;
4274 }
4275
4276 /*******************************************************************
4277  set_user_info_24
4278  ********************************************************************/
4279
4280 static NTSTATUS set_user_info_24(TALLOC_CTX *mem_ctx,
4281                                  struct samr_UserInfo24 *id24,
4282                                  struct samu *pwd)
4283 {
4284         NTSTATUS status;
4285
4286         if (id24 == NULL) {
4287                 DEBUG(5, ("set_user_info_24: NULL id24\n"));
4288                 return NT_STATUS_INVALID_PARAMETER;
4289         }
4290
4291         if (!set_user_info_pw(id24->password.data, pwd)) {
4292                 return NT_STATUS_WRONG_PASSWORD;
4293         }
4294
4295         copy_id24_to_sam_passwd(pwd, id24);
4296
4297         status = pdb_update_sam_account(pwd);
4298         if (!NT_STATUS_IS_OK(status)) {
4299                 return status;
4300         }
4301
4302         return NT_STATUS_OK;
4303 }
4304
4305 /*******************************************************************
4306  set_user_info_25
4307  ********************************************************************/
4308
4309 static NTSTATUS set_user_info_25(TALLOC_CTX *mem_ctx,
4310                                  struct samr_UserInfo25 *id25,
4311                                  struct samu *pwd)
4312 {
4313         NTSTATUS status;
4314
4315         if (id25 == NULL) {
4316                 DEBUG(5, ("set_user_info_25: NULL id25\n"));
4317                 return NT_STATUS_INVALID_PARAMETER;
4318         }
4319
4320         if (id25->info.fields_present == 0) {
4321                 return NT_STATUS_INVALID_PARAMETER;
4322         }
4323
4324         if (id25->info.fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
4325                 return NT_STATUS_ACCESS_DENIED;
4326         }
4327
4328         if ((id25->info.fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
4329             (id25->info.fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT)) {
4330
4331                 if (!set_user_info_pw(id25->password.data, pwd)) {
4332                         return NT_STATUS_WRONG_PASSWORD;
4333                 }
4334         }
4335
4336         copy_id25_to_sam_passwd(pwd, id25);
4337
4338         /* write the change out */
4339         if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4340                 return status;
4341         }
4342
4343         /*
4344          * We need to "pdb_update_sam_account" before the unix primary group
4345          * is set, because the idealx scripts would also change the
4346          * sambaPrimaryGroupSid using the ldap replace method. pdb_ldap uses
4347          * the delete explicit / add explicit, which would then fail to find
4348          * the previous primaryGroupSid value.
4349          */
4350
4351         if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
4352                 status = pdb_set_unix_primary_group(mem_ctx, pwd);
4353                 if ( !NT_STATUS_IS_OK(status) ) {
4354                         return status;
4355                 }
4356         }
4357
4358         return NT_STATUS_OK;
4359 }
4360
4361 /*******************************************************************
4362  set_user_info_26
4363  ********************************************************************/
4364
4365 static NTSTATUS set_user_info_26(TALLOC_CTX *mem_ctx,
4366                                  struct samr_UserInfo26 *id26,
4367                                  struct samu *pwd)
4368 {
4369         NTSTATUS status;
4370
4371         if (id26 == NULL) {
4372                 DEBUG(5, ("set_user_info_26: NULL id26\n"));
4373                 return NT_STATUS_INVALID_PARAMETER;
4374         }
4375
4376         if (!set_user_info_pw(id26->password.data, pwd)) {
4377                 return NT_STATUS_WRONG_PASSWORD;
4378         }
4379
4380         copy_id26_to_sam_passwd(pwd, id26);
4381
4382         status = pdb_update_sam_account(pwd);
4383         if (!NT_STATUS_IS_OK(status)) {
4384                 return status;
4385         }
4386
4387         return NT_STATUS_OK;
4388 }
4389
4390
4391 /*******************************************************************
4392  samr_SetUserInfo
4393  ********************************************************************/
4394
4395 NTSTATUS _samr_SetUserInfo(pipes_struct *p,
4396                            struct samr_SetUserInfo *r)
4397 {
4398         struct samr_user_info *uinfo;
4399         NTSTATUS status;
4400         struct samu *pwd = NULL;
4401         union samr_UserInfo *info = r->in.info;
4402         uint16_t switch_value = r->in.level;
4403         uint32_t acc_required;
4404         bool ret;
4405         bool has_enough_rights = False;
4406         uint32_t acb_info;
4407
4408         DEBUG(5,("_samr_SetUserInfo: %d\n", __LINE__));
4409
4410         /* This is tricky.  A WinXP domain join sets
4411           (SAMR_USER_ACCESS_SET_PASSWORD|SAMR_USER_ACCESS_SET_ATTRIBUTES|SAMR_USER_ACCESS_GET_ATTRIBUTES)
4412           The MMC lusrmgr plugin includes these perms and more in the SamrOpenUser().  But the
4413           standard Win32 API calls just ask for SAMR_USER_ACCESS_SET_PASSWORD in the SamrOpenUser().
4414           This should be enough for levels 18, 24, 25,& 26.  Info level 23 can set more so
4415           we'll use the set from the WinXP join as the basis. */
4416
4417         switch (switch_value) {
4418         case 18:
4419         case 24:
4420         case 25:
4421         case 26:
4422                 acc_required = SAMR_USER_ACCESS_SET_PASSWORD;
4423                 break;
4424         default:
4425                 acc_required = SAMR_USER_ACCESS_SET_PASSWORD |
4426                                SAMR_USER_ACCESS_SET_ATTRIBUTES |
4427                                SAMR_USER_ACCESS_GET_ATTRIBUTES;
4428                 break;
4429         }
4430
4431         uinfo = policy_handle_find(p, r->in.user_handle, acc_required, NULL,
4432                                    struct samr_user_info, &status);
4433         if (!NT_STATUS_IS_OK(status)) {
4434                 return status;
4435         }
4436
4437         DEBUG(5, ("_samr_SetUserInfo: sid:%s, level:%d\n",
4438                   sid_string_dbg(&uinfo->sid), switch_value));
4439
4440         if (info == NULL) {
4441                 DEBUG(5, ("_samr_SetUserInfo: NULL info level\n"));
4442                 return NT_STATUS_INVALID_INFO_CLASS;
4443         }
4444
4445         if (!(pwd = samu_new(NULL))) {
4446                 return NT_STATUS_NO_MEMORY;
4447         }
4448
4449         become_root();
4450         ret = pdb_getsampwsid(pwd, &uinfo->sid);
4451         unbecome_root();
4452
4453         if (!ret) {
4454                 TALLOC_FREE(pwd);
4455                 return NT_STATUS_NO_SUCH_USER;
4456         }
4457
4458         /* deal with machine password changes differently from userinfo changes */
4459         /* check to see if we have the sufficient rights */
4460
4461         acb_info = pdb_get_acct_ctrl(pwd);
4462         if (acb_info & ACB_WSTRUST)
4463                 has_enough_rights = user_has_privileges(p->server_info->ptok,
4464                                                         &se_machine_account);
4465         else if (acb_info & ACB_NORMAL)
4466                 has_enough_rights = user_has_privileges(p->server_info->ptok,
4467                                                         &se_add_users);
4468         else if (acb_info & (ACB_SVRTRUST|ACB_DOMTRUST)) {
4469                 if (lp_enable_privileges()) {
4470                         has_enough_rights = nt_token_check_domain_rid(p->server_info->ptok,
4471                                                                       DOMAIN_GROUP_RID_ADMINS);
4472                 }
4473         }
4474
4475         DEBUG(5, ("_samr_SetUserInfo: %s does%s possess sufficient rights\n",
4476                   uidtoname(p->server_info->utok.uid),
4477                   has_enough_rights ? "" : " not"));
4478
4479         /* ================ BEGIN SeMachineAccountPrivilege BLOCK ================ */
4480
4481         if (has_enough_rights) {
4482                 become_root();
4483         }
4484
4485         /* ok!  user info levels (lots: see MSDEV help), off we go... */
4486
4487         switch (switch_value) {
4488
4489                 case 2:
4490                         status = set_user_info_2(p->mem_ctx,
4491                                                  &info->info2, pwd);
4492                         break;
4493
4494                 case 4:
4495                         status = set_user_info_4(p->mem_ctx,
4496                                                  &info->info4, pwd);
4497                         break;
4498
4499                 case 6:
4500                         status = set_user_info_6(p->mem_ctx,
4501                                                  &info->info6, pwd);
4502                         break;
4503
4504                 case 7:
4505                         status = set_user_info_7(p->mem_ctx,
4506                                                  &info->info7, pwd);
4507                         break;
4508
4509                 case 8:
4510                         status = set_user_info_8(p->mem_ctx,
4511                                                  &info->info8, pwd);
4512                         break;
4513
4514                 case 10:
4515                         status = set_user_info_10(p->mem_ctx,
4516                                                   &info->info10, pwd);
4517                         break;
4518
4519                 case 11:
4520                         status = set_user_info_11(p->mem_ctx,
4521                                                   &info->info11, pwd);
4522                         break;
4523
4524                 case 12:
4525                         status = set_user_info_12(p->mem_ctx,
4526                                                   &info->info12, pwd);
4527                         break;
4528
4529                 case 13:
4530                         status = set_user_info_13(p->mem_ctx,
4531                                                   &info->info13, pwd);
4532                         break;
4533
4534                 case 14:
4535                         status = set_user_info_14(p->mem_ctx,
4536                                                   &info->info14, pwd);
4537                         break;
4538
4539                 case 16:
4540                         status = set_user_info_16(p->mem_ctx,
4541                                                   &info->info16, pwd);
4542                         break;
4543
4544                 case 17:
4545                         status = set_user_info_17(p->mem_ctx,
4546                                                   &info->info17, pwd);
4547                         break;
4548
4549                 case 18:
4550                         /* Used by AS/U JRA. */
4551                         status = set_user_info_18(&info->info18,
4552                                                   p->mem_ctx,
4553                                                   &p->server_info->user_session_key,
4554                                                   pwd);
4555                         break;
4556
4557                 case 20:
4558                         status = set_user_info_20(p->mem_ctx,
4559                                                   &info->info20, pwd);
4560                         break;
4561
4562                 case 21:
4563                         status = set_user_info_21(&info->info21,
4564                                                   p->mem_ctx,
4565                                                   &p->server_info->user_session_key,
4566                                                   pwd);
4567                         break;
4568
4569                 case 23:
4570                         if (!p->server_info->user_session_key.length) {
4571                                 status = NT_STATUS_NO_USER_SESSION_KEY;
4572                         }
4573                         arcfour_crypt_blob(info->info23.password.data, 516,
4574                                            &p->server_info->user_session_key);
4575
4576                         dump_data(100, info->info23.password.data, 516);
4577
4578                         status = set_user_info_23(p->mem_ctx,
4579                                                   &info->info23, pwd);
4580                         break;
4581
4582                 case 24:
4583                         if (!p->server_info->user_session_key.length) {
4584                                 status = NT_STATUS_NO_USER_SESSION_KEY;
4585                         }
4586                         arcfour_crypt_blob(info->info24.password.data,
4587                                            516,
4588                                            &p->server_info->user_session_key);
4589
4590                         dump_data(100, info->info24.password.data, 516);
4591
4592                         status = set_user_info_24(p->mem_ctx,
4593                                                   &info->info24, pwd);
4594                         break;
4595
4596                 case 25:
4597                         if (!p->server_info->user_session_key.length) {
4598                                 status = NT_STATUS_NO_USER_SESSION_KEY;
4599                         }
4600                         encode_or_decode_arc4_passwd_buffer(
4601                                 info->info25.password.data,
4602                                 &p->server_info->user_session_key);
4603
4604                         dump_data(100, info->info25.password.data, 532);
4605
4606                         status = set_user_info_25(p->mem_ctx,
4607                                                   &info->info25, pwd);
4608                         break;
4609
4610                 case 26:
4611                         if (!p->server_info->user_session_key.length) {
4612                                 status = NT_STATUS_NO_USER_SESSION_KEY;
4613                         }
4614                         encode_or_decode_arc4_passwd_buffer(
4615                                 info->info26.password.data,
4616                                 &p->server_info->user_session_key);
4617
4618                         dump_data(100, info->info26.password.data, 516);
4619
4620                         status = set_user_info_26(p->mem_ctx,
4621                                                   &info->info26, pwd);
4622                         break;
4623
4624                 default:
4625                         status = NT_STATUS_INVALID_INFO_CLASS;
4626         }
4627
4628         TALLOC_FREE(pwd);
4629
4630         if (has_enough_rights) {
4631                 unbecome_root();
4632         }
4633
4634         /* ================ END SeMachineAccountPrivilege BLOCK ================ */
4635
4636         if (NT_STATUS_IS_OK(status)) {
4637                 force_flush_samr_cache(&uinfo->sid);
4638         }
4639
4640         return status;
4641 }
4642
4643 /*******************************************************************
4644  _samr_SetUserInfo2
4645  ********************************************************************/
4646
4647 NTSTATUS _samr_SetUserInfo2(pipes_struct *p,
4648                             struct samr_SetUserInfo2 *r)
4649 {
4650         struct samr_SetUserInfo q;
4651
4652         q.in.user_handle        = r->in.user_handle;
4653         q.in.level              = r->in.level;
4654         q.in.info               = r->in.info;
4655
4656         return _samr_SetUserInfo(p, &q);
4657 }
4658
4659 /*********************************************************************
4660  _samr_GetAliasMembership
4661 *********************************************************************/
4662
4663 NTSTATUS _samr_GetAliasMembership(pipes_struct *p,
4664                                   struct samr_GetAliasMembership *r)
4665 {
4666         size_t num_alias_rids;
4667         uint32 *alias_rids;
4668         struct samr_domain_info *dinfo;
4669         size_t i;
4670
4671         NTSTATUS status;
4672
4673         DOM_SID *members;
4674
4675         DEBUG(5,("_samr_GetAliasMembership: %d\n", __LINE__));
4676
4677         dinfo = policy_handle_find(p, r->in.domain_handle,
4678                                    SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS
4679                                    | SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
4680                                    struct samr_domain_info, &status);
4681         if (!NT_STATUS_IS_OK(status)) {
4682                 return status;
4683         }
4684
4685         if (!sid_check_is_domain(&dinfo->sid) &&
4686             !sid_check_is_builtin(&dinfo->sid))
4687                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
4688
4689         if (r->in.sids->num_sids) {
4690                 members = TALLOC_ARRAY(p->mem_ctx, DOM_SID, r->in.sids->num_sids);
4691
4692                 if (members == NULL)
4693                         return NT_STATUS_NO_MEMORY;
4694         } else {
4695                 members = NULL;
4696         }
4697
4698         for (i=0; i<r->in.sids->num_sids; i++)
4699                 sid_copy(&members[i], r->in.sids->sids[i].sid);
4700
4701         alias_rids = NULL;
4702         num_alias_rids = 0;
4703
4704         become_root();
4705         status = pdb_enum_alias_memberships(p->mem_ctx, &dinfo->sid, members,
4706                                             r->in.sids->num_sids,
4707                                             &alias_rids, &num_alias_rids);
4708         unbecome_root();
4709
4710         if (!NT_STATUS_IS_OK(status)) {
4711                 return status;
4712         }
4713
4714         r->out.rids->count = num_alias_rids;
4715         r->out.rids->ids = alias_rids;
4716
4717         return NT_STATUS_OK;
4718 }
4719
4720 /*********************************************************************
4721  _samr_GetMembersInAlias
4722 *********************************************************************/
4723
4724 NTSTATUS _samr_GetMembersInAlias(pipes_struct *p,
4725                                  struct samr_GetMembersInAlias *r)
4726 {
4727         struct samr_alias_info *ainfo;
4728         NTSTATUS status;
4729         size_t i;
4730         size_t num_sids = 0;
4731         struct lsa_SidPtr *sids = NULL;
4732         DOM_SID *pdb_sids = NULL;
4733
4734         ainfo = policy_handle_find(p, r->in.alias_handle,
4735                                    SAMR_ALIAS_ACCESS_GET_MEMBERS, NULL,
4736                                    struct samr_alias_info, &status);
4737         if (!NT_STATUS_IS_OK(status)) {
4738                 return status;
4739         }
4740
4741         DEBUG(10, ("sid is %s\n", sid_string_dbg(&ainfo->sid)));
4742
4743         become_root();
4744         status = pdb_enum_aliasmem(&ainfo->sid, &pdb_sids, &num_sids);
4745         unbecome_root();
4746
4747         if (!NT_STATUS_IS_OK(status)) {
4748                 return status;
4749         }
4750
4751         if (num_sids) {
4752                 sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_SidPtr, num_sids);
4753                 if (sids == NULL) {
4754                         TALLOC_FREE(pdb_sids);
4755                         return NT_STATUS_NO_MEMORY;
4756                 }
4757         }
4758
4759         for (i = 0; i < num_sids; i++) {
4760                 sids[i].sid = sid_dup_talloc(p->mem_ctx, &pdb_sids[i]);
4761                 if (!sids[i].sid) {
4762                         TALLOC_FREE(pdb_sids);
4763                         return NT_STATUS_NO_MEMORY;
4764                 }
4765         }
4766
4767         r->out.sids->num_sids = num_sids;
4768         r->out.sids->sids = sids;
4769
4770         TALLOC_FREE(pdb_sids);
4771
4772         return NT_STATUS_OK;
4773 }
4774
4775 /*********************************************************************
4776  _samr_QueryGroupMember
4777 *********************************************************************/
4778
4779 NTSTATUS _samr_QueryGroupMember(pipes_struct *p,
4780                                 struct samr_QueryGroupMember *r)
4781 {
4782         struct samr_group_info *ginfo;
4783         size_t i, num_members;
4784
4785         uint32 *rid=NULL;
4786         uint32 *attr=NULL;
4787
4788         NTSTATUS status;
4789         struct samr_RidTypeArray *rids = NULL;
4790
4791         ginfo = policy_handle_find(p, r->in.group_handle,
4792                                    SAMR_GROUP_ACCESS_GET_MEMBERS, NULL,
4793                                    struct samr_group_info, &status);
4794         if (!NT_STATUS_IS_OK(status)) {
4795                 return status;
4796         }
4797
4798         rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidTypeArray);
4799         if (!rids) {
4800                 return NT_STATUS_NO_MEMORY;
4801         }
4802
4803         DEBUG(10, ("sid is %s\n", sid_string_dbg(&ginfo->sid)));
4804
4805         if (!sid_check_is_in_our_domain(&ginfo->sid)) {
4806                 DEBUG(3, ("sid %s is not in our domain\n",
4807                           sid_string_dbg(&ginfo->sid)));
4808                 return NT_STATUS_NO_SUCH_GROUP;
4809         }
4810
4811         DEBUG(10, ("lookup on Domain SID\n"));
4812
4813         become_root();
4814         status = pdb_enum_group_members(p->mem_ctx, &ginfo->sid,
4815                                         &rid, &num_members);
4816         unbecome_root();
4817
4818         if (!NT_STATUS_IS_OK(status))
4819                 return status;
4820
4821         if (num_members) {
4822                 attr=TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_members);
4823                 if (attr == NULL) {
4824                         return NT_STATUS_NO_MEMORY;
4825                 }
4826         } else {
4827                 attr = NULL;
4828         }
4829
4830         for (i=0; i<num_members; i++)
4831                 attr[i] = SID_NAME_USER;
4832
4833         rids->count = num_members;
4834         rids->types = attr;
4835         rids->rids = rid;
4836
4837         *r->out.rids = rids;
4838
4839         return NT_STATUS_OK;
4840 }
4841
4842 /*********************************************************************
4843  _samr_AddAliasMember
4844 *********************************************************************/
4845
4846 NTSTATUS _samr_AddAliasMember(pipes_struct *p,
4847                               struct samr_AddAliasMember *r)
4848 {
4849         struct samr_alias_info *ainfo;
4850         SE_PRIV se_rights;
4851         bool can_add_accounts;
4852         NTSTATUS status;
4853
4854         ainfo = policy_handle_find(p, r->in.alias_handle,
4855                                    SAMR_ALIAS_ACCESS_ADD_MEMBER, NULL,
4856                                    struct samr_alias_info, &status);
4857         if (!NT_STATUS_IS_OK(status)) {
4858                 return status;
4859         }
4860
4861         DEBUG(10, ("sid is %s\n", sid_string_dbg(&ainfo->sid)));
4862
4863         se_priv_copy( &se_rights, &se_add_users );
4864         can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
4865
4866         /******** BEGIN SeAddUsers BLOCK *********/
4867
4868         if ( can_add_accounts )
4869                 become_root();
4870
4871         status = pdb_add_aliasmem(&ainfo->sid, r->in.sid);
4872
4873         if ( can_add_accounts )
4874                 unbecome_root();
4875
4876         /******** END SeAddUsers BLOCK *********/
4877
4878         if (NT_STATUS_IS_OK(status)) {
4879                 force_flush_samr_cache(&ainfo->sid);
4880         }
4881
4882         return status;
4883 }
4884
4885 /*********************************************************************
4886  _samr_DeleteAliasMember
4887 *********************************************************************/
4888
4889 NTSTATUS _samr_DeleteAliasMember(pipes_struct *p,
4890                                  struct samr_DeleteAliasMember *r)
4891 {
4892         struct samr_alias_info *ainfo;
4893         SE_PRIV se_rights;
4894         bool can_add_accounts;
4895         NTSTATUS status;
4896
4897         ainfo = policy_handle_find(p, r->in.alias_handle,
4898                                    SAMR_ALIAS_ACCESS_REMOVE_MEMBER, NULL,
4899                                    struct samr_alias_info, &status);
4900         if (!NT_STATUS_IS_OK(status)) {
4901                 return status;
4902         }
4903
4904         DEBUG(10, ("_samr_del_aliasmem:sid is %s\n",
4905                    sid_string_dbg(&ainfo->sid)));
4906
4907         se_priv_copy( &se_rights, &se_add_users );
4908         can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
4909
4910         /******** BEGIN SeAddUsers BLOCK *********/
4911
4912         if ( can_add_accounts )
4913                 become_root();
4914
4915         status = pdb_del_aliasmem(&ainfo->sid, r->in.sid);
4916
4917         if ( can_add_accounts )
4918                 unbecome_root();
4919
4920         /******** END SeAddUsers BLOCK *********/
4921
4922         if (NT_STATUS_IS_OK(status)) {
4923                 force_flush_samr_cache(&ainfo->sid);
4924         }
4925
4926         return status;
4927 }
4928
4929 /*********************************************************************
4930  _samr_AddGroupMember
4931 *********************************************************************/
4932
4933 NTSTATUS _samr_AddGroupMember(pipes_struct *p,
4934                               struct samr_AddGroupMember *r)
4935 {
4936         struct samr_group_info *ginfo;
4937         NTSTATUS status;
4938         uint32 group_rid;
4939         SE_PRIV se_rights;
4940         bool can_add_accounts;
4941
4942         ginfo = policy_handle_find(p, r->in.group_handle,
4943                                    SAMR_GROUP_ACCESS_ADD_MEMBER, NULL,
4944                                    struct samr_group_info, &status);
4945         if (!NT_STATUS_IS_OK(status)) {
4946                 return status;
4947         }
4948
4949         DEBUG(10, ("sid is %s\n", sid_string_dbg(&ginfo->sid)));
4950
4951         if (!sid_peek_check_rid(get_global_sam_sid(), &ginfo->sid,
4952                                 &group_rid)) {
4953                 return NT_STATUS_INVALID_HANDLE;
4954         }
4955
4956         se_priv_copy( &se_rights, &se_add_users );
4957         can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
4958
4959         /******** BEGIN SeAddUsers BLOCK *********/
4960
4961         if ( can_add_accounts )
4962                 become_root();
4963
4964         status = pdb_add_groupmem(p->mem_ctx, group_rid, r->in.rid);
4965
4966         if ( can_add_accounts )
4967                 unbecome_root();
4968
4969         /******** END SeAddUsers BLOCK *********/
4970
4971         force_flush_samr_cache(&ginfo->sid);
4972
4973         return status;
4974 }
4975
4976 /*********************************************************************
4977  _samr_DeleteGroupMember
4978 *********************************************************************/
4979
4980 NTSTATUS _samr_DeleteGroupMember(pipes_struct *p,
4981                                  struct samr_DeleteGroupMember *r)
4982
4983 {
4984         struct samr_group_info *ginfo;
4985         NTSTATUS status;
4986         uint32 group_rid;
4987         SE_PRIV se_rights;
4988         bool can_add_accounts;
4989
4990         /*
4991          * delete the group member named r->in.rid
4992          * who is a member of the sid associated with the handle
4993          * the rid is a user's rid as the group is a domain group.
4994          */
4995
4996         ginfo = policy_handle_find(p, r->in.group_handle,
4997                                    SAMR_GROUP_ACCESS_REMOVE_MEMBER, NULL,
4998                                    struct samr_group_info, &status);
4999         if (!NT_STATUS_IS_OK(status)) {
5000                 return status;
5001         }
5002
5003         if (!sid_peek_check_rid(get_global_sam_sid(), &ginfo->sid,
5004                                 &group_rid)) {
5005                 return NT_STATUS_INVALID_HANDLE;
5006         }
5007
5008         se_priv_copy( &se_rights, &se_add_users );
5009         can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
5010
5011         /******** BEGIN SeAddUsers BLOCK *********/
5012
5013         if ( can_add_accounts )
5014                 become_root();
5015
5016         status = pdb_del_groupmem(p->mem_ctx, group_rid, r->in.rid);
5017
5018         if ( can_add_accounts )
5019                 unbecome_root();
5020
5021         /******** END SeAddUsers BLOCK *********/
5022
5023         force_flush_samr_cache(&ginfo->sid);
5024
5025         return status;
5026 }
5027
5028 /*********************************************************************
5029  _samr_DeleteUser
5030 *********************************************************************/
5031
5032 NTSTATUS _samr_DeleteUser(pipes_struct *p,
5033                           struct samr_DeleteUser *r)
5034 {
5035         struct samr_user_info *uinfo;
5036         NTSTATUS status;
5037         struct samu *sam_pass=NULL;
5038         bool can_add_accounts;
5039         uint32 acb_info;
5040         bool ret;
5041
5042         DEBUG(5, ("_samr_DeleteUser: %d\n", __LINE__));
5043
5044         uinfo = policy_handle_find(p, r->in.user_handle,
5045                                    STD_RIGHT_DELETE_ACCESS, NULL,
5046                                    struct samr_user_info, &status);
5047         if (!NT_STATUS_IS_OK(status)) {
5048                 return status;
5049         }
5050
5051         if (!sid_check_is_in_our_domain(&uinfo->sid))
5052                 return NT_STATUS_CANNOT_DELETE;
5053
5054         /* check if the user exists before trying to delete */
5055         if ( !(sam_pass = samu_new( NULL )) ) {
5056                 return NT_STATUS_NO_MEMORY;
5057         }
5058
5059         become_root();
5060         ret = pdb_getsampwsid(sam_pass, &uinfo->sid);
5061         unbecome_root();
5062
5063         if( !ret ) {
5064                 DEBUG(5,("_samr_DeleteUser: User %s doesn't exist.\n",
5065                         sid_string_dbg(&uinfo->sid)));
5066                 TALLOC_FREE(sam_pass);
5067                 return NT_STATUS_NO_SUCH_USER;
5068         }
5069
5070         acb_info = pdb_get_acct_ctrl(sam_pass);
5071
5072         /* For machine accounts it's the SeMachineAccountPrivilege that counts. */
5073         if ( acb_info & ACB_WSTRUST ) {
5074                 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_machine_account );
5075         } else {
5076                 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_add_users );
5077         }
5078
5079         /******** BEGIN SeAddUsers BLOCK *********/
5080
5081         if ( can_add_accounts )
5082                 become_root();
5083
5084         status = pdb_delete_user(p->mem_ctx, sam_pass);
5085
5086         if ( can_add_accounts )
5087                 unbecome_root();
5088
5089         /******** END SeAddUsers BLOCK *********/
5090
5091         if ( !NT_STATUS_IS_OK(status) ) {
5092                 DEBUG(5,("_samr_DeleteUser: Failed to delete entry for "
5093                          "user %s: %s.\n", pdb_get_username(sam_pass),
5094                          nt_errstr(status)));
5095                 TALLOC_FREE(sam_pass);
5096                 return status;
5097         }
5098
5099
5100         TALLOC_FREE(sam_pass);
5101
5102         if (!close_policy_hnd(p, r->in.user_handle))
5103                 return NT_STATUS_OBJECT_NAME_INVALID;
5104
5105         ZERO_STRUCTP(r->out.user_handle);
5106
5107         force_flush_samr_cache(&uinfo->sid);
5108
5109         return NT_STATUS_OK;
5110 }
5111
5112 /*********************************************************************
5113  _samr_DeleteDomainGroup
5114 *********************************************************************/
5115
5116 NTSTATUS _samr_DeleteDomainGroup(pipes_struct *p,
5117                                  struct samr_DeleteDomainGroup *r)
5118 {
5119         struct samr_group_info *ginfo;
5120         NTSTATUS status;
5121         uint32 group_rid;
5122         SE_PRIV se_rights;
5123         bool can_add_accounts;
5124
5125         DEBUG(5, ("samr_DeleteDomainGroup: %d\n", __LINE__));
5126
5127         ginfo = policy_handle_find(p, r->in.group_handle,
5128                                    STD_RIGHT_DELETE_ACCESS, NULL,
5129                                    struct samr_group_info, &status);
5130         if (!NT_STATUS_IS_OK(status)) {
5131                 return status;
5132         }
5133
5134         DEBUG(10, ("sid is %s\n", sid_string_dbg(&ginfo->sid)));
5135
5136         if (!sid_peek_check_rid(get_global_sam_sid(), &ginfo->sid,
5137                                 &group_rid)) {
5138                 return NT_STATUS_NO_SUCH_GROUP;
5139         }
5140
5141         se_priv_copy( &se_rights, &se_add_users );
5142         can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
5143
5144         /******** BEGIN SeAddUsers BLOCK *********/
5145
5146         if ( can_add_accounts )
5147                 become_root();
5148
5149         status = pdb_delete_dom_group(p->mem_ctx, group_rid);
5150
5151         if ( can_add_accounts )
5152                 unbecome_root();
5153
5154         /******** END SeAddUsers BLOCK *********/
5155
5156         if ( !NT_STATUS_IS_OK(status) ) {
5157                 DEBUG(5,("_samr_DeleteDomainGroup: Failed to delete mapping "
5158                          "entry for group %s: %s\n",
5159                          sid_string_dbg(&ginfo->sid),
5160                          nt_errstr(status)));
5161                 return status;
5162         }
5163
5164         if (!close_policy_hnd(p, r->in.group_handle))
5165                 return NT_STATUS_OBJECT_NAME_INVALID;
5166
5167         force_flush_samr_cache(&ginfo->sid);
5168
5169         return NT_STATUS_OK;
5170 }
5171
5172 /*********************************************************************
5173  _samr_DeleteDomAlias
5174 *********************************************************************/
5175
5176 NTSTATUS _samr_DeleteDomAlias(pipes_struct *p,
5177                               struct samr_DeleteDomAlias *r)
5178 {
5179         struct samr_alias_info *ainfo;
5180         SE_PRIV se_rights;
5181         bool can_add_accounts;
5182         NTSTATUS status;
5183
5184         DEBUG(5, ("_samr_DeleteDomAlias: %d\n", __LINE__));
5185
5186         ainfo = policy_handle_find(p, r->in.alias_handle,
5187                                    STD_RIGHT_DELETE_ACCESS, NULL,
5188                                    struct samr_alias_info, &status);
5189         if (!NT_STATUS_IS_OK(status)) {
5190                 return status;
5191         }
5192
5193         DEBUG(10, ("sid is %s\n", sid_string_dbg(&ainfo->sid)));
5194
5195         /* Don't let Windows delete builtin groups */
5196
5197         if ( sid_check_is_in_builtin( &ainfo->sid ) ) {
5198                 return NT_STATUS_SPECIAL_ACCOUNT;
5199         }
5200
5201         if (!sid_check_is_in_our_domain(&ainfo->sid))
5202                 return NT_STATUS_NO_SUCH_ALIAS;
5203
5204         DEBUG(10, ("lookup on Local SID\n"));
5205
5206         se_priv_copy( &se_rights, &se_add_users );
5207         can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
5208
5209         /******** BEGIN SeAddUsers BLOCK *********/
5210
5211         if ( can_add_accounts )
5212                 become_root();
5213
5214         /* Have passdb delete the alias */
5215         status = pdb_delete_alias(&ainfo->sid);
5216
5217         if ( can_add_accounts )
5218                 unbecome_root();
5219
5220         /******** END SeAddUsers BLOCK *********/
5221
5222         if ( !NT_STATUS_IS_OK(status))
5223                 return status;
5224
5225         if (!close_policy_hnd(p, r->in.alias_handle))
5226                 return NT_STATUS_OBJECT_NAME_INVALID;
5227
5228         force_flush_samr_cache(&ainfo->sid);
5229
5230         return NT_STATUS_OK;
5231 }
5232
5233 /*********************************************************************
5234  _samr_CreateDomainGroup
5235 *********************************************************************/
5236
5237 NTSTATUS _samr_CreateDomainGroup(pipes_struct *p,
5238                                  struct samr_CreateDomainGroup *r)
5239
5240 {
5241         NTSTATUS status;
5242         const char *name;
5243         struct samr_domain_info *dinfo;
5244         struct samr_group_info *ginfo;
5245         SE_PRIV se_rights;
5246         bool can_add_accounts;
5247
5248         dinfo = policy_handle_find(p, r->in.domain_handle,
5249                                    SAMR_DOMAIN_ACCESS_CREATE_GROUP, NULL,
5250                                    struct samr_domain_info, &status);
5251         if (!NT_STATUS_IS_OK(status)) {
5252                 return status;
5253         }
5254
5255         if (!sid_equal(&dinfo->sid, get_global_sam_sid()))
5256                 return NT_STATUS_ACCESS_DENIED;
5257
5258         name = r->in.name->string;
5259         if (name == NULL) {
5260                 return NT_STATUS_NO_MEMORY;
5261         }
5262
5263         status = can_create(p->mem_ctx, name);
5264         if (!NT_STATUS_IS_OK(status)) {
5265                 return status;
5266         }
5267
5268         se_priv_copy( &se_rights, &se_add_users );
5269         can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
5270
5271         /******** BEGIN SeAddUsers BLOCK *********/
5272
5273         if ( can_add_accounts )
5274                 become_root();
5275
5276         /* check that we successfully create the UNIX group */
5277
5278         status = pdb_create_dom_group(p->mem_ctx, name, r->out.rid);
5279
5280         if ( can_add_accounts )
5281                 unbecome_root();
5282
5283         /******** END SeAddUsers BLOCK *********/
5284
5285         /* check if we should bail out here */
5286
5287         if ( !NT_STATUS_IS_OK(status) )
5288                 return status;
5289
5290         ginfo = policy_handle_create(p, r->out.group_handle,
5291                                      GENERIC_RIGHTS_GROUP_ALL_ACCESS,
5292                                      struct samr_group_info, &status);
5293         if (!NT_STATUS_IS_OK(status)) {
5294                 return status;
5295         }
5296         sid_compose(&ginfo->sid, &dinfo->sid, *r->out.rid);
5297
5298         force_flush_samr_cache(&dinfo->sid);
5299
5300         return NT_STATUS_OK;
5301 }
5302
5303 /*********************************************************************
5304  _samr_CreateDomAlias
5305 *********************************************************************/
5306
5307 NTSTATUS _samr_CreateDomAlias(pipes_struct *p,
5308                               struct samr_CreateDomAlias *r)
5309 {
5310         DOM_SID info_sid;
5311         const char *name = NULL;
5312         struct samr_domain_info *dinfo;
5313         struct samr_alias_info *ainfo;
5314         gid_t gid;
5315         NTSTATUS result;
5316         SE_PRIV se_rights;
5317         bool can_add_accounts;
5318
5319         dinfo = policy_handle_find(p, r->in.domain_handle,
5320                                    SAMR_DOMAIN_ACCESS_CREATE_ALIAS, NULL,
5321                                    struct samr_domain_info, &result);
5322         if (!NT_STATUS_IS_OK(result)) {
5323                 return result;
5324         }
5325
5326         if (!sid_equal(&dinfo->sid, get_global_sam_sid()))
5327                 return NT_STATUS_ACCESS_DENIED;
5328
5329         name = r->in.alias_name->string;
5330
5331         se_priv_copy( &se_rights, &se_add_users );
5332         can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
5333
5334         result = can_create(p->mem_ctx, name);
5335         if (!NT_STATUS_IS_OK(result)) {
5336                 return result;
5337         }
5338
5339         /******** BEGIN SeAddUsers BLOCK *********/
5340
5341         if ( can_add_accounts )
5342                 become_root();
5343
5344         /* Have passdb create the alias */
5345         result = pdb_create_alias(name, r->out.rid);
5346
5347         if ( can_add_accounts )
5348                 unbecome_root();
5349
5350         /******** END SeAddUsers BLOCK *********/
5351
5352         if (!NT_STATUS_IS_OK(result)) {
5353                 DEBUG(10, ("pdb_create_alias failed: %s\n",
5354                            nt_errstr(result)));
5355                 return result;
5356         }
5357
5358         sid_compose(&info_sid, &dinfo->sid, *r->out.rid);
5359
5360         if (!sid_to_gid(&info_sid, &gid)) {
5361                 DEBUG(10, ("Could not find alias just created\n"));
5362                 return NT_STATUS_ACCESS_DENIED;
5363         }
5364
5365         /* check if the group has been successfully created */
5366         if ( getgrgid(gid) == NULL ) {
5367                 DEBUG(10, ("getgrgid(%d) of just created alias failed\n",
5368                            gid));
5369                 return NT_STATUS_ACCESS_DENIED;
5370         }
5371
5372         ainfo = policy_handle_create(p, r->out.alias_handle,
5373                                      GENERIC_RIGHTS_ALIAS_ALL_ACCESS,
5374                                      struct samr_alias_info, &result);
5375         if (!NT_STATUS_IS_OK(result)) {
5376                 return result;
5377         }
5378         ainfo->sid = info_sid;
5379
5380         force_flush_samr_cache(&info_sid);
5381
5382         return NT_STATUS_OK;
5383 }
5384
5385 /*********************************************************************
5386  _samr_QueryGroupInfo
5387 *********************************************************************/
5388
5389 NTSTATUS _samr_QueryGroupInfo(pipes_struct *p,
5390                               struct samr_QueryGroupInfo *r)
5391 {
5392         struct samr_group_info *ginfo;
5393         NTSTATUS status;
5394         GROUP_MAP map;
5395         union samr_GroupInfo *info = NULL;
5396         bool ret;
5397         uint32_t attributes = SE_GROUP_MANDATORY |
5398                               SE_GROUP_ENABLED_BY_DEFAULT |
5399                               SE_GROUP_ENABLED;
5400         const char *group_name = NULL;
5401         const char *group_description = NULL;
5402
5403         ginfo = policy_handle_find(p, r->in.group_handle,
5404                                    SAMR_GROUP_ACCESS_LOOKUP_INFO, NULL,
5405                                    struct samr_group_info, &status);
5406         if (!NT_STATUS_IS_OK(status)) {
5407                 return status;
5408         }
5409
5410         become_root();
5411         ret = get_domain_group_from_sid(ginfo->sid, &map);
5412         unbecome_root();
5413         if (!ret)
5414                 return NT_STATUS_INVALID_HANDLE;
5415
5416         /* FIXME: map contains fstrings */
5417         group_name = talloc_strdup(r, map.nt_name);
5418         group_description = talloc_strdup(r, map.comment);
5419
5420         info = TALLOC_ZERO_P(p->mem_ctx, union samr_GroupInfo);
5421         if (!info) {
5422                 return NT_STATUS_NO_MEMORY;
5423         }
5424
5425         switch (r->in.level) {
5426                 case 1: {
5427                         uint32 *members;
5428                         size_t num_members;
5429
5430                         become_root();
5431                         status = pdb_enum_group_members(
5432                                 p->mem_ctx, &ginfo->sid, &members,
5433                                 &num_members);
5434                         unbecome_root();
5435
5436                         if (!NT_STATUS_IS_OK(status)) {
5437                                 return status;
5438                         }
5439
5440                         info->all.name.string           = group_name;
5441                         info->all.attributes            = attributes;
5442                         info->all.num_members           = num_members;
5443                         info->all.description.string    = group_description;
5444                         break;
5445                 }
5446                 case 2:
5447                         info->name.string = group_name;
5448                         break;
5449                 case 3:
5450                         info->attributes.attributes = attributes;
5451                         break;
5452                 case 4:
5453                         info->description.string = group_description;
5454                         break;
5455                 case 5: {
5456                         /*
5457                         uint32 *members;
5458                         size_t num_members;
5459                         */
5460
5461                         /*
5462                         become_root();
5463                         status = pdb_enum_group_members(
5464                                 p->mem_ctx, &ginfo->sid, &members,
5465                                 &num_members);
5466                         unbecome_root();
5467
5468                         if (!NT_STATUS_IS_OK(status)) {
5469                                 return status;
5470                         }
5471                         */
5472                         info->all2.name.string          = group_name;
5473                         info->all2.attributes           = attributes;
5474                         info->all2.num_members          = 0; /* num_members - in w2k3 this is always 0 */
5475                         info->all2.description.string   = group_description;
5476
5477                         break;
5478                 }
5479                 default:
5480                         return NT_STATUS_INVALID_INFO_CLASS;
5481         }
5482
5483         *r->out.info = info;
5484
5485         return NT_STATUS_OK;
5486 }
5487
5488 /*********************************************************************
5489  _samr_SetGroupInfo
5490 *********************************************************************/
5491
5492 NTSTATUS _samr_SetGroupInfo(pipes_struct *p,
5493                             struct samr_SetGroupInfo *r)
5494 {
5495         struct samr_group_info *ginfo;
5496         GROUP_MAP map;
5497         NTSTATUS status;
5498         bool ret;
5499         bool can_mod_accounts;
5500
5501         ginfo = policy_handle_find(p, r->in.group_handle,
5502                                    SAMR_GROUP_ACCESS_SET_INFO, NULL,
5503                                    struct samr_group_info, &status);
5504         if (!NT_STATUS_IS_OK(status)) {
5505                 return status;
5506         }
5507
5508         become_root();
5509         ret = get_domain_group_from_sid(ginfo->sid, &map);
5510         unbecome_root();
5511         if (!ret)
5512                 return NT_STATUS_NO_SUCH_GROUP;
5513
5514         switch (r->in.level) {
5515                 case 1:
5516                         fstrcpy(map.comment, r->in.info->all.description.string);
5517                         break;
5518                 case 2:
5519                         /* group rename is not supported yet */
5520                         return NT_STATUS_NOT_SUPPORTED;
5521                 case 4:
5522                         fstrcpy(map.comment, r->in.info->description.string);
5523                         break;
5524                 default:
5525                         return NT_STATUS_INVALID_INFO_CLASS;
5526         }
5527
5528         can_mod_accounts = user_has_privileges( p->server_info->ptok, &se_add_users );
5529
5530         /******** BEGIN SeAddUsers BLOCK *********/
5531
5532         if ( can_mod_accounts )
5533                 become_root();
5534
5535         status = pdb_update_group_mapping_entry(&map);
5536
5537         if ( can_mod_accounts )
5538                 unbecome_root();
5539
5540         /******** End SeAddUsers BLOCK *********/
5541
5542         if (NT_STATUS_IS_OK(status)) {
5543                 force_flush_samr_cache(&ginfo->sid);
5544         }
5545
5546         return status;
5547 }
5548
5549 /*********************************************************************
5550  _samr_SetAliasInfo
5551 *********************************************************************/
5552
5553 NTSTATUS _samr_SetAliasInfo(pipes_struct *p,
5554                             struct samr_SetAliasInfo *r)
5555 {
5556         struct samr_alias_info *ainfo;
5557         struct acct_info info;
5558         bool can_mod_accounts;
5559         NTSTATUS status;
5560
5561         ainfo = policy_handle_find(p, r->in.alias_handle,
5562                                    SAMR_ALIAS_ACCESS_SET_INFO, NULL,
5563                                    struct samr_alias_info, &status);
5564         if (!NT_STATUS_IS_OK(status)) {
5565                 return status;
5566         }
5567
5568         /* get the current group information */
5569
5570         become_root();
5571         status = pdb_get_aliasinfo( &ainfo->sid, &info );
5572         unbecome_root();
5573
5574         if ( !NT_STATUS_IS_OK(status))
5575                 return status;
5576
5577         switch (r->in.level) {
5578                 case ALIASINFONAME:
5579                 {
5580                         fstring group_name;
5581
5582                         /* We currently do not support renaming groups in the
5583                            the BUILTIN domain.  Refer to util_builtin.c to understand
5584                            why.  The eventually needs to be fixed to be like Windows
5585                            where you can rename builtin groups, just not delete them */
5586
5587                         if ( sid_check_is_in_builtin( &ainfo->sid ) ) {
5588                                 return NT_STATUS_SPECIAL_ACCOUNT;
5589                         }
5590
5591                         /* There has to be a valid name (and it has to be different) */
5592
5593                         if ( !r->in.info->name.string )
5594                                 return NT_STATUS_INVALID_PARAMETER;
5595
5596                         /* If the name is the same just reply "ok".  Yes this
5597                            doesn't allow you to change the case of a group name. */
5598
5599                         if ( strequal( r->in.info->name.string, info.acct_name ) )
5600                                 return NT_STATUS_OK;
5601
5602                         fstrcpy( info.acct_name, r->in.info->name.string);
5603
5604                         /* make sure the name doesn't already exist as a user
5605                            or local group */
5606
5607                         fstr_sprintf( group_name, "%s\\%s", global_myname(), info.acct_name );
5608                         status = can_create( p->mem_ctx, group_name );
5609                         if ( !NT_STATUS_IS_OK( status ) )
5610                                 return status;
5611                         break;
5612                 }
5613                 case ALIASINFODESCRIPTION:
5614                         if (r->in.info->description.string) {
5615                                 fstrcpy(info.acct_desc,
5616                                         r->in.info->description.string);
5617                         } else {
5618                                 fstrcpy( info.acct_desc, "" );
5619                         }
5620                         break;
5621                 default:
5622                         return NT_STATUS_INVALID_INFO_CLASS;
5623         }
5624
5625         can_mod_accounts = user_has_privileges( p->server_info->ptok, &se_add_users );
5626
5627         /******** BEGIN SeAddUsers BLOCK *********/
5628
5629         if ( can_mod_accounts )
5630                 become_root();
5631
5632         status = pdb_set_aliasinfo( &ainfo->sid, &info );
5633
5634         if ( can_mod_accounts )
5635                 unbecome_root();
5636
5637         /******** End SeAddUsers BLOCK *********/
5638
5639         if (NT_STATUS_IS_OK(status))
5640                 force_flush_samr_cache(&ainfo->sid);
5641
5642         return status;
5643 }
5644
5645 /****************************************************************
5646  _samr_GetDomPwInfo
5647 ****************************************************************/
5648
5649 NTSTATUS _samr_GetDomPwInfo(pipes_struct *p,
5650                             struct samr_GetDomPwInfo *r)
5651 {
5652         uint32_t min_password_length = 0;
5653         uint32_t password_properties = 0;
5654
5655         /* Perform access check.  Since this rpc does not require a
5656            policy handle it will not be caught by the access checks on
5657            SAMR_CONNECT or SAMR_CONNECT_ANON. */
5658
5659         if (!pipe_access_check(p)) {
5660                 DEBUG(3, ("access denied to _samr_GetDomPwInfo\n"));
5661                 return NT_STATUS_ACCESS_DENIED;
5662         }
5663
5664         become_root();
5665         pdb_get_account_policy(AP_MIN_PASSWORD_LEN,
5666                                &min_password_length);
5667         pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
5668                                &password_properties);
5669         unbecome_root();
5670
5671         if (lp_check_password_script() && *lp_check_password_script()) {
5672                 password_properties |= DOMAIN_PASSWORD_COMPLEX;
5673         }
5674
5675         r->out.info->min_password_length = min_password_length;
5676         r->out.info->password_properties = password_properties;
5677
5678         return NT_STATUS_OK;
5679 }
5680
5681 /*********************************************************************
5682  _samr_OpenGroup
5683 *********************************************************************/
5684
5685 NTSTATUS _samr_OpenGroup(pipes_struct *p,
5686                          struct samr_OpenGroup *r)
5687
5688 {
5689         DOM_SID info_sid;
5690         GROUP_MAP map;
5691         struct samr_domain_info *dinfo;
5692         struct samr_group_info *ginfo;
5693         SEC_DESC         *psd = NULL;
5694         uint32            acc_granted;
5695         uint32            des_access = r->in.access_mask;
5696         size_t            sd_size;
5697         NTSTATUS          status;
5698         bool ret;
5699         SE_PRIV se_rights;
5700
5701         dinfo = policy_handle_find(p, r->in.domain_handle,
5702                                    SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
5703                                    struct samr_domain_info, &status);
5704         if (!NT_STATUS_IS_OK(status)) {
5705                 return status;
5706         }
5707
5708         /*check if access can be granted as requested by client. */
5709         map_max_allowed_access(p->server_info->ptok, &des_access);
5710
5711         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &grp_generic_mapping, NULL, 0);
5712         se_map_generic(&des_access,&grp_generic_mapping);
5713
5714         se_priv_copy( &se_rights, &se_add_users );
5715
5716         status = access_check_samr_object(psd, p->server_info->ptok,
5717                 &se_rights, GENERIC_RIGHTS_GROUP_WRITE, des_access,
5718                 &acc_granted, "_samr_OpenGroup");
5719
5720         if ( !NT_STATUS_IS_OK(status) )
5721                 return status;
5722
5723         /* this should not be hard-coded like this */
5724
5725         if (!sid_equal(&dinfo->sid, get_global_sam_sid()))
5726                 return NT_STATUS_ACCESS_DENIED;
5727
5728         sid_compose(&info_sid, &dinfo->sid, r->in.rid);
5729
5730         DEBUG(10, ("_samr_OpenGroup:Opening SID: %s\n",
5731                    sid_string_dbg(&info_sid)));
5732
5733         /* check if that group really exists */
5734         become_root();
5735         ret = get_domain_group_from_sid(info_sid, &map);
5736         unbecome_root();
5737         if (!ret)
5738                 return NT_STATUS_NO_SUCH_GROUP;
5739
5740         ginfo = policy_handle_create(p, r->out.group_handle,
5741                                      GENERIC_RIGHTS_GROUP_ALL_ACCESS,
5742                                      struct samr_group_info, &status);
5743         if (!NT_STATUS_IS_OK(status)) {
5744                 return status;
5745         }
5746         ginfo->sid = info_sid;
5747
5748         return NT_STATUS_OK;
5749 }
5750
5751 /*********************************************************************
5752  _samr_RemoveMemberFromForeignDomain
5753 *********************************************************************/
5754
5755 NTSTATUS _samr_RemoveMemberFromForeignDomain(pipes_struct *p,
5756                                              struct samr_RemoveMemberFromForeignDomain *r)
5757 {
5758         struct samr_domain_info *dinfo;
5759         NTSTATUS                result;
5760
5761         DEBUG(5,("_samr_RemoveMemberFromForeignDomain: removing SID [%s]\n",
5762                  sid_string_dbg(r->in.sid)));
5763
5764         /* Find the policy handle. Open a policy on it. */
5765
5766         dinfo = policy_handle_find(p, r->in.domain_handle,
5767                                    STD_RIGHT_DELETE_ACCESS, NULL,
5768                                    struct samr_domain_info, &result);
5769         if (!NT_STATUS_IS_OK(result)) {
5770                 return result;
5771         }
5772
5773         DEBUG(8, ("_samr_RemoveMemberFromForeignDomain: sid is %s\n",
5774                   sid_string_dbg(&dinfo->sid)));
5775
5776         /* we can only delete a user from a group since we don't have
5777            nested groups anyways.  So in the latter case, just say OK */
5778
5779         /* TODO: The above comment nowadays is bogus. Since we have nested
5780          * groups now, and aliases members are never reported out of the unix
5781          * group membership, the "just say OK" makes this call a no-op. For
5782          * us. This needs fixing however. */
5783
5784         /* I've only ever seen this in the wild when deleting a user from
5785          * usrmgr.exe. domain_sid is the builtin domain, and the sid to delete
5786          * is the user about to be deleted. I very much suspect this is the
5787          * only application of this call. To verify this, let people report
5788          * other cases. */
5789
5790         if (!sid_check_is_builtin(&dinfo->sid)) {
5791                 DEBUG(1,("_samr_RemoveMemberFromForeignDomain: domain_sid = %s, "
5792                          "global_sam_sid() = %s\n",
5793                          sid_string_dbg(&dinfo->sid),
5794                          sid_string_dbg(get_global_sam_sid())));
5795                 DEBUGADD(1,("please report to samba-technical@samba.org!\n"));
5796                 return NT_STATUS_OK;
5797         }
5798
5799         force_flush_samr_cache(&dinfo->sid);
5800
5801         result = NT_STATUS_OK;
5802
5803         return result;
5804 }
5805
5806 /*******************************************************************
5807  _samr_QueryDomainInfo2
5808  ********************************************************************/
5809
5810 NTSTATUS _samr_QueryDomainInfo2(pipes_struct *p,
5811                                 struct samr_QueryDomainInfo2 *r)
5812 {
5813         struct samr_QueryDomainInfo q;
5814
5815         q.in.domain_handle      = r->in.domain_handle;
5816         q.in.level              = r->in.level;
5817
5818         q.out.info              = r->out.info;
5819
5820         return _samr_QueryDomainInfo(p, &q);
5821 }
5822
5823 /*******************************************************************
5824  _samr_SetDomainInfo
5825  ********************************************************************/
5826
5827 NTSTATUS _samr_SetDomainInfo(pipes_struct *p,
5828                              struct samr_SetDomainInfo *r)
5829 {
5830         struct samr_domain_info *dinfo;
5831         time_t u_expire, u_min_age;
5832         time_t u_logout;
5833         time_t u_lock_duration, u_reset_time;
5834         NTSTATUS result;
5835
5836         DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
5837
5838         /* We do have different access bits for info
5839          * levels here, but we're really just looking for
5840          * GENERIC_RIGHTS_DOMAIN_WRITE access. Unfortunately
5841          * this maps to different specific bits. So
5842          * assume if we have SAMR_DOMAIN_ACCESS_SET_INFO_1
5843          * set we are ok. */
5844
5845         dinfo = policy_handle_find(p, r->in.domain_handle,
5846                                    SAMR_DOMAIN_ACCESS_SET_INFO_1, NULL,
5847                                    struct samr_domain_info, &result);
5848         if (!NT_STATUS_IS_OK(result)) {
5849                 return result;
5850         }
5851
5852         DEBUG(5,("_samr_SetDomainInfo: level: %d\n", r->in.level));
5853
5854         switch (r->in.level) {
5855                 case 0x01:
5856                         u_expire=nt_time_to_unix_abs((NTTIME *)&r->in.info->info1.max_password_age);
5857                         u_min_age=nt_time_to_unix_abs((NTTIME *)&r->in.info->info1.min_password_age);
5858                         pdb_set_account_policy(AP_MIN_PASSWORD_LEN, (uint32)r->in.info->info1.min_password_length);
5859                         pdb_set_account_policy(AP_PASSWORD_HISTORY, (uint32)r->in.info->info1.password_history_length);
5860                         pdb_set_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, (uint32)r->in.info->info1.password_properties);
5861                         pdb_set_account_policy(AP_MAX_PASSWORD_AGE, (int)u_expire);
5862                         pdb_set_account_policy(AP_MIN_PASSWORD_AGE, (int)u_min_age);
5863                         break;
5864                 case 0x02:
5865                         break;
5866                 case 0x03:
5867                         u_logout=nt_time_to_unix_abs((NTTIME *)&r->in.info->info3.force_logoff_time);
5868                         pdb_set_account_policy(AP_TIME_TO_LOGOUT, (int)u_logout);
5869                         break;
5870                 case 0x05:
5871                         break;
5872                 case 0x06:
5873                         break;
5874                 case 0x07:
5875                         break;
5876                 case 0x0c:
5877                         u_lock_duration=nt_time_to_unix_abs((NTTIME *)&r->in.info->info12.lockout_duration);
5878                         if (u_lock_duration != -1)
5879                                 u_lock_duration /= 60;
5880
5881                         u_reset_time=nt_time_to_unix_abs((NTTIME *)&r->in.info->info12.lockout_window)/60;
5882
5883                         pdb_set_account_policy(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
5884                         pdb_set_account_policy(AP_RESET_COUNT_TIME, (int)u_reset_time);
5885                         pdb_set_account_policy(AP_BAD_ATTEMPT_LOCKOUT, (uint32)r->in.info->info12.lockout_threshold);
5886                         break;
5887                 default:
5888                         return NT_STATUS_INVALID_INFO_CLASS;
5889         }
5890
5891         DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
5892
5893         return NT_STATUS_OK;
5894 }
5895
5896 /****************************************************************
5897  _samr_GetDisplayEnumerationIndex
5898 ****************************************************************/
5899
5900 NTSTATUS _samr_GetDisplayEnumerationIndex(pipes_struct *p,
5901                                           struct samr_GetDisplayEnumerationIndex *r)
5902 {
5903         struct samr_domain_info *dinfo;
5904         uint32_t max_entries = (uint32_t) -1;
5905         uint32_t enum_context = 0;
5906         int i;
5907         uint32_t num_account = 0;
5908         struct samr_displayentry *entries = NULL;
5909         NTSTATUS status;
5910
5911         DEBUG(5,("_samr_GetDisplayEnumerationIndex: %d\n", __LINE__));
5912
5913         dinfo = policy_handle_find(p, r->in.domain_handle,
5914                                    SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
5915                                    struct samr_domain_info, &status);
5916         if (!NT_STATUS_IS_OK(status)) {
5917                 return status;
5918         }
5919
5920         if ((r->in.level < 1) || (r->in.level > 3)) {
5921                 DEBUG(0,("_samr_GetDisplayEnumerationIndex: "
5922                         "Unknown info level (%u)\n",
5923                         r->in.level));
5924                 return NT_STATUS_INVALID_INFO_CLASS;
5925         }
5926
5927         become_root();
5928
5929         /* The following done as ROOT. Don't return without unbecome_root(). */
5930
5931         switch (r->in.level) {
5932         case 1:
5933                 if (dinfo->disp_info->users == NULL) {
5934                         dinfo->disp_info->users = pdb_search_users(
5935                                 dinfo->disp_info, ACB_NORMAL);
5936                         if (dinfo->disp_info->users == NULL) {
5937                                 unbecome_root();
5938                                 return NT_STATUS_ACCESS_DENIED;
5939                         }
5940                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5941                                 "starting user enumeration at index %u\n",
5942                                 (unsigned int)enum_context));
5943                 } else {
5944                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5945                                 "using cached user enumeration at index %u\n",
5946                                 (unsigned int)enum_context));
5947                 }
5948                 num_account = pdb_search_entries(dinfo->disp_info->users,
5949                                                  enum_context, max_entries,
5950                                                  &entries);
5951                 break;
5952         case 2:
5953                 if (dinfo->disp_info->machines == NULL) {
5954                         dinfo->disp_info->machines = pdb_search_users(
5955                                 dinfo->disp_info, ACB_WSTRUST|ACB_SVRTRUST);
5956                         if (dinfo->disp_info->machines == NULL) {
5957                                 unbecome_root();
5958                                 return NT_STATUS_ACCESS_DENIED;
5959                         }
5960                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5961                                 "starting machine enumeration at index %u\n",
5962                                 (unsigned int)enum_context));
5963                 } else {
5964                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5965                                 "using cached machine enumeration at index %u\n",
5966                                 (unsigned int)enum_context));
5967                 }
5968                 num_account = pdb_search_entries(dinfo->disp_info->machines,
5969                                                  enum_context, max_entries,
5970                                                  &entries);
5971                 break;
5972         case 3:
5973                 if (dinfo->disp_info->groups == NULL) {
5974                         dinfo->disp_info->groups = pdb_search_groups(
5975                                 dinfo->disp_info);
5976                         if (dinfo->disp_info->groups == NULL) {
5977                                 unbecome_root();
5978                                 return NT_STATUS_ACCESS_DENIED;
5979                         }
5980                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5981                                 "starting group enumeration at index %u\n",
5982                                 (unsigned int)enum_context));
5983                 } else {
5984                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5985                                 "using cached group enumeration at index %u\n",
5986                                 (unsigned int)enum_context));
5987                 }
5988                 num_account = pdb_search_entries(dinfo->disp_info->groups,
5989                                                  enum_context, max_entries,
5990                                                  &entries);
5991                 break;
5992         default:
5993                 unbecome_root();
5994                 smb_panic("info class changed");
5995                 break;
5996         }
5997
5998         unbecome_root();
5999
6000         /* Ensure we cache this enumeration. */
6001         set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
6002
6003         DEBUG(10,("_samr_GetDisplayEnumerationIndex: looking for :%s\n",
6004                 r->in.name->string));
6005
6006         for (i=0; i<num_account; i++) {
6007                 if (strequal(entries[i].account_name, r->in.name->string)) {
6008                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6009                                 "found %s at idx %d\n",
6010                                 r->in.name->string, i));
6011                         *r->out.idx = i;
6012                         return NT_STATUS_OK;
6013                 }
6014         }
6015
6016         /* assuming account_name lives at the very end */
6017         *r->out.idx = num_account;
6018
6019         return NT_STATUS_NO_MORE_ENTRIES;
6020 }
6021
6022 /****************************************************************
6023  _samr_GetDisplayEnumerationIndex2
6024 ****************************************************************/
6025
6026 NTSTATUS _samr_GetDisplayEnumerationIndex2(pipes_struct *p,
6027                                            struct samr_GetDisplayEnumerationIndex2 *r)
6028 {
6029         struct samr_GetDisplayEnumerationIndex q;
6030
6031         q.in.domain_handle      = r->in.domain_handle;
6032         q.in.level              = r->in.level;
6033         q.in.name               = r->in.name;
6034
6035         q.out.idx               = r->out.idx;
6036
6037         return _samr_GetDisplayEnumerationIndex(p, &q);
6038 }
6039
6040 /****************************************************************
6041 ****************************************************************/
6042
6043 NTSTATUS _samr_Shutdown(pipes_struct *p,
6044                         struct samr_Shutdown *r)
6045 {
6046         p->rng_fault_state = true;
6047         return NT_STATUS_NOT_IMPLEMENTED;
6048 }
6049
6050 /****************************************************************
6051 ****************************************************************/
6052
6053 NTSTATUS _samr_SetMemberAttributesOfGroup(pipes_struct *p,
6054                                           struct samr_SetMemberAttributesOfGroup *r)
6055 {
6056         p->rng_fault_state = true;
6057         return NT_STATUS_NOT_IMPLEMENTED;
6058 }
6059
6060 /****************************************************************
6061 ****************************************************************/
6062
6063 NTSTATUS _samr_ChangePasswordUser(pipes_struct *p,
6064                                   struct samr_ChangePasswordUser *r)
6065 {
6066         p->rng_fault_state = true;
6067         return NT_STATUS_NOT_IMPLEMENTED;
6068 }
6069
6070 /****************************************************************
6071 ****************************************************************/
6072
6073 NTSTATUS _samr_TestPrivateFunctionsDomain(pipes_struct *p,
6074                                           struct samr_TestPrivateFunctionsDomain *r)
6075 {
6076         p->rng_fault_state = true;
6077         return NT_STATUS_NOT_IMPLEMENTED;
6078 }
6079
6080 /****************************************************************
6081 ****************************************************************/
6082
6083 NTSTATUS _samr_TestPrivateFunctionsUser(pipes_struct *p,
6084                                         struct samr_TestPrivateFunctionsUser *r)
6085 {
6086         return NT_STATUS_NOT_IMPLEMENTED;
6087 }
6088
6089 /****************************************************************
6090 ****************************************************************/
6091
6092 NTSTATUS _samr_AddMultipleMembersToAlias(pipes_struct *p,
6093                                          struct samr_AddMultipleMembersToAlias *r)
6094 {
6095         p->rng_fault_state = true;
6096         return NT_STATUS_NOT_IMPLEMENTED;
6097 }
6098
6099 /****************************************************************
6100 ****************************************************************/
6101
6102 NTSTATUS _samr_RemoveMultipleMembersFromAlias(pipes_struct *p,
6103                                               struct samr_RemoveMultipleMembersFromAlias *r)
6104 {
6105         p->rng_fault_state = true;
6106         return NT_STATUS_NOT_IMPLEMENTED;
6107 }
6108
6109 /****************************************************************
6110 ****************************************************************/
6111
6112 NTSTATUS _samr_OemChangePasswordUser2(pipes_struct *p,
6113                                       struct samr_OemChangePasswordUser2 *r)
6114 {
6115         p->rng_fault_state = true;
6116         return NT_STATUS_NOT_IMPLEMENTED;
6117 }
6118
6119 /****************************************************************
6120 ****************************************************************/
6121
6122 NTSTATUS _samr_SetBootKeyInformation(pipes_struct *p,
6123                                      struct samr_SetBootKeyInformation *r)
6124 {
6125         p->rng_fault_state = true;
6126         return NT_STATUS_NOT_IMPLEMENTED;
6127 }
6128
6129 /****************************************************************
6130 ****************************************************************/
6131
6132 NTSTATUS _samr_GetBootKeyInformation(pipes_struct *p,
6133                                      struct samr_GetBootKeyInformation *r)
6134 {
6135         p->rng_fault_state = true;
6136         return NT_STATUS_NOT_IMPLEMENTED;
6137 }
6138
6139 /****************************************************************
6140 ****************************************************************/
6141
6142 NTSTATUS _samr_RidToSid(pipes_struct *p,
6143                         struct samr_RidToSid *r)
6144 {
6145         p->rng_fault_state = true;
6146         return NT_STATUS_NOT_IMPLEMENTED;
6147 }
6148
6149 /****************************************************************
6150 ****************************************************************/
6151
6152 NTSTATUS _samr_SetDsrmPassword(pipes_struct *p,
6153                                struct samr_SetDsrmPassword *r)
6154 {
6155         p->rng_fault_state = true;
6156         return NT_STATUS_NOT_IMPLEMENTED;
6157 }
6158
6159 /****************************************************************
6160 ****************************************************************/
6161
6162 NTSTATUS _samr_ValidatePassword(pipes_struct *p,
6163                                 struct samr_ValidatePassword *r)
6164 {
6165         p->rng_fault_state = true;
6166         return NT_STATUS_NOT_IMPLEMENTED;
6167 }