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