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