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