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