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