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