5f93d4287adb3e16ce8257c66ad04cfb5a73083d
[samba.git] / source3 / rpc_server / samr / srv_samr_nt.c
1 /*
2  *  Unix SMB/CIFS implementation.
3  *  RPC Pipe client / server routines
4  *  Copyright (C) Andrew Tridgell                   1992-1997,
5  *  Copyright (C) Luke Kenneth Casson Leighton      1996-1997,
6  *  Copyright (C) Paul Ashton                       1997,
7  *  Copyright (C) Marc Jacobsen                     1999,
8  *  Copyright (C) Jeremy Allison                    2001-2008,
9  *  Copyright (C) Jean Fran├žois Micouleau           1998-2001,
10  *  Copyright (C) Jim McDonough <jmcd@us.ibm.com>   2002,
11  *  Copyright (C) Gerald (Jerry) Carter             2003-2004,
12  *  Copyright (C) Simo Sorce                        2003.
13  *  Copyright (C) Volker Lendecke                   2005.
14  *  Copyright (C) Guenther Deschner                 2008.
15  *
16  *  This program is free software; you can redistribute it and/or modify
17  *  it under the terms of the GNU General Public License as published by
18  *  the Free Software Foundation; either version 3 of the License, or
19  *  (at your option) any later version.
20  *
21  *  This program is distributed in the hope that it will be useful,
22  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
23  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24  *  GNU General Public License for more details.
25  *
26  *  You should have received a copy of the GNU General Public License
27  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
28  */
29
30 /*
31  * This is the implementation of the SAMR code.
32  */
33
34 #include "includes.h"
35 #include "system/passwd.h"
36 #include "../libcli/auth/libcli_auth.h"
37 #include "ntdomain.h"
38 #include "librpc/rpc/dcesrv_core.h"
39 #include "../librpc/gen_ndr/ndr_samr.h"
40 #include "../librpc/gen_ndr/ndr_samr_scompat.h"
41 #include "rpc_server/samr/srv_samr_util.h"
42 #include "secrets.h"
43 #include "rpc_client/init_lsa.h"
44 #include "../libcli/security/security.h"
45 #include "passdb.h"
46 #include "auth.h"
47 #include "rpc_server/srv_access_check.h"
48 #include "../lib/tsocket/tsocket.h"
49 #include "lib/util/base64.h"
50 #include "param/param.h"
51 #include "librpc/rpc/dcerpc_helper.h"
52 #include "librpc/rpc/dcerpc_samr.h"
53
54 #include "lib/crypto/gnutls_helpers.h"
55 #include <gnutls/gnutls.h>
56 #include <gnutls/crypto.h>
57 #include "lib/global_contexts.h"
58 #include "nsswitch/winbind_client.h"
59
60 #undef DBGC_CLASS
61 #define DBGC_CLASS DBGC_RPC_SRV
62
63 #define SAMR_USR_RIGHTS_WRITE_PW \
64                 ( READ_CONTROL_ACCESS           | \
65                   SAMR_USER_ACCESS_CHANGE_PASSWORD      | \
66                   SAMR_USER_ACCESS_SET_LOC_COM)
67 #define SAMR_USR_RIGHTS_CANT_WRITE_PW \
68                 ( READ_CONTROL_ACCESS | SAMR_USER_ACCESS_SET_LOC_COM )
69
70 #define DISP_INFO_CACHE_TIMEOUT 10
71
72 #define MAX_SAM_ENTRIES_W2K 0x400 /* 1024 */
73 #define MAX_SAM_ENTRIES_W95 50
74
75 enum samr_handle {
76         SAMR_HANDLE_CONNECT,
77         SAMR_HANDLE_DOMAIN,
78         SAMR_HANDLE_USER,
79         SAMR_HANDLE_GROUP,
80         SAMR_HANDLE_ALIAS
81 };
82
83 struct samr_info {
84         uint32_t access_granted;
85         struct dom_sid sid;
86         struct disp_info *disp_info;
87 };
88
89 typedef struct disp_info {
90         struct dom_sid sid; /* identify which domain this is. */
91         struct pdb_search *users; /* querydispinfo 1 and 4 */
92         struct pdb_search *machines; /* querydispinfo 2 */
93         struct pdb_search *groups; /* querydispinfo 3 and 5, enumgroups */
94         struct pdb_search *aliases; /* enumaliases */
95
96         uint32_t enum_acb_mask;
97         struct pdb_search *enum_users; /* enumusers with a mask */
98
99         struct tevent_timer *cache_timeout_event; /* cache idle timeout
100                                                   * handler. */
101 } DISP_INFO;
102
103 static const struct generic_mapping sam_generic_mapping = {
104         GENERIC_RIGHTS_SAM_READ,
105         GENERIC_RIGHTS_SAM_WRITE,
106         GENERIC_RIGHTS_SAM_EXECUTE,
107         GENERIC_RIGHTS_SAM_ALL_ACCESS};
108 static const struct generic_mapping dom_generic_mapping = {
109         GENERIC_RIGHTS_DOMAIN_READ,
110         GENERIC_RIGHTS_DOMAIN_WRITE,
111         GENERIC_RIGHTS_DOMAIN_EXECUTE,
112         GENERIC_RIGHTS_DOMAIN_ALL_ACCESS};
113 static const struct generic_mapping usr_generic_mapping = {
114         GENERIC_RIGHTS_USER_READ,
115         GENERIC_RIGHTS_USER_WRITE,
116         GENERIC_RIGHTS_USER_EXECUTE,
117         GENERIC_RIGHTS_USER_ALL_ACCESS};
118 static const struct generic_mapping usr_nopwchange_generic_mapping = {
119         GENERIC_RIGHTS_USER_READ,
120         GENERIC_RIGHTS_USER_WRITE,
121         GENERIC_RIGHTS_USER_EXECUTE & ~SAMR_USER_ACCESS_CHANGE_PASSWORD,
122         GENERIC_RIGHTS_USER_ALL_ACCESS};
123 static const struct generic_mapping grp_generic_mapping = {
124         GENERIC_RIGHTS_GROUP_READ,
125         GENERIC_RIGHTS_GROUP_WRITE,
126         GENERIC_RIGHTS_GROUP_EXECUTE,
127         GENERIC_RIGHTS_GROUP_ALL_ACCESS};
128 static const struct generic_mapping ali_generic_mapping = {
129         GENERIC_RIGHTS_ALIAS_READ,
130         GENERIC_RIGHTS_ALIAS_WRITE,
131         GENERIC_RIGHTS_ALIAS_EXECUTE,
132         GENERIC_RIGHTS_ALIAS_ALL_ACCESS};
133
134 /*******************************************************************
135 *******************************************************************/
136 static NTSTATUS create_samr_policy_handle(TALLOC_CTX *mem_ctx,
137                                           struct pipes_struct *p,
138                                           enum samr_handle type,
139                                           uint32_t acc_granted,
140                                           struct dom_sid *sid,
141                                           struct disp_info *disp_info,
142                                           struct policy_handle *handle)
143 {
144         struct samr_info *info = NULL;
145         bool ok;
146
147         ZERO_STRUCTP(handle);
148
149         info = talloc_zero(mem_ctx, struct samr_info);
150         if (info == NULL) {
151                 return NT_STATUS_NO_MEMORY;
152         }
153
154         info->access_granted = acc_granted;
155
156         if (sid != NULL) {
157                 sid_copy(&info->sid, sid);
158         }
159
160         if (disp_info != NULL) {
161                 info->disp_info = disp_info;
162         }
163
164         ok = create_policy_hnd(p, handle, type, info);
165         if (!ok) {
166                 talloc_free(info);
167                 ZERO_STRUCTP(handle);
168                 return NT_STATUS_NO_MEMORY;
169         }
170
171         return NT_STATUS_OK;
172 }
173
174 static NTSTATUS samr_handle_access_check(uint32_t access_granted,
175                                          uint32_t access_required,
176                                          uint32_t *paccess_granted)
177 {
178         if ((access_required & access_granted) != access_required) {
179                 if (root_mode()) {
180                         DBG_INFO("ACCESS should be DENIED (granted: "
181                                  "%#010x; required: %#010x) but overwritten "
182                                  "by euid == 0\n", access_granted,
183                                  access_required);
184                         goto okay;
185                 }
186                 DBG_NOTICE("ACCESS DENIED (granted: %#010x; required: "
187                            "%#010x)\n", access_granted, access_required);
188                 return NT_STATUS_ACCESS_DENIED;
189         }
190
191 okay:
192         if (paccess_granted != NULL) {
193                 *paccess_granted = access_granted;
194         }
195         return NT_STATUS_OK;
196 }
197
198 static void *samr_policy_handle_find(struct pipes_struct *p,
199                                      const struct policy_handle *handle,
200                                      uint8_t handle_type,
201                                      uint32_t access_required,
202                                      uint32_t *access_granted,
203                                      NTSTATUS *pstatus)
204 {
205         struct samr_info *info = NULL;
206         NTSTATUS status;
207
208         info = find_policy_by_hnd(p,
209                                   handle,
210                                   handle_type,
211                                   struct samr_info,
212                                   &status);
213         if (!NT_STATUS_IS_OK(status)) {
214                 *pstatus = NT_STATUS_INVALID_HANDLE;
215                 return NULL;
216         }
217
218         status = samr_handle_access_check(info->access_granted,
219                                           access_required,
220                                           access_granted);
221         if (!NT_STATUS_IS_OK(status)) {
222                 *pstatus = status;
223                 return NULL;
224         }
225
226         *pstatus = NT_STATUS_OK;
227         return info;
228 }
229
230 static NTSTATUS make_samr_object_sd( TALLOC_CTX *ctx, struct security_descriptor **psd, size_t *sd_size,
231                                      const struct generic_mapping *map,
232                                      struct dom_sid *sid, uint32_t sid_access )
233 {
234         struct dom_sid domadmin_sid;
235         struct security_ace ace[5];             /* at most 5 entries */
236         size_t i = 0;
237
238         struct security_acl *psa = NULL;
239
240         /* basic access for Everyone */
241
242         init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
243                         map->generic_execute | map->generic_read, 0);
244
245         /* add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
246
247         init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
248                         SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
249         init_sec_ace(&ace[i++], &global_sid_Builtin_Account_Operators,
250                         SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
251
252         /* Add Full Access for Domain Admins if we are a DC */
253
254         if ( IS_DC ) {
255                 sid_compose(&domadmin_sid, get_global_sam_sid(),
256                             DOMAIN_RID_ADMINS);
257                 init_sec_ace(&ace[i++], &domadmin_sid,
258                         SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
259         }
260
261         /* if we have a sid, give it some special access */
262
263         if ( sid ) {
264                 init_sec_ace(&ace[i++], sid, SEC_ACE_TYPE_ACCESS_ALLOWED, sid_access, 0);
265         }
266
267         /* create the security descriptor */
268
269         if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) == NULL)
270                 return NT_STATUS_NO_MEMORY;
271
272         if ((*psd = make_sec_desc(ctx, SECURITY_DESCRIPTOR_REVISION_1,
273                                   SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL,
274                                   psa, sd_size)) == NULL)
275                 return NT_STATUS_NO_MEMORY;
276
277         return NT_STATUS_OK;
278 }
279
280 /*******************************************************************
281  Fetch or create a dispinfo struct.
282 ********************************************************************/
283
284 static DISP_INFO *get_samr_dispinfo_by_sid(const struct dom_sid *psid)
285 {
286         /*
287          * We do a static cache for DISP_INFO's here. Explanation can be found
288          * in Jeremy's checkin message to r11793:
289          *
290          * Fix the SAMR cache so it works across completely insane
291          * client behaviour (ie.:
292          * open pipe/open SAMR handle/enumerate 0 - 1024
293          * close SAMR handle, close pipe.
294          * open pipe/open SAMR handle/enumerate 1024 - 2048...
295          * close SAMR handle, close pipe.
296          * And on ad-nausium. Amazing.... probably object-oriented
297          * client side programming in action yet again.
298          * This change should *massively* improve performance when
299          * enumerating users from an LDAP database.
300          * Jeremy.
301          *
302          * "Our" and the builtin domain are the only ones where we ever
303          * enumerate stuff, so just cache 2 entries.
304          */
305
306         static struct disp_info *builtin_dispinfo;
307         static struct disp_info *domain_dispinfo;
308
309         /* There are two cases to consider here:
310            1) The SID is a domain SID and we look for an equality match, or
311            2) This is an account SID and so we return the DISP_INFO* for our
312               domain */
313
314         if (psid == NULL) {
315                 return NULL;
316         }
317
318         if (sid_check_is_builtin(psid) || sid_check_is_in_builtin(psid)) {
319                 /*
320                  * Necessary only once, but it does not really hurt.
321                  */
322                 if (builtin_dispinfo == NULL) {
323                         builtin_dispinfo = talloc_zero(NULL, struct disp_info);
324                         if (builtin_dispinfo == NULL) {
325                                 return NULL;
326                         }
327                 }
328                 sid_copy(&builtin_dispinfo->sid, &global_sid_Builtin);
329
330                 return builtin_dispinfo;
331         }
332
333         if (sid_check_is_our_sam(psid) || sid_check_is_in_our_sam(psid)) {
334                 /*
335                  * Necessary only once, but it does not really hurt.
336                  */
337                 if (domain_dispinfo == NULL) {
338                         domain_dispinfo = talloc_zero(NULL, struct disp_info);
339                         if (domain_dispinfo == NULL) {
340                                 return NULL;
341                         }
342                 }
343                 sid_copy(&domain_dispinfo->sid, get_global_sam_sid());
344
345                 return domain_dispinfo;
346         }
347
348         return NULL;
349 }
350
351 /*******************************************************************
352  Function to free the per SID data.
353  ********************************************************************/
354
355 static void free_samr_cache(DISP_INFO *disp_info)
356 {
357         struct dom_sid_buf buf;
358
359         DEBUG(10, ("free_samr_cache: deleting cache for SID %s\n",
360                    dom_sid_str_buf(&disp_info->sid, &buf)));
361
362         /* We need to become root here because the paged search might have to
363          * tell the LDAP server we're not interested in the rest anymore. */
364
365         become_root();
366
367         TALLOC_FREE(disp_info->users);
368         TALLOC_FREE(disp_info->machines);
369         TALLOC_FREE(disp_info->groups);
370         TALLOC_FREE(disp_info->aliases);
371         TALLOC_FREE(disp_info->enum_users);
372
373         unbecome_root();
374 }
375
376 /*******************************************************************
377  Idle event handler. Throw away the disp info cache.
378  ********************************************************************/
379
380 static void disp_info_cache_idle_timeout_handler(struct tevent_context *ev_ctx,
381                                                  struct tevent_timer *te,
382                                                  struct timeval now,
383                                                  void *private_data)
384 {
385         DISP_INFO *disp_info = (DISP_INFO *)private_data;
386
387         TALLOC_FREE(disp_info->cache_timeout_event);
388
389         DEBUG(10, ("disp_info_cache_idle_timeout_handler: caching timed "
390                    "out\n"));
391         free_samr_cache(disp_info);
392 }
393
394 /*******************************************************************
395  Setup cache removal idle event handler.
396  ********************************************************************/
397
398 static void set_disp_info_cache_timeout(DISP_INFO *disp_info, time_t secs_fromnow)
399 {
400         struct dom_sid_buf buf;
401
402         /* Remove any pending timeout and update. */
403
404         TALLOC_FREE(disp_info->cache_timeout_event);
405
406         DEBUG(10,("set_disp_info_cache_timeout: caching enumeration for "
407                   "SID %s for %u seconds\n",
408                   dom_sid_str_buf(&disp_info->sid, &buf),
409                   (unsigned int)secs_fromnow ));
410
411         disp_info->cache_timeout_event = tevent_add_timer(
412                 global_event_context(), NULL,
413                 timeval_current_ofs(secs_fromnow, 0),
414                 disp_info_cache_idle_timeout_handler, (void *)disp_info);
415 }
416
417 /*******************************************************************
418  Force flush any cache. We do this on any samr_set_xxx call.
419  We must also remove the timeout handler.
420  ********************************************************************/
421
422 static void force_flush_samr_cache(const struct dom_sid *sid)
423 {
424         struct disp_info *disp_info = get_samr_dispinfo_by_sid(sid);
425
426         if ((disp_info == NULL) || (disp_info->cache_timeout_event == NULL)) {
427                 return;
428         }
429
430         DEBUG(10,("force_flush_samr_cache: clearing idle event\n"));
431         TALLOC_FREE(disp_info->cache_timeout_event);
432         free_samr_cache(disp_info);
433 }
434
435 /*******************************************************************
436  Ensure password info is never given out. Paranioa... JRA.
437  ********************************************************************/
438
439 static void samr_clear_sam_passwd(struct samu *sam_pass)
440 {
441
442         if (!sam_pass)
443                 return;
444
445         /* These now zero out the old password */
446
447         pdb_set_lanman_passwd(sam_pass, NULL, PDB_DEFAULT);
448         pdb_set_nt_passwd(sam_pass, NULL, PDB_DEFAULT);
449 }
450
451 static uint32_t count_sam_users(struct disp_info *info, uint32_t acct_flags)
452 {
453         struct samr_displayentry *entry;
454
455         if (sid_check_is_builtin(&info->sid)) {
456                 /* No users in builtin. */
457                 return 0;
458         }
459
460         if (info->users == NULL) {
461                 info->users = pdb_search_users(info, acct_flags);
462                 if (info->users == NULL) {
463                         return 0;
464                 }
465         }
466         /* Fetch the last possible entry, thus trigger an enumeration */
467         pdb_search_entries(info->users, 0xffffffff, 1, &entry);
468
469         /* Ensure we cache this enumeration. */
470         set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
471
472         return info->users->num_entries;
473 }
474
475 static uint32_t count_sam_groups(struct disp_info *info)
476 {
477         struct samr_displayentry *entry;
478
479         if (sid_check_is_builtin(&info->sid)) {
480                 /* No groups in builtin. */
481                 return 0;
482         }
483
484         if (info->groups == NULL) {
485                 info->groups = pdb_search_groups(info);
486                 if (info->groups == NULL) {
487                         return 0;
488                 }
489         }
490         /* Fetch the last possible entry, thus trigger an enumeration */
491         pdb_search_entries(info->groups, 0xffffffff, 1, &entry);
492
493         /* Ensure we cache this enumeration. */
494         set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
495
496         return info->groups->num_entries;
497 }
498
499 static uint32_t count_sam_aliases(struct disp_info *info)
500 {
501         struct samr_displayentry *entry;
502
503         if (info->aliases == NULL) {
504                 info->aliases = pdb_search_aliases(info, &info->sid);
505                 if (info->aliases == NULL) {
506                         return 0;
507                 }
508         }
509         /* Fetch the last possible entry, thus trigger an enumeration */
510         pdb_search_entries(info->aliases, 0xffffffff, 1, &entry);
511
512         /* Ensure we cache this enumeration. */
513         set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
514
515         return info->aliases->num_entries;
516 }
517
518 /*******************************************************************
519  _samr_Close
520  ********************************************************************/
521
522 NTSTATUS _samr_Close(struct pipes_struct *p, struct samr_Close *r)
523 {
524         if (!close_policy_hnd(p, r->in.handle)) {
525                 return NT_STATUS_INVALID_HANDLE;
526         }
527
528         ZERO_STRUCTP(r->out.handle);
529
530         return NT_STATUS_OK;
531 }
532
533 /*******************************************************************
534  _samr_OpenDomain
535  ********************************************************************/
536
537 NTSTATUS _samr_OpenDomain(struct pipes_struct *p,
538                           struct samr_OpenDomain *r)
539 {
540         struct dcesrv_call_state *dce_call = p->dce_call;
541         struct auth_session_info *session_info =
542                 dcesrv_call_session_info(dce_call);
543         struct security_descriptor *psd = NULL;
544         uint32_t    acc_granted;
545         uint32_t    des_access = r->in.access_mask;
546         NTSTATUS  status;
547         size_t    sd_size;
548         uint32_t extra_access = SAMR_DOMAIN_ACCESS_CREATE_USER;
549         struct disp_info *disp_info = NULL;
550
551         /* find the connection policy handle. */
552         (void)samr_policy_handle_find(p,
553                                       r->in.connect_handle,
554                                       SAMR_HANDLE_CONNECT,
555                                       0,
556                                       NULL,
557                                       &status);
558         if (!NT_STATUS_IS_OK(status)) {
559                 return status;
560         }
561
562         /*check if access can be granted as requested by client. */
563         map_max_allowed_access(session_info->security_token,
564                                session_info->unix_token,
565                                &des_access);
566
567         make_samr_object_sd( p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0 );
568         se_map_generic( &des_access, &dom_generic_mapping );
569
570         /*
571          * Users with SeAddUser get the ability to manipulate groups
572          * and aliases.
573          */
574         if (security_token_has_privilege(
575                     session_info->security_token, SEC_PRIV_ADD_USERS)) {
576                 extra_access |= (SAMR_DOMAIN_ACCESS_CREATE_GROUP |
577                                 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS |
578                                 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
579                                 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS |
580                                 SAMR_DOMAIN_ACCESS_CREATE_ALIAS);
581         }
582
583         /*
584          * Users with SeMachineAccount or SeAddUser get additional
585          * SAMR_DOMAIN_ACCESS_CREATE_USER access.
586          */
587
588         status = access_check_object( psd, session_info->security_token,
589                                       SEC_PRIV_MACHINE_ACCOUNT, SEC_PRIV_ADD_USERS,
590                                       extra_access, des_access,
591                                       &acc_granted, "_samr_OpenDomain" );
592
593         if ( !NT_STATUS_IS_OK(status) )
594                 return status;
595
596         if (!sid_check_is_our_sam(r->in.sid) &&
597             !sid_check_is_builtin(r->in.sid)) {
598                 return NT_STATUS_NO_SUCH_DOMAIN;
599         }
600
601         disp_info = get_samr_dispinfo_by_sid(r->in.sid);
602
603         status = create_samr_policy_handle(p->mem_ctx,
604                                            p,
605                                            SAMR_HANDLE_DOMAIN,
606                                            acc_granted,
607                                            r->in.sid,
608                                            disp_info,
609                                            r->out.domain_handle);
610         if (!NT_STATUS_IS_OK(status)) {
611                 return status;
612         }
613
614         DEBUG(5,("_samr_OpenDomain: %d\n", __LINE__));
615
616         return NT_STATUS_OK;
617 }
618
619 /*******************************************************************
620  _samr_GetUserPwInfo
621  ********************************************************************/
622
623 NTSTATUS _samr_GetUserPwInfo(struct pipes_struct *p,
624                              struct samr_GetUserPwInfo *r)
625 {
626         const struct loadparm_substitution *lp_sub =
627                 loadparm_s3_global_substitution();
628         struct samr_info *uinfo;
629         enum lsa_SidType sid_type;
630         uint32_t min_password_length = 0;
631         uint32_t password_properties = 0;
632         bool ret = false;
633         NTSTATUS status;
634
635         DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__));
636
637         uinfo = samr_policy_handle_find(p, r->in.user_handle,
638                                         SAMR_HANDLE_USER,
639                                         SAMR_USER_ACCESS_GET_ATTRIBUTES,
640                                         NULL,
641                                         &status);
642         if (!NT_STATUS_IS_OK(status)) {
643                 return status;
644         }
645
646         if (!sid_check_is_in_our_sam(&uinfo->sid)) {
647                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
648         }
649
650         become_root();
651         ret = lookup_sid(p->mem_ctx, &uinfo->sid, NULL, NULL, &sid_type);
652         unbecome_root();
653         if (ret == false) {
654                 return NT_STATUS_NO_SUCH_USER;
655         }
656
657         switch (sid_type) {
658                 case SID_NAME_USER:
659                         become_root();
660                         pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN,
661                                                &min_password_length);
662                         pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
663                                                &password_properties);
664                         unbecome_root();
665
666                         if (lp_check_password_script(talloc_tos(), lp_sub)
667                             && *lp_check_password_script(talloc_tos(), lp_sub)) {
668                                 password_properties |= DOMAIN_PASSWORD_COMPLEX;
669                         }
670
671                         break;
672                 default:
673                         break;
674         }
675
676         r->out.info->min_password_length = min_password_length;
677         r->out.info->password_properties = password_properties;
678
679         DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__));
680
681         return NT_STATUS_OK;
682 }
683
684 /*******************************************************************
685  _samr_SetSecurity
686  ********************************************************************/
687
688 NTSTATUS _samr_SetSecurity(struct pipes_struct *p,
689                            struct samr_SetSecurity *r)
690 {
691         struct samr_info *uinfo;
692         uint32_t i;
693         struct security_acl *dacl;
694         bool ret;
695         struct samu *sampass=NULL;
696         NTSTATUS status;
697
698         uinfo = samr_policy_handle_find(p,
699                                         r->in.handle,
700                                         SAMR_HANDLE_USER,
701                                         SAMR_USER_ACCESS_SET_ATTRIBUTES,
702                                         NULL,
703                                         &status);
704         if (!NT_STATUS_IS_OK(status)) {
705                 return status;
706         }
707
708         if (!(sampass = samu_new( p->mem_ctx))) {
709                 DEBUG(0,("No memory!\n"));
710                 return NT_STATUS_NO_MEMORY;
711         }
712
713         /* get the user record */
714         become_root();
715         ret = pdb_getsampwsid(sampass, &uinfo->sid);
716         unbecome_root();
717
718         if (!ret) {
719                 struct dom_sid_buf buf;
720                 DEBUG(4, ("User %s not found\n",
721                           dom_sid_str_buf(&uinfo->sid, &buf)));
722                 TALLOC_FREE(sampass);
723                 return NT_STATUS_INVALID_HANDLE;
724         }
725
726         dacl = r->in.sdbuf->sd->dacl;
727         for (i=0; i < dacl->num_aces; i++) {
728                 if (dom_sid_equal(&uinfo->sid, &dacl->aces[i].trustee)) {
729                         ret = pdb_set_pass_can_change(sampass,
730                                 (dacl->aces[i].access_mask &
731                                  SAMR_USER_ACCESS_CHANGE_PASSWORD) ?
732                                                       True: False);
733                         break;
734                 }
735         }
736
737         if (!ret) {
738                 TALLOC_FREE(sampass);
739                 return NT_STATUS_ACCESS_DENIED;
740         }
741
742         become_root();
743         status = pdb_update_sam_account(sampass);
744         unbecome_root();
745
746         TALLOC_FREE(sampass);
747
748         return status;
749 }
750
751 /*******************************************************************
752   build correct perms based on policies and password times for _samr_query_sec_obj
753 *******************************************************************/
754 static bool check_change_pw_access(TALLOC_CTX *mem_ctx, struct dom_sid *user_sid)
755 {
756         struct samu *sampass=NULL;
757         bool ret;
758
759         if ( !(sampass = samu_new( mem_ctx )) ) {
760                 DEBUG(0,("No memory!\n"));
761                 return False;
762         }
763
764         become_root();
765         ret = pdb_getsampwsid(sampass, user_sid);
766         unbecome_root();
767
768         if (ret == False) {
769                 struct dom_sid_buf buf;
770                 DEBUG(4,("User %s not found\n",
771                          dom_sid_str_buf(user_sid, &buf)));
772                 TALLOC_FREE(sampass);
773                 return False;
774         }
775
776         DEBUG(3,("User:[%s]\n",  pdb_get_username(sampass) ));
777
778         if (pdb_get_pass_can_change(sampass)) {
779                 TALLOC_FREE(sampass);
780                 return True;
781         }
782         TALLOC_FREE(sampass);
783         return False;
784 }
785
786
787 /*******************************************************************
788  _samr_QuerySecurity
789  ********************************************************************/
790
791 NTSTATUS _samr_QuerySecurity(struct pipes_struct *p,
792                              struct samr_QuerySecurity *r)
793 {
794         struct samr_info *info;
795         NTSTATUS status;
796         struct security_descriptor * psd = NULL;
797         size_t sd_size = 0;
798         struct dom_sid_buf buf;
799
800         info = samr_policy_handle_find(p,
801                                        r->in.handle,
802                                        SAMR_HANDLE_CONNECT,
803                                        SEC_STD_READ_CONTROL,
804                                        NULL,
805                                        &status);
806         if (NT_STATUS_IS_OK(status)) {
807                 DEBUG(5,("_samr_QuerySecurity: querying security on SAM\n"));
808                 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size,
809                                              &sam_generic_mapping, NULL, 0);
810                 goto done;
811         }
812
813         info = samr_policy_handle_find(p,
814                                        r->in.handle,
815                                        SAMR_HANDLE_DOMAIN,
816                                        SEC_STD_READ_CONTROL,
817                                        NULL,
818                                        &status);
819         if (NT_STATUS_IS_OK(status)) {
820                 DEBUG(5,("_samr_QuerySecurity: querying security on Domain "
821                          "with SID: %s\n",
822                          dom_sid_str_buf(&info->sid, &buf)));
823                 /*
824                  * TODO: Builtin probably needs a different SD with restricted
825                  * write access
826                  */
827                 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size,
828                                              &dom_generic_mapping, NULL, 0);
829                 goto done;
830         }
831
832         info = samr_policy_handle_find(p,
833                                        r->in.handle,
834                                        SAMR_HANDLE_USER,
835                                        SEC_STD_READ_CONTROL,
836                                        NULL,
837                                        &status);
838         if (NT_STATUS_IS_OK(status)) {
839                 DEBUG(10,("_samr_QuerySecurity: querying security on user "
840                           "Object with SID: %s\n",
841                           dom_sid_str_buf(&info->sid, &buf)));
842                 if (check_change_pw_access(p->mem_ctx, &info->sid)) {
843                         status = make_samr_object_sd(
844                                 p->mem_ctx, &psd, &sd_size,
845                                 &usr_generic_mapping,
846                                 &info->sid, SAMR_USR_RIGHTS_WRITE_PW);
847                 } else {
848                         status = make_samr_object_sd(
849                                 p->mem_ctx, &psd, &sd_size,
850                                 &usr_nopwchange_generic_mapping,
851                                 &info->sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
852                 }
853                 goto done;
854         }
855
856         info = samr_policy_handle_find(p,
857                                        r->in.handle,
858                                        SAMR_HANDLE_GROUP,
859                                        SEC_STD_READ_CONTROL,
860                                        NULL,
861                                        &status);
862         if (NT_STATUS_IS_OK(status)) {
863                 /*
864                  * TODO: different SDs have to be generated for aliases groups
865                  * and users.  Currently all three get a default user SD
866                  */
867                 DEBUG(10,("_samr_QuerySecurity: querying security on group "
868                           "Object with SID: %s\n",
869                           dom_sid_str_buf(&info->sid, &buf)));
870                 status = make_samr_object_sd(
871                         p->mem_ctx, &psd, &sd_size,
872                         &usr_nopwchange_generic_mapping,
873                         &info->sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
874                 goto done;
875         }
876
877         info = samr_policy_handle_find(p,
878                                        r->in.handle,
879                                        SAMR_HANDLE_ALIAS,
880                                        SEC_STD_READ_CONTROL,
881                                        NULL,
882                                        &status);
883         if (NT_STATUS_IS_OK(status)) {
884                 /*
885                  * TODO: different SDs have to be generated for aliases groups
886                  * and users.  Currently all three get a default user SD
887                  */
888                 DEBUG(10,("_samr_QuerySecurity: querying security on alias "
889                           "Object with SID: %s\n",
890                           dom_sid_str_buf(&info->sid, &buf)));
891                 status = make_samr_object_sd(
892                         p->mem_ctx, &psd, &sd_size,
893                         &usr_nopwchange_generic_mapping,
894                         &info->sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
895                 goto done;
896         }
897
898         return NT_STATUS_OBJECT_TYPE_MISMATCH;
899 done:
900         if ((*r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
901                 return NT_STATUS_NO_MEMORY;
902
903         return status;
904 }
905
906 /*******************************************************************
907 makes a SAM_ENTRY / UNISTR2* structure from a user list.
908 ********************************************************************/
909
910 static NTSTATUS make_user_sam_entry_list(TALLOC_CTX *ctx,
911                                          struct samr_SamEntry **sam_pp,
912                                          uint32_t num_entries,
913                                          uint32_t start_idx,
914                                          struct samr_displayentry *entries)
915 {
916         uint32_t i;
917         struct samr_SamEntry *sam;
918
919         *sam_pp = NULL;
920
921         if (num_entries == 0) {
922                 return NT_STATUS_OK;
923         }
924
925         sam = talloc_zero_array(ctx, struct samr_SamEntry, num_entries);
926         if (sam == NULL) {
927                 DEBUG(0, ("make_user_sam_entry_list: TALLOC_ZERO failed!\n"));
928                 return NT_STATUS_NO_MEMORY;
929         }
930
931         for (i = 0; i < num_entries; i++) {
932 #if 0
933                 /*
934                  * usrmgr expects a non-NULL terminated string with
935                  * trust relationships
936                  */
937                 if (entries[i].acct_flags & ACB_DOMTRUST) {
938                         init_unistr2(&uni_temp_name, entries[i].account_name,
939                                      UNI_FLAGS_NONE);
940                 } else {
941                         init_unistr2(&uni_temp_name, entries[i].account_name,
942                                      UNI_STR_TERMINATE);
943                 }
944 #endif
945                 init_lsa_String(&sam[i].name, entries[i].account_name);
946                 sam[i].idx = entries[i].rid;
947         }
948
949         *sam_pp = sam;
950
951         return NT_STATUS_OK;
952 }
953
954 #define MAX_SAM_ENTRIES MAX_SAM_ENTRIES_W2K
955
956 /*******************************************************************
957  _samr_EnumDomainUsers
958  ********************************************************************/
959
960 NTSTATUS _samr_EnumDomainUsers(struct pipes_struct *p,
961                                struct samr_EnumDomainUsers *r)
962 {
963         NTSTATUS status;
964         struct samr_info *dinfo;
965         uint32_t num_account;
966         uint32_t enum_context = *r->in.resume_handle;
967         enum remote_arch_types ra_type = get_remote_arch();
968         int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
969         uint32_t max_entries = max_sam_entries;
970         struct samr_displayentry *entries = NULL;
971         struct samr_SamArray *samr_array = NULL;
972         struct samr_SamEntry *samr_entries = NULL;
973
974         DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
975
976         dinfo = samr_policy_handle_find(p,
977                                         r->in.domain_handle,
978                                         SAMR_HANDLE_DOMAIN,
979                                         SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
980                                         NULL,
981                                         &status);
982         if (!NT_STATUS_IS_OK(status)) {
983                 return status;
984         }
985
986         samr_array = talloc_zero(p->mem_ctx, struct samr_SamArray);
987         if (!samr_array) {
988                 return NT_STATUS_NO_MEMORY;
989         }
990         *r->out.sam = samr_array;
991
992         if (sid_check_is_builtin(&dinfo->sid)) {
993                 /* No users in builtin. */
994                 *r->out.resume_handle = *r->in.resume_handle;
995                 DEBUG(5,("_samr_EnumDomainUsers: No users in BUILTIN\n"));
996                 return status;
997         }
998
999         become_root();
1000
1001         /* AS ROOT !!!! */
1002
1003         if ((dinfo->disp_info->enum_users != NULL) &&
1004             (dinfo->disp_info->enum_acb_mask != r->in.acct_flags)) {
1005                 TALLOC_FREE(dinfo->disp_info->enum_users);
1006         }
1007
1008         if (dinfo->disp_info->enum_users == NULL) {
1009                 dinfo->disp_info->enum_users = pdb_search_users(
1010                         dinfo->disp_info, r->in.acct_flags);
1011                 dinfo->disp_info->enum_acb_mask = r->in.acct_flags;
1012         }
1013
1014         if (dinfo->disp_info->enum_users == NULL) {
1015                 /* END AS ROOT !!!! */
1016                 unbecome_root();
1017                 return NT_STATUS_ACCESS_DENIED;
1018         }
1019
1020         num_account = pdb_search_entries(dinfo->disp_info->enum_users,
1021                                          enum_context, max_entries,
1022                                          &entries);
1023
1024         /* END AS ROOT !!!! */
1025
1026         unbecome_root();
1027
1028         if (num_account == 0) {
1029                 DEBUG(5, ("_samr_EnumDomainUsers: enumeration handle over "
1030                           "total entries\n"));
1031                 *r->out.resume_handle = *r->in.resume_handle;
1032                 return NT_STATUS_OK;
1033         }
1034
1035         status = make_user_sam_entry_list(p->mem_ctx, &samr_entries,
1036                                           num_account, enum_context,
1037                                           entries);
1038         if (!NT_STATUS_IS_OK(status)) {
1039                 return status;
1040         }
1041
1042         if (max_entries <= num_account) {
1043                 status = STATUS_MORE_ENTRIES;
1044         } else {
1045                 status = NT_STATUS_OK;
1046         }
1047
1048         /* Ensure we cache this enumeration. */
1049         set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
1050
1051         DEBUG(5, ("_samr_EnumDomainUsers: %d\n", __LINE__));
1052
1053         samr_array->count = num_account;
1054         samr_array->entries = samr_entries;
1055
1056         *r->out.resume_handle = *r->in.resume_handle + num_account;
1057         *r->out.num_entries = num_account;
1058
1059         DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
1060
1061         return status;
1062 }
1063
1064 /*******************************************************************
1065 makes a SAM_ENTRY / UNISTR2* structure from a group list.
1066 ********************************************************************/
1067
1068 static void make_group_sam_entry_list(TALLOC_CTX *ctx,
1069                                       struct samr_SamEntry **sam_pp,
1070                                       uint32_t num_sam_entries,
1071                                       struct samr_displayentry *entries)
1072 {
1073         struct samr_SamEntry *sam;
1074         uint32_t i;
1075
1076         *sam_pp = NULL;
1077
1078         if (num_sam_entries == 0) {
1079                 return;
1080         }
1081
1082         sam = talloc_zero_array(ctx, struct samr_SamEntry, num_sam_entries);
1083         if (sam == NULL) {
1084                 return;
1085         }
1086
1087         for (i = 0; i < num_sam_entries; i++) {
1088                 /*
1089                  * JRA. I think this should include the null. TNG does not.
1090                  */
1091                 init_lsa_String(&sam[i].name, entries[i].account_name);
1092                 sam[i].idx = entries[i].rid;
1093         }
1094
1095         *sam_pp = sam;
1096 }
1097
1098 /*******************************************************************
1099  _samr_EnumDomainGroups
1100  ********************************************************************/
1101
1102 NTSTATUS _samr_EnumDomainGroups(struct pipes_struct *p,
1103                                 struct samr_EnumDomainGroups *r)
1104 {
1105         NTSTATUS status;
1106         struct samr_info *dinfo;
1107         struct samr_displayentry *groups;
1108         uint32_t num_groups;
1109         struct samr_SamArray *samr_array = NULL;
1110         struct samr_SamEntry *samr_entries = NULL;
1111
1112         dinfo = samr_policy_handle_find(p,
1113                                         r->in.domain_handle,
1114                                         SAMR_HANDLE_DOMAIN,
1115                                         SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
1116                                         NULL,
1117                                         &status);
1118         if (!NT_STATUS_IS_OK(status)) {
1119                 return status;
1120         }
1121
1122         DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
1123
1124         samr_array = talloc_zero(p->mem_ctx, struct samr_SamArray);
1125         if (!samr_array) {
1126                 return NT_STATUS_NO_MEMORY;
1127         }
1128         *r->out.sam = samr_array;
1129
1130         if (sid_check_is_builtin(&dinfo->sid)) {
1131                 /* No groups in builtin. */
1132                 *r->out.resume_handle = *r->in.resume_handle;
1133                 DEBUG(5,("_samr_EnumDomainGroups: No groups in BUILTIN\n"));
1134                 return status;
1135         }
1136
1137         /* the domain group array is being allocated in the function below */
1138
1139         become_root();
1140
1141         if (dinfo->disp_info->groups == NULL) {
1142                 dinfo->disp_info->groups = pdb_search_groups(dinfo->disp_info);
1143
1144                 if (dinfo->disp_info->groups == NULL) {
1145                         unbecome_root();
1146                         return NT_STATUS_ACCESS_DENIED;
1147                 }
1148         }
1149
1150         num_groups = pdb_search_entries(dinfo->disp_info->groups,
1151                                         *r->in.resume_handle,
1152                                         MAX_SAM_ENTRIES, &groups);
1153         unbecome_root();
1154
1155         /* Ensure we cache this enumeration. */
1156         set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
1157
1158         make_group_sam_entry_list(p->mem_ctx, &samr_entries,
1159                                   num_groups, groups);
1160
1161         if (MAX_SAM_ENTRIES <= num_groups) {
1162                 status = STATUS_MORE_ENTRIES;
1163         } else {
1164                 status = NT_STATUS_OK;
1165         }
1166
1167         samr_array->count = num_groups;
1168         samr_array->entries = samr_entries;
1169
1170         *r->out.num_entries = num_groups;
1171         *r->out.resume_handle = num_groups + *r->in.resume_handle;
1172
1173         DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
1174
1175         return status;
1176 }
1177
1178 /*******************************************************************
1179  _samr_EnumDomainAliases
1180  ********************************************************************/
1181
1182 NTSTATUS _samr_EnumDomainAliases(struct pipes_struct *p,
1183                                  struct samr_EnumDomainAliases *r)
1184 {
1185         NTSTATUS status;
1186         struct samr_info *dinfo;
1187         struct samr_displayentry *aliases;
1188         uint32_t num_aliases = 0;
1189         struct samr_SamArray *samr_array = NULL;
1190         struct samr_SamEntry *samr_entries = NULL;
1191         struct dom_sid_buf buf;
1192
1193         dinfo = samr_policy_handle_find(p,
1194                                         r->in.domain_handle,
1195                                         SAMR_HANDLE_DOMAIN,
1196                                         SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
1197                                         NULL,
1198                                         &status);
1199         if (!NT_STATUS_IS_OK(status)) {
1200                 return status;
1201         }
1202
1203         DEBUG(5,("_samr_EnumDomainAliases: sid %s\n",
1204                  dom_sid_str_buf(&dinfo->sid, &buf)));
1205
1206         samr_array = talloc_zero(p->mem_ctx, struct samr_SamArray);
1207         if (!samr_array) {
1208                 return NT_STATUS_NO_MEMORY;
1209         }
1210
1211         become_root();
1212
1213         if (dinfo->disp_info->aliases == NULL) {
1214                 dinfo->disp_info->aliases = pdb_search_aliases(
1215                         dinfo->disp_info, &dinfo->sid);
1216                 if (dinfo->disp_info->aliases == NULL) {
1217                         unbecome_root();
1218                         return NT_STATUS_ACCESS_DENIED;
1219                 }
1220         }
1221
1222         num_aliases = pdb_search_entries(dinfo->disp_info->aliases,
1223                                          *r->in.resume_handle,
1224                                          MAX_SAM_ENTRIES, &aliases);
1225         unbecome_root();
1226
1227         /* Ensure we cache this enumeration. */
1228         set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
1229
1230         make_group_sam_entry_list(p->mem_ctx, &samr_entries,
1231                                   num_aliases, aliases);
1232
1233         DEBUG(5,("_samr_EnumDomainAliases: %d\n", __LINE__));
1234
1235         if (MAX_SAM_ENTRIES <= num_aliases) {
1236                 status = STATUS_MORE_ENTRIES;
1237         } else {
1238                 status = NT_STATUS_OK;
1239         }
1240
1241         samr_array->count = num_aliases;
1242         samr_array->entries = samr_entries;
1243
1244         *r->out.sam = samr_array;
1245         *r->out.num_entries = num_aliases;
1246         *r->out.resume_handle = num_aliases + *r->in.resume_handle;
1247
1248         return status;
1249 }
1250
1251 /*******************************************************************
1252  inits a samr_DispInfoGeneral structure.
1253 ********************************************************************/
1254
1255 static NTSTATUS init_samr_dispinfo_1(TALLOC_CTX *ctx,
1256                                      struct samr_DispInfoGeneral *r,
1257                                      uint32_t num_entries,
1258                                      uint32_t start_idx,
1259                                      struct samr_displayentry *entries)
1260 {
1261         uint32_t i;
1262
1263         DEBUG(10, ("init_samr_dispinfo_1: num_entries: %d\n", num_entries));
1264
1265         if (num_entries == 0) {
1266                 return NT_STATUS_OK;
1267         }
1268
1269         r->count = num_entries;
1270
1271         r->entries = talloc_zero_array(ctx, struct samr_DispEntryGeneral, num_entries);
1272         if (!r->entries) {
1273                 return NT_STATUS_NO_MEMORY;
1274         }
1275
1276         for (i = 0; i < num_entries ; i++) {
1277
1278                 init_lsa_String(&r->entries[i].account_name,
1279                                 entries[i].account_name);
1280
1281                 init_lsa_String(&r->entries[i].description,
1282                                 entries[i].description);
1283
1284                 init_lsa_String(&r->entries[i].full_name,
1285                                 entries[i].fullname);
1286
1287                 r->entries[i].rid = entries[i].rid;
1288                 r->entries[i].acct_flags = entries[i].acct_flags;
1289                 r->entries[i].idx = start_idx+i+1;
1290         }
1291
1292         return NT_STATUS_OK;
1293 }
1294
1295 /*******************************************************************
1296  inits a samr_DispInfoFull structure.
1297 ********************************************************************/
1298
1299 static NTSTATUS init_samr_dispinfo_2(TALLOC_CTX *ctx,
1300                                      struct samr_DispInfoFull *r,
1301                                      uint32_t num_entries,
1302                                      uint32_t start_idx,
1303                                      struct samr_displayentry *entries)
1304 {
1305         uint32_t i;
1306
1307         DEBUG(10, ("init_samr_dispinfo_2: num_entries: %d\n", num_entries));
1308
1309         if (num_entries == 0) {
1310                 return NT_STATUS_OK;
1311         }
1312
1313         r->count = num_entries;
1314
1315         r->entries = talloc_zero_array(ctx, struct samr_DispEntryFull, num_entries);
1316         if (!r->entries) {
1317                 return NT_STATUS_NO_MEMORY;
1318         }
1319
1320         for (i = 0; i < num_entries ; i++) {
1321
1322                 init_lsa_String(&r->entries[i].account_name,
1323                                 entries[i].account_name);
1324
1325                 init_lsa_String(&r->entries[i].description,
1326                                 entries[i].description);
1327
1328                 r->entries[i].rid = entries[i].rid;
1329                 r->entries[i].acct_flags = entries[i].acct_flags;
1330                 r->entries[i].idx = start_idx+i+1;
1331         }
1332
1333         return NT_STATUS_OK;
1334 }
1335
1336 /*******************************************************************
1337  inits a samr_DispInfoFullGroups structure.
1338 ********************************************************************/
1339
1340 static NTSTATUS init_samr_dispinfo_3(TALLOC_CTX *ctx,
1341                                      struct samr_DispInfoFullGroups *r,
1342                                      uint32_t num_entries,
1343                                      uint32_t start_idx,
1344                                      struct samr_displayentry *entries)
1345 {
1346         uint32_t i;
1347
1348         DEBUG(5, ("init_samr_dispinfo_3: num_entries: %d\n", num_entries));
1349
1350         if (num_entries == 0) {
1351                 return NT_STATUS_OK;
1352         }
1353
1354         r->count = num_entries;
1355
1356         r->entries = talloc_zero_array(ctx, struct samr_DispEntryFullGroup, num_entries);
1357         if (!r->entries) {
1358                 return NT_STATUS_NO_MEMORY;
1359         }
1360
1361         for (i = 0; i < num_entries ; i++) {
1362
1363                 init_lsa_String(&r->entries[i].account_name,
1364                                 entries[i].account_name);
1365
1366                 init_lsa_String(&r->entries[i].description,
1367                                 entries[i].description);
1368
1369                 r->entries[i].rid = entries[i].rid;
1370                 r->entries[i].acct_flags = entries[i].acct_flags;
1371                 r->entries[i].idx = start_idx+i+1;
1372         }
1373
1374         return NT_STATUS_OK;
1375 }
1376
1377 /*******************************************************************
1378  inits a samr_DispInfoAscii structure.
1379 ********************************************************************/
1380
1381 static NTSTATUS init_samr_dispinfo_4(TALLOC_CTX *ctx,
1382                                      struct samr_DispInfoAscii *r,
1383                                      uint32_t num_entries,
1384                                      uint32_t start_idx,
1385                                      struct samr_displayentry *entries)
1386 {
1387         uint32_t i;
1388
1389         DEBUG(5, ("init_samr_dispinfo_4: num_entries: %d\n", num_entries));
1390
1391         if (num_entries == 0) {
1392                 return NT_STATUS_OK;
1393         }
1394
1395         r->count = num_entries;
1396
1397         r->entries = talloc_zero_array(ctx, struct samr_DispEntryAscii, num_entries);
1398         if (!r->entries) {
1399                 return NT_STATUS_NO_MEMORY;
1400         }
1401
1402         for (i = 0; i < num_entries ; i++) {
1403
1404                 init_lsa_AsciiStringLarge(&r->entries[i].account_name,
1405                                           entries[i].account_name);
1406
1407                 r->entries[i].idx = start_idx+i+1;
1408         }
1409
1410         return NT_STATUS_OK;
1411 }
1412
1413 /*******************************************************************
1414  inits a samr_DispInfoAscii structure.
1415 ********************************************************************/
1416
1417 static NTSTATUS init_samr_dispinfo_5(TALLOC_CTX *ctx,
1418                                      struct samr_DispInfoAscii *r,
1419                                      uint32_t num_entries,
1420                                      uint32_t start_idx,
1421                                      struct samr_displayentry *entries)
1422 {
1423         uint32_t i;
1424
1425         DEBUG(5, ("init_samr_dispinfo_5: num_entries: %d\n", num_entries));
1426
1427         if (num_entries == 0) {
1428                 return NT_STATUS_OK;
1429         }
1430
1431         r->count = num_entries;
1432
1433         r->entries = talloc_zero_array(ctx, struct samr_DispEntryAscii, num_entries);
1434         if (!r->entries) {
1435                 return NT_STATUS_NO_MEMORY;
1436         }
1437
1438         for (i = 0; i < num_entries ; i++) {
1439
1440                 init_lsa_AsciiStringLarge(&r->entries[i].account_name,
1441                                           entries[i].account_name);
1442
1443                 r->entries[i].idx = start_idx+i+1;
1444         }
1445
1446         return NT_STATUS_OK;
1447 }
1448
1449 /*******************************************************************
1450  _samr_QueryDisplayInfo
1451  ********************************************************************/
1452
1453 NTSTATUS _samr_QueryDisplayInfo(struct pipes_struct *p,
1454                                 struct samr_QueryDisplayInfo *r)
1455 {
1456         NTSTATUS status;
1457         struct samr_info *dinfo;
1458         uint32_t struct_size=0x20; /* W2K always reply that, client doesn't care */
1459
1460         uint32_t max_entries = r->in.max_entries;
1461
1462         union samr_DispInfo *disp_info = r->out.info;
1463
1464         uint32_t temp_size=0;
1465         NTSTATUS disp_ret = NT_STATUS_UNSUCCESSFUL;
1466         uint32_t num_account = 0;
1467         enum remote_arch_types ra_type = get_remote_arch();
1468         uint32_t max_sam_entries = (ra_type == RA_WIN95) ?
1469                 MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
1470         struct samr_displayentry *entries = NULL;
1471
1472         DEBUG(5,("_samr_QueryDisplayInfo: %d\n", __LINE__));
1473
1474         dinfo = samr_policy_handle_find(p,
1475                                         r->in.domain_handle,
1476                                         SAMR_HANDLE_DOMAIN,
1477                                         SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
1478                                         NULL,
1479                                         &status);
1480         if (!NT_STATUS_IS_OK(status)) {
1481                 return status;
1482         }
1483
1484         if (sid_check_is_builtin(&dinfo->sid)) {
1485                 DEBUG(5,("_samr_QueryDisplayInfo: no users in BUILTIN\n"));
1486                 return NT_STATUS_OK;
1487         }
1488
1489         /*
1490          * calculate how many entries we will return.
1491          * based on
1492          * - the number of entries the client asked
1493          * - our limit on that
1494          * - the starting point (enumeration context)
1495          * - the buffer size the client will accept
1496          */
1497
1498         /*
1499          * We are a lot more like W2K. Instead of reading the SAM
1500          * each time to find the records we need to send back,
1501          * we read it once and link that copy to the sam handle.
1502          * For large user list (over the MAX_SAM_ENTRIES)
1503          * it's a definitive win.
1504          * second point to notice: between enumerations
1505          * our sam is now the same as it's a snapshoot.
1506          * third point: got rid of the static SAM_USER_21 struct
1507          * no more intermediate.
1508          * con: it uses much more memory, as a full copy is stored
1509          * in memory.
1510          *
1511          * If you want to change it, think twice and think
1512          * of the second point , that's really important.
1513          *
1514          * JFM, 12/20/2001
1515          */
1516
1517         if ((r->in.level < 1) || (r->in.level > 5)) {
1518                 DEBUG(0,("_samr_QueryDisplayInfo: Unknown info level (%u)\n",
1519                          (unsigned int)r->in.level ));
1520                 return NT_STATUS_INVALID_INFO_CLASS;
1521         }
1522
1523         /* first limit the number of entries we will return */
1524         if (r->in.max_entries > max_sam_entries) {
1525                 DEBUG(5, ("_samr_QueryDisplayInfo: client requested %d "
1526                           "entries, limiting to %d\n", r->in.max_entries,
1527                           max_sam_entries));
1528                 max_entries = max_sam_entries;
1529         }
1530
1531         /* calculate the size and limit on the number of entries we will
1532          * return */
1533
1534         temp_size=max_entries*struct_size;
1535
1536         if (temp_size > r->in.buf_size) {
1537                 max_entries = MIN((r->in.buf_size / struct_size),max_entries);
1538                 DEBUG(5, ("_samr_QueryDisplayInfo: buffer size limits to "
1539                           "only %d entries\n", max_entries));
1540         }
1541
1542         become_root();
1543
1544         /* THe following done as ROOT. Don't return without unbecome_root(). */
1545
1546         switch (r->in.level) {
1547         case 1:
1548         case 4:
1549                 if (dinfo->disp_info->users == NULL) {
1550                         dinfo->disp_info->users = pdb_search_users(
1551                                 dinfo->disp_info, ACB_NORMAL);
1552                         if (dinfo->disp_info->users == NULL) {
1553                                 unbecome_root();
1554                                 return NT_STATUS_ACCESS_DENIED;
1555                         }
1556                         DEBUG(10,("_samr_QueryDisplayInfo: starting user enumeration at index %u\n",
1557                                 (unsigned  int)r->in.start_idx));
1558                 } else {
1559                         DEBUG(10,("_samr_QueryDisplayInfo: using cached user enumeration at index %u\n",
1560                                 (unsigned  int)r->in.start_idx));
1561                 }
1562
1563                 num_account = pdb_search_entries(dinfo->disp_info->users,
1564                                                  r->in.start_idx, max_entries,
1565                                                  &entries);
1566                 break;
1567         case 2:
1568                 if (dinfo->disp_info->machines == NULL) {
1569                         dinfo->disp_info->machines = pdb_search_users(
1570                                 dinfo->disp_info, ACB_WSTRUST|ACB_SVRTRUST);
1571                         if (dinfo->disp_info->machines == NULL) {
1572                                 unbecome_root();
1573                                 return NT_STATUS_ACCESS_DENIED;
1574                         }
1575                         DEBUG(10,("_samr_QueryDisplayInfo: starting machine enumeration at index %u\n",
1576                                 (unsigned  int)r->in.start_idx));
1577                 } else {
1578                         DEBUG(10,("_samr_QueryDisplayInfo: using cached machine enumeration at index %u\n",
1579                                 (unsigned  int)r->in.start_idx));
1580                 }
1581
1582                 num_account = pdb_search_entries(dinfo->disp_info->machines,
1583                                                  r->in.start_idx, max_entries,
1584                                                  &entries);
1585                 break;
1586         case 3:
1587         case 5:
1588                 if (dinfo->disp_info->groups == NULL) {
1589                         dinfo->disp_info->groups = pdb_search_groups(
1590                                 dinfo->disp_info);
1591                         if (dinfo->disp_info->groups == NULL) {
1592                                 unbecome_root();
1593                                 return NT_STATUS_ACCESS_DENIED;
1594                         }
1595                         DEBUG(10,("_samr_QueryDisplayInfo: starting group enumeration at index %u\n",
1596                                 (unsigned  int)r->in.start_idx));
1597                 } else {
1598                         DEBUG(10,("_samr_QueryDisplayInfo: using cached group enumeration at index %u\n",
1599                                 (unsigned  int)r->in.start_idx));
1600                 }
1601
1602                 num_account = pdb_search_entries(dinfo->disp_info->groups,
1603                                                  r->in.start_idx, max_entries,
1604                                                  &entries);
1605                 break;
1606         default:
1607                 unbecome_root();
1608                 smb_panic("info class changed");
1609                 break;
1610         }
1611         unbecome_root();
1612
1613
1614         /* Now create reply structure */
1615         switch (r->in.level) {
1616         case 1:
1617                 disp_ret = init_samr_dispinfo_1(p->mem_ctx, &disp_info->info1,
1618                                                 num_account, r->in.start_idx,
1619                                                 entries);
1620                 break;
1621         case 2:
1622                 disp_ret = init_samr_dispinfo_2(p->mem_ctx, &disp_info->info2,
1623                                                 num_account, r->in.start_idx,
1624                                                 entries);
1625                 break;
1626         case 3:
1627                 disp_ret = init_samr_dispinfo_3(p->mem_ctx, &disp_info->info3,
1628                                                 num_account, r->in.start_idx,
1629                                                 entries);
1630                 break;
1631         case 4:
1632                 disp_ret = init_samr_dispinfo_4(p->mem_ctx, &disp_info->info4,
1633                                                 num_account, r->in.start_idx,
1634                                                 entries);
1635                 break;
1636         case 5:
1637                 disp_ret = init_samr_dispinfo_5(p->mem_ctx, &disp_info->info5,
1638                                                 num_account, r->in.start_idx,
1639                                                 entries);
1640                 break;
1641         default:
1642                 smb_panic("info class changed");
1643                 break;
1644         }
1645
1646         if (!NT_STATUS_IS_OK(disp_ret))
1647                 return disp_ret;
1648
1649         if (max_entries <= num_account) {
1650                 status = STATUS_MORE_ENTRIES;
1651         } else {
1652                 status = NT_STATUS_OK;
1653         }
1654
1655         /* Ensure we cache this enumeration. */
1656         set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
1657
1658         DEBUG(5, ("_samr_QueryDisplayInfo: %d\n", __LINE__));
1659
1660         *r->out.total_size = num_account * struct_size;
1661         *r->out.returned_size = num_account ? temp_size : 0;
1662
1663         return status;
1664 }
1665
1666 /****************************************************************
1667  _samr_QueryDisplayInfo2
1668 ****************************************************************/
1669
1670 NTSTATUS _samr_QueryDisplayInfo2(struct pipes_struct *p,
1671                                  struct samr_QueryDisplayInfo2 *r)
1672 {
1673         struct samr_QueryDisplayInfo q;
1674
1675         q.in.domain_handle      = r->in.domain_handle;
1676         q.in.level              = r->in.level;
1677         q.in.start_idx          = r->in.start_idx;
1678         q.in.max_entries        = r->in.max_entries;
1679         q.in.buf_size           = r->in.buf_size;
1680
1681         q.out.total_size        = r->out.total_size;
1682         q.out.returned_size     = r->out.returned_size;
1683         q.out.info              = r->out.info;
1684
1685         return _samr_QueryDisplayInfo(p, &q);
1686 }
1687
1688 /****************************************************************
1689  _samr_QueryDisplayInfo3
1690 ****************************************************************/
1691
1692 NTSTATUS _samr_QueryDisplayInfo3(struct pipes_struct *p,
1693                                  struct samr_QueryDisplayInfo3 *r)
1694 {
1695         struct samr_QueryDisplayInfo q;
1696
1697         q.in.domain_handle      = r->in.domain_handle;
1698         q.in.level              = r->in.level;
1699         q.in.start_idx          = r->in.start_idx;
1700         q.in.max_entries        = r->in.max_entries;
1701         q.in.buf_size           = r->in.buf_size;
1702
1703         q.out.total_size        = r->out.total_size;
1704         q.out.returned_size     = r->out.returned_size;
1705         q.out.info              = r->out.info;
1706
1707         return _samr_QueryDisplayInfo(p, &q);
1708 }
1709
1710 /*******************************************************************
1711  _samr_QueryAliasInfo
1712  ********************************************************************/
1713
1714 NTSTATUS _samr_QueryAliasInfo(struct pipes_struct *p,
1715                               struct samr_QueryAliasInfo *r)
1716 {
1717         struct samr_info *ainfo;
1718         struct acct_info *info;
1719         NTSTATUS status;
1720         union samr_AliasInfo *alias_info = NULL;
1721         const char *alias_name = NULL;
1722         const char *alias_description = NULL;
1723
1724         DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1725
1726         ainfo = samr_policy_handle_find(p,
1727                                         r->in.alias_handle,
1728                                         SAMR_HANDLE_ALIAS,
1729                                         SAMR_ALIAS_ACCESS_LOOKUP_INFO,
1730                                         NULL,
1731                                         &status);
1732         if (!NT_STATUS_IS_OK(status)) {
1733                 return status;
1734         }
1735
1736         alias_info = talloc_zero(p->mem_ctx, union samr_AliasInfo);
1737         if (!alias_info) {
1738                 return NT_STATUS_NO_MEMORY;
1739         }
1740
1741         info = talloc_zero(p->mem_ctx, struct acct_info);
1742         if (!info) {
1743                 return NT_STATUS_NO_MEMORY;
1744         }
1745
1746         become_root();
1747         status = pdb_get_aliasinfo(&ainfo->sid, info);
1748         unbecome_root();
1749
1750         if (!NT_STATUS_IS_OK(status)) {
1751                 TALLOC_FREE(info);
1752                 return status;
1753         }
1754
1755         alias_name = talloc_steal(r, info->acct_name);
1756         alias_description = talloc_steal(r, info->acct_desc);
1757         TALLOC_FREE(info);
1758
1759         switch (r->in.level) {
1760         case ALIASINFOALL:
1761                 alias_info->all.name.string             = alias_name;
1762                 alias_info->all.num_members             = 1; /* ??? */
1763                 alias_info->all.description.string      = alias_description;
1764                 break;
1765         case ALIASINFONAME:
1766                 alias_info->name.string                 = alias_name;
1767                 break;
1768         case ALIASINFODESCRIPTION:
1769                 alias_info->description.string          = alias_description;
1770                 break;
1771         default:
1772                 return NT_STATUS_INVALID_INFO_CLASS;
1773         }
1774
1775         *r->out.info = alias_info;
1776
1777         DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1778
1779         return NT_STATUS_OK;
1780 }
1781
1782 /*******************************************************************
1783  _samr_LookupNames
1784  ********************************************************************/
1785
1786 NTSTATUS _samr_LookupNames(struct pipes_struct *p,
1787                            struct samr_LookupNames *r)
1788 {
1789         struct samr_info *dinfo;
1790         NTSTATUS status;
1791         uint32_t *rid;
1792         enum lsa_SidType *type;
1793         uint32_t i, num_rids = r->in.num_names;
1794         struct samr_Ids rids, types;
1795         uint32_t num_mapped = 0;
1796         struct dom_sid_buf buf;
1797
1798         DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1799
1800         dinfo = samr_policy_handle_find(p,
1801                                         r->in.domain_handle,
1802                                         SAMR_HANDLE_DOMAIN,
1803                                         0 /* Don't know the acc_bits yet */,
1804                                         NULL,
1805                                         &status);
1806         if (!NT_STATUS_IS_OK(status)) {
1807                 return status;
1808         }
1809
1810         if (num_rids > MAX_SAM_ENTRIES) {
1811                 num_rids = MAX_SAM_ENTRIES;
1812                 DEBUG(5,("_samr_LookupNames: truncating entries to %d\n", num_rids));
1813         }
1814
1815         rid = talloc_array(p->mem_ctx, uint32_t, num_rids);
1816         NT_STATUS_HAVE_NO_MEMORY(rid);
1817
1818         type = talloc_array(p->mem_ctx, enum lsa_SidType, num_rids);
1819         NT_STATUS_HAVE_NO_MEMORY(type);
1820
1821         DEBUG(5,("_samr_LookupNames: looking name on SID %s\n",
1822                  dom_sid_str_buf(&dinfo->sid, &buf)));
1823
1824         for (i = 0; i < num_rids; i++) {
1825
1826                 status = NT_STATUS_NONE_MAPPED;
1827                 type[i] = SID_NAME_UNKNOWN;
1828
1829                 rid[i] = 0xffffffff;
1830
1831                 if (sid_check_is_builtin(&dinfo->sid)) {
1832                         if (lookup_builtin_name(r->in.names[i].string,
1833                                                 &rid[i]))
1834                         {
1835                                 type[i] = SID_NAME_ALIAS;
1836                         }
1837                 } else {
1838                         lookup_global_sam_name(r->in.names[i].string, 0,
1839                                                &rid[i], &type[i]);
1840                 }
1841
1842                 if (type[i] != SID_NAME_UNKNOWN) {
1843                         num_mapped++;
1844                 }
1845         }
1846
1847         if (num_mapped == num_rids) {
1848                 status = NT_STATUS_OK;
1849         } else if (num_mapped == 0) {
1850                 status = NT_STATUS_NONE_MAPPED;
1851         } else {
1852                 status = STATUS_SOME_UNMAPPED;
1853         }
1854
1855         rids.count = num_rids;
1856         rids.ids = rid;
1857
1858         types.count = num_rids;
1859         types.ids = talloc_array(p->mem_ctx, uint32_t, num_rids);
1860         NT_STATUS_HAVE_NO_MEMORY(type);
1861         for (i = 0; i < num_rids; i++) {
1862                 types.ids[i] = (type[i] & 0xffffffff);
1863         }
1864
1865         *r->out.rids = rids;
1866         *r->out.types = types;
1867
1868         DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1869
1870         return status;
1871 }
1872
1873 /****************************************************************
1874  _samr_ChangePasswordUser.
1875
1876  So old it is just not worth implementing
1877  because it does not supply a plaintext and so we can't do password
1878  complexity checking and cannot update other services that use a
1879  plaintext password via passwd chat/pam password change/ldap password
1880  sync.
1881 ****************************************************************/
1882
1883 NTSTATUS _samr_ChangePasswordUser(struct pipes_struct *p,
1884                                   struct samr_ChangePasswordUser *r)
1885 {
1886         return NT_STATUS_NOT_IMPLEMENTED;
1887 }
1888
1889 /*******************************************************************
1890  _samr_ChangePasswordUser2
1891  ********************************************************************/
1892
1893 NTSTATUS _samr_ChangePasswordUser2(struct pipes_struct *p,
1894                                    struct samr_ChangePasswordUser2 *r)
1895 {
1896         struct dcesrv_call_state *dce_call = p->dce_call;
1897         struct dcesrv_connection *dcesrv_conn = dce_call->conn;
1898         const struct tsocket_address *remote_address =
1899                 dcesrv_connection_get_remote_address(dcesrv_conn);
1900         struct auth_session_info *session_info =
1901                 dcesrv_call_session_info(dce_call);
1902         NTSTATUS status;
1903         char *user_name = NULL;
1904         char *rhost;
1905         const char *wks = NULL;
1906         bool encrypted;
1907
1908         DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1909
1910         if (!r->in.account->string) {
1911                 return NT_STATUS_INVALID_PARAMETER;
1912         }
1913         if (r->in.server && r->in.server->string) {
1914                 wks = r->in.server->string;
1915         }
1916
1917         DEBUG(5,("_samr_ChangePasswordUser2: user: %s wks: %s\n", user_name, wks));
1918
1919         /*
1920          * Pass the user through the NT -> unix user mapping
1921          * function.
1922          */
1923
1924         (void)map_username(talloc_tos(), r->in.account->string, &user_name);
1925         if (!user_name) {
1926                 return NT_STATUS_NO_MEMORY;
1927         }
1928
1929         rhost = tsocket_address_inet_addr_string(remote_address,
1930                                                  talloc_tos());
1931         if (rhost == NULL) {
1932                 return NT_STATUS_NO_MEMORY;
1933         }
1934
1935         encrypted = dcerpc_is_transport_encrypted(session_info);
1936         if (lp_weak_crypto() == SAMBA_WEAK_CRYPTO_DISALLOWED &&
1937             !encrypted) {
1938                 return NT_STATUS_ACCESS_DENIED;
1939         }
1940
1941         /*
1942          * UNIX username case mangling not required, pass_oem_change
1943          * is case insensitive.
1944          */
1945
1946         status = pass_oem_change(user_name,
1947                                  rhost,
1948                                  r->in.lm_password->data,
1949                                  r->in.lm_verifier->hash,
1950                                  r->in.nt_password->data,
1951                                  r->in.nt_verifier->hash,
1952                                  NULL);
1953
1954         DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1955
1956         if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
1957                 return NT_STATUS_WRONG_PASSWORD;
1958         }
1959
1960         return status;
1961 }
1962
1963 /****************************************************************
1964  _samr_OemChangePasswordUser2
1965 ****************************************************************/
1966
1967 NTSTATUS _samr_OemChangePasswordUser2(struct pipes_struct *p,
1968                                       struct samr_OemChangePasswordUser2 *r)
1969 {
1970         struct dcesrv_call_state *dce_call = p->dce_call;
1971         struct dcesrv_connection *dcesrv_conn = dce_call->conn;
1972         const struct tsocket_address *remote_address =
1973                 dcesrv_connection_get_remote_address(dcesrv_conn);
1974         struct auth_session_info *session_info =
1975                 dcesrv_call_session_info(dce_call);
1976         NTSTATUS status;
1977         char *user_name = NULL;
1978         const char *wks = NULL;
1979         char *rhost;
1980         bool encrypted;
1981
1982         DEBUG(5,("_samr_OemChangePasswordUser2: %d\n", __LINE__));
1983
1984         if (!r->in.account->string) {
1985                 return NT_STATUS_INVALID_PARAMETER;
1986         }
1987         if (r->in.server && r->in.server->string) {
1988                 wks = r->in.server->string;
1989         }
1990
1991         DEBUG(5,("_samr_OemChangePasswordUser2: user: %s wks: %s\n", user_name, wks));
1992
1993         /*
1994          * Pass the user through the NT -> unix user mapping
1995          * function.
1996          */
1997
1998         (void)map_username(talloc_tos(), r->in.account->string, &user_name);
1999         if (!user_name) {
2000                 return NT_STATUS_NO_MEMORY;
2001         }
2002
2003         /*
2004          * UNIX username case mangling not required, pass_oem_change
2005          * is case insensitive.
2006          */
2007
2008         if (!r->in.hash || !r->in.password) {
2009                 return NT_STATUS_INVALID_PARAMETER;
2010         }
2011
2012         rhost = tsocket_address_inet_addr_string(remote_address,
2013                                                  talloc_tos());
2014         if (rhost == NULL) {
2015                 return NT_STATUS_NO_MEMORY;
2016         }
2017
2018         encrypted = dcerpc_is_transport_encrypted(session_info);
2019         if (lp_weak_crypto() == SAMBA_WEAK_CRYPTO_DISALLOWED &&
2020             !encrypted) {
2021                 return NT_STATUS_ACCESS_DENIED;
2022         }
2023
2024         status = pass_oem_change(user_name,
2025                                  rhost,
2026                                  r->in.password->data,
2027                                  r->in.hash->hash,
2028                                  0,
2029                                  0,
2030                                  NULL);
2031
2032         if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
2033                 return NT_STATUS_WRONG_PASSWORD;
2034         }
2035
2036         DEBUG(5,("_samr_OemChangePasswordUser2: %d\n", __LINE__));
2037
2038         return status;
2039 }
2040
2041 /*******************************************************************
2042  _samr_ChangePasswordUser3
2043  ********************************************************************/
2044
2045 NTSTATUS _samr_ChangePasswordUser3(struct pipes_struct *p,
2046                                    struct samr_ChangePasswordUser3 *r)
2047 {
2048         struct dcesrv_call_state *dce_call = p->dce_call;
2049         struct dcesrv_connection *dcesrv_conn = dce_call->conn;
2050         const struct tsocket_address *remote_address =
2051                 dcesrv_connection_get_remote_address(dcesrv_conn);
2052         NTSTATUS status;
2053         char *user_name = NULL;
2054         const char *wks = NULL;
2055         enum samPwdChangeReason reject_reason;
2056         struct samr_DomInfo1 *dominfo = NULL;
2057         struct userPwdChangeFailureInformation *reject = NULL;
2058         const struct loadparm_substitution *lp_sub =
2059                 loadparm_s3_global_substitution();
2060         uint32_t tmp;
2061         char *rhost;
2062
2063         DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
2064
2065         if (!r->in.account->string) {
2066                 return NT_STATUS_INVALID_PARAMETER;
2067         }
2068         if (r->in.server && r->in.server->string) {
2069                 wks = r->in.server->string;
2070         }
2071
2072         DEBUG(5,("_samr_ChangePasswordUser3: user: %s wks: %s\n", user_name, wks));
2073
2074         /*
2075          * Pass the user through the NT -> unix user mapping
2076          * function.
2077          */
2078
2079         (void)map_username(talloc_tos(), r->in.account->string, &user_name);
2080         if (!user_name) {
2081                 return NT_STATUS_NO_MEMORY;
2082         }
2083
2084         rhost = tsocket_address_inet_addr_string(remote_address,
2085                                                  talloc_tos());
2086         if (rhost == NULL) {
2087                 return NT_STATUS_NO_MEMORY;
2088         }
2089
2090         /*
2091          * UNIX username case mangling not required, pass_oem_change
2092          * is case insensitive.
2093          */
2094
2095         status = pass_oem_change(user_name,
2096                                  rhost,
2097                                  r->in.lm_password->data,
2098                                  r->in.lm_verifier->hash,
2099                                  r->in.nt_password->data,
2100                                  r->in.nt_verifier->hash,
2101                                  &reject_reason);
2102         if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
2103                 return NT_STATUS_WRONG_PASSWORD;
2104         }
2105
2106         if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) ||
2107             NT_STATUS_EQUAL(status, NT_STATUS_ACCOUNT_RESTRICTION)) {
2108
2109                 time_t u_expire, u_min_age;
2110                 uint32_t account_policy_temp;
2111
2112                 dominfo = talloc_zero(p->mem_ctx, struct samr_DomInfo1);
2113                 if (!dominfo) {
2114                         return NT_STATUS_NO_MEMORY;
2115                 }
2116
2117                 reject = talloc_zero(p->mem_ctx,
2118                                 struct userPwdChangeFailureInformation);
2119                 if (!reject) {
2120                         return NT_STATUS_NO_MEMORY;
2121                 }
2122
2123                 become_root();
2124
2125                 /* AS ROOT !!! */
2126
2127                 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN, &tmp);
2128                 dominfo->min_password_length = tmp;
2129
2130                 pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &tmp);
2131                 dominfo->password_history_length = tmp;
2132
2133                 pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
2134                                        &dominfo->password_properties);
2135
2136                 pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, &account_policy_temp);
2137                 u_expire = account_policy_temp;
2138
2139                 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, &account_policy_temp);
2140                 u_min_age = account_policy_temp;
2141
2142                 /* !AS ROOT */
2143
2144                 unbecome_root();
2145
2146                 unix_to_nt_time_abs((NTTIME *)&dominfo->max_password_age, u_expire);
2147                 unix_to_nt_time_abs((NTTIME *)&dominfo->min_password_age, u_min_age);
2148
2149                 if (lp_check_password_script(talloc_tos(), lp_sub)
2150                         && *lp_check_password_script(talloc_tos(), lp_sub)) {
2151                         dominfo->password_properties |= DOMAIN_PASSWORD_COMPLEX;
2152                 }
2153
2154                 reject->extendedFailureReason = reject_reason;
2155
2156                 *r->out.dominfo = dominfo;
2157                 *r->out.reject = reject;
2158         }
2159
2160         DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
2161
2162         return status;
2163 }
2164
2165 /*******************************************************************
2166 makes a SAMR_R_LOOKUP_RIDS structure.
2167 ********************************************************************/
2168
2169 static bool make_samr_lookup_rids(TALLOC_CTX *ctx, uint32_t num_names,
2170                                   const char **names,
2171                                   struct lsa_String **lsa_name_array_p)
2172 {
2173         struct lsa_String *lsa_name_array = NULL;
2174         uint32_t i;
2175
2176         *lsa_name_array_p = NULL;
2177
2178         if (num_names != 0) {
2179                 lsa_name_array = talloc_zero_array(ctx, struct lsa_String, num_names);
2180                 if (!lsa_name_array) {
2181                         return false;
2182                 }
2183         }
2184
2185         for (i = 0; i < num_names; i++) {
2186                 DEBUG(10, ("names[%d]:%s\n", i, names[i] && *names[i] ? names[i] : ""));
2187                 init_lsa_String(&lsa_name_array[i], names[i]);
2188         }
2189
2190         *lsa_name_array_p = lsa_name_array;
2191
2192         return true;
2193 }
2194
2195 /*******************************************************************
2196  _samr_LookupRids
2197  ********************************************************************/
2198
2199 NTSTATUS _samr_LookupRids(struct pipes_struct *p,
2200                           struct samr_LookupRids *r)
2201 {
2202         struct samr_info *dinfo;
2203         NTSTATUS status;
2204         const char **names;
2205         enum lsa_SidType *attrs = NULL;
2206         uint32_t *wire_attrs = NULL;
2207         int num_rids = (int)r->in.num_rids;
2208         int i;
2209         struct lsa_Strings names_array;
2210         struct samr_Ids types_array;
2211         struct lsa_String *lsa_names = NULL;
2212
2213         DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2214
2215         dinfo = samr_policy_handle_find(p,
2216                                         r->in.domain_handle,
2217                                         SAMR_HANDLE_DOMAIN,
2218                                         0 /* Don't know the acc_bits yet */,
2219                                         NULL,
2220                                         &status);
2221         if (!NT_STATUS_IS_OK(status)) {
2222                 return status;
2223         }
2224
2225         if (num_rids > 1000) {
2226                 DEBUG(0, ("Got asked for %d rids (more than 1000) -- according "
2227                           "to samba4 idl this is not possible\n", num_rids));
2228                 return NT_STATUS_UNSUCCESSFUL;
2229         }
2230
2231         if (num_rids) {
2232                 names = talloc_zero_array(p->mem_ctx, const char *, num_rids);
2233                 attrs = talloc_zero_array(p->mem_ctx, enum lsa_SidType, num_rids);
2234                 wire_attrs = talloc_zero_array(p->mem_ctx, uint32_t, num_rids);
2235
2236                 if ((names == NULL) || (attrs == NULL) || (wire_attrs==NULL))
2237                         return NT_STATUS_NO_MEMORY;
2238         } else {
2239                 names = NULL;
2240                 attrs = NULL;
2241                 wire_attrs = NULL;
2242         }
2243
2244         become_root();  /* lookup_sid can require root privs */
2245         status = pdb_lookup_rids(&dinfo->sid, num_rids, r->in.rids,
2246                                  names, attrs);
2247         unbecome_root();
2248
2249         if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED) && (num_rids == 0)) {
2250                 status = NT_STATUS_OK;
2251         }
2252
2253         if (!make_samr_lookup_rids(p->mem_ctx, num_rids, names,
2254                                    &lsa_names)) {
2255                 return NT_STATUS_NO_MEMORY;
2256         }
2257
2258         /* Convert from enum lsa_SidType to uint32_t for wire format. */
2259         for (i = 0; i < num_rids; i++) {
2260                 wire_attrs[i] = (uint32_t)attrs[i];
2261         }
2262
2263         names_array.count = num_rids;
2264         names_array.names = lsa_names;
2265
2266         types_array.count = num_rids;
2267         types_array.ids = wire_attrs;
2268
2269         *r->out.names = names_array;
2270         *r->out.types = types_array;
2271
2272         DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2273
2274         return status;
2275 }
2276
2277 /*******************************************************************
2278  _samr_OpenUser
2279 ********************************************************************/
2280
2281 NTSTATUS _samr_OpenUser(struct pipes_struct *p,
2282                         struct samr_OpenUser *r)
2283 {
2284         struct dcesrv_call_state *dce_call = p->dce_call;
2285         struct auth_session_info *session_info =
2286                 dcesrv_call_session_info(dce_call);
2287         struct samu *sampass=NULL;
2288         struct dom_sid sid;
2289         struct samr_info *dinfo;
2290         struct security_descriptor *psd = NULL;
2291         uint32_t    acc_granted;
2292         uint32_t    des_access = r->in.access_mask;
2293         uint32_t extra_access = 0;
2294         size_t    sd_size;
2295         bool ret;
2296         NTSTATUS nt_status;
2297
2298         /* These two privileges, if != SEC_PRIV_INVALID, indicate
2299          * privileges that the user must have to complete this
2300          * operation in defience of the fixed ACL */
2301         enum sec_privilege needed_priv_1, needed_priv_2;
2302         NTSTATUS status;
2303
2304         dinfo = samr_policy_handle_find(p,
2305                                         r->in.domain_handle,
2306                                         SAMR_HANDLE_DOMAIN,
2307                                         SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
2308                                         NULL,
2309                                         &status);
2310         if (!NT_STATUS_IS_OK(status)) {
2311                 return status;
2312         }
2313
2314         if ( !(sampass = samu_new( p->mem_ctx )) ) {
2315                 return NT_STATUS_NO_MEMORY;
2316         }
2317
2318         /* append the user's RID to it */
2319
2320         if (!sid_compose(&sid, &dinfo->sid, r->in.rid))
2321                 return NT_STATUS_NO_SUCH_USER;
2322
2323         /* check if access can be granted as requested by client. */
2324         map_max_allowed_access(session_info->security_token,
2325                                session_info->unix_token,
2326                                &des_access);
2327
2328         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &sid, SAMR_USR_RIGHTS_WRITE_PW);
2329         se_map_generic(&des_access, &usr_generic_mapping);
2330
2331         /*
2332          * Get the sampass first as we need to check privileges
2333          * based on what kind of user object this is.
2334          * But don't reveal info too early if it didn't exist.
2335          */
2336
2337         become_root();
2338         ret=pdb_getsampwsid(sampass, &sid);
2339         unbecome_root();
2340
2341         needed_priv_1 = SEC_PRIV_INVALID;
2342         needed_priv_2 = SEC_PRIV_INVALID;
2343         /*
2344          * We do the override access checks on *open*, not at
2345          * SetUserInfo time.
2346          */
2347         if (ret) {
2348                 uint32_t acb_info = pdb_get_acct_ctrl(sampass);
2349
2350                 if (acb_info & ACB_WSTRUST) {
2351                         /*
2352                          * SeMachineAccount is needed to add
2353                          * GENERIC_RIGHTS_USER_WRITE to a machine
2354                          * account.
2355                          */
2356                         needed_priv_1 = SEC_PRIV_MACHINE_ACCOUNT;
2357                 }
2358                 if (acb_info & ACB_NORMAL) {
2359                         /*
2360                          * SeAddUsers is needed to add
2361                          * GENERIC_RIGHTS_USER_WRITE to a normal
2362                          * account.
2363                          */
2364                         needed_priv_1 = SEC_PRIV_ADD_USERS;
2365                 }
2366                 /*
2367                  * Cheat - we have not set a specific privilege for
2368                  * server (BDC) or domain trust account, so allow
2369                  * GENERIC_RIGHTS_USER_WRITE if pipe user is in
2370                  * DOMAIN_RID_ADMINS.
2371                  */
2372                 if (acb_info & (ACB_SVRTRUST|ACB_DOMTRUST)) {
2373                         if (lp_enable_privileges() &&
2374                             nt_token_check_domain_rid(
2375                                     session_info->security_token,
2376                                     DOMAIN_RID_ADMINS)) {
2377                                 des_access &= ~GENERIC_RIGHTS_USER_WRITE;
2378                                 extra_access = GENERIC_RIGHTS_USER_WRITE;
2379                                 DEBUG(4,("_samr_OpenUser: Allowing "
2380                                         "GENERIC_RIGHTS_USER_WRITE for "
2381                                         "rid admins\n"));
2382                         }
2383                 }
2384         }
2385
2386         TALLOC_FREE(sampass);
2387
2388         nt_status = access_check_object(psd, session_info->security_token,
2389                                         needed_priv_1, needed_priv_2,
2390                                         GENERIC_RIGHTS_USER_WRITE, des_access,
2391                                         &acc_granted, "_samr_OpenUser");
2392
2393         if ( !NT_STATUS_IS_OK(nt_status) )
2394                 return nt_status;
2395
2396         /* check that the SID exists in our domain. */
2397         if (ret == False) {
2398                 return NT_STATUS_NO_SUCH_USER;
2399         }
2400
2401         /* If we did the rid admins hack above, allow access. */
2402         acc_granted |= extra_access;
2403
2404         status = create_samr_policy_handle(p->mem_ctx,
2405                                            p,
2406                                            SAMR_HANDLE_USER,
2407                                            acc_granted,
2408                                            &sid,
2409                                            NULL,
2410                                            r->out.user_handle);
2411         if (!NT_STATUS_IS_OK(status)) {
2412                 return status;
2413         }
2414
2415         return NT_STATUS_OK;
2416 }
2417
2418 /*************************************************************************
2419  *************************************************************************/
2420
2421 static NTSTATUS init_samr_parameters_string(TALLOC_CTX *mem_ctx,
2422                                             DATA_BLOB *blob,
2423                                             struct lsa_BinaryString **_r)
2424 {
2425         struct lsa_BinaryString *r;
2426
2427         if (!blob || !_r) {
2428                 return NT_STATUS_INVALID_PARAMETER;
2429         }
2430
2431         r = talloc_zero(mem_ctx, struct lsa_BinaryString);
2432         if (!r) {
2433                 return NT_STATUS_NO_MEMORY;
2434         }
2435
2436         r->array = talloc_zero_array(mem_ctx, uint16_t, blob->length/2);
2437         if (!r->array) {
2438                 return NT_STATUS_NO_MEMORY;
2439         }
2440         memcpy(r->array, blob->data, blob->length);
2441         r->size = blob->length;
2442         r->length = blob->length;
2443
2444         if (!r->array) {
2445                 return NT_STATUS_NO_MEMORY;
2446         }
2447
2448         *_r = r;
2449
2450         return NT_STATUS_OK;
2451 }
2452
2453 /*************************************************************************
2454  *************************************************************************/
2455
2456 static struct samr_LogonHours get_logon_hours_from_pdb(TALLOC_CTX *mem_ctx,
2457                                                        struct samu *pw)
2458 {
2459         struct samr_LogonHours hours;
2460         const int units_per_week = 168;
2461
2462         ZERO_STRUCT(hours);
2463         hours.bits = talloc_array(mem_ctx, uint8_t, units_per_week);
2464         if (!hours.bits) {
2465                 return hours;
2466         }
2467
2468         hours.units_per_week = units_per_week;
2469         memset(hours.bits, 0xFF, units_per_week);
2470
2471         if (pdb_get_hours(pw)) {
2472                 memcpy(hours.bits, pdb_get_hours(pw),
2473                        MIN(pdb_get_hours_len(pw), units_per_week));
2474         }
2475
2476         return hours;
2477 }
2478
2479 /*************************************************************************
2480  get_user_info_1.
2481  *************************************************************************/
2482
2483 static NTSTATUS get_user_info_1(TALLOC_CTX *mem_ctx,
2484                                 struct samr_UserInfo1 *r,
2485                                 struct samu *pw,
2486                                 struct dom_sid *domain_sid)
2487 {
2488         const struct dom_sid *sid_group;
2489         uint32_t primary_gid;
2490
2491         become_root();
2492         sid_group = pdb_get_group_sid(pw);
2493         unbecome_root();
2494
2495         if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2496                 struct dom_sid_buf buf1, buf2;
2497
2498                 DEBUG(0, ("get_user_info_1: User %s has Primary Group SID %s, \n"
2499                           "which conflicts with the domain sid %s.  Failing operation.\n",
2500                           pdb_get_username(pw),
2501                           dom_sid_str_buf(sid_group, &buf1),
2502                           dom_sid_str_buf(domain_sid, &buf2)));
2503                 return NT_STATUS_UNSUCCESSFUL;
2504         }
2505
2506         r->account_name.string          = talloc_strdup(mem_ctx, pdb_get_username(pw));
2507         r->full_name.string             = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2508         r->primary_gid                  = primary_gid;
2509         r->description.string           = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2510         r->comment.string               = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2511
2512         return NT_STATUS_OK;
2513 }
2514
2515 /*************************************************************************
2516  get_user_info_2.
2517  *************************************************************************/
2518
2519 static NTSTATUS get_user_info_2(TALLOC_CTX *mem_ctx,
2520                                 struct samr_UserInfo2 *r,
2521                                 struct samu *pw)
2522 {
2523         r->comment.string               = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2524         r->reserved.string              = NULL;
2525         r->country_code                 = pdb_get_country_code(pw);
2526         r->code_page                    = pdb_get_code_page(pw);
2527
2528         return NT_STATUS_OK;
2529 }
2530
2531 /*************************************************************************
2532  get_user_info_3.
2533  *************************************************************************/
2534
2535 static NTSTATUS get_user_info_3(TALLOC_CTX *mem_ctx,
2536                                 struct samr_UserInfo3 *r,
2537                                 struct samu *pw,
2538                                 struct dom_sid *domain_sid)
2539 {
2540         const struct dom_sid *sid_user, *sid_group;
2541         uint32_t rid, primary_gid;
2542         struct dom_sid_buf buf1, buf2;
2543
2544         sid_user = pdb_get_user_sid(pw);
2545
2546         if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2547                 DEBUG(0, ("get_user_info_3: User %s has SID %s, \nwhich conflicts with "
2548                           "the domain sid %s.  Failing operation.\n",
2549                           pdb_get_username(pw),
2550                           dom_sid_str_buf(sid_user, &buf1),
2551                           dom_sid_str_buf(domain_sid, &buf2)));
2552                 return NT_STATUS_UNSUCCESSFUL;
2553         }
2554
2555         become_root();
2556         sid_group = pdb_get_group_sid(pw);
2557         unbecome_root();
2558
2559         if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2560                 DEBUG(0, ("get_user_info_3: User %s has Primary Group SID %s, \n"
2561                           "which conflicts with the domain sid %s.  Failing operation.\n",
2562                           pdb_get_username(pw),
2563                           dom_sid_str_buf(sid_group, &buf1),
2564                           dom_sid_str_buf(domain_sid, &buf2)));
2565                 return NT_STATUS_UNSUCCESSFUL;
2566         }
2567
2568         unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2569         unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2570         unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2571         unix_to_nt_time(&r->allow_password_change, pdb_get_pass_can_change_time(pw));
2572         unix_to_nt_time(&r->force_password_change, pdb_get_pass_must_change_time(pw));
2573
2574         r->account_name.string  = talloc_strdup(mem_ctx, pdb_get_username(pw));
2575         r->full_name.string     = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2576         r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2577         r->home_drive.string    = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2578         r->logon_script.string  = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2579         r->profile_path.string  = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2580         r->workstations.string  = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2581
2582         r->logon_hours          = get_logon_hours_from_pdb(mem_ctx, pw);
2583         r->rid                  = rid;
2584         r->primary_gid          = primary_gid;
2585         r->acct_flags           = pdb_get_acct_ctrl(pw);
2586         r->bad_password_count   = pdb_get_bad_password_count(pw);
2587         r->logon_count          = pdb_get_logon_count(pw);
2588
2589         return NT_STATUS_OK;
2590 }
2591
2592 /*************************************************************************
2593  get_user_info_4.
2594  *************************************************************************/
2595
2596 static NTSTATUS get_user_info_4(TALLOC_CTX *mem_ctx,
2597                                 struct samr_UserInfo4 *r,
2598                                 struct samu *pw)
2599 {
2600         r->logon_hours          = get_logon_hours_from_pdb(mem_ctx, pw);
2601
2602         return NT_STATUS_OK;
2603 }
2604
2605 /*************************************************************************
2606  get_user_info_5.
2607  *************************************************************************/
2608
2609 static NTSTATUS get_user_info_5(TALLOC_CTX *mem_ctx,
2610                                 struct samr_UserInfo5 *r,
2611                                 struct samu *pw,
2612                                 struct dom_sid *domain_sid)
2613 {
2614         const struct dom_sid *sid_user, *sid_group;
2615         uint32_t rid, primary_gid;
2616         struct dom_sid_buf buf1, buf2;
2617
2618         sid_user = pdb_get_user_sid(pw);
2619
2620         if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2621                 DEBUG(0, ("get_user_info_5: User %s has SID %s, \nwhich conflicts with "
2622                           "the domain sid %s.  Failing operation.\n",
2623                           pdb_get_username(pw),
2624                           dom_sid_str_buf(sid_user, &buf1),
2625                           dom_sid_str_buf(domain_sid, &buf2)));
2626                 return NT_STATUS_UNSUCCESSFUL;
2627         }
2628
2629         become_root();
2630         sid_group = pdb_get_group_sid(pw);
2631         unbecome_root();
2632
2633         if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2634                 DEBUG(0, ("get_user_info_5: User %s has Primary Group SID %s, \n"
2635                           "which conflicts with the domain sid %s.  Failing operation.\n",
2636                           pdb_get_username(pw),
2637                           dom_sid_str_buf(sid_group, &buf1),
2638                           dom_sid_str_buf(domain_sid, &buf2)));
2639                 return NT_STATUS_UNSUCCESSFUL;
2640         }
2641
2642         unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2643         unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2644         unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2645         unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2646
2647         r->account_name.string  = talloc_strdup(mem_ctx, pdb_get_username(pw));
2648         r->full_name.string     = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2649         r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2650         r->home_drive.string    = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2651         r->logon_script.string  = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2652         r->profile_path.string  = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2653         r->description.string   = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2654         r->workstations.string  = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2655
2656         r->logon_hours          = get_logon_hours_from_pdb(mem_ctx, pw);
2657         r->rid                  = rid;
2658         r->primary_gid          = primary_gid;
2659         r->acct_flags           = pdb_get_acct_ctrl(pw);
2660         r->bad_password_count   = pdb_get_bad_password_count(pw);
2661         r->logon_count          = pdb_get_logon_count(pw);
2662
2663         return NT_STATUS_OK;
2664 }
2665
2666 /*************************************************************************
2667  get_user_info_6.
2668  *************************************************************************/
2669
2670 static NTSTATUS get_user_info_6(TALLOC_CTX *mem_ctx,
2671                                 struct samr_UserInfo6 *r,
2672                                 struct samu *pw)
2673 {
2674         r->account_name.string  = talloc_strdup(mem_ctx, pdb_get_username(pw));
2675         r->full_name.string     = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2676
2677         return NT_STATUS_OK;
2678 }
2679
2680 /*************************************************************************
2681  get_user_info_7. Safe. Only gives out account_name.
2682  *************************************************************************/
2683
2684 static NTSTATUS get_user_info_7(TALLOC_CTX *mem_ctx,
2685                                 struct samr_UserInfo7 *r,
2686                                 struct samu *smbpass)
2687 {
2688         r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(smbpass));
2689         if (!r->account_name.string) {
2690                 return NT_STATUS_NO_MEMORY;
2691         }
2692
2693         return NT_STATUS_OK;
2694 }
2695
2696 /*************************************************************************
2697  get_user_info_8.
2698  *************************************************************************/
2699
2700 static NTSTATUS get_user_info_8(TALLOC_CTX *mem_ctx,
2701                                 struct samr_UserInfo8 *r,
2702                                 struct samu *pw)
2703 {
2704         r->full_name.string     = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2705
2706         return NT_STATUS_OK;
2707 }
2708
2709 /*************************************************************************
2710  get_user_info_9. Only gives out primary group SID.
2711  *************************************************************************/
2712
2713 static NTSTATUS get_user_info_9(TALLOC_CTX *mem_ctx,
2714                                 struct samr_UserInfo9 *r,
2715                                 struct samu *smbpass)
2716 {
2717         r->primary_gid = pdb_get_group_rid(smbpass);
2718
2719         return NT_STATUS_OK;
2720 }
2721
2722 /*************************************************************************
2723  get_user_info_10.
2724  *************************************************************************/
2725
2726 static NTSTATUS get_user_info_10(TALLOC_CTX *mem_ctx,
2727                                  struct samr_UserInfo10 *r,
2728                                  struct samu *pw)
2729 {
2730         r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2731         r->home_drive.string    = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2732
2733         return NT_STATUS_OK;
2734 }
2735
2736 /*************************************************************************
2737  get_user_info_11.
2738  *************************************************************************/
2739
2740 static NTSTATUS get_user_info_11(TALLOC_CTX *mem_ctx,
2741                                  struct samr_UserInfo11 *r,
2742                                  struct samu *pw)
2743 {
2744         r->logon_script.string  = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2745
2746         return NT_STATUS_OK;
2747 }
2748
2749 /*************************************************************************
2750  get_user_info_12.
2751  *************************************************************************/
2752
2753 static NTSTATUS get_user_info_12(TALLOC_CTX *mem_ctx,
2754                                  struct samr_UserInfo12 *r,
2755                                  struct samu *pw)
2756 {
2757         r->profile_path.string  = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2758
2759         return NT_STATUS_OK;
2760 }
2761
2762 /*************************************************************************
2763  get_user_info_13.
2764  *************************************************************************/
2765
2766 static NTSTATUS get_user_info_13(TALLOC_CTX *mem_ctx,
2767                                  struct samr_UserInfo13 *r,
2768                                  struct samu *pw)
2769 {
2770         r->description.string   = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2771
2772         return NT_STATUS_OK;
2773 }
2774
2775 /*************************************************************************
2776  get_user_info_14.
2777  *************************************************************************/
2778
2779 static NTSTATUS get_user_info_14(TALLOC_CTX *mem_ctx,
2780                                  struct samr_UserInfo14 *r,
2781                                  struct samu *pw)
2782 {
2783         r->workstations.string  = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2784
2785         return NT_STATUS_OK;
2786 }
2787
2788 /*************************************************************************
2789  get_user_info_16. Safe. Only gives out acb bits.
2790  *************************************************************************/
2791
2792 static NTSTATUS get_user_info_16(TALLOC_CTX *mem_ctx,
2793                                  struct samr_UserInfo16 *r,
2794                                  struct samu *smbpass)
2795 {
2796         r->acct_flags = pdb_get_acct_ctrl(smbpass);
2797
2798         return NT_STATUS_OK;
2799 }
2800
2801 /*************************************************************************
2802  get_user_info_17.
2803  *************************************************************************/
2804
2805 static NTSTATUS get_user_info_17(TALLOC_CTX *mem_ctx,
2806                                  struct samr_UserInfo17 *r,
2807                                  struct samu *pw)
2808 {
2809         unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2810
2811         return NT_STATUS_OK;
2812 }
2813
2814 /*************************************************************************
2815  get_user_info_18. OK - this is the killer as it gives out password info.
2816  Ensure that this is only allowed on an encrypted connection with a root
2817  user. JRA.
2818  *************************************************************************/
2819
2820 static NTSTATUS get_user_info_18(struct pipes_struct *p,
2821                                  TALLOC_CTX *mem_ctx,
2822                                  struct samr_UserInfo18 *r,
2823                                  struct dom_sid *user_sid)
2824 {
2825         struct dcesrv_call_state *dce_call = p->dce_call;
2826         struct auth_session_info *session_info =
2827                 dcesrv_call_session_info(dce_call);
2828         struct samu *smbpass=NULL;
2829         bool ret;
2830         const uint8_t *nt_pass = NULL;
2831         const uint8_t *lm_pass = NULL;
2832
2833         ZERO_STRUCTP(r);
2834
2835         if (p->transport != NCALRPC) {
2836                 return NT_STATUS_INVALID_INFO_CLASS;
2837         }
2838
2839         if (!security_token_is_system(session_info->security_token)) {
2840                 return NT_STATUS_ACCESS_DENIED;
2841         }
2842
2843         /*
2844          * Do *NOT* do become_root()/unbecome_root() here ! JRA.
2845          */
2846
2847         if ( !(smbpass = samu_new( mem_ctx )) ) {
2848                 return NT_STATUS_NO_MEMORY;
2849         }
2850
2851         ret = pdb_getsampwsid(smbpass, user_sid);
2852
2853         if (ret == False) {
2854                 struct dom_sid_buf buf;
2855                 DEBUG(4, ("User %s not found\n",
2856                           dom_sid_str_buf(user_sid, &buf)));
2857                 TALLOC_FREE(smbpass);
2858                 return root_mode() ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
2859         }
2860
2861         DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
2862
2863         if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
2864                 TALLOC_FREE(smbpass);
2865                 return NT_STATUS_ACCOUNT_DISABLED;
2866         }
2867
2868         lm_pass = pdb_get_lanman_passwd(smbpass);
2869         if (lm_pass != NULL) {
2870                 memcpy(r->lm_pwd.hash, lm_pass, 16);
2871                 r->lm_pwd_active = true;
2872         }
2873
2874         nt_pass = pdb_get_nt_passwd(smbpass);
2875         if (nt_pass != NULL) {
2876                 memcpy(r->nt_pwd.hash, nt_pass, 16);
2877                 r->nt_pwd_active = true;
2878         }
2879         r->password_expired = 0; /* FIXME */
2880
2881         TALLOC_FREE(smbpass);
2882
2883         return NT_STATUS_OK;
2884 }
2885
2886 /*************************************************************************
2887  get_user_info_20
2888  *************************************************************************/
2889
2890 static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx,
2891                                  struct samr_UserInfo20 *r,
2892                                  struct samu *sampass)
2893 {
2894         const char *munged_dial = NULL;
2895         DATA_BLOB blob;
2896         NTSTATUS status;
2897         struct lsa_BinaryString *parameters = NULL;
2898
2899         ZERO_STRUCTP(r);
2900
2901         munged_dial = pdb_get_munged_dial(sampass);
2902
2903         DEBUG(3,("User:[%s] has [%s] (length: %d)\n", pdb_get_username(sampass),
2904                 munged_dial, (int)strlen(munged_dial)));
2905
2906         if (munged_dial) {
2907                 blob = base64_decode_data_blob(munged_dial);
2908         } else {
2909                 blob = data_blob_string_const_null("");
2910         }
2911
2912         status = init_samr_parameters_string(mem_ctx, &blob, &parameters);
2913         data_blob_free(&blob);
2914         if (!NT_STATUS_IS_OK(status)) {
2915                 return status;
2916         }
2917
2918         r->parameters = *parameters;
2919
2920         return NT_STATUS_OK;
2921 }
2922
2923
2924 /*************************************************************************
2925  get_user_info_21
2926  *************************************************************************/
2927
2928 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx,
2929                                  struct samr_UserInfo21 *r,
2930                                  struct samu *pw,
2931                                  struct dom_sid *domain_sid,
2932                                  uint32_t acc_granted)
2933 {
2934         NTSTATUS status;
2935         const struct dom_sid *sid_user, *sid_group;
2936         uint32_t rid, primary_gid;
2937         NTTIME force_password_change;
2938         time_t must_change_time;
2939         struct lsa_BinaryString *parameters = NULL;
2940         const char *munged_dial = NULL;
2941         DATA_BLOB blob;
2942         struct dom_sid_buf buf1, buf2;
2943
2944         ZERO_STRUCTP(r);
2945
2946         sid_user = pdb_get_user_sid(pw);
2947
2948         if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2949                 DEBUG(0, ("get_user_info_21: User %s has SID %s, \nwhich conflicts with "
2950                           "the domain sid %s.  Failing operation.\n",
2951                           pdb_get_username(pw),
2952                           dom_sid_str_buf(sid_user, &buf1),
2953                           dom_sid_str_buf(domain_sid, &buf2)));
2954                 return NT_STATUS_UNSUCCESSFUL;
2955         }
2956
2957         become_root();
2958         sid_group = pdb_get_group_sid(pw);
2959         unbecome_root();
2960
2961         if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2962                 DEBUG(0, ("get_user_info_21: User %s has Primary Group SID %s, \n"
2963                           "which conflicts with the domain sid %s.  Failing operation.\n",
2964                           pdb_get_username(pw),
2965                           dom_sid_str_buf(sid_group, &buf1),
2966                           dom_sid_str_buf(domain_sid, &buf2)));
2967                 return NT_STATUS_UNSUCCESSFUL;
2968         }
2969
2970         unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2971         unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2972         unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2973         unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2974         unix_to_nt_time(&r->allow_password_change, pdb_get_pass_can_change_time(pw));
2975
2976         must_change_time = pdb_get_pass_must_change_time(pw);
2977         if (pdb_is_password_change_time_max(must_change_time)) {
2978                 unix_to_nt_time_abs(&force_password_change, must_change_time);
2979         } else {
2980                 unix_to_nt_time(&force_password_change, must_change_time);
2981         }
2982
2983         munged_dial = pdb_get_munged_dial(pw);
2984         if (munged_dial) {
2985                 blob = base64_decode_data_blob(munged_dial);
2986         } else {
2987                 blob = data_blob_string_const_null("");
2988         }
2989
2990         status = init_samr_parameters_string(mem_ctx, &blob, &parameters);
2991         data_blob_free(&blob);
2992         if (!NT_STATUS_IS_OK(status)) {
2993                 return status;
2994         }
2995
2996         r->force_password_change        = force_password_change;
2997
2998         r->account_name.string          = talloc_strdup(mem_ctx, pdb_get_username(pw));
2999         r->full_name.string             = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
3000         r->home_directory.string        = talloc_strdup(mem_ctx, pdb_get_homedir(pw));
3001         r->home_drive.string            = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
3002         r->logon_script.string          = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
3003         r->profile_path.string          = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
3004         r->description.string           = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
3005         r->workstations.string          = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
3006         r->comment.string               = talloc_strdup(mem_ctx, pdb_get_comment(pw));
3007
3008         r->logon_hours                  = get_logon_hours_from_pdb(mem_ctx, pw);
3009         r->parameters                   = *parameters;
3010         r->rid                          = rid;
3011         r->primary_gid                  = primary_gid;
3012         r->acct_flags                   = pdb_get_acct_ctrl(pw);
3013         r->bad_password_count           = pdb_get_bad_password_count(pw);
3014         r->logon_count                  = pdb_get_logon_count(pw);
3015         r->fields_present               = pdb_build_fields_present(pw);
3016         r->password_expired             = (pdb_get_pass_must_change_time(pw) == 0) ?
3017                                                 PASS_MUST_CHANGE_AT_NEXT_LOGON : 0;
3018         r->country_code                 = pdb_get_country_code(pw);
3019         r->code_page                    = pdb_get_code_page(pw);
3020         r->lm_password_set              = 0;
3021         r->nt_password_set              = 0;
3022
3023 #if 0
3024
3025         /*
3026           Look at a user on a real NT4 PDC with usrmgr, press
3027           'ok'. Then you will see that fields_present is set to
3028           0x08f827fa. Look at the user immediately after that again,
3029           and you will see that 0x00fffff is returned. This solves
3030           the problem that you get access denied after having looked
3031           at the user.
3032           -- Volker
3033         */
3034
3035 #endif
3036
3037
3038         return NT_STATUS_OK;
3039 }
3040
3041 /*******************************************************************
3042  _samr_QueryUserInfo
3043  ********************************************************************/
3044
3045 NTSTATUS _samr_QueryUserInfo(struct pipes_struct *p,
3046                              struct samr_QueryUserInfo *r)
3047 {
3048         NTSTATUS status;
3049         union samr_UserInfo *user_info = NULL;
3050         struct samr_info *uinfo;
3051         struct dom_sid domain_sid;
3052         uint32_t rid;
3053         bool ret = false;
3054         struct samu *pwd = NULL;
3055         uint32_t acc_required, acc_granted;
3056         struct dom_sid_buf buf;
3057
3058         switch (r->in.level) {
3059         case 1: /* UserGeneralInformation */
3060                 /* USER_READ_GENERAL */
3061                 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC;
3062                 break;
3063         case 2: /* UserPreferencesInformation */
3064                 /* USER_READ_PREFERENCES | USER_READ_GENERAL */
3065                 acc_required = SAMR_USER_ACCESS_GET_LOCALE |
3066                                SAMR_USER_ACCESS_GET_NAME_ETC;
3067                 break;
3068         case 3: /* UserLogonInformation */
3069                 /* USER_READ_GENERAL | USER_READ_PREFERENCES | USER_READ_LOGON | USER_READ_ACCOUNT */
3070                 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC |
3071                                SAMR_USER_ACCESS_GET_LOCALE |
3072                                SAMR_USER_ACCESS_GET_LOGONINFO |
3073                                SAMR_USER_ACCESS_GET_ATTRIBUTES;
3074                 break;
3075         case 4: /* UserLogonHoursInformation */
3076                 /* USER_READ_LOGON */
3077                 acc_required = SAMR_USER_ACCESS_GET_LOGONINFO;
3078                 break;
3079         case 5: /* UserAccountInformation */
3080                 /* USER_READ_GENERAL | USER_READ_PREFERENCES | USER_READ_LOGON | USER_READ_ACCOUNT */
3081                 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC |
3082                                SAMR_USER_ACCESS_GET_LOCALE |
3083                                SAMR_USER_ACCESS_GET_LOGONINFO |
3084                                SAMR_USER_ACCESS_GET_ATTRIBUTES;
3085                 break;
3086         case 6: /* UserNameInformation */
3087         case 7: /* UserAccountNameInformation */
3088         case 8: /* UserFullNameInformation */
3089         case 9: /* UserPrimaryGroupInformation */
3090         case 13: /* UserAdminCommentInformation */
3091                 /* USER_READ_GENERAL */
3092                 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC;
3093                 break;
3094         case 10: /* UserHomeInformation */
3095         case 11: /* UserScriptInformation */
3096         case 12: /* UserProfileInformation */
3097         case 14: /* UserWorkStationsInformation */
3098                 /* USER_READ_LOGON */
3099                 acc_required = SAMR_USER_ACCESS_GET_LOGONINFO;
3100                 break;
3101         case 16: /* UserControlInformation */
3102         case 17: /* UserExpiresInformation */
3103         case 20: /* UserParametersInformation */
3104                 /* USER_READ_ACCOUNT */
3105                 acc_required = SAMR_USER_ACCESS_GET_ATTRIBUTES;
3106                 break;
3107         case 21: /* UserAllInformation */
3108                 /* FIXME! - gd */
3109                 acc_required = SAMR_USER_ACCESS_GET_ATTRIBUTES;
3110                 break;
3111         case 18: /* UserInternal1Information */
3112                 /* FIXME! - gd */
3113                 acc_required = SAMR_USER_ACCESS_GET_ATTRIBUTES;
3114                 break;
3115         case 23: /* UserInternal4Information */
3116         case 24: /* UserInternal4InformationNew */
3117         case 25: /* UserInternal4InformationNew */
3118         case 26: /* UserInternal5InformationNew */
3119         default:
3120                 return NT_STATUS_INVALID_INFO_CLASS;
3121                 break;
3122         }
3123
3124         uinfo = samr_policy_handle_find(p,
3125                                         r->in.user_handle,
3126                                         SAMR_HANDLE_USER,
3127                                         acc_required,
3128                                         &acc_granted,
3129                                         &status);
3130         if (!NT_STATUS_IS_OK(status)) {
3131                 return status;
3132         }
3133
3134         domain_sid = uinfo->sid;
3135
3136         sid_split_rid(&domain_sid, &rid);
3137
3138         if (!sid_check_is_in_our_sam(&uinfo->sid))
3139                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
3140
3141         DEBUG(5,("_samr_QueryUserInfo: sid:%s\n",
3142                  dom_sid_str_buf(&uinfo->sid, &buf)));
3143
3144         user_info = talloc_zero(p->mem_ctx, union samr_UserInfo);
3145         if (!user_info) {
3146                 return NT_STATUS_NO_MEMORY;
3147         }
3148
3149         DEBUG(5,("_samr_QueryUserInfo: user info level: %d\n", r->in.level));
3150
3151         if (!(pwd = samu_new(p->mem_ctx))) {
3152                 return NT_STATUS_NO_MEMORY;
3153         }
3154
3155         become_root();
3156         ret = pdb_getsampwsid(pwd, &uinfo->sid);
3157         unbecome_root();
3158
3159         if (ret == false) {
3160                 DEBUG(4,("User %s not found\n",
3161                          dom_sid_str_buf(&uinfo->sid, &buf)));
3162                 TALLOC_FREE(pwd);
3163                 return NT_STATUS_NO_SUCH_USER;
3164         }
3165
3166         DEBUG(3,("User:[%s]\n", pdb_get_username(pwd)));
3167
3168         samr_clear_sam_passwd(pwd);
3169
3170         switch (r->in.level) {
3171         case 1:
3172                 status = get_user_info_1(p->mem_ctx, &user_info->info1, pwd, &domain_sid);
3173                 break;
3174         case 2:
3175                 status = get_user_info_2(p->mem_ctx, &user_info->info2, pwd);
3176                 break;
3177         case 3:
3178                 status = get_user_info_3(p->mem_ctx, &user_info->info3, pwd, &domain_sid);
3179                 break;
3180         case 4:
3181                 status = get_user_info_4(p->mem_ctx, &user_info->info4, pwd);
3182                 break;
3183         case 5:
3184                 status = get_user_info_5(p->mem_ctx, &user_info->info5, pwd, &domain_sid);
3185                 break;
3186         case 6:
3187                 status = get_user_info_6(p->mem_ctx, &user_info->info6, pwd);
3188                 break;
3189         case 7:
3190                 status = get_user_info_7(p->mem_ctx, &user_info->info7, pwd);
3191                 break;
3192         case 8:
3193                 status = get_user_info_8(p->mem_ctx, &user_info->info8, pwd);
3194                 break;
3195         case 9:
3196                 status = get_user_info_9(p->mem_ctx, &user_info->info9, pwd);
3197                 break;
3198         case 10:
3199                 status = get_user_info_10(p->mem_ctx, &user_info->info10, pwd);
3200                 break;
3201         case 11:
3202                 status = get_user_info_11(p->mem_ctx, &user_info->info11, pwd);
3203                 break;
3204         case 12:
3205                 status = get_user_info_12(p->mem_ctx, &user_info->info12, pwd);
3206                 break;
3207         case 13:
3208                 status = get_user_info_13(p->mem_ctx, &user_info->info13, pwd);
3209                 break;
3210         case 14:
3211                 status = get_user_info_14(p->mem_ctx, &user_info->info14, pwd);
3212                 break;
3213         case 16:
3214                 status = get_user_info_16(p->mem_ctx, &user_info->info16, pwd);
3215                 break;
3216         case 17:
3217                 status = get_user_info_17(p->mem_ctx, &user_info->info17, pwd);
3218                 break;
3219         case 18:
3220                 /* level 18 is special */
3221                 status = get_user_info_18(p, p->mem_ctx, &user_info->info18,
3222                                           &uinfo->sid);
3223                 break;
3224         case 20:
3225                 status = get_user_info_20(p->mem_ctx, &user_info->info20, pwd);
3226                 break;
3227         case 21:
3228                 status = get_user_info_21(p->mem_ctx, &user_info->info21, pwd, &domain_sid, acc_granted);
3229                 break;
3230         default:
3231                 status = NT_STATUS_INVALID_INFO_CLASS;
3232                 break;
3233         }
3234
3235         if (!NT_STATUS_IS_OK(status)) {
3236                 goto done;
3237         }
3238
3239         *r->out.info = user_info;
3240
3241  done:
3242         TALLOC_FREE(pwd);
3243
3244         DEBUG(5,("_samr_QueryUserInfo: %d\n", __LINE__));
3245
3246         return status;
3247 }
3248
3249 /****************************************************************
3250 ****************************************************************/
3251
3252 NTSTATUS _samr_QueryUserInfo2(struct pipes_struct *p,
3253                               struct samr_QueryUserInfo2 *r)
3254 {
3255         struct samr_QueryUserInfo u;
3256
3257         u.in.user_handle        = r->in.user_handle;
3258         u.in.level              = r->in.level;
3259         u.out.info              = r->out.info;
3260
3261         return _samr_QueryUserInfo(p, &u);
3262 }
3263
3264 /*******************************************************************
3265  _samr_GetGroupsForUser
3266  ********************************************************************/
3267
3268 NTSTATUS _samr_GetGroupsForUser(struct pipes_struct *p,
3269                                 struct samr_GetGroupsForUser *r)
3270 {
3271         struct samr_info *uinfo;
3272         struct samu *sam_pass=NULL;
3273         struct dom_sid *sids;
3274         struct samr_RidWithAttribute dom_gid;
3275         struct samr_RidWithAttribute *gids = NULL;
3276         uint32_t primary_group_rid;
3277         uint32_t num_groups = 0;
3278         gid_t *unix_gids;
3279         uint32_t i, num_gids;
3280         bool ret;
3281         NTSTATUS result;
3282         bool success = False;
3283         struct dom_sid_buf buf;
3284
3285         struct samr_RidWithAttributeArray *rids = NULL;
3286
3287         /*
3288          * from the SID in the request:
3289          * we should send back the list of DOMAIN GROUPS
3290          * the user is a member of
3291          *
3292          * and only the DOMAIN GROUPS
3293          * no ALIASES !!! neither aliases of the domain
3294          * nor aliases of the builtin SID
3295          *
3296          * JFM, 12/2/2001
3297          */
3298
3299         DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
3300
3301         uinfo = samr_policy_handle_find(p,
3302                                         r->in.user_handle,
3303                                         SAMR_HANDLE_USER,
3304                                         SAMR_USER_ACCESS_GET_GROUPS,
3305                                         NULL,
3306                                         &result);
3307         if (!NT_STATUS_IS_OK(result)) {
3308                 return result;
3309         }
3310
3311         rids = talloc_zero(p->mem_ctx, struct samr_RidWithAttributeArray);
3312         if (!rids) {
3313                 return NT_STATUS_NO_MEMORY;
3314         }
3315
3316         if (!sid_check_is_in_our_sam(&uinfo->sid))
3317                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
3318
3319         if ( !(sam_pass = samu_new( p->mem_ctx )) ) {
3320                 return NT_STATUS_NO_MEMORY;
3321         }
3322
3323         become_root();
3324         ret = pdb_getsampwsid(sam_pass, &uinfo->sid);
3325         unbecome_root();
3326
3327         if (!ret) {
3328                 DEBUG(10, ("pdb_getsampwsid failed for %s\n",
3329                            dom_sid_str_buf(&uinfo->sid, &buf)));
3330                 return NT_STATUS_NO_SUCH_USER;
3331         }
3332
3333         sids = NULL;
3334
3335         /* make both calls inside the root block */
3336         become_root();
3337         result = pdb_enum_group_memberships(p->mem_ctx, sam_pass,
3338                                             &sids, &unix_gids, &num_groups);
3339         if ( NT_STATUS_IS_OK(result) ) {
3340                 success = sid_peek_check_rid(get_global_sam_sid(),
3341                                              pdb_get_group_sid(sam_pass),
3342                                              &primary_group_rid);
3343         }
3344         unbecome_root();
3345
3346         if (!NT_STATUS_IS_OK(result)) {
3347                 DEBUG(10, ("pdb_enum_group_memberships failed for %s\n",
3348                            dom_sid_str_buf(&uinfo->sid, &buf)));
3349                 return result;
3350         }
3351
3352         if ( !success ) {
3353                 DEBUG(5, ("Group sid %s for user %s not in our domain\n",
3354                           dom_sid_str_buf(pdb_get_group_sid(sam_pass), &buf),
3355                           pdb_get_username(sam_pass)));
3356                 TALLOC_FREE(sam_pass);
3357                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
3358         }
3359
3360         gids = NULL;
3361         num_gids = 0;
3362
3363         dom_gid.attributes = (SE_GROUP_MANDATORY|SE_GROUP_ENABLED_BY_DEFAULT|
3364                               SE_GROUP_ENABLED);
3365         dom_gid.rid = primary_group_rid;
3366         ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
3367
3368         for (i=0; i<num_groups; i++) {
3369
3370                 if (!sid_peek_check_rid(get_global_sam_sid(),
3371                                         &(sids[i]), &dom_gid.rid)) {
3372                         DEBUG(10, ("Found sid %s not in our domain\n",
3373                                    dom_sid_str_buf(&sids[i], &buf)));
3374                         continue;
3375                 }
3376
3377                 if (dom_gid.rid == primary_group_rid) {
3378                         /* We added the primary group directly from the
3379                          * sam_account. The other SIDs are unique from
3380                          * enum_group_memberships */
3381                         continue;
3382                 }
3383
3384                 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
3385         }
3386
3387         rids->count = num_gids;
3388         rids->rids = gids;
3389
3390         *r->out.rids = rids;
3391
3392         DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
3393
3394         return result;
3395 }
3396
3397 /*******************************************************************
3398  ********************************************************************/
3399
3400 static uint32_t samr_get_server_role(void)
3401 {
3402         uint32_t role = ROLE_DOMAIN_PDC;
3403
3404         if (lp_server_role() == ROLE_DOMAIN_BDC) {
3405                 role = ROLE_DOMAIN_BDC;
3406         }
3407
3408         return role;
3409 }
3410
3411 /*******************************************************************
3412  ********************************************************************/
3413
3414 static NTSTATUS query_dom_info_1(TALLOC_CTX *mem_ctx,
3415                                  struct samr_DomInfo1 *r)
3416 {
3417         const struct loadparm_substitution *lp_sub =
3418                 loadparm_s3_global_substitution();
3419         uint32_t account_policy_temp;
3420         time_t u_expire, u_min_age;
3421
3422         become_root();
3423
3424         /* AS ROOT !!! */
3425
3426         pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN, &account_policy_temp);
3427         r->min_password_length = account_policy_temp;
3428
3429         pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &account_policy_temp);
3430         r->password_history_length = account_policy_temp;
3431
3432         pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
3433                                &r->password_properties);
3434
3435         pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, &account_policy_temp);
3436         u_expire = account_policy_temp;
3437
3438         pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, &account_policy_temp);
3439         u_min_age = account_policy_temp;
3440
3441         /* !AS ROOT */
3442
3443         unbecome_root();
3444
3445         unix_to_nt_time_abs((NTTIME *)&r->max_password_age, u_expire);
3446         unix_to_nt_time_abs((NTTIME *)&r->min_password_age, u_min_age);
3447
3448         if (lp_check_password_script(talloc_tos(), lp_sub) && *lp_check_password_script(talloc_tos(), lp_sub)){
3449                 r->password_properties |= DOMAIN_PASSWORD_COMPLEX;
3450         }
3451
3452         return NT_STATUS_OK;
3453 }
3454
3455 /*******************************************************************
3456  ********************************************************************/
3457
3458 static NTSTATUS query_dom_info_2(TALLOC_CTX *mem_ctx,
3459                                  struct samr_DomGeneralInformation *r,
3460                                  struct samr_info *dinfo)
3461 {
3462         const struct loadparm_substitution *lp_sub =
3463                 loadparm_s3_global_substitution();
3464         uint32_t u_logout;
3465         time_t seq_num;
3466
3467         become_root();
3468
3469         /* AS ROOT !!! */
3470
3471         r->num_users    = count_sam_users(dinfo->disp_info, ACB_NORMAL);
3472         r->num_groups   = count_sam_groups(dinfo->disp_info);
3473         r->num_aliases  = count_sam_aliases(dinfo->disp_info);
3474
3475         pdb_get_account_policy(PDB_POLICY_TIME_TO_LOGOUT, &u_logout);
3476
3477         unix_to_nt_time_abs(&r->force_logoff_time, u_logout);
3478
3479         if (!pdb_get_seq_num(&seq_num)) {
3480                 seq_num = time(NULL);
3481         }
3482
3483         /* !AS ROOT */
3484
3485         unbecome_root();
3486
3487         r->oem_information.string       = lp_server_string(r, lp_sub);
3488         r->domain_name.string           = lp_workgroup();
3489         r->primary.string               = lp_netbios_name();
3490         r->sequence_num                 = seq_num;
3491         r->domain_server_state          = DOMAIN_SERVER_ENABLED;
3492         r->role                         = (enum samr_Role) samr_get_server_role();
3493         r->unknown3                     = 1;
3494
3495         return NT_STATUS_OK;
3496 }
3497
3498 /*******************************************************************
3499  ********************************************************************/
3500
3501 static NTSTATUS query_dom_info_3(TALLOC_CTX *mem_ctx,
3502                                  struct samr_DomInfo3 *r)
3503 {
3504         uint32_t u_logout;
3505
3506         become_root();
3507
3508         /* AS ROOT !!! */
3509
3510         {
3511                 uint32_t ul;
3512                 pdb_get_account_policy(PDB_POLICY_TIME_TO_LOGOUT, &ul);
3513                 u_logout = (time_t)ul;
3514         }
3515
3516         /* !AS ROOT */
3517
3518         unbecome_root();
3519
3520         unix_to_nt_time_abs(&r->force_logoff_time, u_logout);
3521
3522         return NT_STATUS_OK;
3523 }
3524
3525 /*******************************************************************
3526  ********************************************************************/
3527
3528 static NTSTATUS query_dom_info_4(TALLOC_CTX *mem_ctx,
3529                                  struct samr_DomOEMInformation *r)
3530 {
3531         const struct loadparm_substitution *lp_sub =
3532                 loadparm_s3_global_substitution();
3533
3534         r->oem_information.string = lp_server_string(r, lp_sub);
3535
3536         return NT_STATUS_OK;
3537 }
3538
3539 /*******************************************************************
3540  ********************************************************************/
3541
3542 static NTSTATUS query_dom_info_5(TALLOC_CTX *mem_ctx,
3543                                  struct samr_DomInfo5 *r)
3544 {
3545         r->domain_name.string = get_global_sam_name();
3546
3547         return NT_STATUS_OK;
3548 }
3549
3550 /*******************************************************************
3551  ********************************************************************/
3552
3553 static NTSTATUS query_dom_info_6(TALLOC_CTX *mem_ctx,
3554                                  struct samr_DomInfo6 *r)
3555 {
3556         /* NT returns its own name when a PDC. win2k and later
3557          * only the name of the PDC if itself is a BDC (samba4
3558          * idl) */
3559         r->primary.string = lp_netbios_name();
3560
3561         return NT_STATUS_OK;
3562 }
3563
3564 /*******************************************************************
3565  ********************************************************************/
3566
3567 static NTSTATUS query_dom_info_7(TALLOC_CTX *mem_ctx,
3568                                  struct samr_DomInfo7 *r)
3569 {
3570         r->role = (enum samr_Role) samr_get_server_role();
3571
3572         return NT_STATUS_OK;
3573 }
3574
3575 /*******************************************************************
3576  ********************************************************************/
3577
3578 static NTSTATUS query_dom_info_8(TALLOC_CTX *mem_ctx,
3579                                  struct samr_DomInfo8 *r)
3580 {
3581         time_t seq_num;
3582
3583         become_root();
3584
3585         /* AS ROOT !!! */
3586
3587         if (!pdb_get_seq_num(&seq_num)) {
3588                 seq_num = time(NULL);
3589         }
3590
3591         /* !AS ROOT */
3592
3593         unbecome_root();
3594
3595         r->sequence_num = seq_num;
3596         r->domain_create_time = 0;
3597
3598         return NT_STATUS_OK;
3599 }
3600
3601 /*******************************************************************
3602  ********************************************************************/
3603
3604 static NTSTATUS query_dom_info_9(TALLOC_CTX *mem_ctx,
3605                                  struct samr_DomInfo9 *r)
3606 {
3607         r->domain_server_state = DOMAIN_SERVER_ENABLED;
3608
3609         return NT_STATUS_OK;
3610 }
3611
3612 /*******************************************************************
3613  ********************************************************************/
3614
3615 static NTSTATUS query_dom_info_11(TALLOC_CTX *mem_ctx,
3616                                   struct samr_DomGeneralInformation2 *r,
3617                                   struct samr_info *dinfo)
3618 {
3619         NTSTATUS status;
3620         uint32_t account_policy_temp;
3621         time_t u_lock_duration, u_reset_time;
3622
3623         status = query_dom_info_2(mem_ctx, &r->general, dinfo);
3624         if (!NT_STATUS_IS_OK(status)) {
3625                 return status;
3626         }
3627
3628         /* AS ROOT !!! */
3629
3630         become_root();
3631
3632         pdb_get_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, &account_policy_temp);
3633         u_lock_duration = account_policy_temp;
3634         if (u_lock_duration != -1) {
3635                 u_lock_duration *= 60;
3636         }
3637
3638         pdb_get_account_policy(PDB_POLICY_RESET_COUNT_TIME, &account_policy_temp);
3639         u_reset_time = account_policy_temp * 60;
3640
3641         pdb_get_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
3642         r->lockout_threshold = account_policy_temp;
3643
3644         /* !AS ROOT */
3645
3646         unbecome_root();
3647
3648         unix_to_nt_time_abs(&r->lockout_duration, u_lock_duration);
3649         unix_to_nt_time_abs(&r->lockout_window, u_reset_time);
3650
3651         return NT_STATUS_OK;
3652 }
3653
3654 /*******************************************************************
3655  ********************************************************************/
3656
3657 static NTSTATUS query_dom_info_12(TALLOC_CTX *mem_ctx,
3658                                   struct samr_DomInfo12 *r)
3659 {
3660         uint32_t account_policy_temp;
3661         time_t u_lock_duration, u_reset_time;
3662
3663         become_root();
3664
3665         /* AS ROOT !!! */
3666
3667         pdb_get_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, &account_policy_temp);
3668         u_lock_duration = account_policy_temp;
3669         if (u_lock_duration != -1) {
3670                 u_lock_duration *= 60;
3671         }
3672
3673         pdb_get_account_policy(PDB_POLICY_RESET_COUNT_TIME, &account_policy_temp);
3674         u_reset_time = account_policy_temp * 60;
3675
3676         pdb_get_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
3677         r->lockout_threshold = account_policy_temp;
3678
3679         /* !AS ROOT */
3680
3681         unbecome_root();
3682
3683         unix_to_nt_time_abs(&r->lockout_duration, u_lock_duration);
3684         unix_to_nt_time_abs(&r->lockout_window, u_reset_time);
3685
3686         return NT_STATUS_OK;
3687 }
3688
3689 /*******************************************************************
3690  ********************************************************************/
3691
3692 static NTSTATUS query_dom_info_13(TALLOC_CTX *mem_ctx,
3693                                   struct samr_DomInfo13 *r)
3694 {
3695         time_t seq_num;
3696
3697         become_root();
3698
3699         /* AS ROOT !!! */
3700
3701         if (!pdb_get_seq_num(&seq_num)) {
3702                 seq_num = time(NULL);
3703         }
3704
3705         /* !AS ROOT */
3706
3707         unbecome_root();
3708
3709         r->sequence_num = seq_num;
3710         r->domain_create_time = 0;
3711         r->modified_count_at_last_promotion = 0;
3712
3713         return NT_STATUS_OK;
3714 }
3715
3716 /*******************************************************************
3717  _samr_QueryDomainInfo
3718  ********************************************************************/
3719
3720 NTSTATUS _samr_QueryDomainInfo(struct pipes_struct *p,
3721                                struct samr_QueryDomainInfo *r)
3722 {
3723         NTSTATUS status = NT_STATUS_OK;
3724         struct samr_info *dinfo;
3725         union samr_DomainInfo *dom_info;
3726
3727         uint32_t acc_required;
3728
3729         DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__));
3730
3731         switch (r->in.level) {
3732         case 1: /* DomainPasswordInformation */
3733         case 12: /* DomainLockoutInformation */
3734                 /* DOMAIN_READ_PASSWORD_PARAMETERS */
3735                 acc_required = SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1;
3736                 break;
3737         case 11: /* DomainGeneralInformation2 */
3738                 /* DOMAIN_READ_PASSWORD_PARAMETERS |
3739                  * DOMAIN_READ_OTHER_PARAMETERS */
3740                 acc_required = SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
3741                                SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2;
3742                 break;
3743         case 2: /* DomainGeneralInformation */
3744         case 3: /* DomainLogoffInformation */
3745         case 4: /* DomainOemInformation */
3746         case 5: /* DomainReplicationInformation */
3747         case 6: /* DomainReplicationInformation */
3748         case 7: /* DomainServerRoleInformation */
3749         case 8: /* DomainModifiedInformation */
3750         case 9: /* DomainStateInformation */
3751         case 10: /* DomainUasInformation */
3752         case 13: /* DomainModifiedInformation2 */
3753                 /* DOMAIN_READ_OTHER_PARAMETERS */
3754                 acc_required = SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2;
3755                 break;
3756         default:
3757                 return NT_STATUS_INVALID_INFO_CLASS;
3758         }
3759
3760         dinfo = samr_policy_handle_find(p,
3761                                         r->in.domain_handle,
3762                                         SAMR_HANDLE_DOMAIN,
3763                                         acc_required,
3764                                         NULL,
3765                                         &status);
3766         if (!NT_STATUS_IS_OK(status)) {
3767                 return status;
3768         }
3769
3770         dom_info = talloc_zero(p->mem_ctx, union samr_DomainInfo);
3771         if (!dom_info) {
3772                 return NT_STATUS_NO_MEMORY;
3773         }
3774
3775         switch (r->in.level) {
3776                 case 1:
3777                         status = query_dom_info_1(p->mem_ctx, &dom_info->info1);
3778                         break;
3779                 case 2:
3780                         status = query_dom_info_2(p->mem_ctx, &dom_info->general, dinfo);
3781                         break;
3782                 case 3:
3783                         status = query_dom_info_3(p->mem_ctx, &dom_info->info3);
3784                         break;
3785                 case 4:
3786                         status = query_dom_info_4(p->mem_ctx, &dom_info->oem);
3787                         break;
3788                 case 5:
3789                         status = query_dom_info_5(p->mem_ctx, &dom_info->info5);
3790                         break;
3791                 case 6:
3792                         status = query_dom_info_6(p->mem_ctx, &dom_info->info6);
3793                         break;
3794                 case 7:
3795                         status = query_dom_info_7(p->mem_ctx, &dom_info->info7);
3796                         break;
3797                 case 8:
3798                         status = query_dom_info_8(p->mem_ctx, &dom_info->info8);
3799                         break;
3800                 case 9:
3801                         status = query_dom_info_9(p->mem_ctx, &dom_info->info9);
3802                         break;
3803                 case 11:
3804                         status = query_dom_info_11(p->mem_ctx, &dom_info->general2, dinfo);
3805                         break;
3806                 case 12:
3807                         status = query_dom_info_12(p->mem_ctx, &dom_info->info12);
3808                         break;
3809                 case 13:
3810                         status = query_dom_info_13(p->mem_ctx, &dom_info->info13);
3811                         break;
3812                 default:
3813                         return NT_STATUS_INVALID_INFO_CLASS;
3814         }
3815
3816         if (!NT_STATUS_IS_OK(status)) {
3817                 return status;
3818         }
3819
3820         *r->out.info = dom_info;
3821
3822         DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__));
3823
3824         return status;
3825 }
3826
3827 /* W2k3 seems to use the same check for all 3 objects that can be created via
3828  * SAMR, if you try to create for example "Dialup" as an alias it says
3829  * "NT_STATUS_USER_EXISTS". This is racy, but we can't really lock the user
3830  * database. */
3831
3832 static NTSTATUS can_create(TALLOC_CTX *mem_ctx, const char *new_name)
3833 {
3834         enum lsa_SidType type;
3835         bool result;
3836
3837         DEBUG(10, ("Checking whether [%s] can be created\n", new_name));
3838
3839         become_root();
3840         /* Lookup in our local databases (LOOKUP_NAME_REMOTE not set)
3841          * whether the name already exists */
3842         result = lookup_name(mem_ctx, new_name, LOOKUP_NAME_LOCAL,
3843                              NULL, NULL, NULL, &type);
3844         unbecome_root();
3845
3846         if (!result) {
3847                 DEBUG(10, ("%s does not exist, can create it\n", new_name));
3848                 return NT_STATUS_OK;
3849         }
3850
3851         DEBUG(5, ("trying to create %s, exists as %s\n",
3852                   new_name, sid_type_lookup(type)));
3853
3854         if (type == SID_NAME_DOM_GRP) {
3855                 return NT_STATUS_GROUP_EXISTS;
3856         }
3857         if (type == SID_NAME_ALIAS) {
3858                 return NT_STATUS_ALIAS_EXISTS;
3859         }
3860
3861         /* Yes, the default is NT_STATUS_USER_EXISTS */
3862         return NT_STATUS_USER_EXISTS;
3863 }
3864
3865 /*******************************************************************
3866  _samr_CreateUser2
3867  ********************************************************************/
3868
3869 NTSTATUS _samr_CreateUser2(struct pipes_struct *p,
3870                            struct samr_CreateUser2 *r)
3871 {
3872         struct dcesrv_call_state *dce_call = p->dce_call;
3873         struct auth_session_info *session_info =
3874                 dcesrv_call_session_info(dce_call);
3875         const char *account = NULL;
3876         struct dom_sid sid;
3877         uint32_t acb_info = r->in.acct_flags;
3878         struct samr_info *dinfo;
3879         NTSTATUS nt_status;
3880         uint32_t acc_granted;
3881         struct security_descriptor *psd;
3882         size_t    sd_size;
3883         /* check this, when giving away 'add computer to domain' privs */
3884         uint32_t    des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
3885         bool can_add_account = False;
3886
3887         /* Which privilege is needed to override the ACL? */
3888         enum sec_privilege needed_priv = SEC_PRIV_INVALID;
3889
3890         dinfo = samr_policy_handle_find(p,
3891                                         r->in.domain_handle,
3892                                         SAMR_HANDLE_DOMAIN,
3893                                         SAMR_DOMAIN_ACCESS_CREATE_USER,
3894                                         NULL,
3895                                         &nt_status);
3896         if (!NT_STATUS_IS_OK(nt_status)) {
3897                 return nt_status;
3898         }
3899
3900         if (sid_check_is_builtin(&dinfo->sid)) {
3901                 DEBUG(5,("_samr_CreateUser2: Refusing user create in BUILTIN\n"));
3902                 return NT_STATUS_ACCESS_DENIED;
3903         }
3904
3905         if (!(acb_info == ACB_NORMAL || acb_info == ACB_DOMTRUST ||
3906               acb_info == ACB_WSTRUST || acb_info == ACB_SVRTRUST)) {
3907                 /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if
3908                    this parameter is not an account type */
3909                 return NT_STATUS_INVALID_PARAMETER;
3910         }
3911
3912         account = r->in.account_name->string;
3913         if (account == NULL) {
3914                 return NT_STATUS_NO_MEMORY;
3915         }
3916
3917         nt_status = can_create(p->mem_ctx, account);
3918         if (!NT_STATUS_IS_OK(nt_status)) {
3919                 return nt_status;
3920         }
3921
3922         /* determine which user right we need to check based on the acb_info */
3923
3924         if (root_mode()) {
3925                 can_add_account = true;
3926         } else if (acb_info & ACB_WSTRUST) {
3927                 needed_priv = SEC_PRIV_MACHINE_ACCOUNT;
3928                 can_add_account = security_token_has_privilege(
3929                         session_info->security_token, needed_priv);
3930         } else if (acb_info & ACB_NORMAL &&
3931                   (account[strlen(account)-1] != '$')) {
3932                 /* usrmgr.exe (and net rpc trustdom add) creates a normal user
3933                    account for domain trusts and changes the ACB flags later */
3934                 needed_priv = SEC_PRIV_ADD_USERS;
3935                 can_add_account = security_token_has_privilege(
3936                         session_info->security_token, needed_priv);
3937         } else if (lp_enable_privileges()) {
3938                 /* implicit assumption of a BDC or domain trust account here
3939                  * (we already check the flags earlier) */
3940                 /* only Domain Admins can add a BDC or domain trust */
3941                 can_add_account = nt_token_check_domain_rid(
3942                         session_info->security_token,
3943                         DOMAIN_RID_ADMINS );
3944         }
3945
3946         DEBUG(5, ("_samr_CreateUser2: %s can add this account : %s\n",
3947                   uidtoname(session_info->unix_token->uid),
3948                   can_add_account ? "True":"False" ));
3949
3950         if (!can_add_account) {
3951                 return NT_STATUS_ACCESS_DENIED;
3952         }
3953
3954         /********** BEGIN Admin BLOCK **********/
3955
3956         (void)winbind_off();
3957         become_root();
3958         nt_status = pdb_create_user(p->mem_ctx, account, acb_info,
3959                                     r->out.rid);
3960         unbecome_root();
3961         (void)winbind_on();
3962
3963         /********** END Admin BLOCK **********/
3964
3965         /* now check for failure */
3966
3967         if ( !NT_STATUS_IS_OK(nt_status) )
3968                 return nt_status;
3969
3970         /* Get the user's SID */
3971
3972         sid_compose(&sid, get_global_sam_sid(), *r->out.rid);
3973
3974         map_max_allowed_access(session_info->security_token,
3975                                session_info->unix_token,
3976                                &des_access);
3977
3978         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping,
3979                             &sid, SAMR_USR_RIGHTS_WRITE_PW);
3980         se_map_generic(&des_access, &usr_generic_mapping);
3981
3982         /*
3983          * JRA - TESTME. We just created this user so we
3984          * had rights to create them. Do we need to check
3985          * any further access on this object ? Can't we
3986          * just assume we have all the rights we need ?
3987          */
3988
3989         nt_status = access_check_object(psd, session_info->security_token,
3990                                         needed_priv, SEC_PRIV_INVALID,
3991                                         GENERIC_RIGHTS_USER_WRITE, des_access,
3992                 &acc_granted, "_samr_CreateUser2");
3993
3994         if ( !NT_STATUS_IS_OK(nt_status) ) {
3995                 return nt_status;
3996         }
3997
3998         nt_status = create_samr_policy_handle(p->mem_ctx,
3999                                               p,
4000                                               SAMR_HANDLE_USER,
4001                                               acc_granted,
4002                                               &sid,
4003                                               NULL,
4004                                               r->out.user_handle);
4005         if (!NT_STATUS_IS_OK(nt_status)) {
4006                 return nt_status;
4007         }
4008
4009         /* After a "set" ensure we have no cached display info. */
4010         force_flush_samr_cache(&sid);
4011
4012         *r->out.access_granted = acc_granted;
4013
4014         return NT_STATUS_OK;
4015 }
4016
4017 /****************************************************************
4018 ****************************************************************/
4019
4020 NTSTATUS _samr_CreateUser(struct pipes_struct *p,
4021                           struct samr_CreateUser *r)
4022 {
4023         struct samr_CreateUser2 c;
4024         uint32_t access_granted;
4025
4026         c.in.domain_handle      = r->in.domain_handle;
4027         c.in.account_name       = r->in.account_name;
4028         c.in.acct_flags         = ACB_NORMAL;
4029         c.in.access_mask        = r->in.access_mask;
4030         c.out.user_handle       = r->out.user_handle;
4031         c.out.access_granted    = &access_granted;
4032         c.out.rid               = r->out.rid;
4033
4034         return _samr_CreateUser2(p, &c);
4035 }
4036
4037 /*******************************************************************
4038  _samr_Connect
4039  ********************************************************************/
4040
4041 NTSTATUS _samr_Connect(struct pipes_struct *p,
4042                        struct samr_Connect *r)
4043 {
4044         struct dcesrv_call_state *dce_call = p->dce_call;
4045         struct auth_session_info *session_info =
4046                 dcesrv_call_session_info(dce_call);
4047         uint32_t acc_granted;
4048         uint32_t    des_access = r->in.access_mask;
4049         NTSTATUS status;
4050
4051         /* Access check */
4052
4053         if (!pipe_access_check(p)) {
4054                 DEBUG(3, ("access denied to _samr_Connect\n"));
4055                 return NT_STATUS_ACCESS_DENIED;
4056         }
4057
4058         /* don't give away the farm but this is probably ok.  The SAMR_ACCESS_ENUM_DOMAINS
4059            was observed from a win98 client trying to enumerate users (when configured
4060            user level access control on shares)   --jerry */
4061
4062         map_max_allowed_access(session_info->security_token,
4063                                session_info->unix_token,
4064                                &des_access);
4065
4066         se_map_generic( &des_access, &sam_generic_mapping );
4067
4068         acc_granted = des_access & (SAMR_ACCESS_ENUM_DOMAINS
4069                                     |SAMR_ACCESS_LOOKUP_DOMAIN);
4070
4071         /* set up the SAMR connect_anon response */
4072         status = create_samr_policy_handle(p->mem_ctx,
4073                                            p,
4074                                            SAMR_HANDLE_CONNECT,
4075                                            acc_granted,
4076                                            NULL,
4077                                            NULL,
4078                                            r->out.connect_handle);
4079         if (!NT_STATUS_IS_OK(status)) {
4080                 return status;
4081         }
4082
4083         return NT_STATUS_OK;
4084 }
4085
4086 /*******************************************************************
4087  _samr_Connect2
4088  ********************************************************************/
4089
4090 NTSTATUS _samr_Connect2(struct pipes_struct *p,
4091                         struct samr_Connect2 *r)
4092 {
4093         struct dcesrv_call_state *dce_call = p->dce_call;
4094         struct auth_session_info *session_info =
4095                 dcesrv_call_session_info(dce_call);
4096         struct security_descriptor *psd = NULL;
4097         uint32_t    acc_granted;
4098         uint32_t    des_access = r->in.access_mask;
4099         NTSTATUS  nt_status;
4100         size_t    sd_size;
4101         const char *fn = "_samr_Connect2";
4102
4103         switch (dce_call->pkt.u.request.opnum) {
4104         case NDR_SAMR_CONNECT2:
4105                 fn = "_samr_Connect2";
4106                 break;
4107         case NDR_SAMR_CONNECT3:
4108                 fn = "_samr_Connect3";
4109                 break;
4110         case NDR_SAMR_CONNECT4:
4111                 fn = "_samr_Connect4";
4112                 break;
4113         case NDR_SAMR_CONNECT5:
4114                 fn = "_samr_Connect5";
4115                 break;
4116         }
4117
4118         DEBUG(5,("%s: %d\n", fn, __LINE__));
4119
4120         /* Access check */
4121
4122         if (!pipe_access_check(p)) {
4123                 DEBUG(3, ("access denied to %s\n", fn));
4124                 return NT_STATUS_ACCESS_DENIED;
4125         }
4126
4127         map_max_allowed_access(session_info->security_token,
4128                                session_info->unix_token,
4129                                &des_access);
4130
4131         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
4132         se_map_generic(&des_access, &sam_generic_mapping);
4133
4134         nt_status = access_check_object(psd, session_info->security_token,
4135                                         SEC_PRIV_INVALID, SEC_PRIV_INVALID,
4136                                         0, des_access, &acc_granted, fn);
4137
4138         if ( !NT_STATUS_IS_OK(nt_status) )
4139                 return nt_status;
4140
4141         nt_status = create_samr_policy_handle(p->mem_ctx,
4142                                               p,
4143                                               SAMR_HANDLE_CONNECT,
4144                                               acc_granted,
4145                                               NULL,
4146                                               NULL,
4147                                               r->out.connect_handle);
4148         if (!NT_STATUS_IS_OK(nt_status)) {
4149                 return nt_status;
4150         }
4151
4152         DEBUG(5,("%s: %d\n", fn, __LINE__));
4153
4154         return NT_STATUS_OK;
4155 }
4156
4157 /****************************************************************
4158  _samr_Connect3
4159 ****************************************************************/
4160
4161 NTSTATUS _samr_Connect3(struct pipes_struct *p,
4162                         struct samr_Connect3 *r)
4163 {
4164         struct samr_Connect2 c;
4165
4166         c.in.system_name        = r->in.system_name;
4167         c.in.access_mask        = r->in.access_mask;
4168         c.out.connect_handle    = r->out.connect_handle;
4169
4170         return _samr_Connect2(p, &c);
4171 }
4172
4173 /*******************************************************************
4174  _samr_Connect4
4175  ********************************************************************/
4176
4177 NTSTATUS _samr_Connect4(struct pipes_struct *p,
4178                         struct samr_Connect4 *r)
4179 {
4180         struct samr_Connect2 c;
4181
4182         c.in.system_name        = r->in.system_name;
4183         c.in.access_mask        = r->in.access_mask;
4184         c.out.connect_handle    = r->out.connect_handle;
4185
4186         return _samr_Connect2(p, &c);
4187 }
4188
4189 /*******************************************************************
4190  _samr_Connect5
4191  ********************************************************************/
4192
4193 NTSTATUS _samr_Connect5(struct pipes_struct *p,
4194                         struct samr_Connect5 *r)
4195 {
4196         NTSTATUS status;
4197         struct samr_Connect2 c;
4198         struct samr_ConnectInfo1 info1;
4199
4200         info1.client_version = SAMR_CONNECT_AFTER_W2K;
4201         info1.supported_features = 0;
4202
4203         c.in.system_name        = r->in.system_name;
4204         c.in.access_mask        = r->in.access_mask;
4205         c.out.connect_handle    = r->out.connect_handle;
4206
4207         *r->out.level_out = 1;
4208
4209         status = _samr_Connect2(p, &c);
4210         if (!NT_STATUS_IS_OK(status)) {
4211                 return status;
4212         }
4213
4214         r->out.info_out->info1 = info1;
4215
4216         return NT_STATUS_OK;
4217 }
4218
4219 /**********************************************************************
4220  _samr_LookupDomain
4221  **********************************************************************/
4222
4223 NTSTATUS _samr_LookupDomain(struct pipes_struct *p,
4224                             struct samr_LookupDomain *r)
4225 {
4226         NTSTATUS status;
4227         const char *domain_name;
4228         struct dom_sid *sid = NULL;
4229         struct dom_sid_buf buf;
4230
4231         /* win9x user manager likes to use SAMR_ACCESS_ENUM_DOMAINS here.
4232            Reverted that change so we will work with RAS servers again */
4233
4234         (void)samr_policy_handle_find(p,
4235                                       r->in.connect_handle,
4236                                       SAMR_HANDLE_CONNECT,
4237                                       SAMR_ACCESS_LOOKUP_DOMAIN,
4238                                       NULL,
4239                                       &status);
4240         if (!NT_STATUS_IS_OK(status)) {
4241                 return status;
4242         }
4243
4244         domain_name = r->in.domain_name->string;
4245         if (!domain_name) {
4246                 return NT_STATUS_INVALID_PARAMETER;
4247         }
4248
4249         sid = talloc_zero(p->mem_ctx, struct dom_sid2);
4250         if (!sid) {
4251                 return NT_STATUS_NO_MEMORY;
4252         }
4253
4254         if (strequal(domain_name, builtin_domain_name())) {
4255                 sid_copy(sid, &global_sid_Builtin);
4256         } else {
4257                 if (!secrets_fetch_domain_sid(domain_name, sid)) {
4258                         status = NT_STATUS_NO_SUCH_DOMAIN;
4259                 }
4260         }
4261
4262         DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name,
4263                  dom_sid_str_buf(sid, &buf)));
4264
4265         *r->out.sid = sid;
4266
4267         return status;
4268 }
4269
4270 /**********************************************************************
4271  _samr_EnumDomains
4272  **********************************************************************/
4273
4274 NTSTATUS _samr_EnumDomains(struct pipes_struct *p,
4275                            struct samr_EnumDomains *r)
4276 {
4277         NTSTATUS status;
4278         uint32_t num_entries = 2;
4279         struct samr_SamEntry *entry_array = NULL;
4280         struct samr_SamArray *sam;
4281
4282         (void)samr_policy_handle_find(p,
4283                                       r->in.connect_handle,
4284                                       SAMR_HANDLE_CONNECT,
4285                                       SAMR_ACCESS_ENUM_DOMAINS,
4286                                       NULL,
4287                                       &status);
4288         if (!NT_STATUS_IS_OK(status)) {
4289                 return status;
4290         }
4291
4292         sam = talloc_zero(p->mem_ctx, struct samr_SamArray);
4293         if (!sam) {
4294                 return NT_STATUS_NO_MEMORY;
4295         }
4296
4297         entry_array = talloc_zero_array(p->mem_ctx,
4298                                         struct samr_SamEntry,
4299                                         num_entries);
4300         if (!entry_array) {
4301                 return NT_STATUS_NO_MEMORY;
4302         }
4303
4304         entry_array[0].idx = 0;
4305         init_lsa_String(&entry_array[0].name, get_global_sam_name());
4306
4307         entry_array[1].idx = 1;
4308         init_lsa_String(&entry_array[1].name, "Builtin");
4309
4310         sam->count = num_entries;
4311         sam->entries = entry_array;
4312
4313         *r->out.sam = sam;
4314         *r->out.num_entries = num_entries;
4315
4316         return status;
4317 }
4318
4319 /*******************************************************************
4320  _samr_OpenAlias
4321  ********************************************************************/
4322
4323 NTSTATUS _samr_OpenAlias(struct pipes_struct *p,
4324                          struct samr_OpenAlias *r)
4325 {
4326         struct dcesrv_call_state *dce_call = p->dce_call;
4327         struct auth_session_info *session_info =
4328                 dcesrv_call_session_info(dce_call);
4329         struct dom_sid sid;
4330         uint32_t alias_rid = r->in.rid;
4331         struct samr_info *dinfo;
4332         struct security_descriptor *psd = NULL;
4333         uint32_t    acc_granted;
4334         uint32_t    des_access = r->in.access_mask;
4335         size_t    sd_size;
4336         NTSTATUS  status;
4337
4338         dinfo = samr_policy_handle_find(p,
4339                                         r->in.domain_handle,
4340                                         SAMR_HANDLE_DOMAIN,
4341                                         SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
4342                                         NULL,
4343                                         &status);
4344         if (!NT_STATUS_IS_OK(status)) {
4345                 return status;
4346         }
4347
4348         /* append the alias' RID to it */
4349
4350         if (!sid_compose(&sid, &dinfo->sid, alias_rid))
4351                 return NT_STATUS_NO_SUCH_ALIAS;
4352
4353         /*check if access can be granted as requested by client. */
4354
4355         map_max_allowed_access(session_info->security_token,
4356                                session_info->unix_token,
4357                                &des_access);
4358
4359         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &ali_generic_mapping, NULL, 0);
4360         se_map_generic(&des_access,&ali_generic_mapping);
4361
4362         status = access_check_object(psd, session_info->security_token,
4363                                      SEC_PRIV_ADD_USERS, SEC_PRIV_INVALID,
4364                                      GENERIC_RIGHTS_ALIAS_ALL_ACCESS,
4365                                      des_access, &acc_granted, "_samr_OpenAlias");
4366
4367         if ( !NT_STATUS_IS_OK(status) )
4368                 return status;
4369
4370         {
4371                 /* Check we actually have the requested alias */
4372                 enum lsa_SidType type;
4373                 bool result;
4374                 gid_t gid;
4375
4376                 become_root();
4377                 result = lookup_sid(NULL, &sid, NULL, NULL, &type);
4378                 unbecome_root();
4379
4380                 if (!result || (type != SID_NAME_ALIAS)) {
4381                         return NT_STATUS_NO_SUCH_ALIAS;
4382                 }
4383
4384                 /* make sure there is a mapping */
4385
4386                 if ( !sid_to_gid( &sid, &gid ) ) {
4387                         return NT_STATUS_NO_SUCH_ALIAS;
4388                 }
4389
4390         }
4391
4392         status = create_samr_policy_handle(p->mem_ctx,
4393                                            p,
4394                                            SAMR_HANDLE_ALIAS,
4395                                            acc_granted,
4396                                            &sid,
4397                                            NULL,
4398                                            r->out.alias_handle);
4399         if (!NT_STATUS_IS_OK(status)) {
4400                 return status;
4401         }
4402
4403         return NT_STATUS_OK;
4404 }
4405
4406 /*******************************************************************
4407  set_user_info_2
4408  ********************************************************************/
4409
4410 static NTSTATUS set_user_info_2(TALLOC_CTX *mem_ctx,
4411                                 struct samr_UserInfo2 *id2,
4412                                 struct samu *pwd)
4413 {
4414         if (id2 == NULL) {
4415                 DEBUG(5,("set_user_info_2: NULL id2\n"));
4416                 return NT_STATUS_ACCESS_DENIED;
4417         }
4418
4419         copy_id2_to_sam_passwd(pwd, id2);
4420
4421         return pdb_update_sam_account(pwd);
4422 }
4423
4424 /*******************************************************************
4425  set_user_info_4
4426  ********************************************************************/
4427
4428 static NTSTATUS set_user_info_4(TALLOC_CTX *mem_ctx,
4429                                 struct samr_UserInfo4 *id4,
4430                                 struct samu *pwd)
4431 {
4432         if (id4 == NULL) {
4433                 DEBUG(5,("set_user_info_2: NULL id4\n"));
4434                 return NT_STATUS_ACCESS_DENIED;
4435         }
4436
4437         copy_id4_to_sam_passwd(pwd, id4);
4438
4439         return pdb_update_sam_account(pwd);
4440 }
4441
4442 /*******************************************************************
4443  set_user_info_6
4444  ********************************************************************/
4445
4446 static NTSTATUS set_user_info_6(TALLOC_CTX *mem_ctx,
4447                                 struct samr_UserInfo6 *id6,
4448                                 struct samu *pwd)
4449 {
4450         if (id6 == NULL) {
4451                 DEBUG(5,("set_user_info_6: NULL id6\n"));
4452                 return NT_STATUS_ACCESS_DENIED;
4453         }
4454
4455         copy_id6_to_sam_passwd(pwd, id6);
4456
4457         return pdb_update_sam_account(pwd);
4458 }
4459
4460 /*******************************************************************
4461  set_user_info_7
4462  ********************************************************************/
4463
4464 static NTSTATUS set_user_info_7(TALLOC_CTX *mem_ctx,
4465                                 struct samr_UserInfo7 *id7,
4466                                 struct samu *pwd)
4467 {
4468         NTSTATUS rc;
4469
4470         if (id7 == NULL) {
4471                 DEBUG(5, ("set_user_info_7: NULL id7\n"));
4472                 return NT_STATUS_ACCESS_DENIED;
4473         }
4474
4475         if (!id7->account_name.string) {
4476                 DEBUG(5, ("set_user_info_7: failed to get new username\n"));
4477                 return NT_STATUS_ACCESS_DENIED;
4478         }
4479
4480         /* check to see if the new username already exists.  Note: we can't
4481            reliably lock all backends, so there is potentially the
4482            possibility that a user can be created in between this check and
4483            the rename.  The rename should fail, but may not get the
4484            exact same failure status code.  I think this is small enough
4485            of a window for this type of operation and the results are
4486            simply that the rename fails with a slightly different status
4487            code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
4488
4489         rc = can_create(mem_ctx, id7->account_name.string);
4490
4491         /* when there is nothing to change, we're done here */
4492         if (NT_STATUS_EQUAL(rc, NT_STATUS_USER_EXISTS) &&
4493             strequal(id7->account_name.string, pdb_get_username(pwd))) {
4494                 return NT_STATUS_OK;
4495         }
4496         if (!NT_STATUS_IS_OK(rc)) {
4497                 return rc;
4498         }
4499