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