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