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