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