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