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