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