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