s3-dcerpc: finally remove the legaqcy spnego_type variable from pipe_auth_data
[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/dom_sid.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 (is_sid_in_token(nt_token, &global_sid_Builtin_Administrators) ||
273                         is_sid_in_token(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 (is_sid_in_token(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(
335                                 talloc_autofree_context(), struct disp_info);
336                         if (builtin_dispinfo == NULL) {
337                                 return NULL;
338                         }
339                 }
340                 sid_copy(&builtin_dispinfo->sid, &global_sid_Builtin);
341
342                 return builtin_dispinfo;
343         }
344
345         if (sid_check_is_domain(psid) || sid_check_is_in_our_domain(psid)) {
346                 /*
347                  * Necessary only once, but it does not really hurt.
348                  */
349                 if (domain_dispinfo == NULL) {
350                         domain_dispinfo = talloc_zero(
351                                 talloc_autofree_context(), struct disp_info);
352                         if (domain_dispinfo == NULL) {
353                                 return NULL;
354                         }
355                 }
356                 sid_copy(&domain_dispinfo->sid, get_global_sam_sid());
357
358                 return domain_dispinfo;
359         }
360
361         return NULL;
362 }
363
364 /*******************************************************************
365  Function to free the per SID data.
366  ********************************************************************/
367
368 static void free_samr_cache(DISP_INFO *disp_info)
369 {
370         DEBUG(10, ("free_samr_cache: deleting cache for SID %s\n",
371                    sid_string_dbg(&disp_info->sid)));
372
373         /* We need to become root here because the paged search might have to
374          * tell the LDAP server we're not interested in the rest anymore. */
375
376         become_root();
377
378         TALLOC_FREE(disp_info->users);
379         TALLOC_FREE(disp_info->machines);
380         TALLOC_FREE(disp_info->groups);
381         TALLOC_FREE(disp_info->aliases);
382         TALLOC_FREE(disp_info->enum_users);
383
384         unbecome_root();
385 }
386
387 /*******************************************************************
388  Idle event handler. Throw away the disp info cache.
389  ********************************************************************/
390
391 static void disp_info_cache_idle_timeout_handler(struct event_context *ev_ctx,
392                                                  struct timed_event *te,
393                                                  struct timeval now,
394                                                  void *private_data)
395 {
396         DISP_INFO *disp_info = (DISP_INFO *)private_data;
397
398         TALLOC_FREE(disp_info->cache_timeout_event);
399
400         DEBUG(10, ("disp_info_cache_idle_timeout_handler: caching timed "
401                    "out\n"));
402         free_samr_cache(disp_info);
403 }
404
405 /*******************************************************************
406  Setup cache removal idle event handler.
407  ********************************************************************/
408
409 static void set_disp_info_cache_timeout(DISP_INFO *disp_info, time_t secs_fromnow)
410 {
411         /* Remove any pending timeout and update. */
412
413         TALLOC_FREE(disp_info->cache_timeout_event);
414
415         DEBUG(10,("set_disp_info_cache_timeout: caching enumeration for "
416                   "SID %s for %u seconds\n", sid_string_dbg(&disp_info->sid),
417                   (unsigned int)secs_fromnow ));
418
419         disp_info->cache_timeout_event = event_add_timed(
420                 server_event_context(), NULL,
421                 timeval_current_ofs(secs_fromnow, 0),
422                 disp_info_cache_idle_timeout_handler, (void *)disp_info);
423 }
424
425 /*******************************************************************
426  Force flush any cache. We do this on any samr_set_xxx call.
427  We must also remove the timeout handler.
428  ********************************************************************/
429
430 static void force_flush_samr_cache(const struct dom_sid *sid)
431 {
432         struct disp_info *disp_info = get_samr_dispinfo_by_sid(sid);
433
434         if ((disp_info == NULL) || (disp_info->cache_timeout_event == NULL)) {
435                 return;
436         }
437
438         DEBUG(10,("force_flush_samr_cache: clearing idle event\n"));
439         TALLOC_FREE(disp_info->cache_timeout_event);
440         free_samr_cache(disp_info);
441 }
442
443 /*******************************************************************
444  Ensure password info is never given out. Paranioa... JRA.
445  ********************************************************************/
446
447 static void samr_clear_sam_passwd(struct samu *sam_pass)
448 {
449
450         if (!sam_pass)
451                 return;
452
453         /* These now zero out the old password */
454
455         pdb_set_lanman_passwd(sam_pass, NULL, PDB_DEFAULT);
456         pdb_set_nt_passwd(sam_pass, NULL, PDB_DEFAULT);
457 }
458
459 static uint32 count_sam_users(struct disp_info *info, uint32 acct_flags)
460 {
461         struct samr_displayentry *entry;
462
463         if (sid_check_is_builtin(&info->sid)) {
464                 /* No users in builtin. */
465                 return 0;
466         }
467
468         if (info->users == NULL) {
469                 info->users = pdb_search_users(info, acct_flags);
470                 if (info->users == NULL) {
471                         return 0;
472                 }
473         }
474         /* Fetch the last possible entry, thus trigger an enumeration */
475         pdb_search_entries(info->users, 0xffffffff, 1, &entry);
476
477         /* Ensure we cache this enumeration. */
478         set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
479
480         return info->users->num_entries;
481 }
482
483 static uint32 count_sam_groups(struct disp_info *info)
484 {
485         struct samr_displayentry *entry;
486
487         if (sid_check_is_builtin(&info->sid)) {
488                 /* No groups in builtin. */
489                 return 0;
490         }
491
492         if (info->groups == NULL) {
493                 info->groups = pdb_search_groups(info);
494                 if (info->groups == NULL) {
495                         return 0;
496                 }
497         }
498         /* Fetch the last possible entry, thus trigger an enumeration */
499         pdb_search_entries(info->groups, 0xffffffff, 1, &entry);
500
501         /* Ensure we cache this enumeration. */
502         set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
503
504         return info->groups->num_entries;
505 }
506
507 static uint32 count_sam_aliases(struct disp_info *info)
508 {
509         struct samr_displayentry *entry;
510
511         if (info->aliases == NULL) {
512                 info->aliases = pdb_search_aliases(info, &info->sid);
513                 if (info->aliases == NULL) {
514                         return 0;
515                 }
516         }
517         /* Fetch the last possible entry, thus trigger an enumeration */
518         pdb_search_entries(info->aliases, 0xffffffff, 1, &entry);
519
520         /* Ensure we cache this enumeration. */
521         set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
522
523         return info->aliases->num_entries;
524 }
525
526 /*******************************************************************
527  _samr_Close
528  ********************************************************************/
529
530 NTSTATUS _samr_Close(struct pipes_struct *p, struct samr_Close *r)
531 {
532         if (!close_policy_hnd(p, r->in.handle)) {
533                 return NT_STATUS_INVALID_HANDLE;
534         }
535
536         ZERO_STRUCTP(r->out.handle);
537
538         return NT_STATUS_OK;
539 }
540
541 /*******************************************************************
542  _samr_OpenDomain
543  ********************************************************************/
544
545 NTSTATUS _samr_OpenDomain(struct pipes_struct *p,
546                           struct samr_OpenDomain *r)
547 {
548         struct samr_connect_info *cinfo;
549         struct samr_domain_info *dinfo;
550         struct security_descriptor *psd = NULL;
551         uint32    acc_granted;
552         uint32    des_access = r->in.access_mask;
553         NTSTATUS  status;
554         size_t    sd_size;
555         uint32_t extra_access = SAMR_DOMAIN_ACCESS_CREATE_USER;
556
557         /* find the connection policy handle. */
558
559         cinfo = policy_handle_find(p, r->in.connect_handle, 0, NULL,
560                                    struct samr_connect_info, &status);
561         if (!NT_STATUS_IS_OK(status)) {
562                 return status;
563         }
564
565         /*check if access can be granted as requested by client. */
566         map_max_allowed_access(p->server_info->ptok,
567                                &p->server_info->utok,
568                                &des_access);
569
570         make_samr_object_sd( p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0 );
571         se_map_generic( &des_access, &dom_generic_mapping );
572
573         /*
574          * Users with SeAddUser get the ability to manipulate groups
575          * and aliases.
576          */
577         if (security_token_has_privilege(p->server_info->ptok, SEC_PRIV_ADD_USERS)) {
578                 extra_access |= (SAMR_DOMAIN_ACCESS_CREATE_GROUP |
579                                 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS |
580                                 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
581                                 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS |
582                                 SAMR_DOMAIN_ACCESS_CREATE_ALIAS);
583         }
584
585         /*
586          * Users with SeMachineAccount or SeAddUser get additional
587          * SAMR_DOMAIN_ACCESS_CREATE_USER access.
588          */
589
590         status = access_check_object( psd, p->server_info->ptok,
591                                       SEC_PRIV_MACHINE_ACCOUNT, SEC_PRIV_ADD_USERS,
592                                       extra_access, des_access,
593                                       &acc_granted, "_samr_OpenDomain" );
594
595         if ( !NT_STATUS_IS_OK(status) )
596                 return status;
597
598         if (!sid_check_is_domain(r->in.sid) &&
599             !sid_check_is_builtin(r->in.sid)) {
600                 return NT_STATUS_NO_SUCH_DOMAIN;
601         }
602
603         dinfo = policy_handle_create(p, r->out.domain_handle, acc_granted,
604                                      struct samr_domain_info, &status);
605         if (!NT_STATUS_IS_OK(status)) {
606                 return status;
607         }
608         dinfo->sid = *r->in.sid;
609         dinfo->disp_info = get_samr_dispinfo_by_sid(r->in.sid);
610
611         DEBUG(5,("_samr_OpenDomain: %d\n", __LINE__));
612
613         return NT_STATUS_OK;
614 }
615
616 /*******************************************************************
617  _samr_GetUserPwInfo
618  ********************************************************************/
619
620 NTSTATUS _samr_GetUserPwInfo(struct pipes_struct *p,
621                              struct samr_GetUserPwInfo *r)
622 {
623         struct samr_user_info *uinfo;
624         enum lsa_SidType sid_type;
625         uint32_t min_password_length = 0;
626         uint32_t password_properties = 0;
627         bool ret = false;
628         NTSTATUS status;
629
630         DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__));
631
632         uinfo = policy_handle_find(p, r->in.user_handle,
633                                    SAMR_USER_ACCESS_GET_ATTRIBUTES, NULL,
634                                    struct samr_user_info, &status);
635         if (!NT_STATUS_IS_OK(status)) {
636                 return status;
637         }
638
639         if (!sid_check_is_in_our_domain(&uinfo->sid)) {
640                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
641         }
642
643         become_root();
644         ret = lookup_sid(p->mem_ctx, &uinfo->sid, NULL, NULL, &sid_type);
645         unbecome_root();
646         if (ret == false) {
647                 return NT_STATUS_NO_SUCH_USER;
648         }
649
650         switch (sid_type) {
651                 case SID_NAME_USER:
652                         become_root();
653                         pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN,
654                                                &min_password_length);
655                         pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
656                                                &password_properties);
657                         unbecome_root();
658
659                         if (lp_check_password_script() && *lp_check_password_script()) {
660                                 password_properties |= DOMAIN_PASSWORD_COMPLEX;
661                         }
662
663                         break;
664                 default:
665                         break;
666         }
667
668         r->out.info->min_password_length = min_password_length;
669         r->out.info->password_properties = password_properties;
670
671         DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__));
672
673         return NT_STATUS_OK;
674 }
675
676 /*******************************************************************
677  _samr_SetSecurity
678  ********************************************************************/
679
680 NTSTATUS _samr_SetSecurity(struct pipes_struct *p,
681                            struct samr_SetSecurity *r)
682 {
683         struct samr_user_info *uinfo;
684         uint32 i;
685         struct security_acl *dacl;
686         bool ret;
687         struct samu *sampass=NULL;
688         NTSTATUS status;
689
690         uinfo = policy_handle_find(p, r->in.handle,
691                                    SAMR_USER_ACCESS_SET_ATTRIBUTES, NULL,
692                                    struct samr_user_info, &status);
693         if (!NT_STATUS_IS_OK(status)) {
694                 return status;
695         }
696
697         if (!(sampass = samu_new( p->mem_ctx))) {
698                 DEBUG(0,("No memory!\n"));
699                 return NT_STATUS_NO_MEMORY;
700         }
701
702         /* get the user record */
703         become_root();
704         ret = pdb_getsampwsid(sampass, &uinfo->sid);
705         unbecome_root();
706
707         if (!ret) {
708                 DEBUG(4, ("User %s not found\n",
709                           sid_string_dbg(&uinfo->sid)));
710                 TALLOC_FREE(sampass);
711                 return NT_STATUS_INVALID_HANDLE;
712         }
713
714         dacl = r->in.sdbuf->sd->dacl;
715         for (i=0; i < dacl->num_aces; i++) {
716                 if (dom_sid_equal(&uinfo->sid, &dacl->aces[i].trustee)) {
717                         ret = pdb_set_pass_can_change(sampass,
718                                 (dacl->aces[i].access_mask &
719                                  SAMR_USER_ACCESS_CHANGE_PASSWORD) ?
720                                                       True: False);
721                         break;
722                 }
723         }
724
725         if (!ret) {
726                 TALLOC_FREE(sampass);
727                 return NT_STATUS_ACCESS_DENIED;
728         }
729
730         become_root();
731         status = pdb_update_sam_account(sampass);
732         unbecome_root();
733
734         TALLOC_FREE(sampass);
735
736         return status;
737 }
738
739 /*******************************************************************
740   build correct perms based on policies and password times for _samr_query_sec_obj
741 *******************************************************************/
742 static bool check_change_pw_access(TALLOC_CTX *mem_ctx, struct dom_sid *user_sid)
743 {
744         struct samu *sampass=NULL;
745         bool ret;
746
747         if ( !(sampass = samu_new( mem_ctx )) ) {
748                 DEBUG(0,("No memory!\n"));
749                 return False;
750         }
751
752         become_root();
753         ret = pdb_getsampwsid(sampass, user_sid);
754         unbecome_root();
755
756         if (ret == False) {
757                 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
758                 TALLOC_FREE(sampass);
759                 return False;
760         }
761
762         DEBUG(3,("User:[%s]\n",  pdb_get_username(sampass) ));
763
764         if (pdb_get_pass_can_change(sampass)) {
765                 TALLOC_FREE(sampass);
766                 return True;
767         }
768         TALLOC_FREE(sampass);
769         return False;
770 }
771
772
773 /*******************************************************************
774  _samr_QuerySecurity
775  ********************************************************************/
776
777 NTSTATUS _samr_QuerySecurity(struct pipes_struct *p,
778                              struct samr_QuerySecurity *r)
779 {
780         struct samr_connect_info *cinfo;
781         struct samr_domain_info *dinfo;
782         struct samr_user_info *uinfo;
783         struct samr_group_info *ginfo;
784         struct samr_alias_info *ainfo;
785         NTSTATUS status;
786         struct security_descriptor * psd = NULL;
787         size_t sd_size = 0;
788
789         cinfo = policy_handle_find(p, r->in.handle,
790                                    SEC_STD_READ_CONTROL, NULL,
791                                    struct samr_connect_info, &status);
792         if (NT_STATUS_IS_OK(status)) {
793                 DEBUG(5,("_samr_QuerySecurity: querying security on SAM\n"));
794                 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size,
795                                              &sam_generic_mapping, NULL, 0);
796                 goto done;
797         }
798
799         dinfo = policy_handle_find(p, r->in.handle,
800                                    SEC_STD_READ_CONTROL, NULL,
801                                    struct samr_domain_info, &status);
802         if (NT_STATUS_IS_OK(status)) {
803                 DEBUG(5,("_samr_QuerySecurity: querying security on Domain "
804                          "with SID: %s\n", sid_string_dbg(&dinfo->sid)));
805                 /*
806                  * TODO: Builtin probably needs a different SD with restricted
807                  * write access
808                  */
809                 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size,
810                                              &dom_generic_mapping, NULL, 0);
811                 goto done;
812         }
813
814         uinfo = policy_handle_find(p, r->in.handle,
815                                    SEC_STD_READ_CONTROL, NULL,
816                                    struct samr_user_info, &status);
817         if (NT_STATUS_IS_OK(status)) {
818                 DEBUG(10,("_samr_QuerySecurity: querying security on user "
819                           "Object with SID: %s\n",
820                           sid_string_dbg(&uinfo->sid)));
821                 if (check_change_pw_access(p->mem_ctx, &uinfo->sid)) {
822                         status = make_samr_object_sd(
823                                 p->mem_ctx, &psd, &sd_size,
824                                 &usr_generic_mapping,
825                                 &uinfo->sid, SAMR_USR_RIGHTS_WRITE_PW);
826                 } else {
827                         status = make_samr_object_sd(
828                                 p->mem_ctx, &psd, &sd_size,
829                                 &usr_nopwchange_generic_mapping,
830                                 &uinfo->sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
831                 }
832                 goto done;
833         }
834
835         ginfo = policy_handle_find(p, r->in.handle,
836                                    SEC_STD_READ_CONTROL, NULL,
837                                    struct samr_group_info, &status);
838         if (NT_STATUS_IS_OK(status)) {
839                 /*
840                  * TODO: different SDs have to be generated for aliases groups
841                  * and users.  Currently all three get a default user SD
842                  */
843                 DEBUG(10,("_samr_QuerySecurity: querying security on group "
844                           "Object with SID: %s\n",
845                           sid_string_dbg(&ginfo->sid)));
846                 status = make_samr_object_sd(
847                         p->mem_ctx, &psd, &sd_size,
848                         &usr_nopwchange_generic_mapping,
849                         &ginfo->sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
850                 goto done;
851         }
852
853         ainfo = policy_handle_find(p, r->in.handle,
854                                    SEC_STD_READ_CONTROL, NULL,
855                                    struct samr_alias_info, &status);
856         if (NT_STATUS_IS_OK(status)) {
857                 /*
858                  * TODO: different SDs have to be generated for aliases groups
859                  * and users.  Currently all three get a default user SD
860                  */
861                 DEBUG(10,("_samr_QuerySecurity: querying security on alias "
862                           "Object with SID: %s\n",
863                           sid_string_dbg(&ainfo->sid)));
864                 status = make_samr_object_sd(
865                         p->mem_ctx, &psd, &sd_size,
866                         &usr_nopwchange_generic_mapping,
867                         &ainfo->sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
868                 goto done;
869         }
870
871         return NT_STATUS_OBJECT_TYPE_MISMATCH;
872 done:
873         if ((*r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
874                 return NT_STATUS_NO_MEMORY;
875
876         return status;
877 }
878
879 /*******************************************************************
880 makes a SAM_ENTRY / UNISTR2* structure from a user list.
881 ********************************************************************/
882
883 static NTSTATUS make_user_sam_entry_list(TALLOC_CTX *ctx,
884                                          struct samr_SamEntry **sam_pp,
885                                          uint32_t num_entries,
886                                          uint32_t start_idx,
887                                          struct samr_displayentry *entries)
888 {
889         uint32_t i;
890         struct samr_SamEntry *sam;
891
892         *sam_pp = NULL;
893
894         if (num_entries == 0) {
895                 return NT_STATUS_OK;
896         }
897
898         sam = TALLOC_ZERO_ARRAY(ctx, struct samr_SamEntry, num_entries);
899         if (sam == NULL) {
900                 DEBUG(0, ("make_user_sam_entry_list: TALLOC_ZERO failed!\n"));
901                 return NT_STATUS_NO_MEMORY;
902         }
903
904         for (i = 0; i < num_entries; i++) {
905 #if 0
906                 /*
907                  * usrmgr expects a non-NULL terminated string with
908                  * trust relationships
909                  */
910                 if (entries[i].acct_flags & ACB_DOMTRUST) {
911                         init_unistr2(&uni_temp_name, entries[i].account_name,
912                                      UNI_FLAGS_NONE);
913                 } else {
914                         init_unistr2(&uni_temp_name, entries[i].account_name,
915                                      UNI_STR_TERMINATE);
916                 }
917 #endif
918                 init_lsa_String(&sam[i].name, entries[i].account_name);
919                 sam[i].idx = entries[i].rid;
920         }
921
922         *sam_pp = sam;
923
924         return NT_STATUS_OK;
925 }
926
927 #define MAX_SAM_ENTRIES MAX_SAM_ENTRIES_W2K
928
929 /*******************************************************************
930  _samr_EnumDomainUsers
931  ********************************************************************/
932
933 NTSTATUS _samr_EnumDomainUsers(struct pipes_struct *p,
934                                struct samr_EnumDomainUsers *r)
935 {
936         NTSTATUS status;
937         struct samr_domain_info *dinfo;
938         int num_account;
939         uint32 enum_context = *r->in.resume_handle;
940         enum remote_arch_types ra_type = get_remote_arch();
941         int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
942         uint32 max_entries = max_sam_entries;
943         struct samr_displayentry *entries = NULL;
944         struct samr_SamArray *samr_array = NULL;
945         struct samr_SamEntry *samr_entries = NULL;
946
947         DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
948
949         dinfo = policy_handle_find(p, r->in.domain_handle,
950                                    SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
951                                    struct samr_domain_info, &status);
952         if (!NT_STATUS_IS_OK(status)) {
953                 return status;
954         }
955
956         samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
957         if (!samr_array) {
958                 return NT_STATUS_NO_MEMORY;
959         }
960         *r->out.sam = samr_array;
961
962         if (sid_check_is_builtin(&dinfo->sid)) {
963                 /* No users in builtin. */
964                 *r->out.resume_handle = *r->in.resume_handle;
965                 DEBUG(5,("_samr_EnumDomainUsers: No users in BUILTIN\n"));
966                 return status;
967         }
968
969         become_root();
970
971         /* AS ROOT !!!! */
972
973         if ((dinfo->disp_info->enum_users != NULL) &&
974             (dinfo->disp_info->enum_acb_mask != r->in.acct_flags)) {
975                 TALLOC_FREE(dinfo->disp_info->enum_users);
976         }
977
978         if (dinfo->disp_info->enum_users == NULL) {
979                 dinfo->disp_info->enum_users = pdb_search_users(
980                         dinfo->disp_info, r->in.acct_flags);
981                 dinfo->disp_info->enum_acb_mask = r->in.acct_flags;
982         }
983
984         if (dinfo->disp_info->enum_users == NULL) {
985                 /* END AS ROOT !!!! */
986                 unbecome_root();
987                 return NT_STATUS_ACCESS_DENIED;
988         }
989
990         num_account = pdb_search_entries(dinfo->disp_info->enum_users,
991                                          enum_context, max_entries,
992                                          &entries);
993
994         /* END AS ROOT !!!! */
995
996         unbecome_root();
997
998         if (num_account == 0) {
999                 DEBUG(5, ("_samr_EnumDomainUsers: enumeration handle over "
1000                           "total entries\n"));
1001                 *r->out.resume_handle = *r->in.resume_handle;
1002                 return NT_STATUS_OK;
1003         }
1004
1005         status = make_user_sam_entry_list(p->mem_ctx, &samr_entries,
1006                                           num_account, enum_context,
1007                                           entries);
1008         if (!NT_STATUS_IS_OK(status)) {
1009                 return status;
1010         }
1011
1012         if (max_entries <= num_account) {
1013                 status = STATUS_MORE_ENTRIES;
1014         } else {
1015                 status = NT_STATUS_OK;
1016         }
1017
1018         /* Ensure we cache this enumeration. */
1019         set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
1020
1021         DEBUG(5, ("_samr_EnumDomainUsers: %d\n", __LINE__));
1022
1023         samr_array->count = num_account;
1024         samr_array->entries = samr_entries;
1025
1026         *r->out.resume_handle = *r->in.resume_handle + num_account;
1027         *r->out.num_entries = num_account;
1028
1029         DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
1030
1031         return status;
1032 }
1033
1034 /*******************************************************************
1035 makes a SAM_ENTRY / UNISTR2* structure from a group list.
1036 ********************************************************************/
1037
1038 static void make_group_sam_entry_list(TALLOC_CTX *ctx,
1039                                       struct samr_SamEntry **sam_pp,
1040                                       uint32_t num_sam_entries,
1041                                       struct samr_displayentry *entries)
1042 {
1043         struct samr_SamEntry *sam;
1044         uint32_t i;
1045
1046         *sam_pp = NULL;
1047
1048         if (num_sam_entries == 0) {
1049                 return;
1050         }
1051
1052         sam = TALLOC_ZERO_ARRAY(ctx, struct samr_SamEntry, num_sam_entries);
1053         if (sam == NULL) {
1054                 return;
1055         }
1056
1057         for (i = 0; i < num_sam_entries; i++) {
1058                 /*
1059                  * JRA. I think this should include the null. TNG does not.
1060                  */
1061                 init_lsa_String(&sam[i].name, entries[i].account_name);
1062                 sam[i].idx = entries[i].rid;
1063         }
1064
1065         *sam_pp = sam;
1066 }
1067
1068 /*******************************************************************
1069  _samr_EnumDomainGroups
1070  ********************************************************************/
1071
1072 NTSTATUS _samr_EnumDomainGroups(struct pipes_struct *p,
1073                                 struct samr_EnumDomainGroups *r)
1074 {
1075         NTSTATUS status;
1076         struct samr_domain_info *dinfo;
1077         struct samr_displayentry *groups;
1078         uint32 num_groups;
1079         struct samr_SamArray *samr_array = NULL;
1080         struct samr_SamEntry *samr_entries = NULL;
1081
1082         dinfo = policy_handle_find(p, r->in.domain_handle,
1083                                    SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
1084                                    struct samr_domain_info, &status);
1085         if (!NT_STATUS_IS_OK(status)) {
1086                 return status;
1087         }
1088
1089         DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
1090
1091         samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
1092         if (!samr_array) {
1093                 return NT_STATUS_NO_MEMORY;
1094         }
1095         *r->out.sam = samr_array;
1096
1097         if (sid_check_is_builtin(&dinfo->sid)) {
1098                 /* No groups in builtin. */
1099                 *r->out.resume_handle = *r->in.resume_handle;
1100                 DEBUG(5,("_samr_EnumDomainGroups: No groups in BUILTIN\n"));
1101                 return status;
1102         }
1103
1104         /* the domain group array is being allocated in the function below */
1105
1106         become_root();
1107
1108         if (dinfo->disp_info->groups == NULL) {
1109                 dinfo->disp_info->groups = pdb_search_groups(dinfo->disp_info);
1110
1111                 if (dinfo->disp_info->groups == NULL) {
1112                         unbecome_root();
1113                         return NT_STATUS_ACCESS_DENIED;
1114                 }
1115         }
1116
1117         num_groups = pdb_search_entries(dinfo->disp_info->groups,
1118                                         *r->in.resume_handle,
1119                                         MAX_SAM_ENTRIES, &groups);
1120         unbecome_root();
1121
1122         /* Ensure we cache this enumeration. */
1123         set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
1124
1125         make_group_sam_entry_list(p->mem_ctx, &samr_entries,
1126                                   num_groups, groups);
1127
1128         if (MAX_SAM_ENTRIES <= num_groups) {
1129                 status = STATUS_MORE_ENTRIES;
1130         } else {
1131                 status = NT_STATUS_OK;
1132         }
1133
1134         samr_array->count = num_groups;
1135         samr_array->entries = samr_entries;
1136
1137         *r->out.num_entries = num_groups;
1138         *r->out.resume_handle = num_groups + *r->in.resume_handle;
1139
1140         DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
1141
1142         return status;
1143 }
1144
1145 /*******************************************************************
1146  _samr_EnumDomainAliases
1147  ********************************************************************/
1148
1149 NTSTATUS _samr_EnumDomainAliases(struct pipes_struct *p,
1150                                  struct samr_EnumDomainAliases *r)
1151 {
1152         NTSTATUS status;
1153         struct samr_domain_info *dinfo;
1154         struct samr_displayentry *aliases;
1155         uint32 num_aliases = 0;
1156         struct samr_SamArray *samr_array = NULL;
1157         struct samr_SamEntry *samr_entries = NULL;
1158
1159         dinfo = policy_handle_find(p, r->in.domain_handle,
1160                                    SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
1161                                    struct samr_domain_info, &status);
1162         if (!NT_STATUS_IS_OK(status)) {
1163                 return status;
1164         }
1165
1166         DEBUG(5,("_samr_EnumDomainAliases: sid %s\n",
1167                  sid_string_dbg(&dinfo->sid)));
1168
1169         samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
1170         if (!samr_array) {
1171                 return NT_STATUS_NO_MEMORY;
1172         }
1173
1174         become_root();
1175
1176         if (dinfo->disp_info->aliases == NULL) {
1177                 dinfo->disp_info->aliases = pdb_search_aliases(
1178                         dinfo->disp_info, &dinfo->sid);
1179                 if (dinfo->disp_info->aliases == NULL) {
1180                         unbecome_root();
1181                         return NT_STATUS_ACCESS_DENIED;
1182                 }
1183         }
1184
1185         num_aliases = pdb_search_entries(dinfo->disp_info->aliases,
1186                                          *r->in.resume_handle,
1187                                          MAX_SAM_ENTRIES, &aliases);
1188         unbecome_root();
1189
1190         /* Ensure we cache this enumeration. */
1191         set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
1192
1193         make_group_sam_entry_list(p->mem_ctx, &samr_entries,
1194                                   num_aliases, aliases);
1195
1196         DEBUG(5,("_samr_EnumDomainAliases: %d\n", __LINE__));
1197
1198         if (MAX_SAM_ENTRIES <= num_aliases) {
1199                 status = STATUS_MORE_ENTRIES;
1200         } else {
1201                 status = NT_STATUS_OK;
1202         }
1203
1204         samr_array->count = num_aliases;
1205         samr_array->entries = samr_entries;
1206
1207         *r->out.sam = samr_array;
1208         *r->out.num_entries = num_aliases;
1209         *r->out.resume_handle = num_aliases + *r->in.resume_handle;
1210
1211         return status;
1212 }
1213
1214 /*******************************************************************
1215  inits a samr_DispInfoGeneral structure.
1216 ********************************************************************/
1217
1218 static NTSTATUS init_samr_dispinfo_1(TALLOC_CTX *ctx,
1219                                      struct samr_DispInfoGeneral *r,
1220                                      uint32_t num_entries,
1221                                      uint32_t start_idx,
1222                                      struct samr_displayentry *entries)
1223 {
1224         uint32 i;
1225
1226         DEBUG(10, ("init_samr_dispinfo_1: num_entries: %d\n", num_entries));
1227
1228         if (num_entries == 0) {
1229                 return NT_STATUS_OK;
1230         }
1231
1232         r->count = num_entries;
1233
1234         r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryGeneral, num_entries);
1235         if (!r->entries) {
1236                 return NT_STATUS_NO_MEMORY;
1237         }
1238
1239         for (i = 0; i < num_entries ; i++) {
1240
1241                 init_lsa_String(&r->entries[i].account_name,
1242                                 entries[i].account_name);
1243
1244                 init_lsa_String(&r->entries[i].description,
1245                                 entries[i].description);
1246
1247                 init_lsa_String(&r->entries[i].full_name,
1248                                 entries[i].fullname);
1249
1250                 r->entries[i].rid = entries[i].rid;
1251                 r->entries[i].acct_flags = entries[i].acct_flags;
1252                 r->entries[i].idx = start_idx+i+1;
1253         }
1254
1255         return NT_STATUS_OK;
1256 }
1257
1258 /*******************************************************************
1259  inits a samr_DispInfoFull structure.
1260 ********************************************************************/
1261
1262 static NTSTATUS init_samr_dispinfo_2(TALLOC_CTX *ctx,
1263                                      struct samr_DispInfoFull *r,
1264                                      uint32_t num_entries,
1265                                      uint32_t start_idx,
1266                                      struct samr_displayentry *entries)
1267 {
1268         uint32_t i;
1269
1270         DEBUG(10, ("init_samr_dispinfo_2: num_entries: %d\n", num_entries));
1271
1272         if (num_entries == 0) {
1273                 return NT_STATUS_OK;
1274         }
1275
1276         r->count = num_entries;
1277
1278         r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryFull, num_entries);
1279         if (!r->entries) {
1280                 return NT_STATUS_NO_MEMORY;
1281         }
1282
1283         for (i = 0; i < num_entries ; i++) {
1284
1285                 init_lsa_String(&r->entries[i].account_name,
1286                                 entries[i].account_name);
1287
1288                 init_lsa_String(&r->entries[i].description,
1289                                 entries[i].description);
1290
1291                 r->entries[i].rid = entries[i].rid;
1292                 r->entries[i].acct_flags = entries[i].acct_flags;
1293                 r->entries[i].idx = start_idx+i+1;
1294         }
1295
1296         return NT_STATUS_OK;
1297 }
1298
1299 /*******************************************************************
1300  inits a samr_DispInfoFullGroups structure.
1301 ********************************************************************/
1302
1303 static NTSTATUS init_samr_dispinfo_3(TALLOC_CTX *ctx,
1304                                      struct samr_DispInfoFullGroups *r,
1305                                      uint32_t num_entries,
1306                                      uint32_t start_idx,
1307                                      struct samr_displayentry *entries)
1308 {
1309         uint32_t i;
1310
1311         DEBUG(5, ("init_samr_dispinfo_3: num_entries: %d\n", num_entries));
1312
1313         if (num_entries == 0) {
1314                 return NT_STATUS_OK;
1315         }
1316
1317         r->count = num_entries;
1318
1319         r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryFullGroup, num_entries);
1320         if (!r->entries) {
1321                 return NT_STATUS_NO_MEMORY;
1322         }
1323
1324         for (i = 0; i < num_entries ; i++) {
1325
1326                 init_lsa_String(&r->entries[i].account_name,
1327                                 entries[i].account_name);
1328
1329                 init_lsa_String(&r->entries[i].description,
1330                                 entries[i].description);
1331
1332                 r->entries[i].rid = entries[i].rid;
1333                 r->entries[i].acct_flags = entries[i].acct_flags;
1334                 r->entries[i].idx = start_idx+i+1;
1335         }
1336
1337         return NT_STATUS_OK;
1338 }
1339
1340 /*******************************************************************
1341  inits a samr_DispInfoAscii structure.
1342 ********************************************************************/
1343
1344 static NTSTATUS init_samr_dispinfo_4(TALLOC_CTX *ctx,
1345                                      struct samr_DispInfoAscii *r,
1346                                      uint32_t num_entries,
1347                                      uint32_t start_idx,
1348                                      struct samr_displayentry *entries)
1349 {
1350         uint32_t i;
1351
1352         DEBUG(5, ("init_samr_dispinfo_4: num_entries: %d\n", num_entries));
1353
1354         if (num_entries == 0) {
1355                 return NT_STATUS_OK;
1356         }
1357
1358         r->count = num_entries;
1359
1360         r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryAscii, num_entries);
1361         if (!r->entries) {
1362                 return NT_STATUS_NO_MEMORY;
1363         }
1364
1365         for (i = 0; i < num_entries ; i++) {
1366
1367                 init_lsa_AsciiStringLarge(&r->entries[i].account_name,
1368                                           entries[i].account_name);
1369
1370                 r->entries[i].idx = start_idx+i+1;
1371         }
1372
1373         return NT_STATUS_OK;
1374 }
1375
1376 /*******************************************************************
1377  inits a samr_DispInfoAscii structure.
1378 ********************************************************************/
1379
1380 static NTSTATUS init_samr_dispinfo_5(TALLOC_CTX *ctx,
1381                                      struct samr_DispInfoAscii *r,
1382                                      uint32_t num_entries,
1383                                      uint32_t start_idx,
1384                                      struct samr_displayentry *entries)
1385 {
1386         uint32_t i;
1387
1388         DEBUG(5, ("init_samr_dispinfo_5: num_entries: %d\n", num_entries));
1389
1390         if (num_entries == 0) {
1391                 return NT_STATUS_OK;
1392         }
1393
1394         r->count = num_entries;
1395
1396         r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryAscii, num_entries);
1397         if (!r->entries) {
1398                 return NT_STATUS_NO_MEMORY;
1399         }
1400
1401         for (i = 0; i < num_entries ; i++) {
1402
1403                 init_lsa_AsciiStringLarge(&r->entries[i].account_name,
1404                                           entries[i].account_name);
1405
1406                 r->entries[i].idx = start_idx+i+1;
1407         }
1408
1409         return NT_STATUS_OK;
1410 }
1411
1412 /*******************************************************************
1413  _samr_QueryDisplayInfo
1414  ********************************************************************/
1415
1416 NTSTATUS _samr_QueryDisplayInfo(struct pipes_struct *p,
1417                                 struct samr_QueryDisplayInfo *r)
1418 {
1419         NTSTATUS status;
1420         struct samr_domain_info *dinfo;
1421         uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
1422
1423         uint32 max_entries = r->in.max_entries;
1424
1425         union samr_DispInfo *disp_info = r->out.info;
1426
1427         uint32 temp_size=0;
1428         NTSTATUS disp_ret = NT_STATUS_UNSUCCESSFUL;
1429         uint32 num_account = 0;
1430         enum remote_arch_types ra_type = get_remote_arch();
1431         int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
1432         struct samr_displayentry *entries = NULL;
1433
1434         DEBUG(5,("_samr_QueryDisplayInfo: %d\n", __LINE__));
1435
1436         dinfo = policy_handle_find(p, r->in.domain_handle,
1437                                    SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
1438                                    struct samr_domain_info, &status);
1439         if (!NT_STATUS_IS_OK(status)) {
1440                 return status;
1441         }
1442
1443         if (sid_check_is_builtin(&dinfo->sid)) {
1444                 DEBUG(5,("_samr_QueryDisplayInfo: no users in BUILTIN\n"));
1445                 return NT_STATUS_OK;
1446         }
1447
1448         /*
1449          * calculate how many entries we will return.
1450          * based on
1451          * - the number of entries the client asked
1452          * - our limit on that
1453          * - the starting point (enumeration context)
1454          * - the buffer size the client will accept
1455          */
1456
1457         /*
1458          * We are a lot more like W2K. Instead of reading the SAM
1459          * each time to find the records we need to send back,
1460          * we read it once and link that copy to the sam handle.
1461          * For large user list (over the MAX_SAM_ENTRIES)
1462          * it's a definitive win.
1463          * second point to notice: between enumerations
1464          * our sam is now the same as it's a snapshoot.
1465          * third point: got rid of the static SAM_USER_21 struct
1466          * no more intermediate.
1467          * con: it uses much more memory, as a full copy is stored
1468          * in memory.
1469          *
1470          * If you want to change it, think twice and think
1471          * of the second point , that's really important.
1472          *
1473          * JFM, 12/20/2001
1474          */
1475
1476         if ((r->in.level < 1) || (r->in.level > 5)) {
1477                 DEBUG(0,("_samr_QueryDisplayInfo: Unknown info level (%u)\n",
1478                          (unsigned int)r->in.level ));
1479                 return NT_STATUS_INVALID_INFO_CLASS;
1480         }
1481
1482         /* first limit the number of entries we will return */
1483         if (r->in.max_entries > max_sam_entries) {
1484                 DEBUG(5, ("_samr_QueryDisplayInfo: client requested %d "
1485                           "entries, limiting to %d\n", r->in.max_entries,
1486                           max_sam_entries));
1487                 max_entries = max_sam_entries;
1488         }
1489
1490         /* calculate the size and limit on the number of entries we will
1491          * return */
1492
1493         temp_size=max_entries*struct_size;
1494
1495         if (temp_size > r->in.buf_size) {
1496                 max_entries = MIN((r->in.buf_size / struct_size),max_entries);;
1497                 DEBUG(5, ("_samr_QueryDisplayInfo: buffer size limits to "
1498                           "only %d entries\n", max_entries));
1499         }
1500
1501         become_root();
1502
1503         /* THe following done as ROOT. Don't return without unbecome_root(). */
1504
1505         switch (r->in.level) {
1506         case 1:
1507         case 4:
1508                 if (dinfo->disp_info->users == NULL) {
1509                         dinfo->disp_info->users = pdb_search_users(
1510                                 dinfo->disp_info, ACB_NORMAL);
1511                         if (dinfo->disp_info->users == NULL) {
1512                                 unbecome_root();
1513                                 return NT_STATUS_ACCESS_DENIED;
1514                         }
1515                         DEBUG(10,("_samr_QueryDisplayInfo: starting user enumeration at index %u\n",
1516                                 (unsigned  int)r->in.start_idx));
1517                 } else {
1518                         DEBUG(10,("_samr_QueryDisplayInfo: using cached user enumeration at index %u\n",
1519                                 (unsigned  int)r->in.start_idx));
1520                 }
1521
1522                 num_account = pdb_search_entries(dinfo->disp_info->users,
1523                                                  r->in.start_idx, max_entries,
1524                                                  &entries);
1525                 break;
1526         case 2:
1527                 if (dinfo->disp_info->machines == NULL) {
1528                         dinfo->disp_info->machines = pdb_search_users(
1529                                 dinfo->disp_info, ACB_WSTRUST|ACB_SVRTRUST);
1530                         if (dinfo->disp_info->machines == NULL) {
1531                                 unbecome_root();
1532                                 return NT_STATUS_ACCESS_DENIED;
1533                         }
1534                         DEBUG(10,("_samr_QueryDisplayInfo: starting machine enumeration at index %u\n",
1535                                 (unsigned  int)r->in.start_idx));
1536                 } else {
1537                         DEBUG(10,("_samr_QueryDisplayInfo: using cached machine enumeration at index %u\n",
1538                                 (unsigned  int)r->in.start_idx));
1539                 }
1540
1541                 num_account = pdb_search_entries(dinfo->disp_info->machines,
1542                                                  r->in.start_idx, max_entries,
1543                                                  &entries);
1544                 break;
1545         case 3:
1546         case 5:
1547                 if (dinfo->disp_info->groups == NULL) {
1548                         dinfo->disp_info->groups = pdb_search_groups(
1549                                 dinfo->disp_info);
1550                         if (dinfo->disp_info->groups == NULL) {
1551                                 unbecome_root();
1552                                 return NT_STATUS_ACCESS_DENIED;
1553                         }
1554                         DEBUG(10,("_samr_QueryDisplayInfo: starting group enumeration at index %u\n",
1555                                 (unsigned  int)r->in.start_idx));
1556                 } else {
1557                         DEBUG(10,("_samr_QueryDisplayInfo: using cached group enumeration at index %u\n",
1558                                 (unsigned  int)r->in.start_idx));
1559                 }
1560
1561                 num_account = pdb_search_entries(dinfo->disp_info->groups,
1562                                                  r->in.start_idx, max_entries,
1563                                                  &entries);
1564                 break;
1565         default:
1566                 unbecome_root();
1567                 smb_panic("info class changed");
1568                 break;
1569         }
1570         unbecome_root();
1571
1572
1573         /* Now create reply structure */
1574         switch (r->in.level) {
1575         case 1:
1576                 disp_ret = init_samr_dispinfo_1(p->mem_ctx, &disp_info->info1,
1577                                                 num_account, r->in.start_idx,
1578                                                 entries);
1579                 break;
1580         case 2:
1581                 disp_ret = init_samr_dispinfo_2(p->mem_ctx, &disp_info->info2,
1582                                                 num_account, r->in.start_idx,
1583                                                 entries);
1584                 break;
1585         case 3:
1586                 disp_ret = init_samr_dispinfo_3(p->mem_ctx, &disp_info->info3,
1587                                                 num_account, r->in.start_idx,
1588                                                 entries);
1589                 break;
1590         case 4:
1591                 disp_ret = init_samr_dispinfo_4(p->mem_ctx, &disp_info->info4,
1592                                                 num_account, r->in.start_idx,
1593                                                 entries);
1594                 break;
1595         case 5:
1596                 disp_ret = init_samr_dispinfo_5(p->mem_ctx, &disp_info->info5,
1597                                                 num_account, r->in.start_idx,
1598                                                 entries);
1599                 break;
1600         default:
1601                 smb_panic("info class changed");
1602                 break;
1603         }
1604
1605         if (!NT_STATUS_IS_OK(disp_ret))
1606                 return disp_ret;
1607
1608         if (max_entries <= num_account) {
1609                 status = STATUS_MORE_ENTRIES;
1610         } else {
1611                 status = NT_STATUS_OK;
1612         }
1613
1614         /* Ensure we cache this enumeration. */
1615         set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
1616
1617         DEBUG(5, ("_samr_QueryDisplayInfo: %d\n", __LINE__));
1618
1619         *r->out.total_size = num_account * struct_size;
1620         *r->out.returned_size = num_account ? temp_size : 0;
1621
1622         return status;
1623 }
1624
1625 /****************************************************************
1626  _samr_QueryDisplayInfo2
1627 ****************************************************************/
1628
1629 NTSTATUS _samr_QueryDisplayInfo2(struct pipes_struct *p,
1630                                  struct samr_QueryDisplayInfo2 *r)
1631 {
1632         struct samr_QueryDisplayInfo q;
1633
1634         q.in.domain_handle      = r->in.domain_handle;
1635         q.in.level              = r->in.level;
1636         q.in.start_idx          = r->in.start_idx;
1637         q.in.max_entries        = r->in.max_entries;
1638         q.in.buf_size           = r->in.buf_size;
1639
1640         q.out.total_size        = r->out.total_size;
1641         q.out.returned_size     = r->out.returned_size;
1642         q.out.info              = r->out.info;
1643
1644         return _samr_QueryDisplayInfo(p, &q);
1645 }
1646
1647 /****************************************************************
1648  _samr_QueryDisplayInfo3
1649 ****************************************************************/
1650
1651 NTSTATUS _samr_QueryDisplayInfo3(struct pipes_struct *p,
1652                                  struct samr_QueryDisplayInfo3 *r)
1653 {
1654         struct samr_QueryDisplayInfo q;
1655
1656         q.in.domain_handle      = r->in.domain_handle;
1657         q.in.level              = r->in.level;
1658         q.in.start_idx          = r->in.start_idx;
1659         q.in.max_entries        = r->in.max_entries;
1660         q.in.buf_size           = r->in.buf_size;
1661
1662         q.out.total_size        = r->out.total_size;
1663         q.out.returned_size     = r->out.returned_size;
1664         q.out.info              = r->out.info;
1665
1666         return _samr_QueryDisplayInfo(p, &q);
1667 }
1668
1669 /*******************************************************************
1670  _samr_QueryAliasInfo
1671  ********************************************************************/
1672
1673 NTSTATUS _samr_QueryAliasInfo(struct pipes_struct *p,
1674                               struct samr_QueryAliasInfo *r)
1675 {
1676         struct samr_alias_info *ainfo;
1677         struct acct_info info;
1678         NTSTATUS status;
1679         union samr_AliasInfo *alias_info = NULL;
1680         const char *alias_name = NULL;
1681         const char *alias_description = NULL;
1682
1683         DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1684
1685         ainfo = policy_handle_find(p, r->in.alias_handle,
1686                                    SAMR_ALIAS_ACCESS_LOOKUP_INFO, NULL,
1687                                    struct samr_alias_info, &status);
1688         if (!NT_STATUS_IS_OK(status)) {
1689                 return status;
1690         }
1691
1692         alias_info = TALLOC_ZERO_P(p->mem_ctx, union samr_AliasInfo);
1693         if (!alias_info) {
1694                 return NT_STATUS_NO_MEMORY;
1695         }
1696
1697         become_root();
1698         status = pdb_get_aliasinfo(&ainfo->sid, &info);
1699         unbecome_root();
1700
1701         if ( !NT_STATUS_IS_OK(status))
1702                 return status;
1703
1704         /* FIXME: info contains fstrings */
1705         alias_name = talloc_strdup(r, info.acct_name);
1706         alias_description = talloc_strdup(r, info.acct_desc);
1707
1708         switch (r->in.level) {
1709         case ALIASINFOALL:
1710                 alias_info->all.name.string             = alias_name;
1711                 alias_info->all.num_members             = 1; /* ??? */
1712                 alias_info->all.description.string      = alias_description;
1713                 break;
1714         case ALIASINFONAME:
1715                 alias_info->name.string                 = alias_name;
1716                 break;
1717         case ALIASINFODESCRIPTION:
1718                 alias_info->description.string          = alias_description;
1719                 break;
1720         default:
1721                 return NT_STATUS_INVALID_INFO_CLASS;
1722         }
1723
1724         *r->out.info = alias_info;
1725
1726         DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1727
1728         return NT_STATUS_OK;
1729 }
1730
1731 /*******************************************************************
1732  _samr_LookupNames
1733  ********************************************************************/
1734
1735 NTSTATUS _samr_LookupNames(struct pipes_struct *p,
1736                            struct samr_LookupNames *r)
1737 {
1738         struct samr_domain_info *dinfo;
1739         NTSTATUS status;
1740         uint32 *rid;
1741         enum lsa_SidType *type;
1742         int i;
1743         int num_rids = r->in.num_names;
1744         struct samr_Ids rids, types;
1745         uint32_t num_mapped = 0;
1746
1747         DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1748
1749         dinfo = policy_handle_find(p, r->in.domain_handle,
1750                                    0 /* Don't know the acc_bits yet */, NULL,
1751                                    struct samr_domain_info, &status);
1752         if (!NT_STATUS_IS_OK(status)) {
1753                 return status;
1754         }
1755
1756         if (num_rids > MAX_SAM_ENTRIES) {
1757                 num_rids = MAX_SAM_ENTRIES;
1758                 DEBUG(5,("_samr_LookupNames: truncating entries to %d\n", num_rids));
1759         }
1760
1761         rid = talloc_array(p->mem_ctx, uint32, num_rids);
1762         NT_STATUS_HAVE_NO_MEMORY(rid);
1763
1764         type = talloc_array(p->mem_ctx, enum lsa_SidType, num_rids);
1765         NT_STATUS_HAVE_NO_MEMORY(type);
1766
1767         DEBUG(5,("_samr_LookupNames: looking name on SID %s\n",
1768                  sid_string_dbg(&dinfo->sid)));
1769
1770         for (i = 0; i < num_rids; i++) {
1771
1772                 status = NT_STATUS_NONE_MAPPED;
1773                 type[i] = SID_NAME_UNKNOWN;
1774
1775                 rid[i] = 0xffffffff;
1776
1777                 if (sid_check_is_builtin(&dinfo->sid)) {
1778                         if (lookup_builtin_name(r->in.names[i].string,
1779                                                 &rid[i]))
1780                         {
1781                                 type[i] = SID_NAME_ALIAS;
1782                         }
1783                 } else {
1784                         lookup_global_sam_name(r->in.names[i].string, 0,
1785                                                &rid[i], &type[i]);
1786                 }
1787
1788                 if (type[i] != SID_NAME_UNKNOWN) {
1789                         num_mapped++;
1790                 }
1791         }
1792
1793         if (num_mapped == num_rids) {
1794                 status = NT_STATUS_OK;
1795         } else if (num_mapped == 0) {
1796                 status = NT_STATUS_NONE_MAPPED;
1797         } else {
1798                 status = STATUS_SOME_UNMAPPED;
1799         }
1800
1801         rids.count = num_rids;
1802         rids.ids = rid;
1803
1804         types.count = num_rids;
1805         types.ids = talloc_array(p->mem_ctx, uint32_t, num_rids);
1806         NT_STATUS_HAVE_NO_MEMORY(type);
1807         for (i = 0; i < num_rids; i++) {
1808                 types.ids[i] = (type[i] & 0xffffffff);
1809         }
1810
1811         *r->out.rids = rids;
1812         *r->out.types = types;
1813
1814         DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1815
1816         return status;
1817 }
1818
1819 /****************************************************************
1820  _samr_ChangePasswordUser
1821 ****************************************************************/
1822
1823 NTSTATUS _samr_ChangePasswordUser(struct pipes_struct *p,
1824                                   struct samr_ChangePasswordUser *r)
1825 {
1826         NTSTATUS status;
1827         bool ret = false;
1828         struct samr_user_info *uinfo;
1829         struct samu *pwd;
1830         struct samr_Password new_lmPwdHash, new_ntPwdHash, checkHash;
1831         struct samr_Password lm_pwd, nt_pwd;
1832
1833         uinfo = policy_handle_find(p, r->in.user_handle,
1834                                    SAMR_USER_ACCESS_SET_PASSWORD, NULL,
1835                                    struct samr_user_info, &status);
1836         if (!NT_STATUS_IS_OK(status)) {
1837                 return status;
1838         }
1839
1840         DEBUG(5,("_samr_ChangePasswordUser: sid:%s\n",
1841                   sid_string_dbg(&uinfo->sid)));
1842
1843         if (!(pwd = samu_new(NULL))) {
1844                 return NT_STATUS_NO_MEMORY;
1845         }
1846
1847         become_root();
1848         ret = pdb_getsampwsid(pwd, &uinfo->sid);
1849         unbecome_root();
1850
1851         if (!ret) {
1852                 TALLOC_FREE(pwd);
1853                 return NT_STATUS_WRONG_PASSWORD;
1854         }
1855
1856         {
1857                 const uint8_t *lm_pass, *nt_pass;
1858
1859                 lm_pass = pdb_get_lanman_passwd(pwd);
1860                 nt_pass = pdb_get_nt_passwd(pwd);
1861
1862                 if (!lm_pass || !nt_pass) {
1863                         status = NT_STATUS_WRONG_PASSWORD;
1864                         goto out;
1865                 }
1866
1867                 memcpy(&lm_pwd.hash, lm_pass, sizeof(lm_pwd.hash));
1868                 memcpy(&nt_pwd.hash, nt_pass, sizeof(nt_pwd.hash));
1869         }
1870
1871         /* basic sanity checking on parameters.  Do this before any database ops */
1872         if (!r->in.lm_present || !r->in.nt_present ||
1873             !r->in.old_lm_crypted || !r->in.new_lm_crypted ||
1874             !r->in.old_nt_crypted || !r->in.new_nt_crypted) {
1875                 /* we should really handle a change with lm not
1876                    present */
1877                 status = NT_STATUS_INVALID_PARAMETER_MIX;
1878                 goto out;
1879         }
1880
1881         /* decrypt and check the new lm hash */
1882         D_P16(lm_pwd.hash, r->in.new_lm_crypted->hash, new_lmPwdHash.hash);
1883         D_P16(new_lmPwdHash.hash, r->in.old_lm_crypted->hash, checkHash.hash);
1884         if (memcmp(checkHash.hash, lm_pwd.hash, 16) != 0) {
1885                 status = NT_STATUS_WRONG_PASSWORD;
1886                 goto out;
1887         }
1888
1889         /* decrypt and check the new nt hash */
1890         D_P16(nt_pwd.hash, r->in.new_nt_crypted->hash, new_ntPwdHash.hash);
1891         D_P16(new_ntPwdHash.hash, r->in.old_nt_crypted->hash, checkHash.hash);
1892         if (memcmp(checkHash.hash, nt_pwd.hash, 16) != 0) {
1893                 status = NT_STATUS_WRONG_PASSWORD;
1894                 goto out;
1895         }
1896
1897         /* The NT Cross is not required by Win2k3 R2, but if present
1898            check the nt cross hash */
1899         if (r->in.cross1_present && r->in.nt_cross) {
1900                 D_P16(lm_pwd.hash, r->in.nt_cross->hash, checkHash.hash);
1901                 if (memcmp(checkHash.hash, new_ntPwdHash.hash, 16) != 0) {
1902                         status = NT_STATUS_WRONG_PASSWORD;
1903                         goto out;
1904                 }
1905         }
1906
1907         /* The LM Cross is not required by Win2k3 R2, but if present
1908            check the lm cross hash */
1909         if (r->in.cross2_present && r->in.lm_cross) {
1910                 D_P16(nt_pwd.hash, r->in.lm_cross->hash, checkHash.hash);
1911                 if (memcmp(checkHash.hash, new_lmPwdHash.hash, 16) != 0) {
1912                         status = NT_STATUS_WRONG_PASSWORD;
1913                         goto out;
1914                 }
1915         }
1916
1917         if (!pdb_set_nt_passwd(pwd, new_ntPwdHash.hash, PDB_CHANGED) ||
1918             !pdb_set_lanman_passwd(pwd, new_lmPwdHash.hash, PDB_CHANGED)) {
1919                 status = NT_STATUS_ACCESS_DENIED;
1920                 goto out;
1921         }
1922
1923         status = pdb_update_sam_account(pwd);
1924  out:
1925         TALLOC_FREE(pwd);
1926
1927         return status;
1928 }
1929
1930 /*******************************************************************
1931  _samr_ChangePasswordUser2
1932  ********************************************************************/
1933
1934 NTSTATUS _samr_ChangePasswordUser2(struct pipes_struct *p,
1935                                    struct samr_ChangePasswordUser2 *r)
1936 {
1937         NTSTATUS status;
1938         fstring user_name;
1939         fstring wks;
1940
1941         DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1942
1943         fstrcpy(user_name, r->in.account->string);
1944         fstrcpy(wks, r->in.server->string);
1945
1946         DEBUG(5,("_samr_ChangePasswordUser2: user: %s wks: %s\n", user_name, wks));
1947
1948         /*
1949          * Pass the user through the NT -> unix user mapping
1950          * function.
1951          */
1952
1953         (void)map_username(user_name);
1954
1955         /*
1956          * UNIX username case mangling not required, pass_oem_change
1957          * is case insensitive.
1958          */
1959
1960         status = pass_oem_change(user_name,
1961                                  p->client_id->name,
1962                                  r->in.lm_password->data,
1963                                  r->in.lm_verifier->hash,
1964                                  r->in.nt_password->data,
1965                                  r->in.nt_verifier->hash,
1966                                  NULL);
1967
1968         DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1969
1970         if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
1971                 return NT_STATUS_WRONG_PASSWORD;
1972         }
1973
1974         return status;
1975 }
1976
1977 /****************************************************************
1978  _samr_OemChangePasswordUser2
1979 ****************************************************************/
1980
1981 NTSTATUS _samr_OemChangePasswordUser2(struct pipes_struct *p,
1982                                       struct samr_OemChangePasswordUser2 *r)
1983 {
1984         NTSTATUS status;
1985         fstring user_name;
1986         const char *wks = NULL;
1987
1988         DEBUG(5,("_samr_OemChangePasswordUser2: %d\n", __LINE__));
1989
1990         fstrcpy(user_name, r->in.account->string);
1991         if (r->in.server && r->in.server->string) {
1992                 wks = r->in.server->string;
1993         }
1994
1995         DEBUG(5,("_samr_OemChangePasswordUser2: user: %s wks: %s\n", user_name, wks));
1996
1997         /*
1998          * Pass the user through the NT -> unix user mapping
1999          * function.
2000          */
2001
2002         (void)map_username(user_name);
2003
2004         /*
2005          * UNIX username case mangling not required, pass_oem_change
2006          * is case insensitive.
2007          */
2008
2009         if (!r->in.hash || !r->in.password) {
2010                 return NT_STATUS_INVALID_PARAMETER;
2011         }
2012
2013         status = pass_oem_change(user_name,
2014                                  p->client_id->name,
2015                                  r->in.password->data,
2016                                  r->in.hash->hash,
2017                                  0,
2018                                  0,
2019                                  NULL);
2020
2021         if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
2022                 return NT_STATUS_WRONG_PASSWORD;
2023         }
2024
2025         DEBUG(5,("_samr_OemChangePasswordUser2: %d\n", __LINE__));
2026
2027         return status;
2028 }
2029
2030 /*******************************************************************
2031  _samr_ChangePasswordUser3
2032  ********************************************************************/
2033
2034 NTSTATUS _samr_ChangePasswordUser3(struct pipes_struct *p,
2035                                    struct samr_ChangePasswordUser3 *r)
2036 {
2037         NTSTATUS status;
2038         fstring user_name;
2039         const char *wks = NULL;
2040         enum samPwdChangeReason reject_reason;
2041         struct samr_DomInfo1 *dominfo = NULL;
2042         struct userPwdChangeFailureInformation *reject = NULL;
2043         uint32_t tmp;
2044
2045         DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
2046
2047         fstrcpy(user_name, r->in.account->string);
2048         if (r->in.server && r->in.server->string) {
2049                 wks = r->in.server->string;
2050         }
2051
2052         DEBUG(5,("_samr_ChangePasswordUser3: user: %s wks: %s\n", user_name, wks));
2053
2054         /*
2055          * Pass the user through the NT -> unix user mapping
2056          * function.
2057          */
2058
2059         (void)map_username(user_name);
2060
2061         /*
2062          * UNIX username case mangling not required, pass_oem_change
2063          * is case insensitive.
2064          */
2065
2066         status = pass_oem_change(user_name,
2067                                  p->client_id->name,
2068                                  r->in.lm_password->data,
2069                                  r->in.lm_verifier->hash,
2070                                  r->in.nt_password->data,
2071                                  r->in.nt_verifier->hash,
2072                                  &reject_reason);
2073         if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
2074                 return NT_STATUS_WRONG_PASSWORD;
2075         }
2076
2077         if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) ||
2078             NT_STATUS_EQUAL(status, NT_STATUS_ACCOUNT_RESTRICTION)) {
2079
2080                 time_t u_expire, u_min_age;
2081                 uint32 account_policy_temp;
2082
2083                 dominfo = TALLOC_ZERO_P(p->mem_ctx, struct samr_DomInfo1);
2084                 if (!dominfo) {
2085                         return NT_STATUS_NO_MEMORY;
2086                 }
2087
2088                 reject = TALLOC_ZERO_P(p->mem_ctx,
2089                                 struct userPwdChangeFailureInformation);
2090                 if (!reject) {
2091                         return NT_STATUS_NO_MEMORY;
2092                 }
2093
2094                 become_root();
2095
2096                 /* AS ROOT !!! */
2097
2098                 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN, &tmp);
2099                 dominfo->min_password_length = tmp;
2100
2101                 pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &tmp);
2102                 dominfo->password_history_length = tmp;
2103
2104                 pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
2105                                        &dominfo->password_properties);
2106
2107                 pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, &account_policy_temp);
2108                 u_expire = account_policy_temp;
2109
2110                 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, &account_policy_temp);
2111                 u_min_age = account_policy_temp;
2112
2113                 /* !AS ROOT */
2114
2115                 unbecome_root();
2116
2117                 unix_to_nt_time_abs((NTTIME *)&dominfo->max_password_age, u_expire);
2118                 unix_to_nt_time_abs((NTTIME *)&dominfo->min_password_age, u_min_age);
2119
2120                 if (lp_check_password_script() && *lp_check_password_script()) {
2121                         dominfo->password_properties |= DOMAIN_PASSWORD_COMPLEX;
2122                 }
2123
2124                 reject->extendedFailureReason = reject_reason;
2125
2126                 *r->out.dominfo = dominfo;
2127                 *r->out.reject = reject;
2128         }
2129
2130         DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
2131
2132         return status;
2133 }
2134
2135 /*******************************************************************
2136 makes a SAMR_R_LOOKUP_RIDS structure.
2137 ********************************************************************/
2138
2139 static bool make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names,
2140                                   const char **names,
2141                                   struct lsa_String **lsa_name_array_p)
2142 {
2143         struct lsa_String *lsa_name_array = NULL;
2144         uint32_t i;
2145
2146         *lsa_name_array_p = NULL;
2147
2148         if (num_names != 0) {
2149                 lsa_name_array = TALLOC_ZERO_ARRAY(ctx, struct lsa_String, num_names);
2150                 if (!lsa_name_array) {
2151                         return false;
2152                 }
2153         }
2154
2155         for (i = 0; i < num_names; i++) {
2156                 DEBUG(10, ("names[%d]:%s\n", i, names[i] && *names[i] ? names[i] : ""));
2157                 init_lsa_String(&lsa_name_array[i], names[i]);
2158         }
2159
2160         *lsa_name_array_p = lsa_name_array;
2161
2162         return true;
2163 }
2164
2165 /*******************************************************************
2166  _samr_LookupRids
2167  ********************************************************************/
2168
2169 NTSTATUS _samr_LookupRids(struct pipes_struct *p,
2170                           struct samr_LookupRids *r)
2171 {
2172         struct samr_domain_info *dinfo;
2173         NTSTATUS status;
2174         const char **names;
2175         enum lsa_SidType *attrs = NULL;
2176         uint32 *wire_attrs = NULL;
2177         int num_rids = (int)r->in.num_rids;
2178         int i;
2179         struct lsa_Strings names_array;
2180         struct samr_Ids types_array;
2181         struct lsa_String *lsa_names = NULL;
2182
2183         DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2184
2185         dinfo = policy_handle_find(p, r->in.domain_handle,
2186                                    0 /* Don't know the acc_bits yet */, NULL,
2187                                    struct samr_domain_info, &status);
2188         if (!NT_STATUS_IS_OK(status)) {
2189                 return status;
2190         }
2191
2192         if (num_rids > 1000) {
2193                 DEBUG(0, ("Got asked for %d rids (more than 1000) -- according "
2194                           "to samba4 idl this is not possible\n", num_rids));
2195                 return NT_STATUS_UNSUCCESSFUL;
2196         }
2197
2198         if (num_rids) {
2199                 names = TALLOC_ZERO_ARRAY(p->mem_ctx, const char *, num_rids);
2200                 attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, enum lsa_SidType, num_rids);
2201                 wire_attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_rids);
2202
2203                 if ((names == NULL) || (attrs == NULL) || (wire_attrs==NULL))
2204                         return NT_STATUS_NO_MEMORY;
2205         } else {
2206                 names = NULL;
2207                 attrs = NULL;
2208                 wire_attrs = NULL;
2209         }
2210
2211         become_root();  /* lookup_sid can require root privs */
2212         status = pdb_lookup_rids(&dinfo->sid, num_rids, r->in.rids,
2213                                  names, attrs);
2214         unbecome_root();
2215
2216         if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED) && (num_rids == 0)) {
2217                 status = NT_STATUS_OK;
2218         }
2219
2220         if (!make_samr_lookup_rids(p->mem_ctx, num_rids, names,
2221                                    &lsa_names)) {
2222                 return NT_STATUS_NO_MEMORY;
2223         }
2224
2225         /* Convert from enum lsa_SidType to uint32 for wire format. */
2226         for (i = 0; i < num_rids; i++) {
2227                 wire_attrs[i] = (uint32)attrs[i];
2228         }
2229
2230         names_array.count = num_rids;
2231         names_array.names = lsa_names;
2232
2233         types_array.count = num_rids;
2234         types_array.ids = wire_attrs;
2235
2236         *r->out.names = names_array;
2237         *r->out.types = types_array;
2238
2239         DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2240
2241         return status;
2242 }
2243
2244 /*******************************************************************
2245  _samr_OpenUser
2246 ********************************************************************/
2247
2248 NTSTATUS _samr_OpenUser(struct pipes_struct *p,
2249                         struct samr_OpenUser *r)
2250 {
2251         struct samu *sampass=NULL;
2252         struct dom_sid sid;
2253         struct samr_domain_info *dinfo;
2254         struct samr_user_info *uinfo;
2255         struct security_descriptor *psd = NULL;
2256         uint32    acc_granted;
2257         uint32    des_access = r->in.access_mask;
2258         uint32_t extra_access = 0;
2259         size_t    sd_size;
2260         bool ret;
2261         NTSTATUS nt_status;
2262
2263         /* These two privileges, if != SEC_PRIV_INVALID, indicate
2264          * privileges that the user must have to complete this
2265          * operation in defience of the fixed ACL */
2266         enum sec_privilege needed_priv_1, needed_priv_2;
2267         NTSTATUS status;
2268
2269         dinfo = policy_handle_find(p, r->in.domain_handle,
2270                                    SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
2271                                    struct samr_domain_info, &status);
2272         if (!NT_STATUS_IS_OK(status)) {
2273                 return status;
2274         }
2275
2276         if ( !(sampass = samu_new( p->mem_ctx )) ) {
2277                 return NT_STATUS_NO_MEMORY;
2278         }
2279
2280         /* append the user's RID to it */
2281
2282         if (!sid_compose(&sid, &dinfo->sid, r->in.rid))
2283                 return NT_STATUS_NO_SUCH_USER;
2284
2285         /* check if access can be granted as requested by client. */
2286         map_max_allowed_access(p->server_info->ptok,
2287                                &p->server_info->utok,
2288                                &des_access);
2289
2290         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &sid, SAMR_USR_RIGHTS_WRITE_PW);
2291         se_map_generic(&des_access, &usr_generic_mapping);
2292
2293         /*
2294          * Get the sampass first as we need to check privileges
2295          * based on what kind of user object this is.
2296          * But don't reveal info too early if it didn't exist.
2297          */
2298
2299         become_root();
2300         ret=pdb_getsampwsid(sampass, &sid);
2301         unbecome_root();
2302
2303         needed_priv_1 = SEC_PRIV_INVALID;
2304         needed_priv_2 = SEC_PRIV_INVALID;
2305         /*
2306          * We do the override access checks on *open*, not at
2307          * SetUserInfo time.
2308          */
2309         if (ret) {
2310                 uint32_t acb_info = pdb_get_acct_ctrl(sampass);
2311
2312                 if (acb_info & ACB_WSTRUST) {
2313                         /*
2314                          * SeMachineAccount is needed to add
2315                          * GENERIC_RIGHTS_USER_WRITE to a machine
2316                          * account.
2317                          */
2318                         needed_priv_1 = SEC_PRIV_MACHINE_ACCOUNT;
2319                 }
2320                 if (acb_info & ACB_NORMAL) {
2321                         /*
2322                          * SeAddUsers is needed to add
2323                          * GENERIC_RIGHTS_USER_WRITE to a normal
2324                          * account.
2325                          */
2326                         needed_priv_1 = SEC_PRIV_ADD_USERS;
2327                 }
2328                 /*
2329                  * Cheat - we have not set a specific privilege for
2330                  * server (BDC) or domain trust account, so allow
2331                  * GENERIC_RIGHTS_USER_WRITE if pipe user is in
2332                  * DOMAIN_RID_ADMINS.
2333                  */
2334                 if (acb_info & (ACB_SVRTRUST|ACB_DOMTRUST)) {
2335                         if (lp_enable_privileges() && nt_token_check_domain_rid(p->server_info->ptok,
2336                                                         DOMAIN_RID_ADMINS)) {
2337                                 des_access &= ~GENERIC_RIGHTS_USER_WRITE;
2338                                 extra_access = GENERIC_RIGHTS_USER_WRITE;
2339                                 DEBUG(4,("_samr_OpenUser: Allowing "
2340                                         "GENERIC_RIGHTS_USER_WRITE for "
2341                                         "rid admins\n"));
2342                         }
2343                 }
2344         }
2345
2346         TALLOC_FREE(sampass);
2347
2348         nt_status = access_check_object(psd, p->server_info->ptok,
2349                                         needed_priv_1, needed_priv_2,
2350                                         GENERIC_RIGHTS_USER_WRITE, des_access,
2351                                         &acc_granted, "_samr_OpenUser");
2352
2353         if ( !NT_STATUS_IS_OK(nt_status) )
2354                 return nt_status;
2355
2356         /* check that the SID exists in our domain. */
2357         if (ret == False) {
2358                 return NT_STATUS_NO_SUCH_USER;
2359         }
2360
2361         /* If we did the rid admins hack above, allow access. */
2362         acc_granted |= extra_access;
2363
2364         uinfo = policy_handle_create(p, r->out.user_handle, acc_granted,
2365                                      struct samr_user_info, &nt_status);
2366         if (!NT_STATUS_IS_OK(nt_status)) {
2367                 return nt_status;
2368         }
2369         uinfo->sid = sid;
2370
2371         return NT_STATUS_OK;
2372 }
2373
2374 /*************************************************************************
2375  *************************************************************************/
2376
2377 static NTSTATUS init_samr_parameters_string(TALLOC_CTX *mem_ctx,
2378                                             DATA_BLOB *blob,
2379                                             struct lsa_BinaryString **_r)
2380 {
2381         struct lsa_BinaryString *r;
2382
2383         if (!blob || !_r) {
2384                 return NT_STATUS_INVALID_PARAMETER;
2385         }
2386
2387         r = TALLOC_ZERO_P(mem_ctx, struct lsa_BinaryString);
2388         if (!r) {
2389                 return NT_STATUS_NO_MEMORY;
2390         }
2391
2392         r->array = TALLOC_ZERO_ARRAY(mem_ctx, uint16_t, blob->length/2);
2393         if (!r->array) {
2394                 return NT_STATUS_NO_MEMORY;
2395         }
2396         memcpy(r->array, blob->data, blob->length);
2397         r->size = blob->length;
2398         r->length = blob->length;
2399
2400         if (!r->array) {
2401                 return NT_STATUS_NO_MEMORY;
2402         }
2403
2404         *_r = r;
2405
2406         return NT_STATUS_OK;
2407 }
2408
2409 /*************************************************************************
2410  *************************************************************************/
2411
2412 static struct samr_LogonHours get_logon_hours_from_pdb(TALLOC_CTX *mem_ctx,
2413                                                        struct samu *pw)
2414 {
2415         struct samr_LogonHours hours;
2416         const int units_per_week = 168;
2417
2418         ZERO_STRUCT(hours);
2419         hours.bits = talloc_array(mem_ctx, uint8_t, units_per_week);
2420         if (!hours.bits) {
2421                 return hours;
2422         }
2423
2424         hours.units_per_week = units_per_week;
2425         memset(hours.bits, 0xFF, units_per_week);
2426
2427         if (pdb_get_hours(pw)) {
2428                 memcpy(hours.bits, pdb_get_hours(pw),
2429                        MIN(pdb_get_hours_len(pw), units_per_week));
2430         }
2431
2432         return hours;
2433 }
2434
2435 /*************************************************************************
2436  get_user_info_1.
2437  *************************************************************************/
2438
2439 static NTSTATUS get_user_info_1(TALLOC_CTX *mem_ctx,
2440                                 struct samr_UserInfo1 *r,
2441                                 struct samu *pw,
2442                                 struct dom_sid *domain_sid)
2443 {
2444         const struct dom_sid *sid_group;
2445         uint32_t primary_gid;
2446
2447         become_root();
2448         sid_group = pdb_get_group_sid(pw);
2449         unbecome_root();
2450
2451         if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2452                 DEBUG(0, ("get_user_info_1: User %s has Primary Group SID %s, \n"
2453                           "which conflicts with the domain sid %s.  Failing operation.\n",
2454                           pdb_get_username(pw), sid_string_dbg(sid_group),
2455                           sid_string_dbg(domain_sid)));
2456                 return NT_STATUS_UNSUCCESSFUL;
2457         }
2458
2459         r->account_name.string          = talloc_strdup(mem_ctx, pdb_get_username(pw));
2460         r->full_name.string             = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2461         r->primary_gid                  = primary_gid;
2462         r->description.string           = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2463         r->comment.string               = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2464
2465         return NT_STATUS_OK;
2466 }
2467
2468 /*************************************************************************
2469  get_user_info_2.
2470  *************************************************************************/
2471
2472 static NTSTATUS get_user_info_2(TALLOC_CTX *mem_ctx,
2473                                 struct samr_UserInfo2 *r,
2474                                 struct samu *pw)
2475 {
2476         r->comment.string               = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2477         r->reserved.string              = NULL;
2478         r->country_code                 = 0;
2479         r->code_page                    = 0;
2480
2481         return NT_STATUS_OK;
2482 }
2483
2484 /*************************************************************************
2485  get_user_info_3.
2486  *************************************************************************/
2487
2488 static NTSTATUS get_user_info_3(TALLOC_CTX *mem_ctx,
2489                                 struct samr_UserInfo3 *r,
2490                                 struct samu *pw,
2491                                 struct dom_sid *domain_sid)
2492 {
2493         const struct dom_sid *sid_user, *sid_group;
2494         uint32_t rid, primary_gid;
2495
2496         sid_user = pdb_get_user_sid(pw);
2497
2498         if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2499                 DEBUG(0, ("get_user_info_3: User %s has SID %s, \nwhich conflicts with "
2500                           "the domain sid %s.  Failing operation.\n",
2501                           pdb_get_username(pw), sid_string_dbg(sid_user),
2502                           sid_string_dbg(domain_sid)));
2503                 return NT_STATUS_UNSUCCESSFUL;
2504         }
2505
2506         become_root();
2507         sid_group = pdb_get_group_sid(pw);
2508         unbecome_root();
2509
2510         if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2511                 DEBUG(0, ("get_user_info_3: User %s has Primary Group SID %s, \n"
2512                           "which conflicts with the domain sid %s.  Failing operation.\n",
2513                           pdb_get_username(pw), sid_string_dbg(sid_group),
2514                           sid_string_dbg(domain_sid)));
2515                 return NT_STATUS_UNSUCCESSFUL;
2516         }
2517
2518         unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2519         unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2520         unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2521         unix_to_nt_time(&r->allow_password_change, pdb_get_pass_can_change_time(pw));
2522         unix_to_nt_time(&r->force_password_change, pdb_get_pass_must_change_time(pw));
2523
2524         r->account_name.string  = talloc_strdup(mem_ctx, pdb_get_username(pw));
2525         r->full_name.string     = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2526         r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2527         r->home_drive.string    = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2528         r->logon_script.string  = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2529         r->profile_path.string  = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2530         r->workstations.string  = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2531
2532         r->logon_hours          = get_logon_hours_from_pdb(mem_ctx, pw);
2533         r->rid                  = rid;
2534         r->primary_gid          = primary_gid;
2535         r->acct_flags           = pdb_get_acct_ctrl(pw);
2536         r->bad_password_count   = pdb_get_bad_password_count(pw);
2537         r->logon_count          = pdb_get_logon_count(pw);
2538
2539         return NT_STATUS_OK;
2540 }
2541
2542 /*************************************************************************
2543  get_user_info_4.
2544  *************************************************************************/
2545
2546 static NTSTATUS get_user_info_4(TALLOC_CTX *mem_ctx,
2547                                 struct samr_UserInfo4 *r,
2548                                 struct samu *pw)
2549 {
2550         r->logon_hours          = get_logon_hours_from_pdb(mem_ctx, pw);
2551
2552         return NT_STATUS_OK;
2553 }
2554
2555 /*************************************************************************
2556  get_user_info_5.
2557  *************************************************************************/
2558
2559 static NTSTATUS get_user_info_5(TALLOC_CTX *mem_ctx,
2560                                 struct samr_UserInfo5 *r,
2561                                 struct samu *pw,
2562                                 struct dom_sid *domain_sid)
2563 {
2564         const struct dom_sid *sid_user, *sid_group;
2565         uint32_t rid, primary_gid;
2566
2567         sid_user = pdb_get_user_sid(pw);
2568
2569         if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2570                 DEBUG(0, ("get_user_info_5: User %s has SID %s, \nwhich conflicts with "
2571                           "the domain sid %s.  Failing operation.\n",
2572                           pdb_get_username(pw), sid_string_dbg(sid_user),
2573                           sid_string_dbg(domain_sid)));
2574                 return NT_STATUS_UNSUCCESSFUL;
2575         }
2576
2577         become_root();
2578         sid_group = pdb_get_group_sid(pw);
2579         unbecome_root();
2580
2581         if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2582                 DEBUG(0, ("get_user_info_5: User %s has Primary Group SID %s, \n"
2583                           "which conflicts with the domain sid %s.  Failing operation.\n",
2584                           pdb_get_username(pw), sid_string_dbg(sid_group),
2585                           sid_string_dbg(domain_sid)));
2586                 return NT_STATUS_UNSUCCESSFUL;
2587         }
2588
2589         unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2590         unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2591         unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2592         unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2593
2594         r->account_name.string  = talloc_strdup(mem_ctx, pdb_get_username(pw));
2595         r->full_name.string     = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2596         r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2597         r->home_drive.string    = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2598         r->logon_script.string  = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2599         r->profile_path.string  = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2600         r->description.string   = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2601         r->workstations.string  = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2602
2603         r->logon_hours          = get_logon_hours_from_pdb(mem_ctx, pw);
2604         r->rid                  = rid;
2605         r->primary_gid          = primary_gid;
2606         r->acct_flags           = pdb_get_acct_ctrl(pw);
2607         r->bad_password_count   = pdb_get_bad_password_count(pw);
2608         r->logon_count          = pdb_get_logon_count(pw);
2609
2610         return NT_STATUS_OK;
2611 }
2612
2613 /*************************************************************************
2614  get_user_info_6.
2615  *************************************************************************/
2616
2617 static NTSTATUS get_user_info_6(TALLOC_CTX *mem_ctx,
2618                                 struct samr_UserInfo6 *r,
2619                                 struct samu *pw)
2620 {
2621         r->account_name.string  = talloc_strdup(mem_ctx, pdb_get_username(pw));
2622         r->full_name.string     = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2623
2624         return NT_STATUS_OK;
2625 }
2626
2627 /*************************************************************************
2628  get_user_info_7. Safe. Only gives out account_name.
2629  *************************************************************************/
2630
2631 static NTSTATUS get_user_info_7(TALLOC_CTX *mem_ctx,
2632                                 struct samr_UserInfo7 *r,
2633                                 struct samu *smbpass)
2634 {
2635         r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(smbpass));
2636         if (!r->account_name.string) {
2637                 return NT_STATUS_NO_MEMORY;
2638         }
2639
2640         return NT_STATUS_OK;
2641 }
2642
2643 /*************************************************************************
2644  get_user_info_8.
2645  *************************************************************************/
2646
2647 static NTSTATUS get_user_info_8(TALLOC_CTX *mem_ctx,
2648                                 struct samr_UserInfo8 *r,
2649                                 struct samu *pw)
2650 {
2651         r->full_name.string     = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2652
2653         return NT_STATUS_OK;
2654 }
2655
2656 /*************************************************************************
2657  get_user_info_9. Only gives out primary group SID.
2658  *************************************************************************/
2659
2660 static NTSTATUS get_user_info_9(TALLOC_CTX *mem_ctx,
2661                                 struct samr_UserInfo9 *r,
2662                                 struct samu *smbpass)
2663 {
2664         r->primary_gid = pdb_get_group_rid(smbpass);
2665
2666         return NT_STATUS_OK;
2667 }
2668
2669 /*************************************************************************
2670  get_user_info_10.
2671  *************************************************************************/
2672
2673 static NTSTATUS get_user_info_10(TALLOC_CTX *mem_ctx,
2674                                  struct samr_UserInfo10 *r,
2675                                  struct samu *pw)
2676 {
2677         r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2678         r->home_drive.string    = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2679
2680         return NT_STATUS_OK;
2681 }
2682
2683 /*************************************************************************
2684  get_user_info_11.
2685  *************************************************************************/
2686
2687 static NTSTATUS get_user_info_11(TALLOC_CTX *mem_ctx,
2688                                  struct samr_UserInfo11 *r,
2689                                  struct samu *pw)
2690 {
2691         r->logon_script.string  = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2692
2693         return NT_STATUS_OK;
2694 }
2695
2696 /*************************************************************************
2697  get_user_info_12.
2698  *************************************************************************/
2699
2700 static NTSTATUS get_user_info_12(TALLOC_CTX *mem_ctx,
2701                                  struct samr_UserInfo12 *r,
2702                                  struct samu *pw)
2703 {
2704         r->profile_path.string  = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2705
2706         return NT_STATUS_OK;
2707 }
2708
2709 /*************************************************************************
2710  get_user_info_13.
2711  *************************************************************************/
2712
2713 static NTSTATUS get_user_info_13(TALLOC_CTX *mem_ctx,
2714                                  struct samr_UserInfo13 *r,
2715                                  struct samu *pw)
2716 {
2717         r->description.string   = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2718
2719         return NT_STATUS_OK;
2720 }
2721
2722 /*************************************************************************
2723  get_user_info_14.
2724  *************************************************************************/
2725
2726 static NTSTATUS get_user_info_14(TALLOC_CTX *mem_ctx,
2727                                  struct samr_UserInfo14 *r,
2728                                  struct samu *pw)
2729 {
2730         r->workstations.string  = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2731
2732         return NT_STATUS_OK;
2733 }
2734
2735 /*************************************************************************
2736  get_user_info_16. Safe. Only gives out acb bits.
2737  *************************************************************************/
2738
2739 static NTSTATUS get_user_info_16(TALLOC_CTX *mem_ctx,
2740                                  struct samr_UserInfo16 *r,
2741                                  struct samu *smbpass)
2742 {
2743         r->acct_flags = pdb_get_acct_ctrl(smbpass);
2744
2745         return NT_STATUS_OK;
2746 }
2747
2748 /*************************************************************************
2749  get_user_info_17.
2750  *************************************************************************/
2751
2752 static NTSTATUS get_user_info_17(TALLOC_CTX *mem_ctx,
2753                                  struct samr_UserInfo17 *r,
2754                                  struct samu *pw)
2755 {
2756         unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2757
2758         return NT_STATUS_OK;
2759 }
2760
2761 /*************************************************************************
2762  get_user_info_18. OK - this is the killer as it gives out password info.
2763  Ensure that this is only allowed on an encrypted connection with a root
2764  user. JRA.
2765  *************************************************************************/
2766
2767 static NTSTATUS get_user_info_18(struct pipes_struct *p,
2768                                  TALLOC_CTX *mem_ctx,
2769                                  struct samr_UserInfo18 *r,
2770                                  struct dom_sid *user_sid)
2771 {
2772         struct samu *smbpass=NULL;
2773         bool ret;
2774         const uint8_t *nt_pass = NULL;
2775         const uint8_t *lm_pass = NULL;
2776
2777         ZERO_STRUCTP(r);
2778
2779         if (p->server_info->system) {
2780                 goto query;
2781         }
2782
2783         if ((p->auth.auth_type != DCERPC_AUTH_TYPE_NTLMSSP) ||
2784             (p->auth.auth_type != DCERPC_AUTH_TYPE_KRB5) ||
2785             (p->auth.auth_type != DCERPC_AUTH_TYPE_SPNEGO)) {
2786                 return NT_STATUS_ACCESS_DENIED;
2787         }
2788
2789         if (p->auth.auth_level != DCERPC_AUTH_LEVEL_PRIVACY) {
2790                 return NT_STATUS_ACCESS_DENIED;
2791         }
2792
2793  query:
2794         /*
2795          * Do *NOT* do become_root()/unbecome_root() here ! JRA.
2796          */
2797
2798         if ( !(smbpass = samu_new( mem_ctx )) ) {
2799                 return NT_STATUS_NO_MEMORY;
2800         }
2801
2802         ret = pdb_getsampwsid(smbpass, user_sid);
2803
2804         if (ret == False) {
2805                 DEBUG(4, ("User %s not found\n", sid_string_dbg(user_sid)));
2806                 TALLOC_FREE(smbpass);
2807                 return (geteuid() == sec_initial_uid()) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
2808         }
2809
2810         DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
2811
2812         if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
2813                 TALLOC_FREE(smbpass);
2814                 return NT_STATUS_ACCOUNT_DISABLED;
2815         }
2816
2817         lm_pass = pdb_get_lanman_passwd(smbpass);
2818         if (lm_pass != NULL) {
2819                 memcpy(r->lm_pwd.hash, lm_pass, 16);
2820                 r->lm_pwd_active = true;
2821         }
2822
2823         nt_pass = pdb_get_nt_passwd(smbpass);
2824         if (nt_pass != NULL) {
2825                 memcpy(r->nt_pwd.hash, nt_pass, 16);
2826                 r->nt_pwd_active = true;
2827         }
2828         r->password_expired = 0; /* FIXME */
2829
2830         TALLOC_FREE(smbpass);
2831
2832         return NT_STATUS_OK;
2833 }
2834
2835 /*************************************************************************
2836  get_user_info_20
2837  *************************************************************************/
2838
2839 static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx,
2840                                  struct samr_UserInfo20 *r,
2841                                  struct samu *sampass)
2842 {
2843         const char *munged_dial = NULL;
2844         DATA_BLOB blob;
2845         NTSTATUS status;
2846         struct lsa_BinaryString *parameters = NULL;
2847
2848         ZERO_STRUCTP(r);
2849
2850         munged_dial = pdb_get_munged_dial(sampass);
2851
2852         DEBUG(3,("User:[%s] has [%s] (length: %d)\n", pdb_get_username(sampass),
2853                 munged_dial, (int)strlen(munged_dial)));
2854
2855         if (munged_dial) {
2856                 blob = base64_decode_data_blob(munged_dial);
2857         } else {
2858                 blob = data_blob_string_const_null("");
2859         }
2860
2861         status = init_samr_parameters_string(mem_ctx, &blob, &parameters);
2862         data_blob_free(&blob);
2863         if (!NT_STATUS_IS_OK(status)) {
2864                 return status;
2865         }
2866
2867         r->parameters = *parameters;
2868
2869         return NT_STATUS_OK;
2870 }
2871
2872
2873 /*************************************************************************
2874  get_user_info_21
2875  *************************************************************************/
2876
2877 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx,
2878                                  struct samr_UserInfo21 *r,
2879                                  struct samu *pw,
2880                                  struct dom_sid *domain_sid,
2881                                  uint32_t acc_granted)
2882 {
2883         NTSTATUS status;
2884         const struct dom_sid *sid_user, *sid_group;
2885         uint32_t rid, primary_gid;
2886         NTTIME force_password_change;
2887         time_t must_change_time;
2888         struct lsa_BinaryString *parameters = NULL;
2889         const char *munged_dial = NULL;
2890         DATA_BLOB blob;
2891
2892         ZERO_STRUCTP(r);
2893
2894         sid_user = pdb_get_user_sid(pw);
2895
2896         if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2897                 DEBUG(0, ("get_user_info_21: User %s has SID %s, \nwhich conflicts with "
2898                           "the domain sid %s.  Failing operation.\n",
2899                           pdb_get_username(pw), sid_string_dbg(sid_user),
2900                           sid_string_dbg(domain_sid)));
2901                 return NT_STATUS_UNSUCCESSFUL;
2902         }
2903
2904         become_root();
2905         sid_group = pdb_get_group_sid(pw);
2906         unbecome_root();
2907
2908         if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2909                 DEBUG(0, ("get_user_info_21: User %s has Primary Group SID %s, \n"
2910                           "which conflicts with the domain sid %s.  Failing operation.\n",
2911                           pdb_get_username(pw), sid_string_dbg(sid_group),
2912                           sid_string_dbg(domain_sid)));
2913                 return NT_STATUS_UNSUCCESSFUL;
2914         }
2915
2916         unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2917         unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2918         unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2919         unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2920         unix_to_nt_time(&r->allow_password_change, pdb_get_pass_can_change_time(pw));
2921
2922         must_change_time = pdb_get_pass_must_change_time(pw);
2923         if (must_change_time == get_time_t_max()) {
2924                 unix_to_nt_time_abs(&force_password_change, must_change_time);
2925         } else {
2926                 unix_to_nt_time(&force_password_change, must_change_time);
2927         }
2928
2929         munged_dial = pdb_get_munged_dial(pw);
2930         if (munged_dial) {
2931                 blob = base64_decode_data_blob(munged_dial);
2932         } else {
2933                 blob = data_blob_string_const_null("");
2934         }
2935
2936         status = init_samr_parameters_string(mem_ctx, &blob, &parameters);
2937         data_blob_free(&blob);
2938         if (!NT_STATUS_IS_OK(status)) {
2939                 return status;
2940         }
2941
2942         r->force_password_change        = force_password_change;
2943
2944         r->account_name.string          = talloc_strdup(mem_ctx, pdb_get_username(pw));
2945         r->full_name.string             = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2946         r->home_directory.string        = talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2947         r->home_drive.string            = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2948         r->logon_script.string          = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2949         r->profile_path.string          = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2950         r->description.string           = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2951         r->workstations.string          = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2952         r->comment.string               = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2953
2954         r->logon_hours                  = get_logon_hours_from_pdb(mem_ctx, pw);
2955         r->parameters                   = *parameters;
2956         r->rid                          = rid;
2957         r->primary_gid                  = primary_gid;
2958         r->acct_flags                   = pdb_get_acct_ctrl(pw);
2959         r->bad_password_count           = pdb_get_bad_password_count(pw);
2960         r->logon_count                  = pdb_get_logon_count(pw);
2961         r->fields_present               = pdb_build_fields_present(pw);
2962         r->password_expired             = (pdb_get_pass_must_change_time(pw) == 0) ?
2963                                                 PASS_MUST_CHANGE_AT_NEXT_LOGON : 0;
2964         r->country_code                 = 0;
2965         r->code_page                    = 0;
2966         r->lm_password_set              = 0;
2967         r->nt_password_set              = 0;
2968
2969 #if 0
2970
2971         /*
2972           Look at a user on a real NT4 PDC with usrmgr, press
2973           'ok'. Then you will see that fields_present is set to
2974           0x08f827fa. Look at the user immediately after that again,
2975           and you will see that 0x00fffff is returned. This solves
2976           the problem that you get access denied after having looked
2977           at the user.
2978           -- Volker
2979         */
2980
2981 #endif
2982
2983
2984         return NT_STATUS_OK;
2985 }
2986
2987 /*******************************************************************
2988  _samr_QueryUserInfo
2989  ********************************************************************/
2990
2991 NTSTATUS _samr_QueryUserInfo(struct pipes_struct *p,
2992                              struct samr_QueryUserInfo *r)
2993 {
2994         NTSTATUS status;
2995         union samr_UserInfo *user_info = NULL;
2996         struct samr_user_info *uinfo;
2997         struct dom_sid domain_sid;
2998         uint32 rid;
2999         bool ret = false;
3000         struct samu *pwd = NULL;
3001         uint32_t acc_required, acc_granted;
3002
3003         switch (r->in.level) {
3004         case 1: /* UserGeneralInformation */
3005                 /* USER_READ_GENERAL */
3006                 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC;
3007                 break;
3008         case 2: /* UserPreferencesInformation */
3009                 /* USER_READ_PREFERENCES | USER_READ_GENERAL */
3010                 acc_required = SAMR_USER_ACCESS_GET_LOCALE |
3011                                SAMR_USER_ACCESS_GET_NAME_ETC;
3012                 break;
3013         case 3: /* UserLogonInformation */
3014                 /* USER_READ_GENERAL | USER_READ_PREFERENCES | USER_READ_LOGON | USER_READ_ACCOUNT */
3015                 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC |
3016                                SAMR_USER_ACCESS_GET_LOCALE |
3017                                SAMR_USER_ACCESS_GET_LOGONINFO |
3018                                SAMR_USER_ACCESS_GET_ATTRIBUTES;
3019                 break;
3020         case 4: /* UserLogonHoursInformation */
3021                 /* USER_READ_LOGON */
3022                 acc_required = SAMR_USER_ACCESS_GET_LOGONINFO;
3023                 break;
3024         case 5: /* UserAccountInformation */
3025                 /* USER_READ_GENERAL | USER_READ_PREFERENCES | USER_READ_LOGON | USER_READ_ACCOUNT */
3026                 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC |
3027                                SAMR_USER_ACCESS_GET_LOCALE |
3028                                SAMR_USER_ACCESS_GET_LOGONINFO |
3029                                SAMR_USER_ACCESS_GET_ATTRIBUTES;
3030                 break;
3031         case 6: /* UserNameInformation */
3032         case 7: /* UserAccountNameInformation */
3033         case 8: /* UserFullNameInformation */
3034         case 9: /* UserPrimaryGroupInformation */
3035         case 13: /* UserAdminCommentInformation */
3036                 /* USER_READ_GENERAL */
3037                 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC;
3038                 break;
3039         case 10: /* UserHomeInformation */
3040         case 11: /* UserScriptInformation */
3041         case 12: /* UserProfileInformation */
3042         case 14: /* UserWorkStationsInformation */
3043                 /* USER_READ_LOGON */
3044                 acc_required = SAMR_USER_ACCESS_GET_LOGONINFO;
3045                 break;
3046         case 16: /* UserControlInformation */
3047         case 17: /* UserExpiresInformation */
3048         case 20: /* UserParametersInformation */
3049                 /* USER_READ_ACCOUNT */
3050                 acc_required = SAMR_USER_ACCESS_GET_ATTRIBUTES;
3051                 break;
3052         case 21: /* UserAllInformation */
3053                 /* FIXME! - gd */
3054                 acc_required = SAMR_USER_ACCESS_GET_ATTRIBUTES;
3055                 break;
3056         case 18: /* UserInternal1Information */
3057                 /* FIXME! - gd */
3058                 acc_required = SAMR_USER_ACCESS_GET_ATTRIBUTES;
3059                 break;
3060         case 23: /* UserInternal4Information */
3061         case 24: /* UserInternal4InformationNew */
3062         case 25: /* UserInternal4InformationNew */
3063         case 26: /* UserInternal5InformationNew */
3064         default:
3065                 return NT_STATUS_INVALID_INFO_CLASS;
3066                 break;
3067         }
3068
3069         uinfo = policy_handle_find(p, r->in.user_handle,
3070                                    acc_required, &acc_granted,
3071                                    struct samr_user_info, &status);
3072         if (!NT_STATUS_IS_OK(status)) {
3073                 return status;
3074         }
3075
3076         domain_sid = uinfo->sid;
3077
3078         sid_split_rid(&domain_sid, &rid);
3079
3080         if (!sid_check_is_in_our_domain(&uinfo->sid))
3081                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
3082
3083         DEBUG(5,("_samr_QueryUserInfo: sid:%s\n",
3084                  sid_string_dbg(&uinfo->sid)));
3085
3086         user_info = TALLOC_ZERO_P(p->mem_ctx, union samr_UserInfo);
3087         if (!user_info) {
3088                 return NT_STATUS_NO_MEMORY;
3089         }
3090
3091         DEBUG(5,("_samr_QueryUserInfo: user info level: %d\n", r->in.level));
3092
3093         if (!(pwd = samu_new(p->mem_ctx))) {
3094                 return NT_STATUS_NO_MEMORY;
3095         }
3096
3097         become_root();
3098         ret = pdb_getsampwsid(pwd, &uinfo->sid);
3099         unbecome_root();
3100
3101         if (ret == false) {
3102                 DEBUG(4,("User %s not found\n", sid_string_dbg(&uinfo->sid)));
3103                 TALLOC_FREE(pwd);
3104                 return NT_STATUS_NO_SUCH_USER;
3105         }
3106
3107         DEBUG(3,("User:[%s]\n", pdb_get_username(pwd)));
3108
3109         samr_clear_sam_passwd(pwd);
3110
3111         switch (r->in.level) {
3112         case 1:
3113                 status = get_user_info_1(p->mem_ctx, &user_info->info1, pwd, &domain_sid);
3114                 break;
3115         case 2:
3116                 status = get_user_info_2(p->mem_ctx, &user_info->info2, pwd);
3117                 break;
3118         case 3:
3119                 status = get_user_info_3(p->mem_ctx, &user_info->info3, pwd, &domain_sid);
3120                 break;
3121         case 4:
3122                 status = get_user_info_4(p->mem_ctx, &user_info->info4, pwd);
3123                 break;
3124         case 5:
3125                 status = get_user_info_5(p->mem_ctx, &user_info->info5, pwd, &domain_sid);
3126                 break;
3127         case 6:
3128                 status = get_user_info_6(p->mem_ctx, &user_info->info6, pwd);
3129                 break;
3130         case 7:
3131                 status = get_user_info_7(p->mem_ctx, &user_info->info7, pwd);
3132                 break;
3133         case 8:
3134                 status = get_user_info_8(p->mem_ctx, &user_info->info8, pwd);
3135                 break;
3136         case 9:
3137                 status = get_user_info_9(p->mem_ctx, &user_info->info9, pwd);
3138                 break;
3139         case 10:
3140                 status = get_user_info_10(p->mem_ctx, &user_info->info10, pwd);
3141                 break;
3142         case 11:
3143                 status = get_user_info_11(p->mem_ctx, &user_info->info11, pwd);
3144                 break;
3145         case 12:
3146                 status = get_user_info_12(p->mem_ctx, &user_info->info12, pwd);
3147                 break;
3148         case 13:
3149                 status = get_user_info_13(p->mem_ctx, &user_info->info13, pwd);
3150                 break;
3151         case 14:
3152                 status = get_user_info_14(p->mem_ctx, &user_info->info14, pwd);
3153                 break;
3154         case 16:
3155                 status = get_user_info_16(p->mem_ctx, &user_info->info16, pwd);
3156                 break;
3157         case 17:
3158                 status = get_user_info_17(p->mem_ctx, &user_info->info17, pwd);
3159                 break;
3160         case 18:
3161                 /* level 18 is special */
3162                 status = get_user_info_18(p, p->mem_ctx, &user_info->info18,
3163                                           &uinfo->sid);
3164                 break;
3165         case 20:
3166                 status = get_user_info_20(p->mem_ctx, &user_info->info20, pwd);
3167                 break;
3168         case 21:
3169                 status = get_user_info_21(p->mem_ctx, &user_info->info21, pwd, &domain_sid, acc_granted);
3170                 break;
3171         default:
3172                 status = NT_STATUS_INVALID_INFO_CLASS;
3173                 break;
3174         }
3175
3176         if (!NT_STATUS_IS_OK(status)) {
3177                 goto done;
3178         }
3179
3180         *r->out.info = user_info;
3181
3182  done:
3183         TALLOC_FREE(pwd);
3184
3185         DEBUG(5,("_samr_QueryUserInfo: %d\n", __LINE__));
3186
3187         return status;
3188 }
3189
3190 /****************************************************************
3191 ****************************************************************/
3192
3193 NTSTATUS _samr_QueryUserInfo2(struct pipes_struct *p,
3194                               struct samr_QueryUserInfo2 *r)
3195 {
3196         struct samr_QueryUserInfo u;
3197
3198         u.in.user_handle        = r->in.user_handle;
3199         u.in.level              = r->in.level;
3200         u.out.info              = r->out.info;
3201
3202         return _samr_QueryUserInfo(p, &u);
3203 }
3204
3205 /*******************************************************************
3206  _samr_GetGroupsForUser
3207  ********************************************************************/
3208
3209 NTSTATUS _samr_GetGroupsForUser(struct pipes_struct *p,
3210                                 struct samr_GetGroupsForUser *r)
3211 {
3212         struct samr_user_info *uinfo;
3213         struct samu *sam_pass=NULL;
3214         struct dom_sid *sids;
3215         struct samr_RidWithAttribute dom_gid;
3216         struct samr_RidWithAttribute *gids = NULL;
3217         uint32 primary_group_rid;
3218         size_t num_groups = 0;
3219         gid_t *unix_gids;
3220         size_t i, num_gids;
3221         bool ret;
3222         NTSTATUS result;
3223         bool success = False;
3224
3225         struct samr_RidWithAttributeArray *rids = NULL;
3226
3227         /*
3228          * from the SID in the request:
3229          * we should send back the list of DOMAIN GROUPS
3230          * the user is a member of
3231          *
3232          * and only the DOMAIN GROUPS
3233          * no ALIASES !!! neither aliases of the domain
3234          * nor aliases of the builtin SID
3235          *
3236          * JFM, 12/2/2001
3237          */
3238
3239         DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
3240
3241         uinfo = policy_handle_find(p, r->in.user_handle,
3242                                    SAMR_USER_ACCESS_GET_GROUPS, NULL,
3243                                    struct samr_user_info, &result);
3244         if (!NT_STATUS_IS_OK(result)) {
3245                 return result;
3246         }
3247
3248         rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidWithAttributeArray);
3249         if (!rids) {
3250                 return NT_STATUS_NO_MEMORY;
3251         }
3252
3253         if (!sid_check_is_in_our_domain(&uinfo->sid))
3254                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
3255
3256         if ( !(sam_pass = samu_new( p->mem_ctx )) ) {
3257                 return NT_STATUS_NO_MEMORY;
3258         }
3259
3260         become_root();
3261         ret = pdb_getsampwsid(sam_pass, &uinfo->sid);
3262         unbecome_root();
3263
3264         if (!ret) {
3265                 DEBUG(10, ("pdb_getsampwsid failed for %s\n",
3266                            sid_string_dbg(&uinfo->sid)));
3267                 return NT_STATUS_NO_SUCH_USER;
3268         }
3269
3270         sids = NULL;
3271
3272         /* make both calls inside the root block */
3273         become_root();
3274         result = pdb_enum_group_memberships(p->mem_ctx, sam_pass,
3275                                             &sids, &unix_gids, &num_groups);
3276         if ( NT_STATUS_IS_OK(result) ) {
3277                 success = sid_peek_check_rid(get_global_sam_sid(),
3278                                              pdb_get_group_sid(sam_pass),
3279                                              &primary_group_rid);
3280         }
3281         unbecome_root();
3282
3283         if (!NT_STATUS_IS_OK(result)) {
3284                 DEBUG(10, ("pdb_enum_group_memberships failed for %s\n",
3285                            sid_string_dbg(&uinfo->sid)));
3286                 return result;
3287         }
3288
3289         if ( !success ) {
3290                 DEBUG(5, ("Group sid %s for user %s not in our domain\n",
3291                           sid_string_dbg(pdb_get_group_sid(sam_pass)),
3292                           pdb_get_username(sam_pass)));
3293                 TALLOC_FREE(sam_pass);
3294                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
3295         }
3296
3297         gids = NULL;
3298         num_gids = 0;
3299
3300         dom_gid.attributes = (SE_GROUP_MANDATORY|SE_GROUP_ENABLED_BY_DEFAULT|
3301                               SE_GROUP_ENABLED);
3302         dom_gid.rid = primary_group_rid;
3303         ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
3304
3305         for (i=0; i<num_groups; i++) {
3306
3307                 if (!sid_peek_check_rid(get_global_sam_sid(),
3308                                         &(sids[i]), &dom_gid.rid)) {
3309                         DEBUG(10, ("Found sid %s not in our domain\n",
3310                                    sid_string_dbg(&sids[i])));
3311                         continue;
3312                 }
3313
3314                 if (dom_gid.rid == primary_group_rid) {
3315                         /* We added the primary group directly from the
3316                          * sam_account. The other SIDs are unique from
3317                          * enum_group_memberships */
3318                         continue;
3319                 }
3320
3321                 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
3322         }
3323
3324         rids->count = num_gids;
3325         rids->rids = gids;
3326
3327         *r->out.rids = rids;
3328
3329         DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
3330
3331         return result;
3332 }
3333
3334 /*******************************************************************
3335  ********************************************************************/
3336
3337 static uint32_t samr_get_server_role(void)
3338 {
3339         uint32_t role = ROLE_DOMAIN_PDC;
3340