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