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