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