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