Collect all init_lsa_string varients in one place.
[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         }
2480
2481
2482         account_name = talloc_strdup(mem_ctx, pdb_get_username(pw));
2483         full_name = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2484         home_directory = talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2485         home_drive = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2486         logon_script = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2487         profile_path = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2488         description = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2489         workstations = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2490         comment = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2491
2492         logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2493 #if 0
2494
2495         /*
2496           Look at a user on a real NT4 PDC with usrmgr, press
2497           'ok'. Then you will see that fields_present is set to
2498           0x08f827fa. Look at the user immediately after that again,
2499           and you will see that 0x00fffff is returned. This solves
2500           the problem that you get access denied after having looked
2501           at the user.
2502           -- Volker
2503         */
2504
2505 #if 0
2506         init_unistr2_from_datablob(&usr->uni_munged_dial, &munged_dial_blob);
2507         init_uni_hdr(&usr->hdr_munged_dial, &usr->uni_munged_dial);
2508         data_blob_free(&munged_dial_blob);
2509 #endif
2510 #endif
2511
2512         init_samr_user_info21(r,
2513                               last_logon,
2514                               last_logoff,
2515                               last_password_change,
2516                               acct_expiry,
2517                               allow_password_change,
2518                               force_password_change,
2519                               account_name,
2520                               full_name,
2521                               home_directory,
2522                               home_drive,
2523                               logon_script,
2524                               profile_path,
2525                               description,
2526                               workstations,
2527                               comment,
2528                               parameters,
2529                               rid,
2530                               primary_gid,
2531                               pdb_get_acct_ctrl(pw),
2532                               pdb_build_fields_present(pw),
2533                               logon_hours,
2534                               pdb_get_bad_password_count(pw),
2535                               pdb_get_logon_count(pw),
2536                               0, //country_code,
2537                               0, //code_page,
2538                               0, //nt_password_set,
2539                               0, //lm_password_set,
2540                               password_expired);
2541         TALLOC_FREE(pw);
2542
2543         return NT_STATUS_OK;
2544 }
2545
2546 /*******************************************************************
2547  _samr_QueryUserInfo
2548  ********************************************************************/
2549
2550 NTSTATUS _samr_QueryUserInfo(pipes_struct *p,
2551                              struct samr_QueryUserInfo *r)
2552 {
2553         NTSTATUS status;
2554         union samr_UserInfo *user_info = NULL;
2555         struct samr_info *info = NULL;
2556         DOM_SID domain_sid;
2557         uint32 rid;
2558
2559         /* search for the handle */
2560         if (!find_policy_by_hnd(p, r->in.user_handle, (void **)(void *)&info))
2561                 return NT_STATUS_INVALID_HANDLE;
2562
2563         domain_sid = info->sid;
2564
2565         sid_split_rid(&domain_sid, &rid);
2566
2567         if (!sid_check_is_in_our_domain(&info->sid))
2568                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2569
2570         DEBUG(5,("_samr_QueryUserInfo: sid:%s\n",
2571                  sid_string_dbg(&info->sid)));
2572
2573         user_info = TALLOC_ZERO_P(p->mem_ctx, union samr_UserInfo);
2574         if (!user_info) {
2575                 return NT_STATUS_NO_MEMORY;
2576         }
2577
2578         DEBUG(5,("_samr_QueryUserInfo: user info level: %d\n", r->in.level));
2579
2580         switch (r->in.level) {
2581         case 7:
2582                 status = get_user_info_7(p->mem_ctx, &user_info->info7, &info->sid);
2583                 if (!NT_STATUS_IS_OK(status)) {
2584                         return status;
2585                 }
2586                 break;
2587         case 9:
2588                 status = get_user_info_9(p->mem_ctx, &user_info->info9, &info->sid);
2589                 if (!NT_STATUS_IS_OK(status)) {
2590                         return status;
2591                 }
2592                 break;
2593         case 16:
2594                 status = get_user_info_16(p->mem_ctx, &user_info->info16, &info->sid);
2595                 if (!NT_STATUS_IS_OK(status)) {
2596                         return status;
2597                 }
2598                 break;
2599
2600         case 18:
2601                 status = get_user_info_18(p, p->mem_ctx, &user_info->info18, &info->sid);
2602                 if (!NT_STATUS_IS_OK(status)) {
2603                         return status;
2604                 }
2605                 break;
2606
2607         case 20:
2608                 status = get_user_info_20(p->mem_ctx, &user_info->info20, &info->sid);
2609                 if (!NT_STATUS_IS_OK(status)) {
2610                         return status;
2611                 }
2612                 break;
2613
2614         case 21:
2615                 status = get_user_info_21(p->mem_ctx, &user_info->info21,
2616                                           &info->sid, &domain_sid);
2617                 if (!NT_STATUS_IS_OK(status)) {
2618                         return status;
2619                 }
2620                 break;
2621
2622         default:
2623                 return NT_STATUS_INVALID_INFO_CLASS;
2624         }
2625
2626         *r->out.info = user_info;
2627
2628         DEBUG(5,("_samr_QueryUserInfo: %d\n", __LINE__));
2629
2630         return status;
2631 }
2632
2633 /*******************************************************************
2634  _samr_GetGroupsForUser
2635  ********************************************************************/
2636
2637 NTSTATUS _samr_GetGroupsForUser(pipes_struct *p,
2638                                 struct samr_GetGroupsForUser *r)
2639 {
2640         struct samu *sam_pass=NULL;
2641         DOM_SID  sid;
2642         DOM_SID *sids;
2643         struct samr_RidWithAttribute dom_gid;
2644         struct samr_RidWithAttribute *gids = NULL;
2645         uint32 primary_group_rid;
2646         size_t num_groups = 0;
2647         gid_t *unix_gids;
2648         size_t i, num_gids;
2649         uint32 acc_granted;
2650         bool ret;
2651         NTSTATUS result;
2652         bool success = False;
2653
2654         struct samr_RidWithAttributeArray *rids = NULL;
2655
2656         /*
2657          * from the SID in the request:
2658          * we should send back the list of DOMAIN GROUPS
2659          * the user is a member of
2660          *
2661          * and only the DOMAIN GROUPS
2662          * no ALIASES !!! neither aliases of the domain
2663          * nor aliases of the builtin SID
2664          *
2665          * JFM, 12/2/2001
2666          */
2667
2668         DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
2669
2670         rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidWithAttributeArray);
2671         if (!rids) {
2672                 return NT_STATUS_NO_MEMORY;
2673         }
2674
2675         /* find the policy handle.  open a policy on it. */
2676         if (!get_lsa_policy_samr_sid(p, r->in.user_handle, &sid, &acc_granted, NULL))
2677                 return NT_STATUS_INVALID_HANDLE;
2678
2679         result = access_check_samr_function(acc_granted,
2680                                             SA_RIGHT_USER_GET_GROUPS,
2681                                             "_samr_GetGroupsForUser");
2682         if (!NT_STATUS_IS_OK(result)) {
2683                 return result;
2684         }
2685
2686         if (!sid_check_is_in_our_domain(&sid))
2687                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2688
2689         if ( !(sam_pass = samu_new( p->mem_ctx )) ) {
2690                 return NT_STATUS_NO_MEMORY;
2691         }
2692
2693         become_root();
2694         ret = pdb_getsampwsid(sam_pass, &sid);
2695         unbecome_root();
2696
2697         if (!ret) {
2698                 DEBUG(10, ("pdb_getsampwsid failed for %s\n",
2699                            sid_string_dbg(&sid)));
2700                 return NT_STATUS_NO_SUCH_USER;
2701         }
2702
2703         sids = NULL;
2704
2705         /* make both calls inside the root block */
2706         become_root();
2707         result = pdb_enum_group_memberships(p->mem_ctx, sam_pass,
2708                                             &sids, &unix_gids, &num_groups);
2709         if ( NT_STATUS_IS_OK(result) ) {
2710                 success = sid_peek_check_rid(get_global_sam_sid(),
2711                                              pdb_get_group_sid(sam_pass),
2712                                              &primary_group_rid);
2713         }
2714         unbecome_root();
2715
2716         if (!NT_STATUS_IS_OK(result)) {
2717                 DEBUG(10, ("pdb_enum_group_memberships failed for %s\n",
2718                            sid_string_dbg(&sid)));
2719                 return result;
2720         }
2721
2722         if ( !success ) {
2723                 DEBUG(5, ("Group sid %s for user %s not in our domain\n",
2724                           sid_string_dbg(pdb_get_group_sid(sam_pass)),
2725                           pdb_get_username(sam_pass)));
2726                 TALLOC_FREE(sam_pass);
2727                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2728         }
2729
2730         gids = NULL;
2731         num_gids = 0;
2732
2733         dom_gid.attributes = (SE_GROUP_MANDATORY|SE_GROUP_ENABLED_BY_DEFAULT|
2734                               SE_GROUP_ENABLED);
2735         dom_gid.rid = primary_group_rid;
2736         ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
2737
2738         for (i=0; i<num_groups; i++) {
2739
2740                 if (!sid_peek_check_rid(get_global_sam_sid(),
2741                                         &(sids[i]), &dom_gid.rid)) {
2742                         DEBUG(10, ("Found sid %s not in our domain\n",
2743                                    sid_string_dbg(&sids[i])));
2744                         continue;
2745                 }
2746
2747                 if (dom_gid.rid == primary_group_rid) {
2748                         /* We added the primary group directly from the
2749                          * sam_account. The other SIDs are unique from
2750                          * enum_group_memberships */
2751                         continue;
2752                 }
2753
2754                 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
2755         }
2756
2757         rids->count = num_gids;
2758         rids->rids = gids;
2759
2760         *r->out.rids = rids;
2761
2762         DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
2763
2764         return result;
2765 }
2766
2767 /*******************************************************************
2768  samr_QueryDomainInfo_internal
2769  ********************************************************************/
2770
2771 static NTSTATUS samr_QueryDomainInfo_internal(const char *fn_name,
2772                                               pipes_struct *p,
2773                                               struct policy_handle *handle,
2774                                               uint32_t level,
2775                                               union samr_DomainInfo **dom_info_ptr)
2776 {
2777         NTSTATUS status = NT_STATUS_OK;
2778         struct samr_info *info = NULL;
2779         union samr_DomainInfo *dom_info;
2780         uint32 min_pass_len,pass_hist,password_properties;
2781         time_t u_expire, u_min_age;
2782         NTTIME nt_expire, nt_min_age;
2783
2784         time_t u_lock_duration, u_reset_time;
2785         NTTIME nt_lock_duration, nt_reset_time;
2786         uint32 lockout;
2787         time_t u_logout;
2788         NTTIME nt_logout;
2789
2790         uint32 account_policy_temp;
2791
2792         time_t seq_num;
2793         uint32 server_role;
2794
2795         uint32 num_users=0, num_groups=0, num_aliases=0;
2796
2797         DEBUG(5,("%s: %d\n", fn_name, __LINE__));
2798
2799         dom_info = TALLOC_ZERO_P(p->mem_ctx, union samr_DomainInfo);
2800         if (!dom_info) {
2801                 return NT_STATUS_NO_MEMORY;
2802         }
2803
2804         *dom_info_ptr = dom_info;
2805
2806         /* find the policy handle.  open a policy on it. */
2807         if (!find_policy_by_hnd(p, handle, (void **)(void *)&info)) {
2808                 return NT_STATUS_INVALID_HANDLE;
2809         }
2810
2811         switch (level) {
2812                 case 0x01:
2813
2814                         become_root();
2815
2816                         /* AS ROOT !!! */
2817
2818                         pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &account_policy_temp);
2819                         min_pass_len = account_policy_temp;
2820
2821                         pdb_get_account_policy(AP_PASSWORD_HISTORY, &account_policy_temp);
2822                         pass_hist = account_policy_temp;
2823
2824                         pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
2825                         password_properties = account_policy_temp;
2826
2827                         pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
2828                         u_expire = account_policy_temp;
2829
2830                         pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
2831                         u_min_age = account_policy_temp;
2832
2833                         /* !AS ROOT */
2834
2835                         unbecome_root();
2836
2837                         unix_to_nt_time_abs(&nt_expire, u_expire);
2838                         unix_to_nt_time_abs(&nt_min_age, u_min_age);
2839
2840                         init_samr_DomInfo1(&dom_info->info1,
2841                                            (uint16)min_pass_len,
2842                                            (uint16)pass_hist,
2843                                            password_properties,
2844                                            nt_expire,
2845                                            nt_min_age);
2846                         break;
2847                 case 0x02:
2848
2849                         become_root();
2850
2851                         /* AS ROOT !!! */
2852
2853                         num_users = count_sam_users(info->disp_info, ACB_NORMAL);
2854                         num_groups = count_sam_groups(info->disp_info);
2855                         num_aliases = count_sam_aliases(info->disp_info);
2856
2857                         pdb_get_account_policy(AP_TIME_TO_LOGOUT, &account_policy_temp);
2858                         u_logout = account_policy_temp;
2859
2860                         unix_to_nt_time_abs(&nt_logout, u_logout);
2861
2862                         if (!pdb_get_seq_num(&seq_num))
2863                                 seq_num = time(NULL);
2864
2865                         /* !AS ROOT */
2866
2867                         unbecome_root();
2868
2869                         server_role = ROLE_DOMAIN_PDC;
2870                         if (lp_server_role() == ROLE_DOMAIN_BDC)
2871                                 server_role = ROLE_DOMAIN_BDC;
2872
2873                         init_samr_DomInfo2(&dom_info->info2,
2874                                            nt_logout,
2875                                            lp_serverstring(),
2876                                            lp_workgroup(),
2877                                            global_myname(),
2878                                            seq_num,
2879                                            1,
2880                                            server_role,
2881                                            1,
2882                                            num_users,
2883                                            num_groups,
2884                                            num_aliases);
2885                         break;
2886                 case 0x03:
2887
2888                         become_root();
2889
2890                         /* AS ROOT !!! */
2891
2892                         {
2893                                 uint32 ul;
2894                                 pdb_get_account_policy(AP_TIME_TO_LOGOUT, &ul);
2895                                 u_logout = (time_t)ul;
2896                         }
2897
2898                         /* !AS ROOT */
2899
2900                         unbecome_root();
2901
2902                         unix_to_nt_time_abs(&nt_logout, u_logout);
2903
2904                         init_samr_DomInfo3(&dom_info->info3,
2905                                            nt_logout);
2906
2907                         break;
2908                 case 0x04:
2909                         init_samr_DomInfo4(&dom_info->info4,
2910                                            lp_serverstring());
2911                         break;
2912                 case 0x05:
2913                         init_samr_DomInfo5(&dom_info->info5,
2914                                            get_global_sam_name());
2915                         break;
2916                 case 0x06:
2917                         /* NT returns its own name when a PDC. win2k and later
2918                          * only the name of the PDC if itself is a BDC (samba4
2919                          * idl) */
2920                         init_samr_DomInfo6(&dom_info->info6,
2921                                            global_myname());
2922                         break;
2923                 case 0x07:
2924                         server_role = ROLE_DOMAIN_PDC;
2925                         if (lp_server_role() == ROLE_DOMAIN_BDC)
2926                                 server_role = ROLE_DOMAIN_BDC;
2927
2928                         init_samr_DomInfo7(&dom_info->info7,
2929                                            server_role);
2930                         break;
2931                 case 0x08:
2932
2933                         become_root();
2934
2935                         /* AS ROOT !!! */
2936
2937                         if (!pdb_get_seq_num(&seq_num)) {
2938                                 seq_num = time(NULL);
2939                         }
2940
2941                         /* !AS ROOT */
2942
2943                         unbecome_root();
2944
2945                         init_samr_DomInfo8(&dom_info->info8,
2946                                            seq_num,
2947                                            0);
2948                         break;
2949                 case 0x0c:
2950
2951                         become_root();
2952
2953                         /* AS ROOT !!! */
2954
2955                         pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
2956                         u_lock_duration = account_policy_temp;
2957                         if (u_lock_duration != -1) {
2958                                 u_lock_duration *= 60;
2959                         }
2960
2961                         pdb_get_account_policy(AP_RESET_COUNT_TIME, &account_policy_temp);
2962                         u_reset_time = account_policy_temp * 60;
2963
2964                         pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
2965                         lockout = account_policy_temp;
2966
2967                         /* !AS ROOT */
2968
2969                         unbecome_root();
2970
2971                         unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
2972                         unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
2973
2974                         init_samr_DomInfo12(&dom_info->info12,
2975                                             nt_lock_duration,
2976                                             nt_reset_time,
2977                                             (uint16)lockout);
2978                         break;
2979                 default:
2980                         return NT_STATUS_INVALID_INFO_CLASS;
2981         }
2982
2983         DEBUG(5,("%s: %d\n", fn_name, __LINE__));
2984
2985         return status;
2986 }
2987
2988 /*******************************************************************
2989  _samr_QueryDomainInfo
2990  ********************************************************************/
2991
2992 NTSTATUS _samr_QueryDomainInfo(pipes_struct *p,
2993                                struct samr_QueryDomainInfo *r)
2994 {
2995         return samr_QueryDomainInfo_internal("_samr_QueryDomainInfo",
2996                                              p,
2997                                              r->in.domain_handle,
2998                                              r->in.level,
2999                                              r->out.info);
3000 }
3001
3002 /* W2k3 seems to use the same check for all 3 objects that can be created via
3003  * SAMR, if you try to create for example "Dialup" as an alias it says
3004  * "NT_STATUS_USER_EXISTS". This is racy, but we can't really lock the user
3005  * database. */
3006
3007 static NTSTATUS can_create(TALLOC_CTX *mem_ctx, const char *new_name)
3008 {
3009         enum lsa_SidType type;
3010         bool result;
3011
3012         DEBUG(10, ("Checking whether [%s] can be created\n", new_name));
3013
3014         become_root();
3015         /* Lookup in our local databases (LOOKUP_NAME_REMOTE not set)
3016          * whether the name already exists */
3017         result = lookup_name(mem_ctx, new_name, LOOKUP_NAME_LOCAL,
3018                              NULL, NULL, NULL, &type);
3019         unbecome_root();
3020
3021         if (!result) {
3022                 DEBUG(10, ("%s does not exist, can create it\n", new_name));
3023                 return NT_STATUS_OK;
3024         }
3025
3026         DEBUG(5, ("trying to create %s, exists as %s\n",
3027                   new_name, sid_type_lookup(type)));
3028
3029         if (type == SID_NAME_DOM_GRP) {
3030                 return NT_STATUS_GROUP_EXISTS;
3031         }
3032         if (type == SID_NAME_ALIAS) {
3033                 return NT_STATUS_ALIAS_EXISTS;
3034         }
3035
3036         /* Yes, the default is NT_STATUS_USER_EXISTS */
3037         return NT_STATUS_USER_EXISTS;
3038 }
3039
3040 /*******************************************************************
3041  _samr_CreateUser2
3042  ********************************************************************/
3043
3044 NTSTATUS _samr_CreateUser2(pipes_struct *p,
3045                            struct samr_CreateUser2 *r)
3046 {
3047         const char *account = NULL;
3048         DOM_SID sid;
3049         POLICY_HND dom_pol = *r->in.domain_handle;
3050         uint32_t acb_info = r->in.acct_flags;
3051         POLICY_HND *user_pol = r->out.user_handle;
3052         struct samr_info *info = NULL;
3053         NTSTATUS nt_status;
3054         uint32 acc_granted;
3055         SEC_DESC *psd;
3056         size_t    sd_size;
3057         /* check this, when giving away 'add computer to domain' privs */
3058         uint32    des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
3059         bool can_add_account = False;
3060         SE_PRIV se_rights;
3061         DISP_INFO *disp_info = NULL;
3062
3063         /* Get the domain SID stored in the domain policy */
3064         if (!get_lsa_policy_samr_sid(p, &dom_pol, &sid, &acc_granted,
3065                                      &disp_info))
3066                 return NT_STATUS_INVALID_HANDLE;
3067
3068         nt_status = access_check_samr_function(acc_granted,
3069                                                SA_RIGHT_DOMAIN_CREATE_USER,
3070                                                "_samr_CreateUser2");
3071         if (!NT_STATUS_IS_OK(nt_status)) {
3072                 return nt_status;
3073         }
3074
3075         if (!(acb_info == ACB_NORMAL || acb_info == ACB_DOMTRUST ||
3076               acb_info == ACB_WSTRUST || acb_info == ACB_SVRTRUST)) {
3077                 /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if
3078                    this parameter is not an account type */
3079                 return NT_STATUS_INVALID_PARAMETER;
3080         }
3081
3082         account = r->in.account_name->string;
3083         if (account == NULL) {
3084                 return NT_STATUS_NO_MEMORY;
3085         }
3086
3087         nt_status = can_create(p->mem_ctx, account);
3088         if (!NT_STATUS_IS_OK(nt_status)) {
3089                 return nt_status;
3090         }
3091
3092         /* determine which user right we need to check based on the acb_info */
3093
3094         if ( acb_info & ACB_WSTRUST )
3095         {
3096                 se_priv_copy( &se_rights, &se_machine_account );
3097                 can_add_account = user_has_privileges(
3098                         p->pipe_user.nt_user_token, &se_rights );
3099         }
3100         /* usrmgr.exe (and net rpc trustdom grant) creates a normal user
3101            account for domain trusts and changes the ACB flags later */
3102         else if ( acb_info & ACB_NORMAL &&
3103                   (account[strlen(account)-1] != '$') )
3104         {
3105                 se_priv_copy( &se_rights, &se_add_users );
3106                 can_add_account = user_has_privileges(
3107                         p->pipe_user.nt_user_token, &se_rights );
3108         }
3109         else    /* implicit assumption of a BDC or domain trust account here
3110                  * (we already check the flags earlier) */
3111         {
3112                 if ( lp_enable_privileges() ) {
3113                         /* only Domain Admins can add a BDC or domain trust */
3114                         se_priv_copy( &se_rights, &se_priv_none );
3115                         can_add_account = nt_token_check_domain_rid(
3116                                 p->pipe_user.nt_user_token,
3117                                 DOMAIN_GROUP_RID_ADMINS );
3118                 }
3119         }
3120
3121         DEBUG(5, ("_samr_CreateUser2: %s can add this account : %s\n",
3122                   uidtoname(p->pipe_user.ut.uid),
3123                   can_add_account ? "True":"False" ));
3124
3125         /********** BEGIN Admin BLOCK **********/
3126
3127         if ( can_add_account )
3128                 become_root();
3129
3130         nt_status = pdb_create_user(p->mem_ctx, account, acb_info,
3131                                     r->out.rid);
3132
3133         if ( can_add_account )
3134                 unbecome_root();
3135
3136         /********** END Admin BLOCK **********/
3137
3138         /* now check for failure */
3139
3140         if ( !NT_STATUS_IS_OK(nt_status) )
3141                 return nt_status;
3142
3143         /* Get the user's SID */
3144
3145         sid_compose(&sid, get_global_sam_sid(), *r->out.rid);
3146
3147         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping,
3148                             &sid, SAMR_USR_RIGHTS_WRITE_PW);
3149         se_map_generic(&des_access, &usr_generic_mapping);
3150
3151         nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3152                 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
3153                 &acc_granted, "_samr_CreateUser2");
3154
3155         if ( !NT_STATUS_IS_OK(nt_status) ) {
3156                 return nt_status;
3157         }
3158
3159         /* associate the user's SID with the new handle. */
3160         if ((info = get_samr_info_by_sid(&sid)) == NULL) {
3161                 return NT_STATUS_NO_MEMORY;
3162         }
3163
3164         ZERO_STRUCTP(info);
3165         info->sid = sid;
3166         info->acc_granted = acc_granted;
3167
3168         /* get a (unique) handle.  open a policy on it. */
3169         if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info)) {
3170                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3171         }
3172
3173         /* After a "set" ensure we have no cached display info. */
3174         force_flush_samr_cache(info->disp_info);
3175
3176         *r->out.access_granted = acc_granted;
3177
3178         return NT_STATUS_OK;
3179 }
3180
3181 /*******************************************************************
3182  _samr_Connect
3183  ********************************************************************/
3184
3185 NTSTATUS _samr_Connect(pipes_struct *p,
3186                        struct samr_Connect *r)
3187 {
3188         struct samr_info *info = NULL;
3189         uint32    des_access = r->in.access_mask;
3190
3191         /* Access check */
3192
3193         if (!pipe_access_check(p)) {
3194                 DEBUG(3, ("access denied to _samr_Connect\n"));
3195                 return NT_STATUS_ACCESS_DENIED;
3196         }
3197
3198         /* set up the SAMR connect_anon response */
3199
3200         /* associate the user's SID with the new handle. */
3201         if ((info = get_samr_info_by_sid(NULL)) == NULL)
3202                 return NT_STATUS_NO_MEMORY;
3203
3204         /* don't give away the farm but this is probably ok.  The SA_RIGHT_SAM_ENUM_DOMAINS
3205            was observed from a win98 client trying to enumerate users (when configured
3206            user level access control on shares)   --jerry */
3207
3208         if (des_access == MAXIMUM_ALLOWED_ACCESS) {
3209                 /* Map to max possible knowing we're filtered below. */
3210                 des_access = GENERIC_ALL_ACCESS;
3211         }
3212
3213         se_map_generic( &des_access, &sam_generic_mapping );
3214         info->acc_granted = des_access & (SA_RIGHT_SAM_ENUM_DOMAINS|SA_RIGHT_SAM_OPEN_DOMAIN);
3215
3216         /* get a (unique) handle.  open a policy on it. */
3217         if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info))
3218                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3219
3220         return NT_STATUS_OK;
3221 }
3222
3223 /*******************************************************************
3224  _samr_Connect2
3225  ********************************************************************/
3226
3227 NTSTATUS _samr_Connect2(pipes_struct *p,
3228                         struct samr_Connect2 *r)
3229 {
3230         struct samr_info *info = NULL;
3231         SEC_DESC *psd = NULL;
3232         uint32    acc_granted;
3233         uint32    des_access = r->in.access_mask;
3234         NTSTATUS  nt_status;
3235         size_t    sd_size;
3236
3237
3238         DEBUG(5,("_samr_Connect2: %d\n", __LINE__));
3239
3240         /* Access check */
3241
3242         if (!pipe_access_check(p)) {
3243                 DEBUG(3, ("access denied to _samr_Connect2\n"));
3244                 return NT_STATUS_ACCESS_DENIED;
3245         }
3246
3247         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
3248         se_map_generic(&des_access, &sam_generic_mapping);
3249
3250         nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3251                 NULL, 0, des_access, &acc_granted, "_samr_Connect2");
3252
3253         if ( !NT_STATUS_IS_OK(nt_status) )
3254                 return nt_status;
3255
3256         /* associate the user's SID and access granted with the new handle. */
3257         if ((info = get_samr_info_by_sid(NULL)) == NULL)
3258                 return NT_STATUS_NO_MEMORY;
3259
3260         info->acc_granted = acc_granted;
3261         info->status = r->in.access_mask; /* this looks so wrong... - gd */
3262
3263         /* get a (unique) handle.  open a policy on it. */
3264         if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info))
3265                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3266
3267         DEBUG(5,("_samr_Connect2: %d\n", __LINE__));
3268
3269         return nt_status;
3270 }
3271
3272 /*******************************************************************
3273  _samr_Connect4
3274  ********************************************************************/
3275
3276 NTSTATUS _samr_Connect4(pipes_struct *p,
3277                         struct samr_Connect4 *r)
3278 {
3279         struct samr_info *info = NULL;
3280         SEC_DESC *psd = NULL;
3281         uint32    acc_granted;
3282         uint32    des_access = r->in.access_mask;
3283         NTSTATUS  nt_status;
3284         size_t    sd_size;
3285
3286
3287         DEBUG(5,("_samr_Connect4: %d\n", __LINE__));
3288
3289         /* Access check */
3290
3291         if (!pipe_access_check(p)) {
3292                 DEBUG(3, ("access denied to samr_Connect4\n"));
3293                 return NT_STATUS_ACCESS_DENIED;
3294         }
3295
3296         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
3297         se_map_generic(&des_access, &sam_generic_mapping);
3298
3299         nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3300                 NULL, 0, des_access, &acc_granted, "_samr_Connect4");
3301
3302         if ( !NT_STATUS_IS_OK(nt_status) )
3303                 return nt_status;
3304
3305         /* associate the user's SID and access granted with the new handle. */
3306         if ((info = get_samr_info_by_sid(NULL)) == NULL)
3307                 return NT_STATUS_NO_MEMORY;
3308
3309         info->acc_granted = acc_granted;
3310         info->status = r->in.access_mask; /* ??? */
3311
3312         /* get a (unique) handle.  open a policy on it. */
3313         if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info))
3314                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3315
3316         DEBUG(5,("_samr_Connect4: %d\n", __LINE__));
3317
3318         return NT_STATUS_OK;
3319 }
3320
3321 /*******************************************************************
3322  _samr_Connect5
3323  ********************************************************************/
3324
3325 NTSTATUS _samr_Connect5(pipes_struct *p,
3326                         struct samr_Connect5 *r)
3327 {
3328         struct samr_info *info = NULL;
3329         SEC_DESC *psd = NULL;
3330         uint32    acc_granted;
3331         uint32    des_access = r->in.access_mask;
3332         NTSTATUS  nt_status;
3333         size_t    sd_size;
3334         struct samr_ConnectInfo1 info1;
3335
3336         DEBUG(5,("_samr_Connect5: %d\n", __LINE__));
3337
3338         /* Access check */
3339
3340         if (!pipe_access_check(p)) {
3341                 DEBUG(3, ("access denied to samr_Connect5\n"));
3342                 return NT_STATUS_ACCESS_DENIED;
3343         }
3344
3345         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
3346         se_map_generic(&des_access, &sam_generic_mapping);
3347
3348         nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3349                 NULL, 0, des_access, &acc_granted, "_samr_Connect5");
3350
3351         if ( !NT_STATUS_IS_OK(nt_status) )
3352                 return nt_status;
3353
3354         /* associate the user's SID and access granted with the new handle. */
3355         if ((info = get_samr_info_by_sid(NULL)) == NULL)
3356                 return NT_STATUS_NO_MEMORY;
3357
3358         info->acc_granted = acc_granted;
3359         info->status = r->in.access_mask; /* ??? */
3360
3361         /* get a (unique) handle.  open a policy on it. */
3362         if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info))
3363                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3364
3365         DEBUG(5,("_samr_Connect5: %d\n", __LINE__));
3366
3367         info1.client_version = SAMR_CONNECT_AFTER_W2K;
3368         info1.unknown2 = 0;
3369
3370         *r->out.level_out = 1;
3371         r->out.info_out->info1 = info1;
3372
3373         return NT_STATUS_OK;
3374 }
3375
3376 /**********************************************************************
3377  _samr_LookupDomain
3378  **********************************************************************/
3379
3380 NTSTATUS _samr_LookupDomain(pipes_struct *p,
3381                             struct samr_LookupDomain *r)
3382 {
3383         NTSTATUS status = NT_STATUS_OK;
3384         struct samr_info *info;
3385         const char *domain_name;
3386         DOM_SID *sid = NULL;
3387
3388         if (!find_policy_by_hnd(p, r->in.connect_handle, (void**)(void *)&info))
3389                 return NT_STATUS_INVALID_HANDLE;
3390
3391         /* win9x user manager likes to use SA_RIGHT_SAM_ENUM_DOMAINS here.
3392            Reverted that change so we will work with RAS servers again */
3393
3394         status = access_check_samr_function(info->acc_granted,
3395                                             SA_RIGHT_SAM_OPEN_DOMAIN,
3396                                             "_samr_LookupDomain");
3397         if (!NT_STATUS_IS_OK(status)) {
3398                 return status;
3399         }
3400
3401         domain_name = r->in.domain_name->string;
3402
3403         sid = TALLOC_ZERO_P(p->mem_ctx, struct dom_sid2);
3404         if (!sid) {
3405                 return NT_STATUS_NO_MEMORY;
3406         }
3407
3408         if (strequal(domain_name, builtin_domain_name())) {
3409                 sid_copy(sid, &global_sid_Builtin);
3410         } else {
3411                 if (!secrets_fetch_domain_sid(domain_name, sid)) {
3412                         status = NT_STATUS_NO_SUCH_DOMAIN;
3413                 }
3414         }
3415
3416         DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name,
3417                  sid_string_dbg(sid)));
3418
3419         *r->out.sid = sid;
3420
3421         return status;
3422 }
3423
3424 /**********************************************************************
3425  _samr_EnumDomains
3426  **********************************************************************/
3427
3428 NTSTATUS _samr_EnumDomains(pipes_struct *p,
3429                            struct samr_EnumDomains *r)
3430 {
3431         NTSTATUS status;
3432         struct samr_info *info;
3433         uint32_t num_entries = 2;
3434         struct samr_SamEntry *entry_array = NULL;
3435         struct samr_SamArray *sam;
3436
3437         if (!find_policy_by_hnd(p, r->in.connect_handle, (void**)(void *)&info))
3438                 return NT_STATUS_INVALID_HANDLE;
3439
3440         status = access_check_samr_function(info->acc_granted,
3441                                             SA_RIGHT_SAM_ENUM_DOMAINS,
3442                                             "_samr_EnumDomains");
3443         if (!NT_STATUS_IS_OK(status)) {
3444                 return status;
3445         }
3446
3447         sam = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
3448         if (!sam) {
3449                 return NT_STATUS_NO_MEMORY;
3450         }
3451
3452         entry_array = TALLOC_ZERO_ARRAY(p->mem_ctx,
3453                                         struct samr_SamEntry,
3454                                         num_entries);
3455         if (!entry_array) {
3456                 return NT_STATUS_NO_MEMORY;
3457         }
3458
3459         entry_array[0].idx = 0;
3460         init_lsa_String(&entry_array[0].name, get_global_sam_name());
3461
3462         entry_array[1].idx = 1;
3463         init_lsa_String(&entry_array[1].name, "Builtin");
3464
3465         sam->count = num_entries;
3466         sam->entries = entry_array;
3467
3468         *r->out.sam = sam;
3469         *r->out.num_entries = num_entries;
3470
3471         return status;
3472 }
3473
3474 /*******************************************************************
3475  _samr_OpenAlias
3476  ********************************************************************/
3477
3478 NTSTATUS _samr_OpenAlias(pipes_struct *p,
3479                          struct samr_OpenAlias *r)
3480 {
3481         DOM_SID sid;
3482         POLICY_HND domain_pol = *r->in.domain_handle;
3483         uint32 alias_rid = r->in.rid;
3484         POLICY_HND *alias_pol = r->out.alias_handle;
3485         struct    samr_info *info = NULL;
3486         SEC_DESC *psd = NULL;
3487         uint32    acc_granted;
3488         uint32    des_access = r->in.access_mask;
3489         size_t    sd_size;
3490         NTSTATUS  status;
3491         SE_PRIV se_rights;
3492
3493         /* find the domain policy and get the SID / access bits stored in the domain policy */
3494
3495         if ( !get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted, NULL) )
3496                 return NT_STATUS_INVALID_HANDLE;
3497
3498         status = access_check_samr_function(acc_granted,
3499                                             SA_RIGHT_DOMAIN_OPEN_ACCOUNT,
3500                                             "_samr_OpenAlias");
3501
3502         if ( !NT_STATUS_IS_OK(status) )
3503                 return status;
3504
3505         /* append the alias' RID to it */
3506
3507         if (!sid_append_rid(&sid, alias_rid))
3508                 return NT_STATUS_NO_SUCH_ALIAS;
3509
3510         /*check if access can be granted as requested by client. */
3511
3512         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &ali_generic_mapping, NULL, 0);
3513         se_map_generic(&des_access,&ali_generic_mapping);
3514
3515         se_priv_copy( &se_rights, &se_add_users );
3516
3517
3518         status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3519                 &se_rights, GENERIC_RIGHTS_ALIAS_WRITE, des_access,
3520                 &acc_granted, "_samr_OpenAlias");
3521
3522         if ( !NT_STATUS_IS_OK(status) )
3523                 return status;
3524
3525         {
3526                 /* Check we actually have the requested alias */
3527                 enum lsa_SidType type;
3528                 bool result;
3529                 gid_t gid;
3530
3531                 become_root();
3532                 result = lookup_sid(NULL, &sid, NULL, NULL, &type);
3533                 unbecome_root();
3534
3535                 if (!result || (type != SID_NAME_ALIAS)) {
3536                         return NT_STATUS_NO_SUCH_ALIAS;
3537                 }
3538
3539                 /* make sure there is a mapping */
3540
3541                 if ( !sid_to_gid( &sid, &gid ) ) {
3542                         return NT_STATUS_NO_SUCH_ALIAS;
3543                 }
3544
3545         }
3546
3547         /* associate the alias SID with the new handle. */
3548         if ((info = get_samr_info_by_sid(&sid)) == NULL)
3549                 return NT_STATUS_NO_MEMORY;
3550
3551         info->acc_granted = acc_granted;
3552
3553         /* get a (unique) handle.  open a policy on it. */
3554         if (!create_policy_hnd(p, alias_pol, free_samr_info, (void *)info))
3555                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3556
3557         return NT_STATUS_OK;
3558 }
3559
3560 /*******************************************************************
3561  set_user_info_7
3562  ********************************************************************/
3563
3564 static NTSTATUS set_user_info_7(TALLOC_CTX *mem_ctx,
3565                                 struct samr_UserInfo7 *id7,
3566                                 struct samu *pwd)
3567 {
3568         NTSTATUS rc;
3569
3570         if (id7 == NULL) {
3571                 DEBUG(5, ("set_user_info_7: NULL id7\n"));
3572                 TALLOC_FREE(pwd);
3573                 return NT_STATUS_ACCESS_DENIED;
3574         }
3575
3576         if (!id7->account_name.string) {
3577                 DEBUG(5, ("set_user_info_7: failed to get new username\n"));
3578                 TALLOC_FREE(pwd);
3579                 return NT_STATUS_ACCESS_DENIED;
3580         }
3581
3582         /* check to see if the new username already exists.  Note: we can't
3583            reliably lock all backends, so there is potentially the
3584            possibility that a user can be created in between this check and
3585            the rename.  The rename should fail, but may not get the
3586            exact same failure status code.  I think this is small enough
3587            of a window for this type of operation and the results are
3588            simply that the rename fails with a slightly different status
3589            code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
3590
3591         rc = can_create(mem_ctx, id7->account_name.string);
3592         if (!NT_STATUS_IS_OK(rc)) {
3593                 return rc;
3594         }
3595
3596         rc = pdb_rename_sam_account(pwd, id7->account_name.string);
3597
3598         TALLOC_FREE(pwd);
3599         return rc;
3600 }
3601
3602 /*******************************************************************
3603  set_user_info_16
3604  ********************************************************************/
3605
3606 static bool set_user_info_16(struct samr_UserInfo16 *id16,
3607                              struct samu *pwd)
3608 {
3609         if (id16 == NULL) {
3610                 DEBUG(5, ("set_user_info_16: NULL id16\n"));
3611                 TALLOC_FREE(pwd);
3612                 return False;
3613         }
3614
3615         /* FIX ME: check if the value is really changed --metze */
3616         if (!pdb_set_acct_ctrl(pwd, id16->acct_flags, PDB_CHANGED)) {
3617                 TALLOC_FREE(pwd);
3618                 return False;
3619         }
3620
3621         if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3622                 TALLOC_FREE(pwd);
3623                 return False;
3624         }
3625
3626         TALLOC_FREE(pwd);
3627
3628         return True;
3629 }
3630
3631 /*******************************************************************
3632  set_user_info_18
3633  ********************************************************************/
3634
3635 static bool set_user_info_18(struct samr_UserInfo18 *id18,
3636                              struct samu *pwd)
3637 {
3638         if (id18 == NULL) {
3639                 DEBUG(2, ("set_user_info_18: id18 is NULL\n"));
3640                 TALLOC_FREE(pwd);
3641                 return False;
3642         }
3643
3644         if (!pdb_set_lanman_passwd (pwd, id18->lm_pwd.hash, PDB_CHANGED)) {
3645                 TALLOC_FREE(pwd);
3646                 return False;
3647         }
3648         if (!pdb_set_nt_passwd     (pwd, id18->nt_pwd.hash, PDB_CHANGED)) {
3649                 TALLOC_FREE(pwd);
3650                 return False;
3651         }
3652         if (!pdb_set_pass_last_set_time (pwd, time(NULL), PDB_CHANGED)) {
3653                 TALLOC_FREE(pwd);
3654                 return False;
3655         }
3656
3657         if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3658                 TALLOC_FREE(pwd);
3659                 return False;
3660         }
3661
3662         TALLOC_FREE(pwd);
3663         return True;
3664 }
3665
3666 /*******************************************************************
3667  set_user_info_20
3668  ********************************************************************/
3669
3670 static bool set_user_info_20(struct samr_UserInfo20 *id20,
3671                              struct samu *pwd)
3672 {
3673         if (id20 == NULL) {
3674                 DEBUG(5, ("set_user_info_20: NULL id20\n"));
3675                 return False;
3676         }
3677
3678         copy_id20_to_sam_passwd(pwd, id20);
3679
3680         /* write the change out */
3681         if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3682                 TALLOC_FREE(pwd);
3683                 return False;
3684         }
3685
3686         TALLOC_FREE(pwd);
3687
3688         return True;
3689 }
3690
3691 /*******************************************************************
3692  set_user_info_21
3693  ********************************************************************/
3694
3695 static NTSTATUS set_user_info_21(TALLOC_CTX *mem_ctx,
3696                                  struct samr_UserInfo21 *id21,
3697                                  struct samu *pwd)
3698 {
3699         NTSTATUS status;
3700
3701         if (id21 == NULL) {
3702                 DEBUG(5, ("set_user_info_21: NULL id21\n"));
3703                 return NT_STATUS_INVALID_PARAMETER;
3704         }
3705
3706         /* we need to separately check for an account rename first */
3707
3708         if (id21->account_name.string &&
3709             (!strequal(id21->account_name.string, pdb_get_username(pwd))))
3710         {
3711
3712                 /* check to see if the new username already exists.  Note: we can't
3713                    reliably lock all backends, so there is potentially the
3714                    possibility that a user can be created in between this check and
3715                    the rename.  The rename should fail, but may not get the
3716                    exact same failure status code.  I think this is small enough
3717                    of a window for this type of operation and the results are
3718                    simply that the rename fails with a slightly different status
3719                    code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
3720
3721                 status = can_create(mem_ctx, id21->account_name.string);
3722                 if (!NT_STATUS_IS_OK(status)) {
3723                         return status;
3724                 }
3725
3726                 status = pdb_rename_sam_account(pwd, id21->account_name.string);
3727
3728                 if (!NT_STATUS_IS_OK(status)) {
3729                         DEBUG(0,("set_user_info_21: failed to rename account: %s\n",
3730                                 nt_errstr(status)));
3731                         TALLOC_FREE(pwd);
3732                         return status;
3733                 }
3734
3735                 /* set the new username so that later
3736                    functions can work on the new account */
3737                 pdb_set_username(pwd, id21->account_name.string, PDB_SET);
3738         }
3739
3740         copy_id21_to_sam_passwd("INFO_21", pwd, id21);
3741
3742         /*
3743          * The funny part about the previous two calls is
3744          * that pwd still has the password hashes from the
3745          * passdb entry.  These have not been updated from
3746          * id21.  I don't know if they need to be set.    --jerry
3747          */
3748
3749         if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
3750                 status = pdb_set_unix_primary_group(mem_ctx, pwd);
3751                 if ( !NT_STATUS_IS_OK(status) ) {
3752                         return status;
3753                 }
3754         }
3755
3756         /* Don't worry about writing out the user account since the
3757            primary group SID is generated solely from the user's Unix
3758            primary group. */
3759
3760         /* write the change out */
3761         if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
3762                 TALLOC_FREE(pwd);
3763                 return status;
3764         }
3765
3766         TALLOC_FREE(pwd);
3767
3768         return NT_STATUS_OK;
3769 }
3770
3771 /*******************************************************************
3772  set_user_info_23
3773  ********************************************************************/
3774
3775 static NTSTATUS set_user_info_23(TALLOC_CTX *mem_ctx,
3776                                  struct samr_UserInfo23 *id23,
3777                                  struct samu *pwd)
3778 {
3779         char *plaintext_buf = NULL;
3780         uint32 len = 0;
3781         uint16 acct_ctrl;
3782         NTSTATUS status;
3783
3784         if (id23 == NULL) {
3785                 DEBUG(5, ("set_user_info_23: NULL id23\n"));
3786                 return NT_STATUS_INVALID_PARAMETER;
3787         }
3788
3789         DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
3790                   pdb_get_username(pwd)));
3791
3792         acct_ctrl = pdb_get_acct_ctrl(pwd);
3793
3794         if (!decode_pw_buffer(mem_ctx,
3795                                 id23->password.data,
3796                                 &plaintext_buf,
3797                                 &len,
3798                                 STR_UNICODE)) {
3799                 TALLOC_FREE(pwd);
3800                 return NT_STATUS_INVALID_PARAMETER;
3801         }
3802
3803         if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
3804                 TALLOC_FREE(pwd);
3805                 return NT_STATUS_ACCESS_DENIED;
3806         }
3807
3808         copy_id23_to_sam_passwd(pwd, id23);
3809
3810         /* if it's a trust account, don't update /etc/passwd */
3811         if (    ( (acct_ctrl &  ACB_DOMTRUST) == ACB_DOMTRUST ) ||
3812                 ( (acct_ctrl &  ACB_WSTRUST) ==  ACB_WSTRUST) ||
3813                 ( (acct_ctrl &  ACB_SVRTRUST) ==  ACB_SVRTRUST) ) {
3814                 DEBUG(5, ("Changing trust account.  Not updating /etc/passwd\n"));
3815         } else  {
3816                 /* update the UNIX password */
3817                 if (lp_unix_password_sync() ) {
3818                         struct passwd *passwd;
3819                         if (pdb_get_username(pwd) == NULL) {
3820                                 DEBUG(1, ("chgpasswd: User without name???\n"));
3821                                 TALLOC_FREE(pwd);
3822                                 return NT_STATUS_ACCESS_DENIED;
3823                         }
3824
3825                         passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
3826                         if (passwd == NULL) {
3827                                 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
3828                         }
3829
3830                         if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
3831                                 TALLOC_FREE(pwd);
3832                                 return NT_STATUS_ACCESS_DENIED;
3833                         }
3834                         TALLOC_FREE(passwd);
3835                 }
3836         }
3837
3838         memset(plaintext_buf, '\0', strlen(plaintext_buf));
3839
3840         if (IS_SAM_CHANGED(pwd, PDB_GROUPSID) &&
3841             (!NT_STATUS_IS_OK(status =  pdb_set_unix_primary_group(mem_ctx,
3842                                                                    pwd)))) {
3843                 TALLOC_FREE(pwd);
3844                 return status;
3845         }
3846
3847         if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
3848                 TALLOC_FREE(pwd);
3849                 return status;
3850         }
3851
3852         TALLOC_FREE(pwd);
3853
3854         return NT_STATUS_OK;
3855 }
3856
3857 /*******************************************************************
3858  set_user_info_pw
3859  ********************************************************************/
3860
3861 static bool set_user_info_pw(uint8 *pass, struct samu *pwd)
3862 {
3863         uint32 len = 0;
3864         char *plaintext_buf = NULL;
3865         uint32 acct_ctrl;
3866         time_t last_set_time;
3867         enum pdb_value_state last_set_state;
3868
3869         DEBUG(5, ("Attempting administrator password change for user %s\n",
3870                   pdb_get_username(pwd)));
3871
3872         acct_ctrl = pdb_get_acct_ctrl(pwd);
3873         /* we need to know if it's expired, because this is an admin change, not a
3874            user change, so it's still expired when we're done */
3875         last_set_state = pdb_get_init_flags(pwd, PDB_PASSLASTSET);
3876         last_set_time = pdb_get_pass_last_set_time(pwd);
3877
3878         if (!decode_pw_buffer(talloc_tos(),
3879                                 pass,
3880                                 &plaintext_buf,
3881                                 &len,
3882                                 STR_UNICODE)) {
3883                 TALLOC_FREE(pwd);
3884                 return False;
3885         }
3886
3887         if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
3888                 TALLOC_FREE(pwd);
3889                 return False;
3890         }
3891
3892         /* if it's a trust account, don't update /etc/passwd */
3893         if ( ( (acct_ctrl &  ACB_DOMTRUST) == ACB_DOMTRUST ) ||
3894                 ( (acct_ctrl &  ACB_WSTRUST) ==  ACB_WSTRUST) ||
3895                 ( (acct_ctrl &  ACB_SVRTRUST) ==  ACB_SVRTRUST) ) {
3896                 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
3897         } else {
3898                 /* update the UNIX password */
3899                 if (lp_unix_password_sync()) {
3900                         struct passwd *passwd;
3901
3902                         if (pdb_get_username(pwd) == NULL) {
3903                                 DEBUG(1, ("chgpasswd: User without name???\n"));
3904                                 TALLOC_FREE(pwd);
3905                                 return False;
3906                         }
3907
3908                         passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
3909                         if (passwd == NULL) {
3910                                 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
3911                         }
3912
3913                         if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
3914                                 TALLOC_FREE(pwd);
3915                                 return False;
3916                         }
3917                         TALLOC_FREE(passwd);
3918                 }
3919         }
3920
3921         memset(plaintext_buf, '\0', strlen(plaintext_buf));
3922
3923         /* restore last set time as this is an admin change, not a user pw change */
3924         pdb_set_pass_last_set_time (pwd, last_set_time, last_set_state);
3925
3926         DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
3927
3928         /* update the SAMBA password */
3929         if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3930                 TALLOC_FREE(pwd);
3931                 return False;
3932         }
3933
3934         TALLOC_FREE(pwd);
3935
3936         return True;
3937 }
3938
3939 /*******************************************************************
3940  set_user_info_25
3941  ********************************************************************/
3942
3943 static NTSTATUS set_user_info_25(TALLOC_CTX *mem_ctx,
3944                                  struct samr_UserInfo25 *id25,
3945                                  struct samu *pwd)
3946 {
3947         NTSTATUS status;
3948
3949         if (id25 == NULL) {
3950                 DEBUG(5, ("set_user_info_25: NULL id25\n"));
3951                 return NT_STATUS_INVALID_PARAMETER;
3952         }
3953
3954         copy_id25_to_sam_passwd(pwd, id25);
3955
3956         /* write the change out */
3957         if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
3958                 TALLOC_FREE(pwd);
3959                 return status;
3960         }
3961
3962         /*
3963          * We need to "pdb_update_sam_account" before the unix primary group
3964          * is set, because the idealx scripts would also change the
3965          * sambaPrimaryGroupSid using the ldap replace method. pdb_ldap uses
3966          * the delete explicit / add explicit, which would then fail to find
3967          * the previous primaryGroupSid value.
3968          */
3969
3970         if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
3971                 status = pdb_set_unix_primary_group(mem_ctx, pwd);
3972                 if ( !NT_STATUS_IS_OK(status) ) {
3973                         return status;
3974                 }
3975         }
3976
3977         /* WARNING: No TALLOC_FREE(pwd), we are about to set the password
3978          * hereafter! */
3979
3980         return NT_STATUS_OK;
3981 }
3982
3983 /*******************************************************************
3984  samr_SetUserInfo_internal
3985  ********************************************************************/
3986
3987 static NTSTATUS samr_SetUserInfo_internal(const char *fn_name,
3988                                           pipes_struct *p,
3989                                           struct policy_handle *user_handle,
3990                                           uint16_t level,
3991                                           union samr_UserInfo *info)
3992 {
3993         NTSTATUS status;
3994         struct samu *pwd = NULL;
3995         DOM_SID sid;
3996         POLICY_HND *pol = user_handle;
3997         uint16_t switch_value = level;
3998         uint32_t acc_granted;
3999         uint32_t acc_required;
4000         bool ret;
4001         bool has_enough_rights = False;
4002         uint32_t acb_info;
4003         DISP_INFO *disp_info = NULL;
4004
4005         DEBUG(5,("%s: %d\n", fn_name, __LINE__));
4006
4007         /* find the policy handle.  open a policy on it. */
4008         if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted, &disp_info)) {
4009                 return NT_STATUS_INVALID_HANDLE;
4010         }
4011
4012         /* This is tricky.  A WinXP domain join sets
4013           (SA_RIGHT_USER_SET_PASSWORD|SA_RIGHT_USER_SET_ATTRIBUTES|SA_RIGHT_USER_ACCT_FLAGS_EXPIRY)
4014           The MMC lusrmgr plugin includes these perms and more in the SamrOpenUser().  But the
4015           standard Win32 API calls just ask for SA_RIGHT_USER_SET_PASSWORD in the SamrOpenUser().
4016           This should be enough for levels 18, 24, 25,& 26.  Info level 23 can set more so
4017           we'll use the set from the WinXP join as the basis. */
4018
4019         switch (switch_value) {
4020         case 18:
4021         case 24:
4022         case 25:
4023         case 26:
4024                 acc_required = SA_RIGHT_USER_SET_PASSWORD;
4025                 break;
4026         default:
4027                 acc_required = SA_RIGHT_USER_SET_PASSWORD |
4028                                SA_RIGHT_USER_SET_ATTRIBUTES |
4029                                SA_RIGHT_USER_ACCT_FLAGS_EXPIRY;
4030                 break;
4031         }
4032
4033         status = access_check_samr_function(acc_granted,
4034                                             acc_required,
4035                                             fn_name);
4036         if (!NT_STATUS_IS_OK(status)) {
4037                 return status;
4038         }
4039
4040         DEBUG(5, ("%s: sid:%s, level:%d\n",
4041                   fn_name, sid_string_dbg(&sid), switch_value));
4042
4043         if (info == NULL) {
4044                 DEBUG(5, ("%s: NULL info level\n", fn_name));
4045                 return NT_STATUS_INVALID_INFO_CLASS;
4046         }
4047
4048         if (!(pwd = samu_new(NULL))) {
4049                 return NT_STATUS_NO_MEMORY;
4050         }
4051
4052         become_root();
4053         ret = pdb_getsampwsid(pwd, &sid);
4054         unbecome_root();
4055
4056         if (!ret) {
4057                 TALLOC_FREE(pwd);
4058                 return NT_STATUS_NO_SUCH_USER;
4059         }
4060
4061         /* deal with machine password changes differently from userinfo changes */
4062         /* check to see if we have the sufficient rights */
4063
4064         acb_info = pdb_get_acct_ctrl(pwd);
4065         if (acb_info & ACB_WSTRUST)
4066                 has_enough_rights = user_has_privileges(p->pipe_user.nt_user_token,
4067                                                         &se_machine_account);
4068         else if (acb_info & ACB_NORMAL)
4069                 has_enough_rights = user_has_privileges(p->pipe_user.nt_user_token,
4070                                                         &se_add_users);
4071         else if (acb_info & (ACB_SVRTRUST|ACB_DOMTRUST)) {
4072                 if (lp_enable_privileges()) {
4073                         has_enough_rights = nt_token_check_domain_rid(p->pipe_user.nt_user_token,
4074                                                                       DOMAIN_GROUP_RID_ADMINS);
4075                 }
4076         }
4077
4078         DEBUG(5, ("%s: %s does%s possess sufficient rights\n",
4079                   fn_name,
4080                   uidtoname(p->pipe_user.ut.uid),
4081                   has_enough_rights ? "" : " not"));
4082
4083         /* ================ BEGIN SeMachineAccountPrivilege BLOCK ================ */
4084
4085         if (has_enough_rights) {
4086                 become_root();
4087         }
4088
4089         /* ok!  user info levels (lots: see MSDEV help), off we go... */
4090
4091         switch (switch_value) {
4092
4093                 case 7:
4094                         status = set_user_info_7(p->mem_ctx,
4095                                                  &info->info7, pwd);
4096                         break;
4097
4098                 case 16:
4099                         if (!set_user_info_16(&info->info16, pwd)) {
4100                                 status = NT_STATUS_ACCESS_DENIED;
4101                         }
4102                         break;
4103
4104                 case 18:
4105                         /* Used by AS/U JRA. */
4106                         if (!set_user_info_18(&info->info18, pwd)) {
4107                                 status = NT_STATUS_ACCESS_DENIED;
4108                         }
4109                         break;
4110
4111                 case 20:
4112                         if (!set_user_info_20(&info->info20, pwd)) {
4113                                 status = NT_STATUS_ACCESS_DENIED;
4114                         }
4115                         break;
4116
4117                 case 21:
4118                         status = set_user_info_21(p->mem_ctx,
4119                                                   &info->info21, pwd);
4120                         break;
4121
4122                 case 23:
4123                         if (!p->session_key.length) {
4124                                 status = NT_STATUS_NO_USER_SESSION_KEY;
4125                         }
4126                         SamOEMhashBlob(info->info23.password.data, 516,
4127                                        &p->session_key);
4128
4129                         dump_data(100, info->info23.password.data, 516);
4130
4131                         status = set_user_info_23(p->mem_ctx,
4132                                                   &info->info23, pwd);
4133                         break;
4134
4135                 case 24:
4136                         if (!p->session_key.length) {
4137                                 status = NT_STATUS_NO_USER_SESSION_KEY;
4138                         }
4139                         SamOEMhashBlob(info->info24.password.data,
4140                                        516,
4141                                        &p->session_key);
4142
4143                         dump_data(100, info->info24.password.data, 516);
4144
4145                         if (!set_user_info_pw(info->info24.password.data, pwd)) {
4146                                 status = NT_STATUS_ACCESS_DENIED;
4147                         }
4148                         break;
4149
4150                 case 25:
4151                         if (!p->session_key.length) {
4152                                 status = NT_STATUS_NO_USER_SESSION_KEY;
4153                         }
4154                         encode_or_decode_arc4_passwd_buffer(info->info25.password.data,
4155                                                             &p->session_key);
4156
4157                         dump_data(100, info->info25.password.data, 532);
4158
4159                         status = set_user_info_25(p->mem_ctx,
4160                                                   &info->info25, pwd);
4161                         if (!NT_STATUS_IS_OK(status)) {
4162                                 goto done;
4163                         }
4164                         if (!set_user_info_pw(info->info25.password.data, pwd)) {
4165                                 status = NT_STATUS_ACCESS_DENIED;
4166                         }
4167                         break;
4168
4169                 case 26:
4170                         if (!p->session_key.length) {
4171                                 status = NT_STATUS_NO_USER_SESSION_KEY;
4172                         }
4173                         encode_or_decode_arc4_passwd_buffer(info->info26.password.data,
4174                                                             &p->session_key);
4175
4176                         dump_data(100, info->info26.password.data, 516);
4177
4178                         if (!set_user_info_pw(info->info26.password.data, pwd)) {
4179                                 status = NT_STATUS_ACCESS_DENIED;
4180                         }
4181                         break;
4182
4183                 default:
4184                         status = NT_STATUS_INVALID_INFO_CLASS;
4185         }
4186
4187  done:
4188
4189         if (has_enough_rights) {
4190                 unbecome_root();
4191         }
4192
4193         /* ================ END SeMachineAccountPrivilege BLOCK ================ */
4194
4195         if (NT_STATUS_IS_OK(status)) {
4196                 force_flush_samr_cache(disp_info);
4197         }
4198
4199         return status;
4200 }
4201
4202 /*******************************************************************
4203  _samr_SetUserInfo
4204  ********************************************************************/
4205
4206 NTSTATUS _samr_SetUserInfo(pipes_struct *p,
4207                            struct samr_SetUserInfo *r)
4208 {
4209         return samr_SetUserInfo_internal("_samr_SetUserInfo",
4210                                          p,
4211                                          r->in.user_handle,
4212                                          r->in.level,
4213                                          r->in.info);
4214 }
4215
4216 /*******************************************************************
4217  _samr_SetUserInfo2
4218  ********************************************************************/
4219
4220 NTSTATUS _samr_SetUserInfo2(pipes_struct *p,
4221                             struct samr_SetUserInfo2 *r)
4222 {
4223         return samr_SetUserInfo_internal("_samr_SetUserInfo2",
4224                                          p,
4225                                          r->in.user_handle,
4226                                          r->in.level,
4227                                          r->in.info);
4228 }
4229
4230 /*********************************************************************
4231  _samr_GetAliasMembership
4232 *********************************************************************/
4233
4234 NTSTATUS _samr_GetAliasMembership(pipes_struct *p,
4235                                   struct samr_GetAliasMembership *r)
4236 {
4237         size_t num_alias_rids;
4238         uint32 *alias_rids;
4239         struct samr_info *info = NULL;
4240         size_t i;
4241
4242         NTSTATUS ntstatus1;
4243         NTSTATUS ntstatus2;
4244
4245         DOM_SID *members;
4246
4247         DEBUG(5,("_samr_GetAliasMembership: %d\n", __LINE__));
4248
4249         /* find the policy handle.  open a policy on it. */
4250         if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
4251                 return NT_STATUS_INVALID_HANDLE;
4252
4253         ntstatus1 = access_check_samr_function(info->acc_granted,
4254                                                SA_RIGHT_DOMAIN_LOOKUP_ALIAS_BY_MEM,
4255                                                "_samr_GetAliasMembership");
4256         ntstatus2 = access_check_samr_function(info->acc_granted,
4257                                                SA_RIGHT_DOMAIN_OPEN_ACCOUNT,
4258                                                "_samr_GetAliasMembership");
4259
4260         if (!NT_STATUS_IS_OK(ntstatus1) || !NT_STATUS_IS_OK(ntstatus2)) {
4261                 if (!(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus2)) &&
4262                     !(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus1))) {
4263                         return (NT_STATUS_IS_OK(ntstatus1)) ? ntstatus2 : ntstatus1;
4264                 }
4265         }
4266
4267         if (!sid_check_is_domain(&info->sid) &&
4268             !sid_check_is_builtin(&info->sid))
4269                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
4270
4271         if (r->in.sids->num_sids) {
4272                 members = TALLOC_ARRAY(p->mem_ctx, DOM_SID, r->in.sids->num_sids);
4273
4274                 if (members == NULL)
4275                         return NT_STATUS_NO_MEMORY;
4276         } else {
4277                 members = NULL;
4278         }
4279
4280         for (i=0; i<r->in.sids->num_sids; i++)
4281                 sid_copy(&members[i], r->in.sids->sids[i].sid);
4282
4283         alias_rids = NULL;
4284         num_alias_rids = 0;
4285
4286         become_root();
4287         ntstatus1 = pdb_enum_alias_memberships(p->mem_ctx, &info->sid, members,
4288                                                r->in.sids->num_sids,
4289                                                &alias_rids, &num_alias_rids);
4290         unbecome_root();
4291
4292         if (!NT_STATUS_IS_OK(ntstatus1)) {
4293                 return ntstatus1;
4294         }
4295
4296         r->out.rids->count = num_alias_rids;
4297         r->out.rids->ids = alias_rids;
4298
4299         return NT_STATUS_OK;
4300 }
4301
4302 /*********************************************************************
4303  _samr_GetMembersInAlias
4304 *********************************************************************/
4305
4306 NTSTATUS _samr_GetMembersInAlias(pipes_struct *p,
4307                                  struct samr_GetMembersInAlias *r)
4308 {
4309         NTSTATUS status;
4310         size_t i;
4311         size_t num_sids = 0;
4312         struct lsa_SidPtr *sids = NULL;
4313         DOM_SID *pdb_sids = NULL;
4314
4315         DOM_SID alias_sid;
4316
4317         uint32 acc_granted;
4318
4319         /* find the policy handle.  open a policy on it. */
4320         if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, NULL))
4321                 return NT_STATUS_INVALID_HANDLE;
4322
4323         status = access_check_samr_function(acc_granted,
4324                                             SA_RIGHT_ALIAS_GET_MEMBERS,
4325                                             "_samr_GetMembersInAlias");
4326         if (!NT_STATUS_IS_OK(status)) {
4327                 return status;
4328         }
4329
4330         DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
4331
4332         become_root();
4333         status = pdb_enum_aliasmem(&alias_sid, &pdb_sids, &num_sids);
4334         unbecome_root();
4335
4336         if (!NT_STATUS_IS_OK(status)) {
4337                 return status;
4338         }
4339
4340         if (num_sids) {
4341                 sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_SidPtr, num_sids);
4342                 if (sids == NULL) {
4343                         TALLOC_FREE(pdb_sids);
4344                         return NT_STATUS_NO_MEMORY;
4345                 }
4346         }
4347
4348         for (i = 0; i < num_sids; i++) {
4349                 sids[i].sid = sid_dup_talloc(p->mem_ctx, &pdb_sids[i]);
4350                 if (!sids[i].sid) {
4351                         TALLOC_FREE(pdb_sids);
4352                         return NT_STATUS_NO_MEMORY;
4353                 }
4354         }
4355
4356         r->out.sids->num_sids = num_sids;
4357         r->out.sids->sids = sids;
4358
4359         TALLOC_FREE(pdb_sids);
4360
4361         return NT_STATUS_OK;
4362 }
4363
4364 /*********************************************************************
4365  _samr_QueryGroupMember
4366 *********************************************************************/
4367
4368 NTSTATUS _samr_QueryGroupMember(pipes_struct *p,
4369                                 struct samr_QueryGroupMember *r)
4370 {
4371         DOM_SID group_sid;
4372         size_t i, num_members;
4373
4374         uint32 *rid=NULL;
4375         uint32 *attr=NULL;
4376
4377         uint32 acc_granted;
4378
4379         NTSTATUS status;
4380         struct samr_RidTypeArray *rids = NULL;
4381
4382         rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidTypeArray);
4383         if (!rids) {
4384                 return NT_STATUS_NO_MEMORY;
4385         }
4386
4387         /* find the policy handle.  open a policy on it. */
4388         if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, NULL))
4389                 return NT_STATUS_INVALID_HANDLE;
4390
4391         status = access_check_samr_function(acc_granted,
4392                                             SA_RIGHT_GROUP_GET_MEMBERS,
4393                                             "_samr_QueryGroupMember");
4394         if (!NT_STATUS_IS_OK(status)) {
4395                 return status;
4396         }
4397
4398         DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
4399
4400         if (!sid_check_is_in_our_domain(&group_sid)) {
4401                 DEBUG(3, ("sid %s is not in our domain\n",
4402                           sid_string_dbg(&group_sid)));
4403                 return NT_STATUS_NO_SUCH_GROUP;
4404         }
4405
4406         DEBUG(10, ("lookup on Domain SID\n"));
4407
4408         become_root();
4409         status = pdb_enum_group_members(p->mem_ctx, &group_sid,
4410                                         &rid, &num_members);
4411         unbecome_root();
4412
4413         if (!NT_STATUS_IS_OK(status))
4414                 return status;
4415
4416         if (num_members) {
4417                 attr=TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_members);
4418                 if (attr == NULL) {
4419                         return NT_STATUS_NO_MEMORY;
4420                 }
4421         } else {
4422                 attr = NULL;
4423         }
4424
4425         for (i=0; i<num_members; i++)
4426                 attr[i] = SID_NAME_USER;
4427
4428         rids->count = num_members;
4429         rids->types = attr;
4430         rids->rids = rid;
4431
4432         *r->out.rids = rids;
4433
4434         return NT_STATUS_OK;
4435 }
4436
4437 /*********************************************************************
4438  _samr_AddAliasMember
4439 *********************************************************************/
4440
4441 NTSTATUS _samr_AddAliasMember(pipes_struct *p,
4442                               struct samr_AddAliasMember *r)
4443 {
4444         DOM_SID alias_sid;
4445         uint32 acc_granted;
4446         SE_PRIV se_rights;
4447         bool can_add_accounts;
4448         NTSTATUS status;
4449         DISP_INFO *disp_info = NULL;
4450
4451         /* Find the policy handle. Open a policy on it. */
4452         if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
4453                 return NT_STATUS_INVALID_HANDLE;
4454
4455         status = access_check_samr_function(acc_granted,
4456                                             SA_RIGHT_ALIAS_ADD_MEMBER,
4457                                             "_samr_AddAliasMember");
4458         if (!NT_STATUS_IS_OK(status)) {
4459                 return status;
4460         }
4461
4462         DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
4463
4464         se_priv_copy( &se_rights, &se_add_users );
4465         can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4466
4467         /******** BEGIN SeAddUsers BLOCK *********/
4468
4469         if ( can_add_accounts )
4470                 become_root();
4471
4472         status = pdb_add_aliasmem(&alias_sid, r->in.sid);
4473
4474         if ( can_add_accounts )
4475                 unbecome_root();
4476
4477         /******** END SeAddUsers BLOCK *********/
4478
4479         if (NT_STATUS_IS_OK(status)) {
4480                 force_flush_samr_cache(disp_info);
4481         }
4482
4483         return status;
4484 }
4485
4486 /*********************************************************************
4487  _samr_DeleteAliasMember
4488 *********************************************************************/
4489
4490 NTSTATUS _samr_DeleteAliasMember(pipes_struct *p,
4491                                  struct samr_DeleteAliasMember *r)
4492 {
4493         DOM_SID alias_sid;
4494         uint32 acc_granted;
4495         SE_PRIV se_rights;
4496         bool can_add_accounts;
4497         NTSTATUS status;
4498         DISP_INFO *disp_info = NULL;
4499
4500         /* Find the policy handle. Open a policy on it. */
4501         if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
4502                 return NT_STATUS_INVALID_HANDLE;
4503
4504         status = access_check_samr_function(acc_granted,
4505                                             SA_RIGHT_ALIAS_REMOVE_MEMBER,
4506                                             "_samr_DeleteAliasMember");
4507         if (!NT_STATUS_IS_OK(status)) {
4508                 return status;
4509         }
4510
4511         DEBUG(10, ("_samr_del_aliasmem:sid is %s\n",
4512                    sid_string_dbg(&alias_sid)));
4513
4514         se_priv_copy( &se_rights, &se_add_users );
4515         can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4516
4517         /******** BEGIN SeAddUsers BLOCK *********/
4518
4519         if ( can_add_accounts )
4520                 become_root();
4521
4522         status = pdb_del_aliasmem(&alias_sid, r->in.sid);
4523
4524         if ( can_add_accounts )
4525                 unbecome_root();
4526
4527         /******** END SeAddUsers BLOCK *********/
4528
4529         if (NT_STATUS_IS_OK(status)) {
4530                 force_flush_samr_cache(disp_info);
4531         }
4532
4533         return status;
4534 }
4535
4536 /*********************************************************************
4537  _samr_AddGroupMember
4538 *********************************************************************/
4539
4540 NTSTATUS _samr_AddGroupMember(pipes_struct *p,
4541                               struct samr_AddGroupMember *r)
4542 {
4543         NTSTATUS status;
4544         DOM_SID group_sid;
4545         uint32 group_rid;
4546         uint32 acc_granted;
4547         SE_PRIV se_rights;
4548         bool can_add_accounts;
4549         DISP_INFO *disp_info = NULL;
4550
4551         /* Find the policy handle. Open a policy on it. */
4552         if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
4553                 return NT_STATUS_INVALID_HANDLE;
4554
4555         status = access_check_samr_function(acc_granted,
4556                                             SA_RIGHT_GROUP_ADD_MEMBER,
4557                                             "_samr_AddGroupMember");
4558         if (!NT_STATUS_IS_OK(status)) {
4559                 return status;
4560         }
4561
4562         DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
4563
4564         if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
4565                                 &group_rid)) {
4566                 return NT_STATUS_INVALID_HANDLE;
4567         }
4568
4569         se_priv_copy( &se_rights, &se_add_users );
4570         can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4571
4572         /******** BEGIN SeAddUsers BLOCK *********/
4573
4574         if ( can_add_accounts )
4575                 become_root();
4576
4577         status = pdb_add_groupmem(p->mem_ctx, group_rid, r->in.rid);
4578
4579         if ( can_add_accounts )
4580                 unbecome_root();
4581
4582         /******** END SeAddUsers BLOCK *********/
4583
4584         force_flush_samr_cache(disp_info);
4585
4586         return status;
4587 }
4588
4589 /*********************************************************************
4590  _samr_DeleteGroupMember
4591 *********************************************************************/
4592
4593 NTSTATUS _samr_DeleteGroupMember(pipes_struct *p,
4594                                  struct samr_DeleteGroupMember *r)
4595
4596 {
4597         NTSTATUS status;
4598         DOM_SID group_sid;
4599         uint32 group_rid;
4600         uint32 acc_granted;
4601         SE_PRIV se_rights;
4602         bool can_add_accounts;
4603         DISP_INFO *disp_info = NULL;
4604
4605         /*
4606          * delete the group member named r->in.rid
4607          * who is a member of the sid associated with the handle
4608          * the rid is a user's rid as the group is a domain group.
4609          */
4610
4611         /* Find the policy handle. Open a policy on it. */
4612         if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
4613                 return NT_STATUS_INVALID_HANDLE;
4614
4615         status = access_check_samr_function(acc_granted,
4616                                             SA_RIGHT_GROUP_REMOVE_MEMBER,
4617                                             "_samr_DeleteGroupMember");
4618         if (!NT_STATUS_IS_OK(status)) {
4619                 return status;
4620         }
4621
4622         if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
4623                                 &group_rid)) {
4624                 return NT_STATUS_INVALID_HANDLE;
4625         }
4626
4627         se_priv_copy( &se_rights, &se_add_users );
4628         can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4629
4630         /******** BEGIN SeAddUsers BLOCK *********/
4631
4632         if ( can_add_accounts )
4633                 become_root();
4634
4635         status = pdb_del_groupmem(p->mem_ctx, group_rid, r->in.rid);
4636
4637         if ( can_add_accounts )
4638                 unbecome_root();
4639
4640         /******** END SeAddUsers BLOCK *********/
4641
4642         force_flush_samr_cache(disp_info);
4643
4644         return status;
4645 }
4646
4647 /*********************************************************************
4648  _samr_DeleteUser
4649 *********************************************************************/
4650
4651 NTSTATUS _samr_DeleteUser(pipes_struct *p,
4652                           struct samr_DeleteUser *r)
4653 {
4654         NTSTATUS status;
4655         DOM_SID user_sid;
4656         struct samu *sam_pass=NULL;
4657         uint32 acc_granted;
4658         bool can_add_accounts;
4659         uint32 acb_info;
4660         DISP_INFO *disp_info = NULL;
4661         bool ret;
4662
4663         DEBUG(5, ("_samr_DeleteUser: %d\n", __LINE__));
4664
4665         /* Find the policy handle. Open a policy on it. */
4666         if (!get_lsa_policy_samr_sid(p, r->in.user_handle, &user_sid, &acc_granted, &disp_info))
4667                 return NT_STATUS_INVALID_HANDLE;
4668
4669         status = access_check_samr_function(acc_granted,
4670                                             STD_RIGHT_DELETE_ACCESS,
4671                                             "_samr_DeleteUser");
4672         if (!NT_STATUS_IS_OK(status)) {
4673                 return status;
4674         }
4675
4676         if (!sid_check_is_in_our_domain(&user_sid))
4677                 return NT_STATUS_CANNOT_DELETE;
4678
4679         /* check if the user exists before trying to delete */
4680         if ( !(sam_pass = samu_new( NULL )) ) {
4681                 return NT_STATUS_NO_MEMORY;
4682         }
4683
4684         become_root();
4685         ret = pdb_getsampwsid(sam_pass, &user_sid);
4686         unbecome_root();
4687
4688         if( !ret ) {
4689                 DEBUG(5,("_samr_DeleteUser: User %s doesn't exist.\n",
4690                         sid_string_dbg(&user_sid)));
4691                 TALLOC_FREE(sam_pass);
4692                 return NT_STATUS_NO_SUCH_USER;
4693         }
4694
4695         acb_info = pdb_get_acct_ctrl(sam_pass);
4696
4697         /* For machine accounts it's the SeMachineAccountPrivilege that counts. */
4698         if ( acb_info & ACB_WSTRUST ) {
4699                 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_machine_account );
4700         } else {
4701                 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_add_users );
4702         }
4703
4704         /******** BEGIN SeAddUsers BLOCK *********/
4705
4706         if ( can_add_accounts )
4707                 become_root();
4708
4709         status = pdb_delete_user(p->mem_ctx, sam_pass);
4710
4711         if ( can_add_accounts )
4712                 unbecome_root();
4713
4714         /******** END SeAddUsers BLOCK *********/
4715
4716         if ( !NT_STATUS_IS_OK(status) ) {
4717                 DEBUG(5,("_samr_DeleteUser: Failed to delete entry for "
4718                          "user %s: %s.\n", pdb_get_username(sam_pass),
4719                          nt_errstr(status)));
4720                 TALLOC_FREE(sam_pass);
4721                 return status;
4722         }
4723
4724
4725         TALLOC_FREE(sam_pass);
4726
4727         if (!close_policy_hnd(p, r->in.user_handle))
4728                 return NT_STATUS_OBJECT_NAME_INVALID;
4729
4730         force_flush_samr_cache(disp_info);
4731
4732         return NT_STATUS_OK;
4733 }
4734
4735 /*********************************************************************
4736  _samr_DeleteDomainGroup
4737 *********************************************************************/
4738
4739 NTSTATUS _samr_DeleteDomainGroup(pipes_struct *p,
4740                                  struct samr_DeleteDomainGroup *r)
4741 {
4742         NTSTATUS status;
4743         DOM_SID group_sid;
4744         uint32 group_rid;
4745         uint32 acc_granted;
4746         SE_PRIV se_rights;
4747         bool can_add_accounts;
4748         DISP_INFO *disp_info = NULL;
4749
4750         DEBUG(5, ("samr_DeleteDomainGroup: %d\n", __LINE__));
4751
4752         /* Find the policy handle. Open a policy on it. */
4753         if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
4754                 return NT_STATUS_INVALID_HANDLE;
4755
4756         status = access_check_samr_function(acc_granted,
4757                                             STD_RIGHT_DELETE_ACCESS,
4758                                             "_samr_DeleteDomainGroup");
4759         if (!NT_STATUS_IS_OK(status)) {
4760                 return status;
4761         }
4762
4763         DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
4764
4765         if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
4766                                 &group_rid)) {
4767                 return NT_STATUS_NO_SUCH_GROUP;
4768         }
4769
4770         se_priv_copy( &se_rights, &se_add_users );
4771         can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4772
4773         /******** BEGIN SeAddUsers BLOCK *********/
4774
4775         if ( can_add_accounts )
4776                 become_root();
4777
4778         status = pdb_delete_dom_group(p->mem_ctx, group_rid);
4779
4780         if ( can_add_accounts )
4781                 unbecome_root();
4782
4783         /******** END SeAddUsers BLOCK *********/
4784
4785         if ( !NT_STATUS_IS_OK(status) ) {
4786                 DEBUG(5,("_samr_DeleteDomainGroup: Failed to delete mapping "
4787                          "entry for group %s: %s\n",
4788                          sid_string_dbg(&group_sid),
4789                          nt_errstr(status)));
4790                 return status;
4791         }
4792
4793         if (!close_policy_hnd(p, r->in.group_handle))
4794                 return NT_STATUS_OBJECT_NAME_INVALID;
4795
4796         force_flush_samr_cache(disp_info);
4797
4798         return NT_STATUS_OK;
4799 }
4800
4801 /*********************************************************************
4802  _samr_DeleteDomAlias
4803 *********************************************************************/
4804
4805 NTSTATUS _samr_DeleteDomAlias(pipes_struct *p,
4806                               struct samr_DeleteDomAlias *r)
4807 {
4808         DOM_SID alias_sid;
4809         uint32 acc_granted;
4810         SE_PRIV se_rights;
4811         bool can_add_accounts;
4812         NTSTATUS status;
4813         DISP_INFO *disp_info = NULL;
4814
4815         DEBUG(5, ("_samr_DeleteDomAlias: %d\n", __LINE__));
4816
4817         /* Find the policy handle. Open a policy on it. */
4818         if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
4819                 return NT_STATUS_INVALID_HANDLE;
4820
4821         /* copy the handle to the outgoing reply */
4822
4823         memcpy(r->out.alias_handle, r->in.alias_handle, sizeof(r->out.alias_handle));
4824
4825         status = access_check_samr_function(acc_granted,
4826                                             STD_RIGHT_DELETE_ACCESS,
4827                                             "_samr_DeleteDomAlias");
4828         if (!NT_STATUS_IS_OK(status)) {
4829                 return status;
4830         }
4831
4832         DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
4833
4834         /* Don't let Windows delete builtin groups */
4835
4836         if ( sid_check_is_in_builtin( &alias_sid ) ) {
4837                 return NT_STATUS_SPECIAL_ACCOUNT;
4838         }
4839
4840         if (!sid_check_is_in_our_domain(&alias_sid))
4841                 return NT_STATUS_NO_SUCH_ALIAS;
4842
4843         DEBUG(10, ("lookup on Local SID\n"));
4844
4845         se_priv_copy( &se_rights, &se_add_users );
4846         can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4847
4848         /******** BEGIN SeAddUsers BLOCK *********/
4849
4850         if ( can_add_accounts )
4851                 become_root();
4852
4853         /* Have passdb delete the alias */
4854         status = pdb_delete_alias(&alias_sid);
4855
4856         if ( can_add_accounts )
4857                 unbecome_root();
4858
4859         /******** END SeAddUsers BLOCK *********/
4860
4861         if ( !NT_STATUS_IS_OK(status))
4862                 return status;
4863
4864         if (!close_policy_hnd(p, r->in.alias_handle))
4865                 return NT_STATUS_OBJECT_NAME_INVALID;
4866
4867         force_flush_samr_cache(disp_info);
4868
4869         return NT_STATUS_OK;
4870 }
4871
4872 /*********************************************************************
4873  _samr_CreateDomainGroup
4874 *********************************************************************/
4875
4876 NTSTATUS _samr_CreateDomainGroup(pipes_struct *p,
4877                                  struct samr_CreateDomainGroup *r)
4878
4879 {
4880         NTSTATUS status;
4881         DOM_SID dom_sid;
4882         DOM_SID info_sid;
4883         const char *name;
4884         struct samr_info *info;
4885         uint32 acc_granted;
4886         SE_PRIV se_rights;
4887         bool can_add_accounts;
4888         DISP_INFO *disp_info = NULL;
4889
4890         /* Find the policy handle. Open a policy on it. */
4891         if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &dom_sid, &acc_granted, &disp_info))
4892                 return NT_STATUS_INVALID_HANDLE;
4893
4894         status = access_check_samr_function(acc_granted,
4895                                             SA_RIGHT_DOMAIN_CREATE_GROUP,
4896                                             "_samr_CreateDomainGroup");
4897         if (!NT_STATUS_IS_OK(status)) {
4898                 return status;
4899         }
4900
4901         if (!sid_equal(&dom_sid, get_global_sam_sid()))
4902                 return NT_STATUS_ACCESS_DENIED;
4903
4904         name = r->in.name->string;
4905         if (name == NULL) {
4906                 return NT_STATUS_NO_MEMORY;
4907         }
4908
4909         status = can_create(p->mem_ctx, name);
4910         if (!NT_STATUS_IS_OK(status)) {
4911                 return status;
4912         }
4913
4914         se_priv_copy( &se_rights, &se_add_users );
4915         can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4916
4917         /******** BEGIN SeAddUsers BLOCK *********/
4918
4919         if ( can_add_accounts )
4920                 become_root();
4921
4922         /* check that we successfully create the UNIX group */
4923
4924         status = pdb_create_dom_group(p->mem_ctx, name, r->out.rid);
4925
4926         if ( can_add_accounts )
4927                 unbecome_root();
4928
4929         /******** END SeAddUsers BLOCK *********/
4930
4931         /* check if we should bail out here */
4932
4933         if ( !NT_STATUS_IS_OK(status) )
4934                 return status;
4935
4936         sid_compose(&info_sid, get_global_sam_sid(), *r->out.rid);
4937
4938         if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4939                 return NT_STATUS_NO_MEMORY;
4940
4941         /* they created it; let the user do what he wants with it */
4942
4943         info->acc_granted = GENERIC_RIGHTS_GROUP_ALL_ACCESS;
4944
4945         /* get a (unique) handle.  open a policy on it. */
4946         if (!create_policy_hnd(p, r->out.group_handle, free_samr_info, (void *)info))
4947                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4948
4949         force_flush_samr_cache(disp_info);
4950
4951         return NT_STATUS_OK;
4952 }
4953
4954 /*********************************************************************
4955  _samr_CreateDomAlias
4956 *********************************************************************/
4957
4958 NTSTATUS _samr_CreateDomAlias(pipes_struct *p,
4959                               struct samr_CreateDomAlias *r)
4960 {
4961         DOM_SID dom_sid;
4962         DOM_SID info_sid;
4963         const char *name = NULL;
4964         struct samr_info *info;
4965         uint32 acc_granted;
4966         gid_t gid;
4967         NTSTATUS result;
4968         SE_PRIV se_rights;
4969         bool can_add_accounts;
4970         DISP_INFO *disp_info = NULL;
4971
4972         /* Find the policy handle. Open a policy on it. */
4973         if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &dom_sid, &acc_granted, &disp_info))
4974                 return NT_STATUS_INVALID_HANDLE;
4975
4976         result = access_check_samr_function(acc_granted,
4977                                             SA_RIGHT_DOMAIN_CREATE_ALIAS,
4978                                             "_samr_CreateDomAlias");
4979         if (!NT_STATUS_IS_OK(result)) {
4980                 return result;
4981         }
4982
4983         if (!sid_equal(&dom_sid, get_global_sam_sid()))
4984                 return NT_STATUS_ACCESS_DENIED;
4985
4986         name = r->in.alias_name->string;
4987
4988         se_priv_copy( &se_rights, &se_add_users );
4989         can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4990
4991         result = can_create(p->mem_ctx, name);
4992         if (!NT_STATUS_IS_OK(result)) {
4993                 return result;
4994         }
4995
4996         /******** BEGIN SeAddUsers BLOCK *********/
4997
4998         if ( can_add_accounts )
4999                 become_root();
5000
5001         /* Have passdb create the alias */
5002         result = pdb_create_alias(name, r->out.rid);
5003
5004         if ( can_add_accounts )
5005                 unbecome_root();
5006
5007         /******** END SeAddUsers BLOCK *********/
5008
5009         if (!NT_STATUS_IS_OK(result)) {
5010                 DEBUG(10, ("pdb_create_alias failed: %s\n",
5011                            nt_errstr(result)));
5012                 return result;
5013         }
5014
5015         sid_copy(&info_sid, get_global_sam_sid());
5016         sid_append_rid(&info_sid, *r->out.rid);
5017
5018         if (!sid_to_gid(&info_sid, &gid)) {
5019                 DEBUG(10, ("Could not find alias just created\n"));
5020                 return NT_STATUS_ACCESS_DENIED;
5021         }
5022
5023         /* check if the group has been successfully created */
5024         if ( getgrgid(gid) == NULL ) {
5025                 DEBUG(10, ("getgrgid(%d) of just created alias failed\n",
5026                            gid));
5027                 return NT_STATUS_ACCESS_DENIED;
5028         }
5029
5030         if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
5031                 return NT_STATUS_NO_MEMORY;
5032
5033         /* they created it; let the user do what he wants with it */
5034
5035         info->acc_granted = GENERIC_RIGHTS_ALIAS_ALL_ACCESS;
5036
5037         /* get a (unique) handle.  open a policy on it. */
5038         if (!create_policy_hnd(p, r->out.alias_handle, free_samr_info, (void *)info))
5039                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5040
5041         force_flush_samr_cache(disp_info);
5042
5043         return NT_STATUS_OK;
5044 }
5045
5046 /*********************************************************************
5047  _samr_QueryGroupInfo
5048 *********************************************************************/
5049
5050 NTSTATUS _samr_QueryGroupInfo(pipes_struct *p,
5051                               struct samr_QueryGroupInfo *r)
5052 {
5053         NTSTATUS status;
5054         DOM_SID group_sid;
5055         GROUP_MAP map;
5056         union samr_GroupInfo *info = NULL;
5057         uint32 acc_granted;
5058         bool ret;
5059         uint32_t attributes = SE_GROUP_MANDATORY |
5060                               SE_GROUP_ENABLED_BY_DEFAULT |
5061                               SE_GROUP_ENABLED;
5062         const char *group_name = NULL;
5063         const char *group_description = NULL;
5064
5065         if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, NULL))
5066                 return NT_STATUS_INVALID_HANDLE;
5067
5068         status = access_check_samr_function(acc_granted,
5069                                             SA_RIGHT_GROUP_LOOKUP_INFO,
5070                                             "_samr_QueryGroupInfo");
5071         if (!NT_STATUS_IS_OK(status)) {
5072                 return status;
5073         }
5074
5075         become_root();
5076         ret = get_domain_group_from_sid(group_sid, &map);
5077         unbecome_root();
5078         if (!ret)
5079                 return NT_STATUS_INVALID_HANDLE;
5080
5081         /* FIXME: map contains fstrings */
5082         group_name = talloc_strdup(r, map.nt_name);
5083         group_description = talloc_strdup(r, map.comment);
5084
5085         info = TALLOC_ZERO_P(p->mem_ctx, union samr_GroupInfo);
5086         if (!info) {
5087                 return NT_STATUS_NO_MEMORY;
5088         }
5089
5090         switch (r->in.level) {
5091                 case 1: {
5092                         uint32 *members;
5093                         size_t num_members;
5094
5095                         become_root();
5096                         status = pdb_enum_group_members(
5097                                 p->mem_ctx, &group_sid, &members, &num_members);
5098                         unbecome_root();
5099
5100                         if (!NT_STATUS_IS_OK(status)) {
5101                                 return status;
5102                         }
5103
5104                         init_samr_group_info1(&info->all,
5105                                               group_name,
5106                                               attributes,
5107                                               num_members,
5108                                               group_description);
5109                         break;
5110                 }
5111                 case 2:
5112                         init_samr_group_info2(&info->name,
5113                                               group_name);
5114                         break;
5115                 case 3:
5116                         init_samr_group_info3(&info->attributes,
5117                                               attributes);
5118                         break;
5119                 case 4:
5120                         init_samr_group_info4(&info->description,
5121                                               group_description);
5122                         break;
5123                 case 5: {
5124                         /*
5125                         uint32 *members;
5126                         size_t num_members;
5127                         */
5128
5129                         /*
5130                         become_root();
5131                         status = pdb_enum_group_members(
5132                                 p->mem_ctx, &group_sid, &members, &num_members);
5133                         unbecome_root();
5134
5135                         if (!NT_STATUS_IS_OK(status)) {
5136                                 return status;
5137                         }
5138                         */
5139                         init_samr_group_info5(&info->all2,
5140                                               group_name,
5141                                               attributes,
5142                                               0, /* num_members - in w2k3 this is always 0 */
5143                                               group_description);
5144
5145                         break;
5146                 }
5147                 default:
5148                         return NT_STATUS_INVALID_INFO_CLASS;
5149         }
5150
5151         *r->out.info = info;
5152
5153         return NT_STATUS_OK;
5154 }
5155
5156 /*********************************************************************
5157  _samr_SetGroupInfo
5158 *********************************************************************/
5159
5160 NTSTATUS _samr_SetGroupInfo(pipes_struct *p,
5161                             struct samr_SetGroupInfo *r)
5162 {
5163         DOM_SID group_sid;
5164         GROUP_MAP map;
5165         uint32 acc_granted;
5166         NTSTATUS status;
5167         bool ret;
5168         bool can_mod_accounts;
5169         DISP_INFO *disp_info = NULL;
5170
5171         if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
5172                 return NT_STATUS_INVALID_HANDLE;
5173
5174         status = access_check_samr_function(acc_granted,
5175                                             SA_RIGHT_GROUP_SET_INFO,
5176                                             "_samr_SetGroupInfo");
5177         if (!NT_STATUS_IS_OK(status)) {
5178                 return status;
5179         }
5180
5181         become_root();
5182         ret = get_domain_group_from_sid(group_sid, &map);
5183         unbecome_root();
5184         if (!ret)
5185                 return NT_STATUS_NO_SUCH_GROUP;
5186
5187         switch (r->in.level) {
5188                 case 1:
5189                         fstrcpy(map.comment, r->in.info->all.description.string);
5190                         break;
5191                 case 4:
5192                         fstrcpy(map.comment, r->in.info->description.string);
5193                         break;
5194                 default:
5195                         return NT_STATUS_INVALID_INFO_CLASS;
5196         }
5197
5198         can_mod_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_add_users );
5199
5200         /******** BEGIN SeAddUsers BLOCK *********/
5201
5202         if ( can_mod_accounts )
5203                 become_root();
5204
5205         status = pdb_update_group_mapping_entry(&map);
5206
5207         if ( can_mod_accounts )
5208                 unbecome_root();
5209
5210         /******** End SeAddUsers BLOCK *********/
5211
5212         if (NT_STATUS_IS_OK(status)) {
5213                 force_flush_samr_cache(disp_info);
5214         }
5215
5216         return status;
5217 }
5218
5219 /*********************************************************************
5220  _samr_SetAliasInfo
5221 *********************************************************************/
5222
5223 NTSTATUS _samr_SetAliasInfo(pipes_struct *p,
5224                             struct samr_SetAliasInfo *r)
5225 {
5226         DOM_SID group_sid;
5227         struct acct_info info;
5228         uint32 acc_granted;
5229         bool can_mod_accounts;
5230         NTSTATUS status;
5231         DISP_INFO *disp_info = NULL;
5232
5233         if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &group_sid, &acc_granted, &disp_info))
5234                 return NT_STATUS_INVALID_HANDLE;
5235
5236         status = access_check_samr_function(acc_granted,
5237                                             SA_RIGHT_ALIAS_SET_INFO,
5238                                             "_samr_SetAliasInfo");
5239         if (!NT_STATUS_IS_OK(status)) {
5240                 return status;
5241         }
5242
5243         /* get the current group information */
5244
5245         become_root();
5246         status = pdb_get_aliasinfo( &group_sid, &info );
5247         unbecome_root();
5248
5249         if ( !NT_STATUS_IS_OK(status))
5250                 return status;
5251
5252         switch (r->in.level) {
5253                 case ALIASINFONAME:
5254                 {
5255                         fstring group_name;
5256
5257                         /* We currently do not support renaming groups in the
5258                            the BUILTIN domain.  Refer to util_builtin.c to understand
5259                            why.  The eventually needs to be fixed to be like Windows
5260                            where you can rename builtin groups, just not delete them */
5261
5262                         if ( sid_check_is_in_builtin( &group_sid ) ) {
5263                                 return NT_STATUS_SPECIAL_ACCOUNT;
5264                         }
5265
5266                         /* There has to be a valid name (and it has to be different) */
5267
5268                         if ( !r->in.info->name.string )
5269                                 return NT_STATUS_INVALID_PARAMETER;
5270
5271                         /* If the name is the same just reply "ok".  Yes this
5272                            doesn't allow you to change the case of a group name. */
5273
5274                         if ( strequal( r->in.info->name.string, info.acct_name ) )
5275                                 return NT_STATUS_OK;
5276
5277                         fstrcpy( info.acct_name, r->in.info->name.string);
5278
5279                         /* make sure the name doesn't already exist as a user
5280                            or local group */
5281
5282                         fstr_sprintf( group_name, "%s\\%s", global_myname(), info.acct_name );
5283                         status = can_create( p->mem_ctx, group_name );
5284                         if ( !NT_STATUS_IS_OK( status ) )
5285                                 return status;
5286                         break;
5287                 }
5288                 case ALIASINFODESCRIPTION:
5289                         if (r->in.info->description.string) {
5290                                 fstrcpy(info.acct_desc,
5291                                         r->in.info->description.string);
5292                         } else {
5293                                 fstrcpy( info.acct_desc, "" );
5294                         }
5295                         break;
5296                 default:
5297                         return NT_STATUS_INVALID_INFO_CLASS;
5298         }
5299
5300         can_mod_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_add_users );
5301
5302         /******** BEGIN SeAddUsers BLOCK *********/
5303
5304         if ( can_mod_accounts )
5305                 become_root();
5306
5307         status = pdb_set_aliasinfo( &group_sid, &info );
5308
5309         if ( can_mod_accounts )
5310                 unbecome_root();
5311
5312         /******** End SeAddUsers BLOCK *********/
5313
5314         if (NT_STATUS_IS_OK(status))
5315                 force_flush_samr_cache(disp_info);
5316
5317         return status;
5318 }
5319
5320 /****************************************************************
5321  _samr_GetDomPwInfo
5322 ****************************************************************/
5323
5324 NTSTATUS _samr_GetDomPwInfo(pipes_struct *p,
5325                             struct samr_GetDomPwInfo *r)
5326 {
5327         /* Perform access check.  Since this rpc does not require a
5328            policy handle it will not be caught by the access checks on
5329            SAMR_CONNECT or SAMR_CONNECT_ANON. */
5330
5331         if (!pipe_access_check(p)) {
5332                 DEBUG(3, ("access denied to _samr_GetDomPwInfo\n"));
5333                 return NT_STATUS_ACCESS_DENIED;
5334         }
5335
5336         /* Actually, returning zeros here works quite well :-). */
5337         ZERO_STRUCTP(r->out.info);
5338
5339         return NT_STATUS_OK;
5340 }
5341
5342 /*********************************************************************
5343  _samr_OpenGroup
5344 *********************************************************************/
5345
5346 NTSTATUS _samr_OpenGroup(pipes_struct *p,
5347                          struct samr_OpenGroup *r)
5348
5349 {
5350         DOM_SID sid;
5351         DOM_SID info_sid;
5352         GROUP_MAP map;
5353         struct samr_info *info;
5354         SEC_DESC         *psd = NULL;
5355         uint32            acc_granted;
5356         uint32            des_access = r->in.access_mask;
5357         size_t            sd_size;
5358         NTSTATUS          status;
5359         fstring sid_string;
5360         bool ret;
5361         SE_PRIV se_rights;
5362
5363         if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &sid, &acc_granted, NULL))
5364                 return NT_STATUS_INVALID_HANDLE;
5365
5366         status = access_check_samr_function(acc_granted,
5367                                             SA_RIGHT_DOMAIN_OPEN_ACCOUNT,
5368                                             "_samr_OpenGroup");
5369
5370         if ( !NT_STATUS_IS_OK(status) )
5371                 return status;
5372
5373         /*check if access can be granted as requested by client. */
5374         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &grp_generic_mapping, NULL, 0);
5375         se_map_generic(&des_access,&grp_generic_mapping);
5376
5377         se_priv_copy( &se_rights, &se_add_users );
5378
5379         status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
5380                 &se_rights, GENERIC_RIGHTS_GROUP_WRITE, des_access,
5381                 &acc_granted, "_samr_OpenGroup");
5382
5383         if ( !NT_STATUS_IS_OK(status) )
5384                 return status;
5385
5386         /* this should not be hard-coded like this */
5387
5388         if (!sid_equal(&sid, get_global_sam_sid()))
5389                 return NT_STATUS_ACCESS_DENIED;
5390
5391         sid_copy(&info_sid, get_global_sam_sid());
5392         sid_append_rid(&info_sid, r->in.rid);
5393         sid_to_fstring(sid_string, &info_sid);
5394
5395         if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
5396                 return NT_STATUS_NO_MEMORY;
5397
5398         info->acc_granted = acc_granted;
5399
5400         DEBUG(10, ("_samr_OpenGroup:Opening SID: %s\n", sid_string));
5401
5402         /* check if that group really exists */
5403         become_root();
5404         ret = get_domain_group_from_sid(info->sid, &map);
5405         unbecome_root();
5406         if (!ret)
5407                 return NT_STATUS_NO_SUCH_GROUP;
5408
5409         /* get a (unique) handle.  open a policy on it. */
5410         if (!create_policy_hnd(p, r->out.group_handle, free_samr_info, (void *)info))
5411                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5412
5413         return NT_STATUS_OK;
5414 }
5415
5416 /*********************************************************************
5417  _samr_RemoveMemberFromForeignDomain
5418 *********************************************************************/
5419
5420 NTSTATUS _samr_RemoveMemberFromForeignDomain(pipes_struct *p,
5421                                              struct samr_RemoveMemberFromForeignDomain *r)
5422 {
5423         DOM_SID                 delete_sid, domain_sid;
5424         uint32                  acc_granted;
5425         NTSTATUS                result;
5426         DISP_INFO *disp_info = NULL;
5427
5428         sid_copy( &delete_sid, r->in.sid );
5429
5430         DEBUG(5,("_samr_RemoveMemberFromForeignDomain: removing SID [%s]\n",
5431                 sid_string_dbg(&delete_sid)));
5432
5433         /* Find the policy handle. Open a policy on it. */
5434
5435         if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &domain_sid,
5436                                      &acc_granted, &disp_info))
5437                 return NT_STATUS_INVALID_HANDLE;
5438
5439         result = access_check_samr_function(acc_granted,
5440                                             STD_RIGHT_DELETE_ACCESS,
5441                                             "_samr_RemoveMemberFromForeignDomain");
5442
5443         if (!NT_STATUS_IS_OK(result))
5444                 return result;
5445
5446         DEBUG(8, ("_samr_RemoveMemberFromForeignDomain: sid is %s\n",
5447                   sid_string_dbg(&domain_sid)));
5448
5449         /* we can only delete a user from a group since we don't have
5450            nested groups anyways.  So in the latter case, just say OK */
5451
5452         /* TODO: The above comment nowadays is bogus. Since we have nested
5453          * groups now, and aliases members are never reported out of the unix
5454          * group membership, the "just say OK" makes this call a no-op. For
5455          * us. This needs fixing however. */
5456
5457         /* I've only ever seen this in the wild when deleting a user from
5458          * usrmgr.exe. domain_sid is the builtin domain, and the sid to delete
5459          * is the user about to be deleted. I very much suspect this is the
5460          * only application of this call. To verify this, let people report
5461          * other cases. */
5462
5463         if (!sid_check_is_builtin(&domain_sid)) {
5464                 DEBUG(1,("_samr_RemoveMemberFromForeignDomain: domain_sid = %s, "
5465                          "global_sam_sid() = %s\n",
5466                          sid_string_dbg(&domain_sid),
5467                          sid_string_dbg(get_global_sam_sid())));
5468                 DEBUGADD(1,("please report to samba-technical@samba.org!\n"));
5469                 return NT_STATUS_OK;
5470         }
5471
5472         force_flush_samr_cache(disp_info);
5473
5474         result = NT_STATUS_OK;
5475
5476         return result;
5477 }
5478
5479 /*******************************************************************
5480  _samr_QueryDomainInfo2
5481  ********************************************************************/
5482
5483 NTSTATUS _samr_QueryDomainInfo2(pipes_struct *p,
5484                                 struct samr_QueryDomainInfo2 *r)
5485 {
5486         return samr_QueryDomainInfo_internal("_samr_QueryDomainInfo2",
5487                                              p,
5488                                              r->in.domain_handle,
5489                                              r->in.level,
5490                                              r->out.info);
5491 }
5492
5493 /*******************************************************************
5494  _samr_SetDomainInfo
5495  ********************************************************************/
5496
5497 NTSTATUS _samr_SetDomainInfo(pipes_struct *p,
5498                              struct samr_SetDomainInfo *r)
5499 {
5500         time_t u_expire, u_min_age;
5501         time_t u_logout;
5502         time_t u_lock_duration, u_reset_time;
5503
5504         DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
5505
5506         /* find the policy handle.  open a policy on it. */
5507         if (!find_policy_by_hnd(p, r->in.domain_handle, NULL))
5508                 return NT_STATUS_INVALID_HANDLE;
5509
5510         DEBUG(5,("_samr_SetDomainInfo: level: %d\n", r->in.level));
5511
5512         switch (r->in.level) {
5513                 case 0x01:
5514                         u_expire=nt_time_to_unix_abs((NTTIME *)&r->in.info->info1.max_password_age);
5515                         u_min_age=nt_time_to_unix_abs((NTTIME *)&r->in.info->info1.min_password_age);
5516                         pdb_set_account_policy(AP_MIN_PASSWORD_LEN, (uint32)r->in.info->info1.min_password_length);
5517                         pdb_set_account_policy(AP_PASSWORD_HISTORY, (uint32)r->in.info->info1.password_history_length);
5518                         pdb_set_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, (uint32)r->in.info->info1.password_properties);
5519                         pdb_set_account_policy(AP_MAX_PASSWORD_AGE, (int)u_expire);
5520                         pdb_set_account_policy(AP_MIN_PASSWORD_AGE, (int)u_min_age);
5521                         break;
5522                 case 0x02:
5523                         break;
5524                 case 0x03:
5525                         u_logout=nt_time_to_unix_abs((NTTIME *)&r->in.info->info3.force_logoff_time);
5526                         pdb_set_account_policy(AP_TIME_TO_LOGOUT, (int)u_logout);
5527                         break;
5528                 case 0x05:
5529                         break;
5530                 case 0x06:
5531                         break;
5532                 case 0x07:
5533                         break;
5534                 case 0x0c:
5535                         u_lock_duration=nt_time_to_unix_abs((NTTIME *)&r->in.info->info12.lockout_duration);
5536                         if (u_lock_duration != -1)
5537                                 u_lock_duration /= 60;
5538
5539                         u_reset_time=nt_time_to_unix_abs((NTTIME *)&r->in.info->info12.lockout_window)/60;
5540
5541                         pdb_set_account_policy(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
5542                         pdb_set_account_policy(AP_RESET_COUNT_TIME, (int)u_reset_time);
5543                         pdb_set_account_policy(AP_BAD_ATTEMPT_LOCKOUT, (uint32)r->in.info->info12.lockout_threshold);
5544                         break;
5545                 default:
5546                         return NT_STATUS_INVALID_INFO_CLASS;
5547         }
5548
5549         DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
5550
5551         return NT_STATUS_OK;
5552 }
5553
5554 /****************************************************************
5555 ****************************************************************/
5556
5557 NTSTATUS _samr_Shutdown(pipes_struct *p,
5558                         struct samr_Shutdown *r)
5559 {
5560         p->rng_fault_state = true;
5561         return NT_STATUS_NOT_IMPLEMENTED;
5562 }
5563
5564 /****************************************************************
5565 ****************************************************************/
5566
5567 NTSTATUS _samr_CreateUser(pipes_struct *p,
5568                           struct samr_CreateUser *r)
5569 {
5570         p->rng_fault_state = true;
5571         return NT_STATUS_NOT_IMPLEMENTED;
5572 }
5573
5574 /****************************************************************
5575 ****************************************************************/
5576
5577 NTSTATUS _samr_SetMemberAttributesOfGroup(pipes_struct *p,
5578                                           struct samr_SetMemberAttributesOfGroup *r)
5579 {
5580         p->rng_fault_state = true;
5581         return NT_STATUS_NOT_IMPLEMENTED;
5582 }
5583
5584 /****************************************************************
5585 ****************************************************************/
5586
5587 NTSTATUS _samr_ChangePasswordUser(pipes_struct *p,
5588                                   struct samr_ChangePasswordUser *r)
5589 {
5590         p->rng_fault_state = true;
5591         return NT_STATUS_NOT_IMPLEMENTED;
5592 }
5593
5594 /****************************************************************
5595 ****************************************************************/
5596
5597 NTSTATUS _samr_GetDisplayEnumerationIndex(pipes_struct *p,
5598                                           struct samr_GetDisplayEnumerationIndex *r)
5599 {
5600         p->rng_fault_state = true;
5601         return NT_STATUS_NOT_IMPLEMENTED;
5602 }
5603
5604 /****************************************************************
5605 ****************************************************************/
5606
5607 NTSTATUS _samr_TestPrivateFunctionsDomain(pipes_struct *p,
5608                                           struct samr_TestPrivateFunctionsDomain *r)
5609 {
5610         p->rng_fault_state = true;
5611         return NT_STATUS_NOT_IMPLEMENTED;
5612 }
5613
5614 /****************************************************************
5615 ****************************************************************/
5616
5617 NTSTATUS _samr_TestPrivateFunctionsUser(pipes_struct *p,
5618                                         struct samr_TestPrivateFunctionsUser *r)
5619 {
5620         p->rng_fault_state = true;
5621         return NT_STATUS_NOT_IMPLEMENTED;
5622 }
5623
5624 /****************************************************************
5625 ****************************************************************/
5626
5627 NTSTATUS _samr_QueryUserInfo2(pipes_struct *p,
5628                               struct samr_QueryUserInfo2 *r)
5629 {
5630         p->rng_fault_state = true;
5631         return NT_STATUS_NOT_IMPLEMENTED;
5632 }
5633
5634 /****************************************************************
5635 ****************************************************************/
5636
5637 NTSTATUS _samr_GetDisplayEnumerationIndex2(pipes_struct *p,
5638                                            struct samr_GetDisplayEnumerationIndex2 *r)
5639 {
5640         p->rng_fault_state = true;
5641         return NT_STATUS_NOT_IMPLEMENTED;
5642 }
5643
5644 /****************************************************************
5645 ****************************************************************/
5646
5647 NTSTATUS _samr_AddMultipleMembersToAlias(pipes_struct *p,
5648                                          struct samr_AddMultipleMembersToAlias *r)
5649 {
5650         p->rng_fault_state = true;
5651         return NT_STATUS_NOT_IMPLEMENTED;
5652 }
5653
5654 /****************************************************************
5655 ****************************************************************/
5656
5657 NTSTATUS _samr_RemoveMultipleMembersFromAlias(pipes_struct *p,
5658                                               struct samr_RemoveMultipleMembersFromAlias *r)
5659 {
5660         p->rng_fault_state = true;
5661         return NT_STATUS_NOT_IMPLEMENTED;
5662 }
5663
5664 /****************************************************************
5665 ****************************************************************/
5666
5667 NTSTATUS _samr_OemChangePasswordUser2(pipes_struct *p,
5668                                       struct samr_OemChangePasswordUser2 *r)
5669 {
5670         p->rng_fault_state = true;
5671         return NT_STATUS_NOT_IMPLEMENTED;
5672 }
5673
5674 /****************************************************************
5675 ****************************************************************/
5676
5677 NTSTATUS _samr_SetBootKeyInformation(pipes_struct *p,
5678                                      struct samr_SetBootKeyInformation *r)
5679 {
5680         p->rng_fault_state = true;
5681         return NT_STATUS_NOT_IMPLEMENTED;
5682 }
5683
5684 /****************************************************************
5685 ****************************************************************/
5686
5687 NTSTATUS _samr_GetBootKeyInformation(pipes_struct *p,
5688                                      struct samr_GetBootKeyInformation *r)
5689 {
5690         p->rng_fault_state = true;
5691         return NT_STATUS_NOT_IMPLEMENTED;
5692 }
5693
5694 /****************************************************************
5695 ****************************************************************/
5696
5697 NTSTATUS _samr_Connect3(pipes_struct *p,
5698                         struct samr_Connect3 *r)
5699 {
5700         p->rng_fault_state = true;
5701         return NT_STATUS_NOT_IMPLEMENTED;
5702 }
5703
5704 /****************************************************************
5705 ****************************************************************/
5706
5707 NTSTATUS _samr_RidToSid(pipes_struct *p,
5708                         struct samr_RidToSid *r)
5709 {
5710         p->rng_fault_state = true;
5711         return NT_STATUS_NOT_IMPLEMENTED;
5712 }
5713
5714 /****************************************************************
5715 ****************************************************************/
5716
5717 NTSTATUS _samr_SetDsrmPassword(pipes_struct *p,
5718                                struct samr_SetDsrmPassword *r)
5719 {
5720         p->rng_fault_state = true;
5721         return NT_STATUS_NOT_IMPLEMENTED;
5722 }
5723
5724 /****************************************************************
5725 ****************************************************************/
5726
5727 NTSTATUS _samr_ValidatePassword(pipes_struct *p,
5728                                 struct samr_ValidatePassword *r)
5729 {
5730         p->rng_fault_state = true;
5731         return NT_STATUS_NOT_IMPLEMENTED;
5732 }