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