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