034392ed2124b18fa21bb0568ef4044f22ae2f12
[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         const char *munged_dial_decoded = NULL;
2372         DATA_BLOB blob;
2373
2374         ZERO_STRUCTP(r);
2375
2376         if ( !(sampass = samu_new( mem_ctx )) ) {
2377                 return NT_STATUS_NO_MEMORY;
2378         }
2379
2380         become_root();
2381         ret = pdb_getsampwsid(sampass, user_sid);
2382         unbecome_root();
2383
2384         if (ret == False) {
2385                 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
2386                 TALLOC_FREE(sampass);
2387                 return NT_STATUS_NO_SUCH_USER;
2388         }
2389
2390         munged_dial = pdb_get_munged_dial(sampass);
2391
2392         samr_clear_sam_passwd(sampass);
2393
2394         DEBUG(3,("User:[%s]\n",  pdb_get_username(sampass) ));
2395
2396         if (munged_dial) {
2397                 blob = base64_decode_data_blob(munged_dial);
2398                 munged_dial_decoded = talloc_strndup(mem_ctx,
2399                                                      (const char *)blob.data,
2400                                                      blob.length);
2401                 data_blob_free(&blob);
2402                 if (!munged_dial_decoded) {
2403                         TALLOC_FREE(sampass);
2404                         return NT_STATUS_NO_MEMORY;
2405                 }
2406         }
2407
2408 #if 0
2409         init_unistr2_from_datablob(&usr->uni_munged_dial, &blob);
2410         init_uni_hdr(&usr->hdr_munged_dial, &usr->uni_munged_dial);
2411         data_blob_free(&blob);
2412 #endif
2413         init_samr_user_info20(r, munged_dial_decoded);
2414
2415         TALLOC_FREE(sampass);
2416
2417         return NT_STATUS_OK;
2418 }
2419
2420
2421 /*************************************************************************
2422  get_user_info_21
2423  *************************************************************************/
2424
2425 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx,
2426                                  struct samr_UserInfo21 *r,
2427                                  DOM_SID *user_sid,
2428                                  DOM_SID *domain_sid)
2429 {
2430         struct samu *pw = NULL;
2431         bool ret;
2432         const DOM_SID *sid_user, *sid_group;
2433         uint32_t rid, primary_gid;
2434         NTTIME last_logon, last_logoff, last_password_change,
2435                acct_expiry, allow_password_change, force_password_change;
2436         time_t must_change_time;
2437         uint8_t password_expired;
2438         const char *account_name, *full_name, *home_directory, *home_drive,
2439                    *logon_script, *profile_path, *description,
2440                    *workstations, *comment, *parameters;
2441         struct samr_LogonHours logon_hours;
2442         const char *munged_dial = NULL;
2443         DATA_BLOB blob;
2444
2445         ZERO_STRUCTP(r);
2446
2447         if (!(pw = samu_new(mem_ctx))) {
2448                 return NT_STATUS_NO_MEMORY;
2449         }
2450
2451         become_root();
2452         ret = pdb_getsampwsid(pw, user_sid);
2453         unbecome_root();
2454
2455         if (ret == False) {
2456                 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
2457                 TALLOC_FREE(pw);
2458                 return NT_STATUS_NO_SUCH_USER;
2459         }
2460
2461         samr_clear_sam_passwd(pw);
2462
2463         DEBUG(3,("User:[%s]\n", pdb_get_username(pw)));
2464
2465         sid_user = pdb_get_user_sid(pw);
2466
2467         if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2468                 DEBUG(0, ("get_user_info_21: User %s has SID %s, \nwhich conflicts with "
2469                           "the domain sid %s.  Failing operation.\n",
2470                           pdb_get_username(pw), sid_string_dbg(sid_user),
2471                           sid_string_dbg(domain_sid)));
2472                 TALLOC_FREE(pw);
2473                 return NT_STATUS_UNSUCCESSFUL;
2474         }
2475
2476         become_root();
2477         sid_group = pdb_get_group_sid(pw);
2478         unbecome_root();
2479
2480         if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2481                 DEBUG(0, ("get_user_info_21: User %s has Primary Group SID %s, \n"
2482                           "which conflicts with the domain sid %s.  Failing operation.\n",
2483                           pdb_get_username(pw), sid_string_dbg(sid_group),
2484                           sid_string_dbg(domain_sid)));
2485                 TALLOC_FREE(pw);
2486                 return NT_STATUS_UNSUCCESSFUL;
2487         }
2488
2489         unix_to_nt_time(&last_logon, pdb_get_logon_time(pw));
2490         unix_to_nt_time(&last_logoff, pdb_get_logoff_time(pw));
2491         unix_to_nt_time(&acct_expiry, pdb_get_kickoff_time(pw));
2492         unix_to_nt_time(&last_password_change, pdb_get_pass_last_set_time(pw));
2493         unix_to_nt_time(&allow_password_change, pdb_get_pass_can_change_time(pw));
2494
2495         must_change_time = pdb_get_pass_must_change_time(pw);
2496         if (must_change_time == get_time_t_max()) {
2497                 unix_to_nt_time_abs(&force_password_change, must_change_time);
2498         } else {
2499                 unix_to_nt_time(&force_password_change, must_change_time);
2500         }
2501
2502         if (pdb_get_pass_must_change_time(pw) == 0) {
2503                 password_expired = PASS_MUST_CHANGE_AT_NEXT_LOGON;
2504         } else {
2505                 password_expired = 0;
2506         }
2507
2508         munged_dial = pdb_get_munged_dial(pw);
2509         if (munged_dial) {
2510                 blob = base64_decode_data_blob(munged_dial);
2511                 parameters = talloc_strndup(mem_ctx, (const char *)blob.data, blob.length);
2512                 data_blob_free(&blob);
2513                 if (!parameters) {
2514                         TALLOC_FREE(pw);
2515                         return NT_STATUS_NO_MEMORY;
2516                 }
2517         } else {
2518                 parameters = NULL;
2519         }
2520
2521
2522         account_name = talloc_strdup(mem_ctx, pdb_get_username(pw));
2523         full_name = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2524         home_directory = talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2525         home_drive = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2526         logon_script = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2527         profile_path = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2528         description = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2529         workstations = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2530         comment = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2531
2532         logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2533 #if 0
2534
2535         /*
2536           Look at a user on a real NT4 PDC with usrmgr, press
2537           'ok'. Then you will see that fields_present is set to
2538           0x08f827fa. Look at the user immediately after that again,
2539           and you will see that 0x00fffff is returned. This solves
2540           the problem that you get access denied after having looked
2541           at the user.
2542           -- Volker
2543         */
2544
2545 #if 0
2546         init_unistr2_from_datablob(&usr->uni_munged_dial, &munged_dial_blob);
2547         init_uni_hdr(&usr->hdr_munged_dial, &usr->uni_munged_dial);
2548         data_blob_free(&munged_dial_blob);
2549 #endif
2550 #endif
2551
2552         init_samr_user_info21(r,
2553                               last_logon,
2554                               last_logoff,
2555                               last_password_change,
2556                               acct_expiry,
2557                               allow_password_change,
2558                               force_password_change,
2559                               account_name,
2560                               full_name,
2561                               home_directory,
2562                               home_drive,
2563                               logon_script,
2564                               profile_path,
2565                               description,
2566                               workstations,
2567                               comment,
2568                               parameters,
2569                               rid,
2570                               primary_gid,
2571                               pdb_get_acct_ctrl(pw),
2572                               pdb_build_fields_present(pw),
2573                               logon_hours,
2574                               pdb_get_bad_password_count(pw),
2575                               pdb_get_logon_count(pw),
2576                               0, /* country_code */
2577                               0, /* code_page */
2578                               0, /* nt_password_set */
2579                               0, /* lm_password_set */
2580                               password_expired);
2581         TALLOC_FREE(pw);
2582
2583         return NT_STATUS_OK;
2584 }
2585
2586 /*******************************************************************
2587  _samr_QueryUserInfo
2588  ********************************************************************/
2589
2590 NTSTATUS _samr_QueryUserInfo(pipes_struct *p,
2591                              struct samr_QueryUserInfo *r)
2592 {
2593         NTSTATUS status;
2594         union samr_UserInfo *user_info = NULL;
2595         struct samr_info *info = NULL;
2596         DOM_SID domain_sid;
2597         uint32 rid;
2598
2599         /* search for the handle */
2600         if (!find_policy_by_hnd(p, r->in.user_handle, (void **)(void *)&info))
2601                 return NT_STATUS_INVALID_HANDLE;
2602
2603         domain_sid = info->sid;
2604
2605         sid_split_rid(&domain_sid, &rid);
2606
2607         if (!sid_check_is_in_our_domain(&info->sid))
2608                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2609
2610         DEBUG(5,("_samr_QueryUserInfo: sid:%s\n",
2611                  sid_string_dbg(&info->sid)));
2612
2613         user_info = TALLOC_ZERO_P(p->mem_ctx, union samr_UserInfo);
2614         if (!user_info) {
2615                 return NT_STATUS_NO_MEMORY;
2616         }
2617
2618         DEBUG(5,("_samr_QueryUserInfo: user info level: %d\n", r->in.level));
2619
2620         switch (r->in.level) {
2621         case 7:
2622                 status = get_user_info_7(p->mem_ctx, &user_info->info7, &info->sid);
2623                 if (!NT_STATUS_IS_OK(status)) {
2624                         return status;
2625                 }
2626                 break;
2627         case 9:
2628                 status = get_user_info_9(p->mem_ctx, &user_info->info9, &info->sid);
2629                 if (!NT_STATUS_IS_OK(status)) {
2630                         return status;
2631                 }
2632                 break;
2633         case 16:
2634                 status = get_user_info_16(p->mem_ctx, &user_info->info16, &info->sid);
2635                 if (!NT_STATUS_IS_OK(status)) {
2636                         return status;
2637                 }
2638                 break;
2639
2640         case 18:
2641                 status = get_user_info_18(p, p->mem_ctx, &user_info->info18, &info->sid);
2642                 if (!NT_STATUS_IS_OK(status)) {
2643                         return status;
2644                 }
2645                 break;
2646
2647         case 20:
2648                 status = get_user_info_20(p->mem_ctx, &user_info->info20, &info->sid);
2649                 if (!NT_STATUS_IS_OK(status)) {
2650                         return status;
2651                 }
2652                 break;
2653
2654         case 21:
2655                 status = get_user_info_21(p->mem_ctx, &user_info->info21,
2656                                           &info->sid, &domain_sid);
2657                 if (!NT_STATUS_IS_OK(status)) {
2658                         return status;
2659                 }
2660                 break;
2661
2662         default:
2663                 return NT_STATUS_INVALID_INFO_CLASS;
2664         }
2665
2666         *r->out.info = user_info;
2667
2668         DEBUG(5,("_samr_QueryUserInfo: %d\n", __LINE__));
2669
2670         return status;
2671 }
2672
2673 /*******************************************************************
2674  _samr_GetGroupsForUser
2675  ********************************************************************/
2676
2677 NTSTATUS _samr_GetGroupsForUser(pipes_struct *p,
2678                                 struct samr_GetGroupsForUser *r)
2679 {
2680         struct samu *sam_pass=NULL;
2681         DOM_SID  sid;
2682         DOM_SID *sids;
2683         struct samr_RidWithAttribute dom_gid;
2684         struct samr_RidWithAttribute *gids = NULL;
2685         uint32 primary_group_rid;
2686         size_t num_groups = 0;
2687         gid_t *unix_gids;
2688         size_t i, num_gids;
2689         uint32 acc_granted;
2690         bool ret;
2691         NTSTATUS result;
2692         bool success = False;
2693
2694         struct samr_RidWithAttributeArray *rids = NULL;
2695
2696         /*
2697          * from the SID in the request:
2698          * we should send back the list of DOMAIN GROUPS
2699          * the user is a member of
2700          *
2701          * and only the DOMAIN GROUPS
2702          * no ALIASES !!! neither aliases of the domain
2703          * nor aliases of the builtin SID
2704          *
2705          * JFM, 12/2/2001
2706          */
2707
2708         DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
2709
2710         rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidWithAttributeArray);
2711         if (!rids) {
2712                 return NT_STATUS_NO_MEMORY;
2713         }
2714
2715         /* find the policy handle.  open a policy on it. */
2716         if (!get_lsa_policy_samr_sid(p, r->in.user_handle, &sid, &acc_granted, NULL))
2717                 return NT_STATUS_INVALID_HANDLE;
2718
2719         result = access_check_samr_function(acc_granted,
2720                                             SA_RIGHT_USER_GET_GROUPS,
2721                                             "_samr_GetGroupsForUser");
2722         if (!NT_STATUS_IS_OK(result)) {
2723                 return result;
2724         }
2725
2726         if (!sid_check_is_in_our_domain(&sid))
2727                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2728
2729         if ( !(sam_pass = samu_new( p->mem_ctx )) ) {
2730                 return NT_STATUS_NO_MEMORY;
2731         }
2732
2733         become_root();
2734         ret = pdb_getsampwsid(sam_pass, &sid);
2735         unbecome_root();
2736
2737         if (!ret) {
2738                 DEBUG(10, ("pdb_getsampwsid failed for %s\n",
2739                            sid_string_dbg(&sid)));
2740                 return NT_STATUS_NO_SUCH_USER;
2741         }
2742
2743         sids = NULL;
2744
2745         /* make both calls inside the root block */
2746         become_root();
2747         result = pdb_enum_group_memberships(p->mem_ctx, sam_pass,
2748                                             &sids, &unix_gids, &num_groups);
2749         if ( NT_STATUS_IS_OK(result) ) {
2750                 success = sid_peek_check_rid(get_global_sam_sid(),
2751                                              pdb_get_group_sid(sam_pass),
2752                                              &primary_group_rid);
2753         }
2754         unbecome_root();
2755
2756         if (!NT_STATUS_IS_OK(result)) {
2757                 DEBUG(10, ("pdb_enum_group_memberships failed for %s\n",
2758                            sid_string_dbg(&sid)));
2759                 return result;
2760         }
2761
2762         if ( !success ) {
2763                 DEBUG(5, ("Group sid %s for user %s not in our domain\n",
2764                           sid_string_dbg(pdb_get_group_sid(sam_pass)),
2765                           pdb_get_username(sam_pass)));
2766                 TALLOC_FREE(sam_pass);
2767                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2768         }
2769
2770         gids = NULL;
2771         num_gids = 0;
2772
2773         dom_gid.attributes = (SE_GROUP_MANDATORY|SE_GROUP_ENABLED_BY_DEFAULT|
2774                               SE_GROUP_ENABLED);
2775         dom_gid.rid = primary_group_rid;
2776         ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
2777
2778         for (i=0; i<num_groups; i++) {
2779
2780                 if (!sid_peek_check_rid(get_global_sam_sid(),
2781                                         &(sids[i]), &dom_gid.rid)) {
2782                         DEBUG(10, ("Found sid %s not in our domain\n",
2783                                    sid_string_dbg(&sids[i])));
2784                         continue;
2785                 }
2786
2787                 if (dom_gid.rid == primary_group_rid) {
2788                         /* We added the primary group directly from the
2789                          * sam_account. The other SIDs are unique from
2790                          * enum_group_memberships */
2791                         continue;
2792                 }
2793
2794                 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
2795         }
2796
2797         rids->count = num_gids;
2798         rids->rids = gids;
2799
2800         *r->out.rids = rids;
2801
2802         DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
2803
2804         return result;
2805 }
2806
2807 /*******************************************************************
2808  samr_QueryDomainInfo_internal
2809  ********************************************************************/
2810
2811 static NTSTATUS samr_QueryDomainInfo_internal(const char *fn_name,
2812                                               pipes_struct *p,
2813                                               struct policy_handle *handle,
2814                                               uint32_t level,
2815                                               union samr_DomainInfo **dom_info_ptr)
2816 {
2817         NTSTATUS status = NT_STATUS_OK;
2818         struct samr_info *info = NULL;
2819         union samr_DomainInfo *dom_info;
2820         uint32 min_pass_len,pass_hist,password_properties;
2821         time_t u_expire, u_min_age;
2822         NTTIME nt_expire, nt_min_age;
2823
2824         time_t u_lock_duration, u_reset_time;
2825         NTTIME nt_lock_duration, nt_reset_time;
2826         uint32 lockout;
2827         time_t u_logout;
2828         NTTIME nt_logout;
2829
2830         uint32 account_policy_temp;
2831
2832         time_t seq_num;
2833         uint32 server_role;
2834
2835         uint32 num_users=0, num_groups=0, num_aliases=0;
2836
2837         DEBUG(5,("%s: %d\n", fn_name, __LINE__));
2838
2839         dom_info = TALLOC_ZERO_P(p->mem_ctx, union samr_DomainInfo);
2840         if (!dom_info) {
2841                 return NT_STATUS_NO_MEMORY;
2842         }
2843
2844         *dom_info_ptr = dom_info;
2845
2846         /* find the policy handle.  open a policy on it. */
2847         if (!find_policy_by_hnd(p, handle, (void **)(void *)&info)) {
2848                 return NT_STATUS_INVALID_HANDLE;
2849         }
2850
2851         switch (level) {
2852                 case 0x01:
2853
2854                         become_root();
2855
2856                         /* AS ROOT !!! */
2857
2858                         pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &account_policy_temp);
2859                         min_pass_len = account_policy_temp;
2860
2861                         pdb_get_account_policy(AP_PASSWORD_HISTORY, &account_policy_temp);
2862                         pass_hist = account_policy_temp;
2863
2864                         pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
2865                         password_properties = account_policy_temp;
2866
2867                         pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
2868                         u_expire = account_policy_temp;
2869
2870                         pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
2871                         u_min_age = account_policy_temp;
2872
2873                         /* !AS ROOT */
2874
2875                         unbecome_root();
2876
2877                         unix_to_nt_time_abs(&nt_expire, u_expire);
2878                         unix_to_nt_time_abs(&nt_min_age, u_min_age);
2879
2880                         init_samr_DomInfo1(&dom_info->info1,
2881                                            (uint16)min_pass_len,
2882                                            (uint16)pass_hist,
2883                                            password_properties,
2884                                            nt_expire,
2885                                            nt_min_age);
2886                         break;
2887                 case 0x02:
2888
2889                         become_root();
2890
2891                         /* AS ROOT !!! */
2892
2893                         num_users = count_sam_users(info->disp_info, ACB_NORMAL);
2894                         num_groups = count_sam_groups(info->disp_info);
2895                         num_aliases = count_sam_aliases(info->disp_info);
2896
2897                         pdb_get_account_policy(AP_TIME_TO_LOGOUT, &account_policy_temp);
2898                         u_logout = account_policy_temp;
2899
2900                         unix_to_nt_time_abs(&nt_logout, u_logout);
2901
2902                         if (!pdb_get_seq_num(&seq_num))
2903                                 seq_num = time(NULL);
2904
2905                         /* !AS ROOT */
2906
2907                         unbecome_root();
2908
2909                         server_role = ROLE_DOMAIN_PDC;
2910                         if (lp_server_role() == ROLE_DOMAIN_BDC)
2911                                 server_role = ROLE_DOMAIN_BDC;
2912
2913                         init_samr_DomInfo2(&dom_info->info2,
2914                                            nt_logout,
2915                                            lp_serverstring(),
2916                                            lp_workgroup(),
2917                                            global_myname(),
2918                                            seq_num,
2919                                            1,
2920                                            server_role,
2921                                            1,
2922                                            num_users,
2923                                            num_groups,
2924                                            num_aliases);
2925                         break;
2926                 case 0x03:
2927
2928                         become_root();
2929
2930                         /* AS ROOT !!! */
2931
2932                         {
2933                                 uint32 ul;
2934                                 pdb_get_account_policy(AP_TIME_TO_LOGOUT, &ul);
2935                                 u_logout = (time_t)ul;
2936                         }
2937
2938                         /* !AS ROOT */
2939
2940                         unbecome_root();
2941
2942                         unix_to_nt_time_abs(&nt_logout, u_logout);
2943
2944                         init_samr_DomInfo3(&dom_info->info3,
2945                                            nt_logout);
2946
2947                         break;
2948                 case 0x04:
2949                         init_samr_DomInfo4(&dom_info->info4,
2950                                            lp_serverstring());
2951                         break;
2952                 case 0x05:
2953                         init_samr_DomInfo5(&dom_info->info5,
2954                                            get_global_sam_name());
2955                         break;
2956                 case 0x06:
2957                         /* NT returns its own name when a PDC. win2k and later
2958                          * only the name of the PDC if itself is a BDC (samba4
2959                          * idl) */
2960                         init_samr_DomInfo6(&dom_info->info6,
2961                                            global_myname());
2962                         break;
2963                 case 0x07:
2964                         server_role = ROLE_DOMAIN_PDC;
2965                         if (lp_server_role() == ROLE_DOMAIN_BDC)
2966                                 server_role = ROLE_DOMAIN_BDC;
2967
2968                         init_samr_DomInfo7(&dom_info->info7,
2969                                            server_role);
2970                         break;
2971                 case 0x08:
2972
2973                         become_root();
2974
2975                         /* AS ROOT !!! */
2976
2977                         if (!pdb_get_seq_num(&seq_num)) {
2978                                 seq_num = time(NULL);
2979                         }
2980
2981                         /* !AS ROOT */
2982
2983                         unbecome_root();
2984
2985                         init_samr_DomInfo8(&dom_info->info8,
2986                                            seq_num,
2987                                            0);
2988                         break;
2989                 case 0x0c:
2990
2991                         become_root();
2992
2993                         /* AS ROOT !!! */
2994
2995                         pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
2996                         u_lock_duration = account_policy_temp;
2997                         if (u_lock_duration != -1) {
2998                                 u_lock_duration *= 60;
2999                         }
3000
3001                         pdb_get_account_policy(AP_RESET_COUNT_TIME, &account_policy_temp);
3002                         u_reset_time = account_policy_temp * 60;
3003
3004                         pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
3005                         lockout = account_policy_temp;
3006
3007                         /* !AS ROOT */
3008
3009                         unbecome_root();
3010
3011                         unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
3012                         unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
3013
3014                         init_samr_DomInfo12(&dom_info->info12,
3015                                             nt_lock_duration,
3016                                             nt_reset_time,
3017                                             (uint16)lockout);
3018                         break;
3019                 default:
3020                         return NT_STATUS_INVALID_INFO_CLASS;
3021         }
3022
3023         DEBUG(5,("%s: %d\n", fn_name, __LINE__));
3024
3025         return status;
3026 }
3027
3028 /*******************************************************************
3029  _samr_QueryDomainInfo
3030  ********************************************************************/
3031
3032 NTSTATUS _samr_QueryDomainInfo(pipes_struct *p,
3033                                struct samr_QueryDomainInfo *r)
3034 {
3035         return samr_QueryDomainInfo_internal("_samr_QueryDomainInfo",
3036                                              p,
3037                                              r->in.domain_handle,
3038                                              r->in.level,
3039                                              r->out.info);
3040 }
3041
3042 /* W2k3 seems to use the same check for all 3 objects that can be created via
3043  * SAMR, if you try to create for example "Dialup" as an alias it says
3044  * "NT_STATUS_USER_EXISTS". This is racy, but we can't really lock the user
3045  * database. */
3046
3047 static NTSTATUS can_create(TALLOC_CTX *mem_ctx, const char *new_name)
3048 {
3049         enum lsa_SidType type;
3050         bool result;
3051
3052         DEBUG(10, ("Checking whether [%s] can be created\n", new_name));
3053
3054         become_root();
3055         /* Lookup in our local databases (LOOKUP_NAME_REMOTE not set)
3056          * whether the name already exists */
3057         result = lookup_name(mem_ctx, new_name, LOOKUP_NAME_LOCAL,
3058                              NULL, NULL, NULL, &type);
3059         unbecome_root();
3060
3061         if (!result) {
3062                 DEBUG(10, ("%s does not exist, can create it\n", new_name));
3063                 return NT_STATUS_OK;
3064         }
3065
3066         DEBUG(5, ("trying to create %s, exists as %s\n",
3067                   new_name, sid_type_lookup(type)));
3068
3069         if (type == SID_NAME_DOM_GRP) {
3070                 return NT_STATUS_GROUP_EXISTS;
3071         }
3072         if (type == SID_NAME_ALIAS) {
3073                 return NT_STATUS_ALIAS_EXISTS;
3074         }
3075
3076         /* Yes, the default is NT_STATUS_USER_EXISTS */
3077         return NT_STATUS_USER_EXISTS;
3078 }
3079
3080 /*******************************************************************
3081  _samr_CreateUser2
3082  ********************************************************************/
3083
3084 NTSTATUS _samr_CreateUser2(pipes_struct *p,
3085                            struct samr_CreateUser2 *r)
3086 {
3087         const char *account = NULL;
3088         DOM_SID sid;
3089         POLICY_HND dom_pol = *r->in.domain_handle;
3090         uint32_t acb_info = r->in.acct_flags;
3091         POLICY_HND *user_pol = r->out.user_handle;
3092         struct samr_info *info = NULL;
3093         NTSTATUS nt_status;
3094         uint32 acc_granted;
3095         SEC_DESC *psd;
3096         size_t    sd_size;
3097         /* check this, when giving away 'add computer to domain' privs */
3098         uint32    des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
3099         bool can_add_account = False;
3100         SE_PRIV se_rights;
3101         DISP_INFO *disp_info = NULL;
3102
3103         /* Get the domain SID stored in the domain policy */
3104         if (!get_lsa_policy_samr_sid(p, &dom_pol, &sid, &acc_granted,
3105                                      &disp_info))
3106                 return NT_STATUS_INVALID_HANDLE;
3107
3108         nt_status = access_check_samr_function(acc_granted,
3109                                                SA_RIGHT_DOMAIN_CREATE_USER,
3110                                                "_samr_CreateUser2");
3111         if (!NT_STATUS_IS_OK(nt_status)) {
3112                 return nt_status;
3113         }
3114
3115         if (!(acb_info == ACB_NORMAL || acb_info == ACB_DOMTRUST ||
3116               acb_info == ACB_WSTRUST || acb_info == ACB_SVRTRUST)) {
3117                 /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if
3118                    this parameter is not an account type */
3119                 return NT_STATUS_INVALID_PARAMETER;
3120         }
3121
3122         account = r->in.account_name->string;
3123         if (account == NULL) {
3124                 return NT_STATUS_NO_MEMORY;
3125         }
3126
3127         nt_status = can_create(p->mem_ctx, account);
3128         if (!NT_STATUS_IS_OK(nt_status)) {
3129                 return nt_status;
3130         }
3131
3132         /* determine which user right we need to check based on the acb_info */
3133
3134         if ( acb_info & ACB_WSTRUST )
3135         {
3136                 se_priv_copy( &se_rights, &se_machine_account );
3137                 can_add_account = user_has_privileges(
3138                         p->pipe_user.nt_user_token, &se_rights );
3139         }
3140         /* usrmgr.exe (and net rpc trustdom grant) creates a normal user
3141            account for domain trusts and changes the ACB flags later */
3142         else if ( acb_info & ACB_NORMAL &&
3143                   (account[strlen(account)-1] != '$') )
3144         {
3145                 se_priv_copy( &se_rights, &se_add_users );
3146                 can_add_account = user_has_privileges(
3147                         p->pipe_user.nt_user_token, &se_rights );
3148         }
3149         else    /* implicit assumption of a BDC or domain trust account here
3150                  * (we already check the flags earlier) */
3151         {
3152                 if ( lp_enable_privileges() ) {
3153                         /* only Domain Admins can add a BDC or domain trust */
3154                         se_priv_copy( &se_rights, &se_priv_none );
3155                         can_add_account = nt_token_check_domain_rid(
3156                                 p->pipe_user.nt_user_token,
3157                                 DOMAIN_GROUP_RID_ADMINS );
3158                 }
3159         }
3160
3161         DEBUG(5, ("_samr_CreateUser2: %s can add this account : %s\n",
3162                   uidtoname(p->pipe_user.ut.uid),
3163                   can_add_account ? "True":"False" ));
3164
3165         /********** BEGIN Admin BLOCK **********/
3166
3167         if ( can_add_account )
3168                 become_root();
3169
3170         nt_status = pdb_create_user(p->mem_ctx, account, acb_info,
3171                                     r->out.rid);
3172
3173         if ( can_add_account )
3174                 unbecome_root();
3175
3176         /********** END Admin BLOCK **********/
3177
3178         /* now check for failure */
3179
3180         if ( !NT_STATUS_IS_OK(nt_status) )
3181                 return nt_status;
3182
3183         /* Get the user's SID */
3184
3185         sid_compose(&sid, get_global_sam_sid(), *r->out.rid);
3186
3187         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping,
3188                             &sid, SAMR_USR_RIGHTS_WRITE_PW);
3189         se_map_generic(&des_access, &usr_generic_mapping);
3190
3191         nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3192                 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
3193                 &acc_granted, "_samr_CreateUser2");
3194
3195         if ( !NT_STATUS_IS_OK(nt_status) ) {
3196                 return nt_status;
3197         }
3198
3199         /* associate the user's SID with the new handle. */
3200         if ((info = get_samr_info_by_sid(&sid)) == NULL) {
3201                 return NT_STATUS_NO_MEMORY;
3202         }
3203
3204         ZERO_STRUCTP(info);
3205         info->sid = sid;
3206         info->acc_granted = acc_granted;
3207
3208         /* get a (unique) handle.  open a policy on it. */
3209         if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info)) {
3210                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3211         }
3212
3213         /* After a "set" ensure we have no cached display info. */
3214         force_flush_samr_cache(info->disp_info);
3215
3216         *r->out.access_granted = acc_granted;
3217
3218         return NT_STATUS_OK;
3219 }
3220
3221 /*******************************************************************
3222  _samr_Connect
3223  ********************************************************************/
3224
3225 NTSTATUS _samr_Connect(pipes_struct *p,
3226                        struct samr_Connect *r)
3227 {
3228         struct samr_info *info = NULL;
3229         uint32    des_access = r->in.access_mask;
3230
3231         /* Access check */
3232
3233         if (!pipe_access_check(p)) {
3234                 DEBUG(3, ("access denied to _samr_Connect\n"));
3235                 return NT_STATUS_ACCESS_DENIED;
3236         }
3237
3238         /* set up the SAMR connect_anon response */
3239
3240         /* associate the user's SID with the new handle. */
3241         if ((info = get_samr_info_by_sid(NULL)) == NULL)
3242                 return NT_STATUS_NO_MEMORY;
3243
3244         /* don't give away the farm but this is probably ok.  The SA_RIGHT_SAM_ENUM_DOMAINS
3245            was observed from a win98 client trying to enumerate users (when configured
3246            user level access control on shares)   --jerry */
3247
3248         if (des_access == MAXIMUM_ALLOWED_ACCESS) {
3249                 /* Map to max possible knowing we're filtered below. */
3250                 des_access = GENERIC_ALL_ACCESS;
3251         }
3252
3253         se_map_generic( &des_access, &sam_generic_mapping );
3254         info->acc_granted = des_access & (SA_RIGHT_SAM_ENUM_DOMAINS|SA_RIGHT_SAM_OPEN_DOMAIN);
3255
3256         /* get a (unique) handle.  open a policy on it. */
3257         if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info))
3258                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3259
3260         return NT_STATUS_OK;
3261 }
3262
3263 /*******************************************************************
3264  _samr_Connect2
3265  ********************************************************************/
3266
3267 NTSTATUS _samr_Connect2(pipes_struct *p,
3268                         struct samr_Connect2 *r)
3269 {
3270         struct samr_info *info = NULL;
3271         SEC_DESC *psd = NULL;
3272         uint32    acc_granted;
3273         uint32    des_access = r->in.access_mask;
3274         NTSTATUS  nt_status;
3275         size_t    sd_size;
3276
3277
3278         DEBUG(5,("_samr_Connect2: %d\n", __LINE__));
3279
3280         /* Access check */
3281
3282         if (!pipe_access_check(p)) {
3283                 DEBUG(3, ("access denied to _samr_Connect2\n"));
3284                 return NT_STATUS_ACCESS_DENIED;
3285         }
3286
3287         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
3288         se_map_generic(&des_access, &sam_generic_mapping);
3289
3290         nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3291                 NULL, 0, des_access, &acc_granted, "_samr_Connect2");
3292
3293         if ( !NT_STATUS_IS_OK(nt_status) )
3294                 return nt_status;
3295
3296         /* associate the user's SID and access granted with the new handle. */
3297         if ((info = get_samr_info_by_sid(NULL)) == NULL)
3298                 return NT_STATUS_NO_MEMORY;
3299
3300         info->acc_granted = acc_granted;
3301         info->status = r->in.access_mask; /* this looks so wrong... - gd */
3302
3303         /* get a (unique) handle.  open a policy on it. */
3304         if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info))
3305                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3306
3307         DEBUG(5,("_samr_Connect2: %d\n", __LINE__));
3308
3309         return nt_status;
3310 }
3311
3312 /*******************************************************************
3313  _samr_Connect4
3314  ********************************************************************/
3315
3316 NTSTATUS _samr_Connect4(pipes_struct *p,
3317                         struct samr_Connect4 *r)
3318 {
3319         struct samr_info *info = NULL;
3320         SEC_DESC *psd = NULL;
3321         uint32    acc_granted;
3322         uint32    des_access = r->in.access_mask;
3323         NTSTATUS  nt_status;
3324         size_t    sd_size;
3325
3326
3327         DEBUG(5,("_samr_Connect4: %d\n", __LINE__));
3328
3329         /* Access check */
3330
3331         if (!pipe_access_check(p)) {
3332                 DEBUG(3, ("access denied to samr_Connect4\n"));
3333                 return NT_STATUS_ACCESS_DENIED;
3334         }
3335
3336         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
3337         se_map_generic(&des_access, &sam_generic_mapping);
3338
3339         nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3340                 NULL, 0, des_access, &acc_granted, "_samr_Connect4");
3341
3342         if ( !NT_STATUS_IS_OK(nt_status) )
3343                 return nt_status;
3344
3345         /* associate the user's SID and access granted with the new handle. */
3346         if ((info = get_samr_info_by_sid(NULL)) == NULL)
3347                 return NT_STATUS_NO_MEMORY;
3348
3349         info->acc_granted = acc_granted;
3350         info->status = r->in.access_mask; /* ??? */
3351
3352         /* get a (unique) handle.  open a policy on it. */
3353         if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info))
3354                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3355
3356         DEBUG(5,("_samr_Connect4: %d\n", __LINE__));
3357
3358         return NT_STATUS_OK;
3359 }
3360
3361 /*******************************************************************
3362  _samr_Connect5
3363  ********************************************************************/
3364
3365 NTSTATUS _samr_Connect5(pipes_struct *p,
3366                         struct samr_Connect5 *r)
3367 {
3368         struct samr_info *info = NULL;
3369         SEC_DESC *psd = NULL;
3370         uint32    acc_granted;
3371         uint32    des_access = r->in.access_mask;
3372         NTSTATUS  nt_status;
3373         size_t    sd_size;
3374         struct samr_ConnectInfo1 info1;
3375
3376         DEBUG(5,("_samr_Connect5: %d\n", __LINE__));
3377
3378         /* Access check */
3379
3380         if (!pipe_access_check(p)) {
3381                 DEBUG(3, ("access denied to samr_Connect5\n"));
3382                 return NT_STATUS_ACCESS_DENIED;
3383         }
3384
3385         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
3386         se_map_generic(&des_access, &sam_generic_mapping);
3387
3388         nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3389                 NULL, 0, des_access, &acc_granted, "_samr_Connect5");
3390
3391         if ( !NT_STATUS_IS_OK(nt_status) )
3392                 return nt_status;
3393
3394         /* associate the user's SID and access granted with the new handle. */
3395         if ((info = get_samr_info_by_sid(NULL)) == NULL)
3396                 return NT_STATUS_NO_MEMORY;
3397
3398         info->acc_granted = acc_granted;
3399         info->status = r->in.access_mask; /* ??? */
3400
3401         /* get a (unique) handle.  open a policy on it. */
3402         if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info))
3403                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3404
3405         DEBUG(5,("_samr_Connect5: %d\n", __LINE__));
3406
3407         info1.client_version = SAMR_CONNECT_AFTER_W2K;
3408         info1.unknown2 = 0;
3409
3410         *r->out.level_out = 1;
3411         r->out.info_out->info1 = info1;
3412
3413         return NT_STATUS_OK;
3414 }
3415
3416 /**********************************************************************
3417  _samr_LookupDomain
3418  **********************************************************************/
3419
3420 NTSTATUS _samr_LookupDomain(pipes_struct *p,
3421                             struct samr_LookupDomain *r)
3422 {
3423         NTSTATUS status = NT_STATUS_OK;
3424         struct samr_info *info;
3425         const char *domain_name;
3426         DOM_SID *sid = NULL;
3427
3428         if (!find_policy_by_hnd(p, r->in.connect_handle, (void**)(void *)&info))
3429                 return NT_STATUS_INVALID_HANDLE;
3430
3431         /* win9x user manager likes to use SA_RIGHT_SAM_ENUM_DOMAINS here.
3432            Reverted that change so we will work with RAS servers again */
3433
3434         status = access_check_samr_function(info->acc_granted,
3435                                             SA_RIGHT_SAM_OPEN_DOMAIN,
3436                                             "_samr_LookupDomain");
3437         if (!NT_STATUS_IS_OK(status)) {
3438                 return status;
3439         }
3440
3441         domain_name = r->in.domain_name->string;
3442
3443         sid = TALLOC_ZERO_P(p->mem_ctx, struct dom_sid2);
3444         if (!sid) {
3445                 return NT_STATUS_NO_MEMORY;
3446         }
3447
3448         if (strequal(domain_name, builtin_domain_name())) {
3449                 sid_copy(sid, &global_sid_Builtin);
3450         } else {
3451                 if (!secrets_fetch_domain_sid(domain_name, sid)) {
3452                         status = NT_STATUS_NO_SUCH_DOMAIN;
3453                 }
3454         }
3455
3456         DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name,
3457                  sid_string_dbg(sid)));
3458
3459         *r->out.sid = sid;
3460
3461         return status;
3462 }
3463
3464 /**********************************************************************
3465  _samr_EnumDomains
3466  **********************************************************************/
3467
3468 NTSTATUS _samr_EnumDomains(pipes_struct *p,
3469                            struct samr_EnumDomains *r)
3470 {
3471         NTSTATUS status;
3472         struct samr_info *info;
3473         uint32_t num_entries = 2;
3474         struct samr_SamEntry *entry_array = NULL;
3475         struct samr_SamArray *sam;
3476
3477         if (!find_policy_by_hnd(p, r->in.connect_handle, (void**)(void *)&info))
3478                 return NT_STATUS_INVALID_HANDLE;
3479
3480         status = access_check_samr_function(info->acc_granted,
3481                                             SA_RIGHT_SAM_ENUM_DOMAINS,
3482                                             "_samr_EnumDomains");
3483         if (!NT_STATUS_IS_OK(status)) {
3484                 return status;
3485         }
3486
3487         sam = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
3488         if (!sam) {
3489                 return NT_STATUS_NO_MEMORY;
3490         }
3491
3492         entry_array = TALLOC_ZERO_ARRAY(p->mem_ctx,
3493                                         struct samr_SamEntry,
3494                                         num_entries);
3495         if (!entry_array) {
3496                 return NT_STATUS_NO_MEMORY;
3497         }
3498
3499         entry_array[0].idx = 0;
3500         init_lsa_String(&entry_array[0].name, get_global_sam_name());
3501
3502         entry_array[1].idx = 1;
3503         init_lsa_String(&entry_array[1].name, "Builtin");
3504
3505         sam->count = num_entries;
3506         sam->entries = entry_array;
3507
3508         *r->out.sam = sam;
3509         *r->out.num_entries = num_entries;
3510
3511         return status;
3512 }
3513
3514 /*******************************************************************
3515  _samr_OpenAlias
3516  ********************************************************************/
3517
3518 NTSTATUS _samr_OpenAlias(pipes_struct *p,
3519                          struct samr_OpenAlias *r)
3520 {
3521         DOM_SID sid;
3522         POLICY_HND domain_pol = *r->in.domain_handle;
3523         uint32 alias_rid = r->in.rid;
3524         POLICY_HND *alias_pol = r->out.alias_handle;
3525         struct    samr_info *info = NULL;
3526         SEC_DESC *psd = NULL;
3527         uint32    acc_granted;
3528         uint32    des_access = r->in.access_mask;
3529         size_t    sd_size;
3530         NTSTATUS  status;
3531         SE_PRIV se_rights;
3532
3533         /* find the domain policy and get the SID / access bits stored in the domain policy */
3534
3535         if ( !get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted, NULL) )
3536                 return NT_STATUS_INVALID_HANDLE;
3537
3538         status = access_check_samr_function(acc_granted,
3539                                             SA_RIGHT_DOMAIN_OPEN_ACCOUNT,
3540                                             "_samr_OpenAlias");
3541
3542         if ( !NT_STATUS_IS_OK(status) )
3543                 return status;
3544
3545         /* append the alias' RID to it */
3546
3547         if (!sid_append_rid(&sid, alias_rid))
3548                 return NT_STATUS_NO_SUCH_ALIAS;
3549
3550         /*check if access can be granted as requested by client. */
3551
3552         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &ali_generic_mapping, NULL, 0);
3553         se_map_generic(&des_access,&ali_generic_mapping);
3554
3555         se_priv_copy( &se_rights, &se_add_users );
3556
3557
3558         status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3559                 &se_rights, GENERIC_RIGHTS_ALIAS_WRITE, des_access,
3560                 &acc_granted, "_samr_OpenAlias");
3561
3562         if ( !NT_STATUS_IS_OK(status) )
3563                 return status;
3564
3565         {
3566                 /* Check we actually have the requested alias */
3567                 enum lsa_SidType type;
3568                 bool result;
3569                 gid_t gid;
3570
3571                 become_root();
3572                 result = lookup_sid(NULL, &sid, NULL, NULL, &type);
3573                 unbecome_root();
3574
3575                 if (!result || (type != SID_NAME_ALIAS)) {
3576                         return NT_STATUS_NO_SUCH_ALIAS;
3577                 }
3578
3579                 /* make sure there is a mapping */
3580
3581                 if ( !sid_to_gid( &sid, &gid ) ) {
3582                         return NT_STATUS_NO_SUCH_ALIAS;
3583                 }
3584
3585         }
3586
3587         /* associate the alias SID with the new handle. */
3588         if ((info = get_samr_info_by_sid(&sid)) == NULL)
3589                 return NT_STATUS_NO_MEMORY;
3590
3591         info->acc_granted = acc_granted;
3592
3593         /* get a (unique) handle.  open a policy on it. */
3594         if (!create_policy_hnd(p, alias_pol, free_samr_info, (void *)info))
3595                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3596
3597         return NT_STATUS_OK;
3598 }
3599
3600 /*******************************************************************
3601  set_user_info_7
3602  ********************************************************************/
3603
3604 static NTSTATUS set_user_info_7(TALLOC_CTX *mem_ctx,
3605                                 struct samr_UserInfo7 *id7,
3606                                 struct samu *pwd)
3607 {
3608         NTSTATUS rc;
3609
3610         if (id7 == NULL) {
3611                 DEBUG(5, ("set_user_info_7: NULL id7\n"));
3612                 TALLOC_FREE(pwd);
3613                 return NT_STATUS_ACCESS_DENIED;
3614         }
3615
3616         if (!id7->account_name.string) {
3617                 DEBUG(5, ("set_user_info_7: failed to get new username\n"));
3618                 TALLOC_FREE(pwd);
3619                 return NT_STATUS_ACCESS_DENIED;
3620         }
3621
3622         /* check to see if the new username already exists.  Note: we can't
3623            reliably lock all backends, so there is potentially the
3624            possibility that a user can be created in between this check and
3625            the rename.  The rename should fail, but may not get the
3626            exact same failure status code.  I think this is small enough
3627            of a window for this type of operation and the results are
3628            simply that the rename fails with a slightly different status
3629            code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
3630
3631         rc = can_create(mem_ctx, id7->account_name.string);
3632         if (!NT_STATUS_IS_OK(rc)) {
3633                 return rc;
3634         }
3635
3636         rc = pdb_rename_sam_account(pwd, id7->account_name.string);
3637
3638         TALLOC_FREE(pwd);
3639         return rc;
3640 }
3641
3642 /*******************************************************************
3643  set_user_info_16
3644  ********************************************************************/
3645
3646 static bool set_user_info_16(struct samr_UserInfo16 *id16,
3647                              struct samu *pwd)
3648 {
3649         if (id16 == NULL) {
3650                 DEBUG(5, ("set_user_info_16: NULL id16\n"));
3651                 TALLOC_FREE(pwd);
3652                 return False;
3653         }
3654
3655         /* FIX ME: check if the value is really changed --metze */
3656         if (!pdb_set_acct_ctrl(pwd, id16->acct_flags, PDB_CHANGED)) {
3657                 TALLOC_FREE(pwd);
3658                 return False;
3659         }
3660
3661         if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3662                 TALLOC_FREE(pwd);
3663                 return False;
3664         }
3665
3666         TALLOC_FREE(pwd);
3667
3668         return True;
3669 }
3670
3671 /*******************************************************************
3672  set_user_info_18
3673  ********************************************************************/
3674
3675 static bool set_user_info_18(struct samr_UserInfo18 *id18,
3676                              struct samu *pwd)
3677 {
3678         if (id18 == NULL) {
3679                 DEBUG(2, ("set_user_info_18: id18 is NULL\n"));
3680                 TALLOC_FREE(pwd);
3681                 return False;
3682         }
3683
3684         if (!pdb_set_lanman_passwd (pwd, id18->lm_pwd.hash, PDB_CHANGED)) {
3685                 TALLOC_FREE(pwd);
3686                 return False;
3687         }
3688         if (!pdb_set_nt_passwd     (pwd, id18->nt_pwd.hash, PDB_CHANGED)) {
3689                 TALLOC_FREE(pwd);
3690                 return False;
3691         }
3692         if (!pdb_set_pass_last_set_time (pwd, time(NULL), PDB_CHANGED)) {
3693                 TALLOC_FREE(pwd);
3694                 return False;
3695         }
3696
3697         if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3698                 TALLOC_FREE(pwd);
3699                 return False;
3700         }
3701
3702         TALLOC_FREE(pwd);
3703         return True;
3704 }
3705
3706 /*******************************************************************
3707  set_user_info_20
3708  ********************************************************************/
3709
3710 static bool set_user_info_20(struct samr_UserInfo20 *id20,
3711                              struct samu *pwd)
3712 {
3713         if (id20 == NULL) {
3714                 DEBUG(5, ("set_user_info_20: NULL id20\n"));
3715                 return False;
3716         }
3717
3718         copy_id20_to_sam_passwd(pwd, id20);
3719
3720         /* write the change out */
3721         if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3722                 TALLOC_FREE(pwd);
3723                 return False;
3724         }
3725
3726         TALLOC_FREE(pwd);
3727
3728         return True;
3729 }
3730
3731 /*******************************************************************
3732  set_user_info_21
3733  ********************************************************************/
3734
3735 static NTSTATUS set_user_info_21(TALLOC_CTX *mem_ctx,
3736                                  struct samr_UserInfo21 *id21,
3737                                  struct samu *pwd)
3738 {
3739         NTSTATUS status;
3740
3741         if (id21 == NULL) {
3742                 DEBUG(5, ("set_user_info_21: NULL id21\n"));
3743                 return NT_STATUS_INVALID_PARAMETER;
3744         }
3745
3746         /* we need to separately check for an account rename first */
3747
3748         if (id21->account_name.string &&
3749             (!strequal(id21->account_name.string, pdb_get_username(pwd))))
3750         {
3751
3752                 /* check to see if the new username already exists.  Note: we can't
3753                    reliably lock all backends, so there is potentially the
3754                    possibility that a user can be created in between this check and
3755                    the rename.  The rename should fail, but may not get the
3756                    exact same failure status code.  I think this is small enough
3757                    of a window for this type of operation and the results are
3758                    simply that the rename fails with a slightly different status
3759                    code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
3760
3761                 status = can_create(mem_ctx, id21->account_name.string);
3762                 if (!NT_STATUS_IS_OK(status)) {
3763                         return status;
3764                 }
3765
3766                 status = pdb_rename_sam_account(pwd, id21->account_name.string);
3767
3768                 if (!NT_STATUS_IS_OK(status)) {
3769                         DEBUG(0,("set_user_info_21: failed to rename account: %s\n",
3770                                 nt_errstr(status)));
3771                         TALLOC_FREE(pwd);
3772                         return status;
3773                 }
3774
3775                 /* set the new username so that later
3776                    functions can work on the new account&