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