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