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