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