s3-rpc_misc: clean out include/rpc_misc.h.
[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_compose(&domadmin_sid, get_global_sam_sid(),
149                             DOMAIN_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_compose(&domadmin_sid, get_global_sam_sid(),
270                             DOMAIN_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_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_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_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         if (r->out.rids->ids == NULL) {
5365                 /* Windows domain clients don't accept a NULL ptr here */
5366                 r->out.rids->ids = talloc_zero(p->mem_ctx, uint32_t);
5367         }
5368         if (r->out.rids->ids == NULL) {
5369                 return NT_STATUS_NO_MEMORY;
5370         }
5371
5372         return NT_STATUS_OK;
5373 }
5374
5375 /*********************************************************************
5376  _samr_GetMembersInAlias
5377 *********************************************************************/
5378
5379 NTSTATUS _samr_GetMembersInAlias(pipes_struct *p,
5380                                  struct samr_GetMembersInAlias *r)
5381 {
5382         struct samr_alias_info *ainfo;
5383         NTSTATUS status;
5384         size_t i;
5385         size_t num_sids = 0;
5386         struct lsa_SidPtr *sids = NULL;
5387         DOM_SID *pdb_sids = NULL;
5388
5389         ainfo = policy_handle_find(p, r->in.alias_handle,
5390                                    SAMR_ALIAS_ACCESS_GET_MEMBERS, NULL,
5391                                    struct samr_alias_info, &status);
5392         if (!NT_STATUS_IS_OK(status)) {
5393                 return status;
5394         }
5395
5396         DEBUG(10, ("sid is %s\n", sid_string_dbg(&ainfo->sid)));
5397
5398         become_root();
5399         status = pdb_enum_aliasmem(&ainfo->sid, talloc_tos(), &pdb_sids,
5400                                    &num_sids);
5401         unbecome_root();
5402
5403         if (!NT_STATUS_IS_OK(status)) {
5404                 return status;
5405         }
5406
5407         if (num_sids) {
5408                 sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_SidPtr, num_sids);
5409                 if (sids == NULL) {
5410                         TALLOC_FREE(pdb_sids);
5411                         return NT_STATUS_NO_MEMORY;
5412                 }
5413         }
5414
5415         for (i = 0; i < num_sids; i++) {
5416                 sids[i].sid = sid_dup_talloc(p->mem_ctx, &pdb_sids[i]);
5417                 if (!sids[i].sid) {
5418                         TALLOC_FREE(pdb_sids);
5419                         return NT_STATUS_NO_MEMORY;
5420                 }
5421         }
5422
5423         r->out.sids->num_sids = num_sids;
5424         r->out.sids->sids = sids;
5425
5426         TALLOC_FREE(pdb_sids);
5427
5428         return NT_STATUS_OK;
5429 }
5430
5431 /*********************************************************************
5432  _samr_QueryGroupMember
5433 *********************************************************************/
5434
5435 NTSTATUS _samr_QueryGroupMember(pipes_struct *p,
5436                                 struct samr_QueryGroupMember *r)
5437 {
5438         struct samr_group_info *ginfo;
5439         size_t i, num_members;
5440
5441         uint32 *rid=NULL;
5442         uint32 *attr=NULL;
5443
5444         NTSTATUS status;
5445         struct samr_RidTypeArray *rids = NULL;
5446
5447         ginfo = policy_handle_find(p, r->in.group_handle,
5448                                    SAMR_GROUP_ACCESS_GET_MEMBERS, NULL,
5449                                    struct samr_group_info, &status);
5450         if (!NT_STATUS_IS_OK(status)) {
5451                 return status;
5452         }
5453
5454         rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidTypeArray);
5455         if (!rids) {
5456                 return NT_STATUS_NO_MEMORY;
5457         }
5458
5459         DEBUG(10, ("sid is %s\n", sid_string_dbg(&ginfo->sid)));
5460
5461         if (!sid_check_is_in_our_domain(&ginfo->sid)) {
5462                 DEBUG(3, ("sid %s is not in our domain\n",
5463                           sid_string_dbg(&ginfo->sid)));
5464                 return NT_STATUS_NO_SUCH_GROUP;
5465         }
5466
5467         DEBUG(10, ("lookup on Domain SID\n"));
5468
5469         become_root();
5470         status = pdb_enum_group_members(p->mem_ctx, &ginfo->sid,
5471                                         &rid, &num_members);
5472         unbecome_root();
5473
5474         if (!NT_STATUS_IS_OK(status))
5475                 return status;
5476
5477         if (num_members) {
5478                 attr=TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_members);
5479                 if (attr == NULL) {
5480                         return NT_STATUS_NO_MEMORY;
5481                 }
5482         } else {
5483                 attr = NULL;
5484         }
5485
5486         for (i=0; i<num_members; i++)
5487                 attr[i] = SID_NAME_USER;
5488
5489         rids->count = num_members;
5490         rids->types = attr;
5491         rids->rids = rid;
5492
5493         *r->out.rids = rids;
5494
5495         return NT_STATUS_OK;
5496 }
5497
5498 /*********************************************************************
5499  _samr_AddAliasMember
5500 *********************************************************************/
5501
5502 NTSTATUS _samr_AddAliasMember(pipes_struct *p,
5503                               struct samr_AddAliasMember *r)
5504 {
5505         struct samr_alias_info *ainfo;
5506         NTSTATUS status;
5507
5508         ainfo = policy_handle_find(p, r->in.alias_handle,
5509                                    SAMR_ALIAS_ACCESS_ADD_MEMBER, NULL,
5510                                    struct samr_alias_info, &status);
5511         if (!NT_STATUS_IS_OK(status)) {
5512                 return status;
5513         }
5514
5515         DEBUG(10, ("sid is %s\n", sid_string_dbg(&ainfo->sid)));
5516
5517         /******** BEGIN SeAddUsers BLOCK *********/
5518
5519         become_root();
5520         status = pdb_add_aliasmem(&ainfo->sid, r->in.sid);
5521         unbecome_root();
5522
5523         /******** END SeAddUsers BLOCK *********/
5524
5525         if (NT_STATUS_IS_OK(status)) {
5526                 force_flush_samr_cache(&ainfo->sid);
5527         }
5528
5529         return status;
5530 }
5531
5532 /*********************************************************************
5533  _samr_DeleteAliasMember
5534 *********************************************************************/
5535
5536 NTSTATUS _samr_DeleteAliasMember(pipes_struct *p,
5537                                  struct samr_DeleteAliasMember *r)
5538 {
5539         struct samr_alias_info *ainfo;
5540         NTSTATUS status;
5541
5542         ainfo = policy_handle_find(p, r->in.alias_handle,
5543                                    SAMR_ALIAS_ACCESS_REMOVE_MEMBER, NULL,
5544                                    struct samr_alias_info, &status);
5545         if (!NT_STATUS_IS_OK(status)) {
5546                 return status;
5547         }
5548
5549         DEBUG(10, ("_samr_del_aliasmem:sid is %s\n",
5550                    sid_string_dbg(&ainfo->sid)));
5551
5552         /******** BEGIN SeAddUsers BLOCK *********/
5553
5554         become_root();
5555         status = pdb_del_aliasmem(&ainfo->sid, r->in.sid);
5556         unbecome_root();
5557
5558         /******** END SeAddUsers BLOCK *********/
5559
5560         if (NT_STATUS_IS_OK(status)) {
5561                 force_flush_samr_cache(&ainfo->sid);
5562         }
5563
5564         return status;
5565 }
5566
5567 /*********************************************************************
5568  _samr_AddGroupMember
5569 *********************************************************************/
5570
5571 NTSTATUS _samr_AddGroupMember(pipes_struct *p,
5572                               struct samr_AddGroupMember *r)
5573 {
5574         struct samr_group_info *ginfo;
5575         NTSTATUS status;
5576         uint32 group_rid;
5577
5578         ginfo = policy_handle_find(p, r->in.group_handle,
5579                                    SAMR_GROUP_ACCESS_ADD_MEMBER, NULL,
5580                                    struct samr_group_info, &status);
5581         if (!NT_STATUS_IS_OK(status)) {
5582                 return status;
5583         }
5584
5585         DEBUG(10, ("sid is %s\n", sid_string_dbg(&ginfo->sid)));
5586
5587         if (!sid_peek_check_rid(get_global_sam_sid(), &ginfo->sid,
5588                                 &group_rid)) {
5589                 return NT_STATUS_INVALID_HANDLE;
5590         }
5591
5592         /******** BEGIN SeAddUsers BLOCK *********/
5593
5594         become_root();
5595         status = pdb_add_groupmem(p->mem_ctx, group_rid, r->in.rid);
5596         unbecome_root();
5597
5598         /******** END SeAddUsers BLOCK *********/
5599
5600         force_flush_samr_cache(&ginfo->sid);
5601
5602         return status;
5603 }
5604
5605 /*********************************************************************
5606  _samr_DeleteGroupMember
5607 *********************************************************************/
5608
5609 NTSTATUS _samr_DeleteGroupMember(pipes_struct *p,
5610                                  struct samr_DeleteGroupMember *r)
5611
5612 {
5613         struct samr_group_info *ginfo;
5614         NTSTATUS status;
5615         uint32 group_rid;
5616
5617         /*
5618          * delete the group member named r->in.rid
5619          * who is a member of the sid associated with the handle
5620          * the rid is a user's rid as the group is a domain group.
5621          */
5622
5623         ginfo = policy_handle_find(p, r->in.group_handle,
5624                                    SAMR_GROUP_ACCESS_REMOVE_MEMBER, NULL,
5625                                    struct samr_group_info, &status);
5626         if (!NT_STATUS_IS_OK(status)) {
5627                 return status;
5628         }
5629
5630         if (!sid_peek_check_rid(get_global_sam_sid(), &ginfo->sid,
5631                                 &group_rid)) {
5632                 return NT_STATUS_INVALID_HANDLE;
5633         }
5634
5635         /******** BEGIN SeAddUsers BLOCK *********/
5636
5637         become_root();
5638         status = pdb_del_groupmem(p->mem_ctx, group_rid, r->in.rid);
5639         unbecome_root();
5640
5641         /******** END SeAddUsers BLOCK *********/
5642
5643         force_flush_samr_cache(&ginfo->sid);
5644
5645         return status;
5646 }
5647
5648 /*********************************************************************
5649  _samr_DeleteUser
5650 *********************************************************************/
5651
5652 NTSTATUS _samr_DeleteUser(pipes_struct *p,
5653                           struct samr_DeleteUser *r)
5654 {
5655         struct samr_user_info *uinfo;
5656         NTSTATUS status;
5657         struct samu *sam_pass=NULL;
5658         bool ret;
5659
5660         DEBUG(5, ("_samr_DeleteUser: %d\n", __LINE__));
5661
5662         uinfo = policy_handle_find(p, r->in.user_handle,
5663                                    STD_RIGHT_DELETE_ACCESS, NULL,
5664                                    struct samr_user_info, &status);
5665         if (!NT_STATUS_IS_OK(status)) {
5666                 return status;
5667         }
5668
5669         if (!sid_check_is_in_our_domain(&uinfo->sid))
5670                 return NT_STATUS_CANNOT_DELETE;
5671
5672         /* check if the user exists before trying to delete */
5673         if ( !(sam_pass = samu_new( NULL )) ) {
5674                 return NT_STATUS_NO_MEMORY;
5675         }
5676
5677         become_root();
5678         ret = pdb_getsampwsid(sam_pass, &uinfo->sid);
5679         unbecome_root();
5680
5681         if(!ret) {
5682                 DEBUG(5,("_samr_DeleteUser: User %s doesn't exist.\n",
5683                         sid_string_dbg(&uinfo->sid)));
5684                 TALLOC_FREE(sam_pass);
5685                 return NT_STATUS_NO_SUCH_USER;
5686         }
5687
5688         /******** BEGIN SeAddUsers BLOCK *********/
5689
5690         become_root();
5691         status = pdb_delete_user(p->mem_ctx, sam_pass);
5692         unbecome_root();
5693
5694         /******** END SeAddUsers BLOCK *********/
5695
5696         if ( !NT_STATUS_IS_OK(status) ) {
5697                 DEBUG(5,("_samr_DeleteUser: Failed to delete entry for "
5698                          "user %s: %s.\n", pdb_get_username(sam_pass),
5699                          nt_errstr(status)));
5700                 TALLOC_FREE(sam_pass);
5701                 return status;
5702         }
5703
5704
5705         TALLOC_FREE(sam_pass);
5706
5707         force_flush_samr_cache(&uinfo->sid);
5708
5709         if (!close_policy_hnd(p, r->in.user_handle))
5710                 return NT_STATUS_OBJECT_NAME_INVALID;
5711
5712         ZERO_STRUCTP(r->out.user_handle);
5713
5714         return NT_STATUS_OK;
5715 }
5716
5717 /*********************************************************************
5718  _samr_DeleteDomainGroup
5719 *********************************************************************/
5720
5721 NTSTATUS _samr_DeleteDomainGroup(pipes_struct *p,
5722                                  struct samr_DeleteDomainGroup *r)
5723 {
5724         struct samr_group_info *ginfo;
5725         NTSTATUS status;
5726         uint32 group_rid;
5727
5728         DEBUG(5, ("samr_DeleteDomainGroup: %d\n", __LINE__));
5729
5730         ginfo = policy_handle_find(p, r->in.group_handle,
5731                                    STD_RIGHT_DELETE_ACCESS, NULL,
5732                                    struct samr_group_info, &status);
5733         if (!NT_STATUS_IS_OK(status)) {
5734                 return status;
5735         }
5736
5737         DEBUG(10, ("sid is %s\n", sid_string_dbg(&ginfo->sid)));
5738
5739         if (!sid_peek_check_rid(get_global_sam_sid(), &ginfo->sid,
5740                                 &group_rid)) {
5741                 return NT_STATUS_NO_SUCH_GROUP;
5742         }
5743
5744         /******** BEGIN SeAddUsers BLOCK *********/
5745
5746         become_root();
5747         status = pdb_delete_dom_group(p->mem_ctx, group_rid);
5748         unbecome_root();
5749
5750         /******** END SeAddUsers BLOCK *********/
5751
5752         if ( !NT_STATUS_IS_OK(status) ) {
5753                 DEBUG(5,("_samr_DeleteDomainGroup: Failed to delete mapping "
5754                          "entry for group %s: %s\n",
5755                          sid_string_dbg(&ginfo->sid),
5756                          nt_errstr(status)));
5757                 return status;
5758         }
5759
5760         force_flush_samr_cache(&ginfo->sid);
5761
5762         if (!close_policy_hnd(p, r->in.group_handle))
5763                 return NT_STATUS_OBJECT_NAME_INVALID;
5764
5765         return NT_STATUS_OK;
5766 }
5767
5768 /*********************************************************************
5769  _samr_DeleteDomAlias
5770 *********************************************************************/
5771
5772 NTSTATUS _samr_DeleteDomAlias(pipes_struct *p,
5773                               struct samr_DeleteDomAlias *r)
5774 {
5775         struct samr_alias_info *ainfo;
5776         NTSTATUS status;
5777
5778         DEBUG(5, ("_samr_DeleteDomAlias: %d\n", __LINE__));
5779
5780         ainfo = policy_handle_find(p, r->in.alias_handle,
5781                                    STD_RIGHT_DELETE_ACCESS, NULL,
5782                                    struct samr_alias_info, &status);
5783         if (!NT_STATUS_IS_OK(status)) {
5784                 return status;
5785         }
5786
5787         DEBUG(10, ("sid is %s\n", sid_string_dbg(&ainfo->sid)));
5788
5789         /* Don't let Windows delete builtin groups */
5790
5791         if ( sid_check_is_in_builtin( &ainfo->sid ) ) {
5792                 return NT_STATUS_SPECIAL_ACCOUNT;
5793         }
5794
5795         if (!sid_check_is_in_our_domain(&ainfo->sid))
5796                 return NT_STATUS_NO_SUCH_ALIAS;
5797
5798         DEBUG(10, ("lookup on Local SID\n"));
5799
5800         /******** BEGIN SeAddUsers BLOCK *********/
5801
5802         become_root();
5803         /* Have passdb delete the alias */
5804         status = pdb_delete_alias(&ainfo->sid);
5805         unbecome_root();
5806
5807         /******** END SeAddUsers BLOCK *********/
5808
5809         if ( !NT_STATUS_IS_OK(status))
5810                 return status;
5811
5812         force_flush_samr_cache(&ainfo->sid);
5813
5814         if (!close_policy_hnd(p, r->in.alias_handle))
5815                 return NT_STATUS_OBJECT_NAME_INVALID;
5816
5817         return NT_STATUS_OK;
5818 }
5819
5820 /*********************************************************************
5821  _samr_CreateDomainGroup
5822 *********************************************************************/
5823
5824 NTSTATUS _samr_CreateDomainGroup(pipes_struct *p,
5825                                  struct samr_CreateDomainGroup *r)
5826
5827 {
5828         NTSTATUS status;
5829         const char *name;
5830         struct samr_domain_info *dinfo;
5831         struct samr_group_info *ginfo;
5832
5833         dinfo = policy_handle_find(p, r->in.domain_handle,
5834                                    SAMR_DOMAIN_ACCESS_CREATE_GROUP, NULL,
5835                                    struct samr_domain_info, &status);
5836         if (!NT_STATUS_IS_OK(status)) {
5837                 return status;
5838         }
5839
5840         if (!sid_check_is_domain(&dinfo->sid)) {
5841                 return NT_STATUS_ACCESS_DENIED;
5842         }
5843
5844         name = r->in.name->string;
5845         if (name == NULL) {
5846                 return NT_STATUS_NO_MEMORY;
5847         }
5848
5849         status = can_create(p->mem_ctx, name);
5850         if (!NT_STATUS_IS_OK(status)) {
5851                 return status;
5852         }
5853
5854         /******** BEGIN SeAddUsers BLOCK *********/
5855
5856         become_root();
5857         /* check that we successfully create the UNIX group */
5858         status = pdb_create_dom_group(p->mem_ctx, name, r->out.rid);
5859         unbecome_root();
5860
5861         /******** END SeAddUsers BLOCK *********/
5862
5863         /* check if we should bail out here */
5864
5865         if ( !NT_STATUS_IS_OK(status) )
5866                 return status;
5867
5868         ginfo = policy_handle_create(p, r->out.group_handle,
5869                                      GENERIC_RIGHTS_GROUP_ALL_ACCESS,
5870                                      struct samr_group_info, &status);
5871         if (!NT_STATUS_IS_OK(status)) {
5872                 return status;
5873         }
5874         sid_compose(&ginfo->sid, &dinfo->sid, *r->out.rid);
5875
5876         force_flush_samr_cache(&dinfo->sid);
5877
5878         return NT_STATUS_OK;
5879 }
5880
5881 /*********************************************************************
5882  _samr_CreateDomAlias
5883 *********************************************************************/
5884
5885 NTSTATUS _samr_CreateDomAlias(pipes_struct *p,
5886                               struct samr_CreateDomAlias *r)
5887 {
5888         DOM_SID info_sid;
5889         const char *name = NULL;
5890         struct samr_domain_info *dinfo;
5891         struct samr_alias_info *ainfo;
5892         gid_t gid;
5893         NTSTATUS result;
5894
5895         dinfo = policy_handle_find(p, r->in.domain_handle,
5896                                    SAMR_DOMAIN_ACCESS_CREATE_ALIAS, NULL,
5897                                    struct samr_domain_info, &result);
5898         if (!NT_STATUS_IS_OK(result)) {
5899                 return result;
5900         }
5901
5902         if (!sid_check_is_domain(&dinfo->sid)) {
5903                 return NT_STATUS_ACCESS_DENIED;
5904         }
5905
5906         name = r->in.alias_name->string;
5907
5908         result = can_create(p->mem_ctx, name);
5909         if (!NT_STATUS_IS_OK(result)) {
5910                 return result;
5911         }
5912
5913         /******** BEGIN SeAddUsers BLOCK *********/
5914
5915         become_root();
5916         /* Have passdb create the alias */
5917         result = pdb_create_alias(name, r->out.rid);
5918         unbecome_root();
5919
5920         /******** END SeAddUsers BLOCK *********/
5921
5922         if (!NT_STATUS_IS_OK(result)) {
5923                 DEBUG(10, ("pdb_create_alias failed: %s\n",
5924                            nt_errstr(result)));
5925                 return result;
5926         }
5927
5928         sid_compose(&info_sid, &dinfo->sid, *r->out.rid);
5929
5930         if (!sid_to_gid(&info_sid, &gid)) {
5931                 DEBUG(10, ("Could not find alias just created\n"));
5932                 return NT_STATUS_ACCESS_DENIED;
5933         }
5934
5935         /* check if the group has been successfully created */
5936         if ( getgrgid(gid) == NULL ) {
5937                 DEBUG(10, ("getgrgid(%u) of just created alias failed\n",
5938                            (unsigned int)gid));
5939                 return NT_STATUS_ACCESS_DENIED;
5940         }
5941
5942         ainfo = policy_handle_create(p, r->out.alias_handle,
5943                                      GENERIC_RIGHTS_ALIAS_ALL_ACCESS,
5944                                      struct samr_alias_info, &result);
5945         if (!NT_STATUS_IS_OK(result)) {
5946                 return result;
5947         }
5948         ainfo->sid = info_sid;
5949
5950         force_flush_samr_cache(&info_sid);
5951
5952         return NT_STATUS_OK;
5953 }
5954
5955 /*********************************************************************
5956  _samr_QueryGroupInfo
5957 *********************************************************************/
5958
5959 NTSTATUS _samr_QueryGroupInfo(pipes_struct *p,
5960                               struct samr_QueryGroupInfo *r)
5961 {
5962         struct samr_group_info *ginfo;
5963         NTSTATUS status;
5964         GROUP_MAP map;
5965         union samr_GroupInfo *info = NULL;
5966         bool ret;
5967         uint32_t attributes = SE_GROUP_MANDATORY |
5968                               SE_GROUP_ENABLED_BY_DEFAULT |
5969                               SE_GROUP_ENABLED;
5970         const char *group_name = NULL;
5971         const char *group_description = NULL;
5972
5973         ginfo = policy_handle_find(p, r->in.group_handle,
5974                                    SAMR_GROUP_ACCESS_LOOKUP_INFO, NULL,
5975                                    struct samr_group_info, &status);
5976         if (!NT_STATUS_IS_OK(status)) {
5977                 return status;
5978         }
5979
5980         become_root();
5981         ret = get_domain_group_from_sid(ginfo->sid, &map);
5982         unbecome_root();
5983         if (!ret)
5984                 return NT_STATUS_INVALID_HANDLE;
5985
5986         /* FIXME: map contains fstrings */
5987         group_name = talloc_strdup(r, map.nt_name);
5988         group_description = talloc_strdup(r, map.comment);
5989
5990         info = TALLOC_ZERO_P(p->mem_ctx, union samr_GroupInfo);
5991         if (!info) {
5992                 return NT_STATUS_NO_MEMORY;
5993         }
5994
5995         switch (r->in.level) {
5996                 case 1: {
5997                         uint32 *members;
5998                         size_t num_members;
5999
6000                         become_root();
6001                         status = pdb_enum_group_members(
6002                                 p->mem_ctx, &ginfo->sid, &members,
6003                                 &num_members);
6004                         unbecome_root();
6005
6006                         if (!NT_STATUS_IS_OK(status)) {
6007                                 return status;
6008                         }
6009
6010                         info->all.name.string           = group_name;
6011                         info->all.attributes            = attributes;
6012                         info->all.num_members           = num_members;
6013                         info->all.description.string    = group_description;
6014                         break;
6015                 }
6016                 case 2:
6017                         info->name.string = group_name;
6018                         break;
6019                 case 3:
6020                         info->attributes.attributes = attributes;
6021                         break;
6022                 case 4:
6023                         info->description.string = group_description;
6024                         break;
6025                 case 5: {
6026                         /*
6027                         uint32 *members;
6028                         size_t num_members;
6029                         */
6030
6031                         /*
6032                         become_root();
6033                         status = pdb_enum_group_members(
6034                                 p->mem_ctx, &ginfo->sid, &members,
6035                                 &num_members);
6036                         unbecome_root();
6037
6038                         if (!NT_STATUS_IS_OK(status)) {
6039                                 return status;
6040                         }
6041                         */
6042                         info->all2.name.string          = group_name;
6043                         info->all2.attributes           = attributes;
6044                         info->all2.num_members          = 0; /* num_members - in w2k3 this is always 0 */
6045                         info->all2.description.string   = group_description;
6046
6047                         break;
6048                 }
6049                 default:
6050                         return NT_STATUS_INVALID_INFO_CLASS;
6051         }
6052
6053         *r->out.info = info;
6054
6055         return NT_STATUS_OK;
6056 }
6057
6058 /*********************************************************************
6059  _samr_SetGroupInfo
6060 *********************************************************************/
6061
6062 NTSTATUS _samr_SetGroupInfo(pipes_struct *p,
6063                             struct samr_SetGroupInfo *r)
6064 {
6065         struct samr_group_info *ginfo;
6066         GROUP_MAP map;
6067         NTSTATUS status;
6068         bool ret;
6069
6070         ginfo = policy_handle_find(p, r->in.group_handle,
6071                                    SAMR_GROUP_ACCESS_SET_INFO, NULL,
6072                                    struct samr_group_info, &status);
6073         if (!NT_STATUS_IS_OK(status)) {
6074                 return status;
6075         }
6076
6077         become_root();
6078         ret = get_domain_group_from_sid(ginfo->sid, &map);
6079         unbecome_root();
6080         if (!ret)
6081                 return NT_STATUS_NO_SUCH_GROUP;
6082
6083         switch (r->in.level) {
6084                 case 2:
6085                         fstrcpy(map.nt_name, r->in.info->name.string);
6086                         break;
6087                 case 3:
6088                         break;
6089                 case 4:
6090                         fstrcpy(map.comment, r->in.info->description.string);
6091                         break;
6092                 default:
6093                         return NT_STATUS_INVALID_INFO_CLASS;
6094         }
6095
6096         /******** BEGIN SeAddUsers BLOCK *********/
6097
6098         become_root();
6099         status = pdb_update_group_mapping_entry(&map);
6100         unbecome_root();
6101
6102         /******** End SeAddUsers BLOCK *********/
6103
6104         if (NT_STATUS_IS_OK(status)) {
6105                 force_flush_samr_cache(&ginfo->sid);
6106         }
6107
6108         return status;
6109 }
6110
6111 /*********************************************************************
6112  _samr_SetAliasInfo
6113 *********************************************************************/
6114
6115 NTSTATUS _samr_SetAliasInfo(pipes_struct *p,
6116                             struct samr_SetAliasInfo *r)
6117 {
6118         struct samr_alias_info *ainfo;
6119         struct acct_info info;
6120         NTSTATUS status;
6121
6122         ainfo = policy_handle_find(p, r->in.alias_handle,
6123                                    SAMR_ALIAS_ACCESS_SET_INFO, NULL,
6124                                    struct samr_alias_info, &status);
6125         if (!NT_STATUS_IS_OK(status)) {
6126                 return status;
6127         }
6128
6129         /* get the current group information */
6130
6131         become_root();
6132         status = pdb_get_aliasinfo( &ainfo->sid, &info );
6133         unbecome_root();
6134
6135         if ( !NT_STATUS_IS_OK(status))
6136                 return status;
6137
6138         switch (r->in.level) {
6139                 case ALIASINFONAME:
6140                 {
6141                         fstring group_name;
6142
6143                         /* We currently do not support renaming groups in the
6144                            the BUILTIN domain.  Refer to util_builtin.c to understand
6145                            why.  The eventually needs to be fixed to be like Windows
6146                            where you can rename builtin groups, just not delete them */
6147
6148                         if ( sid_check_is_in_builtin( &ainfo->sid ) ) {
6149                                 return NT_STATUS_SPECIAL_ACCOUNT;
6150                         }
6151
6152                         /* There has to be a valid name (and it has to be different) */
6153
6154                         if ( !r->in.info->name.string )
6155                                 return NT_STATUS_INVALID_PARAMETER;
6156
6157                         /* If the name is the same just reply "ok".  Yes this
6158                            doesn't allow you to change the case of a group name. */
6159
6160                         if ( strequal( r->in.info->name.string, info.acct_name ) )
6161                                 return NT_STATUS_OK;
6162
6163                         fstrcpy( info.acct_name, r->in.info->name.string);
6164
6165                         /* make sure the name doesn't already exist as a user
6166                            or local group */
6167
6168                         fstr_sprintf( group_name, "%s\\%s", global_myname(), info.acct_name );
6169                         status = can_create( p->mem_ctx, group_name );
6170                         if ( !NT_STATUS_IS_OK( status ) )
6171                                 return status;
6172                         break;
6173                 }
6174                 case ALIASINFODESCRIPTION:
6175                         if (r->in.info->description.string) {
6176                                 fstrcpy(info.acct_desc,
6177                                         r->in.info->description.string);
6178                         } else {
6179                                 fstrcpy( info.acct_desc, "" );
6180                         }
6181                         break;
6182                 default:
6183                         return NT_STATUS_INVALID_INFO_CLASS;
6184         }
6185
6186         /******** BEGIN SeAddUsers BLOCK *********/
6187
6188         become_root();
6189         status = pdb_set_aliasinfo( &ainfo->sid, &info );
6190         unbecome_root();
6191
6192         /******** End SeAddUsers BLOCK *********/
6193
6194         if (NT_STATUS_IS_OK(status))
6195                 force_flush_samr_cache(&ainfo->sid);
6196
6197         return status;
6198 }
6199
6200 /****************************************************************
6201  _samr_GetDomPwInfo
6202 ****************************************************************/
6203
6204 NTSTATUS _samr_GetDomPwInfo(pipes_struct *p,
6205                             struct samr_GetDomPwInfo *r)
6206 {
6207         uint32_t min_password_length = 0;
6208         uint32_t password_properties = 0;
6209
6210         /* Perform access check.  Since this rpc does not require a
6211            policy handle it will not be caught by the access checks on
6212            SAMR_CONNECT or SAMR_CONNECT_ANON. */
6213
6214         if (!pipe_access_check(p)) {
6215                 DEBUG(3, ("access denied to _samr_GetDomPwInfo\n"));
6216                 return NT_STATUS_ACCESS_DENIED;
6217         }
6218
6219         become_root();
6220         pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN,
6221                                &min_password_length);
6222         pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
6223                                &password_properties);
6224         unbecome_root();
6225
6226         if (lp_check_password_script() && *lp_check_password_script()) {
6227                 password_properties |= DOMAIN_PASSWORD_COMPLEX;
6228         }
6229
6230         r->out.info->min_password_length = min_password_length;
6231         r->out.info->password_properties = password_properties;
6232
6233         return NT_STATUS_OK;
6234 }
6235
6236 /*********************************************************************
6237  _samr_OpenGroup
6238 *********************************************************************/
6239
6240 NTSTATUS _samr_OpenGroup(pipes_struct *p,
6241                          struct samr_OpenGroup *r)
6242
6243 {
6244         DOM_SID info_sid;
6245         GROUP_MAP map;
6246         struct samr_domain_info *dinfo;
6247         struct samr_group_info *ginfo;
6248         SEC_DESC         *psd = NULL;
6249         uint32            acc_granted;
6250         uint32            des_access = r->in.access_mask;
6251         size_t            sd_size;
6252         NTSTATUS          status;
6253         bool ret;
6254         SE_PRIV se_rights;
6255
6256         dinfo = policy_handle_find(p, r->in.domain_handle,
6257                                    SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
6258                                    struct samr_domain_info, &status);
6259         if (!NT_STATUS_IS_OK(status)) {
6260                 return status;
6261         }
6262
6263         /*check if access can be granted as requested by client. */
6264         map_max_allowed_access(p->server_info->ptok,
6265                                &p->server_info->utok,
6266                                &des_access);
6267
6268         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &grp_generic_mapping, NULL, 0);
6269         se_map_generic(&des_access,&grp_generic_mapping);
6270
6271         se_priv_copy( &se_rights, &se_add_users );
6272
6273         status = access_check_object(psd, p->server_info->ptok,
6274                 &se_rights, GENERIC_RIGHTS_GROUP_ALL_ACCESS,
6275                 des_access, &acc_granted, "_samr_OpenGroup");
6276
6277         if ( !NT_STATUS_IS_OK(status) )
6278                 return status;
6279
6280         /* this should not be hard-coded like this */
6281
6282         if (!sid_check_is_domain(&dinfo->sid)) {
6283                 return NT_STATUS_ACCESS_DENIED;
6284         }
6285
6286         sid_compose(&info_sid, &dinfo->sid, r->in.rid);
6287
6288         DEBUG(10, ("_samr_OpenGroup:Opening SID: %s\n",
6289                    sid_string_dbg(&info_sid)));
6290
6291         /* check if that group really exists */
6292         become_root();
6293         ret = get_domain_group_from_sid(info_sid, &map);
6294         unbecome_root();
6295         if (!ret)
6296                 return NT_STATUS_NO_SUCH_GROUP;
6297
6298         ginfo = policy_handle_create(p, r->out.group_handle,
6299                                      acc_granted,
6300                                      struct samr_group_info, &status);
6301         if (!NT_STATUS_IS_OK(status)) {
6302                 return status;
6303         }
6304         ginfo->sid = info_sid;
6305
6306         return NT_STATUS_OK;
6307 }
6308
6309 /*********************************************************************
6310  _samr_RemoveMemberFromForeignDomain
6311 *********************************************************************/
6312
6313 NTSTATUS _samr_RemoveMemberFromForeignDomain(pipes_struct *p,
6314                                              struct samr_RemoveMemberFromForeignDomain *r)
6315 {
6316         struct samr_domain_info *dinfo;
6317         NTSTATUS                result;
6318
6319         DEBUG(5,("_samr_RemoveMemberFromForeignDomain: removing SID [%s]\n",
6320                  sid_string_dbg(r->in.sid)));
6321
6322         /* Find the policy handle. Open a policy on it. */
6323
6324         dinfo = policy_handle_find(p, r->in.domain_handle,
6325                                    SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
6326                                    struct samr_domain_info, &result);
6327         if (!NT_STATUS_IS_OK(result)) {
6328                 return result;
6329         }
6330
6331         DEBUG(8, ("_samr_RemoveMemberFromForeignDomain: sid is %s\n",
6332                   sid_string_dbg(&dinfo->sid)));
6333
6334         /* we can only delete a user from a group since we don't have
6335            nested groups anyways.  So in the latter case, just say OK */
6336
6337         /* TODO: The above comment nowadays is bogus. Since we have nested
6338          * groups now, and aliases members are never reported out of the unix
6339          * group membership, the "just say OK" makes this call a no-op. For
6340          * us. This needs fixing however. */
6341
6342         /* I've only ever seen this in the wild when deleting a user from
6343          * usrmgr.exe. domain_sid is the builtin domain, and the sid to delete
6344          * is the user about to be deleted. I very much suspect this is the
6345          * only application of this call. To verify this, let people report
6346          * other cases. */
6347
6348         if (!sid_check_is_builtin(&dinfo->sid)) {
6349                 DEBUG(1,("_samr_RemoveMemberFromForeignDomain: domain_sid = %s, "
6350                          "global_sam_sid() = %s\n",
6351                          sid_string_dbg(&dinfo->sid),
6352                          sid_string_dbg(get_global_sam_sid())));
6353                 DEBUGADD(1,("please report to samba-technical@samba.org!\n"));
6354                 return NT_STATUS_OK;
6355         }
6356
6357         force_flush_samr_cache(&dinfo->sid);
6358
6359         result = NT_STATUS_OK;
6360
6361         return result;
6362 }
6363
6364 /*******************************************************************
6365  _samr_QueryDomainInfo2
6366  ********************************************************************/
6367
6368 NTSTATUS _samr_QueryDomainInfo2(pipes_struct *p,
6369                                 struct samr_QueryDomainInfo2 *r)
6370 {
6371         struct samr_QueryDomainInfo q;
6372
6373         q.in.domain_handle      = r->in.domain_handle;
6374         q.in.level              = r->in.level;
6375
6376         q.out.info              = r->out.info;
6377
6378         return _samr_QueryDomainInfo(p, &q);
6379 }
6380
6381 /*******************************************************************
6382  ********************************************************************/
6383
6384 static NTSTATUS set_dom_info_1(TALLOC_CTX *mem_ctx,
6385                                struct samr_DomInfo1 *r)
6386 {
6387         time_t u_expire, u_min_age;
6388
6389         u_expire = nt_time_to_unix_abs((NTTIME *)&r->max_password_age);
6390         u_min_age = nt_time_to_unix_abs((NTTIME *)&r->min_password_age);
6391
6392         pdb_set_account_policy(PDB_POLICY_MIN_PASSWORD_LEN,
6393                                (uint32_t)r->min_password_length);
6394         pdb_set_account_policy(PDB_POLICY_PASSWORD_HISTORY,
6395                                (uint32_t)r->password_history_length);
6396         pdb_set_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
6397                                (uint32_t)r->password_properties);
6398         pdb_set_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, (int)u_expire);
6399         pdb_set_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, (int)u_min_age);
6400
6401         return NT_STATUS_OK;
6402 }
6403
6404 /*******************************************************************
6405  ********************************************************************/
6406
6407 static NTSTATUS set_dom_info_3(TALLOC_CTX *mem_ctx,
6408                                struct samr_DomInfo3 *r)
6409 {
6410         time_t u_logout;
6411
6412         u_logout = nt_time_to_unix_abs((NTTIME *)&r->force_logoff_time);
6413
6414         pdb_set_account_policy(PDB_POLICY_TIME_TO_LOGOUT, (int)u_logout);
6415
6416         return NT_STATUS_OK;
6417 }
6418
6419 /*******************************************************************
6420  ********************************************************************/
6421
6422 static NTSTATUS set_dom_info_12(TALLOC_CTX *mem_ctx,
6423                                 struct samr_DomInfo12 *r)
6424 {
6425         time_t u_lock_duration, u_reset_time;
6426
6427         u_lock_duration = nt_time_to_unix_abs((NTTIME *)&r->lockout_duration);
6428         if (u_lock_duration != -1) {
6429                 u_lock_duration /= 60;
6430         }
6431
6432         u_reset_time = nt_time_to_unix_abs((NTTIME *)&r->lockout_window)/60;
6433
6434         pdb_set_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
6435         pdb_set_account_policy(PDB_POLICY_RESET_COUNT_TIME, (int)u_reset_time);
6436         pdb_set_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT,
6437                                (uint32_t)r->lockout_threshold);
6438
6439         return NT_STATUS_OK;
6440 }
6441
6442 /*******************************************************************
6443  _samr_SetDomainInfo
6444  ********************************************************************/
6445
6446 NTSTATUS _samr_SetDomainInfo(pipes_struct *p,
6447                              struct samr_SetDomainInfo *r)
6448 {
6449         struct samr_domain_info *dinfo;
6450         NTSTATUS status;
6451         uint32_t acc_required = 0;
6452
6453         DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
6454
6455         switch (r->in.level) {
6456         case 1: /* DomainPasswordInformation */
6457         case 12: /* DomainLockoutInformation */
6458                 /* DOMAIN_WRITE_PASSWORD_PARAMETERS */
6459                 acc_required = SAMR_DOMAIN_ACCESS_SET_INFO_1;
6460                 break;
6461         case 3: /* DomainLogoffInformation */
6462         case 4: /* DomainOemInformation */
6463                 /* DOMAIN_WRITE_OTHER_PARAMETERS */
6464                 acc_required = SAMR_DOMAIN_ACCESS_SET_INFO_2;
6465                 break;
6466         case 6: /* DomainReplicationInformation */
6467         case 9: /* DomainStateInformation */
6468         case 7: /* DomainServerRoleInformation */
6469                 /* DOMAIN_ADMINISTER_SERVER */
6470                 acc_required = SAMR_DOMAIN_ACCESS_SET_INFO_3;
6471                 break;
6472         default:
6473                 return NT_STATUS_INVALID_INFO_CLASS;
6474         }
6475
6476         dinfo = policy_handle_find(p, r->in.domain_handle,
6477                                    acc_required, NULL,
6478                                    struct samr_domain_info, &status);
6479         if (!NT_STATUS_IS_OK(status)) {
6480                 return status;
6481         }
6482
6483         DEBUG(5,("_samr_SetDomainInfo: level: %d\n", r->in.level));
6484
6485         switch (r->in.level) {
6486                 case 1:
6487                         status = set_dom_info_1(p->mem_ctx, &r->in.info->info1);
6488                         break;
6489                 case 3:
6490                         status = set_dom_info_3(p->mem_ctx, &r->in.info->info3);
6491                         break;
6492                 case 4:
6493                         break;
6494                 case 6:
6495                         break;
6496                 case 7:
6497                         break;
6498                 case 9:
6499                         break;
6500                 case 12:
6501                         status = set_dom_info_12(p->mem_ctx, &r->in.info->info12);
6502                         break;
6503                 default:
6504                         return NT_STATUS_INVALID_INFO_CLASS;
6505         }
6506
6507         if (!NT_STATUS_IS_OK(status)) {
6508                 return status;
6509         }
6510
6511         DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
6512
6513         return NT_STATUS_OK;
6514 }
6515
6516 /****************************************************************
6517  _samr_GetDisplayEnumerationIndex
6518 ****************************************************************/
6519
6520 NTSTATUS _samr_GetDisplayEnumerationIndex(pipes_struct *p,
6521                                           struct samr_GetDisplayEnumerationIndex *r)
6522 {
6523         struct samr_domain_info *dinfo;
6524         uint32_t max_entries = (uint32_t) -1;
6525         uint32_t enum_context = 0;
6526         int i;
6527         uint32_t num_account = 0;
6528         struct samr_displayentry *entries = NULL;
6529         NTSTATUS status;
6530
6531         DEBUG(5,("_samr_GetDisplayEnumerationIndex: %d\n", __LINE__));
6532
6533         dinfo = policy_handle_find(p, r->in.domain_handle,
6534                                    SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
6535                                    struct samr_domain_info, &status);
6536         if (!NT_STATUS_IS_OK(status)) {
6537                 return status;
6538         }
6539
6540         if ((r->in.level < 1) || (r->in.level > 3)) {
6541                 DEBUG(0,("_samr_GetDisplayEnumerationIndex: "
6542                         "Unknown info level (%u)\n",
6543                         r->in.level));
6544                 return NT_STATUS_INVALID_INFO_CLASS;
6545         }
6546
6547         become_root();
6548
6549         /* The following done as ROOT. Don't return without unbecome_root(). */
6550
6551         switch (r->in.level) {
6552         case 1:
6553                 if (dinfo->disp_info->users == NULL) {
6554                         dinfo->disp_info->users = pdb_search_users(
6555                                 dinfo->disp_info, ACB_NORMAL);
6556                         if (dinfo->disp_info->users == NULL) {
6557                                 unbecome_root();
6558                                 return NT_STATUS_ACCESS_DENIED;
6559                         }
6560                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6561                                 "starting user enumeration at index %u\n",
6562                                 (unsigned int)enum_context));
6563                 } else {
6564                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6565                                 "using cached user enumeration at index %u\n",
6566                                 (unsigned int)enum_context));
6567                 }
6568                 num_account = pdb_search_entries(dinfo->disp_info->users,
6569                                                  enum_context, max_entries,
6570                                                  &entries);
6571                 break;
6572         case 2:
6573                 if (dinfo->disp_info->machines == NULL) {
6574                         dinfo->disp_info->machines = pdb_search_users(
6575                                 dinfo->disp_info, ACB_WSTRUST|ACB_SVRTRUST);
6576                         if (dinfo->disp_info->machines == NULL) {
6577                                 unbecome_root();
6578                                 return NT_STATUS_ACCESS_DENIED;
6579                         }
6580                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6581                                 "starting machine enumeration at index %u\n",
6582                                 (unsigned int)enum_context));
6583                 } else {
6584                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6585                                 "using cached machine enumeration at index %u\n",
6586                                 (unsigned int)enum_context));
6587                 }
6588                 num_account = pdb_search_entries(dinfo->disp_info->machines,
6589                                                  enum_context, max_entries,
6590                                                  &entries);
6591                 break;
6592         case 3:
6593                 if (dinfo->disp_info->groups == NULL) {
6594                         dinfo->disp_info->groups = pdb_search_groups(
6595                                 dinfo->disp_info);
6596                         if (dinfo->disp_info->groups == NULL) {
6597                                 unbecome_root();
6598                                 return NT_STATUS_ACCESS_DENIED;
6599                         }
6600                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6601                                 "starting group enumeration at index %u\n",
6602                                 (unsigned int)enum_context));
6603                 } else {
6604                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6605                                 "using cached group enumeration at index %u\n",
6606                                 (unsigned int)enum_context));
6607                 }
6608                 num_account = pdb_search_entries(dinfo->disp_info->groups,
6609                                                  enum_context, max_entries,
6610                                                  &entries);
6611                 break;
6612         default:
6613                 unbecome_root();
6614                 smb_panic("info class changed");
6615                 break;
6616         }
6617
6618         unbecome_root();
6619
6620         /* Ensure we cache this enumeration. */
6621         set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
6622
6623         DEBUG(10,("_samr_GetDisplayEnumerationIndex: looking for :%s\n",
6624                 r->in.name->string));
6625
6626         for (i=0; i<num_account; i++) {
6627                 if (strequal(entries[i].account_name, r->in.name->string)) {
6628                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6629                                 "found %s at idx %d\n",
6630                                 r->in.name->string, i));
6631                         *r->out.idx = i;
6632                         return NT_STATUS_OK;
6633                 }
6634         }
6635
6636         /* assuming account_name lives at the very end */
6637         *r->out.idx = num_account;
6638
6639         return NT_STATUS_NO_MORE_ENTRIES;
6640 }
6641
6642 /****************************************************************
6643  _samr_GetDisplayEnumerationIndex2
6644 ****************************************************************/
6645
6646 NTSTATUS _samr_GetDisplayEnumerationIndex2(pipes_struct *p,
6647                                            struct samr_GetDisplayEnumerationIndex2 *r)
6648 {
6649         struct samr_GetDisplayEnumerationIndex q;
6650
6651         q.in.domain_handle      = r->in.domain_handle;
6652         q.in.level              = r->in.level;
6653         q.in.name               = r->in.name;
6654
6655         q.out.idx               = r->out.idx;
6656
6657         return _samr_GetDisplayEnumerationIndex(p, &q);
6658 }
6659
6660 /****************************************************************
6661  _samr_RidToSid
6662 ****************************************************************/
6663
6664 NTSTATUS _samr_RidToSid(pipes_struct *p,
6665                         struct samr_RidToSid *r)
6666 {
6667         struct samr_domain_info *dinfo;
6668         NTSTATUS status;
6669         struct dom_sid sid;
6670
6671         dinfo = policy_handle_find(p, r->in.domain_handle,
6672                                    0, NULL,
6673                                    struct samr_domain_info, &status);
6674         if (!NT_STATUS_IS_OK(status)) {
6675                 return status;
6676         }
6677
6678         if (!sid_compose(&sid, &dinfo->sid, r->in.rid)) {
6679                 return NT_STATUS_NO_MEMORY;
6680         }
6681
6682         *r->out.sid = sid_dup_talloc(p->mem_ctx, &sid);
6683         if (!*r->out.sid) {
6684                 return NT_STATUS_NO_MEMORY;
6685         }
6686
6687         return NT_STATUS_OK;
6688 }
6689
6690 /****************************************************************
6691 ****************************************************************/
6692
6693 static enum samr_ValidationStatus samr_ValidatePassword_Change(TALLOC_CTX *mem_ctx,
6694                                                                const struct samr_PwInfo *dom_pw_info,
6695                                                                const struct samr_ValidatePasswordReq2 *req,
6696                                                                struct samr_ValidatePasswordRepCtr *rep)
6697 {
6698         NTSTATUS status;
6699
6700         if (req->password.string == NULL) {
6701                 return SAMR_VALIDATION_STATUS_SUCCESS;
6702         }
6703         if (strlen(req->password.string) < dom_pw_info->min_password_length) {
6704                 ZERO_STRUCT(rep->info);
6705                 return SAMR_VALIDATION_STATUS_PWD_TOO_SHORT;
6706         }
6707         if (dom_pw_info->password_properties & DOMAIN_PASSWORD_COMPLEX) {
6708                 status = check_password_complexity(req->account.string,
6709                                                    req->password.string,
6710                                                    NULL);
6711                 if (!NT_STATUS_IS_OK(status)) {
6712                         ZERO_STRUCT(rep->info);
6713                         return SAMR_VALIDATION_STATUS_NOT_COMPLEX_ENOUGH;
6714                 }
6715         }
6716
6717         return SAMR_VALIDATION_STATUS_SUCCESS;
6718 }
6719
6720 /****************************************************************
6721 ****************************************************************/
6722
6723 static enum samr_ValidationStatus samr_ValidatePassword_Reset(TALLOC_CTX *mem_ctx,
6724                                                               const struct samr_PwInfo *dom_pw_info,
6725                                                               const struct samr_ValidatePasswordReq3 *req,
6726                                                               struct samr_ValidatePasswordRepCtr *rep)
6727 {
6728         NTSTATUS status;
6729
6730         if (req->password.string == NULL) {
6731                 return SAMR_VALIDATION_STATUS_SUCCESS;
6732         }
6733         if (strlen(req->password.string) < dom_pw_info->min_password_length) {
6734                 ZERO_STRUCT(rep->info);
6735                 return SAMR_VALIDATION_STATUS_PWD_TOO_SHORT;
6736         }
6737         if (dom_pw_info->password_properties & DOMAIN_PASSWORD_COMPLEX) {
6738                 status = check_password_complexity(req->account.string,
6739                                                    req->password.string,
6740                                                    NULL);
6741                 if (!NT_STATUS_IS_OK(status)) {
6742                         ZERO_STRUCT(rep->info);
6743                         return SAMR_VALIDATION_STATUS_NOT_COMPLEX_ENOUGH;
6744                 }
6745         }
6746
6747         return SAMR_VALIDATION_STATUS_SUCCESS;
6748 }
6749
6750 /****************************************************************
6751  _samr_ValidatePassword
6752 ****************************************************************/
6753
6754 NTSTATUS _samr_ValidatePassword(pipes_struct *p,
6755                                 struct samr_ValidatePassword *r)
6756 {
6757         union samr_ValidatePasswordRep *rep;
6758         NTSTATUS status;
6759         struct samr_GetDomPwInfo pw;
6760         struct samr_PwInfo dom_pw_info;
6761
6762         if (r->in.level < 1 || r->in.level > 3) {
6763                 return NT_STATUS_INVALID_INFO_CLASS;
6764         }
6765
6766         pw.in.domain_name = NULL;
6767         pw.out.info = &dom_pw_info;
6768
6769         status = _samr_GetDomPwInfo(p, &pw);
6770         if (!NT_STATUS_IS_OK(status)) {
6771                 return status;
6772         }
6773
6774         rep = talloc_zero(p->mem_ctx, union samr_ValidatePasswordRep);
6775         if (!rep) {
6776                 return NT_STATUS_NO_MEMORY;
6777         }
6778
6779         switch (r->in.level) {
6780         case 1:
6781                 status = NT_STATUS_NOT_SUPPORTED;
6782                 break;
6783         case 2:
6784                 rep->ctr2.status = samr_ValidatePassword_Change(p->mem_ctx,
6785                                                                 &dom_pw_info,
6786                                                                 &r->in.req->req2,
6787                                                                 &rep->ctr2);
6788                 break;
6789         case 3:
6790                 rep->ctr3.status = samr_ValidatePassword_Reset(p->mem_ctx,
6791                                                                &dom_pw_info,
6792                                                                &r->in.req->req3,
6793                                                                &rep->ctr3);
6794                 break;
6795         default:
6796                 status = NT_STATUS_INVALID_INFO_CLASS;
6797                 break;
6798         }
6799
6800         if (!NT_STATUS_IS_OK(status)) {
6801                 talloc_free(rep);
6802                 return status;
6803         }
6804
6805         *r->out.rep = rep;
6806
6807         return NT_STATUS_OK;
6808 }
6809
6810 /****************************************************************
6811 ****************************************************************/
6812
6813 NTSTATUS _samr_Shutdown(pipes_struct *p,
6814                         struct samr_Shutdown *r)
6815 {
6816         p->rng_fault_state = true;
6817         return NT_STATUS_NOT_IMPLEMENTED;
6818 }
6819
6820 /****************************************************************
6821 ****************************************************************/
6822
6823 NTSTATUS _samr_SetMemberAttributesOfGroup(pipes_struct *p,
6824                                           struct samr_SetMemberAttributesOfGroup *r)
6825 {
6826         p->rng_fault_state = true;
6827         return NT_STATUS_NOT_IMPLEMENTED;
6828 }
6829
6830 /****************************************************************
6831 ****************************************************************/
6832
6833 NTSTATUS _samr_TestPrivateFunctionsDomain(pipes_struct *p,
6834                                           struct samr_TestPrivateFunctionsDomain *r)
6835 {
6836         return NT_STATUS_NOT_IMPLEMENTED;
6837 }
6838
6839 /****************************************************************
6840 ****************************************************************/
6841
6842 NTSTATUS _samr_TestPrivateFunctionsUser(pipes_struct *p,
6843                                         struct samr_TestPrivateFunctionsUser *r)
6844 {
6845         return NT_STATUS_NOT_IMPLEMENTED;
6846 }
6847
6848 /****************************************************************
6849 ****************************************************************/
6850
6851 NTSTATUS _samr_AddMultipleMembersToAlias(pipes_struct *p,
6852                                          struct samr_AddMultipleMembersToAlias *r)
6853 {
6854         p->rng_fault_state = true;
6855         return NT_STATUS_NOT_IMPLEMENTED;
6856 }
6857
6858 /****************************************************************
6859 ****************************************************************/
6860
6861 NTSTATUS _samr_RemoveMultipleMembersFromAlias(pipes_struct *p,
6862                                               struct samr_RemoveMultipleMembersFromAlias *r)
6863 {
6864         p->rng_fault_state = true;
6865         return NT_STATUS_NOT_IMPLEMENTED;
6866 }
6867
6868 /****************************************************************
6869 ****************************************************************/
6870
6871 NTSTATUS _samr_SetBootKeyInformation(pipes_struct *p,
6872                                      struct samr_SetBootKeyInformation *r)
6873 {
6874         p->rng_fault_state = true;
6875         return NT_STATUS_NOT_IMPLEMENTED;
6876 }
6877
6878 /****************************************************************
6879 ****************************************************************/
6880
6881 NTSTATUS _samr_GetBootKeyInformation(pipes_struct *p,
6882                                      struct samr_GetBootKeyInformation *r)
6883 {
6884         p->rng_fault_state = true;
6885         return NT_STATUS_NOT_IMPLEMENTED;
6886 }
6887
6888 /****************************************************************
6889 ****************************************************************/
6890
6891 NTSTATUS _samr_SetDsrmPassword(pipes_struct *p,
6892                                struct samr_SetDsrmPassword *r)
6893 {
6894         p->rng_fault_state = true;
6895         return NT_STATUS_NOT_IMPLEMENTED;
6896 }