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