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