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