7881ca62eaf02183d1a60521f00fd4013e0b07fd
[bbaumbach/samba-autobuild/.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 && user_has_any_privilege( token, rights ) ) {
180
181                 saved_mask = (des_access & rights_mask);
182                 des_access &= ~saved_mask;
183
184                 DEBUG(4,("access_check_samr_object: user rights access mask [0x%x]\n",
185                         rights_mask));
186         }
187
188
189         /* check the security descriptor first */
190
191         status = se_access_check(psd, token, des_access, acc_granted);
192         if (NT_STATUS_IS_OK(status)) {
193                 goto done;
194         }
195
196         /* give root a free pass */
197
198         if ( geteuid() == sec_initial_uid() ) {
199
200                 DEBUG(4,("%s: ACCESS should be DENIED  (requested: %#010x)\n", debug, des_access));
201                 DEBUGADD(4,("but overritten by euid == sec_initial_uid()\n"));
202
203                 *acc_granted = des_access;
204
205                 status = NT_STATUS_OK;
206                 goto done;
207         }
208
209
210 done:
211         /* add in any bits saved during the privilege check (only
212            matters is status is ok) */
213
214         *acc_granted |= rights_mask;
215
216         DEBUG(4,("%s: access %s (requested: 0x%08x, granted: 0x%08x)\n",
217                 debug, NT_STATUS_IS_OK(status) ? "GRANTED" : "DENIED",
218                 des_access, *acc_granted));
219
220         return status;
221 }
222
223 /*******************************************************************
224  Checks if access to a function can be granted
225 ********************************************************************/
226
227 static NTSTATUS access_check_samr_function(uint32 acc_granted, uint32 acc_required, const char *debug)
228 {
229         DEBUG(5,("%s: access check ((granted: %#010x;  required: %#010x)\n",
230                 debug, acc_granted, acc_required));
231
232         /* check the security descriptor first */
233
234         if ( (acc_granted&acc_required) == acc_required )
235                 return NT_STATUS_OK;
236
237         /* give root a free pass */
238
239         if (geteuid() == sec_initial_uid()) {
240
241                 DEBUG(4,("%s: ACCESS should be DENIED (granted: %#010x;  required: %#010x)\n",
242                         debug, acc_granted, acc_required));
243                 DEBUGADD(4,("but overwritten by euid == 0\n"));
244
245                 return NT_STATUS_OK;
246         }
247
248         DEBUG(2,("%s: ACCESS DENIED (granted: %#010x;  required: %#010x)\n",
249                 debug, acc_granted, acc_required));
250
251         return NT_STATUS_ACCESS_DENIED;
252 }
253
254 /*******************************************************************
255  Map any MAXIMUM_ALLOWED_ACCESS request to a valid access set.
256 ********************************************************************/
257
258 static void map_max_allowed_access(const NT_USER_TOKEN *token,
259                                         uint32_t *pacc_requested)
260 {
261         if (!((*pacc_requested) & MAXIMUM_ALLOWED_ACCESS)) {
262                 return;
263         }
264         *pacc_requested &= ~MAXIMUM_ALLOWED_ACCESS;
265
266         /* At least try for generic read. */
267         *pacc_requested = GENERIC_READ_ACCESS;
268
269         /* root gets anything. */
270         if (geteuid() == sec_initial_uid()) {
271                 *pacc_requested |= GENERIC_ALL_ACCESS;
272                 return;
273         }
274
275         /* Full Access for 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
276
277         if (is_sid_in_token(token, &global_sid_Builtin_Administrators) ||
278                         is_sid_in_token(token, &global_sid_Builtin_Account_Operators)) {
279                 *pacc_requested |= GENERIC_ALL_ACCESS;
280                 return;
281         }
282
283         /* Full access for DOMAIN\Domain Admins. */
284         if ( IS_DC ) {
285                 DOM_SID domadmin_sid;
286                 sid_copy( &domadmin_sid, get_global_sam_sid() );
287                 sid_append_rid( &domadmin_sid, DOMAIN_GROUP_RID_ADMINS );
288                 if (is_sid_in_token(token, &domadmin_sid)) {
289                         *pacc_requested |= GENERIC_ALL_ACCESS;
290                         return;
291                 }
292         }
293         /* TODO ! Check privileges. */
294 }
295
296 /*******************************************************************
297  Fetch or create a dispinfo struct.
298 ********************************************************************/
299
300 static DISP_INFO *get_samr_dispinfo_by_sid(DOM_SID *psid)
301 {
302         /*
303          * We do a static cache for DISP_INFO's here. Explanation can be found
304          * in Jeremy's checkin message to r11793:
305          *
306          * Fix the SAMR cache so it works across completely insane
307          * client behaviour (ie.:
308          * open pipe/open SAMR handle/enumerate 0 - 1024
309          * close SAMR handle, close pipe.
310          * open pipe/open SAMR handle/enumerate 1024 - 2048...
311          * close SAMR handle, close pipe.
312          * And on ad-nausium. Amazing.... probably object-oriented
313          * client side programming in action yet again.
314          * This change should *massively* improve performance when
315          * enumerating users from an LDAP database.
316          * Jeremy.
317          *
318          * "Our" and the builtin domain are the only ones where we ever
319          * enumerate stuff, so just cache 2 entries.
320          */
321
322         static struct disp_info *builtin_dispinfo;
323         static struct disp_info *domain_dispinfo;
324
325         /* There are two cases to consider here:
326            1) The SID is a domain SID and we look for an equality match, or
327            2) This is an account SID and so we return the DISP_INFO* for our
328               domain */
329
330         if (psid == NULL) {
331                 return NULL;
332         }
333
334         if (sid_check_is_builtin(psid) || sid_check_is_in_builtin(psid)) {
335                 /*
336                  * Necessary only once, but it does not really hurt.
337                  */
338                 if (builtin_dispinfo == NULL) {
339                         builtin_dispinfo = talloc_zero(
340                                 talloc_autofree_context(), struct disp_info);
341                         if (builtin_dispinfo == NULL) {
342                                 return NULL;
343                         }
344                 }
345                 sid_copy(&builtin_dispinfo->sid, &global_sid_Builtin);
346
347                 return builtin_dispinfo;
348         }
349
350         if (sid_check_is_domain(psid) || sid_check_is_in_our_domain(psid)) {
351                 /*
352                  * Necessary only once, but it does not really hurt.
353                  */
354                 if (domain_dispinfo == NULL) {
355                         domain_dispinfo = talloc_zero(
356                                 talloc_autofree_context(), struct disp_info);
357                         if (domain_dispinfo == NULL) {
358                                 return NULL;
359                         }
360                 }
361                 sid_copy(&domain_dispinfo->sid, get_global_sam_sid());
362
363                 return domain_dispinfo;
364         }
365
366         return NULL;
367 }
368
369 /*******************************************************************
370  Create a samr_info struct.
371 ********************************************************************/
372
373 static int samr_info_destructor(struct samr_info *info);
374
375 static struct samr_info *get_samr_info_by_sid(TALLOC_CTX *mem_ctx,
376                                               DOM_SID *psid)
377 {
378         struct samr_info *info;
379         fstring sid_str;
380
381         if (psid) {
382                 sid_to_fstring(sid_str, psid);
383         } else {
384                 fstrcpy(sid_str,"(NULL)");
385         }
386
387         if ((info = TALLOC_ZERO_P(mem_ctx, struct samr_info)) == NULL) {
388                 return NULL;
389         }
390         talloc_set_destructor(info, samr_info_destructor);
391
392         DEBUG(10,("get_samr_info_by_sid: created new info for sid %s\n", sid_str));
393         if (psid) {
394                 sid_copy( &info->sid, psid);
395                 info->builtin_domain = sid_check_is_builtin(psid);
396         } else {
397                 DEBUG(10,("get_samr_info_by_sid: created new info for NULL sid.\n"));
398                 info->builtin_domain = False;
399         }
400
401         info->disp_info = get_samr_dispinfo_by_sid(psid);
402
403         return info;
404 }
405
406 /*******************************************************************
407  Function to free the per SID data.
408  ********************************************************************/
409
410 static void free_samr_cache(DISP_INFO *disp_info)
411 {
412         DEBUG(10, ("free_samr_cache: deleting cache for SID %s\n",
413                    sid_string_dbg(&disp_info->sid)));
414
415         /* We need to become root here because the paged search might have to
416          * tell the LDAP server we're not interested in the rest anymore. */
417
418         become_root();
419
420         TALLOC_FREE(disp_info->users);
421         TALLOC_FREE(disp_info->machines);
422         TALLOC_FREE(disp_info->groups);
423         TALLOC_FREE(disp_info->aliases);
424         TALLOC_FREE(disp_info->enum_users);
425
426         unbecome_root();
427 }
428
429 static int samr_info_destructor(struct samr_info *info)
430 {
431         /* Only free the dispinfo cache if no one bothered to set up
432            a timeout. */
433
434         if (info->disp_info && info->disp_info->cache_timeout_event == NULL) {
435                 free_samr_cache(info->disp_info);
436         }
437         return 0;
438 }
439
440 /*******************************************************************
441  Idle event handler. Throw away the disp info cache.
442  ********************************************************************/
443
444 static void disp_info_cache_idle_timeout_handler(struct event_context *ev_ctx,
445                                                  struct timed_event *te,
446                                                  struct timeval now,
447                                                  void *private_data)
448 {
449         DISP_INFO *disp_info = (DISP_INFO *)private_data;
450
451         TALLOC_FREE(disp_info->cache_timeout_event);
452
453         DEBUG(10, ("disp_info_cache_idle_timeout_handler: caching timed "
454                    "out\n"));
455         free_samr_cache(disp_info);
456 }
457
458 /*******************************************************************
459  Setup cache removal idle event handler.
460  ********************************************************************/
461
462 static void set_disp_info_cache_timeout(DISP_INFO *disp_info, time_t secs_fromnow)
463 {
464         /* Remove any pending timeout and update. */
465
466         TALLOC_FREE(disp_info->cache_timeout_event);
467
468         DEBUG(10,("set_disp_info_cache_timeout: caching enumeration for "
469                   "SID %s for %u seconds\n", sid_string_dbg(&disp_info->sid),
470                   (unsigned int)secs_fromnow ));
471
472         disp_info->cache_timeout_event = event_add_timed(
473                 smbd_event_context(), NULL,
474                 timeval_current_ofs(secs_fromnow, 0),
475                 disp_info_cache_idle_timeout_handler, (void *)disp_info);
476 }
477
478 /*******************************************************************
479  Force flush any cache. We do this on any samr_set_xxx call.
480  We must also remove the timeout handler.
481  ********************************************************************/
482
483 static void force_flush_samr_cache(DISP_INFO *disp_info)
484 {
485         if ((disp_info == NULL) || (disp_info->cache_timeout_event == NULL)) {
486                 return;
487         }
488
489         DEBUG(10,("force_flush_samr_cache: clearing idle event\n"));
490         TALLOC_FREE(disp_info->cache_timeout_event);
491         free_samr_cache(disp_info);
492 }
493
494 /*******************************************************************
495  Ensure password info is never given out. Paranioa... JRA.
496  ********************************************************************/
497
498 static void samr_clear_sam_passwd(struct samu *sam_pass)
499 {
500
501         if (!sam_pass)
502                 return;
503
504         /* These now zero out the old password */
505
506         pdb_set_lanman_passwd(sam_pass, NULL, PDB_DEFAULT);
507         pdb_set_nt_passwd(sam_pass, NULL, PDB_DEFAULT);
508 }
509
510 static uint32 count_sam_users(struct disp_info *info, uint32 acct_flags)
511 {
512         struct samr_displayentry *entry;
513
514         if (info->builtin_domain) {
515                 /* No users in builtin. */
516                 return 0;
517         }
518
519         if (info->users == NULL) {
520                 info->users = pdb_search_users(info, acct_flags);
521                 if (info->users == NULL) {
522                         return 0;
523                 }
524         }
525         /* Fetch the last possible entry, thus trigger an enumeration */
526         pdb_search_entries(info->users, 0xffffffff, 1, &entry);
527
528         /* Ensure we cache this enumeration. */
529         set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
530
531         return info->users->num_entries;
532 }
533
534 static uint32 count_sam_groups(struct disp_info *info)
535 {
536         struct samr_displayentry *entry;
537
538         if (info->builtin_domain) {
539                 /* No groups in builtin. */
540                 return 0;
541         }
542
543         if (info->groups == NULL) {
544                 info->groups = pdb_search_groups(info);
545                 if (info->groups == NULL) {
546                         return 0;
547                 }
548         }
549         /* Fetch the last possible entry, thus trigger an enumeration */
550         pdb_search_entries(info->groups, 0xffffffff, 1, &entry);
551
552         /* Ensure we cache this enumeration. */
553         set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
554
555         return info->groups->num_entries;
556 }
557
558 static uint32 count_sam_aliases(struct disp_info *info)
559 {
560         struct samr_displayentry *entry;
561
562         if (info->aliases == NULL) {
563                 info->aliases = pdb_search_aliases(info, &info->sid);
564                 if (info->aliases == NULL) {
565                         return 0;
566                 }
567         }
568         /* Fetch the last possible entry, thus trigger an enumeration */
569         pdb_search_entries(info->aliases, 0xffffffff, 1, &entry);
570
571         /* Ensure we cache this enumeration. */
572         set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
573
574         return info->aliases->num_entries;
575 }
576
577 /*******************************************************************
578  _samr_Close
579  ********************************************************************/
580
581 NTSTATUS _samr_Close(pipes_struct *p, struct samr_Close *r)
582 {
583         if (!close_policy_hnd(p, r->in.handle)) {
584                 return NT_STATUS_INVALID_HANDLE;
585         }
586
587         ZERO_STRUCTP(r->out.handle);
588
589         return NT_STATUS_OK;
590 }
591
592 /*******************************************************************
593  _samr_OpenDomain
594  ********************************************************************/
595
596 NTSTATUS _samr_OpenDomain(pipes_struct *p,
597                           struct samr_OpenDomain *r)
598 {
599         struct    samr_info *info;
600         SEC_DESC *psd = NULL;
601         uint32    acc_granted;
602         uint32    des_access = r->in.access_mask;
603         NTSTATUS  status;
604         size_t    sd_size;
605         SE_PRIV se_rights;
606
607         /* find the connection policy handle. */
608
609         if ( !find_policy_by_hnd(p, r->in.connect_handle, (void**)(void *)&info) )
610                 return NT_STATUS_INVALID_HANDLE;
611
612         status = access_check_samr_function(info->acc_granted,
613                                             SAMR_ACCESS_OPEN_DOMAIN,
614                                             "_samr_OpenDomain" );
615
616         if ( !NT_STATUS_IS_OK(status) )
617                 return status;
618
619         /*check if access can be granted as requested by client. */
620         map_max_allowed_access(p->server_info->ptok, &des_access);
621
622         make_samr_object_sd( p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0 );
623         se_map_generic( &des_access, &dom_generic_mapping );
624
625         se_priv_copy( &se_rights, &se_machine_account );
626         se_priv_add( &se_rights, &se_add_users );
627
628         status = access_check_samr_object( psd, p->server_info->ptok,
629                 &se_rights, GENERIC_RIGHTS_DOMAIN_WRITE, des_access,
630                 &acc_granted, "_samr_OpenDomain" );
631
632         if ( !NT_STATUS_IS_OK(status) )
633                 return status;
634
635         if (!sid_check_is_domain(r->in.sid) &&
636             !sid_check_is_builtin(r->in.sid)) {
637                 return NT_STATUS_NO_SUCH_DOMAIN;
638         }
639
640         /* associate the domain SID with the (unique) handle. */
641         if ((info = get_samr_info_by_sid(p->mem_ctx, r->in.sid))==NULL)
642                 return NT_STATUS_NO_MEMORY;
643         info->acc_granted = acc_granted;
644
645         /* get a (unique) handle.  open a policy on it. */
646         if (!create_policy_hnd(p, r->out.domain_handle, info))
647                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
648
649         DEBUG(5,("_samr_OpenDomain: %d\n", __LINE__));
650
651         return NT_STATUS_OK;
652 }
653
654 /*******************************************************************
655  _samr_GetUserPwInfo
656  ********************************************************************/
657
658 NTSTATUS _samr_GetUserPwInfo(pipes_struct *p,
659                              struct samr_GetUserPwInfo *r)
660 {
661         struct samr_info *info = NULL;
662         enum lsa_SidType sid_type;
663         uint32_t min_password_length = 0;
664         uint32_t password_properties = 0;
665         bool ret = false;
666         NTSTATUS status;
667
668         DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__));
669
670         /* find the policy handle.  open a policy on it. */
671         if (!find_policy_by_hnd(p, r->in.user_handle, (void **)(void *)&info)) {
672                 return NT_STATUS_INVALID_HANDLE;
673         }
674
675         status = access_check_samr_function(info->acc_granted,
676                                             SAMR_USER_ACCESS_GET_ATTRIBUTES,
677                                             "_samr_GetUserPwInfo" );
678         if (!NT_STATUS_IS_OK(status)) {
679                 return status;
680         }
681
682         if (!sid_check_is_in_our_domain(&info->sid)) {
683                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
684         }
685
686         become_root();
687         ret = lookup_sid(p->mem_ctx, &info->sid, NULL, NULL, &sid_type);
688         unbecome_root();
689         if (ret == false) {
690                 return NT_STATUS_NO_SUCH_USER;
691         }
692
693         switch (sid_type) {
694                 case SID_NAME_USER:
695                         become_root();
696                         pdb_get_account_policy(AP_MIN_PASSWORD_LEN,
697                                                &min_password_length);
698                         pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
699                                                &password_properties);
700                         unbecome_root();
701
702                         if (lp_check_password_script() && *lp_check_password_script()) {
703                                 password_properties |= DOMAIN_PASSWORD_COMPLEX;
704                         }
705
706                         break;
707                 default:
708                         break;
709         }
710
711         r->out.info->min_password_length = min_password_length;
712         r->out.info->password_properties = password_properties;
713
714         DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__));
715
716         return NT_STATUS_OK;
717 }
718
719 /*******************************************************************
720 ********************************************************************/
721
722 static bool get_lsa_policy_samr_sid( pipes_struct *p, struct policy_handle *pol,
723                                         DOM_SID *sid, uint32 *acc_granted,
724                                         DISP_INFO **ppdisp_info)
725 {
726         struct samr_info *info = NULL;
727
728         /* find the policy handle.  open a policy on it. */
729         if (!find_policy_by_hnd(p, pol, (void **)(void *)&info))
730                 return False;
731
732         if (!info)
733                 return False;
734
735         *sid = info->sid;
736         *acc_granted = info->acc_granted;
737         if (ppdisp_info) {
738                 *ppdisp_info = info->disp_info;
739         }
740
741         return True;
742 }
743
744 /*******************************************************************
745  _samr_SetSecurity
746  ********************************************************************/
747
748 NTSTATUS _samr_SetSecurity(pipes_struct *p,
749                            struct samr_SetSecurity *r)
750 {
751         DOM_SID pol_sid;
752         uint32 acc_granted, i;
753         SEC_ACL *dacl;
754         bool ret;
755         struct samu *sampass=NULL;
756         NTSTATUS status;
757
758         if (!get_lsa_policy_samr_sid(p, r->in.handle, &pol_sid, &acc_granted, NULL))
759                 return NT_STATUS_INVALID_HANDLE;
760
761         if (!(sampass = samu_new( p->mem_ctx))) {
762                 DEBUG(0,("No memory!\n"));
763                 return NT_STATUS_NO_MEMORY;
764         }
765
766         /* get the user record */
767         become_root();
768         ret = pdb_getsampwsid(sampass, &pol_sid);
769         unbecome_root();
770
771         if (!ret) {
772                 DEBUG(4, ("User %s not found\n", sid_string_dbg(&pol_sid)));
773                 TALLOC_FREE(sampass);
774                 return NT_STATUS_INVALID_HANDLE;
775         }
776
777         dacl = r->in.sdbuf->sd->dacl;
778         for (i=0; i < dacl->num_aces; i++) {
779                 if (sid_equal(&pol_sid, &dacl->aces[i].trustee)) {
780                         ret = pdb_set_pass_can_change(sampass,
781                                 (dacl->aces[i].access_mask &
782                                  SAMR_USER_ACCESS_CHANGE_PASSWORD) ?
783                                                       True: False);
784                         break;
785                 }
786         }
787
788         if (!ret) {
789                 TALLOC_FREE(sampass);
790                 return NT_STATUS_ACCESS_DENIED;
791         }
792
793         status = access_check_samr_function(acc_granted,
794                                             SAMR_USER_ACCESS_SET_ATTRIBUTES,
795                                             "_samr_SetSecurity");
796         if (NT_STATUS_IS_OK(status)) {
797                 become_root();
798                 status = pdb_update_sam_account(sampass);
799                 unbecome_root();
800         }
801
802         TALLOC_FREE(sampass);
803
804         return status;
805 }
806
807 /*******************************************************************
808   build correct perms based on policies and password times for _samr_query_sec_obj
809 *******************************************************************/
810 static bool check_change_pw_access(TALLOC_CTX *mem_ctx, DOM_SID *user_sid)
811 {
812         struct samu *sampass=NULL;
813         bool ret;
814
815         if ( !(sampass = samu_new( mem_ctx )) ) {
816                 DEBUG(0,("No memory!\n"));
817                 return False;
818         }
819
820         become_root();
821         ret = pdb_getsampwsid(sampass, user_sid);
822         unbecome_root();
823
824         if (ret == False) {
825                 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
826                 TALLOC_FREE(sampass);
827                 return False;
828         }
829
830         DEBUG(3,("User:[%s]\n",  pdb_get_username(sampass) ));
831
832         if (pdb_get_pass_can_change(sampass)) {
833                 TALLOC_FREE(sampass);
834                 return True;
835         }
836         TALLOC_FREE(sampass);
837         return False;
838 }
839
840
841 /*******************************************************************
842  _samr_QuerySecurity
843  ********************************************************************/
844
845 NTSTATUS _samr_QuerySecurity(pipes_struct *p,
846                              struct samr_QuerySecurity *r)
847 {
848         NTSTATUS status;
849         DOM_SID pol_sid;
850         SEC_DESC * psd = NULL;
851         uint32 acc_granted;
852         size_t sd_size;
853
854         /* Get the SID. */
855         if (!get_lsa_policy_samr_sid(p, r->in.handle, &pol_sid, &acc_granted, NULL))
856                 return NT_STATUS_INVALID_HANDLE;
857
858         DEBUG(10,("_samr_QuerySecurity: querying security on SID: %s\n",
859                   sid_string_dbg(&pol_sid)));
860
861         status = access_check_samr_function(acc_granted,
862                                             STD_RIGHT_READ_CONTROL_ACCESS,
863                                             "_samr_QuerySecurity");
864         if (!NT_STATUS_IS_OK(status)) {
865                 return status;
866         }
867
868         /* Check what typ of SID is beeing queried (e.g Domain SID, User SID, Group SID) */
869
870         /* To query the security of the SAM it self an invalid SID with S-0-0 is passed to this function */
871         if (pol_sid.sid_rev_num == 0) {
872                 DEBUG(5,("_samr_QuerySecurity: querying security on SAM\n"));
873                 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
874         } else if (sid_equal(&pol_sid,get_global_sam_sid())) {
875                 /* check if it is our domain SID */
876                 DEBUG(5,("_samr_QuerySecurity: querying security on Domain "
877                          "with SID: %s\n", sid_string_dbg(&pol_sid)));
878                 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0);
879         } else if (sid_equal(&pol_sid,&global_sid_Builtin)) {
880                 /* check if it is the Builtin  Domain */
881                 /* TODO: Builtin probably needs a different SD with restricted write access*/
882                 DEBUG(5,("_samr_QuerySecurity: querying security on Builtin "
883                          "Domain with SID: %s\n", sid_string_dbg(&pol_sid)));
884                 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0);
885         } else if (sid_check_is_in_our_domain(&pol_sid) ||
886                  sid_check_is_in_builtin(&pol_sid)) {
887                 /* TODO: different SDs have to be generated for aliases groups and users.
888                          Currently all three get a default user SD  */
889                 DEBUG(10,("_samr_QuerySecurity: querying security on Object "
890                           "with SID: %s\n", sid_string_dbg(&pol_sid)));
891                 if (check_change_pw_access(p->mem_ctx, &pol_sid)) {
892                         status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping,
893                                                           &pol_sid, SAMR_USR_RIGHTS_WRITE_PW);
894                 } else {
895                         status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_nopwchange_generic_mapping,
896                                                           &pol_sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
897                 }
898         } else {
899                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
900         }
901
902         if ((*r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
903                 return NT_STATUS_NO_MEMORY;
904
905         return status;
906 }
907
908 /*******************************************************************
909 makes a SAM_ENTRY / UNISTR2* structure from a user list.
910 ********************************************************************/
911
912 static NTSTATUS make_user_sam_entry_list(TALLOC_CTX *ctx,
913                                          struct samr_SamEntry **sam_pp,
914                                          uint32_t num_entries,
915                                          uint32_t start_idx,
916                                          struct samr_displayentry *entries)
917 {
918         uint32_t i;
919         struct samr_SamEntry *sam;
920
921         *sam_pp = NULL;
922
923         if (num_entries == 0) {
924                 return NT_STATUS_OK;
925         }
926
927         sam = TALLOC_ZERO_ARRAY(ctx, struct samr_SamEntry, num_entries);
928         if (sam == NULL) {
929                 DEBUG(0, ("make_user_sam_entry_list: TALLOC_ZERO failed!\n"));
930                 return NT_STATUS_NO_MEMORY;
931         }
932
933         for (i = 0; i < num_entries; i++) {
934 #if 0
935                 /*
936                  * usrmgr expects a non-NULL terminated string with
937                  * trust relationships
938                  */
939                 if (entries[i].acct_flags & ACB_DOMTRUST) {
940                         init_unistr2(&uni_temp_name, entries[i].account_name,
941                                      UNI_FLAGS_NONE);
942                 } else {
943                         init_unistr2(&uni_temp_name, entries[i].account_name,
944                                      UNI_STR_TERMINATE);
945                 }
946 #endif
947                 init_lsa_String(&sam[i].name, entries[i].account_name);
948                 sam[i].idx = entries[i].rid;
949         }
950
951         *sam_pp = sam;
952
953         return NT_STATUS_OK;
954 }
955
956 #define MAX_SAM_ENTRIES MAX_SAM_ENTRIES_W2K
957
958 /*******************************************************************
959  _samr_EnumDomainUsers
960  ********************************************************************/
961
962 NTSTATUS _samr_EnumDomainUsers(pipes_struct *p,
963                                struct samr_EnumDomainUsers *r)
964 {
965         NTSTATUS status;
966         struct samr_info *info = NULL;
967         int num_account;
968         uint32 enum_context = *r->in.resume_handle;
969         enum remote_arch_types ra_type = get_remote_arch();
970         int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
971         uint32 max_entries = max_sam_entries;
972         struct samr_displayentry *entries = NULL;
973         struct samr_SamArray *samr_array = NULL;
974         struct samr_SamEntry *samr_entries = NULL;
975
976         /* find the policy handle.  open a policy on it. */
977         if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
978                 return NT_STATUS_INVALID_HANDLE;
979
980         status = access_check_samr_function(info->acc_granted,
981                                             SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
982                                             "_samr_EnumDomainUsers");
983         if (!NT_STATUS_IS_OK(status)) {
984                 return status;
985         }
986
987         DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
988
989         if (info->builtin_domain) {
990                 /* No users in builtin. */
991                 *r->out.resume_handle = *r->in.resume_handle;
992                 DEBUG(5,("_samr_EnumDomainUsers: No users in BUILTIN\n"));
993                 return status;
994         }
995
996         samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
997         if (!samr_array) {
998                 return NT_STATUS_NO_MEMORY;
999         }
1000         *r->out.sam = samr_array;
1001
1002         become_root();
1003
1004         /* AS ROOT !!!! */
1005
1006         if ((info->disp_info->enum_users != NULL) &&
1007             (info->disp_info->enum_acb_mask != r->in.acct_flags)) {
1008                 TALLOC_FREE(info->disp_info->enum_users);
1009         }
1010
1011         if (info->disp_info->enum_users == NULL) {
1012                 info->disp_info->enum_users = pdb_search_users(
1013                         info->disp_info, r->in.acct_flags);
1014                 info->disp_info->enum_acb_mask = r->in.acct_flags;
1015         }
1016
1017         if (info->disp_info->enum_users == NULL) {
1018                 /* END AS ROOT !!!! */
1019                 unbecome_root();
1020                 return NT_STATUS_ACCESS_DENIED;
1021         }
1022
1023         num_account = pdb_search_entries(info->disp_info->enum_users,
1024                                          enum_context, max_entries,
1025                                          &entries);
1026
1027         /* END AS ROOT !!!! */
1028
1029         unbecome_root();
1030
1031         if (num_account == 0) {
1032                 DEBUG(5, ("_samr_EnumDomainUsers: enumeration handle over "
1033                           "total entries\n"));
1034                 *r->out.resume_handle = *r->in.resume_handle;
1035                 return NT_STATUS_OK;
1036         }
1037
1038         status = make_user_sam_entry_list(p->mem_ctx, &samr_entries,
1039                                           num_account, enum_context,
1040                                           entries);
1041         if (!NT_STATUS_IS_OK(status)) {
1042                 return status;
1043         }
1044
1045         if (max_entries <= num_account) {
1046                 status = STATUS_MORE_ENTRIES;
1047         } else {
1048                 status = NT_STATUS_OK;
1049         }
1050
1051         /* Ensure we cache this enumeration. */
1052         set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1053
1054         DEBUG(5, ("_samr_EnumDomainUsers: %d\n", __LINE__));
1055
1056         samr_array->count = num_account;
1057         samr_array->entries = samr_entries;
1058
1059         *r->out.resume_handle = *r->in.resume_handle + num_account;
1060         *r->out.num_entries = num_account;
1061
1062         DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
1063
1064         return status;
1065 }
1066
1067 /*******************************************************************
1068 makes a SAM_ENTRY / UNISTR2* structure from a group list.
1069 ********************************************************************/
1070
1071 static void make_group_sam_entry_list(TALLOC_CTX *ctx,
1072                                       struct samr_SamEntry **sam_pp,
1073                                       uint32_t num_sam_entries,
1074                                       struct samr_displayentry *entries)
1075 {
1076         struct samr_SamEntry *sam;
1077         uint32_t i;
1078
1079         *sam_pp = NULL;
1080
1081         if (num_sam_entries == 0) {
1082                 return;
1083         }
1084
1085         sam = TALLOC_ZERO_ARRAY(ctx, struct samr_SamEntry, num_sam_entries);
1086         if (sam == NULL) {
1087                 return;
1088         }
1089
1090         for (i = 0; i < num_sam_entries; i++) {
1091                 /*
1092                  * JRA. I think this should include the null. TNG does not.
1093                  */
1094                 init_lsa_String(&sam[i].name, entries[i].account_name);
1095                 sam[i].idx = entries[i].rid;
1096         }
1097
1098         *sam_pp = sam;
1099 }
1100
1101 /*******************************************************************
1102  _samr_EnumDomainGroups
1103  ********************************************************************/
1104
1105 NTSTATUS _samr_EnumDomainGroups(pipes_struct *p,
1106                                 struct samr_EnumDomainGroups *r)
1107 {
1108         NTSTATUS status;
1109         struct samr_info *info = NULL;
1110         struct samr_displayentry *groups;
1111         uint32 num_groups;
1112         struct samr_SamArray *samr_array = NULL;
1113         struct samr_SamEntry *samr_entries = NULL;
1114
1115         /* find the policy handle.  open a policy on it. */
1116         if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
1117                 return NT_STATUS_INVALID_HANDLE;
1118
1119         status = access_check_samr_function(info->acc_granted,
1120                                             SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
1121                                             "_samr_EnumDomainGroups");
1122         if (!NT_STATUS_IS_OK(status)) {
1123                 return status;
1124         }
1125
1126         DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
1127
1128         if (info->builtin_domain) {
1129                 /* No groups in builtin. */
1130                 *r->out.resume_handle = *r->in.resume_handle;
1131                 DEBUG(5,("_samr_EnumDomainGroups: No groups in BUILTIN\n"));
1132                 return status;
1133         }
1134
1135         samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
1136         if (!samr_array) {
1137                 return NT_STATUS_NO_MEMORY;
1138         }
1139
1140         /* the domain group array is being allocated in the function below */
1141
1142         become_root();
1143
1144         if (info->disp_info->groups == NULL) {
1145                 info->disp_info->groups = pdb_search_groups(info->disp_info);
1146
1147                 if (info->disp_info->groups == NULL) {
1148                         unbecome_root();
1149                         return NT_STATUS_ACCESS_DENIED;
1150                 }
1151         }
1152
1153         num_groups = pdb_search_entries(info->disp_info->groups,
1154                                         *r->in.resume_handle,
1155                                         MAX_SAM_ENTRIES, &groups);
1156         unbecome_root();
1157
1158         /* Ensure we cache this enumeration. */
1159         set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1160
1161         make_group_sam_entry_list(p->mem_ctx, &samr_entries,
1162                                   num_groups, groups);
1163
1164         samr_array->count = num_groups;
1165         samr_array->entries = samr_entries;
1166
1167         *r->out.sam = samr_array;
1168         *r->out.num_entries = num_groups;
1169         *r->out.resume_handle = num_groups + *r->in.resume_handle;
1170
1171         DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
1172
1173         return status;
1174 }
1175
1176 /*******************************************************************
1177  _samr_EnumDomainAliases
1178  ********************************************************************/
1179
1180 NTSTATUS _samr_EnumDomainAliases(pipes_struct *p,
1181                                  struct samr_EnumDomainAliases *r)
1182 {
1183         NTSTATUS status;
1184         struct samr_info *info;
1185         struct samr_displayentry *aliases;
1186         uint32 num_aliases = 0;
1187         struct samr_SamArray *samr_array = NULL;
1188         struct samr_SamEntry *samr_entries = NULL;
1189
1190         /* find the policy handle.  open a policy on it. */
1191         if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
1192                 return NT_STATUS_INVALID_HANDLE;
1193
1194         DEBUG(5,("_samr_EnumDomainAliases: sid %s\n",
1195                  sid_string_dbg(&info->sid)));
1196
1197         status = access_check_samr_function(info->acc_granted,
1198                                             SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
1199                                             "_samr_EnumDomainAliases");
1200         if (!NT_STATUS_IS_OK(status)) {
1201                 return status;
1202         }
1203
1204         samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
1205         if (!samr_array) {
1206                 return NT_STATUS_NO_MEMORY;
1207         }
1208
1209         become_root();
1210
1211         if (info->disp_info->aliases == NULL) {
1212                 info->disp_info->aliases = pdb_search_aliases(
1213                         info->disp_info, &info->sid);
1214                 if (info->disp_info->aliases == NULL) {
1215                         unbecome_root();
1216                         return NT_STATUS_ACCESS_DENIED;
1217                 }
1218         }
1219
1220         num_aliases = pdb_search_entries(info->disp_info->aliases,
1221                                          *r->in.resume_handle,
1222                                          MAX_SAM_ENTRIES, &aliases);
1223         unbecome_root();
1224
1225         /* Ensure we cache this enumeration. */
1226         set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1227
1228         make_group_sam_entry_list(p->mem_ctx, &samr_entries,
1229                                   num_aliases, aliases);
1230
1231         DEBUG(5,("_samr_EnumDomainAliases: %d\n", __LINE__));
1232
1233         samr_array->count = num_aliases;
1234         samr_array->entries = samr_entries;
1235
1236         *r->out.sam = samr_array;
1237         *r->out.num_entries = num_aliases;
1238         *r->out.resume_handle = num_aliases + *r->in.resume_handle;
1239
1240         return status;
1241 }
1242
1243 /*******************************************************************
1244  inits a samr_DispInfoGeneral structure.
1245 ********************************************************************/
1246
1247 static NTSTATUS init_samr_dispinfo_1(TALLOC_CTX *ctx,
1248                                      struct samr_DispInfoGeneral *r,
1249                                      uint32_t num_entries,
1250                                      uint32_t start_idx,
1251                                      struct samr_displayentry *entries)
1252 {
1253         uint32 i;
1254
1255         DEBUG(10, ("init_samr_dispinfo_1: num_entries: %d\n", num_entries));
1256
1257         if (num_entries == 0) {
1258                 return NT_STATUS_OK;
1259         }
1260
1261         r->count = num_entries;
1262
1263         r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryGeneral, num_entries);
1264         if (!r->entries) {
1265                 return NT_STATUS_NO_MEMORY;
1266         }
1267
1268         for (i = 0; i < num_entries ; i++) {
1269
1270                 init_lsa_String(&r->entries[i].account_name,
1271                                 entries[i].account_name);
1272
1273                 init_lsa_String(&r->entries[i].description,
1274                                 entries[i].description);
1275
1276                 init_lsa_String(&r->entries[i].full_name,
1277                                 entries[i].fullname);
1278
1279                 r->entries[i].rid = entries[i].rid;
1280                 r->entries[i].acct_flags = entries[i].acct_flags;
1281                 r->entries[i].idx = start_idx+i+1;
1282         }
1283
1284         return NT_STATUS_OK;
1285 }
1286
1287 /*******************************************************************
1288  inits a samr_DispInfoFull structure.
1289 ********************************************************************/
1290
1291 static NTSTATUS init_samr_dispinfo_2(TALLOC_CTX *ctx,
1292                                      struct samr_DispInfoFull *r,
1293                                      uint32_t num_entries,
1294                                      uint32_t start_idx,
1295                                      struct samr_displayentry *entries)
1296 {
1297         uint32_t i;
1298
1299         DEBUG(10, ("init_samr_dispinfo_2: num_entries: %d\n", num_entries));
1300
1301         if (num_entries == 0) {
1302                 return NT_STATUS_OK;
1303         }
1304
1305         r->count = num_entries;
1306
1307         r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryFull, num_entries);
1308         if (!r->entries) {
1309                 return NT_STATUS_NO_MEMORY;
1310         }
1311
1312         for (i = 0; i < num_entries ; i++) {
1313
1314                 init_lsa_String(&r->entries[i].account_name,
1315                                 entries[i].account_name);
1316
1317                 init_lsa_String(&r->entries[i].description,
1318                                 entries[i].description);
1319
1320                 r->entries[i].rid = entries[i].rid;
1321                 r->entries[i].acct_flags = entries[i].acct_flags;
1322                 r->entries[i].idx = start_idx+i+1;
1323         }
1324
1325         return NT_STATUS_OK;
1326 }
1327
1328 /*******************************************************************
1329  inits a samr_DispInfoFullGroups structure.
1330 ********************************************************************/
1331
1332 static NTSTATUS init_samr_dispinfo_3(TALLOC_CTX *ctx,
1333                                      struct samr_DispInfoFullGroups *r,
1334                                      uint32_t num_entries,
1335                                      uint32_t start_idx,
1336                                      struct samr_displayentry *entries)
1337 {
1338         uint32_t i;
1339
1340         DEBUG(5, ("init_samr_dispinfo_3: num_entries: %d\n", num_entries));
1341
1342         if (num_entries == 0) {
1343                 return NT_STATUS_OK;
1344         }
1345
1346         r->count = num_entries;
1347
1348         r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryFullGroup, num_entries);
1349         if (!r->entries) {
1350                 return NT_STATUS_NO_MEMORY;
1351         }
1352
1353         for (i = 0; i < num_entries ; i++) {
1354
1355                 init_lsa_String(&r->entries[i].account_name,
1356                                 entries[i].account_name);
1357
1358                 init_lsa_String(&r->entries[i].description,
1359                                 entries[i].description);
1360
1361                 r->entries[i].rid = entries[i].rid;
1362                 r->entries[i].acct_flags = entries[i].acct_flags;
1363                 r->entries[i].idx = start_idx+i+1;
1364         }
1365
1366         return NT_STATUS_OK;
1367 }
1368
1369 /*******************************************************************
1370  inits a samr_DispInfoAscii structure.
1371 ********************************************************************/
1372
1373 static NTSTATUS init_samr_dispinfo_4(TALLOC_CTX *ctx,
1374                                      struct samr_DispInfoAscii *r,
1375                                      uint32_t num_entries,
1376                                      uint32_t start_idx,
1377                                      struct samr_displayentry *entries)
1378 {
1379         uint32_t i;
1380
1381         DEBUG(5, ("init_samr_dispinfo_4: num_entries: %d\n", num_entries));
1382
1383         if (num_entries == 0) {
1384                 return NT_STATUS_OK;
1385         }
1386
1387         r->count = num_entries;
1388
1389         r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryAscii, num_entries);
1390         if (!r->entries) {
1391                 return NT_STATUS_NO_MEMORY;
1392         }
1393
1394         for (i = 0; i < num_entries ; i++) {
1395
1396                 init_lsa_AsciiStringLarge(&r->entries[i].account_name,
1397                                           entries[i].account_name);
1398
1399                 r->entries[i].idx = start_idx+i+1;
1400         }
1401
1402         return NT_STATUS_OK;
1403 }
1404
1405 /*******************************************************************
1406  inits a samr_DispInfoAscii structure.
1407 ********************************************************************/
1408
1409 static NTSTATUS init_samr_dispinfo_5(TALLOC_CTX *ctx,
1410                                      struct samr_DispInfoAscii *r,
1411                                      uint32_t num_entries,
1412                                      uint32_t start_idx,
1413                                      struct samr_displayentry *entries)
1414 {
1415         uint32_t i;
1416
1417         DEBUG(5, ("init_samr_dispinfo_5: num_entries: %d\n", num_entries));
1418
1419         if (num_entries == 0) {
1420                 return NT_STATUS_OK;
1421         }
1422
1423         r->count = num_entries;
1424
1425         r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryAscii, num_entries);
1426         if (!r->entries) {
1427                 return NT_STATUS_NO_MEMORY;
1428         }
1429
1430         for (i = 0; i < num_entries ; i++) {
1431
1432                 init_lsa_AsciiStringLarge(&r->entries[i].account_name,
1433                                           entries[i].account_name);
1434
1435                 r->entries[i].idx = start_idx+i+1;
1436         }
1437
1438         return NT_STATUS_OK;
1439 }
1440
1441 /*******************************************************************
1442  _samr_QueryDisplayInfo
1443  ********************************************************************/
1444
1445 NTSTATUS _samr_QueryDisplayInfo(pipes_struct *p,
1446                                 struct samr_QueryDisplayInfo *r)
1447 {
1448         NTSTATUS status;
1449         struct samr_info *info = NULL;
1450         uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
1451
1452         uint32 max_entries = r->in.max_entries;
1453         uint32 enum_context = r->in.start_idx;
1454         uint32 max_size = r->in.buf_size;
1455
1456         union samr_DispInfo *disp_info = r->out.info;
1457
1458         uint32 temp_size=0, total_data_size=0;
1459         NTSTATUS disp_ret = NT_STATUS_UNSUCCESSFUL;
1460         uint32 num_account = 0;
1461         enum remote_arch_types ra_type = get_remote_arch();
1462         int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
1463         struct samr_displayentry *entries = NULL;
1464
1465         DEBUG(5,("_samr_QueryDisplayInfo: %d\n", __LINE__));
1466
1467         /* find the policy handle.  open a policy on it. */
1468         if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
1469                 return NT_STATUS_INVALID_HANDLE;
1470
1471         if (info->builtin_domain) {
1472                 DEBUG(5,("_samr_QueryDisplayInfo: Nothing in BUILTIN\n"));
1473                 return NT_STATUS_OK;
1474         }
1475
1476         status = access_check_samr_function(info->acc_granted,
1477                                             SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
1478                                             "_samr_QueryDisplayInfo");
1479         if (!NT_STATUS_IS_OK(status)) {
1480                 return status;
1481         }
1482
1483         /*
1484          * calculate how many entries we will return.
1485          * based on
1486          * - the number of entries the client asked
1487          * - our limit on that
1488          * - the starting point (enumeration context)
1489          * - the buffer size the client will accept
1490          */
1491
1492         /*
1493          * We are a lot more like W2K. Instead of reading the SAM
1494          * each time to find the records we need to send back,
1495          * we read it once and link that copy to the sam handle.
1496          * For large user list (over the MAX_SAM_ENTRIES)
1497          * it's a definitive win.
1498          * second point to notice: between enumerations
1499          * our sam is now the same as it's a snapshoot.
1500          * third point: got rid of the static SAM_USER_21 struct
1501          * no more intermediate.
1502          * con: it uses much more memory, as a full copy is stored
1503          * in memory.
1504          *
1505          * If you want to change it, think twice and think
1506          * of the second point , that's really important.
1507          *
1508          * JFM, 12/20/2001
1509          */
1510
1511         if ((r->in.level < 1) || (r->in.level > 5)) {
1512                 DEBUG(0,("_samr_QueryDisplayInfo: Unknown info level (%u)\n",
1513                          (unsigned int)r->in.level ));
1514                 return NT_STATUS_INVALID_INFO_CLASS;
1515         }
1516
1517         /* first limit the number of entries we will return */
1518         if(max_entries > max_sam_entries) {
1519                 DEBUG(5, ("_samr_QueryDisplayInfo: client requested %d "
1520                           "entries, limiting to %d\n", max_entries,
1521                           max_sam_entries));
1522                 max_entries = max_sam_entries;
1523         }
1524
1525         /* calculate the size and limit on the number of entries we will
1526          * return */
1527
1528         temp_size=max_entries*struct_size;
1529
1530         if (temp_size>max_size) {
1531                 max_entries=MIN((max_size/struct_size),max_entries);;
1532                 DEBUG(5, ("_samr_QueryDisplayInfo: buffer size limits to "
1533                           "only %d entries\n", max_entries));
1534         }
1535
1536         become_root();
1537
1538         /* THe following done as ROOT. Don't return without unbecome_root(). */
1539
1540         switch (r->in.level) {
1541         case 0x1:
1542         case 0x4:
1543                 if (info->disp_info->users == NULL) {
1544                         info->disp_info->users = pdb_search_users(
1545                                 info->disp_info, ACB_NORMAL);
1546                         if (info->disp_info->users == NULL) {
1547                                 unbecome_root();
1548                                 return NT_STATUS_ACCESS_DENIED;
1549                         }
1550                         DEBUG(10,("_samr_QueryDisplayInfo: starting user enumeration at index %u\n",
1551                                 (unsigned  int)enum_context ));
1552                 } else {
1553                         DEBUG(10,("_samr_QueryDisplayInfo: using cached user enumeration at index %u\n",
1554                                 (unsigned  int)enum_context ));
1555                 }
1556
1557                 num_account = pdb_search_entries(info->disp_info->users,
1558                                                  enum_context, max_entries,
1559                                                  &entries);
1560                 break;
1561         case 0x2:
1562                 if (info->disp_info->machines == NULL) {
1563                         info->disp_info->machines = pdb_search_users(
1564                                 info->disp_info, ACB_WSTRUST|ACB_SVRTRUST);
1565                         if (info->disp_info->machines == NULL) {
1566                                 unbecome_root();
1567                                 return NT_STATUS_ACCESS_DENIED;
1568                         }
1569                         DEBUG(10,("_samr_QueryDisplayInfo: starting machine enumeration at index %u\n",
1570                                 (unsigned  int)enum_context ));
1571                 } else {
1572                         DEBUG(10,("_samr_QueryDisplayInfo: using cached machine enumeration at index %u\n",
1573                                 (unsigned  int)enum_context ));
1574                 }
1575
1576                 num_account = pdb_search_entries(info->disp_info->machines,
1577                                                  enum_context, max_entries,
1578                                                  &entries);
1579                 break;
1580         case 0x3:
1581         case 0x5:
1582                 if (info->disp_info->groups == NULL) {
1583                         info->disp_info->groups = pdb_search_groups(
1584                                 info->disp_info);
1585                         if (info->disp_info->groups == NULL) {
1586                                 unbecome_root();
1587                                 return NT_STATUS_ACCESS_DENIED;
1588                         }
1589                         DEBUG(10,("_samr_QueryDisplayInfo: starting group enumeration at index %u\n",
1590                                 (unsigned  int)enum_context ));
1591                 } else {
1592                         DEBUG(10,("_samr_QueryDisplayInfo: using cached group enumeration at index %u\n",
1593                                 (unsigned  int)enum_context ));
1594                 }
1595
1596                 num_account = pdb_search_entries(info->disp_info->groups,
1597                                                  enum_context, max_entries,
1598                                                  &entries);
1599                 break;
1600         default:
1601                 unbecome_root();
1602                 smb_panic("info class changed");
1603                 break;
1604         }
1605         unbecome_root();
1606
1607
1608         /* Now create reply structure */
1609         switch (r->in.level) {
1610         case 0x1:
1611                 disp_ret = init_samr_dispinfo_1(p->mem_ctx, &disp_info->info1,
1612                                                 num_account, enum_context,
1613                                                 entries);
1614                 break;
1615         case 0x2:
1616                 disp_ret = init_samr_dispinfo_2(p->mem_ctx, &disp_info->info2,
1617                                                 num_account, enum_context,
1618                                                 entries);
1619                 break;
1620         case 0x3:
1621                 disp_ret = init_samr_dispinfo_3(p->mem_ctx, &disp_info->info3,
1622                                                 num_account, enum_context,
1623                                                 entries);
1624                 break;
1625         case 0x4:
1626                 disp_ret = init_samr_dispinfo_4(p->mem_ctx, &disp_info->info4,
1627                                                 num_account, enum_context,
1628                                                 entries);
1629                 break;
1630         case 0x5:
1631                 disp_ret = init_samr_dispinfo_5(p->mem_ctx, &disp_info->info5,
1632                                                 num_account, enum_context,
1633                                                 entries);
1634                 break;
1635         default:
1636                 smb_panic("info class changed");
1637                 break;
1638         }
1639
1640         if (!NT_STATUS_IS_OK(disp_ret))
1641                 return disp_ret;
1642
1643         /* calculate the total size */
1644         total_data_size=num_account*struct_size;
1645
1646         if (max_entries <= num_account) {
1647                 status = STATUS_MORE_ENTRIES;
1648         } else {
1649                 status = NT_STATUS_OK;
1650         }
1651
1652         /* Ensure we cache this enumeration. */
1653         set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1654
1655         DEBUG(5, ("_samr_QueryDisplayInfo: %d\n", __LINE__));
1656
1657         *r->out.total_size = total_data_size;
1658         *r->out.returned_size = temp_size;
1659
1660         return status;
1661 }
1662
1663 /****************************************************************
1664  _samr_QueryDisplayInfo2
1665 ****************************************************************/
1666
1667 NTSTATUS _samr_QueryDisplayInfo2(pipes_struct *p,
1668                                  struct samr_QueryDisplayInfo2 *r)
1669 {
1670         struct samr_QueryDisplayInfo q;
1671
1672         q.in.domain_handle      = r->in.domain_handle;
1673         q.in.level              = r->in.level;
1674         q.in.start_idx          = r->in.start_idx;
1675         q.in.max_entries        = r->in.max_entries;
1676         q.in.buf_size           = r->in.buf_size;
1677
1678         q.out.total_size        = r->out.total_size;
1679         q.out.returned_size     = r->out.returned_size;
1680         q.out.info              = r->out.info;
1681
1682         return _samr_QueryDisplayInfo(p, &q);
1683 }
1684
1685 /****************************************************************
1686  _samr_QueryDisplayInfo3
1687 ****************************************************************/
1688
1689 NTSTATUS _samr_QueryDisplayInfo3(pipes_struct *p,
1690                                  struct samr_QueryDisplayInfo3 *r)
1691 {
1692         struct samr_QueryDisplayInfo q;
1693
1694         q.in.domain_handle      = r->in.domain_handle;
1695         q.in.level              = r->in.level;
1696         q.in.start_idx          = r->in.start_idx;
1697         q.in.max_entries        = r->in.max_entries;
1698         q.in.buf_size           = r->in.buf_size;
1699
1700         q.out.total_size        = r->out.total_size;
1701         q.out.returned_size     = r->out.returned_size;
1702         q.out.info              = r->out.info;
1703
1704         return _samr_QueryDisplayInfo(p, &q);
1705 }
1706
1707 /*******************************************************************
1708  _samr_QueryAliasInfo
1709  ********************************************************************/
1710
1711 NTSTATUS _samr_QueryAliasInfo(pipes_struct *p,
1712                               struct samr_QueryAliasInfo *r)
1713 {
1714         DOM_SID   sid;
1715         struct acct_info info;
1716         uint32    acc_granted;
1717         NTSTATUS status;
1718         union samr_AliasInfo *alias_info = NULL;
1719         const char *alias_name = NULL;
1720         const char *alias_description = NULL;
1721
1722         DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1723
1724         alias_info = TALLOC_ZERO_P(p->mem_ctx, union samr_AliasInfo);
1725         if (!alias_info) {
1726                 return NT_STATUS_NO_MEMORY;
1727         }
1728
1729         /* find the policy handle.  open a policy on it. */
1730         if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &sid, &acc_granted, NULL))
1731                 return NT_STATUS_INVALID_HANDLE;
1732
1733         status = access_check_samr_function(acc_granted,
1734                                             SAMR_ALIAS_ACCESS_LOOKUP_INFO,
1735                                             "_samr_QueryAliasInfo");
1736         if (!NT_STATUS_IS_OK(status)) {
1737                 return status;
1738         }
1739
1740         become_root();
1741         status = pdb_get_aliasinfo(&sid, &info);
1742         unbecome_root();
1743
1744         if ( !NT_STATUS_IS_OK(status))
1745                 return status;
1746
1747         /* FIXME: info contains fstrings */
1748         alias_name = talloc_strdup(r, info.acct_name);
1749         alias_description = talloc_strdup(r, info.acct_desc);
1750
1751         switch (r->in.level) {
1752         case ALIASINFOALL:
1753                 alias_info->all.name.string             = alias_name;
1754                 alias_info->all.num_members             = 1; /* ??? */
1755                 alias_info->all.description.string      = alias_description;
1756                 break;
1757         case ALIASINFODESCRIPTION:
1758                 alias_info->description.string          = alias_description;
1759                 break;
1760         default:
1761                 return NT_STATUS_INVALID_INFO_CLASS;
1762         }
1763
1764         *r->out.info = alias_info;
1765
1766         DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1767
1768         return NT_STATUS_OK;
1769 }
1770
1771 /*******************************************************************
1772  _samr_LookupNames
1773  ********************************************************************/
1774
1775 NTSTATUS _samr_LookupNames(pipes_struct *p,
1776                            struct samr_LookupNames *r)
1777 {
1778         NTSTATUS status;
1779         uint32 *rid;
1780         enum lsa_SidType *type;
1781         int i;
1782         int num_rids = r->in.num_names;
1783         DOM_SID pol_sid;
1784         uint32  acc_granted;
1785         struct samr_Ids rids, types;
1786         uint32_t num_mapped = 0;
1787
1788         DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1789
1790         if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &pol_sid, &acc_granted, NULL)) {
1791                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1792         }
1793
1794         status = access_check_samr_function(acc_granted,
1795                                             0, /* Don't know the acc_bits yet */
1796                                             "_samr_LookupNames");
1797         if (!NT_STATUS_IS_OK(status)) {
1798                 return status;
1799         }
1800
1801         if (num_rids > MAX_SAM_ENTRIES) {
1802                 num_rids = MAX_SAM_ENTRIES;
1803                 DEBUG(5,("_samr_LookupNames: truncating entries to %d\n", num_rids));
1804         }
1805
1806         rid = talloc_array(p->mem_ctx, uint32, num_rids);
1807         NT_STATUS_HAVE_NO_MEMORY(rid);
1808
1809         type = talloc_array(p->mem_ctx, enum lsa_SidType, num_rids);
1810         NT_STATUS_HAVE_NO_MEMORY(type);
1811
1812         DEBUG(5,("_samr_LookupNames: looking name on SID %s\n",
1813                  sid_string_dbg(&pol_sid)));
1814
1815         for (i = 0; i < num_rids; i++) {
1816
1817                 status = NT_STATUS_NONE_MAPPED;
1818                 type[i] = SID_NAME_UNKNOWN;
1819
1820                 rid[i] = 0xffffffff;
1821
1822                 if (sid_check_is_builtin(&pol_sid)) {
1823                         if (lookup_builtin_name(r->in.names[i].string,
1824                                                 &rid[i]))
1825                         {
1826                                 type[i] = SID_NAME_ALIAS;
1827                         }
1828                 } else {
1829                         lookup_global_sam_name(r->in.names[i].string, 0,
1830                                                &rid[i], &type[i]);
1831                 }
1832
1833                 if (type[i] != SID_NAME_UNKNOWN) {
1834                         num_mapped++;
1835                 }
1836         }
1837
1838         if (num_mapped == num_rids) {
1839                 status = NT_STATUS_OK;
1840         } else if (num_mapped == 0) {
1841                 status = NT_STATUS_NONE_MAPPED;
1842         } else {
1843                 status = STATUS_SOME_UNMAPPED;
1844         }
1845
1846         rids.count = num_rids;
1847         rids.ids = rid;
1848
1849         types.count = num_rids;
1850         types.ids = type;
1851
1852         *r->out.rids = rids;
1853         *r->out.types = types;
1854
1855         DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1856
1857         return status;
1858 }
1859
1860 /*******************************************************************
1861  _samr_ChangePasswordUser2
1862  ********************************************************************/
1863
1864 NTSTATUS _samr_ChangePasswordUser2(pipes_struct *p,
1865                                    struct samr_ChangePasswordUser2 *r)
1866 {
1867         NTSTATUS status;
1868         fstring user_name;
1869         fstring wks;
1870
1871         DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1872
1873         fstrcpy(user_name, r->in.account->string);
1874         fstrcpy(wks, r->in.server->string);
1875
1876         DEBUG(5,("_samr_ChangePasswordUser2: user: %s wks: %s\n", user_name, wks));
1877
1878         /*
1879          * Pass the user through the NT -> unix user mapping
1880          * function.
1881          */
1882
1883         (void)map_username(user_name);
1884
1885         /*
1886          * UNIX username case mangling not required, pass_oem_change
1887          * is case insensitive.
1888          */
1889
1890         status = pass_oem_change(user_name,
1891                                  r->in.lm_password->data,
1892                                  r->in.lm_verifier->hash,
1893                                  r->in.nt_password->data,
1894                                  r->in.nt_verifier->hash,
1895                                  NULL);
1896
1897         DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1898
1899         return status;
1900 }
1901
1902 /*******************************************************************
1903  _samr_ChangePasswordUser3
1904  ********************************************************************/
1905
1906 NTSTATUS _samr_ChangePasswordUser3(pipes_struct *p,
1907                                    struct samr_ChangePasswordUser3 *r)
1908 {
1909         NTSTATUS status;
1910         fstring user_name;
1911         const char *wks = NULL;
1912         uint32 reject_reason;
1913         struct samr_DomInfo1 *dominfo = NULL;
1914         struct samr_ChangeReject *reject = NULL;
1915         uint32_t tmp;
1916
1917         DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
1918
1919         fstrcpy(user_name, r->in.account->string);
1920         if (r->in.server && r->in.server->string) {
1921                 wks = r->in.server->string;
1922         }
1923
1924         DEBUG(5,("_samr_ChangePasswordUser3: user: %s wks: %s\n", user_name, wks));
1925
1926         /*
1927          * Pass the user through the NT -> unix user mapping
1928          * function.
1929          */
1930
1931         (void)map_username(user_name);
1932
1933         /*
1934          * UNIX username case mangling not required, pass_oem_change
1935          * is case insensitive.
1936          */
1937
1938         status = pass_oem_change(user_name,
1939                                  r->in.lm_password->data,
1940                                  r->in.lm_verifier->hash,
1941                                  r->in.nt_password->data,
1942                                  r->in.nt_verifier->hash,
1943                                  &reject_reason);
1944
1945         if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) ||
1946             NT_STATUS_EQUAL(status, NT_STATUS_ACCOUNT_RESTRICTION)) {
1947
1948                 time_t u_expire, u_min_age;
1949                 uint32 account_policy_temp;
1950
1951                 dominfo = TALLOC_ZERO_P(p->mem_ctx, struct samr_DomInfo1);
1952                 if (!dominfo) {
1953                         return NT_STATUS_NO_MEMORY;
1954                 }
1955
1956                 reject = TALLOC_ZERO_P(p->mem_ctx, struct samr_ChangeReject);
1957                 if (!reject) {
1958                         return NT_STATUS_NO_MEMORY;
1959                 }
1960
1961                 become_root();
1962
1963                 /* AS ROOT !!! */
1964
1965                 pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &tmp);
1966                 dominfo->min_password_length = tmp;
1967
1968                 pdb_get_account_policy(AP_PASSWORD_HISTORY, &tmp);
1969                 dominfo->password_history_length = tmp;
1970
1971                 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
1972                                        &dominfo->password_properties);
1973
1974                 pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
1975                 u_expire = account_policy_temp;
1976
1977                 pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
1978                 u_min_age = account_policy_temp;
1979
1980                 /* !AS ROOT */
1981
1982                 unbecome_root();
1983
1984                 unix_to_nt_time_abs((NTTIME *)&dominfo->max_password_age, u_expire);
1985                 unix_to_nt_time_abs((NTTIME *)&dominfo->min_password_age, u_min_age);
1986
1987                 if (lp_check_password_script() && *lp_check_password_script()) {
1988                         dominfo->password_properties |= DOMAIN_PASSWORD_COMPLEX;
1989                 }
1990
1991                 reject->reason = reject_reason;
1992
1993                 *r->out.dominfo = dominfo;
1994                 *r->out.reject = reject;
1995         }
1996
1997         DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
1998
1999         return status;
2000 }
2001
2002 /*******************************************************************
2003 makes a SAMR_R_LOOKUP_RIDS structure.
2004 ********************************************************************/
2005
2006 static bool make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names,
2007                                   const char **names,
2008                                   struct lsa_String **lsa_name_array_p)
2009 {
2010         struct lsa_String *lsa_name_array = NULL;
2011         uint32_t i;
2012
2013         *lsa_name_array_p = NULL;
2014
2015         if (num_names != 0) {
2016                 lsa_name_array = TALLOC_ZERO_ARRAY(ctx, struct lsa_String, num_names);
2017                 if (!lsa_name_array) {
2018                         return false;
2019                 }
2020         }
2021
2022         for (i = 0; i < num_names; i++) {
2023                 DEBUG(10, ("names[%d]:%s\n", i, names[i] && *names[i] ? names[i] : ""));
2024                 init_lsa_String(&lsa_name_array[i], names[i]);
2025         }
2026
2027         *lsa_name_array_p = lsa_name_array;
2028
2029         return true;
2030 }
2031
2032 /*******************************************************************
2033  _samr_LookupRids
2034  ********************************************************************/
2035
2036 NTSTATUS _samr_LookupRids(pipes_struct *p,
2037                           struct samr_LookupRids *r)
2038 {
2039         NTSTATUS status;
2040         const char **names;
2041         enum lsa_SidType *attrs = NULL;
2042         uint32 *wire_attrs = NULL;
2043         DOM_SID pol_sid;
2044         int num_rids = (int)r->in.num_rids;
2045         uint32 acc_granted;
2046         int i;
2047         struct lsa_Strings names_array;
2048         struct samr_Ids types_array;
2049         struct lsa_String *lsa_names = NULL;
2050
2051         DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2052
2053         /* find the policy handle.  open a policy on it. */
2054         if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &pol_sid, &acc_granted, NULL))
2055                 return NT_STATUS_INVALID_HANDLE;
2056
2057         status = access_check_samr_function(acc_granted,
2058                                             0, /* Don't know the acc_bits yet */
2059                                             "_samr_LookupRids");
2060         if (!NT_STATUS_IS_OK(status)) {
2061                 return status;
2062         }
2063
2064         if (num_rids > 1000) {
2065                 DEBUG(0, ("Got asked for %d rids (more than 1000) -- according "
2066                           "to samba4 idl this is not possible\n", num_rids));
2067                 return NT_STATUS_UNSUCCESSFUL;
2068         }
2069
2070         if (num_rids) {
2071                 names = TALLOC_ZERO_ARRAY(p->mem_ctx, const char *, num_rids);
2072                 attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, enum lsa_SidType, num_rids);
2073                 wire_attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_rids);
2074
2075                 if ((names == NULL) || (attrs == NULL) || (wire_attrs==NULL))
2076                         return NT_STATUS_NO_MEMORY;
2077         } else {
2078                 names = NULL;
2079                 attrs = NULL;
2080                 wire_attrs = NULL;
2081         }
2082
2083         become_root();  /* lookup_sid can require root privs */
2084         status = pdb_lookup_rids(&pol_sid, num_rids, r->in.rids,
2085                                  names, attrs);
2086         unbecome_root();
2087
2088         if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED) && (num_rids == 0)) {
2089                 status = NT_STATUS_OK;
2090         }
2091
2092         if (!make_samr_lookup_rids(p->mem_ctx, num_rids, names,
2093                                    &lsa_names)) {
2094                 return NT_STATUS_NO_MEMORY;
2095         }
2096
2097         /* Convert from enum lsa_SidType to uint32 for wire format. */
2098         for (i = 0; i < num_rids; i++) {
2099                 wire_attrs[i] = (uint32)attrs[i];
2100         }
2101
2102         names_array.count = num_rids;
2103         names_array.names = lsa_names;
2104
2105         types_array.count = num_rids;
2106         types_array.ids = wire_attrs;
2107
2108         *r->out.names = names_array;
2109         *r->out.types = types_array;
2110
2111         DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2112
2113         return status;
2114 }
2115
2116 /*******************************************************************
2117  _samr_OpenUser
2118 ********************************************************************/
2119
2120 NTSTATUS _samr_OpenUser(pipes_struct *p,
2121                         struct samr_OpenUser *r)
2122 {
2123         struct samu *sampass=NULL;
2124         DOM_SID sid;
2125         struct samr_info *info = NULL;
2126         SEC_DESC *psd = NULL;
2127         uint32    acc_granted;
2128         uint32    des_access = r->in.access_mask;
2129         size_t    sd_size;
2130         bool ret;
2131         NTSTATUS nt_status;
2132         SE_PRIV se_rights;
2133
2134         /* find the domain policy handle and get domain SID / access bits in the domain policy. */
2135
2136         if ( !get_lsa_policy_samr_sid(p, r->in.domain_handle, &sid, &acc_granted, NULL) )
2137                 return NT_STATUS_INVALID_HANDLE;
2138
2139         nt_status = access_check_samr_function(acc_granted,
2140                                                SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
2141                                                "_samr_OpenUser" );
2142
2143         if ( !NT_STATUS_IS_OK(nt_status) )
2144                 return nt_status;
2145
2146         if ( !(sampass = samu_new( p->mem_ctx )) ) {
2147                 return NT_STATUS_NO_MEMORY;
2148         }
2149
2150         /* append the user's RID to it */
2151
2152         if (!sid_append_rid(&sid, r->in.rid))
2153                 return NT_STATUS_NO_SUCH_USER;
2154
2155         /* check if access can be granted as requested by client. */
2156
2157         map_max_allowed_access(p->server_info->ptok, &des_access);
2158
2159         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &sid, SAMR_USR_RIGHTS_WRITE_PW);
2160         se_map_generic(&des_access, &usr_generic_mapping);
2161
2162         se_priv_copy( &se_rights, &se_machine_account );
2163         se_priv_add( &se_rights, &se_add_users );
2164
2165         nt_status = access_check_samr_object(psd, p->server_info->ptok,
2166                 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
2167                 &acc_granted, "_samr_OpenUser");
2168
2169         if ( !NT_STATUS_IS_OK(nt_status) )
2170                 return nt_status;
2171
2172         become_root();
2173         ret=pdb_getsampwsid(sampass, &sid);
2174         unbecome_root();
2175
2176         /* check that the SID exists in our domain. */
2177         if (ret == False) {
2178                 return NT_STATUS_NO_SUCH_USER;
2179         }
2180
2181         TALLOC_FREE(sampass);
2182
2183         /* associate the user's SID and access bits with the new handle. */
2184         if ((info = get_samr_info_by_sid(p->mem_ctx, &sid)) == NULL)
2185                 return NT_STATUS_NO_MEMORY;
2186         info->acc_granted = acc_granted;
2187
2188         /* get a (unique) handle.  open a policy on it. */
2189         if (!create_policy_hnd(p, r->out.user_handle, info))
2190                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2191
2192         return NT_STATUS_OK;
2193 }
2194
2195 /*************************************************************************
2196  *************************************************************************/
2197
2198 static NTSTATUS init_samr_parameters_string(TALLOC_CTX *mem_ctx,
2199                                             DATA_BLOB *blob,
2200                                             struct lsa_BinaryString **_r)
2201 {
2202         struct lsa_BinaryString *r;
2203
2204         if (!blob || !_r) {
2205                 return NT_STATUS_INVALID_PARAMETER;
2206         }
2207
2208         r = TALLOC_ZERO_P(mem_ctx, struct lsa_BinaryString);
2209         if (!r) {
2210                 return NT_STATUS_NO_MEMORY;
2211         }
2212
2213         r->array = TALLOC_ZERO_ARRAY(mem_ctx, uint16_t, blob->length/2);
2214         if (!r->array) {
2215                 return NT_STATUS_NO_MEMORY;
2216         }
2217         memcpy(r->array, blob->data, blob->length);
2218         r->size = blob->length;
2219         r->length = blob->length;
2220
2221         if (!r->array) {
2222                 return NT_STATUS_NO_MEMORY;
2223         }
2224
2225         *_r = r;
2226
2227         return NT_STATUS_OK;
2228 }
2229
2230 static NTSTATUS get_user_info_5(TALLOC_CTX *mem_ctx,
2231                                 struct samr_UserInfo5 *r,
2232                                 struct samu *pw,
2233                                 DOM_SID *domain_sid)
2234 {
2235         const DOM_SID *sid_user, *sid_group;
2236         uint32_t rid, primary_gid;
2237
2238         sid_user = pdb_get_user_sid(pw);
2239
2240         if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2241                 DEBUG(0, ("get_user_info_5: User %s has SID %s, \nwhich conflicts with "
2242                           "the domain sid %s.  Failing operation.\n",
2243                           pdb_get_username(pw), sid_string_dbg(sid_user),
2244                           sid_string_dbg(domain_sid)));
2245                 return NT_STATUS_UNSUCCESSFUL;
2246         }
2247
2248         become_root();
2249         sid_group = pdb_get_group_sid(pw);
2250         unbecome_root();
2251
2252         if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2253                 DEBUG(0, ("get_user_info_5: User %s has Primary Group SID %s, \n"
2254                           "which conflicts with the domain sid %s.  Failing operation.\n",
2255                           pdb_get_username(pw), sid_string_dbg(sid_group),
2256                           sid_string_dbg(domain_sid)));
2257                 return NT_STATUS_UNSUCCESSFUL;
2258         }
2259
2260         unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2261         unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2262         unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2263         unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2264
2265         r->account_name.string  = talloc_strdup(mem_ctx, pdb_get_username(pw));
2266         r->full_name.string     = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2267         r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2268         r->home_drive.string    = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2269         r->logon_script.string  = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2270         r->profile_path.string  = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2271         r->description.string   = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2272         r->workstations.string  = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2273
2274         r->logon_hours          = get_logon_hours_from_pdb(mem_ctx, pw);
2275         r->rid                  = rid;
2276         r->primary_gid          = primary_gid;
2277         r->acct_flags           = pdb_get_acct_ctrl(pw);
2278         r->bad_password_count   = pdb_get_bad_password_count(pw);
2279         r->logon_count          = pdb_get_logon_count(pw);
2280
2281         return NT_STATUS_OK;
2282 }
2283
2284 /*************************************************************************
2285  get_user_info_7. Safe. Only gives out account_name.
2286  *************************************************************************/
2287
2288 static NTSTATUS get_user_info_7(TALLOC_CTX *mem_ctx,
2289                                 struct samr_UserInfo7 *r,
2290                                 struct samu *smbpass)
2291 {
2292         r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(smbpass));
2293         if (!r->account_name.string) {
2294                 return NT_STATUS_NO_MEMORY;
2295         }
2296
2297         return NT_STATUS_OK;
2298 }
2299
2300 /*************************************************************************
2301  get_user_info_9. Only gives out primary group SID.
2302  *************************************************************************/
2303
2304 static NTSTATUS get_user_info_9(TALLOC_CTX *mem_ctx,
2305                                 struct samr_UserInfo9 *r,
2306                                 struct samu *smbpass)
2307 {
2308         r->primary_gid = pdb_get_group_rid(smbpass);
2309
2310         return NT_STATUS_OK;
2311 }
2312
2313 /*************************************************************************
2314  get_user_info_16. Safe. Only gives out acb bits.
2315  *************************************************************************/
2316
2317 static NTSTATUS get_user_info_16(TALLOC_CTX *mem_ctx,
2318                                  struct samr_UserInfo16 *r,
2319                                  struct samu *smbpass)
2320 {
2321         r->acct_flags = pdb_get_acct_ctrl(smbpass);
2322
2323         return NT_STATUS_OK;
2324 }
2325
2326 /*************************************************************************
2327  get_user_info_18. OK - this is the killer as it gives out password info.
2328  Ensure that this is only allowed on an encrypted connection with a root
2329  user. JRA.
2330  *************************************************************************/
2331
2332 static NTSTATUS get_user_info_18(pipes_struct *p,
2333                                  TALLOC_CTX *mem_ctx,
2334                                  struct samr_UserInfo18 *r,
2335                                  DOM_SID *user_sid)
2336 {
2337         struct samu *smbpass=NULL;
2338         bool ret;
2339
2340         ZERO_STRUCTP(r);
2341
2342         if (p->auth.auth_type != PIPE_AUTH_TYPE_NTLMSSP || p->auth.auth_type != PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) {
2343                 return NT_STATUS_ACCESS_DENIED;
2344         }
2345
2346         if (p->auth.auth_level != PIPE_AUTH_LEVEL_PRIVACY) {
2347                 return NT_STATUS_ACCESS_DENIED;
2348         }
2349
2350         /*
2351          * Do *NOT* do become_root()/unbecome_root() here ! JRA.
2352          */
2353
2354         if ( !(smbpass = samu_new( mem_ctx )) ) {
2355                 return NT_STATUS_NO_MEMORY;
2356         }
2357
2358         ret = pdb_getsampwsid(smbpass, user_sid);
2359
2360         if (ret == False) {
2361                 DEBUG(4, ("User %s not found\n", sid_string_dbg(user_sid)));
2362                 TALLOC_FREE(smbpass);
2363                 return (geteuid() == (uid_t)0) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
2364         }
2365
2366         DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
2367
2368         if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
2369                 TALLOC_FREE(smbpass);
2370                 return NT_STATUS_ACCOUNT_DISABLED;
2371         }
2372
2373         r->lm_pwd_active = true;
2374         r->nt_pwd_active = true;
2375         memcpy(r->lm_pwd.hash, pdb_get_lanman_passwd(smbpass), 16);
2376         memcpy(r->nt_pwd.hash, pdb_get_nt_passwd(smbpass), 16);
2377         r->password_expired = 0; /* FIXME */
2378
2379         TALLOC_FREE(smbpass);
2380
2381         return NT_STATUS_OK;
2382 }
2383
2384 /*************************************************************************
2385  get_user_info_20
2386  *************************************************************************/
2387
2388 static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx,
2389                                  struct samr_UserInfo20 *r,
2390                                  struct samu *sampass)
2391 {
2392         const char *munged_dial = NULL;
2393         DATA_BLOB blob;
2394         NTSTATUS status;
2395         struct lsa_BinaryString *parameters = NULL;
2396
2397         ZERO_STRUCTP(r);
2398
2399         munged_dial = pdb_get_munged_dial(sampass);
2400
2401         DEBUG(3,("User:[%s] has [%s] (length: %d)\n", pdb_get_username(sampass),
2402                 munged_dial, (int)strlen(munged_dial)));
2403
2404         if (munged_dial) {
2405                 blob = base64_decode_data_blob(munged_dial);
2406         } else {
2407                 blob = data_blob_string_const_null("");
2408         }
2409
2410         status = init_samr_parameters_string(mem_ctx, &blob, &parameters);
2411         data_blob_free(&blob);
2412         if (!NT_STATUS_IS_OK(status)) {
2413                 return status;
2414         }
2415
2416         r->parameters = *parameters;
2417
2418         return NT_STATUS_OK;
2419 }
2420
2421
2422 /*************************************************************************
2423  get_user_info_21
2424  *************************************************************************/
2425
2426 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx,
2427                                  struct samr_UserInfo21 *r,
2428                                  struct samu *pw,
2429                                  DOM_SID *domain_sid)
2430 {
2431         NTSTATUS status;
2432         const DOM_SID *sid_user, *sid_group;
2433         uint32_t rid, primary_gid;
2434         NTTIME force_password_change;
2435         time_t must_change_time;
2436         struct lsa_BinaryString *parameters = NULL;
2437         const char *munged_dial = NULL;
2438         DATA_BLOB blob;
2439
2440         ZERO_STRUCTP(r);
2441
2442         sid_user = pdb_get_user_sid(pw);
2443
2444         if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2445                 DEBUG(0, ("get_user_info_21: User %s has SID %s, \nwhich conflicts with "
2446                           "the domain sid %s.  Failing operation.\n",
2447                           pdb_get_username(pw), sid_string_dbg(sid_user),
2448                           sid_string_dbg(domain_sid)));
2449                 return NT_STATUS_UNSUCCESSFUL;
2450         }
2451
2452         become_root();
2453         sid_group = pdb_get_group_sid(pw);
2454         unbecome_root();
2455
2456         if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2457                 DEBUG(0, ("get_user_info_21: User %s has Primary Group SID %s, \n"
2458                           "which conflicts with the domain sid %s.  Failing operation.\n",
2459                           pdb_get_username(pw), sid_string_dbg(sid_group),
2460                           sid_string_dbg(domain_sid)));
2461                 return NT_STATUS_UNSUCCESSFUL;
2462         }
2463
2464         unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2465         unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2466         unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2467         unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2468         unix_to_nt_time(&r->allow_password_change, pdb_get_pass_can_change_time(pw));
2469
2470         must_change_time = pdb_get_pass_must_change_time(pw);
2471         if (must_change_time == get_time_t_max()) {
2472                 unix_to_nt_time_abs(&force_password_change, must_change_time);
2473         } else {
2474                 unix_to_nt_time(&force_password_change, must_change_time);
2475         }
2476
2477         munged_dial = pdb_get_munged_dial(pw);
2478         if (munged_dial) {
2479                 blob = base64_decode_data_blob(munged_dial);
2480         } else {
2481                 blob = data_blob_string_const_null("");
2482         }
2483
2484         status = init_samr_parameters_string(mem_ctx, &blob, &parameters);
2485         data_blob_free(&blob);
2486         if (!NT_STATUS_IS_OK(status)) {
2487                 return status;
2488         }
2489
2490         r->force_password_change        = force_password_change;
2491
2492         r->account_name.string          = talloc_strdup(mem_ctx, pdb_get_username(pw));
2493         r->full_name.string             = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2494         r->home_directory.string        = talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2495         r->home_drive.string            = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2496         r->logon_script.string          = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2497         r->profile_path.string          = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2498         r->description.string           = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2499         r->workstations.string          = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2500         r->comment.string               = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2501
2502         r->logon_hours                  = get_logon_hours_from_pdb(mem_ctx, pw);
2503         r->parameters                   = *parameters;
2504         r->rid                          = rid;
2505         r->primary_gid                  = primary_gid;
2506         r->acct_flags                   = pdb_get_acct_ctrl(pw);
2507         r->bad_password_count           = pdb_get_bad_password_count(pw);
2508         r->logon_count                  = pdb_get_logon_count(pw);
2509         r->fields_present               = pdb_build_fields_present(pw);
2510         r->password_expired             = (pdb_get_pass_must_change_time(pw) == 0) ?
2511                                                 PASS_MUST_CHANGE_AT_NEXT_LOGON : 0;
2512         r->country_code                 = 0;
2513         r->code_page                    = 0;
2514         r->lm_password_set              = 0;
2515         r->nt_password_set              = 0;
2516
2517 #if 0
2518
2519         /*
2520           Look at a user on a real NT4 PDC with usrmgr, press
2521           'ok'. Then you will see that fields_present is set to
2522           0x08f827fa. Look at the user immediately after that again,
2523           and you will see that 0x00fffff is returned. This solves
2524           the problem that you get access denied after having looked
2525           at the user.
2526           -- Volker
2527         */
2528
2529 #endif
2530
2531
2532         return NT_STATUS_OK;
2533 }
2534
2535 /*******************************************************************
2536  _samr_QueryUserInfo
2537  ********************************************************************/
2538
2539 NTSTATUS _samr_QueryUserInfo(pipes_struct *p,
2540                              struct samr_QueryUserInfo *r)
2541 {
2542         NTSTATUS status;
2543         union samr_UserInfo *user_info = NULL;
2544         struct samr_info *info = NULL;
2545         DOM_SID domain_sid;
2546         uint32 rid;
2547         bool ret = false;
2548         struct samu *pwd = NULL;
2549
2550         /* search for the handle */
2551         if (!find_policy_by_hnd(p, r->in.user_handle, (void **)(void *)&info))
2552                 return NT_STATUS_INVALID_HANDLE;
2553
2554         status = access_check_samr_function(info->acc_granted,
2555                                             SAMR_USER_ACCESS_GET_ATTRIBUTES,
2556                                             "_samr_QueryUserInfo");
2557         if (!NT_STATUS_IS_OK(status)) {
2558                 return status;
2559         }
2560
2561         domain_sid = info->sid;
2562
2563         sid_split_rid(&domain_sid, &rid);
2564
2565         if (!sid_check_is_in_our_domain(&info->sid))
2566                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2567
2568         DEBUG(5,("_samr_QueryUserInfo: sid:%s\n",
2569                  sid_string_dbg(&info->sid)));
2570
2571         user_info = TALLOC_ZERO_P(p->mem_ctx, union samr_UserInfo);
2572         if (!user_info) {
2573                 return NT_STATUS_NO_MEMORY;
2574         }
2575
2576         DEBUG(5,("_samr_QueryUserInfo: user info level: %d\n", r->in.level));
2577
2578         if (!(pwd = samu_new(p->mem_ctx))) {
2579                 return NT_STATUS_NO_MEMORY;
2580         }
2581
2582         become_root();
2583         ret = pdb_getsampwsid(pwd, &info->sid);
2584         unbecome_root();
2585
2586         if (ret == false) {
2587                 DEBUG(4,("User %s not found\n", sid_string_dbg(&info->sid)));
2588                 TALLOC_FREE(pwd);
2589                 return NT_STATUS_NO_SUCH_USER;
2590         }
2591
2592         DEBUG(3,("User:[%s]\n", pdb_get_username(pwd)));
2593
2594         samr_clear_sam_passwd(pwd);
2595
2596         switch (r->in.level) {
2597         case 5:
2598                 status = get_user_info_5(p->mem_ctx, &user_info->info5, pwd, &domain_sid);
2599                 break;
2600         case 7:
2601                 status = get_user_info_7(p->mem_ctx, &user_info->info7, pwd);
2602                 break;
2603         case 9:
2604                 status = get_user_info_9(p->mem_ctx, &user_info->info9, pwd);
2605                 break;
2606         case 16:
2607                 status = get_user_info_16(p->mem_ctx, &user_info->info16, pwd);
2608                 break;
2609         case 18:
2610                 /* level 18 is special */
2611                 status = get_user_info_18(p, p->mem_ctx, &user_info->info18, &info->sid);
2612                 break;
2613         case 20:
2614                 status = get_user_info_20(p->mem_ctx, &user_info->info20, pwd);
2615                 break;
2616         case 21:
2617                 status = get_user_info_21(p->mem_ctx, &user_info->info21, pwd, &domain_sid);
2618                 break;
2619         default:
2620                 status = NT_STATUS_INVALID_INFO_CLASS;
2621                 break;
2622         }
2623
2624         TALLOC_FREE(pwd);
2625
2626         *r->out.info = user_info;
2627
2628         DEBUG(5,("_samr_QueryUserInfo: %d\n", __LINE__));
2629
2630         return status;
2631 }
2632
2633 /****************************************************************
2634 ****************************************************************/
2635
2636 NTSTATUS _samr_QueryUserInfo2(pipes_struct *p,
2637                               struct samr_QueryUserInfo2 *r)
2638 {
2639         struct samr_QueryUserInfo u;
2640
2641         u.in.user_handle        = r->in.user_handle;
2642         u.in.level              = r->in.level;
2643         u.out.info              = r->out.info;
2644
2645         return _samr_QueryUserInfo(p, &u);
2646 }
2647
2648 /*******************************************************************
2649  _samr_GetGroupsForUser
2650  ********************************************************************/
2651
2652 NTSTATUS _samr_GetGroupsForUser(pipes_struct *p,
2653                                 struct samr_GetGroupsForUser *r)
2654 {
2655         struct samu *sam_pass=NULL;
2656         DOM_SID  sid;
2657         DOM_SID *sids;
2658         struct samr_RidWithAttribute dom_gid;
2659         struct samr_RidWithAttribute *gids = NULL;
2660         uint32 primary_group_rid;
2661         size_t num_groups = 0;
2662         gid_t *unix_gids;
2663         size_t i, num_gids;
2664         uint32 acc_granted;
2665         bool ret;
2666         NTSTATUS result;
2667         bool success = False;
2668
2669         struct samr_RidWithAttributeArray *rids = NULL;
2670
2671         /*
2672          * from the SID in the request:
2673          * we should send back the list of DOMAIN GROUPS
2674          * the user is a member of
2675          *
2676          * and only the DOMAIN GROUPS
2677          * no ALIASES !!! neither aliases of the domain
2678          * nor aliases of the builtin SID
2679          *
2680          * JFM, 12/2/2001
2681          */
2682
2683         DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
2684
2685         rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidWithAttributeArray);
2686         if (!rids) {
2687                 return NT_STATUS_NO_MEMORY;
2688         }
2689
2690         /* find the policy handle.  open a policy on it. */
2691         if (!get_lsa_policy_samr_sid(p, r->in.user_handle, &sid, &acc_granted, NULL))
2692                 return NT_STATUS_INVALID_HANDLE;
2693
2694         result = access_check_samr_function(acc_granted,
2695                                             SAMR_USER_ACCESS_GET_GROUPS,
2696                                             "_samr_GetGroupsForUser");
2697         if (!NT_STATUS_IS_OK(result)) {
2698                 return result;
2699         }
2700
2701         if (!sid_check_is_in_our_domain(&sid))
2702                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2703
2704         if ( !(sam_pass = samu_new( p->mem_ctx )) ) {
2705                 return NT_STATUS_NO_MEMORY;
2706         }
2707
2708         become_root();
2709         ret = pdb_getsampwsid(sam_pass, &sid);
2710         unbecome_root();
2711
2712         if (!ret) {
2713                 DEBUG(10, ("pdb_getsampwsid failed for %s\n",
2714                            sid_string_dbg(&sid)));
2715                 return NT_STATUS_NO_SUCH_USER;
2716         }
2717
2718         sids = NULL;
2719
2720         /* make both calls inside the root block */
2721         become_root();
2722         result = pdb_enum_group_memberships(p->mem_ctx, sam_pass,
2723                                             &sids, &unix_gids, &num_groups);
2724         if ( NT_STATUS_IS_OK(result) ) {
2725                 success = sid_peek_check_rid(get_global_sam_sid(),
2726                                              pdb_get_group_sid(sam_pass),
2727                                              &primary_group_rid);
2728         }
2729         unbecome_root();
2730
2731         if (!NT_STATUS_IS_OK(result)) {
2732                 DEBUG(10, ("pdb_enum_group_memberships failed for %s\n",
2733                            sid_string_dbg(&sid)));
2734                 return result;
2735         }
2736
2737         if ( !success ) {
2738                 DEBUG(5, ("Group sid %s for user %s not in our domain\n",
2739                           sid_string_dbg(pdb_get_group_sid(sam_pass)),
2740                           pdb_get_username(sam_pass)));
2741                 TALLOC_FREE(sam_pass);
2742                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2743         }
2744
2745         gids = NULL;
2746         num_gids = 0;
2747
2748         dom_gid.attributes = (SE_GROUP_MANDATORY|SE_GROUP_ENABLED_BY_DEFAULT|
2749                               SE_GROUP_ENABLED);
2750         dom_gid.rid = primary_group_rid;
2751         ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
2752
2753         for (i=0; i<num_groups; i++) {
2754
2755                 if (!sid_peek_check_rid(get_global_sam_sid(),
2756                                         &(sids[i]), &dom_gid.rid)) {
2757                         DEBUG(10, ("Found sid %s not in our domain\n",
2758                                    sid_string_dbg(&sids[i])));
2759                         continue;
2760                 }
2761
2762                 if (dom_gid.rid == primary_group_rid) {
2763                         /* We added the primary group directly from the
2764                          * sam_account. The other SIDs are unique from
2765                          * enum_group_memberships */
2766                         continue;
2767                 }
2768
2769                 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
2770         }
2771
2772         rids->count = num_gids;
2773         rids->rids = gids;
2774
2775         *r->out.rids = rids;
2776
2777         DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
2778
2779         return result;
2780 }
2781
2782 /*******************************************************************
2783  _samr_QueryDomainInfo
2784  ********************************************************************/
2785
2786 NTSTATUS _samr_QueryDomainInfo(pipes_struct *p,
2787                                struct samr_QueryDomainInfo *r)
2788 {
2789         NTSTATUS status = NT_STATUS_OK;
2790         struct samr_info *info = NULL;
2791         union samr_DomainInfo *dom_info;
2792         time_t u_expire, u_min_age;
2793
2794         time_t u_lock_duration, u_reset_time;
2795         uint32_t u_logout;
2796
2797         uint32 account_policy_temp;
2798
2799         time_t seq_num;
2800         uint32 server_role;
2801
2802         DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__));
2803
2804         dom_info = TALLOC_ZERO_P(p->mem_ctx, union samr_DomainInfo);
2805         if (!dom_info) {
2806                 return NT_STATUS_NO_MEMORY;
2807         }
2808
2809         /* find the policy handle.  open a policy on it. */
2810         if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info)) {
2811                 return NT_STATUS_INVALID_HANDLE;
2812         }
2813
2814         status = access_check_samr_function(info->acc_granted,
2815                                             SAMR_ACCESS_OPEN_DOMAIN,
2816                                             "_samr_QueryDomainInfo" );
2817
2818         if ( !NT_STATUS_IS_OK(status) )
2819                 return status;
2820
2821         switch (r->in.level) {
2822                 case 0x01:
2823
2824                         become_root();
2825
2826                         /* AS ROOT !!! */
2827
2828                         pdb_get_account_policy(AP_MIN_PASSWORD_LEN,
2829                                                &account_policy_temp);
2830                         dom_info->info1.min_password_length = account_policy_temp;
2831
2832                         pdb_get_account_policy(AP_PASSWORD_HISTORY, &account_policy_temp);
2833                         dom_info->info1.password_history_length = account_policy_temp;
2834
2835                         pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
2836                                 &dom_info->info1.password_properties);
2837
2838                         pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
2839                         u_expire = account_policy_temp;
2840
2841                         pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
2842                         u_min_age = account_policy_temp;
2843
2844                         /* !AS ROOT */
2845
2846                         unbecome_root();
2847
2848                         unix_to_nt_time_abs((NTTIME *)&dom_info->info1.max_password_age, u_expire);
2849                         unix_to_nt_time_abs((NTTIME *)&dom_info->info1.min_password_age, u_min_age);
2850
2851                         if (lp_check_password_script() && *lp_check_password_script()) {
2852                                 dom_info->info1.password_properties |= DOMAIN_PASSWORD_COMPLEX;
2853                         }
2854
2855                         break;
2856                 case 0x02:
2857
2858                         become_root();
2859
2860                         /* AS ROOT !!! */
2861
2862                         dom_info->general.num_users     = count_sam_users(info->disp_info, ACB_NORMAL);
2863                         dom_info->general.num_groups    = count_sam_groups(info->disp_info);
2864                         dom_info->general.num_aliases   = count_sam_aliases(info->disp_info);
2865
2866                         pdb_get_account_policy(AP_TIME_TO_LOGOUT, &u_logout);
2867
2868                         unix_to_nt_time_abs(&dom_info->general.force_logoff_time, u_logout);
2869
2870                         if (!pdb_get_seq_num(&seq_num))
2871                                 seq_num = time(NULL);
2872
2873                         /* !AS ROOT */
2874
2875                         unbecome_root();
2876
2877                         server_role = ROLE_DOMAIN_PDC;
2878                         if (lp_server_role() == ROLE_DOMAIN_BDC)
2879                                 server_role = ROLE_DOMAIN_BDC;
2880
2881                         dom_info->general.oem_information.string        = lp_serverstring();
2882                         dom_info->general.domain_name.string            = lp_workgroup();
2883                         dom_info->general.primary.string                = global_myname();
2884                         dom_info->general.sequence_num                  = seq_num;
2885                         dom_info->general.domain_server_state           = DOMAIN_SERVER_ENABLED;
2886                         dom_info->general.role                          = server_role;
2887                         dom_info->general.unknown3                      = 1;
2888
2889                         break;
2890                 case 0x03:
2891
2892                         become_root();
2893
2894                         /* AS ROOT !!! */
2895
2896                         {
2897                                 uint32 ul;
2898                                 pdb_get_account_policy(AP_TIME_TO_LOGOUT, &ul);
2899                                 u_logout = (time_t)ul;
2900                         }
2901
2902                         /* !AS ROOT */
2903
2904                         unbecome_root();
2905
2906                         unix_to_nt_time_abs(&dom_info->info3.force_logoff_time, u_logout);
2907
2908                         break;
2909                 case 0x04:
2910                         dom_info->oem.oem_information.string = lp_serverstring();
2911                         break;
2912                 case 0x05:
2913                         dom_info->info5.domain_name.string = get_global_sam_name();
2914                         break;
2915                 case 0x06:
2916                         /* NT returns its own name when a PDC. win2k and later
2917                          * only the name of the PDC if itself is a BDC (samba4
2918                          * idl) */
2919                         dom_info->info6.primary.string = global_myname();
2920                         break;
2921                 case 0x07:
2922                         server_role = ROLE_DOMAIN_PDC;
2923                         if (lp_server_role() == ROLE_DOMAIN_BDC)
2924                                 server_role = ROLE_DOMAIN_BDC;
2925
2926                         dom_info->info7.role = server_role;
2927                         break;
2928                 case 0x08:
2929
2930                         become_root();
2931
2932                         /* AS ROOT !!! */
2933
2934                         if (!pdb_get_seq_num(&seq_num)) {
2935                                 seq_num = time(NULL);
2936                         }
2937
2938                         /* !AS ROOT */
2939
2940                         unbecome_root();
2941
2942                         dom_info->info8.sequence_num = seq_num;
2943                         dom_info->info8.domain_create_time = 0;
2944
2945                         break;
2946                 case 0x0c:
2947
2948                         become_root();
2949
2950                         /* AS ROOT !!! */
2951
2952                         pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
2953                         u_lock_duration = account_policy_temp;
2954                         if (u_lock_duration != -1) {
2955                                 u_lock_duration *= 60;
2956                         }
2957
2958                         pdb_get_account_policy(AP_RESET_COUNT_TIME, &account_policy_temp);
2959                         u_reset_time = account_policy_temp * 60;
2960
2961                         pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT,
2962                                                &account_policy_temp);
2963                         dom_info->info12.lockout_threshold = account_policy_temp;
2964
2965                         /* !AS ROOT */
2966
2967                         unbecome_root();
2968
2969                         unix_to_nt_time_abs(&dom_info->info12.lockout_duration,
2970                                             u_lock_duration);
2971                         unix_to_nt_time_abs(&dom_info->info12.lockout_window,
2972                                             u_reset_time);
2973
2974                         break;
2975                 default:
2976                         return NT_STATUS_INVALID_INFO_CLASS;
2977         }
2978
2979         *r->out.info = dom_info;
2980
2981         DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__));
2982
2983         return status;
2984 }
2985
2986 /* W2k3 seems to use the same check for all 3 objects that can be created via
2987  * SAMR, if you try to create for example "Dialup" as an alias it says
2988  * "NT_STATUS_USER_EXISTS". This is racy, but we can't really lock the user
2989  * database. */
2990
2991 static NTSTATUS can_create(TALLOC_CTX *mem_ctx, const char *new_name)
2992 {
2993         enum lsa_SidType type;
2994         bool result;
2995
2996         DEBUG(10, ("Checking whether [%s] can be created\n", new_name));
2997
2998         become_root();
2999         /* Lookup in our local databases (LOOKUP_NAME_REMOTE not set)
3000          * whether the name already exists */
3001         result = lookup_name(mem_ctx, new_name, LOOKUP_NAME_LOCAL,
3002                              NULL, NULL, NULL, &type);
3003         unbecome_root();
3004
3005         if (!result) {
3006                 DEBUG(10, ("%s does not exist, can create it\n", new_name));
3007                 return NT_STATUS_OK;
3008         }
3009
3010         DEBUG(5, ("trying to create %s, exists as %s\n",
3011                   new_name, sid_type_lookup(type)));
3012
3013         if (type == SID_NAME_DOM_GRP) {
3014                 return NT_STATUS_GROUP_EXISTS;
3015         }
3016         if (type == SID_NAME_ALIAS) {
3017                 return NT_STATUS_ALIAS_EXISTS;
3018         }
3019
3020         /* Yes, the default is NT_STATUS_USER_EXISTS */
3021         return NT_STATUS_USER_EXISTS;
3022 }
3023
3024 /*******************************************************************
3025  _samr_CreateUser2
3026  ********************************************************************/
3027
3028 NTSTATUS _samr_CreateUser2(pipes_struct *p,
3029                            struct samr_CreateUser2 *r)
3030 {
3031         const char *account = NULL;
3032         DOM_SID sid;
3033         uint32_t acb_info = r->in.acct_flags;
3034         struct samr_info *info = NULL;
3035         NTSTATUS nt_status;
3036         uint32 acc_granted;
3037         SEC_DESC *psd;
3038         size_t    sd_size;
3039         /* check this, when giving away 'add computer to domain' privs */
3040         uint32    des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
3041         bool can_add_account = False;
3042         SE_PRIV se_rights;
3043         DISP_INFO *disp_info = NULL;
3044
3045         /* Get the domain SID stored in the domain policy */
3046         if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &sid, &acc_granted,
3047                                      &disp_info))
3048                 return NT_STATUS_INVALID_HANDLE;
3049
3050         if (disp_info->builtin_domain) {
3051                 DEBUG(5,("_samr_CreateUser2: Refusing user create in BUILTIN\n"));
3052                 return NT_STATUS_ACCESS_DENIED;
3053         }
3054
3055         nt_status = access_check_samr_function(acc_granted,
3056                                                SAMR_DOMAIN_ACCESS_CREATE_USER,
3057                                                "_samr_CreateUser2");
3058         if (!NT_STATUS_IS_OK(nt_status)) {
3059                 return nt_status;
3060         }
3061
3062         if (!(acb_info == ACB_NORMAL || acb_info == ACB_DOMTRUST ||
3063               acb_info == ACB_WSTRUST || acb_info == ACB_SVRTRUST)) {
3064                 /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if
3065                    this parameter is not an account type */
3066                 return NT_STATUS_INVALID_PARAMETER;
3067         }
3068
3069         account = r->in.account_name->string;
3070         if (account == NULL) {
3071                 return NT_STATUS_NO_MEMORY;
3072         }
3073
3074         nt_status = can_create(p->mem_ctx, account);
3075         if (!NT_STATUS_IS_OK(nt_status)) {
3076                 return nt_status;
3077         }
3078
3079         /* determine which user right we need to check based on the acb_info */
3080
3081         if ( acb_info & ACB_WSTRUST )
3082         {
3083                 se_priv_copy( &se_rights, &se_machine_account );
3084                 can_add_account = user_has_privileges(
3085                         p->server_info->ptok, &se_rights );
3086         }
3087         /* usrmgr.exe (and net rpc trustdom grant) creates a normal user
3088            account for domain trusts and changes the ACB flags later */
3089         else if ( acb_info & ACB_NORMAL &&
3090                   (account[strlen(account)-1] != '$') )
3091         {
3092                 se_priv_copy( &se_rights, &se_add_users );
3093                 can_add_account = user_has_privileges(
3094                         p->server_info->ptok, &se_rights );
3095         }
3096         else    /* implicit assumption of a BDC or domain trust account here
3097                  * (we already check the flags earlier) */
3098         {
3099                 if ( lp_enable_privileges() ) {
3100                         /* only Domain Admins can add a BDC or domain trust */
3101                         se_priv_copy( &se_rights, &se_priv_none );
3102                         can_add_account = nt_token_check_domain_rid(
3103                                 p->server_info->ptok,
3104                                 DOMAIN_GROUP_RID_ADMINS );
3105                 }
3106         }
3107
3108         DEBUG(5, ("_samr_CreateUser2: %s can add this account : %s\n",
3109                   uidtoname(p->server_info->utok.uid),
3110                   can_add_account ? "True":"False" ));
3111
3112         /********** BEGIN Admin BLOCK **********/
3113
3114         if ( can_add_account )
3115                 become_root();
3116
3117         nt_status = pdb_create_user(p->mem_ctx, account, acb_info,
3118                                     r->out.rid);
3119
3120         if ( can_add_account )
3121                 unbecome_root();
3122
3123         /********** END Admin BLOCK **********/
3124
3125         /* now check for failure */
3126
3127         if ( !NT_STATUS_IS_OK(nt_status) )
3128                 return nt_status;
3129
3130         /* Get the user's SID */
3131
3132         sid_compose(&sid, get_global_sam_sid(), *r->out.rid);
3133
3134         map_max_allowed_access(p->server_info->ptok, &des_access);
3135
3136         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping,
3137                             &sid, SAMR_USR_RIGHTS_WRITE_PW);
3138         se_map_generic(&des_access, &usr_generic_mapping);
3139
3140         nt_status = access_check_samr_object(psd, p->server_info->ptok,
3141                 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
3142                 &acc_granted, "_samr_CreateUser2");
3143
3144         if ( !NT_STATUS_IS_OK(nt_status) ) {
3145                 return nt_status;
3146         }
3147
3148         /* associate the user's SID with the new handle. */
3149         if ((info = get_samr_info_by_sid(p->mem_ctx, &sid)) == NULL) {
3150                 return NT_STATUS_NO_MEMORY;
3151         }
3152
3153         ZERO_STRUCTP(info);
3154         info->sid = sid;
3155         info->acc_granted = acc_granted;
3156
3157         /* get a (unique) handle.  open a policy on it. */
3158         if (!create_policy_hnd(p, r->out.user_handle, info)) {
3159                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3160         }
3161
3162         /* After a "set" ensure we have no cached display info. */
3163         force_flush_samr_cache(info->disp_info);
3164
3165         *r->out.access_granted = acc_granted;
3166
3167         return NT_STATUS_OK;
3168 }
3169
3170 /****************************************************************
3171 ****************************************************************/
3172
3173 NTSTATUS _samr_CreateUser(pipes_struct *p,
3174                           struct samr_CreateUser *r)
3175 {
3176         struct samr_CreateUser2 c;
3177         uint32_t access_granted;
3178
3179         c.in.domain_handle      = r->in.domain_handle;
3180         c.in.account_name       = r->in.account_name;
3181         c.in.acct_flags         = ACB_NORMAL;
3182         c.in.access_mask        = r->in.access_mask;
3183         c.out.user_handle       = r->out.user_handle;
3184         c.out.access_granted    = &access_granted;
3185         c.out.rid               = r->out.rid;
3186
3187         return _samr_CreateUser2(p, &c);
3188 }
3189
3190 /*******************************************************************
3191  _samr_Connect
3192  ********************************************************************/
3193
3194 NTSTATUS _samr_Connect(pipes_struct *p,
3195                        struct samr_Connect *r)
3196 {
3197         struct samr_info *info = NULL;
3198         uint32    des_access = r->in.access_mask;
3199
3200         /* Access check */
3201
3202         if (!pipe_access_check(p)) {
3203                 DEBUG(3, ("access denied to _samr_Connect\n"));
3204                 return NT_STATUS_ACCESS_DENIED;
3205         }
3206
3207         /* set up the SAMR connect_anon response */
3208
3209         /* associate the user's SID with the new handle. */
3210         if ((info = get_samr_info_by_sid(p->mem_ctx, NULL)) == NULL)
3211                 return NT_STATUS_NO_MEMORY;
3212
3213         /* don't give away the farm but this is probably ok.  The SAMR_ACCESS_ENUM_DOMAINS
3214            was observed from a win98 client trying to enumerate users (when configured
3215            user level access control on shares)   --jerry */
3216
3217         map_max_allowed_access(p->server_info->ptok, &des_access);
3218
3219         se_map_generic( &des_access, &sam_generic_mapping );
3220         info->acc_granted = des_access & (SAMR_ACCESS_ENUM_DOMAINS|SAMR_ACCESS_OPEN_DOMAIN);
3221
3222         /* get a (unique) handle.  open a policy on it. */
3223         if (!create_policy_hnd(p, r->out.connect_handle, info))
3224                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3225
3226         return NT_STATUS_OK;
3227 }
3228
3229 /*******************************************************************
3230  _samr_Connect2
3231  ********************************************************************/
3232
3233 NTSTATUS _samr_Connect2(pipes_struct *p,
3234                         struct samr_Connect2 *r)
3235 {
3236         struct samr_info *info = NULL;
3237         SEC_DESC *psd = NULL;
3238         uint32    acc_granted;
3239         uint32    des_access = r->in.access_mask;
3240         NTSTATUS  nt_status;
3241         size_t    sd_size;
3242         const char *fn = "_samr_Connect2";
3243
3244         switch (p->hdr_req.opnum) {
3245         case NDR_SAMR_CONNECT2:
3246                 fn = "_samr_Connect2";
3247                 break;
3248         case NDR_SAMR_CONNECT3:
3249                 fn = "_samr_Connect3";
3250                 break;
3251         case NDR_SAMR_CONNECT4:
3252                 fn = "_samr_Connect4";
3253                 break;
3254         case NDR_SAMR_CONNECT5:
3255                 fn = "_samr_Connect5";
3256                 break;
3257         }
3258
3259         DEBUG(5,("%s: %d\n", fn, __LINE__));
3260
3261         /* Access check */
3262
3263         if (!pipe_access_check(p)) {
3264                 DEBUG(3, ("access denied to %s\n", fn));
3265                 return NT_STATUS_ACCESS_DENIED;
3266         }
3267
3268         map_max_allowed_access(p->server_info->ptok, &des_access);
3269
3270         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
3271         se_map_generic(&des_access, &sam_generic_mapping);
3272
3273         nt_status = access_check_samr_object(psd, p->server_info->ptok,
3274                 NULL, 0, des_access, &acc_granted, fn);
3275
3276         if ( !NT_STATUS_IS_OK(nt_status) )
3277                 return nt_status;
3278
3279         /* associate the user's SID and access granted with the new handle. */
3280         if ((info = get_samr_info_by_sid(p->mem_ctx, NULL)) == NULL)
3281                 return NT_STATUS_NO_MEMORY;
3282
3283         info->acc_granted = acc_granted;
3284         info->status = r->in.access_mask; /* this looks so wrong... - gd */
3285
3286         /* get a (unique) handle.  open a policy on it. */
3287         if (!create_policy_hnd(p, r->out.connect_handle, info))
3288                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3289
3290         DEBUG(5,("%s: %d\n", fn, __LINE__));
3291
3292         return nt_status;
3293 }
3294
3295 /****************************************************************
3296  _samr_Connect3
3297 ****************************************************************/
3298
3299 NTSTATUS _samr_Connect3(pipes_struct *p,
3300                         struct samr_Connect3 *r)
3301 {
3302         struct samr_Connect2 c;
3303
3304         c.in.system_name        = r->in.system_name;
3305         c.in.access_mask        = r->in.access_mask;
3306         c.out.connect_handle    = r->out.connect_handle;
3307
3308         return _samr_Connect2(p, &c);
3309 }
3310
3311 /*******************************************************************
3312  _samr_Connect4
3313  ********************************************************************/
3314
3315 NTSTATUS _samr_Connect4(pipes_struct *p,
3316                         struct samr_Connect4 *r)
3317 {
3318         struct samr_Connect2 c;
3319
3320         c.in.system_name        = r->in.system_name;
3321         c.in.access_mask        = r->in.access_mask;
3322         c.out.connect_handle    = r->out.connect_handle;
3323
3324         return _samr_Connect2(p, &c);
3325 }
3326
3327 /*******************************************************************
3328  _samr_Connect5
3329  ********************************************************************/
3330
3331 NTSTATUS _samr_Connect5(pipes_struct *p,
3332                         struct samr_Connect5 *r)
3333 {
3334         NTSTATUS status;
3335         struct samr_Connect2 c;
3336         struct samr_ConnectInfo1 info1;
3337
3338         info1.client_version = SAMR_CONNECT_AFTER_W2K;
3339         info1.unknown2 = 0;
3340
3341         c.in.system_name        = r->in.system_name;
3342         c.in.access_mask        = r->in.access_mask;
3343         c.out.connect_handle    = r->out.connect_handle;
3344
3345         status = _samr_Connect2(p, &c);
3346         if (!NT_STATUS_IS_OK(status)) {
3347                 return status;
3348         }
3349
3350         *r->out.level_out = 1;
3351         r->out.info_out->info1 = info1;
3352
3353         return NT_STATUS_OK;
3354 }
3355
3356 /**********************************************************************
3357  _samr_LookupDomain
3358  **********************************************************************/
3359
3360 NTSTATUS _samr_LookupDomain(pipes_struct *p,
3361                             struct samr_LookupDomain *r)
3362 {
3363         NTSTATUS status = NT_STATUS_OK;
3364         struct samr_info *info;
3365         const char *domain_name;
3366         DOM_SID *sid = NULL;
3367
3368         if (!find_policy_by_hnd(p, r->in.connect_handle, (void**)(void *)&info))
3369                 return NT_STATUS_INVALID_HANDLE;
3370
3371         /* win9x user manager likes to use SAMR_ACCESS_ENUM_DOMAINS here.
3372            Reverted that change so we will work with RAS servers again */
3373
3374         status = access_check_samr_function(info->acc_granted,
3375                                             SAMR_ACCESS_OPEN_DOMAIN,
3376                                             "_samr_LookupDomain");
3377         if (!NT_STATUS_IS_OK(status)) {
3378                 return status;
3379         }
3380
3381         domain_name = r->in.domain_name->string;
3382         if (!domain_name) {
3383                 return NT_STATUS_INVALID_PARAMETER;
3384         }
3385
3386         sid = TALLOC_ZERO_P(p->mem_ctx, struct dom_sid2);
3387         if (!sid) {
3388                 return NT_STATUS_NO_MEMORY;
3389         }
3390
3391         if (strequal(domain_name, builtin_domain_name())) {
3392                 sid_copy(sid, &global_sid_Builtin);
3393         } else {
3394                 if (!secrets_fetch_domain_sid(domain_name, sid)) {
3395                         status = NT_STATUS_NO_SUCH_DOMAIN;
3396                 }
3397         }
3398
3399         DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name,
3400                  sid_string_dbg(sid)));
3401
3402         *r->out.sid = sid;
3403
3404         return status;
3405 }
3406
3407 /**********************************************************************
3408  _samr_EnumDomains
3409  **********************************************************************/
3410
3411 NTSTATUS _samr_EnumDomains(pipes_struct *p,
3412                            struct samr_EnumDomains *r)
3413 {
3414         NTSTATUS status;
3415         struct samr_info *info;
3416         uint32_t num_entries = 2;
3417         struct samr_SamEntry *entry_array = NULL;
3418         struct samr_SamArray *sam;
3419
3420         if (!find_policy_by_hnd(p, r->in.connect_handle, (void**)(void *)&info))
3421                 return NT_STATUS_INVALID_HANDLE;
3422
3423         status = access_check_samr_function(info->acc_granted,
3424                                             SAMR_ACCESS_ENUM_DOMAINS,
3425                                             "_samr_EnumDomains");
3426         if (!NT_STATUS_IS_OK(status)) {
3427                 return status;
3428         }
3429
3430         sam = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
3431         if (!sam) {
3432                 return NT_STATUS_NO_MEMORY;
3433         }
3434
3435         entry_array = TALLOC_ZERO_ARRAY(p->mem_ctx,
3436                                         struct samr_SamEntry,
3437                                         num_entries);
3438         if (!entry_array) {
3439                 return NT_STATUS_NO_MEMORY;
3440         }
3441
3442         entry_array[0].idx = 0;
3443         init_lsa_String(&entry_array[0].name, get_global_sam_name());
3444
3445         entry_array[1].idx = 1;
3446         init_lsa_String(&entry_array[1].name, "Builtin");
3447
3448         sam->count = num_entries;
3449         sam->entries = entry_array;
3450
3451         *r->out.sam = sam;
3452         *r->out.num_entries = num_entries;
3453
3454         return status;
3455 }
3456
3457 /*******************************************************************
3458  _samr_OpenAlias
3459  ********************************************************************/
3460
3461 NTSTATUS _samr_OpenAlias(pipes_struct *p,
3462                          struct samr_OpenAlias *r)
3463 {
3464         DOM_SID sid;
3465         uint32 alias_rid = r->in.rid;
3466         struct    samr_info *info = NULL;
3467         SEC_DESC *psd = NULL;
3468         uint32    acc_granted;
3469         uint32    des_access = r->in.access_mask;
3470         size_t    sd_size;
3471         NTSTATUS  status;
3472         SE_PRIV se_rights;
3473
3474         /* find the domain policy and get the SID / access bits stored in the domain policy */
3475
3476         if ( !get_lsa_policy_samr_sid(p, r->in.domain_handle, &sid, &acc_granted, NULL) )
3477                 return NT_STATUS_INVALID_HANDLE;
3478
3479         status = access_check_samr_function(acc_granted,
3480                                             SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
3481                                             "_samr_OpenAlias");
3482
3483         if ( !NT_STATUS_IS_OK(status) )
3484                 return status;
3485
3486         /* append the alias' RID to it */
3487
3488         if (!sid_append_rid(&sid, alias_rid))
3489                 return NT_STATUS_NO_SUCH_ALIAS;
3490
3491         /*check if access can be granted as requested by client. */
3492
3493         map_max_allowed_access(p->server_info->ptok, &des_access);
3494
3495         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &ali_generic_mapping, NULL, 0);
3496         se_map_generic(&des_access,&ali_generic_mapping);
3497
3498         se_priv_copy( &se_rights, &se_add_users );
3499
3500
3501         status = access_check_samr_object(psd, p->server_info->ptok,
3502                 &se_rights, GENERIC_RIGHTS_ALIAS_WRITE, des_access,
3503                 &acc_granted, "_samr_OpenAlias");
3504
3505         if ( !NT_STATUS_IS_OK(status) )
3506                 return status;
3507
3508         {
3509                 /* Check we actually have the requested alias */