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