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