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