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