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