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