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