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