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