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