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