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