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