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