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