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