a04584e7c158a217e44af64af17060fd7efa3083
[kai/samba.git] / source3 / rpc_server / srv_samr_nt.c
1 /*
2  *  Unix SMB/CIFS implementation.
3  *  RPC Pipe client / server routines
4  *  Copyright (C) Andrew Tridgell                   1992-1997,
5  *  Copyright (C) Luke Kenneth Casson Leighton      1996-1997,
6  *  Copyright (C) Paul Ashton                       1997,
7  *  Copyright (C) Marc Jacobsen                     1999,
8  *  Copyright (C) Jeremy Allison                    2001-2008,
9  *  Copyright (C) Jean Fran├žois Micouleau           1998-2001,
10  *  Copyright (C) Jim McDonough <jmcd@us.ibm.com>   2002,
11  *  Copyright (C) Gerald (Jerry) Carter             2003-2004,
12  *  Copyright (C) Simo Sorce                        2003.
13  *  Copyright (C) Volker Lendecke                   2005.
14  *  Copyright (C) Guenther Deschner                 2008.
15  *
16  *  This program is free software; you can redistribute it and/or modify
17  *  it under the terms of the GNU General Public License as published by
18  *  the Free Software Foundation; either version 3 of the License, or
19  *  (at your option) any later version.
20  *
21  *  This program is distributed in the hope that it will be useful,
22  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
23  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24  *  GNU General Public License for more details.
25  *
26  *  You should have received a copy of the GNU General Public License
27  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
28  */
29
30 /*
31  * This is the implementation of the SAMR code.
32  */
33
34 #include "includes.h"
35 #include "smbd/globals.h"
36 #include "../libcli/auth/libcli_auth.h"
37 #include "../librpc/gen_ndr/srv_samr.h"
38 #include "rpc_server/srv_samr_util.h"
39 #include "../lib/crypto/arcfour.h"
40 #include "secrets.h"
41 #include "rpc_client/init_lsa.h"
42 #include "../libcli/security/security.h"
43
44 #undef DBGC_CLASS
45 #define DBGC_CLASS DBGC_RPC_SRV
46
47 #define SAMR_USR_RIGHTS_WRITE_PW \
48                 ( READ_CONTROL_ACCESS           | \
49                   SAMR_USER_ACCESS_CHANGE_PASSWORD      | \
50                   SAMR_USER_ACCESS_SET_LOC_COM)
51 #define SAMR_USR_RIGHTS_CANT_WRITE_PW \
52                 ( READ_CONTROL_ACCESS | SAMR_USER_ACCESS_SET_LOC_COM )
53
54 #define DISP_INFO_CACHE_TIMEOUT 10
55
56 #define MAX_SAM_ENTRIES_W2K 0x400 /* 1024 */
57 #define MAX_SAM_ENTRIES_W95 50
58
59 struct samr_connect_info {
60         uint8_t dummy;
61 };
62
63 struct samr_domain_info {
64         struct dom_sid sid;
65         struct disp_info *disp_info;
66 };
67
68 struct samr_user_info {
69         struct dom_sid sid;
70 };
71
72 struct samr_group_info {
73         struct dom_sid sid;
74 };
75
76 struct samr_alias_info {
77         struct dom_sid sid;
78 };
79
80 typedef struct disp_info {
81         struct dom_sid sid; /* identify which domain this is. */
82         struct pdb_search *users; /* querydispinfo 1 and 4 */
83         struct pdb_search *machines; /* querydispinfo 2 */
84         struct pdb_search *groups; /* querydispinfo 3 and 5, enumgroups */
85         struct pdb_search *aliases; /* enumaliases */
86
87         uint32_t enum_acb_mask;
88         struct pdb_search *enum_users; /* enumusers with a mask */
89
90         struct timed_event *cache_timeout_event; /* cache idle timeout
91                                                   * handler. */
92 } DISP_INFO;
93
94 static const struct generic_mapping sam_generic_mapping = {
95         GENERIC_RIGHTS_SAM_READ,
96         GENERIC_RIGHTS_SAM_WRITE,
97         GENERIC_RIGHTS_SAM_EXECUTE,
98         GENERIC_RIGHTS_SAM_ALL_ACCESS};
99 static const struct generic_mapping dom_generic_mapping = {
100         GENERIC_RIGHTS_DOMAIN_READ,
101         GENERIC_RIGHTS_DOMAIN_WRITE,
102         GENERIC_RIGHTS_DOMAIN_EXECUTE,
103         GENERIC_RIGHTS_DOMAIN_ALL_ACCESS};
104 static const struct generic_mapping usr_generic_mapping = {
105         GENERIC_RIGHTS_USER_READ,
106         GENERIC_RIGHTS_USER_WRITE,
107         GENERIC_RIGHTS_USER_EXECUTE,
108         GENERIC_RIGHTS_USER_ALL_ACCESS};
109 static const struct generic_mapping usr_nopwchange_generic_mapping = {
110         GENERIC_RIGHTS_USER_READ,
111         GENERIC_RIGHTS_USER_WRITE,
112         GENERIC_RIGHTS_USER_EXECUTE & ~SAMR_USER_ACCESS_CHANGE_PASSWORD,
113         GENERIC_RIGHTS_USER_ALL_ACCESS};
114 static const struct generic_mapping grp_generic_mapping = {
115         GENERIC_RIGHTS_GROUP_READ,
116         GENERIC_RIGHTS_GROUP_WRITE,
117         GENERIC_RIGHTS_GROUP_EXECUTE,
118         GENERIC_RIGHTS_GROUP_ALL_ACCESS};
119 static const struct generic_mapping ali_generic_mapping = {
120         GENERIC_RIGHTS_ALIAS_READ,
121         GENERIC_RIGHTS_ALIAS_WRITE,
122         GENERIC_RIGHTS_ALIAS_EXECUTE,
123         GENERIC_RIGHTS_ALIAS_ALL_ACCESS};
124
125 /*******************************************************************
126 *******************************************************************/
127
128 static NTSTATUS make_samr_object_sd( TALLOC_CTX *ctx, struct security_descriptor **psd, size_t *sd_size,
129                                      const struct generic_mapping *map,
130                                      struct dom_sid *sid, uint32 sid_access )
131 {
132         struct dom_sid domadmin_sid;
133         struct security_ace ace[5];             /* at most 5 entries */
134         size_t i = 0;
135
136         struct security_acl *psa = NULL;
137
138         /* basic access for Everyone */
139
140         init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
141                         map->generic_execute | map->generic_read, 0);
142
143         /* add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
144
145         init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
146                         SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
147         init_sec_ace(&ace[i++], &global_sid_Builtin_Account_Operators,
148                         SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
149
150         /* Add Full Access for Domain Admins if we are a DC */
151
152         if ( IS_DC ) {
153                 sid_compose(&domadmin_sid, get_global_sam_sid(),
154                             DOMAIN_RID_ADMINS);
155                 init_sec_ace(&ace[i++], &domadmin_sid,
156                         SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
157         }
158
159         /* if we have a sid, give it some special access */
160
161         if ( sid ) {
162                 init_sec_ace(&ace[i++], sid, SEC_ACE_TYPE_ACCESS_ALLOWED, sid_access, 0);
163         }
164
165         /* create the security descriptor */
166
167         if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) == NULL)
168                 return NT_STATUS_NO_MEMORY;
169
170         if ((*psd = make_sec_desc(ctx, SECURITY_DESCRIPTOR_REVISION_1,
171                                   SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL,
172                                   psa, sd_size)) == NULL)
173                 return NT_STATUS_NO_MEMORY;
174
175         return NT_STATUS_OK;
176 }
177
178 /*******************************************************************
179  Checks if access to an object should be granted, and returns that
180  level of access for further checks.
181
182  If the user has either of needed_priv_1 or needed_priv_2 then they
183  get the rights in rights_mask in addition to any calulated rights.
184
185  This handles the unusual case where we need to allow two different
186  privileges to obtain exactly the same rights, which occours only in
187  SAMR.
188 ********************************************************************/
189
190 NTSTATUS access_check_object( struct security_descriptor *psd, struct security_token *token,
191                               enum sec_privilege needed_priv_1, enum sec_privilege needed_priv_2,
192                               uint32 rights_mask,
193                               uint32 des_access, uint32 *acc_granted,
194                               const char *debug )
195 {
196         NTSTATUS status = NT_STATUS_ACCESS_DENIED;
197         uint32 saved_mask = 0;
198
199         /* check privileges; certain SAM access bits should be overridden
200            by privileges (mostly having to do with creating/modifying/deleting
201            users and groups) */
202
203         if ((needed_priv_1 != SEC_PRIV_INVALID && security_token_has_privilege(token, needed_priv_1)) ||
204             (needed_priv_2 != SEC_PRIV_INVALID && security_token_has_privilege(token, needed_priv_2))) {
205                 saved_mask = (des_access & rights_mask);
206                 des_access &= ~saved_mask;
207
208                 DEBUG(4,("access_check_object: user rights access mask [0x%x]\n",
209                         rights_mask));
210         }
211
212
213         /* check the security descriptor first */
214
215         status = se_access_check(psd, token, des_access, acc_granted);
216         if (NT_STATUS_IS_OK(status)) {
217                 goto done;
218         }
219
220         /* give root a free pass */
221
222         if ( geteuid() == sec_initial_uid() ) {
223
224                 DEBUG(4,("%s: ACCESS should be DENIED  (requested: %#010x)\n", debug, des_access));
225                 DEBUGADD(4,("but overritten by euid == sec_initial_uid()\n"));
226
227                 *acc_granted = des_access;
228
229                 status = NT_STATUS_OK;
230                 goto done;
231         }
232
233
234 done:
235         /* add in any bits saved during the privilege check (only
236            matters is status is ok) */
237
238         *acc_granted |= rights_mask;
239
240         DEBUG(4,("%s: access %s (requested: 0x%08x, granted: 0x%08x)\n",
241                 debug, NT_STATUS_IS_OK(status) ? "GRANTED" : "DENIED",
242                 des_access, *acc_granted));
243
244         return status;
245 }
246
247
248 /*******************************************************************
249  Map any MAXIMUM_ALLOWED_ACCESS request to a valid access set.
250 ********************************************************************/
251
252 void map_max_allowed_access(const struct security_token *nt_token,
253                             const struct unix_user_token *unix_token,
254                             uint32_t *pacc_requested)
255 {
256         if (!((*pacc_requested) & MAXIMUM_ALLOWED_ACCESS)) {
257                 return;
258         }
259         *pacc_requested &= ~MAXIMUM_ALLOWED_ACCESS;
260
261         /* At least try for generic read|execute - Everyone gets that. */
262         *pacc_requested = GENERIC_READ_ACCESS|GENERIC_EXECUTE_ACCESS;
263
264         /* root gets anything. */
265         if (unix_token->uid == sec_initial_uid()) {
266                 *pacc_requested |= GENERIC_ALL_ACCESS;
267                 return;
268         }
269
270         /* Full Access for 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
271
272         if (security_token_has_sid(nt_token, &global_sid_Builtin_Administrators) ||
273                         security_token_has_sid(nt_token, &global_sid_Builtin_Account_Operators)) {
274                 *pacc_requested |= GENERIC_ALL_ACCESS;
275                 return;
276         }
277
278         /* Full access for DOMAIN\Domain Admins. */
279         if ( IS_DC ) {
280                 struct dom_sid domadmin_sid;
281                 sid_compose(&domadmin_sid, get_global_sam_sid(),
282                             DOMAIN_RID_ADMINS);
283                 if (security_token_has_sid(nt_token, &domadmin_sid)) {
284                         *pacc_requested |= GENERIC_ALL_ACCESS;
285                         return;
286                 }
287         }
288         /* TODO ! Check privileges. */
289 }
290
291 /*******************************************************************
292  Fetch or create a dispinfo struct.
293 ********************************************************************/
294
295 static DISP_INFO *get_samr_dispinfo_by_sid(const struct dom_sid *psid)
296 {
297         /*
298          * We do a static cache for DISP_INFO's here. Explanation can be found
299          * in Jeremy's checkin message to r11793:
300          *
301          * Fix the SAMR cache so it works across completely insane
302          * client behaviour (ie.:
303          * open pipe/open SAMR handle/enumerate 0 - 1024
304          * close SAMR handle, close pipe.
305          * open pipe/open SAMR handle/enumerate 1024 - 2048...
306          * close SAMR handle, close pipe.
307          * And on ad-nausium. Amazing.... probably object-oriented
308          * client side programming in action yet again.
309          * This change should *massively* improve performance when
310          * enumerating users from an LDAP database.
311          * Jeremy.
312          *
313          * "Our" and the builtin domain are the only ones where we ever
314          * enumerate stuff, so just cache 2 entries.
315          */
316
317         static struct disp_info *builtin_dispinfo;
318         static struct disp_info *domain_dispinfo;
319
320         /* There are two cases to consider here:
321            1) The SID is a domain SID and we look for an equality match, or
322            2) This is an account SID and so we return the DISP_INFO* for our
323               domain */
324
325         if (psid == NULL) {
326                 return NULL;
327         }
328
329         if (sid_check_is_builtin(psid) || sid_check_is_in_builtin(psid)) {
330                 /*
331                  * Necessary only once, but it does not really hurt.
332                  */
333                 if (builtin_dispinfo == NULL) {
334                         builtin_dispinfo = talloc_zero(NULL, struct disp_info);
335                         if (builtin_dispinfo == NULL) {
336                                 return NULL;
337                         }
338                 }
339                 sid_copy(&builtin_dispinfo->sid, &global_sid_Builtin);
340
341                 return builtin_dispinfo;
342         }
343
344         if (sid_check_is_domain(psid) || sid_check_is_in_our_domain(psid)) {
345                 /*
346                  * Necessary only once, but it does not really hurt.
347                  */
348                 if (domain_dispinfo == NULL) {
349                         domain_dispinfo = talloc_zero(NULL, struct disp_info);
350                         if (domain_dispinfo == NULL) {
351                                 return NULL;
352                         }
353                 }
354                 sid_copy(&domain_dispinfo->sid, get_global_sam_sid());
355
356                 return domain_dispinfo;
357         }
358
359         return NULL;
360 }
361
362 /*******************************************************************
363  Function to free the per SID data.
364  ********************************************************************/
365
366 static void free_samr_cache(DISP_INFO *disp_info)
367 {
368         DEBUG(10, ("free_samr_cache: deleting cache for SID %s\n",
369                    sid_string_dbg(&disp_info->sid)));
370
371         /* We need to become root here because the paged search might have to
372          * tell the LDAP server we're not interested in the rest anymore. */
373
374         become_root();
375
376         TALLOC_FREE(disp_info->users);
377         TALLOC_FREE(disp_info->machines);
378         TALLOC_FREE(disp_info->groups);
379         TALLOC_FREE(disp_info->aliases);
380         TALLOC_FREE(disp_info->enum_users);
381
382         unbecome_root();
383 }
384
385 /*******************************************************************
386  Idle event handler. Throw away the disp info cache.
387  ********************************************************************/
388
389 static void disp_info_cache_idle_timeout_handler(struct event_context *ev_ctx,
390                                                  struct timed_event *te,
391                                                  struct timeval now,
392                                                  void *private_data)
393 {
394         DISP_INFO *disp_info = (DISP_INFO *)private_data;
395
396         TALLOC_FREE(disp_info->cache_timeout_event);
397
398         DEBUG(10, ("disp_info_cache_idle_timeout_handler: caching timed "
399                    "out\n"));
400         free_samr_cache(disp_info);
401 }
402
403 /*******************************************************************
404  Setup cache removal idle event handler.
405  ********************************************************************/
406
407 static void set_disp_info_cache_timeout(DISP_INFO *disp_info, time_t secs_fromnow)
408 {
409         /* Remove any pending timeout and update. */
410
411         TALLOC_FREE(disp_info->cache_timeout_event);
412
413         DEBUG(10,("set_disp_info_cache_timeout: caching enumeration for "
414                   "SID %s for %u seconds\n", sid_string_dbg(&disp_info->sid),
415                   (unsigned int)secs_fromnow ));
416
417         disp_info->cache_timeout_event = event_add_timed(
418                 server_event_context(), NULL,
419                 timeval_current_ofs(secs_fromnow, 0),
420                 disp_info_cache_idle_timeout_handler, (void *)disp_info);
421 }
422
423 /*******************************************************************
424  Force flush any cache. We do this on any samr_set_xxx call.
425  We must also remove the timeout handler.
426  ********************************************************************/
427
428 static void force_flush_samr_cache(const struct dom_sid *sid)
429 {
430         struct disp_info *disp_info = get_samr_dispinfo_by_sid(sid);
431
432         if ((disp_info == NULL) || (disp_info->cache_timeout_event == NULL)) {
433                 return;
434         }
435
436         DEBUG(10,("force_flush_samr_cache: clearing idle event\n"));
437         TALLOC_FREE(disp_info->cache_timeout_event);
438         free_samr_cache(disp_info);
439 }
440
441 /*******************************************************************
442  Ensure password info is never given out. Paranioa... JRA.
443  ********************************************************************/
444
445 static void samr_clear_sam_passwd(struct samu *sam_pass)
446 {
447
448         if (!sam_pass)
449                 return;
450
451         /* These now zero out the old password */
452
453         pdb_set_lanman_passwd(sam_pass, NULL, PDB_DEFAULT);
454         pdb_set_nt_passwd(sam_pass, NULL, PDB_DEFAULT);
455 }
456
457 static uint32 count_sam_users(struct disp_info *info, uint32 acct_flags)
458 {
459         struct samr_displayentry *entry;
460
461         if (sid_check_is_builtin(&info->sid)) {
462                 /* No users in builtin. */
463                 return 0;
464         }
465
466         if (info->users == NULL) {
467                 info->users = pdb_search_users(info, acct_flags);
468                 if (info->users == NULL) {
469                         return 0;
470                 }
471         }
472         /* Fetch the last possible entry, thus trigger an enumeration */
473         pdb_search_entries(info->users, 0xffffffff, 1, &entry);
474
475         /* Ensure we cache this enumeration. */
476         set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
477
478         return info->users->num_entries;
479 }
480
481 static uint32 count_sam_groups(struct disp_info *info)
482 {
483         struct samr_displayentry *entry;
484
485         if (sid_check_is_builtin(&info->sid)) {
486                 /* No groups in builtin. */
487                 return 0;
488         }
489
490         if (info->groups == NULL) {
491                 info->groups = pdb_search_groups(info);
492                 if (info->groups == NULL) {
493                         return 0;
494                 }
495         }
496         /* Fetch the last possible entry, thus trigger an enumeration */
497         pdb_search_entries(info->groups, 0xffffffff, 1, &entry);
498
499         /* Ensure we cache this enumeration. */
500         set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
501
502         return info->groups->num_entries;
503 }
504
505 static uint32 count_sam_aliases(struct disp_info *info)
506 {
507         struct samr_displayentry *entry;
508
509         if (info->aliases == NULL) {
510                 info->aliases = pdb_search_aliases(info, &info->sid);
511                 if (info->aliases == NULL) {
512                         return 0;
513                 }
514         }
515         /* Fetch the last possible entry, thus trigger an enumeration */
516         pdb_search_entries(info->aliases, 0xffffffff, 1, &entry);
517
518         /* Ensure we cache this enumeration. */
519         set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
520
521         return info->aliases->num_entries;
522 }
523
524 /*******************************************************************
525  _samr_Close
526  ********************************************************************/
527
528 NTSTATUS _samr_Close(struct pipes_struct *p, struct samr_Close *r)
529 {
530         if (!close_policy_hnd(p, r->in.handle)) {
531                 return NT_STATUS_INVALID_HANDLE;
532         }
533
534         ZERO_STRUCTP(r->out.handle);
535
536         return NT_STATUS_OK;
537 }
538
539 /*******************************************************************
540  _samr_OpenDomain
541  ********************************************************************/
542
543 NTSTATUS _samr_OpenDomain(struct pipes_struct *p,
544                           struct samr_OpenDomain *r)
545 {
546         struct samr_connect_info *cinfo;
547         struct samr_domain_info *dinfo;
548         struct security_descriptor *psd = NULL;
549         uint32    acc_granted;
550         uint32    des_access = r->in.access_mask;
551         NTSTATUS  status;
552         size_t    sd_size;
553         uint32_t extra_access = SAMR_DOMAIN_ACCESS_CREATE_USER;
554
555         /* find the connection policy handle. */
556
557         cinfo = policy_handle_find(p, r->in.connect_handle, 0, NULL,
558                                    struct samr_connect_info, &status);
559         if (!NT_STATUS_IS_OK(status)) {
560                 return status;
561         }
562
563         /*check if access can be granted as requested by client. */
564         map_max_allowed_access(p->server_info->ptok,
565                                &p->server_info->utok,
566                                &des_access);
567
568         make_samr_object_sd( p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0 );
569         se_map_generic( &des_access, &dom_generic_mapping );
570
571         /*
572          * Users with SeAddUser get the ability to manipulate groups
573          * and aliases.
574          */
575         if (security_token_has_privilege(p->server_info->ptok, SEC_PRIV_ADD_USERS)) {
576                 extra_access |= (SAMR_DOMAIN_ACCESS_CREATE_GROUP |
577                                 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS |
578                                 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
579                                 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS |
580                                 SAMR_DOMAIN_ACCESS_CREATE_ALIAS);
581         }
582
583         /*
584          * Users with SeMachineAccount or SeAddUser get additional
585          * SAMR_DOMAIN_ACCESS_CREATE_USER access.
586          */
587
588         status = access_check_object( psd, p->server_info->ptok,
589                                       SEC_PRIV_MACHINE_ACCOUNT, SEC_PRIV_ADD_USERS,
590                                       extra_access, des_access,
591                                       &acc_granted, "_samr_OpenDomain" );
592
593         if ( !NT_STATUS_IS_OK(status) )
594                 return status;
595
596         if (!sid_check_is_domain(r->in.sid) &&
597             !sid_check_is_builtin(r->in.sid)) {
598                 return NT_STATUS_NO_SUCH_DOMAIN;
599         }
600
601         dinfo = policy_handle_create(p, r->out.domain_handle, acc_granted,
602                                      struct samr_domain_info, &status);
603         if (!NT_STATUS_IS_OK(status)) {
604                 return status;
605         }
606         dinfo->sid = *r->in.sid;
607         dinfo->disp_info = get_samr_dispinfo_by_sid(r->in.sid);
608
609         DEBUG(5,("_samr_OpenDomain: %d\n", __LINE__));
610
611         return NT_STATUS_OK;
612 }
613
614 /*******************************************************************
615  _samr_GetUserPwInfo
616  ********************************************************************/
617
618 NTSTATUS _samr_GetUserPwInfo(struct pipes_struct *p,
619                              struct samr_GetUserPwInfo *r)
620 {
621         struct samr_user_info *uinfo;
622         enum lsa_SidType sid_type;
623         uint32_t min_password_length = 0;
624         uint32_t password_properties = 0;
625         bool ret = false;
626         NTSTATUS status;
627
628         DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__));
629
630         uinfo = policy_handle_find(p, r->in.user_handle,
631                                    SAMR_USER_ACCESS_GET_ATTRIBUTES, NULL,
632                                    struct samr_user_info, &status);
633         if (!NT_STATUS_IS_OK(status)) {
634                 return status;
635         }
636
637         if (!sid_check_is_in_our_domain(&uinfo->sid)) {
638                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
639         }
640
641         become_root();
642         ret = lookup_sid(p->mem_ctx, &uinfo->sid, NULL, NULL, &sid_type);
643         unbecome_root();
644         if (ret == false) {
645                 return NT_STATUS_NO_SUCH_USER;
646         }
647
648         switch (sid_type) {
649                 case SID_NAME_USER:
650                         become_root();
651                         pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN,
652                                                &min_password_length);
653                         pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
654                                                &password_properties);
655                         unbecome_root();
656
657                         if (lp_check_password_script() && *lp_check_password_script()) {
658                                 password_properties |= DOMAIN_PASSWORD_COMPLEX;
659                         }
660
661                         break;
662                 default:
663                         break;
664         }
665
666         r->out.info->min_password_length = min_password_length;
667         r->out.info->password_properties = password_properties;
668
669         DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__));
670
671         return NT_STATUS_OK;
672 }
673
674 /*******************************************************************
675  _samr_SetSecurity
676  ********************************************************************/
677
678 NTSTATUS _samr_SetSecurity(struct pipes_struct *p,
679                            struct samr_SetSecurity *r)
680 {
681         struct samr_user_info *uinfo;
682         uint32 i;
683         struct security_acl *dacl;
684         bool ret;
685         struct samu *sampass=NULL;
686         NTSTATUS status;
687
688         uinfo = policy_handle_find(p, r->in.handle,
689                                    SAMR_USER_ACCESS_SET_ATTRIBUTES, NULL,
690                                    struct samr_user_info, &status);
691         if (!NT_STATUS_IS_OK(status)) {
692                 return status;
693         }
694
695         if (!(sampass = samu_new( p->mem_ctx))) {
696                 DEBUG(0,("No memory!\n"));
697                 return NT_STATUS_NO_MEMORY;
698         }
699
700         /* get the user record */
701         become_root();
702         ret = pdb_getsampwsid(sampass, &uinfo->sid);
703         unbecome_root();
704
705         if (!ret) {
706                 DEBUG(4, ("User %s not found\n",
707                           sid_string_dbg(&uinfo->sid)));
708                 TALLOC_FREE(sampass);
709                 return NT_STATUS_INVALID_HANDLE;
710         }
711
712         dacl = r->in.sdbuf->sd->dacl;
713         for (i=0; i < dacl->num_aces; i++) {
714                 if (dom_sid_equal(&uinfo->sid, &dacl->aces[i].trustee)) {
715                         ret = pdb_set_pass_can_change(sampass,
716                                 (dacl->aces[i].access_mask &
717                                  SAMR_USER_ACCESS_CHANGE_PASSWORD) ?
718                                                       True: False);
719                         break;
720                 }
721         }
722
723         if (!ret) {
724                 TALLOC_FREE(sampass);
725                 return NT_STATUS_ACCESS_DENIED;
726         }
727
728         become_root();
729         status = pdb_update_sam_account(sampass);
730         unbecome_root();
731
732         TALLOC_FREE(sampass);
733
734         return status;
735 }
736
737 /*******************************************************************
738   build correct perms based on policies and password times for _samr_query_sec_obj
739 *******************************************************************/
740 static bool check_change_pw_access(TALLOC_CTX *mem_ctx, struct dom_sid *user_sid)
741 {
742         struct samu *sampass=NULL;
743         bool ret;
744
745         if ( !(sampass = samu_new( mem_ctx )) ) {
746                 DEBUG(0,("No memory!\n"));
747                 return False;
748         }
749
750         become_root();
751         ret = pdb_getsampwsid(sampass, user_sid);
752         unbecome_root();
753
754         if (ret == False) {
755                 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
756                 TALLOC_FREE(sampass);
757                 return False;
758         }
759
760         DEBUG(3,("User:[%s]\n",  pdb_get_username(sampass) ));
761
762         if (pdb_get_pass_can_change(sampass)) {
763                 TALLOC_FREE(sampass);
764                 return True;
765         }
766         TALLOC_FREE(sampass);
767         return False;
768 }
769
770
771 /*******************************************************************
772  _samr_QuerySecurity
773  ********************************************************************/
774
775 NTSTATUS _samr_QuerySecurity(struct pipes_struct *p,
776                              struct samr_QuerySecurity *r)
777 {
778         struct samr_connect_info *cinfo;
779         struct samr_domain_info *dinfo;
780         struct samr_user_info *uinfo;
781         struct samr_group_info *ginfo;
782         struct samr_alias_info *ainfo;
783         NTSTATUS status;
784         struct security_descriptor * psd = NULL;
785         size_t sd_size = 0;
786
787         cinfo = policy_handle_find(p, r->in.handle,
788                                    SEC_STD_READ_CONTROL, NULL,
789                                    struct samr_connect_info, &status);
790         if (NT_STATUS_IS_OK(status)) {
791                 DEBUG(5,("_samr_QuerySecurity: querying security on SAM\n"));
792                 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size,
793                                              &sam_generic_mapping, NULL, 0);
794                 goto done;
795         }
796
797         dinfo = policy_handle_find(p, r->in.handle,
798                                    SEC_STD_READ_CONTROL, NULL,
799                                    struct samr_domain_info, &status);
800         if (NT_STATUS_IS_OK(status)) {
801                 DEBUG(5,("_samr_QuerySecurity: querying security on Domain "
802                          "with SID: %s\n", sid_string_dbg(&dinfo->sid)));
803                 /*
804                  * TODO: Builtin probably needs a different SD with restricted
805                  * write access
806                  */
807                 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size,
808                                              &dom_generic_mapping, NULL, 0);
809                 goto done;
810         }
811
812         uinfo = policy_handle_find(p, r->in.handle,
813                                    SEC_STD_READ_CONTROL, NULL,
814                                    struct samr_user_info, &status);
815         if (NT_STATUS_IS_OK(status)) {
816                 DEBUG(10,("_samr_QuerySecurity: querying security on user "
817                           "Object with SID: %s\n",
818                           sid_string_dbg(&uinfo->sid)));
819                 if (check_change_pw_access(p->mem_ctx, &uinfo->sid)) {
820                         status = make_samr_object_sd(
821                                 p->mem_ctx, &psd, &sd_size,
822                                 &usr_generic_mapping,
823                                 &uinfo->sid, SAMR_USR_RIGHTS_WRITE_PW);
824                 } else {
825                         status = make_samr_object_sd(
826                                 p->mem_ctx, &psd, &sd_size,
827                                 &usr_nopwchange_generic_mapping,
828                                 &uinfo->sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
829                 }
830                 goto done;
831         }
832
833         ginfo = policy_handle_find(p, r->in.handle,
834                                    SEC_STD_READ_CONTROL, NULL,
835                                    struct samr_group_info, &status);
836         if (NT_STATUS_IS_OK(status)) {
837                 /*
838                  * TODO: different SDs have to be generated for aliases groups
839                  * and users.  Currently all three get a default user SD
840                  */
841                 DEBUG(10,("_samr_QuerySecurity: querying security on group "
842                           "Object with SID: %s\n",
843                           sid_string_dbg(&ginfo->sid)));
844                 status = make_samr_object_sd(
845                         p->mem_ctx, &psd, &sd_size,
846                         &usr_nopwchange_generic_mapping,
847                         &ginfo->sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
848                 goto done;
849         }
850
851         ainfo = policy_handle_find(p, r->in.handle,
852                                    SEC_STD_READ_CONTROL, NULL,
853                                    struct samr_alias_info, &status);
854         if (NT_STATUS_IS_OK(status)) {
855                 /*
856                  * TODO: different SDs have to be generated for aliases groups
857                  * and users.  Currently all three get a default user SD
858                  */
859                 DEBUG(10,("_samr_QuerySecurity: querying security on alias "
860                           "Object with SID: %s\n",
861                           sid_string_dbg(&ainfo->sid)));
862                 status = make_samr_object_sd(
863                         p->mem_ctx, &psd, &sd_size,
864                         &usr_nopwchange_generic_mapping,
865                         &ainfo->sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
866                 goto done;
867         }
868
869         return NT_STATUS_OBJECT_TYPE_MISMATCH;
870 done:
871         if ((*r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
872                 return NT_STATUS_NO_MEMORY;
873
874         return status;
875 }
876
877 /*******************************************************************
878 makes a SAM_ENTRY / UNISTR2* structure from a user list.
879 ********************************************************************/
880
881 static NTSTATUS make_user_sam_entry_list(TALLOC_CTX *ctx,
882                                          struct samr_SamEntry **sam_pp,
883                                          uint32_t num_entries,
884                                          uint32_t start_idx,
885                                          struct samr_displayentry *entries)
886 {
887         uint32_t i;
888         struct samr_SamEntry *sam;
889
890         *sam_pp = NULL;
891
892         if (num_entries == 0) {
893                 return NT_STATUS_OK;
894         }
895
896         sam = TALLOC_ZERO_ARRAY(ctx, struct samr_SamEntry, num_entries);
897         if (sam == NULL) {
898                 DEBUG(0, ("make_user_sam_entry_list: TALLOC_ZERO failed!\n"));
899                 return NT_STATUS_NO_MEMORY;
900         }
901
902         for (i = 0; i < num_entries; i++) {
903 #if 0
904                 /*
905                  * usrmgr expects a non-NULL terminated string with
906                  * trust relationships
907                  */
908                 if (entries[i].acct_flags & ACB_DOMTRUST) {
909                         init_unistr2(&uni_temp_name, entries[i].account_name,
910                                      UNI_FLAGS_NONE);
911                 } else {
912                         init_unistr2(&uni_temp_name, entries[i].account_name,
913                                      UNI_STR_TERMINATE);
914                 }
915 #endif
916                 init_lsa_String(&sam[i].name, entries[i].account_name);
917                 sam[i].idx = entries[i].rid;
918         }
919
920         *sam_pp = sam;
921
922         return NT_STATUS_OK;
923 }
924
925 #define MAX_SAM_ENTRIES MAX_SAM_ENTRIES_W2K
926
927 /*******************************************************************
928  _samr_EnumDomainUsers
929  ********************************************************************/
930
931 NTSTATUS _samr_EnumDomainUsers(struct pipes_struct *p,
932                                struct samr_EnumDomainUsers *r)
933 {
934         NTSTATUS status;
935         struct samr_domain_info *dinfo;
936         int num_account;
937         uint32 enum_context = *r->in.resume_handle;
938         enum remote_arch_types ra_type = get_remote_arch();
939         int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
940         uint32 max_entries = max_sam_entries;
941         struct samr_displayentry *entries = NULL;
942         struct samr_SamArray *samr_array = NULL;
943         struct samr_SamEntry *samr_entries = NULL;
944
945         DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
946
947         dinfo = policy_handle_find(p, r->in.domain_handle,
948                                    SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
949                                    struct samr_domain_info, &status);
950         if (!NT_STATUS_IS_OK(status)) {
951                 return status;
952         }
953
954         samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
955         if (!samr_array) {
956                 return NT_STATUS_NO_MEMORY;
957         }
958         *r->out.sam = samr_array;
959
960         if (sid_check_is_builtin(&dinfo->sid)) {
961                 /* No users in builtin. */
962                 *r->out.resume_handle = *r->in.resume_handle;
963                 DEBUG(5,("_samr_EnumDomainUsers: No users in BUILTIN\n"));
964                 return status;
965         }
966
967         become_root();
968
969         /* AS ROOT !!!! */
970
971         if ((dinfo->disp_info->enum_users != NULL) &&
972             (dinfo->disp_info->enum_acb_mask != r->in.acct_flags)) {
973                 TALLOC_FREE(dinfo->disp_info->enum_users);
974         }
975
976         if (dinfo->disp_info->enum_users == NULL) {
977                 dinfo->disp_info->enum_users = pdb_search_users(
978                         dinfo->disp_info, r->in.acct_flags);
979                 dinfo->disp_info->enum_acb_mask = r->in.acct_flags;
980         }
981
982         if (dinfo->disp_info->enum_users == NULL) {
983                 /* END AS ROOT !!!! */
984                 unbecome_root();
985                 return NT_STATUS_ACCESS_DENIED;
986         }
987
988         num_account = pdb_search_entries(dinfo->disp_info->enum_users,
989                                          enum_context, max_entries,
990                                          &entries);
991
992         /* END AS ROOT !!!! */
993
994         unbecome_root();
995
996         if (num_account == 0) {
997                 DEBUG(5, ("_samr_EnumDomainUsers: enumeration handle over "
998                           "total entries\n"));
999                 *r->out.resume_handle = *r->in.resume_handle;
1000                 return NT_STATUS_OK;
1001         }
1002
1003         status = make_user_sam_entry_list(p->mem_ctx, &samr_entries,
1004                                           num_account, enum_context,
1005                                           entries);
1006         if (!NT_STATUS_IS_OK(status)) {
1007                 return status;
1008         }
1009
1010         if (max_entries <= num_account) {
1011                 status = STATUS_MORE_ENTRIES;
1012         } else {
1013                 status = NT_STATUS_OK;
1014         }
1015
1016         /* Ensure we cache this enumeration. */
1017         set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
1018
1019         DEBUG(5, ("_samr_EnumDomainUsers: %d\n", __LINE__));
1020
1021         samr_array->count = num_account;
1022         samr_array->entries = samr_entries;
1023
1024         *r->out.resume_handle = *r->in.resume_handle + num_account;
1025         *r->out.num_entries = num_account;
1026
1027         DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
1028
1029         return status;
1030 }
1031
1032 /*******************************************************************
1033 makes a SAM_ENTRY / UNISTR2* structure from a group list.
1034 ********************************************************************/
1035
1036 static void make_group_sam_entry_list(TALLOC_CTX *ctx,
1037                                       struct samr_SamEntry **sam_pp,
1038                                       uint32_t num_sam_entries,
1039                                       struct samr_displayentry *entries)
1040 {
1041         struct samr_SamEntry *sam;
1042         uint32_t i;
1043
1044         *sam_pp = NULL;
1045
1046         if (num_sam_entries == 0) {
1047                 return;
1048         }
1049
1050         sam = TALLOC_ZERO_ARRAY(ctx, struct samr_SamEntry, num_sam_entries);
1051         if (sam == NULL) {
1052                 return;
1053         }
1054
1055         for (i = 0; i < num_sam_entries; i++) {
1056                 /*
1057                  * JRA. I think this should include the null. TNG does not.
1058                  */
1059                 init_lsa_String(&sam[i].name, entries[i].account_name);
1060                 sam[i].idx = entries[i].rid;
1061         }
1062
1063         *sam_pp = sam;
1064 }
1065
1066 /*******************************************************************
1067  _samr_EnumDomainGroups
1068  ********************************************************************/
1069
1070 NTSTATUS _samr_EnumDomainGroups(struct pipes_struct *p,
1071                                 struct samr_EnumDomainGroups *r)
1072 {
1073         NTSTATUS status;
1074         struct samr_domain_info *dinfo;
1075         struct samr_displayentry *groups;
1076         uint32 num_groups;
1077         struct samr_SamArray *samr_array = NULL;
1078         struct samr_SamEntry *samr_entries = NULL;
1079
1080         dinfo = policy_handle_find(p, r->in.domain_handle,
1081                                    SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
1082                                    struct samr_domain_info, &status);
1083         if (!NT_STATUS_IS_OK(status)) {
1084                 return status;
1085         }
1086
1087         DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
1088
1089         samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
1090         if (!samr_array) {
1091                 return NT_STATUS_NO_MEMORY;
1092         }
1093         *r->out.sam = samr_array;
1094
1095         if (sid_check_is_builtin(&dinfo->sid)) {
1096                 /* No groups in builtin. */
1097                 *r->out.resume_handle = *r->in.resume_handle;
1098                 DEBUG(5,("_samr_EnumDomainGroups: No groups in BUILTIN\n"));
1099                 return status;
1100         }
1101
1102         /* the domain group array is being allocated in the function below */
1103
1104         become_root();
1105
1106         if (dinfo->disp_info->groups == NULL) {
1107                 dinfo->disp_info->groups = pdb_search_groups(dinfo->disp_info);
1108
1109                 if (dinfo->disp_info->groups == NULL) {
1110                         unbecome_root();
1111                         return NT_STATUS_ACCESS_DENIED;
1112                 }
1113         }
1114
1115         num_groups = pdb_search_entries(dinfo->disp_info->groups,
1116                                         *r->in.resume_handle,
1117                                         MAX_SAM_ENTRIES, &groups);
1118         unbecome_root();
1119
1120         /* Ensure we cache this enumeration. */
1121         set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
1122
1123         make_group_sam_entry_list(p->mem_ctx, &samr_entries,
1124                                   num_groups, groups);
1125
1126         if (MAX_SAM_ENTRIES <= num_groups) {
1127                 status = STATUS_MORE_ENTRIES;
1128         } else {
1129                 status = NT_STATUS_OK;
1130         }
1131
1132         samr_array->count = num_groups;
1133         samr_array->entries = samr_entries;
1134
1135         *r->out.num_entries = num_groups;
1136         *r->out.resume_handle = num_groups + *r->in.resume_handle;
1137
1138         DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
1139
1140         return status;
1141 }
1142
1143 /*******************************************************************
1144  _samr_EnumDomainAliases
1145  ********************************************************************/
1146
1147 NTSTATUS _samr_EnumDomainAliases(struct pipes_struct *p,
1148                                  struct samr_EnumDomainAliases *r)
1149 {
1150         NTSTATUS status;
1151         struct samr_domain_info *dinfo;
1152         struct samr_displayentry *aliases;
1153         uint32 num_aliases = 0;
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_EnumDomainAliases: sid %s\n",
1165                  sid_string_dbg(&dinfo->sid)));
1166
1167         samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
1168         if (!samr_array) {
1169                 return NT_STATUS_NO_MEMORY;
1170         }
1171
1172         become_root();
1173
1174         if (dinfo->disp_info->aliases == NULL) {
1175                 dinfo->disp_info->aliases = pdb_search_aliases(
1176                         dinfo->disp_info, &dinfo->sid);
1177                 if (dinfo->disp_info->aliases == NULL) {
1178                         unbecome_root();
1179                         return NT_STATUS_ACCESS_DENIED;
1180                 }
1181         }
1182
1183         num_aliases = pdb_search_entries(dinfo->disp_info->aliases,
1184                                          *r->in.resume_handle,
1185                                          MAX_SAM_ENTRIES, &aliases);
1186         unbecome_root();
1187
1188         /* Ensure we cache this enumeration. */
1189         set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
1190
1191         make_group_sam_entry_list(p->mem_ctx, &samr_entries,
1192                                   num_aliases, aliases);
1193
1194         DEBUG(5,("_samr_EnumDomainAliases: %d\n", __LINE__));
1195
1196         if (MAX_SAM_ENTRIES <= num_aliases) {
1197                 status = STATUS_MORE_ENTRIES;
1198         } else {
1199                 status = NT_STATUS_OK;
1200         }
1201
1202         samr_array->count = num_aliases;
1203         samr_array->entries = samr_entries;
1204
1205         *r->out.sam = samr_array;
1206         *r->out.num_entries = num_aliases;
1207         *r->out.resume_handle = num_aliases + *r->in.resume_handle;
1208
1209         return status;
1210 }
1211
1212 /*******************************************************************
1213  inits a samr_DispInfoGeneral structure.
1214 ********************************************************************/
1215
1216 static NTSTATUS init_samr_dispinfo_1(TALLOC_CTX *ctx,
1217                                      struct samr_DispInfoGeneral *r,
1218                                      uint32_t num_entries,
1219                                      uint32_t start_idx,
1220                                      struct samr_displayentry *entries)
1221 {
1222         uint32 i;
1223
1224         DEBUG(10, ("init_samr_dispinfo_1: num_entries: %d\n", num_entries));
1225
1226         if (num_entries == 0) {
1227                 return NT_STATUS_OK;
1228         }
1229
1230         r->count = num_entries;
1231
1232         r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryGeneral, num_entries);
1233         if (!r->entries) {
1234                 return NT_STATUS_NO_MEMORY;
1235         }
1236
1237         for (i = 0; i < num_entries ; i++) {
1238
1239                 init_lsa_String(&r->entries[i].account_name,
1240                                 entries[i].account_name);
1241
1242                 init_lsa_String(&r->entries[i].description,
1243                                 entries[i].description);
1244
1245                 init_lsa_String(&r->entries[i].full_name,
1246                                 entries[i].fullname);
1247
1248                 r->entries[i].rid = entries[i].rid;
1249                 r->entries[i].acct_flags = entries[i].acct_flags;
1250                 r->entries[i].idx = start_idx+i+1;
1251         }
1252
1253         return NT_STATUS_OK;
1254 }
1255
1256 /*******************************************************************
1257  inits a samr_DispInfoFull structure.
1258 ********************************************************************/
1259
1260 static NTSTATUS init_samr_dispinfo_2(TALLOC_CTX *ctx,
1261                                      struct samr_DispInfoFull *r,
1262                                      uint32_t num_entries,
1263                                      uint32_t start_idx,
1264                                      struct samr_displayentry *entries)
1265 {
1266         uint32_t i;
1267
1268         DEBUG(10, ("init_samr_dispinfo_2: num_entries: %d\n", num_entries));
1269
1270         if (num_entries == 0) {
1271                 return NT_STATUS_OK;
1272         }
1273
1274         r->count = num_entries;
1275
1276         r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryFull, num_entries);
1277         if (!r->entries) {
1278                 return NT_STATUS_NO_MEMORY;
1279         }
1280
1281         for (i = 0; i < num_entries ; i++) {
1282
1283                 init_lsa_String(&r->entries[i].account_name,
1284                                 entries[i].account_name);
1285
1286                 init_lsa_String(&r->entries[i].description,
1287                                 entries[i].description);
1288
1289                 r->entries[i].rid = entries[i].rid;
1290                 r->entries[i].acct_flags = entries[i].acct_flags;
1291                 r->entries[i].idx = start_idx+i+1;
1292         }
1293
1294         return NT_STATUS_OK;
1295 }
1296
1297 /*******************************************************************
1298  inits a samr_DispInfoFullGroups structure.
1299 ********************************************************************/
1300
1301 static NTSTATUS init_samr_dispinfo_3(TALLOC_CTX *ctx,
1302                                      struct samr_DispInfoFullGroups *r,
1303                                      uint32_t num_entries,
1304                                      uint32_t start_idx,
1305                                      struct samr_displayentry *entries)
1306 {
1307         uint32_t i;
1308
1309         DEBUG(5, ("init_samr_dispinfo_3: num_entries: %d\n", num_entries));
1310
1311         if (num_entries == 0) {
1312                 return NT_STATUS_OK;
1313         }
1314
1315         r->count = num_entries;
1316
1317         r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryFullGroup, num_entries);
1318         if (!r->entries) {
1319                 return NT_STATUS_NO_MEMORY;
1320         }
1321
1322         for (i = 0; i < num_entries ; i++) {
1323
1324                 init_lsa_String(&r->entries[i].account_name,
1325                                 entries[i].account_name);
1326
1327                 init_lsa_String(&r->entries[i].description,
1328                                 entries[i].description);
1329
1330                 r->entries[i].rid = entries[i].rid;
1331                 r->entries[i].acct_flags = entries[i].acct_flags;
1332                 r->entries[i].idx = start_idx+i+1;
1333         }
1334
1335         return NT_STATUS_OK;
1336 }
1337
1338 /*******************************************************************
1339  inits a samr_DispInfoAscii structure.
1340 ********************************************************************/
1341
1342 static NTSTATUS init_samr_dispinfo_4(TALLOC_CTX *ctx,
1343                                      struct samr_DispInfoAscii *r,
1344                                      uint32_t num_entries,
1345                                      uint32_t start_idx,
1346                                      struct samr_displayentry *entries)
1347 {
1348         uint32_t i;
1349
1350         DEBUG(5, ("init_samr_dispinfo_4: num_entries: %d\n", num_entries));
1351
1352         if (num_entries == 0) {
1353                 return NT_STATUS_OK;
1354         }
1355
1356         r->count = num_entries;
1357
1358         r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryAscii, num_entries);
1359         if (!r->entries) {
1360                 return NT_STATUS_NO_MEMORY;
1361         }
1362
1363         for (i = 0; i < num_entries ; i++) {
1364
1365                 init_lsa_AsciiStringLarge(&r->entries[i].account_name,
1366                                           entries[i].account_name);
1367
1368                 r->entries[i].idx = start_idx+i+1;
1369         }
1370
1371         return NT_STATUS_OK;
1372 }
1373
1374 /*******************************************************************
1375  inits a samr_DispInfoAscii structure.
1376 ********************************************************************/
1377
1378 static NTSTATUS init_samr_dispinfo_5(TALLOC_CTX *ctx,
1379                                      struct samr_DispInfoAscii *r,
1380                                      uint32_t num_entries,
1381                                      uint32_t start_idx,
1382                                      struct samr_displayentry *entries)
1383 {
1384         uint32_t i;
1385
1386         DEBUG(5, ("init_samr_dispinfo_5: num_entries: %d\n", num_entries));
1387
1388         if (num_entries == 0) {
1389                 return NT_STATUS_OK;
1390         }
1391
1392         r->count = num_entries;
1393
1394         r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryAscii, num_entries);
1395         if (!r->entries) {
1396                 return NT_STATUS_NO_MEMORY;
1397         }
1398
1399         for (i = 0; i < num_entries ; i++) {
1400
1401                 init_lsa_AsciiStringLarge(&r->entries[i].account_name,
1402                                           entries[i].account_name);
1403
1404                 r->entries[i].idx = start_idx+i+1;
1405         }
1406
1407         return NT_STATUS_OK;
1408 }
1409
1410 /*******************************************************************
1411  _samr_QueryDisplayInfo
1412  ********************************************************************/
1413
1414 NTSTATUS _samr_QueryDisplayInfo(struct pipes_struct *p,
1415                                 struct samr_QueryDisplayInfo *r)
1416 {
1417         NTSTATUS status;
1418         struct samr_domain_info *dinfo;
1419         uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
1420
1421         uint32 max_entries = r->in.max_entries;
1422
1423         union samr_DispInfo *disp_info = r->out.info;
1424
1425         uint32 temp_size=0;
1426         NTSTATUS disp_ret = NT_STATUS_UNSUCCESSFUL;
1427         uint32 num_account = 0;
1428         enum remote_arch_types ra_type = get_remote_arch();
1429         int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
1430         struct samr_displayentry *entries = NULL;
1431
1432         DEBUG(5,("_samr_QueryDisplayInfo: %d\n", __LINE__));
1433
1434         dinfo = policy_handle_find(p, r->in.domain_handle,
1435                                    SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
1436                                    struct samr_domain_info, &status);
1437         if (!NT_STATUS_IS_OK(status)) {
1438                 return status;
1439         }
1440
1441         if (sid_check_is_builtin(&dinfo->sid)) {
1442                 DEBUG(5,("_samr_QueryDisplayInfo: no users in BUILTIN\n"));
1443                 return NT_STATUS_OK;
1444         }
1445
1446         /*
1447          * calculate how many entries we will return.
1448          * based on
1449          * - the number of entries the client asked
1450          * - our limit on that
1451          * - the starting point (enumeration context)
1452          * - the buffer size the client will accept
1453          */
1454
1455         /*
1456          * We are a lot more like W2K. Instead of reading the SAM
1457          * each time to find the records we need to send back,
1458          * we read it once and link that copy to the sam handle.
1459          * For large user list (over the MAX_SAM_ENTRIES)
1460          * it's a definitive win.
1461          * second point to notice: between enumerations
1462          * our sam is now the same as it's a snapshoot.
1463          * third point: got rid of the static SAM_USER_21 struct
1464          * no more intermediate.
1465          * con: it uses much more memory, as a full copy is stored
1466          * in memory.
1467          *
1468          * If you want to change it, think twice and think
1469          * of the second point , that's really important.
1470          *
1471          * JFM, 12/20/2001
1472          */
1473
1474         if ((r->in.level < 1) || (r->in.level > 5)) {
1475                 DEBUG(0,("_samr_QueryDisplayInfo: Unknown info level (%u)\n",
1476                          (unsigned int)r->in.level ));
1477                 return NT_STATUS_INVALID_INFO_CLASS;
1478         }
1479
1480         /* first limit the number of entries we will return */
1481         if (r->in.max_entries > max_sam_entries) {
1482                 DEBUG(5, ("_samr_QueryDisplayInfo: client requested %d "
1483                           "entries, limiting to %d\n", r->in.max_entries,
1484                           max_sam_entries));
1485                 max_entries = max_sam_entries;
1486         }
1487
1488         /* calculate the size and limit on the number of entries we will
1489          * return */
1490
1491         temp_size=max_entries*struct_size;
1492
1493         if (temp_size > r->in.buf_size) {
1494                 max_entries = MIN((r->in.buf_size / struct_size),max_entries);;
1495                 DEBUG(5, ("_samr_QueryDisplayInfo: buffer size limits to "
1496                           "only %d entries\n", max_entries));
1497         }
1498
1499         become_root();
1500
1501         /* THe following done as ROOT. Don't return without unbecome_root(). */
1502
1503         switch (r->in.level) {
1504         case 1:
1505         case 4:
1506                 if (dinfo->disp_info->users == NULL) {
1507                         dinfo->disp_info->users = pdb_search_users(
1508                                 dinfo->disp_info, ACB_NORMAL);
1509                         if (dinfo->disp_info->users == NULL) {
1510                                 unbecome_root();
1511                                 return NT_STATUS_ACCESS_DENIED;
1512                         }
1513                         DEBUG(10,("_samr_QueryDisplayInfo: starting user enumeration at index %u\n",
1514                                 (unsigned  int)r->in.start_idx));
1515                 } else {
1516                         DEBUG(10,("_samr_QueryDisplayInfo: using cached user enumeration at index %u\n",
1517                                 (unsigned  int)r->in.start_idx));
1518                 }
1519
1520                 num_account = pdb_search_entries(dinfo->disp_info->users,
1521                                                  r->in.start_idx, max_entries,
1522                                                  &entries);
1523                 break;
1524         case 2:
1525                 if (dinfo->disp_info->machines == NULL) {
1526                         dinfo->disp_info->machines = pdb_search_users(
1527                                 dinfo->disp_info, ACB_WSTRUST|ACB_SVRTRUST);
1528                         if (dinfo->disp_info->machines == NULL) {
1529                                 unbecome_root();
1530                                 return NT_STATUS_ACCESS_DENIED;
1531                         }
1532                         DEBUG(10,("_samr_QueryDisplayInfo: starting machine enumeration at index %u\n",
1533                                 (unsigned  int)r->in.start_idx));
1534                 } else {
1535                         DEBUG(10,("_samr_QueryDisplayInfo: using cached machine enumeration at index %u\n",
1536                                 (unsigned  int)r->in.start_idx));
1537                 }
1538
1539                 num_account = pdb_search_entries(dinfo->disp_info->machines,
1540                                                  r->in.start_idx, max_entries,
1541                                                  &entries);
1542                 break;
1543         case 3:
1544         case 5:
1545                 if (dinfo->disp_info->groups == NULL) {
1546                         dinfo->disp_info->groups = pdb_search_groups(
1547                                 dinfo->disp_info);
1548                         if (dinfo->disp_info->groups == NULL) {
1549                                 unbecome_root();
1550                                 return NT_STATUS_ACCESS_DENIED;
1551                         }
1552                         DEBUG(10,("_samr_QueryDisplayInfo: starting group enumeration at index %u\n",
1553                                 (unsigned  int)r->in.start_idx));
1554                 } else {
1555                         DEBUG(10,("_samr_QueryDisplayInfo: using cached group enumeration at index %u\n",
1556                                 (unsigned  int)r->in.start_idx));
1557                 }
1558
1559                 num_account = pdb_search_entries(dinfo->disp_info->groups,
1560                                                  r->in.start_idx, max_entries,
1561                                                  &entries);
1562                 break;
1563         default:
1564                 unbecome_root();
1565                 smb_panic("info class changed");
1566                 break;
1567         }
1568         unbecome_root();
1569
1570
1571         /* Now create reply structure */
1572         switch (r->in.level) {
1573         case 1:
1574                 disp_ret = init_samr_dispinfo_1(p->mem_ctx, &disp_info->info1,
1575                                                 num_account, r->in.start_idx,
1576                                                 entries);
1577                 break;
1578         case 2:
1579                 disp_ret = init_samr_dispinfo_2(p->mem_ctx, &disp_info->info2,
1580                                                 num_account, r->in.start_idx,
1581                                                 entries);
1582                 break;
1583         case 3:
1584                 disp_ret = init_samr_dispinfo_3(p->mem_ctx, &disp_info->info3,
1585                                                 num_account, r->in.start_idx,
1586                                                 entries);
1587                 break;
1588         case 4:
1589                 disp_ret = init_samr_dispinfo_4(p->mem_ctx, &disp_info->info4,
1590                                                 num_account, r->in.start_idx,
1591                                                 entries);
1592                 break;
1593         case 5:
1594                 disp_ret = init_samr_dispinfo_5(p->mem_ctx, &disp_info->info5,
1595                                                 num_account, r->in.start_idx,
1596                                                 entries);
1597                 break;
1598         default:
1599                 smb_panic("info class changed");
1600                 break;
1601         }
1602
1603         if (!NT_STATUS_IS_OK(disp_ret))
1604                 return disp_ret;
1605
1606         if (max_entries <= num_account) {
1607                 status = STATUS_MORE_ENTRIES;
1608         } else {
1609                 status = NT_STATUS_OK;
1610         }
1611
1612         /* Ensure we cache this enumeration. */
1613         set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
1614
1615         DEBUG(5, ("_samr_QueryDisplayInfo: %d\n", __LINE__));
1616
1617         *r->out.total_size = num_account * struct_size;
1618         *r->out.returned_size = num_account ? temp_size : 0;
1619
1620         return status;
1621 }
1622
1623 /****************************************************************
1624  _samr_QueryDisplayInfo2
1625 ****************************************************************/
1626
1627 NTSTATUS _samr_QueryDisplayInfo2(struct pipes_struct *p,
1628                                  struct samr_QueryDisplayInfo2 *r)
1629 {
1630         struct samr_QueryDisplayInfo q;
1631
1632         q.in.domain_handle      = r->in.domain_handle;
1633         q.in.level              = r->in.level;
1634         q.in.start_idx          = r->in.start_idx;
1635         q.in.max_entries        = r->in.max_entries;
1636         q.in.buf_size           = r->in.buf_size;
1637
1638         q.out.total_size        = r->out.total_size;
1639         q.out.returned_size     = r->out.returned_size;
1640         q.out.info              = r->out.info;
1641
1642         return _samr_QueryDisplayInfo(p, &q);
1643 }
1644
1645 /****************************************************************
1646  _samr_QueryDisplayInfo3
1647 ****************************************************************/
1648
1649 NTSTATUS _samr_QueryDisplayInfo3(struct pipes_struct *p,
1650                                  struct samr_QueryDisplayInfo3 *r)
1651 {
1652         struct samr_QueryDisplayInfo q;
1653
1654         q.in.domain_handle      = r->in.domain_handle;
1655         q.in.level              = r->in.level;
1656         q.in.start_idx          = r->in.start_idx;
1657         q.in.max_entries        = r->in.max_entries;
1658         q.in.buf_size           = r->in.buf_size;
1659
1660         q.out.total_size        = r->out.total_size;
1661         q.out.returned_size     = r->out.returned_size;
1662         q.out.info              = r->out.info;
1663
1664         return _samr_QueryDisplayInfo(p, &q);
1665 }
1666
1667 /*******************************************************************
1668  _samr_QueryAliasInfo
1669  ********************************************************************/
1670
1671 NTSTATUS _samr_QueryAliasInfo(struct pipes_struct *p,
1672                               struct samr_QueryAliasInfo *r)
1673 {
1674         struct samr_alias_info *ainfo;
1675         struct acct_info info;
1676         NTSTATUS status;
1677         union samr_AliasInfo *alias_info = NULL;
1678         const char *alias_name = NULL;
1679         const char *alias_description = NULL;
1680
1681         DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1682
1683         ainfo = policy_handle_find(p, r->in.alias_handle,
1684                                    SAMR_ALIAS_ACCESS_LOOKUP_INFO, NULL,
1685                                    struct samr_alias_info, &status);
1686         if (!NT_STATUS_IS_OK(status)) {
1687                 return status;
1688         }
1689
1690         alias_info = TALLOC_ZERO_P(p->mem_ctx, union samr_AliasInfo);
1691         if (!alias_info) {
1692                 return NT_STATUS_NO_MEMORY;
1693         }
1694
1695         become_root();
1696         status = pdb_get_aliasinfo(&ainfo->sid, &info);
1697         unbecome_root();
1698
1699         if ( !NT_STATUS_IS_OK(status))
1700                 return status;
1701
1702         /* FIXME: info contains fstrings */
1703         alias_name = talloc_strdup(r, info.acct_name);
1704         alias_description = talloc_strdup(r, info.acct_desc);
1705
1706         switch (r->in.level) {
1707         case ALIASINFOALL:
1708                 alias_info->all.name.string             = alias_name;
1709                 alias_info->all.num_members             = 1; /* ??? */
1710                 alias_info->all.description.string      = alias_description;
1711                 break;
1712         case ALIASINFONAME:
1713                 alias_info->name.string                 = alias_name;
1714                 break;
1715         case ALIASINFODESCRIPTION:
1716                 alias_info->description.string          = alias_description;
1717                 break;
1718         default:
1719                 return NT_STATUS_INVALID_INFO_CLASS;
1720         }
1721
1722         *r->out.info = alias_info;
1723
1724         DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1725
1726         return NT_STATUS_OK;
1727 }
1728
1729 /*******************************************************************
1730  _samr_LookupNames
1731  ********************************************************************/
1732
1733 NTSTATUS _samr_LookupNames(struct pipes_struct *p,
1734                            struct samr_LookupNames *r)
1735 {
1736         struct samr_domain_info *dinfo;
1737         NTSTATUS status;
1738         uint32 *rid;
1739         enum lsa_SidType *type;
1740         int i;
1741         int num_rids = r->in.num_names;
1742         struct samr_Ids rids, types;
1743         uint32_t num_mapped = 0;
1744
1745         DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1746
1747         dinfo = policy_handle_find(p, r->in.domain_handle,
1748                                    0 /* Don't know the acc_bits yet */, NULL,
1749                                    struct samr_domain_info, &status);
1750         if (!NT_STATUS_IS_OK(status)) {
1751                 return status;
1752         }
1753
1754         if (num_rids > MAX_SAM_ENTRIES) {
1755                 num_rids = MAX_SAM_ENTRIES;
1756                 DEBUG(5,("_samr_LookupNames: truncating entries to %d\n", num_rids));
1757         }
1758
1759         rid = talloc_array(p->mem_ctx, uint32, num_rids);
1760         NT_STATUS_HAVE_NO_MEMORY(rid);
1761
1762         type = talloc_array(p->mem_ctx, enum lsa_SidType, num_rids);
1763         NT_STATUS_HAVE_NO_MEMORY(type);
1764
1765         DEBUG(5,("_samr_LookupNames: looking name on SID %s\n",
1766                  sid_string_dbg(&dinfo->sid)));
1767
1768         for (i = 0; i < num_rids; i++) {
1769
1770                 status = NT_STATUS_NONE_MAPPED;
1771                 type[i] = SID_NAME_UNKNOWN;
1772
1773                 rid[i] = 0xffffffff;
1774
1775                 if (sid_check_is_builtin(&dinfo->sid)) {
1776                         if (lookup_builtin_name(r->in.names[i].string,
1777                                                 &rid[i]))
1778                         {
1779                                 type[i] = SID_NAME_ALIAS;
1780                         }
1781                 } else {
1782                         lookup_global_sam_name(r->in.names[i].string, 0,
1783                                                &rid[i], &type[i]);
1784                 }
1785
1786                 if (type[i] != SID_NAME_UNKNOWN) {
1787                         num_mapped++;
1788                 }
1789         }
1790
1791         if (num_mapped == num_rids) {
1792                 status = NT_STATUS_OK;
1793         } else if (num_mapped == 0) {
1794                 status = NT_STATUS_NONE_MAPPED;
1795         } else {
1796                 status = STATUS_SOME_UNMAPPED;
1797         }
1798
1799         rids.count = num_rids;
1800         rids.ids = rid;
1801
1802         types.count = num_rids;
1803         types.ids = talloc_array(p->mem_ctx, uint32_t, num_rids);
1804         NT_STATUS_HAVE_NO_MEMORY(type);
1805         for (i = 0; i < num_rids; i++) {
1806                 types.ids[i] = (type[i] & 0xffffffff);
1807         }
1808
1809         *r->out.rids = rids;
1810         *r->out.types = types;
1811
1812         DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1813
1814         return status;
1815 }
1816
1817 /****************************************************************
1818  _samr_ChangePasswordUser
1819 ****************************************************************/
1820
1821 NTSTATUS _samr_ChangePasswordUser(struct pipes_struct *p,
1822                                   struct samr_ChangePasswordUser *r)
1823 {
1824         NTSTATUS status;
1825         bool ret = false;
1826         struct samr_user_info *uinfo;
1827         struct samu *pwd;
1828         struct samr_Password new_lmPwdHash, new_ntPwdHash, checkHash;
1829         struct samr_Password lm_pwd, nt_pwd;
1830
1831         uinfo = policy_handle_find(p, r->in.user_handle,
1832                                    SAMR_USER_ACCESS_SET_PASSWORD, NULL,
1833                                    struct samr_user_info, &status);
1834         if (!NT_STATUS_IS_OK(status)) {
1835                 return status;
1836         }
1837
1838         DEBUG(5,("_samr_ChangePasswordUser: sid:%s\n",
1839                   sid_string_dbg(&uinfo->sid)));
1840
1841         if (!(pwd = samu_new(NULL))) {
1842                 return NT_STATUS_NO_MEMORY;
1843         }
1844
1845         become_root();
1846         ret = pdb_getsampwsid(pwd, &uinfo->sid);
1847         unbecome_root();
1848
1849         if (!ret) {
1850                 TALLOC_FREE(pwd);
1851                 return NT_STATUS_WRONG_PASSWORD;
1852         }
1853
1854         {
1855                 const uint8_t *lm_pass, *nt_pass;
1856
1857                 lm_pass = pdb_get_lanman_passwd(pwd);
1858                 nt_pass = pdb_get_nt_passwd(pwd);
1859
1860                 if (!lm_pass || !nt_pass) {
1861                         status = NT_STATUS_WRONG_PASSWORD;
1862                         goto out;
1863                 }
1864
1865                 memcpy(&lm_pwd.hash, lm_pass, sizeof(lm_pwd.hash));
1866                 memcpy(&nt_pwd.hash, nt_pass, sizeof(nt_pwd.hash));
1867         }
1868
1869         /* basic sanity checking on parameters.  Do this before any database ops */
1870         if (!r->in.lm_present || !r->in.nt_present ||
1871             !r->in.old_lm_crypted || !r->in.new_lm_crypted ||
1872             !r->in.old_nt_crypted || !r->in.new_nt_crypted) {
1873                 /* we should really handle a change with lm not
1874                    present */
1875                 status = NT_STATUS_INVALID_PARAMETER_MIX;
1876                 goto out;
1877         }
1878
1879         /* decrypt and check the new lm hash */
1880         D_P16(lm_pwd.hash, r->in.new_lm_crypted->hash, new_lmPwdHash.hash);
1881         D_P16(new_lmPwdHash.hash, r->in.old_lm_crypted->hash, checkHash.hash);
1882         if (memcmp(checkHash.hash, lm_pwd.hash, 16) != 0) {
1883                 status = NT_STATUS_WRONG_PASSWORD;
1884                 goto out;
1885         }
1886
1887         /* decrypt and check the new nt hash */
1888         D_P16(nt_pwd.hash, r->in.new_nt_crypted->hash, new_ntPwdHash.hash);
1889         D_P16(new_ntPwdHash.hash, r->in.old_nt_crypted->hash, checkHash.hash);
1890         if (memcmp(checkHash.hash, nt_pwd.hash, 16) != 0) {
1891                 status = NT_STATUS_WRONG_PASSWORD;
1892                 goto out;
1893         }
1894
1895         /* The NT Cross is not required by Win2k3 R2, but if present
1896            check the nt cross hash */
1897         if (r->in.cross1_present && r->in.nt_cross) {
1898                 D_P16(lm_pwd.hash, r->in.nt_cross->hash, checkHash.hash);
1899                 if (memcmp(checkHash.hash, new_ntPwdHash.hash, 16) != 0) {
1900                         status = NT_STATUS_WRONG_PASSWORD;
1901                         goto out;
1902                 }
1903         }
1904
1905         /* The LM Cross is not required by Win2k3 R2, but if present
1906            check the lm cross hash */
1907         if (r->in.cross2_present && r->in.lm_cross) {
1908                 D_P16(nt_pwd.hash, r->in.lm_cross->hash, checkHash.hash);
1909                 if (memcmp(checkHash.hash, new_lmPwdHash.hash, 16) != 0) {
1910                         status = NT_STATUS_WRONG_PASSWORD;
1911                         goto out;
1912                 }
1913         }
1914
1915         if (!pdb_set_nt_passwd(pwd, new_ntPwdHash.hash, PDB_CHANGED) ||
1916             !pdb_set_lanman_passwd(pwd, new_lmPwdHash.hash, PDB_CHANGED)) {
1917                 status = NT_STATUS_ACCESS_DENIED;
1918                 goto out;
1919         }
1920
1921         status = pdb_update_sam_account(pwd);
1922  out:
1923         TALLOC_FREE(pwd);
1924
1925         return status;
1926 }
1927
1928 /*******************************************************************
1929  _samr_ChangePasswordUser2
1930  ********************************************************************/
1931
1932 NTSTATUS _samr_ChangePasswordUser2(struct pipes_struct *p,
1933                                    struct samr_ChangePasswordUser2 *r)
1934 {
1935         NTSTATUS status;
1936         fstring user_name;
1937         fstring wks;
1938
1939         DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1940
1941         fstrcpy(user_name, r->in.account->string);
1942         fstrcpy(wks, r->in.server->string);
1943
1944         DEBUG(5,("_samr_ChangePasswordUser2: user: %s wks: %s\n", user_name, wks));
1945
1946         /*
1947          * Pass the user through the NT -> unix user mapping
1948          * function.
1949          */
1950
1951         (void)map_username(user_name);
1952
1953         /*
1954          * UNIX username case mangling not required, pass_oem_change
1955          * is case insensitive.
1956          */
1957
1958         status = pass_oem_change(user_name,
1959                                  p->client_id->name,
1960                                  r->in.lm_password->data,
1961                                  r->in.lm_verifier->hash,
1962                                  r->in.nt_password->data,
1963                                  r->in.nt_verifier->hash,
1964                                  NULL);
1965
1966         DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1967
1968         if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
1969                 return NT_STATUS_WRONG_PASSWORD;
1970         }
1971
1972         return status;
1973 }
1974
1975 /****************************************************************
1976  _samr_OemChangePasswordUser2
1977 ****************************************************************/
1978
1979 NTSTATUS _samr_OemChangePasswordUser2(struct pipes_struct *p,
1980                                       struct samr_OemChangePasswordUser2 *r)
1981 {
1982         NTSTATUS status;
1983         fstring user_name;
1984         const char *wks = NULL;
1985
1986         DEBUG(5,("_samr_OemChangePasswordUser2: %d\n", __LINE__));
1987
1988         fstrcpy(user_name, r->in.account->string);
1989         if (r->in.server && r->in.server->string) {
1990                 wks = r->in.server->string;
1991         }
1992
1993         DEBUG(5,("_samr_OemChangePasswordUser2: user: %s wks: %s\n", user_name, wks));
1994
1995         /*
1996          * Pass the user through the NT -> unix user mapping
1997          * function.
1998          */
1999
2000         (void)map_username(user_name);
2001
2002         /*
2003          * UNIX username case mangling not required, pass_oem_change
2004          * is case insensitive.
2005          */
2006
2007         if (!r->in.hash || !r->in.password) {
2008                 return NT_STATUS_INVALID_PARAMETER;
2009         }
2010
2011         status = pass_oem_change(user_name,
2012                                  p->client_id->name,
2013                                  r->in.password->data,
2014                                  r->in.hash->hash,
2015                                  0,
2016                                  0,
2017                                  NULL);
2018
2019         if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
2020                 return NT_STATUS_WRONG_PASSWORD;
2021         }
2022
2023         DEBUG(5,("_samr_OemChangePasswordUser2: %d\n", __LINE__));
2024
2025         return status;
2026 }
2027
2028 /*******************************************************************
2029  _samr_ChangePasswordUser3
2030  ********************************************************************/
2031
2032 NTSTATUS _samr_ChangePasswordUser3(struct pipes_struct *p,
2033                                    struct samr_ChangePasswordUser3 *r)
2034 {
2035         NTSTATUS status;
2036         fstring user_name;
2037         const char *wks = NULL;
2038         enum samPwdChangeReason reject_reason;
2039         struct samr_DomInfo1 *dominfo = NULL;
2040         struct userPwdChangeFailureInformation *reject = NULL;
2041         uint32_t tmp;
2042
2043         DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
2044
2045         fstrcpy(user_name, r->in.account->string);
2046         if (r->in.server && r->in.server->string) {
2047                 wks = r->in.server->string;
2048         }
2049
2050         DEBUG(5,("_samr_ChangePasswordUser3: user: %s wks: %s\n", user_name, wks));
2051
2052         /*
2053          * Pass the user through the NT -> unix user mapping
2054          * function.
2055          */
2056
2057         (void)map_username(user_name);
2058
2059         /*
2060          * UNIX username case mangling not required, pass_oem_change
2061          * is case insensitive.
2062          */
2063
2064         status = pass_oem_change(user_name,
2065                                  p->client_id->name,
2066                                  r->in.lm_password->data,
2067                                  r->in.lm_verifier->hash,
2068                                  r->in.nt_password->data,
2069                                  r->in.nt_verifier->hash,
2070                                  &reject_reason);
2071         if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
2072                 return NT_STATUS_WRONG_PASSWORD;
2073         }
2074
2075         if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) ||
2076             NT_STATUS_EQUAL(status, NT_STATUS_ACCOUNT_RESTRICTION)) {
2077
2078                 time_t u_expire, u_min_age;
2079                 uint32 account_policy_temp;
2080
2081                 dominfo = TALLOC_ZERO_P(p->mem_ctx, struct samr_DomInfo1);
2082                 if (!dominfo) {
2083                         return NT_STATUS_NO_MEMORY;
2084                 }
2085
2086                 reject = TALLOC_ZERO_P(p->mem_ctx,
2087                                 struct userPwdChangeFailureInformation);
2088                 if (!reject) {
2089                         return NT_STATUS_NO_MEMORY;
2090                 }
2091
2092                 become_root();
2093
2094                 /* AS ROOT !!! */
2095
2096                 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN, &tmp);
2097                 dominfo->min_password_length = tmp;
2098
2099                 pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &tmp);
2100                 dominfo->password_history_length = tmp;
2101
2102                 pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
2103                                        &dominfo->password_properties);
2104
2105                 pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, &account_policy_temp);
2106                 u_expire = account_policy_temp;
2107
2108                 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, &account_policy_temp);
2109                 u_min_age = account_policy_temp;
2110
2111                 /* !AS ROOT */
2112
2113                 unbecome_root();
2114
2115                 unix_to_nt_time_abs((NTTIME *)&dominfo->max_password_age, u_expire);
2116                 unix_to_nt_time_abs((NTTIME *)&dominfo->min_password_age, u_min_age);
2117
2118                 if (lp_check_password_script() && *lp_check_password_script()) {
2119                         dominfo->password_properties |= DOMAIN_PASSWORD_COMPLEX;
2120                 }
2121
2122                 reject->extendedFailureReason = reject_reason;
2123
2124                 *r->out.dominfo = dominfo;
2125                 *r->out.reject = reject;
2126         }
2127
2128         DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
2129
2130         return status;
2131 }
2132
2133 /*******************************************************************
2134 makes a SAMR_R_LOOKUP_RIDS structure.
2135 ********************************************************************/
2136
2137 static bool make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names,
2138                                   const char **names,
2139                                   struct lsa_String **lsa_name_array_p)
2140 {
2141         struct lsa_String *lsa_name_array = NULL;
2142         uint32_t i;
2143
2144         *lsa_name_array_p = NULL;
2145
2146         if (num_names != 0) {
2147                 lsa_name_array = TALLOC_ZERO_ARRAY(ctx, struct lsa_String, num_names);
2148                 if (!lsa_name_array) {
2149                         return false;
2150                 }
2151         }
2152
2153         for (i = 0; i < num_names; i++) {
2154                 DEBUG(10, ("names[%d]:%s\n", i, names[i] && *names[i] ? names[i] : ""));
2155                 init_lsa_String(&lsa_name_array[i], names[i]);
2156         }
2157
2158         *lsa_name_array_p = lsa_name_array;
2159
2160         return true;
2161 }
2162
2163 /*******************************************************************
2164  _samr_LookupRids
2165  ********************************************************************/
2166
2167 NTSTATUS _samr_LookupRids(struct pipes_struct *p,
2168                           struct samr_LookupRids *r)
2169 {
2170         struct samr_domain_info *dinfo;
2171         NTSTATUS status;
2172         const char **names;
2173         enum lsa_SidType *attrs = NULL;
2174         uint32 *wire_attrs = NULL;
2175         int num_rids = (int)r->in.num_rids;
2176         int i;
2177         struct lsa_Strings names_array;
2178         struct samr_Ids types_array;
2179         struct lsa_String *lsa_names = NULL;
2180
2181         DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2182
2183         dinfo = policy_handle_find(p, r->in.domain_handle,
2184                                    0 /* Don't know the acc_bits yet */, NULL,
2185                                    struct samr_domain_info, &status);
2186         if (!NT_STATUS_IS_OK(status)) {
2187                 return status;
2188         }
2189
2190         if (num_rids > 1000) {
2191                 DEBUG(0, ("Got asked for %d rids (more than 1000) -- according "
2192                           "to samba4 idl this is not possible\n", num_rids));
2193                 return NT_STATUS_UNSUCCESSFUL;
2194         }
2195
2196         if (num_rids) {
2197                 names = TALLOC_ZERO_ARRAY(p->mem_ctx, const char *, num_rids);
2198                 attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, enum lsa_SidType, num_rids);
2199                 wire_attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_rids);
2200
2201                 if ((names == NULL) || (attrs == NULL) || (wire_attrs==NULL))
2202                         return NT_STATUS_NO_MEMORY;
2203         } else {
2204                 names = NULL;
2205                 attrs = NULL;
2206                 wire_attrs = NULL;
2207         }
2208
2209         become_root();  /* lookup_sid can require root privs */
2210         status = pdb_lookup_rids(&dinfo->sid, num_rids, r->in.rids,
2211                                  names, attrs);
2212         unbecome_root();
2213
2214         if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED) && (num_rids == 0)) {
2215                 status = NT_STATUS_OK;
2216         }
2217
2218         if (!make_samr_lookup_rids(p->mem_ctx, num_rids, names,
2219                                    &lsa_names)) {
2220                 return NT_STATUS_NO_MEMORY;
2221         }
2222
2223         /* Convert from enum lsa_SidType to uint32 for wire format. */
2224         for (i = 0; i < num_rids; i++) {
2225                 wire_attrs[i] = (uint32)attrs[i];
2226         }
2227
2228         names_array.count = num_rids;
2229         names_array.names = lsa_names;
2230
2231         types_array.count = num_rids;
2232         types_array.ids = wire_attrs;
2233
2234         *r->out.names = names_array;
2235         *r->out.types = types_array;
2236
2237         DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2238
2239         return status;
2240 }
2241
2242 /*******************************************************************
2243  _samr_OpenUser
2244 ********************************************************************/
2245
2246 NTSTATUS _samr_OpenUser(struct pipes_struct *p,
2247                         struct samr_OpenUser *r)
2248 {
2249         struct samu *sampass=NULL;
2250         struct dom_sid sid;
2251         struct samr_domain_info *dinfo;
2252         struct samr_user_info *uinfo;
2253         struct security_descriptor *psd = NULL;
2254         uint32    acc_granted;
2255         uint32    des_access = r->in.access_mask;
2256         uint32_t extra_access = 0;
2257         size_t    sd_size;
2258         bool ret;
2259         NTSTATUS nt_status;
2260
2261         /* These two privileges, if != SEC_PRIV_INVALID, indicate
2262          * privileges that the user must have to complete this
2263          * operation in defience of the fixed ACL */
2264         enum sec_privilege needed_priv_1, needed_priv_2;
2265         NTSTATUS status;
2266
2267         dinfo = policy_handle_find(p, r->in.domain_handle,
2268                                    SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
2269                                    struct samr_domain_info, &status);
2270         if (!NT_STATUS_IS_OK(status)) {
2271                 return status;
2272         }
2273
2274         if ( !(sampass = samu_new( p->mem_ctx )) ) {
2275                 return NT_STATUS_NO_MEMORY;
2276         }
2277
2278         /* append the user's RID to it */
2279
2280         if (!sid_compose(&sid, &dinfo->sid, r->in.rid))
2281                 return NT_STATUS_NO_SUCH_USER;
2282
2283         /* check if access can be granted as requested by client. */
2284         map_max_allowed_access(p->server_info->ptok,
2285                                &p->server_info->utok,
2286                                &des_access);
2287
2288         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &sid, SAMR_USR_RIGHTS_WRITE_PW);
2289         se_map_generic(&des_access, &usr_generic_mapping);
2290
2291         /*
2292          * Get the sampass first as we need to check privileges
2293          * based on what kind of user object this is.
2294          * But don't reveal info too early if it didn't exist.
2295          */
2296
2297         become_root();
2298         ret=pdb_getsampwsid(sampass, &sid);
2299         unbecome_root();
2300
2301         needed_priv_1 = SEC_PRIV_INVALID;
2302         needed_priv_2 = SEC_PRIV_INVALID;
2303         /*
2304          * We do the override access checks on *open*, not at
2305          * SetUserInfo time.
2306          */
2307         if (ret) {
2308                 uint32_t acb_info = pdb_get_acct_ctrl(sampass);
2309
2310                 if (acb_info & ACB_WSTRUST) {
2311                         /*
2312                          * SeMachineAccount is needed to add
2313                          * GENERIC_RIGHTS_USER_WRITE to a machine
2314                          * account.
2315                          */
2316                         needed_priv_1 = SEC_PRIV_MACHINE_ACCOUNT;
2317                 }
2318                 if (acb_info & ACB_NORMAL) {
2319                         /*
2320                          * SeAddUsers is needed to add
2321                          * GENERIC_RIGHTS_USER_WRITE to a normal
2322                          * account.
2323                          */
2324                         needed_priv_1 = SEC_PRIV_ADD_USERS;
2325                 }
2326                 /*
2327                  * Cheat - we have not set a specific privilege for
2328                  * server (BDC) or domain trust account, so allow
2329                  * GENERIC_RIGHTS_USER_WRITE if pipe user is in
2330                  * DOMAIN_RID_ADMINS.
2331                  */
2332                 if (acb_info & (ACB_SVRTRUST|ACB_DOMTRUST)) {
2333                         if (lp_enable_privileges() && nt_token_check_domain_rid(p->server_info->ptok,
2334                                                         DOMAIN_RID_ADMINS)) {
2335                                 des_access &= ~GENERIC_RIGHTS_USER_WRITE;
2336                                 extra_access = GENERIC_RIGHTS_USER_WRITE;
2337                                 DEBUG(4,("_samr_OpenUser: Allowing "
2338                                         "GENERIC_RIGHTS_USER_WRITE for "
2339                                         "rid admins\n"));
2340                         }
2341                 }
2342         }
2343
2344         TALLOC_FREE(sampass);
2345
2346         nt_status = access_check_object(psd, p->server_info->ptok,
2347                                         needed_priv_1, needed_priv_2,
2348                                         GENERIC_RIGHTS_USER_WRITE, des_access,
2349                                         &acc_granted, "_samr_OpenUser");
2350
2351         if ( !NT_STATUS_IS_OK(nt_status) )
2352                 return nt_status;
2353
2354         /* check that the SID exists in our domain. */
2355         if (ret == False) {
2356                 return NT_STATUS_NO_SUCH_USER;
2357         }
2358
2359         /* If we did the rid admins hack above, allow access. */
2360         acc_granted |= extra_access;
2361
2362         uinfo = policy_handle_create(p, r->out.user_handle, acc_granted,
2363                                      struct samr_user_info, &nt_status);
2364         if (!NT_STATUS_IS_OK(nt_status)) {
2365                 return nt_status;
2366         }
2367         uinfo->sid = sid;
2368
2369         return NT_STATUS_OK;
2370 }
2371
2372 /*************************************************************************
2373  *************************************************************************/
2374
2375 static NTSTATUS init_samr_parameters_string(TALLOC_CTX *mem_ctx,
2376                                             DATA_BLOB *blob,
2377                                             struct lsa_BinaryString **_r)
2378 {
2379         struct lsa_BinaryString *r;
2380
2381         if (!blob || !_r) {
2382                 return NT_STATUS_INVALID_PARAMETER;
2383         }
2384
2385         r = TALLOC_ZERO_P(mem_ctx, struct lsa_BinaryString);
2386         if (!r) {
2387                 return NT_STATUS_NO_MEMORY;
2388         }
2389
2390         r->array = TALLOC_ZERO_ARRAY(mem_ctx, uint16_t, blob->length/2);
2391         if (!r->array) {
2392                 return NT_STATUS_NO_MEMORY;
2393         }
2394         memcpy(r->array, blob->data, blob->length);
2395         r->size = blob->length;
2396         r->length = blob->length;
2397
2398         if (!r->array) {
2399                 return NT_STATUS_NO_MEMORY;
2400         }
2401
2402         *_r = r;
2403
2404         return NT_STATUS_OK;
2405 }
2406
2407 /*************************************************************************
2408  *************************************************************************/
2409
2410 static struct samr_LogonHours get_logon_hours_from_pdb(TALLOC_CTX *mem_ctx,
2411                                                        struct samu *pw)
2412 {
2413         struct samr_LogonHours hours;
2414         const int units_per_week = 168;
2415
2416         ZERO_STRUCT(hours);
2417         hours.bits = talloc_array(mem_ctx, uint8_t, units_per_week);
2418         if (!hours.bits) {
2419                 return hours;
2420         }
2421
2422         hours.units_per_week = units_per_week;
2423         memset(hours.bits, 0xFF, units_per_week);
2424
2425         if (pdb_get_hours(pw)) {
2426                 memcpy(hours.bits, pdb_get_hours(pw),
2427                        MIN(pdb_get_hours_len(pw), units_per_week));
2428         }
2429
2430         return hours;
2431 }
2432
2433 /*************************************************************************
2434  get_user_info_1.
2435  *************************************************************************/
2436
2437 static NTSTATUS get_user_info_1(TALLOC_CTX *mem_ctx,
2438                                 struct samr_UserInfo1 *r,
2439                                 struct samu *pw,
2440                                 struct dom_sid *domain_sid)
2441 {
2442         const struct dom_sid *sid_group;
2443         uint32_t primary_gid;
2444
2445         become_root();
2446         sid_group = pdb_get_group_sid(pw);
2447         unbecome_root();
2448
2449         if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2450                 DEBUG(0, ("get_user_info_1: User %s has Primary Group SID %s, \n"
2451                           "which conflicts with the domain sid %s.  Failing operation.\n",
2452                           pdb_get_username(pw), sid_string_dbg(sid_group),
2453                           sid_string_dbg(domain_sid)));
2454                 return NT_STATUS_UNSUCCESSFUL;
2455         }
2456
2457         r->account_name.string          = talloc_strdup(mem_ctx, pdb_get_username(pw));
2458         r->full_name.string             = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2459         r->primary_gid                  = primary_gid;
2460         r->description.string           = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2461         r->comment.string               = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2462
2463         return NT_STATUS_OK;
2464 }
2465
2466 /*************************************************************************
2467  get_user_info_2.
2468  *************************************************************************/
2469
2470 static NTSTATUS get_user_info_2(TALLOC_CTX *mem_ctx,
2471                                 struct samr_UserInfo2 *r,
2472                                 struct samu *pw)
2473 {
2474         r->comment.string               = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2475         r->reserved.string              = NULL;
2476         r->country_code                 = 0;
2477         r->code_page                    = 0;
2478
2479         return NT_STATUS_OK;
2480 }
2481
2482 /*************************************************************************
2483  get_user_info_3.
2484  *************************************************************************/
2485
2486 static NTSTATUS get_user_info_3(TALLOC_CTX *mem_ctx,
2487                                 struct samr_UserInfo3 *r,
2488                                 struct samu *pw,
2489                                 struct dom_sid *domain_sid)
2490 {
2491         const struct dom_sid *sid_user, *sid_group;
2492         uint32_t rid, primary_gid;
2493
2494         sid_user = pdb_get_user_sid(pw);
2495
2496         if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2497                 DEBUG(0, ("get_user_info_3: User %s has SID %s, \nwhich conflicts with "
2498                           "the domain sid %s.  Failing operation.\n",
2499                           pdb_get_username(pw), sid_string_dbg(sid_user),
2500                           sid_string_dbg(domain_sid)));
2501                 return NT_STATUS_UNSUCCESSFUL;
2502         }
2503
2504         become_root();
2505         sid_group = pdb_get_group_sid(pw);
2506         unbecome_root();
2507
2508         if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2509                 DEBUG(0, ("get_user_info_3: User %s has Primary Group SID %s, \n"
2510                           "which conflicts with the domain sid %s.  Failing operation.\n",
2511                           pdb_get_username(pw), sid_string_dbg(sid_group),
2512                           sid_string_dbg(domain_sid)));
2513                 return NT_STATUS_UNSUCCESSFUL;
2514         }
2515
2516         unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2517         unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2518         unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2519         unix_to_nt_time(&r->allow_password_change, pdb_get_pass_can_change_time(pw));
2520         unix_to_nt_time(&r->force_password_change, pdb_get_pass_must_change_time(pw));
2521
2522         r->account_name.string  = talloc_strdup(mem_ctx, pdb_get_username(pw));
2523         r->full_name.string     = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2524         r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2525         r->home_drive.string    = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2526         r->logon_script.string  = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2527         r->profile_path.string  = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2528         r->workstations.string  = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2529
2530         r->logon_hours          = get_logon_hours_from_pdb(mem_ctx, pw);
2531         r->rid                  = rid;
2532         r->primary_gid          = primary_gid;
2533         r->acct_flags           = pdb_get_acct_ctrl(pw);
2534         r->bad_password_count   = pdb_get_bad_password_count(pw);
2535         r->logon_count          = pdb_get_logon_count(pw);
2536
2537         return NT_STATUS_OK;
2538 }
2539
2540 /*************************************************************************
2541  get_user_info_4.
2542  *************************************************************************/
2543
2544 static NTSTATUS get_user_info_4(TALLOC_CTX *mem_ctx,
2545                                 struct samr_UserInfo4 *r,
2546                                 struct samu *pw)
2547 {
2548         r->logon_hours          = get_logon_hours_from_pdb(mem_ctx, pw);
2549
2550         return NT_STATUS_OK;
2551 }
2552
2553 /*************************************************************************
2554  get_user_info_5.
2555  *************************************************************************/
2556
2557 static NTSTATUS get_user_info_5(TALLOC_CTX *mem_ctx,
2558                                 struct samr_UserInfo5 *r,
2559                                 struct samu *pw,
2560                                 struct dom_sid *domain_sid)
2561 {
2562         const struct dom_sid *sid_user, *sid_group;
2563         uint32_t rid, primary_gid;
2564
2565         sid_user = pdb_get_user_sid(pw);
2566
2567         if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2568                 DEBUG(0, ("get_user_info_5: User %s has SID %s, \nwhich conflicts with "
2569                           "the domain sid %s.  Failing operation.\n",
2570                           pdb_get_username(pw), sid_string_dbg(sid_user),
2571                           sid_string_dbg(domain_sid)));
2572                 return NT_STATUS_UNSUCCESSFUL;
2573         }
2574
2575         become_root();
2576         sid_group = pdb_get_group_sid(pw);
2577         unbecome_root();
2578
2579         if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2580                 DEBUG(0, ("get_user_info_5: User %s has Primary Group SID %s, \n"
2581                           "which conflicts with the domain sid %s.  Failing operation.\n",
2582                           pdb_get_username(pw), sid_string_dbg(sid_group),
2583                           sid_string_dbg(domain_sid)));
2584                 return NT_STATUS_UNSUCCESSFUL;
2585         }
2586
2587         unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2588         unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2589         unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2590         unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2591
2592         r->account_name.string  = talloc_strdup(mem_ctx, pdb_get_username(pw));
2593         r->full_name.string     = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2594         r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2595         r->home_drive.string    = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2596         r->logon_script.string  = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2597         r->profile_path.string  = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2598         r->description.string   = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2599         r->workstations.string  = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2600
2601         r->logon_hours          = get_logon_hours_from_pdb(mem_ctx, pw);
2602         r->rid                  = rid;
2603         r->primary_gid          = primary_gid;
2604         r->acct_flags           = pdb_get_acct_ctrl(pw);
2605         r->bad_password_count   = pdb_get_bad_password_count(pw);
2606         r->logon_count          = pdb_get_logon_count(pw);
2607
2608         return NT_STATUS_OK;
2609 }
2610
2611 /*************************************************************************
2612  get_user_info_6.
2613  *************************************************************************/
2614
2615 static NTSTATUS get_user_info_6(TALLOC_CTX *mem_ctx,
2616                                 struct samr_UserInfo6 *r,
2617                                 struct samu *pw)
2618 {
2619         r->account_name.string  = talloc_strdup(mem_ctx, pdb_get_username(pw));
2620         r->full_name.string     = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2621
2622         return NT_STATUS_OK;
2623 }
2624
2625 /*************************************************************************
2626  get_user_info_7. Safe. Only gives out account_name.
2627  *************************************************************************/
2628
2629 static NTSTATUS get_user_info_7(TALLOC_CTX *mem_ctx,
2630                                 struct samr_UserInfo7 *r,
2631                                 struct samu *smbpass)
2632 {
2633         r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(smbpass));
2634         if (!r->account_name.string) {
2635                 return NT_STATUS_NO_MEMORY;
2636         }
2637
2638         return NT_STATUS_OK;
2639 }
2640
2641 /*************************************************************************
2642  get_user_info_8.
2643  *************************************************************************/
2644
2645 static NTSTATUS get_user_info_8(TALLOC_CTX *mem_ctx,
2646                                 struct samr_UserInfo8 *r,
2647                                 struct samu *pw)
2648 {
2649         r->full_name.string     = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2650
2651         return NT_STATUS_OK;
2652 }
2653
2654 /*************************************************************************
2655  get_user_info_9. Only gives out primary group SID.
2656  *************************************************************************/
2657
2658 static NTSTATUS get_user_info_9(TALLOC_CTX *mem_ctx,
2659                                 struct samr_UserInfo9 *r,
2660                                 struct samu *smbpass)
2661 {
2662         r->primary_gid = pdb_get_group_rid(smbpass);
2663
2664         return NT_STATUS_OK;
2665 }
2666
2667 /*************************************************************************
2668  get_user_info_10.
2669  *************************************************************************/
2670
2671 static NTSTATUS get_user_info_10(TALLOC_CTX *mem_ctx,
2672                                  struct samr_UserInfo10 *r,
2673                                  struct samu *pw)
2674 {
2675         r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2676         r->home_drive.string    = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2677
2678         return NT_STATUS_OK;
2679 }
2680
2681 /*************************************************************************
2682  get_user_info_11.
2683  *************************************************************************/
2684
2685 static NTSTATUS get_user_info_11(TALLOC_CTX *mem_ctx,
2686                                  struct samr_UserInfo11 *r,
2687                                  struct samu *pw)
2688 {
2689         r->logon_script.string  = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2690
2691         return NT_STATUS_OK;
2692 }
2693
2694 /*************************************************************************
2695  get_user_info_12.
2696  *************************************************************************/
2697
2698 static NTSTATUS get_user_info_12(TALLOC_CTX *mem_ctx,
2699                                  struct samr_UserInfo12 *r,
2700                                  struct samu *pw)
2701 {
2702         r->profile_path.string  = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2703
2704         return NT_STATUS_OK;
2705 }
2706
2707 /*************************************************************************
2708  get_user_info_13.
2709  *************************************************************************/
2710
2711 static NTSTATUS get_user_info_13(TALLOC_CTX *mem_ctx,
2712                                  struct samr_UserInfo13 *r,
2713                                  struct samu *pw)
2714 {
2715         r->description.string   = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2716
2717         return NT_STATUS_OK;
2718 }
2719
2720 /*************************************************************************
2721  get_user_info_14.
2722  *************************************************************************/
2723
2724 static NTSTATUS get_user_info_14(TALLOC_CTX *mem_ctx,
2725                                  struct samr_UserInfo14 *r,
2726                                  struct samu *pw)
2727 {
2728         r->workstations.string  = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2729
2730         return NT_STATUS_OK;
2731 }
2732
2733 /*************************************************************************
2734  get_user_info_16. Safe. Only gives out acb bits.
2735  *************************************************************************/
2736
2737 static NTSTATUS get_user_info_16(TALLOC_CTX *mem_ctx,
2738                                  struct samr_UserInfo16 *r,
2739                                  struct samu *smbpass)
2740 {
2741         r->acct_flags = pdb_get_acct_ctrl(smbpass);
2742
2743         return NT_STATUS_OK;
2744 }
2745
2746 /*************************************************************************
2747  get_user_info_17.
2748  *************************************************************************/
2749
2750 static NTSTATUS get_user_info_17(TALLOC_CTX *mem_ctx,
2751                                  struct samr_UserInfo17 *r,
2752                                  struct samu *pw)
2753 {
2754         unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2755
2756         return NT_STATUS_OK;
2757 }
2758
2759 /*************************************************************************
2760  get_user_info_18. OK - this is the killer as it gives out password info.
2761  Ensure that this is only allowed on an encrypted connection with a root
2762  user. JRA.
2763  *************************************************************************/
2764
2765 static NTSTATUS get_user_info_18(struct pipes_struct *p,
2766                                  TALLOC_CTX *mem_ctx,
2767                                  struct samr_UserInfo18 *r,
2768                                  struct dom_sid *user_sid)
2769 {
2770         struct samu *smbpass=NULL;
2771         bool ret;
2772         const uint8_t *nt_pass = NULL;
2773         const uint8_t *lm_pass = NULL;
2774
2775         ZERO_STRUCTP(r);
2776
2777         if (p->server_info->system) {
2778                 goto query;
2779         }
2780
2781         if ((p->auth.auth_type != DCERPC_AUTH_TYPE_NTLMSSP) ||
2782             (p->auth.auth_type != DCERPC_AUTH_TYPE_KRB5) ||
2783             (p->auth.auth_type != DCERPC_AUTH_TYPE_SPNEGO)) {
2784                 return NT_STATUS_ACCESS_DENIED;
2785         }
2786
2787         if (p->auth.auth_level != DCERPC_AUTH_LEVEL_PRIVACY) {
2788                 return NT_STATUS_ACCESS_DENIED;
2789         }
2790
2791  query:
2792         /*
2793          * Do *NOT* do become_root()/unbecome_root() here ! JRA.
2794          */
2795
2796         if ( !(smbpass = samu_new( mem_ctx )) ) {
2797                 return NT_STATUS_NO_MEMORY;
2798         }
2799
2800         ret = pdb_getsampwsid(smbpass, user_sid);
2801
2802         if (ret == False) {
2803                 DEBUG(4, ("User %s not found\n", sid_string_dbg(user_sid)));
2804                 TALLOC_FREE(smbpass);
2805                 return (geteuid() == sec_initial_uid()) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
2806         }
2807
2808         DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
2809
2810         if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
2811                 TALLOC_FREE(smbpass);
2812                 return NT_STATUS_ACCOUNT_DISABLED;
2813         }
2814
2815         lm_pass = pdb_get_lanman_passwd(smbpass);
2816         if (lm_pass != NULL) {
2817                 memcpy(r->lm_pwd.hash, lm_pass, 16);
2818                 r->lm_pwd_active = true;
2819         }
2820
2821         nt_pass = pdb_get_nt_passwd(smbpass);
2822         if (nt_pass != NULL) {
2823                 memcpy(r->nt_pwd.hash, nt_pass, 16);
2824                 r->nt_pwd_active = true;
2825         }
2826         r->password_expired = 0; /* FIXME */
2827
2828         TALLOC_FREE(smbpass);
2829
2830         return NT_STATUS_OK;
2831 }
2832
2833 /*************************************************************************
2834  get_user_info_20
2835  *************************************************************************/
2836
2837 static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx,
2838                                  struct samr_UserInfo20 *r,
2839                                  struct samu *sampass)
2840 {
2841         const char *munged_dial = NULL;
2842         DATA_BLOB blob;
2843         NTSTATUS status;
2844         struct lsa_BinaryString *parameters = NULL;
2845
2846         ZERO_STRUCTP(r);
2847
2848         munged_dial = pdb_get_munged_dial(sampass);
2849
2850         DEBUG(3,("User:[%s] has [%s] (length: %d)\n", pdb_get_username(sampass),
2851                 munged_dial, (int)strlen(munged_dial)));
2852
2853         if (munged_dial) {
2854                 blob = base64_decode_data_blob(munged_dial);
2855         } else {
2856                 blob = data_blob_string_const_null("");
2857         }
2858
2859         status = init_samr_parameters_string(mem_ctx, &blob, &parameters);
2860         data_blob_free(&blob);
2861         if (!NT_STATUS_IS_OK(status)) {
2862                 return status;
2863         }
2864
2865         r->parameters = *parameters;
2866
2867         return NT_STATUS_OK;
2868 }
2869
2870
2871 /*************************************************************************
2872  get_user_info_21
2873  *************************************************************************/
2874
2875 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx,
2876                                  struct samr_UserInfo21 *r,
2877                                  struct samu *pw,
2878                                  struct dom_sid *domain_sid,
2879                                  uint32_t acc_granted)
2880 {
2881         NTSTATUS status;
2882         const struct dom_sid *sid_user, *sid_group;
2883         uint32_t rid, primary_gid;
2884         NTTIME force_password_change;
2885         time_t must_change_time;
2886         struct lsa_BinaryString *parameters = NULL;
2887         const char *munged_dial = NULL;
2888         DATA_BLOB blob;
2889
2890         ZERO_STRUCTP(r);
2891
2892         sid_user = pdb_get_user_sid(pw);
2893
2894         if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2895                 DEBUG(0, ("get_user_info_21: User %s has SID %s, \nwhich conflicts with "
2896                           "the domain sid %s.  Failing operation.\n",
2897                           pdb_get_username(pw), sid_string_dbg(sid_user),
2898                           sid_string_dbg(domain_sid)));
2899                 return NT_STATUS_UNSUCCESSFUL;
2900         }
2901
2902         become_root();
2903         sid_group = pdb_get_group_sid(pw);
2904         unbecome_root();
2905
2906         if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2907                 DEBUG(0, ("get_user_info_21: User %s has Primary Group SID %s, \n"
2908                           "which conflicts with the domain sid %s.  Failing operation.\n",
2909                           pdb_get_username(pw), sid_string_dbg(sid_group),
2910                           sid_string_dbg(domain_sid)));
2911                 return NT_STATUS_UNSUCCESSFUL;
2912         }
2913
2914         unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2915         unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2916         unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2917         unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2918         unix_to_nt_time(&r->allow_password_change, pdb_get_pass_can_change_time(pw));
2919
2920         must_change_time = pdb_get_pass_must_change_time(pw);
2921         if (must_change_time == get_time_t_max()) {
2922                 unix_to_nt_time_abs(&force_password_change, must_change_time);
2923         } else {
2924                 unix_to_nt_time(&force_password_change, must_change_time);
2925         }
2926
2927         munged_dial = pdb_get_munged_dial(pw);
2928         if (munged_dial) {
2929                 blob = base64_decode_data_blob(munged_dial);
2930         } else {
2931                 blob = data_blob_string_const_null("");
2932         }
2933
2934         status = init_samr_parameters_string(mem_ctx, &blob, &parameters);
2935         data_blob_free(&blob);
2936         if (!NT_STATUS_IS_OK(status)) {
2937                 return status;
2938         }
2939
2940         r->force_password_change        = force_password_change;
2941
2942         r->account_name.string          = talloc_strdup(mem_ctx, pdb_get_username(pw));
2943         r->full_name.string             = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2944         r->home_directory.string        = talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2945         r->home_drive.string            = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2946         r->logon_script.string          = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2947         r->profile_path.string          = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2948         r->description.string           = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2949         r->workstations.string          = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2950         r->comment.string               = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2951
2952         r->logon_hours                  = get_logon_hours_from_pdb(mem_ctx, pw);
2953         r->parameters                   = *parameters;
2954         r->rid                          = rid;
2955         r->primary_gid                  = primary_gid;
2956         r->acct_flags                   = pdb_get_acct_ctrl(pw);
2957         r->bad_password_count           = pdb_get_bad_password_count(pw);
2958         r->logon_count                  = pdb_get_logon_count(pw);
2959         r->fields_present               = pdb_build_fields_present(pw);
2960         r->password_expired             = (pdb_get_pass_must_change_time(pw) == 0) ?
2961                                                 PASS_MUST_CHANGE_AT_NEXT_LOGON : 0;
2962         r->country_code                 = 0;
2963         r->code_page                    = 0;
2964         r->lm_password_set              = 0;
2965         r->nt_password_set              = 0;
2966
2967 #if 0
2968
2969         /*
2970           Look at a user on a real NT4 PDC with usrmgr, press
2971           'ok'. Then you will see that fields_present is set to
2972           0x08f827fa. Look at the user immediately after that again,
2973           and you will see that 0x00fffff is returned. This solves
2974           the problem that you get access denied after having looked
2975           at the user.
2976           -- Volker
2977         */
2978
2979 #endif
2980
2981
2982         return NT_STATUS_OK;
2983 }
2984
2985 /*******************************************************************
2986  _samr_QueryUserInfo
2987  ********************************************************************/
2988
2989 NTSTATUS _samr_QueryUserInfo(struct pipes_struct *p,
2990                              struct samr_QueryUserInfo *r)
2991 {
2992         NTSTATUS status;
2993         union samr_UserInfo *user_info = NULL;
2994         struct samr_user_info *uinfo;
2995         struct dom_sid domain_sid;
2996         uint32 rid;
2997         bool ret = false;
2998         struct samu *pwd = NULL;
2999         uint32_t acc_required, acc_granted;
3000
3001         switch (r->in.level) {
3002         case 1: /* UserGeneralInformation */
3003                 /* USER_READ_GENERAL */
3004                 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC;
3005                 break;
3006         case 2: /* UserPreferencesInformation */
3007                 /* USER_READ_PREFERENCES | USER_READ_GENERAL */
3008                 acc_required = SAMR_USER_ACCESS_GET_LOCALE |
3009                                SAMR_USER_ACCESS_GET_NAME_ETC;
3010                 break;
3011         case 3: /* UserLogonInformation */
3012                 /* USER_READ_GENERAL | USER_READ_PREFERENCES | USER_READ_LOGON | USER_READ_ACCOUNT */
3013                 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC |
3014                                SAMR_USER_ACCESS_GET_LOCALE |
3015                                SAMR_USER_ACCESS_GET_LOGONINFO |
3016                                SAMR_USER_ACCESS_GET_ATTRIBUTES;
3017                 break;
3018         case 4: /* UserLogonHoursInformation */
3019                 /* USER_READ_LOGON */
3020                 acc_required = SAMR_USER_ACCESS_GET_LOGONINFO;
3021                 break;
3022         case 5: /* UserAccountInformation */
3023                 /* USER_READ_GENERAL | USER_READ_PREFERENCES | USER_READ_LOGON | USER_READ_ACCOUNT */
3024                 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC |
3025                                SAMR_USER_ACCESS_GET_LOCALE |
3026                                SAMR_USER_ACCESS_GET_LOGONINFO |
3027                                SAMR_USER_ACCESS_GET_ATTRIBUTES;
3028                 break;
3029         case 6: /* UserNameInformation */
3030         case 7: /* UserAccountNameInformation */
3031         case 8: /* UserFullNameInformation */
3032         case 9: /* UserPrimaryGroupInformation */
3033         case 13: /* UserAdminCommentInformation */
3034                 /* USER_READ_GENERAL */
3035                 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC;
3036                 break;
3037         case 10: /* UserHomeInformation */
3038         case 11: /* UserScriptInformation */
3039         case 12: /* UserProfileInformation */
3040         case 14: /* UserWorkStationsInformation */
3041                 /* USER_READ_LOGON */
3042                 acc_required = SAMR_USER_ACCESS_GET_LOGONINFO;
3043                 break;
3044         case 16: /* UserControlInformation */
3045         case 17: /* UserExpiresInformation */
3046         case 20: /* UserParametersInformation */
3047                 /* USER_READ_ACCOUNT */
3048                 acc_required = SAMR_USER_ACCESS_GET_ATTRIBUTES;
3049                 break;
3050         case 21: /* UserAllInformation */
3051                 /* FIXME! - gd */
3052                 acc_required = SAMR_USER_ACCESS_GET_ATTRIBUTES;
3053                 break;
3054         case 18: /* UserInternal1Information */
3055                 /* FIXME! - gd */
3056                 acc_required = SAMR_USER_ACCESS_GET_ATTRIBUTES;
3057                 break;
3058         case 23: /* UserInternal4Information */
3059         case 24: /* UserInternal4InformationNew */
3060         case 25: /* UserInternal4InformationNew */
3061         case 26: /* UserInternal5InformationNew */
3062         default:
3063                 return NT_STATUS_INVALID_INFO_CLASS;
3064                 break;
3065         }
3066
3067         uinfo = policy_handle_find(p, r->in.user_handle,
3068                                    acc_required, &acc_granted,
3069                                    struct samr_user_info, &status);
3070         if (!NT_STATUS_IS_OK(status)) {
3071                 return status;
3072         }
3073
3074         domain_sid = uinfo->sid;
3075
3076         sid_split_rid(&domain_sid, &rid);
3077
3078         if (!sid_check_is_in_our_domain(&uinfo->sid))
3079                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
3080
3081         DEBUG(5,("_samr_QueryUserInfo: sid:%s\n",
3082                  sid_string_dbg(&uinfo->sid)));
3083
3084         user_info = TALLOC_ZERO_P(p->mem_ctx, union samr_UserInfo);
3085         if (!user_info) {
3086                 return NT_STATUS_NO_MEMORY;
3087         }
3088
3089         DEBUG(5,("_samr_QueryUserInfo: user info level: %d\n", r->in.level));
3090
3091         if (!(pwd = samu_new(p->mem_ctx))) {
3092                 return NT_STATUS_NO_MEMORY;
3093         }
3094
3095         become_root();
3096         ret = pdb_getsampwsid(pwd, &uinfo->sid);
3097         unbecome_root();
3098
3099         if (ret == false) {
3100                 DEBUG(4,("User %s not found\n", sid_string_dbg(&uinfo->sid)));
3101                 TALLOC_FREE(pwd);
3102                 return NT_STATUS_NO_SUCH_USER;
3103         }
3104
3105         DEBUG(3,("User:[%s]\n", pdb_get_username(pwd)));
3106
3107         samr_clear_sam_passwd(pwd);
3108
3109         switch (r->in.level) {
3110         case 1:
3111                 status = get_user_info_1(p->mem_ctx, &user_info->info1, pwd, &domain_sid);
3112                 break;
3113         case 2:
3114                 status = get_user_info_2(p->mem_ctx, &user_info->info2, pwd);
3115                 break;
3116         case 3:
3117                 status = get_user_info_3(p->mem_ctx, &user_info->info3, pwd, &domain_sid);
3118                 break;
3119         case 4:
3120                 status = get_user_info_4(p->mem_ctx, &user_info->info4, pwd);
3121                 break;
3122         case 5:
3123                 status = get_user_info_5(p->mem_ctx, &user_info->info5, pwd, &domain_sid);
3124                 break;
3125         case 6:
3126                 status = get_user_info_6(p->mem_ctx, &user_info->info6, pwd);
3127                 break;
3128         case 7:
3129                 status = get_user_info_7(p->mem_ctx, &user_info->info7, pwd);
3130                 break;
3131         case 8:
3132                 status = get_user_info_8(p->mem_ctx, &user_info->info8, pwd);
3133                 break;
3134         case 9:
3135                 status = get_user_info_9(p->mem_ctx, &user_info->info9, pwd);
3136                 break;
3137         case 10:
3138                 status = get_user_info_10(p->mem_ctx, &user_info->info10, pwd);
3139                 break;
3140         case 11:
3141                 status = get_user_info_11(p->mem_ctx, &user_info->info11, pwd);
3142                 break;
3143         case 12:
3144                 status = get_user_info_12(p->mem_ctx, &user_info->info12, pwd);
3145                 break;
3146         case 13:
3147                 status = get_user_info_13(p->mem_ctx, &user_info->info13, pwd);
3148                 break;
3149         case 14:
3150                 status = get_user_info_14(p->mem_ctx, &user_info->info14, pwd);
3151                 break;
3152         case 16:
3153                 status = get_user_info_16(p->mem_ctx, &user_info->info16, pwd);
3154                 break;
3155         case 17:
3156                 status = get_user_info_17(p->mem_ctx, &user_info->info17, pwd);
3157                 break;
3158         case 18:
3159                 /* level 18 is special */
3160                 status = get_user_info_18(p, p->mem_ctx, &user_info->info18,
3161                                           &uinfo->sid);
3162                 break;
3163         case 20:
3164                 status = get_user_info_20(p->mem_ctx, &user_info->info20, pwd);
3165                 break;
3166         case 21:
3167                 status = get_user_info_21(p->mem_ctx, &user_info->info21, pwd, &domain_sid, acc_granted);
3168                 break;
3169         default:
3170                 status = NT_STATUS_INVALID_INFO_CLASS;
3171                 break;
3172         }
3173
3174         if (!NT_STATUS_IS_OK(status)) {
3175                 goto done;
3176         }
3177
3178         *r->out.info = user_info;
3179
3180  done:
3181         TALLOC_FREE(pwd);
3182
3183         DEBUG(5,("_samr_QueryUserInfo: %d\n", __LINE__));
3184
3185         return status;
3186 }
3187
3188 /****************************************************************
3189 ****************************************************************/
3190
3191 NTSTATUS _samr_QueryUserInfo2(struct pipes_struct *p,
3192                               struct samr_QueryUserInfo2 *r)
3193 {
3194         struct samr_QueryUserInfo u;
3195
3196         u.in.user_handle        = r->in.user_handle;
3197         u.in.level              = r->in.level;
3198         u.out.info              = r->out.info;
3199
3200         return _samr_QueryUserInfo(p, &u);
3201 }
3202
3203 /*******************************************************************
3204  _samr_GetGroupsForUser
3205  ********************************************************************/
3206
3207 NTSTATUS _samr_GetGroupsForUser(struct pipes_struct *p,
3208                                 struct samr_GetGroupsForUser *r)
3209 {
3210         struct samr_user_info *uinfo;
3211         struct samu *sam_pass=NULL;
3212         struct dom_sid *sids;
3213         struct samr_RidWithAttribute dom_gid;
3214         struct samr_RidWithAttribute *gids = NULL;
3215         uint32 primary_group_rid;
3216         size_t num_groups = 0;
3217         gid_t *unix_gids;
3218         size_t i, num_gids;
3219         bool ret;
3220         NTSTATUS result;
3221         bool success = False;
3222
3223         struct samr_RidWithAttributeArray *rids = NULL;
3224
3225         /*
3226          * from the SID in the request:
3227          * we should send back the list of DOMAIN GROUPS
3228          * the user is a member of
3229          *
3230          * and only the DOMAIN GROUPS
3231          * no ALIASES !!! neither aliases of the domain
3232          * nor aliases of the builtin SID
3233          *
3234          * JFM, 12/2/2001
3235          */
3236
3237         DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
3238
3239         uinfo = policy_handle_find(p, r->in.user_handle,
3240                                    SAMR_USER_ACCESS_GET_GROUPS, NULL,
3241                                    struct samr_user_info, &result);
3242         if (!NT_STATUS_IS_OK(result)) {
3243                 return result;
3244         }
3245
3246         rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidWithAttributeArray);
3247         if (!rids) {
3248                 return NT_STATUS_NO_MEMORY;
3249         }
3250
3251         if (!sid_check_is_in_our_domain(&uinfo->sid))
3252                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
3253
3254         if ( !(sam_pass = samu_new( p->mem_ctx )) ) {
3255                 return NT_STATUS_NO_MEMORY;
3256         }
3257
3258         become_root();
3259         ret = pdb_getsampwsid(sam_pass, &uinfo->sid);
3260         unbecome_root();
3261
3262         if (!ret) {
3263                 DEBUG(10, ("pdb_getsampwsid failed for %s\n",
3264                            sid_string_dbg(&uinfo->sid)));
3265                 return NT_STATUS_NO_SUCH_USER;
3266         }
3267
3268         sids = NULL;
3269
3270         /* make both calls inside the root block */
3271         become_root();
3272         result = pdb_enum_group_memberships(p->mem_ctx, sam_pass,
3273                                             &sids, &unix_gids, &num_groups);
3274         if ( NT_STATUS_IS_OK(result) ) {
3275                 success = sid_peek_check_rid(get_global_sam_sid(),
3276                                              pdb_get_group_sid(sam_pass),
3277                                              &primary_group_rid);
3278         }
3279         unbecome_root();
3280
3281         if (!NT_STATUS_IS_OK(result)) {
3282                 DEBUG(10, ("pdb_enum_group_memberships failed for %s\n",
3283                            sid_string_dbg(&uinfo->sid)));
3284                 return result;
3285         }
3286
3287         if ( !success ) {
3288                 DEBUG(5, ("Group sid %s for user %s not in our domain\n",
3289                           sid_string_dbg(pdb_get_group_sid(sam_pass)),
3290                           pdb_get_username(sam_pass)));
3291                 TALLOC_FREE(sam_pass);
3292                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
3293         }
3294
3295         gids = NULL;
3296         num_gids = 0;
3297
3298         dom_gid.attributes = (SE_GROUP_MANDATORY|SE_GROUP_ENABLED_BY_DEFAULT|
3299                               SE_GROUP_ENABLED);
3300         dom_gid.rid = primary_group_rid;
3301         ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
3302
3303         for (i=0; i<num_groups; i++) {
3304
3305                 if (!sid_peek_check_rid(get_global_sam_sid(),
3306                                         &(sids[i]), &dom_gid.rid)) {
3307                         DEBUG(10, ("Found sid %s not in our domain\n",
3308                                    sid_string_dbg(&sids[i])));
3309                         continue;
3310                 }
3311
3312                 if (dom_gid.rid == primary_group_rid) {
3313                         /* We added the primary group directly from the
3314                          * sam_account. The other SIDs are unique from
3315                          * enum_group_memberships */
3316                         continue;
3317                 }
3318
3319                 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
3320         }
3321
3322         rids->count = num_gids;
3323         rids->rids = gids;
3324
3325         *r->out.rids = rids;
3326
3327         DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
3328
3329         return result;
3330 }
3331
3332 /*******************************************************************
3333  ********************************************************************/
3334
3335 static uint32_t samr_get_server_role(void)
3336 {
3337         uint32_t role = ROLE_DOMAIN_PDC;
3338
3339         if (lp_server_role() == ROLE_DOMAIN_BDC) {
3340                 role = ROLE_DOMAIN_BDC;
3341         }
3342
3343         return role;
3344 }
3345
3346 /*******************************************************************
3347  ********************************************************************/
3348
3349 static NTSTATUS query_dom_info_1(TALLOC_CTX *mem_ctx,
3350                                  struct samr_DomInfo1 *r)
3351 {
3352         uint32_t account_policy_temp;
3353         time_t u_expire, u_min_age;
3354
3355         become_root();
3356
3357         /* AS ROOT !!! */
3358
3359         pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN, &account_policy_temp);
3360         r->min_password_length = account_policy_temp;
3361
3362         pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &account_policy_temp);
3363         r->password_history_length = account_policy_temp;
3364
3365         pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
3366                                &r->password_properties);
3367
3368         pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, &account_policy_temp);
3369         u_expire = account_policy_temp;
3370
3371         pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, &account_policy_temp);
3372         u_min_age = account_policy_temp;
3373
3374         /* !AS ROOT */
3375
3376         unbecome_root();
3377
3378         unix_to_nt_time_abs((NTTIME *)&r->max_password_age, u_expire);
3379         unix_to_nt_time_abs((NTTIME *)&r->min_password_age, u_min_age);
3380
3381         if (lp_check_password_script() && *lp_check_password_script()) {
3382                 r->password_properties |= DOMAIN_PASSWORD_COMPLEX;
3383         }
3384
3385         return NT_STATUS_OK;
3386 }
3387
3388 /*******************************************************************
3389  ********************************************************************/
3390
3391 static NTSTATUS query_dom_info_2(TALLOC_CTX *mem_ctx,
3392                                  struct samr_DomGeneralInformation *r,
3393                                  struct samr_domain_info *dinfo)
3394 {
3395         uint32_t u_logout;
3396         time_t seq_num;
3397
3398         become_root();
3399
3400         /* AS ROOT !!! */
3401
3402         r->num_users    = count_sam_users(dinfo->disp_info, ACB_NORMAL);
3403         r->num_groups   = count_sam_groups(dinfo->disp_info);
3404         r->num_aliases  = count_sam_aliases(dinfo->disp_info);
3405
3406         pdb_get_account_policy(PDB_POLICY_TIME_TO_LOGOUT, &u_logout);
3407
3408         unix_to_nt_time_abs(&r->force_logoff_time, u_logout);
3409
3410         if (!pdb_get_seq_num(&seq_num)) {
3411                 seq_num = time(NULL);
3412         }
3413
3414         /* !AS ROOT */
3415
3416         unbecome_root();
3417
3418         r->oem_information.string       = lp_serverstring();
3419         r->domain_name.string           = lp_workgroup();
3420         r->primary.string               = global_myname();
3421         r->sequence_num                 = seq_num;
3422         r->domain_server_state          = DOMAIN_SERVER_ENABLED;
3423         r->role                         = (enum samr_Role) samr_get_server_role();
3424         r->unknown3                     = 1;
3425
3426         return NT_STATUS_OK;
3427 }
3428
3429 /*******************************************************************
3430  ********************************************************************/
3431
3432 static NTSTATUS query_dom_info_3(TALLOC_CTX *mem_ctx,
3433                                  struct samr_DomInfo3 *r)
3434 {
3435         uint32_t u_logout;
3436
3437         become_root();
3438
3439         /* AS ROOT !!! */
3440
3441         {
3442                 uint32_t ul;
3443                 pdb_get_account_policy(PDB_POLICY_TIME_TO_LOGOUT, &ul);
3444                 u_logout = (time_t)ul;
3445         }
3446
3447         /* !AS ROOT */
3448
3449         unbecome_root();
3450
3451         unix_to_nt_time_abs(&r->force_logoff_time, u_logout);
3452
3453         return NT_STATUS_OK;
3454 }
3455
3456 /*******************************************************************
3457  ********************************************************************/
3458
3459 static NTSTATUS query_dom_info_4(TALLOC_CTX *mem_ctx,
3460                                  struct samr_DomOEMInformation *r)
3461 {
3462         r->oem_information.string = lp_serverstring();
3463
3464         return NT_STATUS_OK;
3465 }
3466
3467 /*******************************************************************
3468  ********************************************************************/
3469
3470 static NTSTATUS query_dom_info_5(TALLOC_CTX *mem_ctx,
3471                                  struct samr_DomInfo5 *r)
3472 {
3473         r->domain_name.string = get_global_sam_name();
3474
3475         return NT_STATUS_OK;
3476 }
3477
3478 /*******************************************************************
3479  ********************************************************************/
3480
3481 static NTSTATUS query_dom_info_6(TALLOC_CTX *mem_ctx,
3482                                  struct samr_DomInfo6 *r)
3483 {
3484         /* NT returns its own name when a PDC. win2k and later
3485          * only the name of the PDC if itself is a BDC (samba4
3486          * idl) */
3487         r->primary.string = global_myname();
3488
3489         return NT_STATUS_OK;
3490 }
3491
3492 /*******************************************************************
3493  ********************************************************************/
3494
3495 static NTSTATUS query_dom_info_7(TALLOC_CTX *mem_ctx,
3496                                  struct samr_DomInfo7 *r)
3497 {
3498         r->role = (enum samr_Role) samr_get_server_role();
3499
3500         return NT_STATUS_OK;
3501 }
3502
3503 /*******************************************************************
3504  ********************************************************************/
3505
3506 static NTSTATUS query_dom_info_8(TALLOC_CTX *mem_ctx,
3507                                  struct samr_DomInfo8 *r)
3508 {
3509         time_t seq_num;
3510
3511         become_root();
3512
3513         /* AS ROOT !!! */
3514
3515         if (!pdb_get_seq_num(&seq_num)) {
3516                 seq_num = time(NULL);
3517         }
3518
3519         /* !AS ROOT */
3520
3521         unbecome_root();
3522
3523         r->sequence_num = seq_num;
3524         r->domain_create_time = 0;
3525
3526         return NT_STATUS_OK;
3527 }
3528
3529 /*******************************************************************
3530  ********************************************************************/
3531
3532 static NTSTATUS query_dom_info_9(TALLOC_CTX *mem_ctx,
3533                                  struct samr_DomInfo9 *r)
3534 {
3535         r->domain_server_state = DOMAIN_SERVER_ENABLED;
3536
3537         return NT_STATUS_OK;
3538 }
3539
3540 /*******************************************************************
3541  ********************************************************************/
3542
3543 static NTSTATUS query_dom_info_11(TALLOC_CTX *mem_ctx,
3544                                   struct samr_DomGeneralInformation2 *r,
3545                                   struct samr_domain_info *dinfo)
3546 {
3547         NTSTATUS status;
3548         uint32_t account_policy_temp;
3549         time_t u_lock_duration, u_reset_time;
3550
3551         status = query_dom_info_2(mem_ctx, &r->general, dinfo);
3552         if (!NT_STATUS_IS_OK(status)) {
3553                 return status;
3554         }
3555
3556         /* AS ROOT !!! */
3557
3558         become_root();
3559
3560         pdb_get_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, &account_policy_temp);
3561         u_lock_duration = account_policy_temp;
3562         if (u_lock_duration != -1) {
3563                 u_lock_duration *= 60;
3564         }
3565
3566         pdb_get_account_policy(PDB_POLICY_RESET_COUNT_TIME, &account_policy_temp);
3567         u_reset_time = account_policy_temp * 60;
3568
3569         pdb_get_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
3570         r->lockout_threshold = account_policy_temp;
3571
3572         /* !AS ROOT */
3573
3574         unbecome_root();
3575
3576         unix_to_nt_time_abs(&r->lockout_duration, u_lock_duration);
3577         unix_to_nt_time_abs(&r->lockout_window, u_reset_time);
3578
3579         return NT_STATUS_OK;
3580 }
3581
3582 /*******************************************************************
3583  ********************************************************************/
3584
3585 static NTSTATUS query_dom_info_12(TALLOC_CTX *mem_ctx,
3586                                   struct samr_DomInfo12 *r)
3587 {
3588         uint32_t account_policy_temp;
3589         time_t u_lock_duration, u_reset_time;
3590
3591         become_root();
3592
3593         /* AS ROOT !!! */
3594
3595         pdb_get_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, &account_policy_temp);
3596         u_lock_duration = account_policy_temp;
3597         if (u_lock_duration != -1) {
3598                 u_lock_duration *= 60;
3599         }
3600
3601         pdb_get_account_policy(PDB_POLICY_RESET_COUNT_TIME, &account_policy_temp);
3602         u_reset_time = account_policy_temp * 60;
3603
3604         pdb_get_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
3605         r->lockout_threshold = account_policy_temp;
3606
3607         /* !AS ROOT */
3608
3609         unbecome_root();
3610
3611         unix_to_nt_time_abs(&r->lockout_duration, u_lock_duration);
3612         unix_to_nt_time_abs(&r->lockout_window, u_reset_time);
3613
3614         return NT_STATUS_OK;
3615 }
3616
3617 /*******************************************************************
3618  ********************************************************************/
3619
3620 static NTSTATUS query_dom_info_13(TALLOC_CTX *mem_ctx,
3621                                   struct samr_DomInfo13 *r)
3622 {
3623         time_t seq_num;
3624
3625         become_root();
3626
3627         /* AS ROOT !!! */
3628
3629         if (!pdb_get_seq_num(&seq_num)) {
3630                 seq_num = time(NULL);
3631         }
3632
3633         /* !AS ROOT */
3634
3635         unbecome_root();
3636
3637         r->sequence_num = seq_num;
3638         r->domain_create_time = 0;
3639         r->modified_count_at_last_promotion = 0;
3640
3641         return NT_STATUS_OK;
3642 }
3643
3644 /*******************************************************************
3645  _samr_QueryDomainInfo
3646  ********************************************************************/
3647
3648 NTSTATUS _samr_QueryDomainInfo(struct pipes_struct *p,
3649                                struct samr_QueryDomainInfo *r)
3650 {
3651         NTSTATUS status = NT_STATUS_OK;
3652         struct samr_domain_info *dinfo;
3653         union samr_DomainInfo *dom_info;
3654
3655         uint32_t acc_required;
3656
3657         DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__));
3658
3659         switch (r->in.level) {
3660         case 1: /* DomainPasswordInformation */
3661         case 12: /* DomainLockoutInformation */
3662                 /* DOMAIN_READ_PASSWORD_PARAMETERS */
3663                 acc_required = SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1;
3664                 break;
3665         case 11: /* DomainGeneralInformation2 */
3666                 /* DOMAIN_READ_PASSWORD_PARAMETERS |
3667                  * DOMAIN_READ_OTHER_PARAMETERS */
3668                 acc_required = SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
3669                                SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2;
3670                 break;
3671         case 2: /* DomainGeneralInformation */
3672         case 3: /* DomainLogoffInformation */
3673         case 4: /* DomainOemInformation */
3674         case 5: /* DomainReplicationInformation */
3675         case 6: /* DomainReplicationInformation */
3676         case 7: /* DomainServerRoleInformation */
3677         case 8: /* DomainModifiedInformation */
3678         case 9: /* DomainStateInformation */
3679         case 10: /* DomainUasInformation */
3680         case 13: /* DomainModifiedInformation2 */
3681                 /* DOMAIN_READ_OTHER_PARAMETERS */
3682                 acc_required = SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2;
3683                 break;
3684         default:
3685                 return NT_STATUS_INVALID_INFO_CLASS;
3686         }
3687
3688         dinfo = policy_handle_find(p, r->in.domain_handle,
3689                                    acc_required, NULL,
3690                                    struct samr_domain_info, &status);
3691         if (!NT_STATUS_IS_OK(status)) {
3692                 return status;
3693         }
3694
3695         dom_info = TALLOC_ZERO_P(p->mem_ctx, union samr_DomainInfo);
3696         if (!dom_info) {
3697                 return NT_STATUS_NO_MEMORY;
3698         }
3699
3700         switch (r->in.level) {
3701                 case 1:
3702                         status = query_dom_info_1(p->mem_ctx, &dom_info->info1);
3703                         break;
3704                 case 2:
3705                         status = query_dom_info_2(p->mem_ctx, &dom_info->general, dinfo);
3706                         break;
3707                 case 3:
3708                         status = query_dom_info_3(p->mem_ctx, &dom_info->info3);
3709                         break;
3710                 case 4:
3711                         status = query_dom_info_4(p->mem_ctx, &dom_info->oem);
3712                         break;
3713                 case 5:
3714                         status = query_dom_info_5(p->mem_ctx, &dom_info->info5);
3715                         break;
3716                 case 6:
3717                         status = query_dom_info_6(p->mem_ctx, &dom_info->info6);
3718                         break;
3719                 case 7:
3720                         status = query_dom_info_7(p->mem_ctx, &dom_info->info7);
3721                         break;
3722                 case 8:
3723                         status = query_dom_info_8(p->mem_ctx, &dom_info->info8);
3724                         break;
3725                 case 9:
3726                         status = query_d