s3:rpc_server: Activate samba-dcerpcd
[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
53 #include "lib/crypto/gnutls_helpers.h"
54 #include <gnutls/gnutls.h>
55 #include <gnutls/crypto.h>
56 #include "lib/global_contexts.h"
57 #include "nsswitch/winbind_client.h"
58
59 #undef DBGC_CLASS
60 #define DBGC_CLASS DBGC_RPC_SRV
61
62 #define SAMR_USR_RIGHTS_WRITE_PW \
63                 ( READ_CONTROL_ACCESS           | \
64                   SAMR_USER_ACCESS_CHANGE_PASSWORD      | \
65                   SAMR_USER_ACCESS_SET_LOC_COM)
66 #define SAMR_USR_RIGHTS_CANT_WRITE_PW \
67                 ( READ_CONTROL_ACCESS | SAMR_USER_ACCESS_SET_LOC_COM )
68
69 #define DISP_INFO_CACHE_TIMEOUT 10
70
71 #define MAX_SAM_ENTRIES_W2K 0x400 /* 1024 */
72 #define MAX_SAM_ENTRIES_W95 50
73
74 enum samr_handle {
75         SAMR_HANDLE_CONNECT,
76         SAMR_HANDLE_DOMAIN,
77         SAMR_HANDLE_USER,
78         SAMR_HANDLE_GROUP,
79         SAMR_HANDLE_ALIAS
80 };
81
82 struct samr_info {
83         uint32_t access_granted;
84         struct dom_sid sid;
85         struct disp_info *disp_info;
86 };
87
88 typedef struct disp_info {
89         struct dom_sid sid; /* identify which domain this is. */
90         struct pdb_search *users; /* querydispinfo 1 and 4 */
91         struct pdb_search *machines; /* querydispinfo 2 */
92         struct pdb_search *groups; /* querydispinfo 3 and 5, enumgroups */
93         struct pdb_search *aliases; /* enumaliases */
94
95         uint32_t enum_acb_mask;
96         struct pdb_search *enum_users; /* enumusers with a mask */
97
98         struct tevent_timer *cache_timeout_event; /* cache idle timeout
99                                                   * handler. */
100 } DISP_INFO;
101
102 static const struct generic_mapping sam_generic_mapping = {
103         GENERIC_RIGHTS_SAM_READ,
104         GENERIC_RIGHTS_SAM_WRITE,
105         GENERIC_RIGHTS_SAM_EXECUTE,
106         GENERIC_RIGHTS_SAM_ALL_ACCESS};
107 static const struct generic_mapping dom_generic_mapping = {
108         GENERIC_RIGHTS_DOMAIN_READ,
109         GENERIC_RIGHTS_DOMAIN_WRITE,
110         GENERIC_RIGHTS_DOMAIN_EXECUTE,
111         GENERIC_RIGHTS_DOMAIN_ALL_ACCESS};
112 static const struct generic_mapping usr_generic_mapping = {
113         GENERIC_RIGHTS_USER_READ,
114         GENERIC_RIGHTS_USER_WRITE,
115         GENERIC_RIGHTS_USER_EXECUTE,
116         GENERIC_RIGHTS_USER_ALL_ACCESS};
117 static const struct generic_mapping usr_nopwchange_generic_mapping = {
118         GENERIC_RIGHTS_USER_READ,
119         GENERIC_RIGHTS_USER_WRITE,
120         GENERIC_RIGHTS_USER_EXECUTE & ~SAMR_USER_ACCESS_CHANGE_PASSWORD,
121         GENERIC_RIGHTS_USER_ALL_ACCESS};
122 static const struct generic_mapping grp_generic_mapping = {
123         GENERIC_RIGHTS_GROUP_READ,
124         GENERIC_RIGHTS_GROUP_WRITE,
125         GENERIC_RIGHTS_GROUP_EXECUTE,
126         GENERIC_RIGHTS_GROUP_ALL_ACCESS};
127 static const struct generic_mapping ali_generic_mapping = {
128         GENERIC_RIGHTS_ALIAS_READ,
129         GENERIC_RIGHTS_ALIAS_WRITE,
130         GENERIC_RIGHTS_ALIAS_EXECUTE,
131         GENERIC_RIGHTS_ALIAS_ALL_ACCESS};
132
133 /*******************************************************************
134 *******************************************************************/
135 static NTSTATUS create_samr_policy_handle(TALLOC_CTX *mem_ctx,
136                                           struct pipes_struct *p,
137                                           enum samr_handle type,
138                                           uint32_t acc_granted,
139                                           struct dom_sid *sid,
140                                           struct disp_info *disp_info,
141                                           struct policy_handle *handle)
142 {
143         struct samr_info *info = NULL;
144         bool ok;
145
146         ZERO_STRUCTP(handle);
147
148         info = talloc_zero(mem_ctx, struct samr_info);
149         if (info == NULL) {
150                 return NT_STATUS_NO_MEMORY;
151         }
152
153         info->access_granted = acc_granted;
154
155         if (sid != NULL) {
156                 sid_copy(&info->sid, sid);
157         }
158
159         if (disp_info != NULL) {
160                 info->disp_info = disp_info;
161         }
162
163         ok = create_policy_hnd(p, handle, type, info);
164         if (!ok) {
165                 talloc_free(info);
166                 ZERO_STRUCTP(handle);
167                 return NT_STATUS_NO_MEMORY;
168         }
169
170         return NT_STATUS_OK;
171 }
172
173 static NTSTATUS samr_handle_access_check(uint32_t access_granted,
174                                          uint32_t access_required,
175                                          uint32_t *paccess_granted)
176 {
177         if ((access_required & access_granted) != access_required) {
178                 if (root_mode()) {
179                         DBG_INFO("ACCESS should be DENIED (granted: "
180                                  "%#010x; required: %#010x) but overwritten "
181                                  "by euid == 0\n", access_granted,
182                                  access_required);
183                         goto okay;
184                 }
185                 DBG_NOTICE("ACCESS DENIED (granted: %#010x; required: "
186                            "%#010x)\n", access_granted, access_required);
187                 return NT_STATUS_ACCESS_DENIED;
188         }
189
190 okay:
191         if (paccess_granted != NULL) {
192                 *paccess_granted = access_granted;
193         }
194         return NT_STATUS_OK;
195 }
196
197 static void *samr_policy_handle_find(struct pipes_struct *p,
198                                      const struct policy_handle *handle,
199                                      uint8_t handle_type,
200                                      uint32_t access_required,
201                                      uint32_t *access_granted,
202                                      NTSTATUS *pstatus)
203 {
204         struct samr_info *info = NULL;
205         NTSTATUS status;
206
207         info = find_policy_by_hnd(p,
208                                   handle,
209                                   handle_type,
210                                   struct samr_info,
211                                   &status);
212         if (!NT_STATUS_IS_OK(status)) {
213                 *pstatus = NT_STATUS_INVALID_HANDLE;
214                 return NULL;
215         }
216
217         status = samr_handle_access_check(info->access_granted,
218                                           access_required,
219                                           access_granted);
220         if (!NT_STATUS_IS_OK(status)) {
221                 *pstatus = status;
222                 return NULL;
223         }
224
225         *pstatus = NT_STATUS_OK;
226         return info;
227 }
228
229 static NTSTATUS make_samr_object_sd( TALLOC_CTX *ctx, struct security_descriptor **psd, size_t *sd_size,
230                                      const struct generic_mapping *map,
231                                      struct dom_sid *sid, uint32_t sid_access )
232 {
233         struct dom_sid domadmin_sid;
234         struct security_ace ace[5];             /* at most 5 entries */
235         size_t i = 0;
236
237         struct security_acl *psa = NULL;
238
239         /* basic access for Everyone */
240
241         init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
242                         map->generic_execute | map->generic_read, 0);
243
244         /* add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
245
246         init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
247                         SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
248         init_sec_ace(&ace[i++], &global_sid_Builtin_Account_Operators,
249                         SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
250
251         /* Add Full Access for Domain Admins if we are a DC */
252
253         if ( IS_DC ) {
254                 sid_compose(&domadmin_sid, get_global_sam_sid(),
255                             DOMAIN_RID_ADMINS);
256                 init_sec_ace(&ace[i++], &domadmin_sid,
257                         SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
258         }
259
260         /* if we have a sid, give it some special access */
261
262         if ( sid ) {
263                 init_sec_ace(&ace[i++], sid, SEC_ACE_TYPE_ACCESS_ALLOWED, sid_access, 0);
264         }
265
266         /* create the security descriptor */
267
268         if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) == NULL)
269                 return NT_STATUS_NO_MEMORY;
270
271         if ((*psd = make_sec_desc(ctx, SECURITY_DESCRIPTOR_REVISION_1,
272                                   SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL,
273                                   psa, sd_size)) == NULL)
274                 return NT_STATUS_NO_MEMORY;
275
276         return NT_STATUS_OK;
277 }
278
279 /*******************************************************************
280  Fetch or create a dispinfo struct.
281 ********************************************************************/
282
283 static DISP_INFO *get_samr_dispinfo_by_sid(const struct dom_sid *psid)
284 {
285         /*
286          * We do a static cache for DISP_INFO's here. Explanation can be found
287          * in Jeremy's checkin message to r11793:
288          *
289          * Fix the SAMR cache so it works across completely insane
290          * client behaviour (ie.:
291          * open pipe/open SAMR handle/enumerate 0 - 1024
292          * close SAMR handle, close pipe.
293          * open pipe/open SAMR handle/enumerate 1024 - 2048...
294          * close SAMR handle, close pipe.
295          * And on ad-nausium. Amazing.... probably object-oriented
296          * client side programming in action yet again.
297          * This change should *massively* improve performance when
298          * enumerating users from an LDAP database.
299          * Jeremy.
300          *
301          * "Our" and the builtin domain are the only ones where we ever
302          * enumerate stuff, so just cache 2 entries.
303          */
304
305         static struct disp_info *builtin_dispinfo;
306         static struct disp_info *domain_dispinfo;
307
308         /* There are two cases to consider here:
309            1) The SID is a domain SID and we look for an equality match, or
310            2) This is an account SID and so we return the DISP_INFO* for our
311               domain */
312
313         if (psid == NULL) {
314                 return NULL;
315         }
316
317         if (sid_check_is_builtin(psid) || sid_check_is_in_builtin(psid)) {
318                 /*
319                  * Necessary only once, but it does not really hurt.
320                  */
321                 if (builtin_dispinfo == NULL) {
322                         builtin_dispinfo = talloc_zero(NULL, struct disp_info);
323                         if (builtin_dispinfo == NULL) {
324                                 return NULL;
325                         }
326                 }
327                 sid_copy(&builtin_dispinfo->sid, &global_sid_Builtin);
328
329                 return builtin_dispinfo;
330         }
331
332         if (sid_check_is_our_sam(psid) || sid_check_is_in_our_sam(psid)) {
333                 /*
334                  * Necessary only once, but it does not really hurt.
335                  */
336                 if (domain_dispinfo == NULL) {
337                         domain_dispinfo = talloc_zero(NULL, struct disp_info);
338                         if (domain_dispinfo == NULL) {
339                                 return NULL;
340                         }
341                 }
342                 sid_copy(&domain_dispinfo->sid, get_global_sam_sid());
343
344                 return domain_dispinfo;
345         }
346
347         return NULL;
348 }
349
350 /*******************************************************************
351  Function to free the per SID data.
352  ********************************************************************/
353
354 static void free_samr_cache(DISP_INFO *disp_info)
355 {
356         struct dom_sid_buf buf;
357
358         DEBUG(10, ("free_samr_cache: deleting cache for SID %s\n",
359                    dom_sid_str_buf(&disp_info->sid, &buf)));
360
361         /* We need to become root here because the paged search might have to
362          * tell the LDAP server we're not interested in the rest anymore. */
363
364         become_root();
365
366         TALLOC_FREE(disp_info->users);
367         TALLOC_FREE(disp_info->machines);
368         TALLOC_FREE(disp_info->groups);
369         TALLOC_FREE(disp_info->aliases);
370         TALLOC_FREE(disp_info->enum_users);
371
372         unbecome_root();
373 }
374
375 /*******************************************************************
376  Idle event handler. Throw away the disp info cache.
377  ********************************************************************/
378
379 static void disp_info_cache_idle_timeout_handler(struct tevent_context *ev_ctx,
380                                                  struct tevent_timer *te,
381                                                  struct timeval now,
382                                                  void *private_data)
383 {
384         DISP_INFO *disp_info = (DISP_INFO *)private_data;
385
386         TALLOC_FREE(disp_info->cache_timeout_event);
387
388         DEBUG(10, ("disp_info_cache_idle_timeout_handler: caching timed "
389                    "out\n"));
390         free_samr_cache(disp_info);
391 }
392
393 /*******************************************************************
394  Setup cache removal idle event handler.
395  ********************************************************************/
396
397 static void set_disp_info_cache_timeout(DISP_INFO *disp_info, time_t secs_fromnow)
398 {
399         struct dom_sid_buf buf;
400
401         /* Remove any pending timeout and update. */
402
403         TALLOC_FREE(disp_info->cache_timeout_event);
404
405         DEBUG(10,("set_disp_info_cache_timeout: caching enumeration for "
406                   "SID %s for %u seconds\n",
407                   dom_sid_str_buf(&disp_info->sid, &buf),
408                   (unsigned int)secs_fromnow ));
409
410         disp_info->cache_timeout_event = tevent_add_timer(
411                 global_event_context(), NULL,
412                 timeval_current_ofs(secs_fromnow, 0),
413                 disp_info_cache_idle_timeout_handler, (void *)disp_info);
414 }
415
416 /*******************************************************************
417  Force flush any cache. We do this on any samr_set_xxx call.
418  We must also remove the timeout handler.
419  ********************************************************************/
420
421 static void force_flush_samr_cache(const struct dom_sid *sid)
422 {
423         struct disp_info *disp_info = get_samr_dispinfo_by_sid(sid);
424
425         if ((disp_info == NULL) || (disp_info->cache_timeout_event == NULL)) {
426                 return;
427         }
428
429         DEBUG(10,("force_flush_samr_cache: clearing idle event\n"));
430         TALLOC_FREE(disp_info->cache_timeout_event);
431         free_samr_cache(disp_info);
432 }
433
434 /*******************************************************************
435  Ensure password info is never given out. Paranioa... JRA.
436  ********************************************************************/
437
438 static void samr_clear_sam_passwd(struct samu *sam_pass)
439 {
440
441         if (!sam_pass)
442                 return;
443
444         /* These now zero out the old password */
445
446         pdb_set_lanman_passwd(sam_pass, NULL, PDB_DEFAULT);
447         pdb_set_nt_passwd(sam_pass, NULL, PDB_DEFAULT);
448 }
449
450 static uint32_t count_sam_users(struct disp_info *info, uint32_t acct_flags)
451 {
452         struct samr_displayentry *entry;
453
454         if (sid_check_is_builtin(&info->sid)) {
455                 /* No users in builtin. */
456                 return 0;
457         }
458
459         if (info->users == NULL) {
460                 info->users = pdb_search_users(info, acct_flags);
461                 if (info->users == NULL) {
462                         return 0;
463                 }
464         }
465         /* Fetch the last possible entry, thus trigger an enumeration */
466         pdb_search_entries(info->users, 0xffffffff, 1, &entry);
467
468         /* Ensure we cache this enumeration. */
469         set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
470
471         return info->users->num_entries;
472 }
473
474 static uint32_t count_sam_groups(struct disp_info *info)
475 {
476         struct samr_displayentry *entry;
477
478         if (sid_check_is_builtin(&info->sid)) {
479                 /* No groups in builtin. */
480                 return 0;
481         }
482
483         if (info->groups == NULL) {
484                 info->groups = pdb_search_groups(info);
485                 if (info->groups == NULL) {
486                         return 0;
487                 }
488         }
489         /* Fetch the last possible entry, thus trigger an enumeration */
490         pdb_search_entries(info->groups, 0xffffffff, 1, &entry);
491
492         /* Ensure we cache this enumeration. */
493         set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
494
495         return info->groups->num_entries;
496 }
497
498 static uint32_t count_sam_aliases(struct disp_info *info)
499 {
500         struct samr_displayentry *entry;
501
502         if (info->aliases == NULL) {
503                 info->aliases = pdb_search_aliases(info, &info->sid);
504                 if (info->aliases == NULL) {
505                         return 0;
506                 }
507         }
508         /* Fetch the last possible entry, thus trigger an enumeration */
509         pdb_search_entries(info->aliases, 0xffffffff, 1, &entry);
510
511         /* Ensure we cache this enumeration. */
512         set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
513
514         return info->aliases->num_entries;
515 }
516
517 /*******************************************************************
518  _samr_Close
519  ********************************************************************/
520
521 NTSTATUS _samr_Close(struct pipes_struct *p, struct samr_Close *r)
522 {
523         if (!close_policy_hnd(p, r->in.handle)) {
524                 return NT_STATUS_INVALID_HANDLE;
525         }
526
527         ZERO_STRUCTP(r->out.handle);
528
529         return NT_STATUS_OK;
530 }
531
532 /*******************************************************************
533  _samr_OpenDomain
534  ********************************************************************/
535
536 NTSTATUS _samr_OpenDomain(struct pipes_struct *p,
537                           struct samr_OpenDomain *r)
538 {
539         struct security_descriptor *psd = NULL;
540         uint32_t    acc_granted;
541         uint32_t    des_access = r->in.access_mask;
542         NTSTATUS  status;
543         size_t    sd_size;
544         uint32_t extra_access = SAMR_DOMAIN_ACCESS_CREATE_USER;
545         struct disp_info *disp_info = NULL;
546
547         /* find the connection policy handle. */
548         (void)samr_policy_handle_find(p,
549                                       r->in.connect_handle,
550                                       SAMR_HANDLE_CONNECT,
551                                       0,
552                                       NULL,
553                                       &status);
554         if (!NT_STATUS_IS_OK(status)) {
555                 return status;
556         }
557
558         /*check if access can be granted as requested by client. */
559         map_max_allowed_access(p->session_info->security_token,
560                                p->session_info->unix_token,
561                                &des_access);
562
563         make_samr_object_sd( p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0 );
564         se_map_generic( &des_access, &dom_generic_mapping );
565
566         /*
567          * Users with SeAddUser get the ability to manipulate groups
568          * and aliases.
569          */
570         if (security_token_has_privilege(p->session_info->security_token, SEC_PRIV_ADD_USERS)) {
571                 extra_access |= (SAMR_DOMAIN_ACCESS_CREATE_GROUP |
572                                 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS |
573                                 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
574                                 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS |
575                                 SAMR_DOMAIN_ACCESS_CREATE_ALIAS);
576         }
577
578         /*
579          * Users with SeMachineAccount or SeAddUser get additional
580          * SAMR_DOMAIN_ACCESS_CREATE_USER access.
581          */
582
583         status = access_check_object( psd, p->session_info->security_token,
584                                       SEC_PRIV_MACHINE_ACCOUNT, SEC_PRIV_ADD_USERS,
585                                       extra_access, des_access,
586                                       &acc_granted, "_samr_OpenDomain" );
587
588         if ( !NT_STATUS_IS_OK(status) )
589                 return status;
590
591         if (!sid_check_is_our_sam(r->in.sid) &&
592             !sid_check_is_builtin(r->in.sid)) {
593                 return NT_STATUS_NO_SUCH_DOMAIN;
594         }
595
596         disp_info = get_samr_dispinfo_by_sid(r->in.sid);
597
598         status = create_samr_policy_handle(p->mem_ctx,
599                                            p,
600                                            SAMR_HANDLE_DOMAIN,
601                                            acc_granted,
602                                            r->in.sid,
603                                            disp_info,
604                                            r->out.domain_handle);
605         if (!NT_STATUS_IS_OK(status)) {
606                 return status;
607         }
608
609         DEBUG(5,("_samr_OpenDomain: %d\n", __LINE__));
610
611         return NT_STATUS_OK;
612 }
613
614 /*******************************************************************
615  _samr_GetUserPwInfo
616  ********************************************************************/
617
618 NTSTATUS _samr_GetUserPwInfo(struct pipes_struct *p,
619                              struct samr_GetUserPwInfo *r)
620 {
621         const struct loadparm_substitution *lp_sub =
622                 loadparm_s3_global_substitution();
623         struct samr_info *uinfo;
624         enum lsa_SidType sid_type;
625         uint32_t min_password_length = 0;
626         uint32_t password_properties = 0;
627         bool ret = false;
628         NTSTATUS status;
629
630         DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__));
631
632         uinfo = samr_policy_handle_find(p, r->in.user_handle,
633                                         SAMR_HANDLE_USER,
634                                         SAMR_USER_ACCESS_GET_ATTRIBUTES,
635                                         NULL,
636                                         &status);
637         if (!NT_STATUS_IS_OK(status)) {
638                 return status;
639         }
640
641         if (!sid_check_is_in_our_sam(&uinfo->sid)) {
642                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
643         }
644
645         become_root();
646         ret = lookup_sid(p->mem_ctx, &uinfo->sid, NULL, NULL, &sid_type);
647         unbecome_root();
648         if (ret == false) {
649                 return NT_STATUS_NO_SUCH_USER;
650         }
651
652         switch (sid_type) {
653                 case SID_NAME_USER:
654                         become_root();
655                         pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN,
656                                                &min_password_length);
657                         pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
658                                                &password_properties);
659                         unbecome_root();
660
661                         if (lp_check_password_script(talloc_tos(), lp_sub)
662                             && *lp_check_password_script(talloc_tos(), lp_sub)) {
663                                 password_properties |= DOMAIN_PASSWORD_COMPLEX;
664                         }
665
666                         break;
667                 default:
668                         break;
669         }
670
671         r->out.info->min_password_length = min_password_length;
672         r->out.info->password_properties = password_properties;
673
674         DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__));
675
676         return NT_STATUS_OK;
677 }
678
679 /*******************************************************************
680  _samr_SetSecurity
681  ********************************************************************/
682
683 NTSTATUS _samr_SetSecurity(struct pipes_struct *p,
684                            struct samr_SetSecurity *r)
685 {
686         struct samr_info *uinfo;
687         uint32_t i;
688         struct security_acl *dacl;
689         bool ret;
690         struct samu *sampass=NULL;
691         NTSTATUS status;
692
693         uinfo = samr_policy_handle_find(p,
694                                         r->in.handle,
695                                         SAMR_HANDLE_USER,
696                                         SAMR_USER_ACCESS_SET_ATTRIBUTES,
697                                         NULL,
698                                         &status);
699         if (!NT_STATUS_IS_OK(status)) {
700                 return status;
701         }
702
703         if (!(sampass = samu_new( p->mem_ctx))) {
704                 DEBUG(0,("No memory!\n"));
705                 return NT_STATUS_NO_MEMORY;
706         }
707
708         /* get the user record */
709         become_root();
710         ret = pdb_getsampwsid(sampass, &uinfo->sid);
711         unbecome_root();
712
713         if (!ret) {
714                 struct dom_sid_buf buf;
715                 DEBUG(4, ("User %s not found\n",
716                           dom_sid_str_buf(&uinfo->sid, &buf)));
717                 TALLOC_FREE(sampass);
718                 return NT_STATUS_INVALID_HANDLE;
719         }
720
721         dacl = r->in.sdbuf->sd->dacl;
722         for (i=0; i < dacl->num_aces; i++) {
723                 if (dom_sid_equal(&uinfo->sid, &dacl->aces[i].trustee)) {
724                         ret = pdb_set_pass_can_change(sampass,
725                                 (dacl->aces[i].access_mask &
726                                  SAMR_USER_ACCESS_CHANGE_PASSWORD) ?
727                                                       True: False);
728                         break;
729                 }
730         }
731
732         if (!ret) {
733                 TALLOC_FREE(sampass);
734                 return NT_STATUS_ACCESS_DENIED;
735         }
736
737         become_root();
738         status = pdb_update_sam_account(sampass);
739         unbecome_root();
740
741         TALLOC_FREE(sampass);
742
743         return status;
744 }
745
746 /*******************************************************************
747   build correct perms based on policies and password times for _samr_query_sec_obj
748 *******************************************************************/
749 static bool check_change_pw_access(TALLOC_CTX *mem_ctx, struct dom_sid *user_sid)
750 {
751         struct samu *sampass=NULL;
752         bool ret;
753
754         if ( !(sampass = samu_new( mem_ctx )) ) {
755                 DEBUG(0,("No memory!\n"));
756                 return False;
757         }
758
759         become_root();
760         ret = pdb_getsampwsid(sampass, user_sid);
761         unbecome_root();
762
763         if (ret == False) {
764                 struct dom_sid_buf buf;
765                 DEBUG(4,("User %s not found\n",
766                          dom_sid_str_buf(user_sid, &buf)));
767                 TALLOC_FREE(sampass);
768                 return False;
769         }
770
771         DEBUG(3,("User:[%s]\n",  pdb_get_username(sampass) ));
772
773         if (pdb_get_pass_can_change(sampass)) {
774                 TALLOC_FREE(sampass);
775                 return True;
776         }
777         TALLOC_FREE(sampass);
778         return False;
779 }
780
781
782 /*******************************************************************
783  _samr_QuerySecurity
784  ********************************************************************/
785
786 NTSTATUS _samr_QuerySecurity(struct pipes_struct *p,
787                              struct samr_QuerySecurity *r)
788 {
789         struct samr_info *info;
790         NTSTATUS status;
791         struct security_descriptor * psd = NULL;
792         size_t sd_size = 0;
793         struct dom_sid_buf buf;
794
795         info = samr_policy_handle_find(p,
796                                        r->in.handle,
797                                        SAMR_HANDLE_CONNECT,
798                                        SEC_STD_READ_CONTROL,
799                                        NULL,
800                                        &status);
801         if (NT_STATUS_IS_OK(status)) {
802                 DEBUG(5,("_samr_QuerySecurity: querying security on SAM\n"));
803                 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size,
804                                              &sam_generic_mapping, NULL, 0);
805                 goto done;
806         }
807
808         info = samr_policy_handle_find(p,
809                                        r->in.handle,
810                                        SAMR_HANDLE_DOMAIN,
811                                        SEC_STD_READ_CONTROL,
812                                        NULL,
813                                        &status);
814         if (NT_STATUS_IS_OK(status)) {
815                 DEBUG(5,("_samr_QuerySecurity: querying security on Domain "
816                          "with SID: %s\n",
817                          dom_sid_str_buf(&info->sid, &buf)));
818                 /*
819                  * TODO: Builtin probably needs a different SD with restricted
820                  * write access
821                  */
822                 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size,
823                                              &dom_generic_mapping, NULL, 0);
824                 goto done;
825         }
826
827         info = samr_policy_handle_find(p,
828                                        r->in.handle,
829                                        SAMR_HANDLE_USER,
830                                        SEC_STD_READ_CONTROL,
831                                        NULL,
832                                        &status);
833         if (NT_STATUS_IS_OK(status)) {
834                 DEBUG(10,("_samr_QuerySecurity: querying security on user "
835                           "Object with SID: %s\n",
836                           dom_sid_str_buf(&info->sid, &buf)));
837                 if (check_change_pw_access(p->mem_ctx, &info->sid)) {
838                         status = make_samr_object_sd(
839                                 p->mem_ctx, &psd, &sd_size,
840                                 &usr_generic_mapping,
841                                 &info->sid, SAMR_USR_RIGHTS_WRITE_PW);
842                 } else {
843                         status = make_samr_object_sd(
844                                 p->mem_ctx, &psd, &sd_size,
845                                 &usr_nopwchange_generic_mapping,
846                                 &info->sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
847                 }
848                 goto done;
849         }
850
851         info = samr_policy_handle_find(p,
852                                        r->in.handle,
853                                        SAMR_HANDLE_GROUP,
854                                        SEC_STD_READ_CONTROL,
855                                        NULL,
856                                        &status);
857         if (NT_STATUS_IS_OK(status)) {
858                 /*
859                  * TODO: different SDs have to be generated for aliases groups
860                  * and users.  Currently all three get a default user SD
861                  */
862                 DEBUG(10,("_samr_QuerySecurity: querying security on group "
863                           "Object with SID: %s\n",
864                           dom_sid_str_buf(&info->sid, &buf)));
865                 status = make_samr_object_sd(
866                         p->mem_ctx, &psd, &sd_size,
867                         &usr_nopwchange_generic_mapping,
868                         &info->sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
869                 goto done;
870         }
871
872         info = samr_policy_handle_find(p,
873                                        r->in.handle,
874                                        SAMR_HANDLE_ALIAS,
875                                        SEC_STD_READ_CONTROL,
876                                        NULL,
877                                        &status);
878         if (NT_STATUS_IS_OK(status)) {
879                 /*
880                  * TODO: different SDs have to be generated for aliases groups
881                  * and users.  Currently all three get a default user SD
882                  */
883                 DEBUG(10,("_samr_QuerySecurity: querying security on alias "
884                           "Object with SID: %s\n",
885                           dom_sid_str_buf(&info->sid, &buf)));
886                 status = make_samr_object_sd(
887                         p->mem_ctx, &psd, &sd_size,
888                         &usr_nopwchange_generic_mapping,
889                         &info->sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
890                 goto done;
891         }
892
893         return NT_STATUS_OBJECT_TYPE_MISMATCH;
894 done:
895         if ((*r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
896                 return NT_STATUS_NO_MEMORY;
897
898         return status;
899 }
900
901 /*******************************************************************
902 makes a SAM_ENTRY / UNISTR2* structure from a user list.
903 ********************************************************************/
904
905 static NTSTATUS make_user_sam_entry_list(TALLOC_CTX *ctx,
906                                          struct samr_SamEntry **sam_pp,
907                                          uint32_t num_entries,
908                                          uint32_t start_idx,
909                                          struct samr_displayentry *entries)
910 {
911         uint32_t i;
912         struct samr_SamEntry *sam;
913
914         *sam_pp = NULL;
915
916         if (num_entries == 0) {
917                 return NT_STATUS_OK;
918         }
919
920         sam = talloc_zero_array(ctx, struct samr_SamEntry, num_entries);
921         if (sam == NULL) {
922                 DEBUG(0, ("make_user_sam_entry_list: TALLOC_ZERO failed!\n"));
923                 return NT_STATUS_NO_MEMORY;
924         }
925
926         for (i = 0; i < num_entries; i++) {
927 #if 0
928                 /*
929                  * usrmgr expects a non-NULL terminated string with
930                  * trust relationships
931                  */
932                 if (entries[i].acct_flags & ACB_DOMTRUST) {
933                         init_unistr2(&uni_temp_name, entries[i].account_name,
934                                      UNI_FLAGS_NONE);
935                 } else {
936                         init_unistr2(&uni_temp_name, entries[i].account_name,
937                                      UNI_STR_TERMINATE);
938                 }
939 #endif
940                 init_lsa_String(&sam[i].name, entries[i].account_name);
941                 sam[i].idx = entries[i].rid;
942         }
943
944         *sam_pp = sam;
945
946         return NT_STATUS_OK;
947 }
948
949 #define MAX_SAM_ENTRIES MAX_SAM_ENTRIES_W2K
950
951 /*******************************************************************
952  _samr_EnumDomainUsers
953  ********************************************************************/
954
955 NTSTATUS _samr_EnumDomainUsers(struct pipes_struct *p,
956                                struct samr_EnumDomainUsers *r)
957 {
958         NTSTATUS status;
959         struct samr_info *dinfo;
960         uint32_t num_account;
961         uint32_t enum_context = *r->in.resume_handle;
962         enum remote_arch_types ra_type = get_remote_arch();
963         int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
964         uint32_t max_entries = max_sam_entries;
965         struct samr_displayentry *entries = NULL;
966         struct samr_SamArray *samr_array = NULL;
967         struct samr_SamEntry *samr_entries = NULL;
968
969         DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
970
971         dinfo = samr_policy_handle_find(p,
972                                         r->in.domain_handle,
973                                         SAMR_HANDLE_DOMAIN,
974                                         SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
975                                         NULL,
976                                         &status);
977         if (!NT_STATUS_IS_OK(status)) {
978                 return status;
979         }
980
981         samr_array = talloc_zero(p->mem_ctx, struct samr_SamArray);
982         if (!samr_array) {
983                 return NT_STATUS_NO_MEMORY;
984         }
985         *r->out.sam = samr_array;
986
987         if (sid_check_is_builtin(&dinfo->sid)) {
988                 /* No users in builtin. */
989                 *r->out.resume_handle = *r->in.resume_handle;
990                 DEBUG(5,("_samr_EnumDomainUsers: No users in BUILTIN\n"));
991                 return status;
992         }
993
994         become_root();
995
996         /* AS ROOT !!!! */
997
998         if ((dinfo->disp_info->enum_users != NULL) &&
999             (dinfo->disp_info->enum_acb_mask != r->in.acct_flags)) {
1000                 TALLOC_FREE(dinfo->disp_info->enum_users);
1001         }
1002
1003         if (dinfo->disp_info->enum_users == NULL) {
1004                 dinfo->disp_info->enum_users = pdb_search_users(
1005                         dinfo->disp_info, r->in.acct_flags);
1006                 dinfo->disp_info->enum_acb_mask = r->in.acct_flags;
1007         }
1008
1009         if (dinfo->disp_info->enum_users == NULL) {
1010                 /* END AS ROOT !!!! */
1011                 unbecome_root();
1012                 return NT_STATUS_ACCESS_DENIED;
1013         }
1014
1015         num_account = pdb_search_entries(dinfo->disp_info->enum_users,
1016                                          enum_context, max_entries,
1017                                          &entries);
1018
1019         /* END AS ROOT !!!! */
1020
1021         unbecome_root();
1022
1023         if (num_account == 0) {
1024                 DEBUG(5, ("_samr_EnumDomainUsers: enumeration handle over "
1025                           "total entries\n"));
1026                 *r->out.resume_handle = *r->in.resume_handle;
1027                 return NT_STATUS_OK;
1028         }
1029
1030         status = make_user_sam_entry_list(p->mem_ctx, &samr_entries,
1031                                           num_account, enum_context,
1032                                           entries);
1033         if (!NT_STATUS_IS_OK(status)) {
1034                 return status;
1035         }
1036
1037         if (max_entries <= num_account) {
1038                 status = STATUS_MORE_ENTRIES;
1039         } else {
1040                 status = NT_STATUS_OK;
1041         }
1042
1043         /* Ensure we cache this enumeration. */
1044         set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
1045
1046         DEBUG(5, ("_samr_EnumDomainUsers: %d\n", __LINE__));
1047
1048         samr_array->count = num_account;
1049         samr_array->entries = samr_entries;
1050
1051         *r->out.resume_handle = *r->in.resume_handle + num_account;
1052         *r->out.num_entries = num_account;
1053
1054         DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
1055
1056         return status;
1057 }
1058
1059 /*******************************************************************
1060 makes a SAM_ENTRY / UNISTR2* structure from a group list.
1061 ********************************************************************/
1062
1063 static void make_group_sam_entry_list(TALLOC_CTX *ctx,
1064                                       struct samr_SamEntry **sam_pp,
1065                                       uint32_t num_sam_entries,
1066                                       struct samr_displayentry *entries)
1067 {
1068         struct samr_SamEntry *sam;
1069         uint32_t i;
1070
1071         *sam_pp = NULL;
1072
1073         if (num_sam_entries == 0) {
1074                 return;
1075         }
1076
1077         sam = talloc_zero_array(ctx, struct samr_SamEntry, num_sam_entries);
1078         if (sam == NULL) {
1079                 return;
1080         }
1081
1082         for (i = 0; i < num_sam_entries; i++) {
1083                 /*
1084                  * JRA. I think this should include the null. TNG does not.
1085                  */
1086                 init_lsa_String(&sam[i].name, entries[i].account_name);
1087                 sam[i].idx = entries[i].rid;
1088         }
1089
1090         *sam_pp = sam;
1091 }
1092
1093 /*******************************************************************
1094  _samr_EnumDomainGroups
1095  ********************************************************************/
1096
1097 NTSTATUS _samr_EnumDomainGroups(struct pipes_struct *p,
1098                                 struct samr_EnumDomainGroups *r)
1099 {
1100         NTSTATUS status;
1101         struct samr_info *dinfo;
1102         struct samr_displayentry *groups;
1103         uint32_t num_groups;
1104         struct samr_SamArray *samr_array = NULL;
1105         struct samr_SamEntry *samr_entries = NULL;
1106
1107         dinfo = samr_policy_handle_find(p,
1108                                         r->in.domain_handle,
1109                                         SAMR_HANDLE_DOMAIN,
1110                                         SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
1111                                         NULL,
1112                                         &status);
1113         if (!NT_STATUS_IS_OK(status)) {
1114                 return status;
1115         }
1116
1117         DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
1118
1119         samr_array = talloc_zero(p->mem_ctx, struct samr_SamArray);
1120         if (!samr_array) {
1121                 return NT_STATUS_NO_MEMORY;
1122         }
1123         *r->out.sam = samr_array;
1124
1125         if (sid_check_is_builtin(&dinfo->sid)) {
1126                 /* No groups in builtin. */
1127                 *r->out.resume_handle = *r->in.resume_handle;
1128                 DEBUG(5,("_samr_EnumDomainGroups: No groups in BUILTIN\n"));
1129                 return status;
1130         }
1131
1132         /* the domain group array is being allocated in the function below */
1133
1134         become_root();
1135
1136         if (dinfo->disp_info->groups == NULL) {
1137                 dinfo->disp_info->groups = pdb_search_groups(dinfo->disp_info);
1138
1139                 if (dinfo->disp_info->groups == NULL) {
1140                         unbecome_root();
1141                         return NT_STATUS_ACCESS_DENIED;
1142                 }
1143         }
1144
1145         num_groups = pdb_search_entries(dinfo->disp_info->groups,
1146                                         *r->in.resume_handle,
1147                                         MAX_SAM_ENTRIES, &groups);
1148         unbecome_root();
1149
1150         /* Ensure we cache this enumeration. */
1151         set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
1152
1153         make_group_sam_entry_list(p->mem_ctx, &samr_entries,
1154                                   num_groups, groups);
1155
1156         if (MAX_SAM_ENTRIES <= num_groups) {
1157                 status = STATUS_MORE_ENTRIES;
1158         } else {
1159                 status = NT_STATUS_OK;
1160         }
1161
1162         samr_array->count = num_groups;
1163         samr_array->entries = samr_entries;
1164
1165         *r->out.num_entries = num_groups;
1166         *r->out.resume_handle = num_groups + *r->in.resume_handle;
1167
1168         DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
1169
1170         return status;
1171 }
1172
1173 /*******************************************************************
1174  _samr_EnumDomainAliases
1175  ********************************************************************/
1176
1177 NTSTATUS _samr_EnumDomainAliases(struct pipes_struct *p,
1178                                  struct samr_EnumDomainAliases *r)
1179 {
1180         NTSTATUS status;
1181         struct samr_info *dinfo;
1182         struct samr_displayentry *aliases;
1183         uint32_t num_aliases = 0;
1184         struct samr_SamArray *samr_array = NULL;
1185         struct samr_SamEntry *samr_entries = NULL;
1186         struct dom_sid_buf buf;
1187
1188         dinfo = samr_policy_handle_find(p,
1189                                         r->in.domain_handle,
1190                                         SAMR_HANDLE_DOMAIN,
1191                                         SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
1192                                         NULL,
1193                                         &status);
1194         if (!NT_STATUS_IS_OK(status)) {
1195                 return status;
1196         }
1197
1198         DEBUG(5,("_samr_EnumDomainAliases: sid %s\n",
1199                  dom_sid_str_buf(&dinfo->sid, &buf)));
1200
1201         samr_array = talloc_zero(p->mem_ctx, struct samr_SamArray);
1202         if (!samr_array) {
1203                 return NT_STATUS_NO_MEMORY;
1204         }
1205
1206         become_root();
1207
1208         if (dinfo->disp_info->aliases == NULL) {
1209                 dinfo->disp_info->aliases = pdb_search_aliases(
1210                         dinfo->disp_info, &dinfo->sid);
1211                 if (dinfo->disp_info->aliases == NULL) {
1212                         unbecome_root();
1213                         return NT_STATUS_ACCESS_DENIED;
1214                 }
1215         }
1216
1217         num_aliases = pdb_search_entries(dinfo->disp_info->aliases,
1218                                          *r->in.resume_handle,
1219                                          MAX_SAM_ENTRIES, &aliases);
1220         unbecome_root();
1221
1222         /* Ensure we cache this enumeration. */
1223         set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
1224
1225         make_group_sam_entry_list(p->mem_ctx, &samr_entries,
1226                                   num_aliases, aliases);
1227
1228         DEBUG(5,("_samr_EnumDomainAliases: %d\n", __LINE__));
1229
1230         if (MAX_SAM_ENTRIES <= num_aliases) {
1231                 status = STATUS_MORE_ENTRIES;
1232         } else {
1233                 status = NT_STATUS_OK;
1234         }
1235
1236         samr_array->count = num_aliases;
1237         samr_array->entries = samr_entries;
1238
1239         *r->out.sam = samr_array;
1240         *r->out.num_entries = num_aliases;
1241         *r->out.resume_handle = num_aliases + *r->in.resume_handle;
1242
1243         return status;
1244 }
1245
1246 /*******************************************************************
1247  inits a samr_DispInfoGeneral structure.
1248 ********************************************************************/
1249
1250 static NTSTATUS init_samr_dispinfo_1(TALLOC_CTX *ctx,
1251                                      struct samr_DispInfoGeneral *r,
1252                                      uint32_t num_entries,
1253                                      uint32_t start_idx,
1254                                      struct samr_displayentry *entries)
1255 {
1256         uint32_t i;
1257
1258         DEBUG(10, ("init_samr_dispinfo_1: num_entries: %d\n", num_entries));
1259
1260         if (num_entries == 0) {
1261                 return NT_STATUS_OK;
1262         }
1263
1264         r->count = num_entries;
1265
1266         r->entries = talloc_zero_array(ctx, struct samr_DispEntryGeneral, num_entries);
1267         if (!r->entries) {
1268                 return NT_STATUS_NO_MEMORY;
1269         }
1270
1271         for (i = 0; i < num_entries ; i++) {
1272
1273                 init_lsa_String(&r->entries[i].account_name,
1274                                 entries[i].account_name);
1275
1276                 init_lsa_String(&r->entries[i].description,
1277                                 entries[i].description);
1278
1279                 init_lsa_String(&r->entries[i].full_name,
1280                                 entries[i].fullname);
1281
1282                 r->entries[i].rid = entries[i].rid;
1283                 r->entries[i].acct_flags = entries[i].acct_flags;
1284                 r->entries[i].idx = start_idx+i+1;
1285         }
1286
1287         return NT_STATUS_OK;
1288 }
1289
1290 /*******************************************************************
1291  inits a samr_DispInfoFull structure.
1292 ********************************************************************/
1293
1294 static NTSTATUS init_samr_dispinfo_2(TALLOC_CTX *ctx,
1295                                      struct samr_DispInfoFull *r,
1296                                      uint32_t num_entries,
1297                                      uint32_t start_idx,
1298                                      struct samr_displayentry *entries)
1299 {
1300         uint32_t i;
1301
1302         DEBUG(10, ("init_samr_dispinfo_2: num_entries: %d\n", num_entries));
1303
1304         if (num_entries == 0) {
1305                 return NT_STATUS_OK;
1306         }
1307
1308         r->count = num_entries;
1309
1310         r->entries = talloc_zero_array(ctx, struct samr_DispEntryFull, num_entries);
1311         if (!r->entries) {
1312                 return NT_STATUS_NO_MEMORY;
1313         }
1314
1315         for (i = 0; i < num_entries ; i++) {
1316
1317                 init_lsa_String(&r->entries[i].account_name,
1318                                 entries[i].account_name);
1319
1320                 init_lsa_String(&r->entries[i].description,
1321                                 entries[i].description);
1322
1323                 r->entries[i].rid = entries[i].rid;
1324                 r->entries[i].acct_flags = entries[i].acct_flags;
1325                 r->entries[i].idx = start_idx+i+1;
1326         }
1327
1328         return NT_STATUS_OK;
1329 }
1330
1331 /*******************************************************************
1332  inits a samr_DispInfoFullGroups structure.
1333 ********************************************************************/
1334
1335 static NTSTATUS init_samr_dispinfo_3(TALLOC_CTX *ctx,
1336                                      struct samr_DispInfoFullGroups *r,
1337                                      uint32_t num_entries,
1338                                      uint32_t start_idx,
1339                                      struct samr_displayentry *entries)
1340 {
1341         uint32_t i;
1342
1343         DEBUG(5, ("init_samr_dispinfo_3: num_entries: %d\n", num_entries));
1344
1345         if (num_entries == 0) {
1346                 return NT_STATUS_OK;
1347         }
1348
1349         r->count = num_entries;
1350
1351         r->entries = talloc_zero_array(ctx, struct samr_DispEntryFullGroup, num_entries);
1352         if (!r->entries) {
1353                 return NT_STATUS_NO_MEMORY;
1354         }
1355
1356         for (i = 0; i < num_entries ; i++) {
1357
1358                 init_lsa_String(&r->entries[i].account_name,
1359                                 entries[i].account_name);
1360
1361                 init_lsa_String(&r->entries[i].description,
1362                                 entries[i].description);
1363
1364                 r->entries[i].rid = entries[i].rid;
1365                 r->entries[i].acct_flags = entries[i].acct_flags;
1366                 r->entries[i].idx = start_idx+i+1;
1367         }
1368
1369         return NT_STATUS_OK;
1370 }
1371
1372 /*******************************************************************
1373  inits a samr_DispInfoAscii structure.
1374 ********************************************************************/
1375
1376 static NTSTATUS init_samr_dispinfo_4(TALLOC_CTX *ctx,
1377                                      struct samr_DispInfoAscii *r,
1378                                      uint32_t num_entries,
1379                                      uint32_t start_idx,
1380                                      struct samr_displayentry *entries)
1381 {
1382         uint32_t i;
1383
1384         DEBUG(5, ("init_samr_dispinfo_4: num_entries: %d\n", num_entries));
1385
1386         if (num_entries == 0) {
1387                 return NT_STATUS_OK;
1388         }
1389
1390         r->count = num_entries;
1391
1392         r->entries = talloc_zero_array(ctx, struct samr_DispEntryAscii, num_entries);
1393         if (!r->entries) {
1394                 return NT_STATUS_NO_MEMORY;
1395         }
1396
1397         for (i = 0; i < num_entries ; i++) {
1398
1399                 init_lsa_AsciiStringLarge(&r->entries[i].account_name,
1400                                           entries[i].account_name);
1401
1402                 r->entries[i].idx = start_idx+i+1;
1403         }
1404
1405         return NT_STATUS_OK;
1406 }
1407
1408 /*******************************************************************
1409  inits a samr_DispInfoAscii structure.
1410 ********************************************************************/
1411
1412 static NTSTATUS init_samr_dispinfo_5(TALLOC_CTX *ctx,
1413                                      struct samr_DispInfoAscii *r,
1414                                      uint32_t num_entries,
1415                                      uint32_t start_idx,
1416                                      struct samr_displayentry *entries)
1417 {
1418         uint32_t i;
1419
1420         DEBUG(5, ("init_samr_dispinfo_5: num_entries: %d\n", num_entries));
1421
1422         if (num_entries == 0) {
1423                 return NT_STATUS_OK;
1424         }
1425
1426         r->count = num_entries;
1427
1428         r->entries = talloc_zero_array(ctx, struct samr_DispEntryAscii, num_entries);
1429         if (!r->entries) {
1430                 return NT_STATUS_NO_MEMORY;
1431         }
1432
1433         for (i = 0; i < num_entries ; i++) {
1434
1435                 init_lsa_AsciiStringLarge(&r->entries[i].account_name,
1436                                           entries[i].account_name);
1437
1438                 r->entries[i].idx = start_idx+i+1;
1439         }
1440
1441         return NT_STATUS_OK;
1442 }
1443
1444 /*******************************************************************
1445  _samr_QueryDisplayInfo
1446  ********************************************************************/
1447
1448 NTSTATUS _samr_QueryDisplayInfo(struct pipes_struct *p,
1449                                 struct samr_QueryDisplayInfo *r)
1450 {
1451         NTSTATUS status;
1452         struct samr_info *dinfo;
1453         uint32_t struct_size=0x20; /* W2K always reply that, client doesn't care */
1454
1455         uint32_t max_entries = r->in.max_entries;
1456
1457         union samr_DispInfo *disp_info = r->out.info;
1458
1459         uint32_t temp_size=0;
1460         NTSTATUS disp_ret = NT_STATUS_UNSUCCESSFUL;
1461         uint32_t num_account = 0;
1462         enum remote_arch_types ra_type = get_remote_arch();
1463         uint32_t max_sam_entries = (ra_type == RA_WIN95) ?
1464                 MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
1465         struct samr_displayentry *entries = NULL;
1466
1467         DEBUG(5,("_samr_QueryDisplayInfo: %d\n", __LINE__));
1468
1469         dinfo = samr_policy_handle_find(p,
1470                                         r->in.domain_handle,
1471                                         SAMR_HANDLE_DOMAIN,
1472                                         SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
1473                                         NULL,
1474                                         &status);
1475         if (!NT_STATUS_IS_OK(status)) {
1476                 return status;
1477         }
1478
1479         if (sid_check_is_builtin(&dinfo->sid)) {
1480                 DEBUG(5,("_samr_QueryDisplayInfo: no users in BUILTIN\n"));
1481                 return NT_STATUS_OK;
1482         }
1483
1484         /*
1485          * calculate how many entries we will return.
1486          * based on
1487          * - the number of entries the client asked
1488          * - our limit on that
1489          * - the starting point (enumeration context)
1490          * - the buffer size the client will accept
1491          */
1492
1493         /*
1494          * We are a lot more like W2K. Instead of reading the SAM
1495          * each time to find the records we need to send back,
1496          * we read it once and link that copy to the sam handle.
1497          * For large user list (over the MAX_SAM_ENTRIES)
1498          * it's a definitive win.
1499          * second point to notice: between enumerations
1500          * our sam is now the same as it's a snapshoot.
1501          * third point: got rid of the static SAM_USER_21 struct
1502          * no more intermediate.
1503          * con: it uses much more memory, as a full copy is stored
1504          * in memory.
1505          *
1506          * If you want to change it, think twice and think
1507          * of the second point , that's really important.
1508          *
1509          * JFM, 12/20/2001
1510          */
1511
1512         if ((r->in.level < 1) || (r->in.level > 5)) {
1513                 DEBUG(0,("_samr_QueryDisplayInfo: Unknown info level (%u)\n",
1514                          (unsigned int)r->in.level ));
1515                 return NT_STATUS_INVALID_INFO_CLASS;
1516         }
1517
1518         /* first limit the number of entries we will return */
1519         if (r->in.max_entries > max_sam_entries) {
1520                 DEBUG(5, ("_samr_QueryDisplayInfo: client requested %d "
1521                           "entries, limiting to %d\n", r->in.max_entries,
1522                           max_sam_entries));
1523                 max_entries = max_sam_entries;
1524         }
1525
1526         /* calculate the size and limit on the number of entries we will
1527          * return */
1528
1529         temp_size=max_entries*struct_size;
1530
1531         if (temp_size > r->in.buf_size) {
1532                 max_entries = MIN((r->in.buf_size / struct_size),max_entries);
1533                 DEBUG(5, ("_samr_QueryDisplayInfo: buffer size limits to "
1534                           "only %d entries\n", max_entries));
1535         }
1536
1537         become_root();
1538
1539         /* THe following done as ROOT. Don't return without unbecome_root(). */
1540
1541         switch (r->in.level) {
1542         case 1:
1543         case 4:
1544                 if (dinfo->disp_info->users == NULL) {
1545                         dinfo->disp_info->users = pdb_search_users(
1546                                 dinfo->disp_info, ACB_NORMAL);
1547                         if (dinfo->disp_info->users == NULL) {
1548                                 unbecome_root();
1549                                 return NT_STATUS_ACCESS_DENIED;
1550                         }
1551                         DEBUG(10,("_samr_QueryDisplayInfo: starting user enumeration at index %u\n",
1552                                 (unsigned  int)r->in.start_idx));
1553                 } else {
1554                         DEBUG(10,("_samr_QueryDisplayInfo: using cached user enumeration at index %u\n",
1555                                 (unsigned  int)r->in.start_idx));
1556                 }
1557
1558                 num_account = pdb_search_entries(dinfo->disp_info->users,
1559                                                  r->in.start_idx, max_entries,
1560                                                  &entries);
1561                 break;
1562         case 2:
1563                 if (dinfo->disp_info->machines == NULL) {
1564                         dinfo->disp_info->machines = pdb_search_users(
1565                                 dinfo->disp_info, ACB_WSTRUST|ACB_SVRTRUST);
1566                         if (dinfo->disp_info->machines == NULL) {
1567                                 unbecome_root();
1568                                 return NT_STATUS_ACCESS_DENIED;
1569                         }
1570                         DEBUG(10,("_samr_QueryDisplayInfo: starting machine enumeration at index %u\n",
1571                                 (unsigned  int)r->in.start_idx));
1572                 } else {
1573                         DEBUG(10,("_samr_QueryDisplayInfo: using cached machine enumeration at index %u\n",
1574                                 (unsigned  int)r->in.start_idx));
1575                 }
1576
1577                 num_account = pdb_search_entries(dinfo->disp_info->machines,
1578                                                  r->in.start_idx, max_entries,
1579                                                  &entries);
1580                 break;
1581         case 3:
1582         case 5:
1583                 if (dinfo->disp_info->groups == NULL) {
1584                         dinfo->disp_info->groups = pdb_search_groups(
1585                                 dinfo->disp_info);
1586                         if (dinfo->disp_info->groups == NULL) {
1587                                 unbecome_root();
1588                                 return NT_STATUS_ACCESS_DENIED;
1589                         }
1590                         DEBUG(10,("_samr_QueryDisplayInfo: starting group enumeration at index %u\n",
1591                                 (unsigned  int)r->in.start_idx));
1592                 } else {
1593                         DEBUG(10,("_samr_QueryDisplayInfo: using cached group enumeration at index %u\n",
1594                                 (unsigned  int)r->in.start_idx));
1595                 }
1596
1597                 num_account = pdb_search_entries(dinfo->disp_info->groups,
1598                                                  r->in.start_idx, max_entries,
1599                                                  &entries);
1600                 break;
1601         default:
1602                 unbecome_root();
1603                 smb_panic("info class changed");
1604                 break;
1605         }
1606         unbecome_root();
1607
1608
1609         /* Now create reply structure */
1610         switch (r->in.level) {
1611         case 1:
1612                 disp_ret = init_samr_dispinfo_1(p->mem_ctx, &disp_info->info1,
1613                                                 num_account, r->in.start_idx,
1614                                                 entries);
1615                 break;
1616         case 2:
1617                 disp_ret = init_samr_dispinfo_2(p->mem_ctx, &disp_info->info2,
1618                                                 num_account, r->in.start_idx,
1619                                                 entries);
1620                 break;
1621         case 3:
1622                 disp_ret = init_samr_dispinfo_3(p->mem_ctx, &disp_info->info3,
1623                                                 num_account, r->in.start_idx,
1624                                                 entries);
1625                 break;
1626         case 4:
1627                 disp_ret = init_samr_dispinfo_4(p->mem_ctx, &disp_info->info4,
1628                                                 num_account, r->in.start_idx,
1629                                                 entries);
1630                 break;
1631         case 5:
1632                 disp_ret = init_samr_dispinfo_5(p->mem_ctx, &disp_info->info5,
1633                                                 num_account, r->in.start_idx,
1634                                                 entries);
1635                 break;
1636         default:
1637                 smb_panic("info class changed");
1638                 break;
1639         }
1640
1641         if (!NT_STATUS_IS_OK(disp_ret))
1642                 return disp_ret;
1643
1644         if (max_entries <= num_account) {
1645                 status = STATUS_MORE_ENTRIES;
1646         } else {
1647                 status = NT_STATUS_OK;
1648         }
1649
1650         /* Ensure we cache this enumeration. */
1651         set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
1652
1653         DEBUG(5, ("_samr_QueryDisplayInfo: %d\n", __LINE__));
1654
1655         *r->out.total_size = num_account * struct_size;
1656         *r->out.returned_size = num_account ? temp_size : 0;
1657
1658         return status;
1659 }
1660
1661 /****************************************************************
1662  _samr_QueryDisplayInfo2
1663 ****************************************************************/
1664
1665 NTSTATUS _samr_QueryDisplayInfo2(struct pipes_struct *p,
1666                                  struct samr_QueryDisplayInfo2 *r)
1667 {
1668         struct samr_QueryDisplayInfo q;
1669
1670         q.in.domain_handle      = r->in.domain_handle;
1671         q.in.level              = r->in.level;
1672         q.in.start_idx          = r->in.start_idx;
1673         q.in.max_entries        = r->in.max_entries;
1674         q.in.buf_size           = r->in.buf_size;
1675
1676         q.out.total_size        = r->out.total_size;
1677         q.out.returned_size     = r->out.returned_size;
1678         q.out.info              = r->out.info;
1679
1680         return _samr_QueryDisplayInfo(p, &q);
1681 }
1682
1683 /****************************************************************
1684  _samr_QueryDisplayInfo3
1685 ****************************************************************/
1686
1687 NTSTATUS _samr_QueryDisplayInfo3(struct pipes_struct *p,
1688                                  struct samr_QueryDisplayInfo3 *r)
1689 {
1690         struct samr_QueryDisplayInfo q;
1691
1692         q.in.domain_handle      = r->in.domain_handle;
1693         q.in.level              = r->in.level;
1694         q.in.start_idx          = r->in.start_idx;
1695         q.in.max_entries        = r->in.max_entries;
1696         q.in.buf_size           = r->in.buf_size;
1697
1698         q.out.total_size        = r->out.total_size;
1699         q.out.returned_size     = r->out.returned_size;
1700         q.out.info              = r->out.info;
1701
1702         return _samr_QueryDisplayInfo(p, &q);
1703 }
1704
1705 /*******************************************************************
1706  _samr_QueryAliasInfo
1707  ********************************************************************/
1708
1709 NTSTATUS _samr_QueryAliasInfo(struct pipes_struct *p,
1710                               struct samr_QueryAliasInfo *r)
1711 {
1712         struct samr_info *ainfo;
1713         struct acct_info *info;
1714         NTSTATUS status;
1715         union samr_AliasInfo *alias_info = NULL;
1716         const char *alias_name = NULL;
1717         const char *alias_description = NULL;
1718
1719         DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1720
1721         ainfo = samr_policy_handle_find(p,
1722                                         r->in.alias_handle,
1723                                         SAMR_HANDLE_ALIAS,
1724                                         SAMR_ALIAS_ACCESS_LOOKUP_INFO,
1725                                         NULL,
1726                                         &status);
1727         if (!NT_STATUS_IS_OK(status)) {
1728                 return status;
1729         }
1730
1731         alias_info = talloc_zero(p->mem_ctx, union samr_AliasInfo);
1732         if (!alias_info) {
1733                 return NT_STATUS_NO_MEMORY;
1734         }
1735
1736         info = talloc_zero(p->mem_ctx, struct acct_info);
1737         if (!info) {
1738                 return NT_STATUS_NO_MEMORY;
1739         }
1740
1741         become_root();
1742         status = pdb_get_aliasinfo(&ainfo->sid, info);
1743         unbecome_root();
1744
1745         if (!NT_STATUS_IS_OK(status)) {
1746                 TALLOC_FREE(info);
1747                 return status;
1748         }
1749
1750         alias_name = talloc_steal(r, info->acct_name);
1751         alias_description = talloc_steal(r, info->acct_desc);
1752         TALLOC_FREE(info);
1753
1754         switch (r->in.level) {
1755         case ALIASINFOALL:
1756                 alias_info->all.name.string             = alias_name;
1757                 alias_info->all.num_members             = 1; /* ??? */
1758                 alias_info->all.description.string      = alias_description;
1759                 break;
1760         case ALIASINFONAME:
1761                 alias_info->name.string                 = alias_name;
1762                 break;
1763         case ALIASINFODESCRIPTION:
1764                 alias_info->description.string          = alias_description;
1765                 break;
1766         default:
1767                 return NT_STATUS_INVALID_INFO_CLASS;
1768         }
1769
1770         *r->out.info = alias_info;
1771
1772         DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1773
1774         return NT_STATUS_OK;
1775 }
1776
1777 /*******************************************************************
1778  _samr_LookupNames
1779  ********************************************************************/
1780
1781 NTSTATUS _samr_LookupNames(struct pipes_struct *p,
1782                            struct samr_LookupNames *r)
1783 {
1784         struct samr_info *dinfo;
1785         NTSTATUS status;
1786         uint32_t *rid;
1787         enum lsa_SidType *type;
1788         uint32_t i, num_rids = r->in.num_names;
1789         struct samr_Ids rids, types;
1790         uint32_t num_mapped = 0;
1791         struct dom_sid_buf buf;
1792
1793         DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1794
1795         dinfo = samr_policy_handle_find(p,
1796                                         r->in.domain_handle,
1797                                         SAMR_HANDLE_DOMAIN,
1798                                         0 /* Don't know the acc_bits yet */,
1799                                         NULL,
1800                                         &status);
1801         if (!NT_STATUS_IS_OK(status)) {
1802                 return status;
1803         }
1804
1805         if (num_rids > MAX_SAM_ENTRIES) {
1806                 num_rids = MAX_SAM_ENTRIES;
1807                 DEBUG(5,("_samr_LookupNames: truncating entries to %d\n", num_rids));
1808         }
1809
1810         rid = talloc_array(p->mem_ctx, uint32_t, num_rids);
1811         NT_STATUS_HAVE_NO_MEMORY(rid);
1812
1813         type = talloc_array(p->mem_ctx, enum lsa_SidType, num_rids);
1814         NT_STATUS_HAVE_NO_MEMORY(type);
1815
1816         DEBUG(5,("_samr_LookupNames: looking name on SID %s\n",
1817                  dom_sid_str_buf(&dinfo->sid, &buf)));
1818
1819         for (i = 0; i < num_rids; i++) {
1820
1821                 status = NT_STATUS_NONE_MAPPED;
1822                 type[i] = SID_NAME_UNKNOWN;
1823
1824                 rid[i] = 0xffffffff;
1825
1826                 if (sid_check_is_builtin(&dinfo->sid)) {
1827                         if (lookup_builtin_name(r->in.names[i].string,
1828                                                 &rid[i]))
1829                         {
1830                                 type[i] = SID_NAME_ALIAS;
1831                         }
1832                 } else {
1833                         lookup_global_sam_name(r->in.names[i].string, 0,
1834                                                &rid[i], &type[i]);
1835                 }
1836
1837                 if (type[i] != SID_NAME_UNKNOWN) {
1838                         num_mapped++;
1839                 }
1840         }
1841
1842         if (num_mapped == num_rids) {
1843                 status = NT_STATUS_OK;
1844         } else if (num_mapped == 0) {
1845                 status = NT_STATUS_NONE_MAPPED;
1846         } else {
1847                 status = STATUS_SOME_UNMAPPED;
1848         }
1849
1850         rids.count = num_rids;
1851         rids.ids = rid;
1852
1853         types.count = num_rids;
1854         types.ids = talloc_array(p->mem_ctx, uint32_t, num_rids);
1855         NT_STATUS_HAVE_NO_MEMORY(type);
1856         for (i = 0; i < num_rids; i++) {
1857                 types.ids[i] = (type[i] & 0xffffffff);
1858         }
1859
1860         *r->out.rids = rids;
1861         *r->out.types = types;
1862
1863         DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1864
1865         return status;
1866 }
1867
1868 /****************************************************************
1869  _samr_ChangePasswordUser.
1870
1871  So old it is just not worth implementing
1872  because it does not supply a plaintext and so we can't do password
1873  complexity checking and cannot update other services that use a
1874  plaintext password via passwd chat/pam password change/ldap password
1875  sync.
1876 ****************************************************************/
1877
1878 NTSTATUS _samr_ChangePasswordUser(struct pipes_struct *p,
1879                                   struct samr_ChangePasswordUser *r)
1880 {
1881         return NT_STATUS_NOT_IMPLEMENTED;
1882 }
1883
1884 /*******************************************************************
1885  _samr_ChangePasswordUser2
1886  ********************************************************************/
1887
1888 NTSTATUS _samr_ChangePasswordUser2(struct pipes_struct *p,
1889                                    struct samr_ChangePasswordUser2 *r)
1890 {
1891         NTSTATUS status;
1892         char *user_name = NULL;
1893         char *rhost;
1894         const char *wks = NULL;
1895         bool encrypted;
1896
1897         DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1898
1899         if (!r->in.account->string) {
1900                 return NT_STATUS_INVALID_PARAMETER;
1901         }
1902         if (r->in.server && r->in.server->string) {
1903                 wks = r->in.server->string;
1904         }
1905
1906         DEBUG(5,("_samr_ChangePasswordUser2: user: %s wks: %s\n", user_name, wks));
1907
1908         /*
1909          * Pass the user through the NT -> unix user mapping
1910          * function.
1911          */
1912
1913         (void)map_username(talloc_tos(), r->in.account->string, &user_name);
1914         if (!user_name) {
1915                 return NT_STATUS_NO_MEMORY;
1916         }
1917
1918         rhost = tsocket_address_inet_addr_string(p->remote_address,
1919                                                  talloc_tos());
1920         if (rhost == NULL) {
1921                 return NT_STATUS_NO_MEMORY;
1922         }
1923
1924         encrypted = dcerpc_is_transport_encrypted(p->session_info);
1925         if (lp_weak_crypto() == SAMBA_WEAK_CRYPTO_DISALLOWED &&
1926             !encrypted) {
1927                 return NT_STATUS_ACCESS_DENIED;
1928         }
1929
1930         /*
1931          * UNIX username case mangling not required, pass_oem_change
1932          * is case insensitive.
1933          */
1934
1935         status = pass_oem_change(user_name,
1936                                  rhost,
1937                                  r->in.lm_password->data,
1938                                  r->in.lm_verifier->hash,
1939                                  r->in.nt_password->data,
1940                                  r->in.nt_verifier->hash,
1941                                  NULL);
1942
1943         DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1944
1945         if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
1946                 return NT_STATUS_WRONG_PASSWORD;
1947         }
1948
1949         return status;
1950 }
1951
1952 /****************************************************************
1953  _samr_OemChangePasswordUser2
1954 ****************************************************************/
1955
1956 NTSTATUS _samr_OemChangePasswordUser2(struct pipes_struct *p,
1957                                       struct samr_OemChangePasswordUser2 *r)
1958 {
1959         NTSTATUS status;
1960         char *user_name = NULL;
1961         const char *wks = NULL;
1962         char *rhost;
1963         bool encrypted;
1964
1965         DEBUG(5,("_samr_OemChangePasswordUser2: %d\n", __LINE__));
1966
1967         if (!r->in.account->string) {
1968                 return NT_STATUS_INVALID_PARAMETER;
1969         }
1970         if (r->in.server && r->in.server->string) {
1971                 wks = r->in.server->string;
1972         }
1973
1974         DEBUG(5,("_samr_OemChangePasswordUser2: user: %s wks: %s\n", user_name, wks));
1975
1976         /*
1977          * Pass the user through the NT -> unix user mapping
1978          * function.
1979          */
1980
1981         (void)map_username(talloc_tos(), r->in.account->string, &user_name);
1982         if (!user_name) {
1983                 return NT_STATUS_NO_MEMORY;
1984         }
1985
1986         /*
1987          * UNIX username case mangling not required, pass_oem_change
1988          * is case insensitive.
1989          */
1990
1991         if (!r->in.hash || !r->in.password) {
1992                 return NT_STATUS_INVALID_PARAMETER;
1993         }
1994
1995         rhost = tsocket_address_inet_addr_string(p->remote_address,
1996                                                  talloc_tos());
1997         if (rhost == NULL) {
1998                 return NT_STATUS_NO_MEMORY;
1999         }
2000
2001         encrypted = dcerpc_is_transport_encrypted(p->session_info);
2002         if (lp_weak_crypto() == SAMBA_WEAK_CRYPTO_DISALLOWED &&
2003             !encrypted) {
2004                 return NT_STATUS_ACCESS_DENIED;
2005         }
2006
2007         status = pass_oem_change(user_name,
2008                                  rhost,
2009                                  r->in.password->data,
2010                                  r->in.hash->hash,
2011                                  0,
2012                                  0,
2013                                  NULL);
2014
2015         if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
2016                 return NT_STATUS_WRONG_PASSWORD;
2017         }
2018
2019         DEBUG(5,("_samr_OemChangePasswordUser2: %d\n", __LINE__));
2020
2021         return status;
2022 }
2023
2024 /*******************************************************************
2025  _samr_ChangePasswordUser3
2026  ********************************************************************/
2027
2028 NTSTATUS _samr_ChangePasswordUser3(struct pipes_struct *p,
2029                                    struct samr_ChangePasswordUser3 *r)
2030 {
2031         NTSTATUS status;
2032         char *user_name = NULL;
2033         const char *wks = NULL;
2034         enum samPwdChangeReason reject_reason;
2035         struct samr_DomInfo1 *dominfo = NULL;
2036         struct userPwdChangeFailureInformation *reject = NULL;
2037         const struct loadparm_substitution *lp_sub =
2038                 loadparm_s3_global_substitution();
2039         uint32_t tmp;
2040         char *rhost;
2041
2042         DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
2043
2044         if (!r->in.account->string) {
2045                 return NT_STATUS_INVALID_PARAMETER;
2046         }
2047         if (r->in.server && r->in.server->string) {
2048                 wks = r->in.server->string;
2049         }
2050
2051         DEBUG(5,("_samr_ChangePasswordUser3: user: %s wks: %s\n", user_name, wks));
2052
2053         /*
2054          * Pass the user through the NT -> unix user mapping
2055          * function.
2056          */
2057
2058         (void)map_username(talloc_tos(), r->in.account->string, &user_name);
2059         if (!user_name) {
2060                 return NT_STATUS_NO_MEMORY;
2061         }
2062
2063         rhost = tsocket_address_inet_addr_string(p->remote_address,
2064                                                  talloc_tos());
2065         if (rhost == NULL) {
2066                 return NT_STATUS_NO_MEMORY;
2067         }
2068
2069         /*
2070          * UNIX username case mangling not required, pass_oem_change
2071          * is case insensitive.
2072          */
2073
2074         status = pass_oem_change(user_name,
2075                                  rhost,
2076                                  r->in.lm_password->data,
2077                                  r->in.lm_verifier->hash,
2078                                  r->in.nt_password->data,
2079                                  r->in.nt_verifier->hash,
2080                                  &reject_reason);
2081         if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
2082                 return NT_STATUS_WRONG_PASSWORD;
2083         }
2084
2085         if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) ||
2086             NT_STATUS_EQUAL(status, NT_STATUS_ACCOUNT_RESTRICTION)) {
2087
2088                 time_t u_expire, u_min_age;
2089                 uint32_t account_policy_temp;
2090
2091                 dominfo = talloc_zero(p->mem_ctx, struct samr_DomInfo1);
2092                 if (!dominfo) {
2093                         return NT_STATUS_NO_MEMORY;
2094                 }
2095
2096                 reject = talloc_zero(p->mem_ctx,
2097                                 struct userPwdChangeFailureInformation);
2098                 if (!reject) {
2099                         return NT_STATUS_NO_MEMORY;
2100                 }
2101
2102                 become_root();
2103
2104                 /* AS ROOT !!! */
2105
2106                 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN, &tmp);
2107                 dominfo->min_password_length = tmp;
2108
2109                 pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &tmp);
2110                 dominfo->password_history_length = tmp;
2111
2112                 pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
2113                                        &dominfo->password_properties);
2114
2115                 pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, &account_policy_temp);
2116                 u_expire = account_policy_temp;
2117
2118                 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, &account_policy_temp);
2119                 u_min_age = account_policy_temp;
2120
2121                 /* !AS ROOT */
2122
2123                 unbecome_root();
2124
2125                 unix_to_nt_time_abs((NTTIME *)&dominfo->max_password_age, u_expire);
2126                 unix_to_nt_time_abs((NTTIME *)&dominfo->min_password_age, u_min_age);
2127
2128                 if (lp_check_password_script(talloc_tos(), lp_sub)
2129                         && *lp_check_password_script(talloc_tos(), lp_sub)) {
2130                         dominfo->password_properties |= DOMAIN_PASSWORD_COMPLEX;
2131                 }
2132
2133                 reject->extendedFailureReason = reject_reason;
2134
2135                 *r->out.dominfo = dominfo;
2136                 *r->out.reject = reject;
2137         }
2138
2139         DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
2140
2141         return status;
2142 }
2143
2144 /*******************************************************************
2145 makes a SAMR_R_LOOKUP_RIDS structure.
2146 ********************************************************************/
2147
2148 static bool make_samr_lookup_rids(TALLOC_CTX *ctx, uint32_t num_names,
2149                                   const char **names,
2150                                   struct lsa_String **lsa_name_array_p)
2151 {
2152         struct lsa_String *lsa_name_array = NULL;
2153         uint32_t i;
2154
2155         *lsa_name_array_p = NULL;
2156
2157         if (num_names != 0) {
2158                 lsa_name_array = talloc_zero_array(ctx, struct lsa_String, num_names);
2159                 if (!lsa_name_array) {
2160                         return false;
2161                 }
2162         }
2163
2164         for (i = 0; i < num_names; i++) {
2165                 DEBUG(10, ("names[%d]:%s\n", i, names[i] && *names[i] ? names[i] : ""));
2166                 init_lsa_String(&lsa_name_array[i], names[i]);
2167         }
2168
2169         *lsa_name_array_p = lsa_name_array;
2170
2171         return true;
2172 }
2173
2174 /*******************************************************************
2175  _samr_LookupRids
2176  ********************************************************************/
2177
2178 NTSTATUS _samr_LookupRids(struct pipes_struct *p,
2179                           struct samr_LookupRids *r)
2180 {
2181         struct samr_info *dinfo;
2182         NTSTATUS status;
2183         const char **names;
2184         enum lsa_SidType *attrs = NULL;
2185         uint32_t *wire_attrs = NULL;
2186         int num_rids = (int)r->in.num_rids;
2187         int i;
2188         struct lsa_Strings names_array;
2189         struct samr_Ids types_array;
2190         struct lsa_String *lsa_names = NULL;
2191
2192         DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2193
2194         dinfo = samr_policy_handle_find(p,
2195                                         r->in.domain_handle,
2196                                         SAMR_HANDLE_DOMAIN,
2197                                         0 /* Don't know the acc_bits yet */,
2198                                         NULL,
2199                                         &status);
2200         if (!NT_STATUS_IS_OK(status)) {
2201                 return status;
2202         }
2203
2204         if (num_rids > 1000) {
2205                 DEBUG(0, ("Got asked for %d rids (more than 1000) -- according "
2206                           "to samba4 idl this is not possible\n", num_rids));
2207                 return NT_STATUS_UNSUCCESSFUL;
2208         }
2209
2210         if (num_rids) {
2211                 names = talloc_zero_array(p->mem_ctx, const char *, num_rids);
2212                 attrs = talloc_zero_array(p->mem_ctx, enum lsa_SidType, num_rids);
2213                 wire_attrs = talloc_zero_array(p->mem_ctx, uint32_t, num_rids);
2214
2215                 if ((names == NULL) || (attrs == NULL) || (wire_attrs==NULL))
2216                         return NT_STATUS_NO_MEMORY;
2217         } else {
2218                 names = NULL;
2219                 attrs = NULL;
2220                 wire_attrs = NULL;
2221         }
2222
2223         become_root();  /* lookup_sid can require root privs */
2224         status = pdb_lookup_rids(&dinfo->sid, num_rids, r->in.rids,
2225                                  names, attrs);
2226         unbecome_root();
2227
2228         if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED) && (num_rids == 0)) {
2229                 status = NT_STATUS_OK;
2230         }
2231
2232         if (!make_samr_lookup_rids(p->mem_ctx, num_rids, names,
2233                                    &lsa_names)) {
2234                 return NT_STATUS_NO_MEMORY;
2235         }
2236
2237         /* Convert from enum lsa_SidType to uint32_t for wire format. */
2238         for (i = 0; i < num_rids; i++) {
2239                 wire_attrs[i] = (uint32_t)attrs[i];
2240         }
2241
2242         names_array.count = num_rids;
2243         names_array.names = lsa_names;
2244
2245         types_array.count = num_rids;
2246         types_array.ids = wire_attrs;
2247
2248         *r->out.names = names_array;
2249         *r->out.types = types_array;
2250
2251         DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2252
2253         return status;
2254 }
2255
2256 /*******************************************************************
2257  _samr_OpenUser
2258 ********************************************************************/
2259
2260 NTSTATUS _samr_OpenUser(struct pipes_struct *p,
2261                         struct samr_OpenUser *r)
2262 {
2263         struct samu *sampass=NULL;
2264         struct dom_sid sid;
2265         struct samr_info *dinfo;
2266         struct security_descriptor *psd = NULL;
2267         uint32_t    acc_granted;
2268         uint32_t    des_access = r->in.access_mask;
2269         uint32_t extra_access = 0;
2270         size_t    sd_size;
2271         bool ret;
2272         NTSTATUS nt_status;
2273
2274         /* These two privileges, if != SEC_PRIV_INVALID, indicate
2275          * privileges that the user must have to complete this
2276          * operation in defience of the fixed ACL */
2277         enum sec_privilege needed_priv_1, needed_priv_2;
2278         NTSTATUS status;
2279
2280         dinfo = samr_policy_handle_find(p,
2281                                         r->in.domain_handle,
2282                                         SAMR_HANDLE_DOMAIN,
2283                                         SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
2284                                         NULL,
2285                                         &status);
2286         if (!NT_STATUS_IS_OK(status)) {
2287                 return status;
2288         }
2289
2290         if ( !(sampass = samu_new( p->mem_ctx )) ) {
2291                 return NT_STATUS_NO_MEMORY;
2292         }
2293
2294         /* append the user's RID to it */
2295
2296         if (!sid_compose(&sid, &dinfo->sid, r->in.rid))
2297                 return NT_STATUS_NO_SUCH_USER;
2298
2299         /* check if access can be granted as requested by client. */
2300         map_max_allowed_access(p->session_info->security_token,
2301                                p->session_info->unix_token,
2302                                &des_access);
2303
2304         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &sid, SAMR_USR_RIGHTS_WRITE_PW);
2305         se_map_generic(&des_access, &usr_generic_mapping);
2306
2307         /*
2308          * Get the sampass first as we need to check privileges
2309          * based on what kind of user object this is.
2310          * But don't reveal info too early if it didn't exist.
2311          */
2312
2313         become_root();
2314         ret=pdb_getsampwsid(sampass, &sid);
2315         unbecome_root();
2316
2317         needed_priv_1 = SEC_PRIV_INVALID;
2318         needed_priv_2 = SEC_PRIV_INVALID;
2319         /*
2320          * We do the override access checks on *open*, not at
2321          * SetUserInfo time.
2322          */
2323         if (ret) {
2324                 uint32_t acb_info = pdb_get_acct_ctrl(sampass);
2325
2326                 if (acb_info & ACB_WSTRUST) {
2327                         /*
2328                          * SeMachineAccount is needed to add
2329                          * GENERIC_RIGHTS_USER_WRITE to a machine
2330                          * account.
2331                          */
2332                         needed_priv_1 = SEC_PRIV_MACHINE_ACCOUNT;
2333                 }
2334                 if (acb_info & ACB_NORMAL) {
2335                         /*
2336                          * SeAddUsers is needed to add
2337                          * GENERIC_RIGHTS_USER_WRITE to a normal
2338                          * account.
2339                          */
2340                         needed_priv_1 = SEC_PRIV_ADD_USERS;
2341                 }
2342                 /*
2343                  * Cheat - we have not set a specific privilege for
2344                  * server (BDC) or domain trust account, so allow
2345                  * GENERIC_RIGHTS_USER_WRITE if pipe user is in
2346                  * DOMAIN_RID_ADMINS.
2347                  */
2348                 if (acb_info & (ACB_SVRTRUST|ACB_DOMTRUST)) {
2349                         if (lp_enable_privileges() && nt_token_check_domain_rid(p->session_info->security_token,
2350                                                         DOMAIN_RID_ADMINS)) {
2351                                 des_access &= ~GENERIC_RIGHTS_USER_WRITE;
2352                                 extra_access = GENERIC_RIGHTS_USER_WRITE;
2353                                 DEBUG(4,("_samr_OpenUser: Allowing "
2354                                         "GENERIC_RIGHTS_USER_WRITE for "
2355                                         "rid admins\n"));
2356                         }
2357                 }
2358         }
2359
2360         TALLOC_FREE(sampass);
2361
2362         nt_status = access_check_object(psd, p->session_info->security_token,
2363                                         needed_priv_1, needed_priv_2,
2364                                         GENERIC_RIGHTS_USER_WRITE, des_access,
2365                                         &acc_granted, "_samr_OpenUser");
2366
2367         if ( !NT_STATUS_IS_OK(nt_status) )
2368                 return nt_status;
2369
2370         /* check that the SID exists in our domain. */
2371         if (ret == False) {
2372                 return NT_STATUS_NO_SUCH_USER;
2373         }
2374
2375         /* If we did the rid admins hack above, allow access. */
2376         acc_granted |= extra_access;
2377
2378         status = create_samr_policy_handle(p->mem_ctx,
2379                                            p,
2380                                            SAMR_HANDLE_USER,
2381                                            acc_granted,
2382                                            &sid,
2383                                            NULL,
2384                                            r->out.user_handle);
2385         if (!NT_STATUS_IS_OK(status)) {
2386                 return status;
2387         }
2388
2389         return NT_STATUS_OK;
2390 }
2391
2392 /*************************************************************************
2393  *************************************************************************/
2394
2395 static NTSTATUS init_samr_parameters_string(TALLOC_CTX *mem_ctx,
2396                                             DATA_BLOB *blob,
2397                                             struct lsa_BinaryString **_r)
2398 {
2399         struct lsa_BinaryString *r;
2400
2401         if (!blob || !_r) {
2402                 return NT_STATUS_INVALID_PARAMETER;
2403         }
2404
2405         r = talloc_zero(mem_ctx, struct lsa_BinaryString);
2406         if (!r) {
2407                 return NT_STATUS_NO_MEMORY;
2408         }
2409
2410         r->array = talloc_zero_array(mem_ctx, uint16_t, blob->length/2);
2411         if (!r->array) {
2412                 return NT_STATUS_NO_MEMORY;
2413         }
2414         memcpy(r->array, blob->data, blob->length);
2415         r->size = blob->length;
2416         r->length = blob->length;
2417
2418         if (!r->array) {
2419                 return NT_STATUS_NO_MEMORY;
2420         }
2421
2422         *_r = r;
2423
2424         return NT_STATUS_OK;
2425 }
2426
2427 /*************************************************************************
2428  *************************************************************************/
2429
2430 static struct samr_LogonHours get_logon_hours_from_pdb(TALLOC_CTX *mem_ctx,
2431                                                        struct samu *pw)
2432 {
2433         struct samr_LogonHours hours;
2434         const int units_per_week = 168;
2435
2436         ZERO_STRUCT(hours);
2437         hours.bits = talloc_array(mem_ctx, uint8_t, units_per_week);
2438         if (!hours.bits) {
2439                 return hours;
2440         }
2441
2442         hours.units_per_week = units_per_week;
2443         memset(hours.bits, 0xFF, units_per_week);
2444
2445         if (pdb_get_hours(pw)) {
2446                 memcpy(hours.bits, pdb_get_hours(pw),
2447                        MIN(pdb_get_hours_len(pw), units_per_week));
2448         }
2449
2450         return hours;
2451 }
2452
2453 /*************************************************************************
2454  get_user_info_1.
2455  *************************************************************************/
2456
2457 static NTSTATUS get_user_info_1(TALLOC_CTX *mem_ctx,
2458                                 struct samr_UserInfo1 *r,
2459                                 struct samu *pw,
2460                                 struct dom_sid *domain_sid)
2461 {
2462         const struct dom_sid *sid_group;
2463         uint32_t primary_gid;
2464
2465         become_root();
2466         sid_group = pdb_get_group_sid(pw);
2467         unbecome_root();
2468
2469         if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2470                 struct dom_sid_buf buf1, buf2;
2471
2472                 DEBUG(0, ("get_user_info_1: User %s has Primary Group SID %s, \n"
2473                           "which conflicts with the domain sid %s.  Failing operation.\n",
2474                           pdb_get_username(pw),
2475                           dom_sid_str_buf(sid_group, &buf1),
2476                           dom_sid_str_buf(domain_sid, &buf2)));
2477                 return NT_STATUS_UNSUCCESSFUL;
2478         }
2479
2480         r->account_name.string          = talloc_strdup(mem_ctx, pdb_get_username(pw));
2481         r->full_name.string             = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2482         r->primary_gid                  = primary_gid;
2483         r->description.string           = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2484         r->comment.string               = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2485
2486         return NT_STATUS_OK;
2487 }
2488
2489 /*************************************************************************
2490  get_user_info_2.
2491  *************************************************************************/
2492
2493 static NTSTATUS get_user_info_2(TALLOC_CTX *mem_ctx,
2494                                 struct samr_UserInfo2 *r,
2495                                 struct samu *pw)
2496 {
2497         r->comment.string               = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2498         r->reserved.string              = NULL;
2499         r->country_code                 = pdb_get_country_code(pw);
2500         r->code_page                    = pdb_get_code_page(pw);
2501
2502         return NT_STATUS_OK;
2503 }
2504
2505 /*************************************************************************
2506  get_user_info_3.
2507  *************************************************************************/
2508
2509 static NTSTATUS get_user_info_3(TALLOC_CTX *mem_ctx,
2510                                 struct samr_UserInfo3 *r,
2511                                 struct samu *pw,
2512                                 struct dom_sid *domain_sid)
2513 {
2514         const struct dom_sid *sid_user, *sid_group;
2515         uint32_t rid, primary_gid;
2516         struct dom_sid_buf buf1, buf2;
2517
2518         sid_user = pdb_get_user_sid(pw);
2519
2520         if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2521                 DEBUG(0, ("get_user_info_3: User %s has SID %s, \nwhich conflicts with "
2522                           "the domain sid %s.  Failing operation.\n",
2523                           pdb_get_username(pw),
2524                           dom_sid_str_buf(sid_user, &buf1),
2525                           dom_sid_str_buf(domain_sid, &buf2)));
2526                 return NT_STATUS_UNSUCCESSFUL;
2527         }
2528
2529         become_root();
2530         sid_group = pdb_get_group_sid(pw);
2531         unbecome_root();
2532
2533         if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2534                 DEBUG(0, ("get_user_info_3: User %s has Primary Group SID %s, \n"
2535                           "which conflicts with the domain sid %s.  Failing operation.\n",
2536                           pdb_get_username(pw),
2537                           dom_sid_str_buf(sid_group, &buf1),
2538                           dom_sid_str_buf(domain_sid, &buf2)));
2539                 return NT_STATUS_UNSUCCESSFUL;
2540         }
2541
2542         unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2543         unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2544         unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2545         unix_to_nt_time(&r->allow_password_change, pdb_get_pass_can_change_time(pw));
2546         unix_to_nt_time(&r->force_password_change, pdb_get_pass_must_change_time(pw));
2547
2548         r->account_name.string  = talloc_strdup(mem_ctx, pdb_get_username(pw));
2549         r->full_name.string     = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2550         r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2551         r->home_drive.string    = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2552         r->logon_script.string  = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2553         r->profile_path.string  = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2554         r->workstations.string  = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2555
2556         r->logon_hours          = get_logon_hours_from_pdb(mem_ctx, pw);
2557         r->rid                  = rid;
2558         r->primary_gid          = primary_gid;
2559         r->acct_flags           = pdb_get_acct_ctrl(pw);
2560         r->bad_password_count   = pdb_get_bad_password_count(pw);
2561         r->logon_count          = pdb_get_logon_count(pw);
2562
2563         return NT_STATUS_OK;
2564 }
2565
2566 /*************************************************************************
2567  get_user_info_4.
2568  *************************************************************************/
2569
2570 static NTSTATUS get_user_info_4(TALLOC_CTX *mem_ctx,
2571                                 struct samr_UserInfo4 *r,
2572                                 struct samu *pw)
2573 {
2574         r->logon_hours          = get_logon_hours_from_pdb(mem_ctx, pw);
2575
2576         return NT_STATUS_OK;
2577 }
2578
2579 /*************************************************************************
2580  get_user_info_5.
2581  *************************************************************************/
2582
2583 static NTSTATUS get_user_info_5(TALLOC_CTX *mem_ctx,
2584                                 struct samr_UserInfo5 *r,
2585                                 struct samu *pw,
2586                                 struct dom_sid *domain_sid)
2587 {
2588         const struct dom_sid *sid_user, *sid_group;
2589         uint32_t rid, primary_gid;
2590         struct dom_sid_buf buf1, buf2;
2591
2592         sid_user = pdb_get_user_sid(pw);
2593
2594         if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2595                 DEBUG(0, ("get_user_info_5: User %s has SID %s, \nwhich conflicts with "
2596                           "the domain sid %s.  Failing operation.\n",
2597                           pdb_get_username(pw),
2598                           dom_sid_str_buf(sid_user, &buf1),
2599                           dom_sid_str_buf(domain_sid, &buf2)));
2600                 return NT_STATUS_UNSUCCESSFUL;
2601         }
2602
2603         become_root();
2604         sid_group = pdb_get_group_sid(pw);
2605         unbecome_root();
2606
2607         if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2608                 DEBUG(0, ("get_user_info_5: User %s has Primary Group SID %s, \n"
2609                           "which conflicts with the domain sid %s.  Failing operation.\n",
2610                           pdb_get_username(pw),
2611                           dom_sid_str_buf(sid_group, &buf1),
2612                           dom_sid_str_buf(domain_sid, &buf2)));
2613                 return NT_STATUS_UNSUCCESSFUL;
2614         }
2615
2616         unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2617         unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2618         unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2619         unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2620
2621         r->account_name.string  = talloc_strdup(mem_ctx, pdb_get_username(pw));
2622         r->full_name.string     = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2623         r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2624         r->home_drive.string    = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2625         r->logon_script.string  = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2626         r->profile_path.string  = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2627         r->description.string   = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2628         r->workstations.string  = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2629
2630         r->logon_hours          = get_logon_hours_from_pdb(mem_ctx, pw);
2631         r->rid                  = rid;
2632         r->primary_gid          = primary_gid;
2633         r->acct_flags           = pdb_get_acct_ctrl(pw);
2634         r->bad_password_count   = pdb_get_bad_password_count(pw);
2635         r->logon_count          = pdb_get_logon_count(pw);
2636
2637         return NT_STATUS_OK;
2638 }
2639
2640 /*************************************************************************
2641  get_user_info_6.
2642  *************************************************************************/
2643
2644 static NTSTATUS get_user_info_6(TALLOC_CTX *mem_ctx,
2645                                 struct samr_UserInfo6 *r,
2646                                 struct samu *pw)
2647 {
2648         r->account_name.string  = talloc_strdup(mem_ctx, pdb_get_username(pw));
2649         r->full_name.string     = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2650
2651         return NT_STATUS_OK;
2652 }
2653
2654 /*************************************************************************
2655  get_user_info_7. Safe. Only gives out account_name.
2656  *************************************************************************/
2657
2658 static NTSTATUS get_user_info_7(TALLOC_CTX *mem_ctx,
2659                                 struct samr_UserInfo7 *r,
2660                                 struct samu *smbpass)
2661 {
2662         r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(smbpass));
2663         if (!r->account_name.string) {
2664                 return NT_STATUS_NO_MEMORY;
2665         }
2666
2667         return NT_STATUS_OK;
2668 }
2669
2670 /*************************************************************************
2671  get_user_info_8.
2672  *************************************************************************/
2673
2674 static NTSTATUS get_user_info_8(TALLOC_CTX *mem_ctx,
2675                                 struct samr_UserInfo8 *r,
2676                                 struct samu *pw)
2677 {
2678         r->full_name.string     = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2679
2680         return NT_STATUS_OK;
2681 }
2682
2683 /*************************************************************************
2684  get_user_info_9. Only gives out primary group SID.
2685  *************************************************************************/
2686
2687 static NTSTATUS get_user_info_9(TALLOC_CTX *mem_ctx,
2688                                 struct samr_UserInfo9 *r,
2689                                 struct samu *smbpass)
2690 {
2691         r->primary_gid = pdb_get_group_rid(smbpass);
2692
2693         return NT_STATUS_OK;
2694 }
2695
2696 /*************************************************************************
2697  get_user_info_10.
2698  *************************************************************************/
2699
2700 static NTSTATUS get_user_info_10(TALLOC_CTX *mem_ctx,
2701                                  struct samr_UserInfo10 *r,
2702                                  struct samu *pw)
2703 {
2704         r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2705         r->home_drive.string    = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2706
2707         return NT_STATUS_OK;
2708 }
2709
2710 /*************************************************************************
2711  get_user_info_11.
2712  *************************************************************************/
2713
2714 static NTSTATUS get_user_info_11(TALLOC_CTX *mem_ctx,
2715                                  struct samr_UserInfo11 *r,
2716                                  struct samu *pw)
2717 {
2718         r->logon_script.string  = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2719
2720         return NT_STATUS_OK;
2721 }
2722
2723 /*************************************************************************
2724  get_user_info_12.
2725  *************************************************************************/
2726
2727 static NTSTATUS get_user_info_12(TALLOC_CTX *mem_ctx,
2728                                  struct samr_UserInfo12 *r,
2729                                  struct samu *pw)
2730 {
2731         r->profile_path.string  = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2732
2733         return NT_STATUS_OK;
2734 }
2735
2736 /*************************************************************************
2737  get_user_info_13.
2738  *************************************************************************/
2739
2740 static NTSTATUS get_user_info_13(TALLOC_CTX *mem_ctx,
2741                                  struct samr_UserInfo13 *r,
2742                                  struct samu *pw)
2743 {
2744         r->description.string   = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2745
2746         return NT_STATUS_OK;
2747 }
2748
2749 /*************************************************************************
2750  get_user_info_14.
2751  *************************************************************************/
2752
2753 static NTSTATUS get_user_info_14(TALLOC_CTX *mem_ctx,
2754                                  struct samr_UserInfo14 *r,
2755                                  struct samu *pw)
2756 {
2757         r->workstations.string  = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2758
2759         return NT_STATUS_OK;
2760 }
2761
2762 /*************************************************************************
2763  get_user_info_16. Safe. Only gives out acb bits.
2764  *************************************************************************/
2765
2766 static NTSTATUS get_user_info_16(TALLOC_CTX *mem_ctx,
2767                                  struct samr_UserInfo16 *r,
2768                                  struct samu *smbpass)
2769 {
2770         r->acct_flags = pdb_get_acct_ctrl(smbpass);
2771
2772         return NT_STATUS_OK;
2773 }
2774
2775 /*************************************************************************
2776  get_user_info_17.
2777  *************************************************************************/
2778
2779 static NTSTATUS get_user_info_17(TALLOC_CTX *mem_ctx,
2780                                  struct samr_UserInfo17 *r,
2781                                  struct samu *pw)
2782 {
2783         unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2784
2785         return NT_STATUS_OK;
2786 }
2787
2788 /*************************************************************************
2789  get_user_info_18. OK - this is the killer as it gives out password info.
2790  Ensure that this is only allowed on an encrypted connection with a root
2791  user. JRA.
2792  *************************************************************************/
2793
2794 static NTSTATUS get_user_info_18(struct pipes_struct *p,
2795                                  TALLOC_CTX *mem_ctx,
2796                                  struct samr_UserInfo18 *r,
2797                                  struct dom_sid *user_sid)
2798 {
2799         struct samu *smbpass=NULL;
2800         bool ret;
2801         const uint8_t *nt_pass = NULL;
2802         const uint8_t *lm_pass = NULL;
2803
2804         ZERO_STRUCTP(r);
2805
2806         if (p->transport != NCALRPC) {
2807                 return NT_STATUS_INVALID_INFO_CLASS;
2808         }
2809
2810         if (!security_token_is_system(p->session_info->security_token)) {
2811                 return NT_STATUS_ACCESS_DENIED;
2812         }
2813
2814         /*
2815          * Do *NOT* do become_root()/unbecome_root() here ! JRA.
2816          */
2817
2818         if ( !(smbpass = samu_new( mem_ctx )) ) {
2819                 return NT_STATUS_NO_MEMORY;
2820         }
2821
2822         ret = pdb_getsampwsid(smbpass, user_sid);
2823
2824         if (ret == False) {
2825                 struct dom_sid_buf buf;
2826                 DEBUG(4, ("User %s not found\n",
2827                           dom_sid_str_buf(user_sid, &buf)));
2828                 TALLOC_FREE(smbpass);
2829                 return root_mode() ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
2830         }
2831
2832         DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
2833
2834         if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
2835                 TALLOC_FREE(smbpass);
2836                 return NT_STATUS_ACCOUNT_DISABLED;
2837         }
2838
2839         lm_pass = pdb_get_lanman_passwd(smbpass);
2840         if (lm_pass != NULL) {
2841                 memcpy(r->lm_pwd.hash, lm_pass, 16);
2842                 r->lm_pwd_active = true;
2843         }
2844
2845         nt_pass = pdb_get_nt_passwd(smbpass);
2846         if (nt_pass != NULL) {
2847                 memcpy(r->nt_pwd.hash, nt_pass, 16);
2848                 r->nt_pwd_active = true;
2849         }
2850         r->password_expired = 0; /* FIXME */
2851
2852         TALLOC_FREE(smbpass);
2853
2854         return NT_STATUS_OK;
2855 }
2856
2857 /*************************************************************************
2858  get_user_info_20
2859  *************************************************************************/
2860
2861 static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx,
2862                                  struct samr_UserInfo20 *r,
2863                                  struct samu *sampass)
2864 {
2865         const char *munged_dial = NULL;
2866         DATA_BLOB blob;
2867         NTSTATUS status;
2868         struct lsa_BinaryString *parameters = NULL;
2869
2870         ZERO_STRUCTP(r);
2871
2872         munged_dial = pdb_get_munged_dial(sampass);
2873
2874         DEBUG(3,("User:[%s] has [%s] (length: %d)\n", pdb_get_username(sampass),
2875                 munged_dial, (int)strlen(munged_dial)));
2876
2877         if (munged_dial) {
2878                 blob = base64_decode_data_blob(munged_dial);
2879         } else {
2880                 blob = data_blob_string_const_null("");
2881         }
2882
2883         status = init_samr_parameters_string(mem_ctx, &blob, &parameters);
2884         data_blob_free(&blob);
2885         if (!NT_STATUS_IS_OK(status)) {
2886                 return status;
2887         }
2888
2889         r->parameters = *parameters;
2890
2891         return NT_STATUS_OK;
2892 }
2893
2894
2895 /*************************************************************************
2896  get_user_info_21
2897  *************************************************************************/
2898
2899 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx,
2900                                  struct samr_UserInfo21 *r,
2901                                  struct samu *pw,
2902                                  struct dom_sid *domain_sid,
2903                                  uint32_t acc_granted)
2904 {
2905         NTSTATUS status;
2906         const struct dom_sid *sid_user, *sid_group;
2907         uint32_t rid, primary_gid;
2908         NTTIME force_password_change;
2909         time_t must_change_time;
2910         struct lsa_BinaryString *parameters = NULL;
2911         const char *munged_dial = NULL;
2912         DATA_BLOB blob;
2913         struct dom_sid_buf buf1, buf2;
2914
2915         ZERO_STRUCTP(r);
2916
2917         sid_user = pdb_get_user_sid(pw);
2918
2919         if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2920                 DEBUG(0, ("get_user_info_21: User %s has SID %s, \nwhich conflicts with "
2921                           "the domain sid %s.  Failing operation.\n",
2922                           pdb_get_username(pw),
2923                           dom_sid_str_buf(sid_user, &buf1),
2924                           dom_sid_str_buf(domain_sid, &buf2)));
2925                 return NT_STATUS_UNSUCCESSFUL;
2926         }
2927
2928         become_root();
2929         sid_group = pdb_get_group_sid(pw);
2930         unbecome_root();
2931
2932         if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2933                 DEBUG(0, ("get_user_info_21: User %s has Primary Group SID %s, \n"
2934                           "which conflicts with the domain sid %s.  Failing operation.\n",
2935                           pdb_get_username(pw),
2936                           dom_sid_str_buf(sid_group, &buf1),
2937                           dom_sid_str_buf(domain_sid, &buf2)));
2938                 return NT_STATUS_UNSUCCESSFUL;
2939         }
2940
2941         unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2942         unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2943         unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2944         unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2945         unix_to_nt_time(&r->allow_password_change, pdb_get_pass_can_change_time(pw));
2946
2947         must_change_time = pdb_get_pass_must_change_time(pw);
2948         if (pdb_is_password_change_time_max(must_change_time)) {
2949                 unix_to_nt_time_abs(&force_password_change, must_change_time);
2950         } else {
2951                 unix_to_nt_time(&force_password_change, must_change_time);
2952         }
2953
2954         munged_dial = pdb_get_munged_dial(pw);
2955         if (munged_dial) {
2956                 blob = base64_decode_data_blob(munged_dial);
2957         } else {
2958                 blob = data_blob_string_const_null("");
2959         }
2960
2961         status = init_samr_parameters_string(mem_ctx, &blob, &parameters);
2962         data_blob_free(&blob);
2963         if (!NT_STATUS_IS_OK(status)) {
2964                 return status;
2965         }
2966
2967         r->force_password_change        = force_password_change;
2968
2969         r->account_name.string          = talloc_strdup(mem_ctx, pdb_get_username(pw));
2970         r->full_name.string             = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2971         r->home_directory.string        = talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2972         r->home_drive.string            = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2973         r->logon_script.string          = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2974         r->profile_path.string          = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2975         r->description.string           = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2976         r->workstations.string          = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2977         r->comment.string               = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2978
2979         r->logon_hours                  = get_logon_hours_from_pdb(mem_ctx, pw);
2980         r->parameters                   = *parameters;
2981         r->rid                          = rid;
2982         r->primary_gid                  = primary_gid;
2983         r->acct_flags                   = pdb_get_acct_ctrl(pw);
2984         r->bad_password_count           = pdb_get_bad_password_count(pw);
2985         r->logon_count                  = pdb_get_logon_count(pw);
2986         r->fields_present               = pdb_build_fields_present(pw);
2987         r->password_expired             = (pdb_get_pass_must_change_time(pw) == 0) ?
2988                                                 PASS_MUST_CHANGE_AT_NEXT_LOGON : 0;
2989         r->country_code                 = pdb_get_country_code(pw);
2990         r->code_page                    = pdb_get_code_page(pw);
2991         r->lm_password_set              = 0;
2992         r->nt_password_set              = 0;
2993
2994 #if 0
2995
2996         /*
2997           Look at a user on a real NT4 PDC with usrmgr, press
2998           'ok'. Then you will see that fields_present is set to
2999           0x08f827fa. Look at the user immediately after that again,
3000           and you will see that 0x00fffff is returned. This solves
3001           the problem that you get access denied after having looked
3002           at the user.
3003           -- Volker
3004         */
3005
3006 #endif
3007
3008
3009         return NT_STATUS_OK;
3010 }
3011
3012 /*******************************************************************
3013  _samr_QueryUserInfo
3014  ********************************************************************/
3015
3016 NTSTATUS _samr_QueryUserInfo(struct pipes_struct *p,
3017                              struct samr_QueryUserInfo *r)
3018 {
3019         NTSTATUS status;
3020         union samr_UserInfo *user_info = NULL;
3021         struct samr_info *uinfo;
3022         struct dom_sid domain_sid;
3023         uint32_t rid;
3024         bool ret = false;
3025         struct samu *pwd = NULL;
3026         uint32_t acc_required, acc_granted;
3027         struct dom_sid_buf buf;
3028
3029         switch (r->in.level) {
3030         case 1: /* UserGeneralInformation */
3031                 /* USER_READ_GENERAL */
3032                 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC;
3033                 break;
3034         case 2: /* UserPreferencesInformation */
3035                 /* USER_READ_PREFERENCES | USER_READ_GENERAL */
3036                 acc_required = SAMR_USER_ACCESS_GET_LOCALE |
3037                                SAMR_USER_ACCESS_GET_NAME_ETC;
3038                 break;
3039         case 3: /* UserLogonInformation */
3040                 /* USER_READ_GENERAL | USER_READ_PREFERENCES | USER_READ_LOGON | USER_READ_ACCOUNT */
3041                 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC |
3042                                SAMR_USER_ACCESS_GET_LOCALE |
3043                                SAMR_USER_ACCESS_GET_LOGONINFO |
3044                                SAMR_USER_ACCESS_GET_ATTRIBUTES;
3045                 break;
3046         case 4: /* UserLogonHoursInformation */
3047                 /* USER_READ_LOGON */
3048                 acc_required = SAMR_USER_ACCESS_GET_LOGONINFO;
3049                 break;
3050         case 5: /* UserAccountInformation */
3051                 /* USER_READ_GENERAL | USER_READ_PREFERENCES | USER_READ_LOGON | USER_READ_ACCOUNT */
3052                 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC |
3053                                SAMR_USER_ACCESS_GET_LOCALE |
3054                                SAMR_USER_ACCESS_GET_LOGONINFO |
3055                                SAMR_USER_ACCESS_GET_ATTRIBUTES;
3056                 break;
3057         case 6: /* UserNameInformation */
3058         case 7: /* UserAccountNameInformation */
3059         case 8: /* UserFullNameInformation */
3060         case 9: /* UserPrimaryGroupInformation */
3061         case 13: /* UserAdminCommentInformation */
3062                 /* USER_READ_GENERAL */
3063                 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC;
3064                 break;
3065         case 10: /* UserHomeInformation */
3066         case 11: /* UserScriptInformation */
3067         case 12: /* UserProfileInformation */
3068         case 14: /* UserWorkStationsInformation */
3069                 /* USER_READ_LOGON */
3070                 acc_required = SAMR_USER_ACCESS_GET_LOGONINFO;
3071                 break;
3072         case 16: /* UserControlInformation */
3073         case 17: /* UserExpiresInformation */
3074         case 20: /* UserParametersInformation */
3075                 /* USER_READ_ACCOUNT */
3076                 acc_required = SAMR_USER_ACCESS_GET_ATTRIBUTES;
3077                 break;
3078         case 21: /* UserAllInformation */
3079                 /* FIXME! - gd */
3080                 acc_required = SAMR_USER_ACCESS_GET_ATTRIBUTES;
3081                 break;
3082         case 18: /* UserInternal1Information */
3083                 /* FIXME! - gd */
3084                 acc_required = SAMR_USER_ACCESS_GET_ATTRIBUTES;
3085                 break;
3086         case 23: /* UserInternal4Information */
3087         case 24: /* UserInternal4InformationNew */
3088         case 25: /* UserInternal4InformationNew */
3089         case 26: /* UserInternal5InformationNew */
3090         default:
3091                 return NT_STATUS_INVALID_INFO_CLASS;
3092                 break;
3093         }
3094
3095         uinfo = samr_policy_handle_find(p,
3096                                         r->in.user_handle,
3097                                         SAMR_HANDLE_USER,
3098                                         acc_required,
3099                                         &acc_granted,
3100                                         &status);
3101         if (!NT_STATUS_IS_OK(status)) {
3102                 return status;
3103         }
3104
3105         domain_sid = uinfo->sid;
3106
3107         sid_split_rid(&domain_sid, &rid);
3108
3109         if (!sid_check_is_in_our_sam(&uinfo->sid))
3110                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
3111
3112         DEBUG(5,("_samr_QueryUserInfo: sid:%s\n",
3113                  dom_sid_str_buf(&uinfo->sid, &buf)));
3114
3115         user_info = talloc_zero(p->mem_ctx, union samr_UserInfo);
3116         if (!user_info) {
3117                 return NT_STATUS_NO_MEMORY;
3118         }
3119
3120         DEBUG(5,("_samr_QueryUserInfo: user info level: %d\n", r->in.level));
3121
3122         if (!(pwd = samu_new(p->mem_ctx))) {
3123                 return NT_STATUS_NO_MEMORY;
3124         }
3125
3126         become_root();
3127         ret = pdb_getsampwsid(pwd, &uinfo->sid);
3128         unbecome_root();
3129
3130         if (ret == false) {
3131                 DEBUG(4,("User %s not found\n",
3132                          dom_sid_str_buf(&uinfo->sid, &buf)));
3133                 TALLOC_FREE(pwd);
3134                 return NT_STATUS_NO_SUCH_USER;
3135         }
3136
3137         DEBUG(3,("User:[%s]\n", pdb_get_username(pwd)));
3138
3139         samr_clear_sam_passwd(pwd);
3140
3141         switch (r->in.level) {
3142         case 1:
3143                 status = get_user_info_1(p->mem_ctx, &user_info->info1, pwd, &domain_sid);
3144                 break;
3145         case 2:
3146                 status = get_user_info_2(p->mem_ctx, &user_info->info2, pwd);
3147                 break;
3148         case 3:
3149                 status = get_user_info_3(p->mem_ctx, &user_info->info3, pwd, &domain_sid);
3150                 break;
3151         case 4:
3152                 status = get_user_info_4(p->mem_ctx, &user_info->info4, pwd);
3153                 break;
3154         case 5:
3155                 status = get_user_info_5(p->mem_ctx, &user_info->info5, pwd, &domain_sid);
3156                 break;
3157         case 6:
3158                 status = get_user_info_6(p->mem_ctx, &user_info->info6, pwd);
3159                 break;
3160         case 7:
3161                 status = get_user_info_7(p->mem_ctx, &user_info->info7, pwd);
3162                 break;
3163         case 8:
3164                 status = get_user_info_8(p->mem_ctx, &user_info->info8, pwd);
3165                 break;
3166         case 9:
3167                 status = get_user_info_9(p->mem_ctx, &user_info->info9, pwd);
3168                 break;
3169         case 10:
3170                 status = get_user_info_10(p->mem_ctx, &user_info->info10, pwd);
3171                 break;
3172         case 11:
3173                 status = get_user_info_11(p->mem_ctx, &user_info->info11, pwd);
3174                 break;
3175         case 12:
3176                 status = get_user_info_12(p->mem_ctx, &user_info->info12, pwd);
3177                 break;
3178         case 13:
3179                 status = get_user_info_13(p->mem_ctx, &user_info->info13, pwd);
3180                 break;
3181         case 14:
3182                 status = get_user_info_14(p->mem_ctx, &user_info->info14, pwd);
3183                 break;
3184         case 16:
3185                 status = get_user_info_16(p->mem_ctx, &user_info->info16, pwd);
3186                 break;
3187         case 17:
3188                 status = get_user_info_17(p->mem_ctx, &user_info->info17, pwd);
3189                 break;
3190         case 18:
3191                 /* level 18 is special */
3192                 status = get_user_info_18(p, p->mem_ctx, &user_info->info18,
3193                                           &uinfo->sid);
3194                 break;
3195         case 20:
3196                 status = get_user_info_20(p->mem_ctx, &user_info->info20, pwd);
3197                 break;
3198         case 21:
3199                 status = get_user_info_21(p->mem_ctx, &user_info->info21, pwd, &domain_sid, acc_granted);
3200                 break;
3201         default:
3202                 status = NT_STATUS_INVALID_INFO_CLASS;
3203                 break;
3204         }
3205
3206         if (!NT_STATUS_IS_OK(status)) {
3207                 goto done;
3208         }
3209
3210         *r->out.info = user_info;
3211
3212  done:
3213         TALLOC_FREE(pwd);
3214
3215         DEBUG(5,("_samr_QueryUserInfo: %d\n", __LINE__));
3216
3217         return status;
3218 }
3219
3220 /****************************************************************
3221 ****************************************************************/
3222
3223 NTSTATUS _samr_QueryUserInfo2(struct pipes_struct *p,
3224                               struct samr_QueryUserInfo2 *r)
3225 {
3226         struct samr_QueryUserInfo u;
3227
3228         u.in.user_handle        = r->in.user_handle;
3229         u.in.level              = r->in.level;
3230         u.out.info              = r->out.info;
3231
3232         return _samr_QueryUserInfo(p, &u);
3233 }
3234
3235 /*******************************************************************
3236  _samr_GetGroupsForUser
3237  ********************************************************************/
3238
3239 NTSTATUS _samr_GetGroupsForUser(struct pipes_struct *p,
3240                                 struct samr_GetGroupsForUser *r)
3241 {
3242         struct samr_info *uinfo;
3243         struct samu *sam_pass=NULL;
3244         struct dom_sid *sids;
3245         struct samr_RidWithAttribute dom_gid;
3246         struct samr_RidWithAttribute *gids = NULL;
3247         uint32_t primary_group_rid;
3248         uint32_t num_groups = 0;
3249         gid_t *unix_gids;
3250         uint32_t i, num_gids;
3251         bool ret;
3252         NTSTATUS result;
3253         bool success = False;
3254         struct dom_sid_buf buf;
3255
3256         struct samr_RidWithAttributeArray *rids = NULL;
3257
3258         /*
3259          * from the SID in the request:
3260          * we should send back the list of DOMAIN GROUPS
3261          * the user is a member of
3262          *
3263          * and only the DOMAIN GROUPS
3264          * no ALIASES !!! neither aliases of the domain
3265          * nor aliases of the builtin SID
3266          *
3267          * JFM, 12/2/2001
3268          */
3269
3270         DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
3271
3272         uinfo = samr_policy_handle_find(p,
3273                                         r->in.user_handle,
3274                                         SAMR_HANDLE_USER,
3275                                         SAMR_USER_ACCESS_GET_GROUPS,
3276                                         NULL,
3277                                         &result);
3278         if (!NT_STATUS_IS_OK(result)) {
3279                 return result;
3280         }
3281
3282         rids = talloc_zero(p->mem_ctx, struct samr_RidWithAttributeArray);
3283         if (!rids) {
3284                 return NT_STATUS_NO_MEMORY;
3285         }
3286
3287         if (!sid_check_is_in_our_sam(&uinfo->sid))
3288                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
3289
3290         if ( !(sam_pass = samu_new( p->mem_ctx )) ) {
3291                 return NT_STATUS_NO_MEMORY;
3292         }
3293
3294         become_root();
3295         ret = pdb_getsampwsid(sam_pass, &uinfo->sid);
3296         unbecome_root();
3297
3298         if (!ret) {
3299                 DEBUG(10, ("pdb_getsampwsid failed for %s\n",
3300                            dom_sid_str_buf(&uinfo->sid, &buf)));
3301                 return NT_STATUS_NO_SUCH_USER;
3302         }
3303
3304         sids = NULL;
3305
3306         /* make both calls inside the root block */
3307         become_root();
3308         result = pdb_enum_group_memberships(p->mem_ctx, sam_pass,
3309                                             &sids, &unix_gids, &num_groups);
3310         if ( NT_STATUS_IS_OK(result) ) {
3311                 success = sid_peek_check_rid(get_global_sam_sid(),
3312                                              pdb_get_group_sid(sam_pass),
3313                                              &primary_group_rid);
3314         }
3315         unbecome_root();
3316
3317         if (!NT_STATUS_IS_OK(result)) {
3318                 DEBUG(10, ("pdb_enum_group_memberships failed for %s\n",
3319                            dom_sid_str_buf(&uinfo->sid, &buf)));
3320                 return result;
3321         }
3322
3323         if ( !success ) {
3324                 DEBUG(5, ("Group sid %s for user %s not in our domain\n",
3325                           dom_sid_str_buf(pdb_get_group_sid(sam_pass), &buf),
3326                           pdb_get_username(sam_pass)));
3327                 TALLOC_FREE(sam_pass);
3328                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
3329         }
3330
3331         gids = NULL;
3332         num_gids = 0;
3333
3334         dom_gid.attributes = (SE_GROUP_MANDATORY|SE_GROUP_ENABLED_BY_DEFAULT|
3335                               SE_GROUP_ENABLED);
3336         dom_gid.rid = primary_group_rid;
3337         ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
3338
3339         for (i=0; i<num_groups; i++) {
3340
3341                 if (!sid_peek_check_rid(get_global_sam_sid(),
3342                                         &(sids[i]), &dom_gid.rid)) {
3343                         DEBUG(10, ("Found sid %s not in our domain\n",
3344                                    dom_sid_str_buf(&sids[i], &buf)));
3345                         continue;
3346                 }
3347
3348                 if (dom_gid.rid == primary_group_rid) {
3349                         /* We added the primary group directly from the
3350                          * sam_account. The other SIDs are unique from
3351                          * enum_group_memberships */
3352                         continue;
3353                 }
3354
3355                 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
3356         }
3357
3358         rids->count = num_gids;
3359         rids->rids = gids;
3360
3361         *r->out.rids = rids;
3362
3363         DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
3364
3365         return result;
3366 }
3367
3368 /*******************************************************************
3369  ********************************************************************/
3370
3371 static uint32_t samr_get_server_role(void)
3372 {
3373         uint32_t role = ROLE_DOMAIN_PDC;
3374
3375         if (lp_server_role() == ROLE_DOMAIN_BDC) {
3376                 role = ROLE_DOMAIN_BDC;
3377         }
3378
3379         return role;
3380 }
3381
3382 /*******************************************************************
3383  ********************************************************************/
3384
3385 static NTSTATUS query_dom_info_1(TALLOC_CTX *mem_ctx,
3386                                  struct samr_DomInfo1 *r)
3387 {
3388         const struct loadparm_substitution *lp_sub =
3389                 loadparm_s3_global_substitution();
3390         uint32_t account_policy_temp;
3391         time_t u_expire, u_min_age;
3392
3393         become_root();
3394
3395         /* AS ROOT !!! */
3396
3397         pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN, &account_policy_temp);
3398         r->min_password_length = account_policy_temp;
3399
3400         pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &account_policy_temp);
3401         r->password_history_length = account_policy_temp;
3402
3403         pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
3404                                &r->password_properties);
3405
3406         pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, &account_policy_temp);
3407         u_expire = account_policy_temp;
3408
3409         pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, &account_policy_temp);
3410         u_min_age = account_policy_temp;
3411
3412         /* !AS ROOT */
3413
3414         unbecome_root();
3415
3416         unix_to_nt_time_abs((NTTIME *)&r->max_password_age, u_expire);
3417         unix_to_nt_time_abs((NTTIME *)&r->min_password_age, u_min_age);
3418
3419         if (lp_check_password_script(talloc_tos(), lp_sub) && *lp_check_password_script(talloc_tos(), lp_sub)){
3420                 r->password_properties |= DOMAIN_PASSWORD_COMPLEX;
3421         }
3422
3423         return NT_STATUS_OK;
3424 }
3425
3426 /*******************************************************************
3427  ********************************************************************/
3428
3429 static NTSTATUS query_dom_info_2(TALLOC_CTX *mem_ctx,
3430                                  struct samr_DomGeneralInformation *r,
3431                                  struct samr_info *dinfo)
3432 {
3433         const struct loadparm_substitution *lp_sub =
3434                 loadparm_s3_global_substitution();
3435         uint32_t u_logout;
3436         time_t seq_num;
3437
3438         become_root();
3439
3440         /* AS ROOT !!! */
3441
3442         r->num_users    = count_sam_users(dinfo->disp_info, ACB_NORMAL);
3443         r->num_groups   = count_sam_groups(dinfo->disp_info);
3444         r->num_aliases  = count_sam_aliases(dinfo->disp_info);
3445
3446         pdb_get_account_policy(PDB_POLICY_TIME_TO_LOGOUT, &u_logout);
3447
3448         unix_to_nt_time_abs(&r->force_logoff_time, u_logout);
3449
3450         if (!pdb_get_seq_num(&seq_num)) {
3451                 seq_num = time(NULL);
3452         }
3453
3454         /* !AS ROOT */
3455
3456         unbecome_root();
3457
3458         r->oem_information.string       = lp_server_string(r, lp_sub);
3459         r->domain_name.string           = lp_workgroup();
3460         r->primary.string               = lp_netbios_name();
3461         r->sequence_num                 = seq_num;
3462         r->domain_server_state          = DOMAIN_SERVER_ENABLED;
3463         r->role                         = (enum samr_Role) samr_get_server_role();
3464         r->unknown3                     = 1;
3465
3466         return NT_STATUS_OK;
3467 }
3468
3469 /*******************************************************************
3470  ********************************************************************/
3471
3472 static NTSTATUS query_dom_info_3(TALLOC_CTX *mem_ctx,
3473                                  struct samr_DomInfo3 *r)
3474 {
3475         uint32_t u_logout;
3476
3477         become_root();
3478
3479         /* AS ROOT !!! */
3480
3481         {
3482                 uint32_t ul;
3483                 pdb_get_account_policy(PDB_POLICY_TIME_TO_LOGOUT, &ul);
3484                 u_logout = (time_t)ul;
3485         }
3486
3487         /* !AS ROOT */
3488
3489         unbecome_root();
3490
3491         unix_to_nt_time_abs(&r->force_logoff_time, u_logout);
3492
3493         return NT_STATUS_OK;
3494 }
3495
3496 /*******************************************************************
3497  ********************************************************************/
3498
3499 static NTSTATUS query_dom_info_4(TALLOC_CTX *mem_ctx,
3500                                  struct samr_DomOEMInformation *r)
3501 {
3502         const struct loadparm_substitution *lp_sub =
3503                 loadparm_s3_global_substitution();
3504
3505         r->oem_information.string = lp_server_string(r, lp_sub);
3506
3507         return NT_STATUS_OK;
3508 }
3509
3510 /*******************************************************************
3511  ********************************************************************/
3512
3513 static NTSTATUS query_dom_info_5(TALLOC_CTX *mem_ctx,
3514                                  struct samr_DomInfo5 *r)
3515 {
3516         r->domain_name.string = get_global_sam_name();
3517
3518         return NT_STATUS_OK;
3519 }
3520
3521 /*******************************************************************
3522  ********************************************************************/
3523
3524 static NTSTATUS query_dom_info_6(TALLOC_CTX *mem_ctx,
3525                                  struct samr_DomInfo6 *r)
3526 {
3527         /* NT returns its own name when a PDC. win2k and later
3528          * only the name of the PDC if itself is a BDC (samba4
3529          * idl) */
3530         r->primary.string = lp_netbios_name();
3531
3532         return NT_STATUS_OK;
3533 }
3534
3535 /*******************************************************************
3536  ********************************************************************/
3537
3538 static NTSTATUS query_dom_info_7(TALLOC_CTX *mem_ctx,
3539                                  struct samr_DomInfo7 *r)
3540 {
3541         r->role = (enum samr_Role) samr_get_server_role();
3542
3543         return NT_STATUS_OK;
3544 }
3545
3546 /*******************************************************************
3547  ********************************************************************/
3548
3549 static NTSTATUS query_dom_info_8(TALLOC_CTX *mem_ctx,
3550                                  struct samr_DomInfo8 *r)
3551 {
3552         time_t seq_num;
3553
3554         become_root();
3555
3556         /* AS ROOT !!! */
3557
3558         if (!pdb_get_seq_num(&seq_num)) {
3559                 seq_num = time(NULL);
3560         }
3561
3562         /* !AS ROOT */
3563
3564         unbecome_root();
3565
3566         r->sequence_num = seq_num;
3567         r->domain_create_time = 0;
3568
3569         return NT_STATUS_OK;
3570 }
3571
3572 /*******************************************************************
3573  ********************************************************************/
3574
3575 static NTSTATUS query_dom_info_9(TALLOC_CTX *mem_ctx,
3576                                  struct samr_DomInfo9 *r)
3577 {
3578         r->domain_server_state = DOMAIN_SERVER_ENABLED;
3579
3580         return NT_STATUS_OK;
3581 }
3582
3583 /*******************************************************************
3584  ********************************************************************/
3585
3586 static NTSTATUS query_dom_info_11(TALLOC_CTX *mem_ctx,
3587                                   struct samr_DomGeneralInformation2 *r,
3588                                   struct samr_info *dinfo)
3589 {
3590         NTSTATUS status;
3591         uint32_t account_policy_temp;
3592         time_t u_lock_duration, u_reset_time;
3593
3594         status = query_dom_info_2(mem_ctx, &r->general, dinfo);
3595         if (!NT_STATUS_IS_OK(status)) {
3596                 return status;
3597         }
3598
3599         /* AS ROOT !!! */
3600
3601         become_root();
3602
3603         pdb_get_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, &account_policy_temp);
3604         u_lock_duration = account_policy_temp;
3605         if (u_lock_duration != -1) {
3606                 u_lock_duration *= 60;
3607         }
3608
3609         pdb_get_account_policy(PDB_POLICY_RESET_COUNT_TIME, &account_policy_temp);
3610         u_reset_time = account_policy_temp * 60;
3611
3612         pdb_get_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
3613         r->lockout_threshold = account_policy_temp;
3614
3615         /* !AS ROOT */
3616
3617         unbecome_root();
3618
3619         unix_to_nt_time_abs(&r->lockout_duration, u_lock_duration);
3620         unix_to_nt_time_abs(&r->lockout_window, u_reset_time);
3621
3622         return NT_STATUS_OK;
3623 }
3624
3625 /*******************************************************************
3626  ********************************************************************/
3627
3628 static NTSTATUS query_dom_info_12(TALLOC_CTX *mem_ctx,
3629                                   struct samr_DomInfo12 *r)
3630 {
3631         uint32_t account_policy_temp;
3632         time_t u_lock_duration, u_reset_time;
3633
3634         become_root();
3635
3636         /* AS ROOT !!! */
3637
3638         pdb_get_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, &account_policy_temp);
3639         u_lock_duration = account_policy_temp;
3640         if (u_lock_duration != -1) {
3641                 u_lock_duration *= 60;
3642         }
3643
3644         pdb_get_account_policy(PDB_POLICY_RESET_COUNT_TIME, &account_policy_temp);
3645         u_reset_time = account_policy_temp * 60;
3646
3647         pdb_get_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
3648         r->lockout_threshold = account_policy_temp;
3649
3650         /* !AS ROOT */
3651
3652         unbecome_root();
3653
3654         unix_to_nt_time_abs(&r->lockout_duration, u_lock_duration);
3655         unix_to_nt_time_abs(&r->lockout_window, u_reset_time);
3656
3657         return NT_STATUS_OK;
3658 }
3659
3660 /*******************************************************************
3661  ********************************************************************/
3662
3663 static NTSTATUS query_dom_info_13(TALLOC_CTX *mem_ctx,
3664                                   struct samr_DomInfo13 *r)
3665 {
3666         time_t seq_num;
3667
3668         become_root();
3669
3670         /* AS ROOT !!! */
3671
3672         if (!pdb_get_seq_num(&seq_num)) {
3673                 seq_num = time(NULL);
3674         }
3675
3676         /* !AS ROOT */
3677
3678         unbecome_root();
3679
3680         r->sequence_num = seq_num;
3681         r->domain_create_time = 0;
3682         r->modified_count_at_last_promotion = 0;
3683
3684         return NT_STATUS_OK;
3685 }
3686
3687 /*******************************************************************
3688  _samr_QueryDomainInfo
3689  ********************************************************************/
3690
3691 NTSTATUS _samr_QueryDomainInfo(struct pipes_struct *p,
3692                                struct samr_QueryDomainInfo *r)
3693 {
3694         NTSTATUS status = NT_STATUS_OK;
3695         struct samr_info *dinfo;
3696         union samr_DomainInfo *dom_info;
3697
3698         uint32_t acc_required;
3699
3700         DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__));
3701
3702         switch (r->in.level) {
3703         case 1: /* DomainPasswordInformation */
3704         case 12: /* DomainLockoutInformation */
3705                 /* DOMAIN_READ_PASSWORD_PARAMETERS */
3706                 acc_required = SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1;
3707                 break;
3708         case 11: /* DomainGeneralInformation2 */
3709                 /* DOMAIN_READ_PASSWORD_PARAMETERS |
3710                  * DOMAIN_READ_OTHER_PARAMETERS */
3711                 acc_required = SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
3712                                SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2;
3713                 break;
3714         case 2: /* DomainGeneralInformation */
3715         case 3: /* DomainLogoffInformation */
3716         case 4: /* DomainOemInformation */
3717         case 5: /* DomainReplicationInformation */
3718         case 6: /* DomainReplicationInformation */
3719         case 7: /* DomainServerRoleInformation */
3720         case 8: /* DomainModifiedInformation */
3721         case 9: /* DomainStateInformation */
3722         case 10: /* DomainUasInformation */
3723         case 13: /* DomainModifiedInformation2 */
3724                 /* DOMAIN_READ_OTHER_PARAMETERS */
3725                 acc_required = SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2;
3726                 break;
3727         default:
3728                 return NT_STATUS_INVALID_INFO_CLASS;
3729         }
3730
3731         dinfo = samr_policy_handle_find(p,
3732                                         r->in.domain_handle,
3733                                         SAMR_HANDLE_DOMAIN,
3734                                         acc_required,
3735                                         NULL,
3736                                         &status);
3737         if (!NT_STATUS_IS_OK(status)) {
3738                 return status;
3739         }
3740
3741         dom_info = talloc_zero(p->mem_ctx, union samr_DomainInfo);
3742         if (!dom_info) {
3743                 return NT_STATUS_NO_MEMORY;
3744         }
3745
3746         switch (r->in.level) {
3747                 case 1:
3748                         status = query_dom_info_1(p->mem_ctx, &dom_info->info1);
3749                         break;
3750                 case 2:
3751                         status = query_dom_info_2(p->mem_ctx, &dom_info->general, dinfo);
3752                         break;
3753                 case 3:
3754                         status = query_dom_info_3(p->mem_ctx, &dom_info->info3);
3755                         break;
3756                 case 4:
3757                         status = query_dom_info_4(p->mem_ctx, &dom_info->oem);
3758                         break;
3759                 case 5:
3760                         status = query_dom_info_5(p->mem_ctx, &dom_info->info5);
3761                         break;
3762                 case 6:
3763                         status = query_dom_info_6(p->mem_ctx, &dom_info->info6);
3764                         break;
3765                 case 7:
3766                         status = query_dom_info_7(p->mem_ctx, &dom_info->info7);
3767                         break;
3768                 case 8:
3769                         status = query_dom_info_8(p->mem_ctx, &dom_info->info8);
3770                         break;
3771                 case 9:
3772                         status = query_dom_info_9(p->mem_ctx, &dom_info->info9);
3773                         break;
3774                 case 11:
3775                         status = query_dom_info_11(p->mem_ctx, &dom_info->general2, dinfo);
3776                         break;
3777                 case 12:
3778                         status = query_dom_info_12(p->mem_ctx, &dom_info->info12);
3779                         break;
3780                 case 13:
3781                         status = query_dom_info_13(p->mem_ctx, &dom_info->info13);
3782                         break;
3783                 default:
3784                         return NT_STATUS_INVALID_INFO_CLASS;
3785         }
3786
3787         if (!NT_STATUS_IS_OK(status)) {
3788                 return status;
3789         }
3790
3791         *r->out.info = dom_info;
3792
3793         DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__));
3794
3795         return status;
3796 }
3797
3798 /* W2k3 seems to use the same check for all 3 objects that can be created via
3799  * SAMR, if you try to create for example "Dialup" as an alias it says
3800  * "NT_STATUS_USER_EXISTS". This is racy, but we can't really lock the user
3801  * database. */
3802
3803 static NTSTATUS can_create(TALLOC_CTX *mem_ctx, const char *new_name)
3804 {
3805         enum lsa_SidType type;
3806         bool result;
3807
3808         DEBUG(10, ("Checking whether [%s] can be created\n", new_name));
3809
3810         become_root();
3811         /* Lookup in our local databases (LOOKUP_NAME_REMOTE not set)
3812          * whether the name already exists */
3813         result = lookup_name(mem_ctx, new_name, LOOKUP_NAME_LOCAL,
3814                              NULL, NULL, NULL, &type);
3815         unbecome_root();
3816
3817         if (!result) {
3818                 DEBUG(10, ("%s does not exist, can create it\n", new_name));
3819                 return NT_STATUS_OK;
3820         }
3821
3822         DEBUG(5, ("trying to create %s, exists as %s\n",
3823                   new_name, sid_type_lookup(type)));
3824
3825         if (type == SID_NAME_DOM_GRP) {
3826                 return NT_STATUS_GROUP_EXISTS;
3827         }
3828         if (type == SID_NAME_ALIAS) {
3829                 return NT_STATUS_ALIAS_EXISTS;
3830         }
3831
3832         /* Yes, the default is NT_STATUS_USER_EXISTS */
3833         return NT_STATUS_USER_EXISTS;
3834 }
3835
3836 /*******************************************************************
3837  _samr_CreateUser2
3838  ********************************************************************/
3839
3840 NTSTATUS _samr_CreateUser2(struct pipes_struct *p,
3841                            struct samr_CreateUser2 *r)
3842 {
3843         const char *account = NULL;
3844         struct dom_sid sid;
3845         uint32_t acb_info = r->in.acct_flags;
3846         struct samr_info *dinfo;
3847         NTSTATUS nt_status;
3848         uint32_t acc_granted;
3849         struct security_descriptor *psd;
3850         size_t    sd_size;
3851         /* check this, when giving away 'add computer to domain' privs */
3852         uint32_t    des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
3853         bool can_add_account = False;
3854
3855         /* Which privilege is needed to override the ACL? */
3856         enum sec_privilege needed_priv = SEC_PRIV_INVALID;
3857
3858         dinfo = samr_policy_handle_find(p,
3859                                         r->in.domain_handle,
3860                                         SAMR_HANDLE_DOMAIN,
3861                                         SAMR_DOMAIN_ACCESS_CREATE_USER,
3862                                         NULL,
3863                                         &nt_status);
3864         if (!NT_STATUS_IS_OK(nt_status)) {
3865                 return nt_status;
3866         }
3867
3868         if (sid_check_is_builtin(&dinfo->sid)) {
3869                 DEBUG(5,("_samr_CreateUser2: Refusing user create in BUILTIN\n"));
3870                 return NT_STATUS_ACCESS_DENIED;
3871         }
3872
3873         if (!(acb_info == ACB_NORMAL || acb_info == ACB_DOMTRUST ||
3874               acb_info == ACB_WSTRUST || acb_info == ACB_SVRTRUST)) {
3875                 /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if
3876                    this parameter is not an account type */
3877                 return NT_STATUS_INVALID_PARAMETER;
3878         }
3879
3880         account = r->in.account_name->string;
3881         if (account == NULL) {
3882                 return NT_STATUS_NO_MEMORY;
3883         }
3884
3885         nt_status = can_create(p->mem_ctx, account);
3886         if (!NT_STATUS_IS_OK(nt_status)) {
3887                 return nt_status;
3888         }
3889
3890         /* determine which user right we need to check based on the acb_info */
3891
3892         if (root_mode()) {
3893                 can_add_account = true;
3894         } else if (acb_info & ACB_WSTRUST) {
3895                 needed_priv = SEC_PRIV_MACHINE_ACCOUNT;
3896                 can_add_account = security_token_has_privilege(
3897                         p->session_info->security_token, needed_priv);
3898         } else if (acb_info & ACB_NORMAL &&
3899                   (account[strlen(account)-1] != '$')) {
3900                 /* usrmgr.exe (and net rpc trustdom add) creates a normal user
3901                    account for domain trusts and changes the ACB flags later */
3902                 needed_priv = SEC_PRIV_ADD_USERS;
3903                 can_add_account = security_token_has_privilege(
3904                         p->session_info->security_token, needed_priv);
3905         } else if (lp_enable_privileges()) {
3906                 /* implicit assumption of a BDC or domain trust account here
3907                  * (we already check the flags earlier) */
3908                 /* only Domain Admins can add a BDC or domain trust */
3909                 can_add_account = nt_token_check_domain_rid(
3910                         p->session_info->security_token,
3911                         DOMAIN_RID_ADMINS );
3912         }
3913
3914         DEBUG(5, ("_samr_CreateUser2: %s can add this account : %s\n",
3915                   uidtoname(p->session_info->unix_token->uid),
3916                   can_add_account ? "True":"False" ));
3917
3918         if (!can_add_account) {
3919                 return NT_STATUS_ACCESS_DENIED;
3920         }
3921
3922         /********** BEGIN Admin BLOCK **********/
3923
3924         (void)winbind_off();
3925         become_root();
3926         nt_status = pdb_create_user(p->mem_ctx, account, acb_info,
3927                                     r->out.rid);
3928         unbecome_root();
3929         (void)winbind_on();
3930
3931         /********** END Admin BLOCK **********/
3932
3933         /* now check for failure */
3934
3935         if ( !NT_STATUS_IS_OK(nt_status) )
3936                 return nt_status;
3937
3938         /* Get the user's SID */
3939
3940         sid_compose(&sid, get_global_sam_sid(), *r->out.rid);
3941
3942         map_max_allowed_access(p->session_info->security_token,
3943                                p->session_info->unix_token,
3944                                &des_access);
3945
3946         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping,
3947                             &sid, SAMR_USR_RIGHTS_WRITE_PW);
3948         se_map_generic(&des_access, &usr_generic_mapping);
3949
3950         /*
3951          * JRA - TESTME. We just created this user so we
3952          * had rights to create them. Do we need to check
3953          * any further access on this object ? Can't we
3954          * just assume we have all the rights we need ?
3955          */
3956
3957         nt_status = access_check_object(psd, p->session_info->security_token,
3958                                         needed_priv, SEC_PRIV_INVALID,
3959                                         GENERIC_RIGHTS_USER_WRITE, des_access,
3960                 &acc_granted, "_samr_CreateUser2");
3961
3962         if ( !NT_STATUS_IS_OK(nt_status) ) {
3963                 return nt_status;
3964         }
3965
3966         nt_status = create_samr_policy_handle(p->mem_ctx,
3967                                               p,
3968                                               SAMR_HANDLE_USER,
3969                                               acc_granted,
3970                                               &sid,
3971                                               NULL,
3972                                               r->out.user_handle);
3973         if (!NT_STATUS_IS_OK(nt_status)) {
3974                 return nt_status;
3975         }
3976
3977         /* After a "set" ensure we have no cached display info. */
3978         force_flush_samr_cache(&sid);
3979
3980         *r->out.access_granted = acc_granted;
3981
3982         return NT_STATUS_OK;
3983 }
3984
3985 /****************************************************************
3986 ****************************************************************/
3987
3988 NTSTATUS _samr_CreateUser(struct pipes_struct *p,
3989                           struct samr_CreateUser *r)
3990 {
3991         struct samr_CreateUser2 c;
3992         uint32_t access_granted;
3993
3994         c.in.domain_handle      = r->in.domain_handle;
3995         c.in.account_name       = r->in.account_name;
3996         c.in.acct_flags         = ACB_NORMAL;
3997         c.in.access_mask        = r->in.access_mask;
3998         c.out.user_handle       = r->out.user_handle;
3999         c.out.access_granted    = &access_granted;
4000         c.out.rid               = r->out.rid;
4001
4002         return _samr_CreateUser2(p, &c);
4003 }
4004
4005 /*******************************************************************
4006  _samr_Connect
4007  ********************************************************************/
4008
4009 NTSTATUS _samr_Connect(struct pipes_struct *p,
4010                        struct samr_Connect *r)
4011 {
4012         uint32_t acc_granted;
4013         uint32_t    des_access = r->in.access_mask;
4014         NTSTATUS status;
4015
4016         /* Access check */
4017
4018         if (!pipe_access_check(p)) {
4019                 DEBUG(3, ("access denied to _samr_Connect\n"));
4020                 return NT_STATUS_ACCESS_DENIED;
4021         }
4022
4023         /* don't give away the farm but this is probably ok.  The SAMR_ACCESS_ENUM_DOMAINS
4024            was observed from a win98 client trying to enumerate users (when configured
4025            user level access control on shares)   --jerry */
4026
4027         map_max_allowed_access(p->session_info->security_token,
4028                                p->session_info->unix_token,
4029                                &des_access);
4030
4031         se_map_generic( &des_access, &sam_generic_mapping );
4032
4033         acc_granted = des_access & (SAMR_ACCESS_ENUM_DOMAINS
4034                                     |SAMR_ACCESS_LOOKUP_DOMAIN);
4035
4036         /* set up the SAMR connect_anon response */
4037         status = create_samr_policy_handle(p->mem_ctx,
4038                                            p,
4039                                            SAMR_HANDLE_CONNECT,
4040                                            acc_granted,
4041                                            NULL,
4042                                            NULL,
4043                                            r->out.connect_handle);
4044         if (!NT_STATUS_IS_OK(status)) {
4045                 return status;
4046         }
4047
4048         return NT_STATUS_OK;
4049 }
4050
4051 /*******************************************************************
4052  _samr_Connect2
4053  ********************************************************************/
4054
4055 NTSTATUS _samr_Connect2(struct pipes_struct *p,
4056                         struct samr_Connect2 *r)
4057 {
4058         struct dcesrv_call_state *dce_call = p->dce_call;
4059         struct security_descriptor *psd = NULL;
4060         uint32_t    acc_granted;
4061         uint32_t    des_access = r->in.access_mask;
4062         NTSTATUS  nt_status;
4063         size_t    sd_size;
4064         const char *fn = "_samr_Connect2";
4065
4066         switch (dce_call->pkt.u.request.opnum) {
4067         case NDR_SAMR_CONNECT2:
4068                 fn = "_samr_Connect2";
4069                 break;
4070         case NDR_SAMR_CONNECT3:
4071                 fn = "_samr_Connect3";
4072                 break;
4073         case NDR_SAMR_CONNECT4:
4074                 fn = "_samr_Connect4";
4075                 break;
4076         case NDR_SAMR_CONNECT5:
4077                 fn = "_samr_Connect5";
4078                 break;
4079         }
4080
4081         DEBUG(5,("%s: %d\n", fn, __LINE__));
4082
4083         /* Access check */
4084
4085         if (!pipe_access_check(p)) {
4086                 DEBUG(3, ("access denied to %s\n", fn));
4087                 return NT_STATUS_ACCESS_DENIED;
4088         }
4089
4090         map_max_allowed_access(p->session_info->security_token,
4091                                p->session_info->unix_token,
4092                                &des_access);
4093
4094         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
4095         se_map_generic(&des_access, &sam_generic_mapping);
4096
4097         nt_status = access_check_object(psd, p->session_info->security_token,
4098                                         SEC_PRIV_INVALID, SEC_PRIV_INVALID,
4099                                         0, des_access, &acc_granted, fn);
4100
4101         if ( !NT_STATUS_IS_OK(nt_status) )
4102                 return nt_status;
4103
4104         nt_status = create_samr_policy_handle(p->mem_ctx,
4105                                               p,
4106                                               SAMR_HANDLE_CONNECT,
4107                                               acc_granted,
4108                                               NULL,
4109                                               NULL,
4110                                               r->out.connect_handle);
4111         if (!NT_STATUS_IS_OK(nt_status)) {
4112                 return nt_status;
4113         }
4114
4115         DEBUG(5,("%s: %d\n", fn, __LINE__));
4116
4117         return NT_STATUS_OK;
4118 }
4119
4120 /****************************************************************
4121  _samr_Connect3
4122 ****************************************************************/
4123
4124 NTSTATUS _samr_Connect3(struct pipes_struct *p,
4125                         struct samr_Connect3 *r)
4126 {
4127         struct samr_Connect2 c;
4128
4129         c.in.system_name        = r->in.system_name;
4130         c.in.access_mask        = r->in.access_mask;
4131         c.out.connect_handle    = r->out.connect_handle;
4132
4133         return _samr_Connect2(p, &c);
4134 }
4135
4136 /*******************************************************************
4137  _samr_Connect4
4138  ********************************************************************/
4139
4140 NTSTATUS _samr_Connect4(struct pipes_struct *p,
4141                         struct samr_Connect4 *r)
4142 {
4143         struct samr_Connect2 c;
4144
4145         c.in.system_name        = r->in.system_name;
4146         c.in.access_mask        = r->in.access_mask;
4147         c.out.connect_handle    = r->out.connect_handle;
4148
4149         return _samr_Connect2(p, &c);
4150 }
4151
4152 /*******************************************************************
4153  _samr_Connect5
4154  ********************************************************************/
4155
4156 NTSTATUS _samr_Connect5(struct pipes_struct *p,
4157                         struct samr_Connect5 *r)
4158 {
4159         NTSTATUS status;
4160         struct samr_Connect2 c;
4161         struct samr_ConnectInfo1 info1;
4162
4163         info1.client_version = SAMR_CONNECT_AFTER_W2K;
4164         info1.unknown2 = 0;
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         *r->out.level_out = 1;
4171
4172         status = _samr_Connect2(p, &c);
4173         if (!NT_STATUS_IS_OK(status)) {
4174                 return status;
4175         }
4176
4177         r->out.info_out->info1 = info1;
4178
4179         return NT_STATUS_OK;
4180 }
4181
4182 /**********************************************************************
4183  _samr_LookupDomain
4184  **********************************************************************/
4185
4186 NTSTATUS _samr_LookupDomain(struct pipes_struct *p,
4187                             struct samr_LookupDomain *r)
4188 {
4189         NTSTATUS status;
4190         const char *domain_name;
4191         struct dom_sid *sid = NULL;
4192         struct dom_sid_buf buf;
4193
4194         /* win9x user manager likes to use SAMR_ACCESS_ENUM_DOMAINS here.
4195            Reverted that change so we will work with RAS servers again */
4196
4197         (void)samr_policy_handle_find(p,
4198                                       r->in.connect_handle,
4199                                       SAMR_HANDLE_CONNECT,
4200                                       SAMR_ACCESS_LOOKUP_DOMAIN,
4201                                       NULL,
4202                                       &status);
4203         if (!NT_STATUS_IS_OK(status)) {
4204                 return status;
4205         }
4206
4207         domain_name = r->in.domain_name->string;
4208         if (!domain_name) {
4209                 return NT_STATUS_INVALID_PARAMETER;
4210         }
4211
4212         sid = talloc_zero(p->mem_ctx, struct dom_sid2);
4213         if (!sid) {
4214                 return NT_STATUS_NO_MEMORY;
4215         }
4216
4217         if (strequal(domain_name, builtin_domain_name())) {
4218                 sid_copy(sid, &global_sid_Builtin);
4219         } else {
4220                 if (!secrets_fetch_domain_sid(domain_name, sid)) {
4221                         status = NT_STATUS_NO_SUCH_DOMAIN;
4222                 }
4223         }
4224
4225         DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name,
4226                  dom_sid_str_buf(sid, &buf)));
4227
4228         *r->out.sid = sid;
4229
4230         return status;
4231 }
4232
4233 /**********************************************************************
4234  _samr_EnumDomains
4235  **********************************************************************/
4236
4237 NTSTATUS _samr_EnumDomains(struct pipes_struct *p,
4238                            struct samr_EnumDomains *r)
4239 {
4240         NTSTATUS status;
4241         uint32_t num_entries = 2;
4242         struct samr_SamEntry *entry_array = NULL;
4243         struct samr_SamArray *sam;
4244
4245         (void)samr_policy_handle_find(p,
4246                                       r->in.connect_handle,
4247                                       SAMR_HANDLE_CONNECT,
4248                                       SAMR_ACCESS_ENUM_DOMAINS,
4249                                       NULL,
4250                                       &status);
4251         if (!NT_STATUS_IS_OK(status)) {
4252                 return status;
4253         }
4254
4255         sam = talloc_zero(p->mem_ctx, struct samr_SamArray);
4256         if (!sam) {
4257                 return NT_STATUS_NO_MEMORY;
4258         }
4259
4260         entry_array = talloc_zero_array(p->mem_ctx,
4261                                         struct samr_SamEntry,
4262                                         num_entries);
4263         if (!entry_array) {
4264                 return NT_STATUS_NO_MEMORY;
4265         }
4266
4267         entry_array[0].idx = 0;
4268         init_lsa_String(&entry_array[0].name, get_global_sam_name());
4269
4270         entry_array[1].idx = 1;
4271         init_lsa_String(&entry_array[1].name, "Builtin");
4272
4273         sam->count = num_entries;
4274         sam->entries = entry_array;
4275
4276         *r->out.sam = sam;
4277         *r->out.num_entries = num_entries;
4278
4279         return status;
4280 }
4281
4282 /*******************************************************************
4283  _samr_OpenAlias
4284  ********************************************************************/
4285
4286 NTSTATUS _samr_OpenAlias(struct pipes_struct *p,
4287                          struct samr_OpenAlias *r)
4288 {
4289         struct dom_sid sid;
4290         uint32_t alias_rid = r->in.rid;
4291         struct samr_info *dinfo;
4292         struct security_descriptor *psd = NULL;
4293         uint32_t    acc_granted;
4294         uint32_t    des_access = r->in.access_mask;
4295         size_t    sd_size;
4296         NTSTATUS  status;
4297
4298         dinfo = samr_policy_handle_find(p,
4299                                         r->in.domain_handle,
4300                                         SAMR_HANDLE_DOMAIN,
4301                                         SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
4302                                         NULL,
4303                                         &status);
4304         if (!NT_STATUS_IS_OK(status)) {
4305                 return status;
4306         }
4307
4308         /* append the alias' RID to it */
4309
4310         if (!sid_compose(&sid, &dinfo->sid, alias_rid))
4311                 return NT_STATUS_NO_SUCH_ALIAS;
4312
4313         /*check if access can be granted as requested by client. */
4314
4315         map_max_allowed_access(p->session_info->security_token,
4316                                p->session_info->unix_token,
4317                                &des_access);
4318
4319         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &ali_generic_mapping, NULL, 0);
4320         se_map_generic(&des_access,&ali_generic_mapping);
4321
4322         status = access_check_object(psd, p->session_info->security_token,
4323                                      SEC_PRIV_ADD_USERS, SEC_PRIV_INVALID,
4324                                      GENERIC_RIGHTS_ALIAS_ALL_ACCESS,
4325                                      des_access, &acc_granted, "_samr_OpenAlias");
4326
4327         if ( !NT_STATUS_IS_OK(status) )
4328                 return status;
4329
4330         {
4331                 /* Check we actually have the requested alias */
4332                 enum lsa_SidType type;
4333                 bool result;
4334                 gid_t gid;
4335
4336                 become_root();
4337                 result = lookup_sid(NULL, &sid, NULL, NULL, &type);
4338                 unbecome_root();
4339
4340                 if (!result || (type != SID_NAME_ALIAS)) {
4341                         return NT_STATUS_NO_SUCH_ALIAS;
4342                 }
4343
4344                 /* make sure there is a mapping */
4345
4346                 if ( !sid_to_gid( &sid, &gid ) ) {
4347                         return NT_STATUS_NO_SUCH_ALIAS;
4348                 }
4349
4350         }
4351
4352         status = create_samr_policy_handle(p->mem_ctx,
4353                                            p,
4354                                            SAMR_HANDLE_ALIAS,
4355                                            acc_granted,
4356                                            &sid,
4357                                            NULL,
4358                                            r->out.alias_handle);
4359         if (!NT_STATUS_IS_OK(status)) {
4360                 return status;
4361         }
4362
4363         return NT_STATUS_OK;
4364 }
4365
4366 /*******************************************************************
4367  set_user_info_2
4368  ********************************************************************/
4369
4370 static NTSTATUS set_user_info_2(TALLOC_CTX *mem_ctx,
4371                                 struct samr_UserInfo2 *id2,
4372                                 struct samu *pwd)
4373 {
4374         if (id2 == NULL) {
4375                 DEBUG(5,("set_user_info_2: NULL id2\n"));
4376                 return NT_STATUS_ACCESS_DENIED;
4377         }
4378
4379         copy_id2_to_sam_passwd(pwd, id2);
4380
4381         return pdb_update_sam_account(pwd);
4382 }
4383
4384 /*******************************************************************
4385  set_user_info_4
4386  ********************************************************************/
4387
4388 static NTSTATUS set_user_info_4(TALLOC_CTX *mem_ctx,
4389                                 struct samr_UserInfo4 *id4,
4390                                 struct samu *pwd)
4391 {
4392         if (id4 == NULL) {
4393                 DEBUG(5,("set_user_info_2: NULL id4\n"));
4394                 return NT_STATUS_ACCESS_DENIED;
4395         }
4396
4397         copy_id4_to_sam_passwd(pwd, id4);
4398
4399         return pdb_update_sam_account(pwd);
4400 }
4401
4402 /*******************************************************************
4403  set_user_info_6
4404  ********************************************************************/
4405
4406 static NTSTATUS set_user_info_6(TALLOC_CTX *mem_ctx,
4407                                 struct samr_UserInfo6 *id6,
4408                                 struct samu *pwd)
4409 {
4410         if (id6 == NULL) {
4411                 DEBUG(5,("set_user_info_6: NULL id6\n"));
4412                 return NT_STATUS_ACCESS_DENIED;
4413         }
4414
4415         copy_id6_to_sam_passwd(pwd, id6);
4416
4417         return pdb_update_sam_account(pwd);
4418 }
4419
4420 /*******************************************************************
4421  set_user_info_7
4422  ********************************************************************/
4423
4424 static NTSTATUS set_user_info_7(TALLOC_CTX *mem_ctx,
4425                                 struct samr_UserInfo7 *id7,
4426                                 struct samu *pwd)
4427 {
4428         NTSTATUS rc;
4429
4430         if (id7 == NULL) {
4431                 DEBUG(5, ("set_user_info_7: NULL id7\n"));
4432                 return NT_STATUS_ACCESS_DENIED;
4433         }
4434
4435         if (!id7->account_name.string) {
4436                 DEBUG(5, ("set_user_info_7: failed to get new username\n"));
4437                 return NT_STATUS_ACCESS_DENIED;
4438         }
4439
4440         /* check to see if the new username already exists.  Note: we can't
4441            reliably lock all backends, so there is potentially the
4442            possibility that a user can be created in between this check and
4443            the rename.  The rename should fail, but may not get the
4444            exact same failure status code.  I think this is small enough
4445            of a window for this type of operation and the results are
4446            simply that the rename fails with a slightly different status
4447            code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
4448
4449         rc = can_create(mem_ctx, id7->account_name.string);
4450
4451         /* when there is nothing to change, we're done here */
4452         if (NT_STATUS_EQUAL(rc, NT_STATUS_USER_EXISTS) &&
4453             strequal(id7->account_name.string, pdb_get_username(pwd))) {
4454                 return NT_STATUS_OK;
4455         }
4456         if (!NT_STATUS_IS_OK(rc)) {
4457                 return rc;
4458         }
4459
4460         rc = pdb_rename_sam_account(pwd, id7->account_name.string);
4461
4462         return rc;
4463 }
4464
4465 /*******************************************************************
4466  set_user_info_8
4467  ********************************************************************/
4468
4469 static NTSTATUS set_user_info_8(TALLOC_CTX *mem_ctx,
4470                                 struct samr_UserInfo8 *id8,
4471                                 struct samu *pwd)
4472 {
4473         if (id8 == NULL) {
4474                 DEBUG(5,("set_user_info_8: NULL id8\n"));
4475                 return NT_STATUS_ACCESS_DENIED;
4476         }
4477
4478         copy_id8_to_sam_passwd(pwd, id8);
4479
4480         return pdb_update_sam_account(pwd);
4481 }
4482
4483 /*******************************************************************
4484  set_user_info_10
4485  ********************************************************************/
4486
4487 static NTSTATUS set_user_info_10(TALLOC_CTX *mem_ctx,
4488                                  struct samr_UserInfo10 *id10,
4489                                  struct samu *pwd)
4490 {
4491         if (id10 == NULL) {
4492                 DEBUG(5,("set_user_info_8: NULL id10\n"));
4493                 return NT_STATUS_ACCESS_DENIED;
4494         }
4495
4496         copy_id10_to_sam_passwd(pwd, id10);
4497
4498         return pdb_update_sam_account(pwd);
4499 }
4500
4501 /*******************************************************************
4502  set_user_info_11
4503  ********************************************************************/
4504
4505 static NTSTATUS set_user_info_11(TALLOC_CTX *mem_ctx,
4506                                  struct samr_UserInfo11 *id11,
4507                                  struct samu *pwd)
4508 {
4509         if (id11 == NULL) {
4510                 DEBUG(5,("set_user_info_11: NULL id11\n"));
4511                 return NT_STATUS_ACCESS_DENIED;
4512         }
4513
4514         copy_id11_to_sam_passwd(pwd, id11);
4515
4516         return pdb_update_sam_account(pwd);
4517 }
4518
4519 /*******************************************************************
4520  set_user_info_12
4521  ********************************************************************/
4522
4523 static NTSTATUS set_user_info_12(TALLOC_CTX *mem_ctx,
4524                                  struct samr_UserInfo12 *id12,
4525                                  struct samu *pwd)
4526 {
4527         if (id12 == NULL) {
4528                 DEBUG(5,("set_user_info_12: NULL id12\n"));
4529                 return NT_STATUS_ACCESS_DENIED;
4530         }
4531
4532         copy_id12_to_sam_passwd(pwd, id12);
4533
4534         return pdb_update_sam_account(pwd);
4535 }
4536
4537 /*******************************************************************
4538  set_user_info_13
4539  ********************************************************************/
4540
4541 static NTSTATUS set_user_info_13(TALLOC_CTX *mem_ctx,
4542                                  struct samr_UserInfo13 *id13,
4543                                  struct samu *pwd)
4544 {
4545         if (id13 == NULL) {
4546                 DEBUG(5,("set_user_info_13: NULL id13\n"));
4547                 return NT_STATUS_ACCESS_DENIED;
4548         }
4549
4550         copy_id13_to_sam_passwd(pwd, id13);
4551
4552         return pdb_update_sam_account(pwd);
4553 }
4554
4555 /*******************************************************************
4556  set_user_info_14
4557  ********************************************************************/
4558
4559 static NTSTATUS set_user_info_14(TALLOC_CTX *mem_ctx,
4560                                  struct samr_UserInfo14 *id14,
4561                                  struct samu *pwd)
4562 {
4563         if (id14 == NULL) {
4564                 DEBUG(5,("set_user_info_14: NULL id14\n"));
4565                 return NT_STATUS_ACCESS_DENIED;
4566         }
4567
4568         copy_id14_to_sam_passwd(pwd, id14);
4569
4570         return pdb_update_sam_account(pwd);
4571 }
4572
4573 /*******************************************************************
4574  set_user_info_16
4575  ********************************************************************/
4576
4577 static NTSTATUS set_user_info_16(TALLOC_CTX *mem_ctx,
4578                                  struct samr_UserInfo16 *id16,
4579                                  struct samu *pwd)
4580 {
4581         if (id16 == NULL) {
4582                 DEBUG(5,("set_user_info_16: NULL id16\n"));
4583                 return NT_STATUS_ACCESS_DENIED;
4584         }
4585
4586         copy_id16_to_sam_passwd(pwd, id16);
4587
4588         return pdb_update_sam_account(pwd);
4589 }
4590
4591 /*******************************************************************
4592  set_user_info_17
4593  ********************************************************************/
4594
4595 static NTSTATUS set_user_info_17(TALLOC_CTX *mem_ctx,
4596                                  struct samr_UserInfo17 *id17,
4597                                  struct samu *pwd)
4598 {
4599         if (id17 == NULL) {
4600                 DEBUG(5,("set_user_info_17: NULL id17\n"));
4601                 return NT_STATUS_ACCESS_DENIED;
4602         }
4603
4604         copy_id17_to_sam_passwd(pwd, id17);
4605
4606         return pdb_update_sam_account(pwd);
4607 }
4608
4609 /*******************************************************************
4610  set_user_info_18
4611  ********************************************************************/
4612
4613 static NTSTATUS set_user_info_18(struct samr_UserInfo18 *id18,
4614                                  TALLOC_CTX *mem_ctx,
4615                                  DATA_BLOB *session_key,
4616                                  struct samu *pwd)
4617 {
4618         int rc;
4619
4620         if (id18 == NULL) {
4621                 DEBUG(2, ("set_user_info_18: id18 is NULL\n"));
4622                 return NT_STATUS_INVALID_PARAMETER;
4623         }
4624
4625         if (id18->nt_pwd_active || id18->lm_pwd_active) {
4626                 if (!session_key->length) {
4627                         return NT_STATUS_NO_USER_SESSION_KEY;
4628                 }
4629         }
4630
4631         if (id18->nt_pwd_active) {
4632                 DATA_BLOB in = data_blob_const(id18->nt_pwd.hash, 16);
4633                 uint8_t outbuf[16] = { 0, };
4634                 DATA_BLOB out = data_blob_const(outbuf, sizeof(outbuf));
4635
4636                 rc = sess_crypt_blob(&out, &in, session_key, SAMBA_GNUTLS_DECRYPT);
4637                 if (rc != 0) {
4638                         return gnutls_error_to_ntstatus(rc,
4639                                                         NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER);
4640                 }
4641
4642                 if (!pdb_set_nt_passwd(pwd, out.data, PDB_CHANGED)) {
4643                         return NT_STATUS_ACCESS_DENIED;
4644                 }
4645
4646                 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4647         }
4648
4649         if (id18->lm_pwd_active) {
4650                 DATA_BLOB in = data_blob_const(id18->lm_pwd.hash, 16);
4651                 uint8_t outbuf[16] = { 0, };
4652                 DATA_BLOB out = data_blob_const(outbuf, sizeof(outbuf));
4653
4654                 rc = sess_crypt_blob(&out, &in, session_key, SAMBA_GNUTLS_DECRYPT);
4655                 if (rc != 0) {
4656                         return gnutls_error_to_ntstatus(rc,
4657                                                         NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER);
4658                 }
4659
4660                 if (!pdb_set_lanman_passwd(pwd, out.data, PDB_CHANGED)) {
4661                         return NT_STATUS_ACCESS_DENIED;
4662                 }
4663
4664                 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4665         }
4666
4667         copy_id18_to_sam_passwd(pwd, id18);
4668
4669         return pdb_update_sam_account(pwd);
4670 }
4671
4672 /*******************************************************************
4673  set_user_info_20
4674  ********************************************************************/
4675
4676 static NTSTATUS set_user_info_20(TALLOC_CTX *mem_ctx,
4677                                  struct samr_UserInfo20 *id20,
4678                                  struct samu *pwd)
4679 {
4680         if (id20 == NULL) {
4681                 DEBUG(5,("set_user_info_20: NULL id20\n"));
4682                 return NT_STATUS_ACCESS_DENIED;
4683         }
4684
4685         copy_id20_to_sam_passwd(pwd, id20);
4686
4687         return pdb_update_sam_account(pwd);
4688 }
4689
4690 /*******************************************************************
4691  set_user_info_21
4692  ********************************************************************/
4693
4694 static NTSTATUS set_user_info_21(struct samr_UserInfo21 *id21,
4695                                  TALLOC_CTX *mem_ctx,
4696                                  DATA_BLOB *session_key,
4697                                  struct samu *pwd)
4698 {
4699         NTSTATUS status;
4700         int rc;
4701
4702         if (id21 == NULL) {
4703                 DEBUG(5, ("set_user_info_21: NULL id21\n"));
4704                 return NT_STATUS_INVALID_PARAMETER;
4705         }
4706
4707         if (id21->fields_present == 0) {
4708                 return NT_STATUS_INVALID_PARAMETER;
4709         }
4710
4711         if (id21->fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
4712                 return NT_STATUS_ACCESS_DENIED;
4713         }
4714
4715         if (id21->fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
4716                 if (id21->nt_password_set) {
4717                         DATA_BLOB in = data_blob_const(
4718                                 id21->nt_owf_password.array, 16);
4719                         uint8_t outbuf[16] = { 0, };
4720                         DATA_BLOB out = data_blob_const(
4721                                 outbuf, sizeof(outbuf));
4722
4723                         if ((id21->nt_owf_password.length != 16) ||
4724                             (id21->nt_owf_password.size != 16)) {
4725                                 return NT_STATUS_INVALID_PARAMETER;
4726                         }
4727
4728                         if (!session_key->length) {
4729                                 return NT_STATUS_NO_USER_SESSION_KEY;
4730                         }
4731
4732                         rc = sess_crypt_blob(&out, &in, session_key, SAMBA_GNUTLS_DECRYPT);
4733                         if (rc != 0) {
4734                                 return gnutls_error_to_ntstatus(rc,
4735                                                                 NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER);
4736                         }
4737
4738                         pdb_set_nt_passwd(pwd, out.data, PDB_CHANGED);
4739                         pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4740                 }
4741         }
4742
4743         if (id21->fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
4744                 if (id21->lm_password_set) {
4745                         DATA_BLOB in = data_blob_const(
4746                                 id21->lm_owf_password.array, 16);
4747                         uint8_t outbuf[16] = { 0, };
4748                         DATA_BLOB out = data_blob_const(
4749                                 outbuf, sizeof(outbuf));
4750
4751                         if ((id21->lm_owf_password.length != 16) ||
4752                             (id21->lm_owf_password.size != 16)) {
4753                                 return NT_STATUS_INVALID_PARAMETER;
4754                         }
4755
4756                         if (!session_key->length) {
4757                                 return NT_STATUS_NO_USER_SESSION_KEY;
4758                         }
4759
4760                         rc = sess_crypt_blob(&out, &in, session_key, SAMBA_GNUTLS_DECRYPT);
4761                         if (rc != 0) {
4762                                 return gnutls_error_to_ntstatus(rc,
4763                                                                 NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER);
4764                         }
4765
4766                         pdb_set_lanman_passwd(pwd, out.data, PDB_CHANGED);
4767                         pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4768                 }
4769         }
4770
4771         /* we need to separately check for an account rename first */
4772
4773         if (id21->account_name.string &&
4774             (!strequal(id21->account_name.string, pdb_get_username(pwd))))
4775         {
4776
4777                 /* check to see if the new username already exists.  Note: we can't
4778                    reliably lock all backends, so there is potentially the
4779                    possibility that a user can be created in between this check and
4780                    the rename.  The rename should fail, but may not get the
4781                    exact same failure status code.  I think this is small enough
4782                    of a window for this type of operation and the results are
4783                    simply that the rename fails with a slightly different status
4784                    code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
4785
4786                 status = can_create(mem_ctx, id21->account_name.string);
4787                 if (!NT_STATUS_IS_OK(status)) {
4788                         return status;
4789                 }
4790
4791                 status = pdb_rename_sam_account(pwd, id21->account_name.string);
4792
4793                 if (!NT_STATUS_IS_OK(status)) {
4794                         DEBUG(0,("set_user_info_21: failed to rename account: %s\n",
4795                                 nt_errstr(status)));
4796                         return status;
4797                 }
4798
4799                 /* set the new username so that later
4800                    functions can work on the new account */
4801                 pdb_set_username(pwd, id21->account_name.string, PDB_SET);
4802         }
4803
4804         copy_id21_to_sam_passwd("INFO_21", pwd, id21);
4805
4806         /*
4807          * The funny part about the previous two calls is
4808          * that pwd still has the password hashes from the
4809          * passdb entry.  These have not been updated from
4810          * id21.  I don't know if they need to be set.    --jerry
4811          */
4812
4813         if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
4814                 status = pdb_set_unix_primary_group(mem_ctx, pwd);
4815                 if ( !NT_STATUS_IS_OK(status) ) {
4816                         return status;
4817                 }
4818         }
4819
4820         /* Don't worry about writing out the user account since the
4821            primary group SID is generated solely from the user's Unix
4822            primary group. */
4823
4824         /* write the change out */
4825         if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4826                 return status;
4827         }
4828
4829         return NT_STATUS_OK;
4830 }
4831
4832 /*******************************************************************
4833  set_user_info_23
4834  ********************************************************************/
4835
4836 static NTSTATUS set_user_info_23(TALLOC_CTX *mem_ctx,
4837                                  struct samr_UserInfo23 *id23,
4838                                  const char *rhost,
4839                                  struct samu *pwd)
4840 {
4841         char *plaintext_buf = NULL;
4842         size_t len = 0;
4843         uint32_t acct_ctrl;
4844         NTSTATUS status;
4845
4846         if (id23 == NULL) {
4847                 DEBUG(5, ("set_user_info_23: NULL id23\n"));
4848                 return NT_STATUS_INVALID_PARAMETER;
4849         }
4850
4851         if (id23->info.fields_present == 0) {
4852                 return NT_STATUS_INVALID_PARAMETER;
4853         }
4854
4855         if (id23->info.fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
4856                 return NT_STATUS_ACCESS_DENIED;
4857         }
4858
4859         if ((id23->info.fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
4860             (id23->info.fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT)) {
4861
4862                 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
4863                           pdb_get_username(pwd)));
4864
4865                 if (!decode_pw_buffer(mem_ctx,
4866                                       id23->password.data,
4867                                       &plaintext_buf,
4868                                       &len,
4869                                       CH_UTF16)) {
4870                         return NT_STATUS_WRONG_PASSWORD;
4871                 }
4872
4873                 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
4874                         return NT_STATUS_ACCESS_DENIED;
4875                 }
4876         }
4877
4878         copy_id23_to_sam_passwd(pwd, id23);
4879
4880         acct_ctrl = pdb_get_acct_ctrl(pwd);
4881
4882         /* if it's a trust account, don't update /etc/passwd */
4883         if (    ( (acct_ctrl &  ACB_DOMTRUST) == ACB_DOMTRUST ) ||
4884                 ( (acct_ctrl &  ACB_WSTRUST) ==  ACB_WSTRUST) ||
4885                 ( (acct_ctrl &  ACB_SVRTRUST) ==  ACB_SVRTRUST) ) {
4886                 DEBUG(5, ("Changing trust account.  Not updating /etc/passwd\n"));
4887         } else if (plaintext_buf) {
4888                 /* update the UNIX password */
4889                 if (lp_unix_password_sync() ) {
4890                         struct passwd *passwd;
4891                         if (pdb_get_username(pwd) == NULL) {
4892                                 DEBUG(1, ("chgpasswd: User without name???\n"));
4893                                 return NT_STATUS_ACCESS_DENIED;
4894                         }
4895
4896                         passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
4897                         if (passwd == NULL) {
4898                                 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
4899                         }
4900
4901                         if(!chgpasswd(pdb_get_username(pwd), rhost,
4902                                       passwd, "", plaintext_buf, True)) {
4903                                 return NT_STATUS_ACCESS_DENIED;
4904                         }
4905                         TALLOC_FREE(passwd);
4906                 }
4907         }
4908
4909         if (plaintext_buf) {
4910                 memset(plaintext_buf, '\0', strlen(plaintext_buf));
4911         }
4912
4913         if (IS_SAM_CHANGED(pwd, PDB_GROUPSID) &&
4914             (!NT_STATUS_IS_OK(status =  pdb_set_unix_primary_group(mem_ctx,
4915                                                                    pwd)))) {
4916                 return status;
4917         }
4918
4919         if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4920                 return status;
4921         }
4922
4923         return NT_STATUS_OK;
4924 }
4925
4926 /*******************************************************************
4927  set_user_info_pw
4928  ********************************************************************/
4929
4930 static bool set_user_info_pw(uint8_t *pass, const char *rhost, struct samu *pwd)
4931 {
4932         size_t len = 0;
4933         char *plaintext_buf = NULL;
4934         uint32_t acct_ctrl;
4935
4936         DEBUG(5, ("Attempting administrator password change for user %s\n",
4937                   pdb_get_username(pwd)));
4938
4939         acct_ctrl = pdb_get_acct_ctrl(pwd);
4940
4941         if (!decode_pw_buffer(talloc_tos(),
4942                                 pass,
4943                                 &plaintext_buf,
4944                                 &len,
4945                                 CH_UTF16)) {
4946                 return False;
4947         }
4948
4949         if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
4950                 return False;
4951         }
4952
4953         /* if it's a trust account, don't update /etc/passwd */
4954         if ( ( (acct_ctrl &  ACB_DOMTRUST) == ACB_DOMTRUST ) ||
4955                 ( (acct_ctrl &  ACB_WSTRUST) ==  ACB_WSTRUST) ||
4956                 ( (acct_ctrl &  ACB_SVRTRUST) ==  ACB_SVRTRUST) ) {
4957                 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
4958         } else {
4959                 /* update the UNIX password */
4960                 if (lp_unix_password_sync()) {
4961                         struct passwd *passwd;
4962
4963                         if (pdb_get_username(pwd) == NULL) {
4964                                 DEBUG(1, ("chgpasswd: User without name???\n"));
4965                                 return False;
4966                         }
4967
4968                         passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
4969                         if (passwd == NULL) {
4970                                 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
4971                         }
4972
4973                         if(!chgpasswd(pdb_get_username(pwd), rhost, passwd,
4974                                       "", plaintext_buf, True)) {
4975                                 return False;
4976                         }
4977                         TALLOC_FREE(passwd);
4978                 }
4979         }
4980
4981         memset(plaintext_buf, '\0', strlen(plaintext_buf));
4982
4983         DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
4984
4985         return True;
4986 }
4987
4988 /*******************************************************************
4989  set_user_info_24
4990  ********************************************************************/
4991
4992 static NTSTATUS set_user_info_24(TALLOC_CTX *mem_ctx,
4993                                  const char *rhost,
4994                                  struct samr_UserInfo24 *id24,
4995                                  struct samu *pwd)
4996 {
4997         NTSTATUS status;
4998
4999         if (id24 == NULL) {
5000                 DEBUG(5, ("set_user_info_24: NULL id24\n"));
5001                 return NT_STATUS_INVALID_PARAMETER;
5002         }
5003
5004         if (!set_user_info_pw(id24->password.data, rhost, pwd)) {
5005                 return NT_STATUS_WRONG_PASSWORD;
5006         }
5007
5008         copy_id24_to_sam_passwd(pwd, id24);
5009
5010         status = pdb_update_sam_account(pwd);
5011         if (!NT_STATUS_IS_OK(status)) {
5012                 return status;
5013         }
5014
5015         return NT_STATUS_OK;
5016 }
5017
5018 /*******************************************************************
5019  set_user_info_25
5020  ********************************************************************/
5021
5022 static NTSTATUS set_user_info_25(TALLOC_CTX *mem_ctx,
5023                                  const char *rhost,
5024                                  struct samr_UserInfo25 *id25,
5025                                  struct samu *pwd)
5026 {
5027         NTSTATUS status;
5028
5029         if (id25 == NULL) {
5030                 DEBUG(5, ("set_user_info_25: NULL id25\n"));
5031                 return NT_STATUS_INVALID_PARAMETER;
5032         }
5033
5034         if (id25->info.fields_present == 0) {
5035                 return NT_STATUS_INVALID_PARAMETER;
5036         }
5037
5038         if (id25->info.fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
5039                 return NT_STATUS_ACCESS_DENIED;
5040         }
5041
5042         if ((id25->info.fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
5043             (id25->info.fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT)) {
5044
5045                 if (!set_user_info_pw(id25->password.data, rhost, pwd)) {
5046                         return NT_STATUS_WRONG_PASSWORD;
5047                 }
5048         }
5049
5050         copy_id25_to_sam_passwd(pwd, id25);
5051
5052         /* write the change out */
5053         if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
5054                 return status;
5055         }
5056
5057         /*
5058          * We need to "pdb_update_sam_account" before the unix primary group
5059          * is set, because the idealx scripts would also change the
5060          * sambaPrimaryGroupSid using the ldap replace method. pdb_ldap uses
5061          * the delete explicit / add explicit, which would then fail to find
5062          * the previous primaryGroupSid value.
5063          */
5064
5065         if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
5066                 status = pdb_set_unix_primary_group(mem_ctx, pwd);
5067                 if ( !NT_STATUS_IS_OK(status) ) {
5068                         return status;
5069                 }
5070         }
5071
5072         return NT_STATUS_OK;
5073 }
5074
5075 /*******************************************************************
5076  set_user_info_26
5077  ********************************************************************/
5078
5079 static NTSTATUS set_user_info_26(TALLOC_CTX *mem_ctx,
5080                                  const char *rhost,
5081                                  struct samr_UserInfo26 *id26,
5082                                  struct samu *pwd)
5083 {
5084         NTSTATUS status;
5085
5086         if (id26 == NULL) {
5087                 DEBUG(5, ("set_user_info_26: NULL id26\n"));
5088                 return NT_STATUS_INVALID_PARAMETER;
5089         }
5090
5091         if (!set_user_info_pw(id26->password.data, rhost, pwd)) {
5092                 return NT_STATUS_WRONG_PASSWORD;
5093         }
5094
5095         copy_id26_to_sam_passwd(pwd, id26);
5096
5097         status = pdb_update_sam_account(pwd);
5098         if (!NT_STATUS_IS_OK(status)) {
5099                 return status;
5100         }
5101
5102         return NT_STATUS_OK;
5103 }
5104
5105 /*************************************************************
5106 **************************************************************/
5107
5108 static uint32_t samr_set_user_info_map_fields_to_access_mask(uint32_t fields)
5109 {
5110         uint32_t acc_required = 0;
5111
5112         /* USER_ALL_USERNAME */
5113         if (fields & SAMR_FIELD_ACCOUNT_NAME)
5114                 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5115         /* USER_ALL_FULLNAME */
5116         if (fields & SAMR_FIELD_FULL_NAME)
5117                 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5118         /* USER_ALL_PRIMARYGROUPID */
5119         if (fields & SAMR_FIELD_PRIMARY_GID)
5120                 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5121         /* USER_ALL_HOMEDIRECTORY */
5122         if (fields & SAMR_FIELD_HOME_DIRECTORY)
5123                 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5124         /* USER_ALL_HOMEDIRECTORYDRIVE */
5125         if (fields & SAMR_FIELD_HOME_DRIVE)
5126                 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5127         /* USER_ALL_SCRIPTPATH */
5128         if (fields & SAMR_FIELD_LOGON_SCRIPT)
5129                 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5130         /* USER_ALL_PROFILEPATH */
5131         if (fields & SAMR_FIELD_PROFILE_PATH)
5132                 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5133         /* USER_ALL_ADMINCOMMENT */
5134         if (fields & SAMR_FIELD_COMMENT)
5135                 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5136         /* USER_ALL_WORKSTATIONS */
5137         if (fields & SAMR_FIELD_WORKSTATIONS)
5138                 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5139         /* USER_ALL_LOGONHOURS */
5140         if (fields & SAMR_FIELD_LOGON_HOURS)
5141                 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5142         /* USER_ALL_ACCOUNTEXPIRES */
5143         if (fields & SAMR_FIELD_ACCT_EXPIRY)
5144                 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5145         /* USER_ALL_USERACCOUNTCONTROL */
5146         if (fields & SAMR_FIELD_ACCT_FLAGS)
5147                 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5148         /* USER_ALL_PARAMETERS */
5149         if (fields & SAMR_FIELD_PARAMETERS)
5150                 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5151         /* USER_ALL_USERCOMMENT */
5152         if (fields & SAMR_FIELD_COMMENT)
5153                 acc_required |= SAMR_USER_ACCESS_SET_LOC_COM;
5154         /* USER_ALL_COUNTRYCODE */
5155         if (fields & SAMR_FIELD_COUNTRY_CODE)
5156                 acc_required |= SAMR_USER_ACCESS_SET_LOC_COM;
5157         /* USER_ALL_CODEPAGE */
5158         if (fields & SAMR_FIELD_CODE_PAGE)
5159                 acc_required |= SAMR_USER_ACCESS_SET_LOC_COM;
5160         /* USER_ALL_NTPASSWORDPRESENT */
5161         if (fields & SAMR_FIELD_NT_PASSWORD_PRESENT)
5162                 acc_required |= SAMR_USER_ACCESS_SET_PASSWORD;
5163         /* USER_ALL_LMPASSWORDPRESENT */
5164         if (fields & SAMR_FIELD_LM_PASSWORD_PRESENT)
5165                 acc_required |= SAMR_USER_ACCESS_SET_PASSWORD;
5166         /* USER_ALL_PASSWORDEXPIRED */
5167         if (fields & SAMR_FIELD_EXPIRED_FLAG)
5168                 acc_required |= SAMR_USER_ACCESS_SET_PASSWORD;
5169
5170         return acc_required;
5171 }
5172
5173 static NTSTATUS arc4_decrypt_data(DATA_BLOB session_key,
5174                                      uint8_t *data,
5175                                      size_t data_size)
5176 {
5177         gnutls_cipher_hd_t cipher_hnd = NULL;
5178         gnutls_datum_t my_session_key = {
5179                 .data = session_key.data,
5180                 .size = session_key.length,
5181         };
5182         NTSTATUS status = NT_STATUS_INTERNAL_ERROR;
5183         int rc;
5184
5185         rc = gnutls_cipher_init(&cipher_hnd,
5186                                 GNUTLS_CIPHER_ARCFOUR_128,
5187                                 &my_session_key,
5188                                 NULL);
5189         if (rc < 0) {
5190                 status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID);
5191                 goto out;
5192         }
5193
5194         rc = gnutls_cipher_decrypt(cipher_hnd,
5195                                    data,
5196                                    data_size);
5197         gnutls_cipher_deinit(cipher_hnd);
5198         if (rc < 0) {
5199                 status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID);
5200                 goto out;
5201         }
5202
5203         status = NT_STATUS_OK;
5204 out:
5205         return status;
5206 }
5207
5208 /*******************************************************************
5209  samr_SetUserInfo
5210  ********************************************************************/
5211
5212 NTSTATUS _samr_SetUserInfo(struct pipes_struct *p,
5213                            struct samr_SetUserInfo *r)
5214 {
5215         struct samr_info *uinfo;
5216         NTSTATUS status;
5217         struct samu *pwd = NULL;
5218         union samr_UserInfo *info = r->in.info;
5219         uint32_t acc_required = 0;
5220         uint32_t fields = 0;
5221         bool ret;
5222         char *rhost;
5223         DATA_BLOB session_key;
5224         struct dom_sid_buf buf;
5225         struct loadparm_context *lp_ctx = NULL;
5226         bool encrypted;
5227
5228         lp_ctx = loadparm_init_s3(p->mem_ctx, loadparm_s3_helpers());
5229         if (lp_ctx == NULL) {
5230                 return NT_STATUS_NO_MEMORY;
5231         }
5232
5233         /* This is tricky.  A WinXP domain join sets
5234           (SAMR_USER_ACCESS_SET_PASSWORD|SAMR_USER_ACCESS_SET_ATTRIBUTES|SAMR_USER_ACCESS_GET_ATTRIBUTES)
5235           The MMC lusrmgr plugin includes these perms and more in the SamrOpenUser().  But the
5236           standard Win32 API calls just ask for SAMR_USER_ACCESS_SET_PASSWORD in the SamrOpenUser().
5237           This should be enough for levels 18, 24, 25,& 26.  Info level 23 can set more so
5238           we'll use the set from the WinXP join as the basis. */
5239
5240         switch (r->in.level) {
5241         case 2: /* UserPreferencesInformation */
5242                 /* USER_WRITE_ACCOUNT | USER_WRITE_PREFERENCES */
5243                 acc_required = SAMR_USER_ACCESS_SET_ATTRIBUTES | SAMR_USER_ACCESS_SET_LOC_COM;
5244                 break;
5245         case 4: /* UserLogonHoursInformation */
5246         case 6: /* UserNameInformation */
5247         case 7: /* UserAccountNameInformation */
5248         case 8: /* UserFullNameInformation */
5249         case 9: /* UserPrimaryGroupInformation */
5250         case 10: /* UserHomeInformation */
5251         case 11: /* UserScriptInformation */
5252         case 12: /* UserProfileInformation */
5253         case 13: /* UserAdminCommentInformation */
5254         case 14: /* UserWorkStationsInformation */
5255         case 16: /* UserControlInformation */
5256         case 17: /* UserExpiresInformation */
5257         case 20: /* UserParametersInformation */
5258                 /* USER_WRITE_ACCOUNT */
5259                 acc_required = SAMR_USER_ACCESS_SET_ATTRIBUTES;
5260                 break;
5261         case 18: /* UserInternal1Information */
5262                 /* FIXME: gd, this is a guess */
5263                 acc_required = SAMR_USER_ACCESS_SET_PASSWORD;
5264                 break;
5265         case 21: /* UserAllInformation */
5266                 fields = info->info21.fields_present;
5267                 acc_required = samr_set_user_info_map_fields_to_access_mask(fields);
5268                 break;
5269         case 23: /* UserInternal4Information */
5270                 fields = info->info23.info.fields_present;
5271                 acc_required = samr_set_user_info_map_fields_to_access_mask(fields);
5272                 break;
5273         case 25: /* UserInternal4InformationNew */
5274                 fields = info->info25.info.fields_present;
5275                 acc_required = samr_set_user_info_map_fields_to_access_mask(fields);
5276                 break;
5277         case 24: /* UserInternal5Information */
5278         case 26: /* UserInternal5InformationNew */
5279                 acc_required = SAMR_USER_ACCESS_SET_PASSWORD;
5280                 break;
5281         default:
5282                 return NT_STATUS_INVALID_INFO_CLASS;
5283         }
5284
5285         uinfo = samr_policy_handle_find(p,
5286                                         r->in.user_handle,
5287                                         SAMR_HANDLE_USER,
5288                                         acc_required,
5289                                         NULL,
5290                                         &status);
5291         if (!NT_STATUS_IS_OK(status)) {
5292                 return status;
5293         }
5294
5295         DEBUG(5, ("_samr_SetUserInfo: sid:%s, level:%d\n",
5296                   dom_sid_str_buf(&uinfo->sid, &buf),
5297                   r->in.level));
5298
5299         if (info == NULL) {
5300                 DEBUG(5, ("_samr_SetUserInfo: NULL info level\n"));
5301                 return NT_STATUS_INVALID_INFO_CLASS;
5302         }
5303
5304         if (!(pwd = samu_new(NULL))) {
5305                 return NT_STATUS_NO_MEMORY;
5306         }
5307
5308         become_root();
5309         ret = pdb_getsampwsid(pwd, &uinfo->sid);
5310         unbecome_root();
5311
5312         if (!ret) {
5313                 TALLOC_FREE(pwd);
5314                 return NT_STATUS_NO_SUCH_USER;
5315         }
5316
5317         rhost = tsocket_address_inet_addr_string(p->remote_address,
5318                                                  talloc_tos());
5319         if (rhost == NULL) {
5320                 return NT_STATUS_NO_MEMORY;
5321         }
5322
5323         /* ================ BEGIN Privilege BLOCK ================ */
5324
5325         become_root();
5326
5327         /* ok!  user info levels (lots: see MSDEV help), off we go... */
5328
5329         switch (r->in.level) {
5330
5331                 case 2:
5332                         status = set_user_info_2(p->mem_ctx,
5333                                                  &info->info2, pwd);
5334                         break;
5335
5336                 case 4:
5337                         status = set_user_info_4(p->mem_ctx,
5338                                                  &info->info4, pwd);
5339                         break;
5340
5341                 case 6:
5342                         status = set_user_info_6(p->mem_ctx,
5343                                                  &info->info6, pwd);
5344                         break;
5345
5346                 case 7:
5347                         status = set_user_info_7(p->mem_ctx,
5348                                                  &info->info7, pwd);
5349                         break;
5350
5351                 case 8:
5352                         status = set_user_info_8(p->mem_ctx,
5353                                                  &info->info8, pwd);
5354                         break;
5355
5356                 case 10:
5357                         status = set_user_info_10(p->mem_ctx,
5358                                                   &info->info10, pwd);
5359                         break;
5360
5361                 case 11:
5362                         status = set_user_info_11(p->mem_ctx,
5363                                                   &info->info11, pwd);
5364                         break;
5365
5366                 case 12:
5367                         status = set_user_info_12(p->mem_ctx,
5368                                                   &info->info12, pwd);
5369                         break;
5370
5371                 case 13:
5372                         status = set_user_info_13(p->mem_ctx,
5373                                                   &info->info13, pwd);
5374                         break;
5375
5376                 case 14:
5377                         status = set_user_info_14(p->mem_ctx,
5378                                                   &info->info14, pwd);
5379                         break;
5380
5381                 case 16:
5382                         status = set_user_info_16(p->mem_ctx,
5383                                                   &info->info16, pwd);
5384                         break;
5385
5386                 case 17:
5387                         status = set_user_info_17(p->mem_ctx,
5388                                                   &info->info17, pwd);
5389                         break;
5390
5391                 case 18:
5392                         status = session_extract_session_key(p->session_info, &session_key, KEY_USE_16BYTES);
5393                         if(!NT_STATUS_IS_OK(status)) {
5394                                 break;
5395                         }
5396                         /* Used by AS/U JRA. */
5397                         status = set_user_info_18(&info->info18,
5398                                                   p->mem_ctx,
5399                                                   &session_key,
5400                                                   pwd);
5401                         break;
5402
5403                 case 20:
5404                         status = set_user_info_20(p->mem_ctx,
5405                                                   &info->info20, pwd);
5406                         break;
5407
5408                 case 21:
5409                         status = session_extract_session_key(p->session_info, &session_key, KEY_USE_16BYTES);
5410                         if(!NT_STATUS_IS_OK(status)) {
5411                                 break;
5412                         }
5413                         status = set_user_info_21(&info->info21,
5414                                                   p->mem_ctx,
5415                                                   &session_key,
5416                                                   pwd);
5417                         break;
5418
5419                 case 23:
5420                         encrypted =
5421                                 dcerpc_is_transport_encrypted(p->session_info);
5422                         if (lp_weak_crypto() == SAMBA_WEAK_CRYPTO_DISALLOWED &&
5423                             !encrypted) {
5424                                 status = NT_STATUS_ACCESS_DENIED;
5425                                 break;
5426                         }
5427
5428                         status = session_extract_session_key(p->session_info, &session_key, KEY_USE_16BYTES);
5429                         if(!NT_STATUS_IS_OK(status)) {
5430                                 break;
5431                         }
5432                         /*
5433                          * This can be allowed as it requires a session key
5434                          * which we only have if we have a SMB session.
5435                          */
5436                         GNUTLS_FIPS140_SET_LAX_MODE();
5437                         status = arc4_decrypt_data(session_key,
5438                                                    info->info23.password.data,
5439                                                    516);
5440                         GNUTLS_FIPS140_SET_STRICT_MODE();
5441                         if(!NT_STATUS_IS_OK(status)) {
5442                                 break;
5443                         }
5444
5445 #ifdef DEBUG_PASSWORD
5446                         dump_data(100, info->info23.password.data, 516);
5447 #endif
5448
5449                         status = set_user_info_23(p->mem_ctx,
5450                                                   &info->info23,
5451                                                   rhost,
5452                                                   pwd);
5453                         break;
5454
5455                 case 24:
5456                         encrypted =
5457                                 dcerpc_is_transport_encrypted(p->session_info);
5458                         if (lp_weak_crypto() == SAMBA_WEAK_CRYPTO_DISALLOWED &&
5459                             !encrypted) {
5460                                 status = NT_STATUS_ACCESS_DENIED;
5461                                 break;
5462                         }
5463
5464                         status = session_extract_session_key(p->session_info, &session_key, KEY_USE_16BYTES);
5465                         if(!NT_STATUS_IS_OK(status)) {
5466                                 break;
5467                         }
5468                         /*
5469                          * This can be allowed as it requires a session key
5470                          * which we only have if we have a SMB session.
5471                          */
5472                         GNUTLS_FIPS140_SET_LAX_MODE();
5473                         status = arc4_decrypt_data(session_key,
5474                                                    info->info24.password.data,
5475                                                    516);
5476                         GNUTLS_FIPS140_SET_STRICT_MODE();
5477                         if(!NT_STATUS_IS_OK(status)) {
5478                                 break;
5479                         }
5480
5481 #ifdef DEBUG_PASSWORD
5482                         dump_data(100, info->info24.password.data, 516);
5483 #endif
5484
5485                         status = set_user_info_24(p->mem_ctx,
5486                                                   rhost,
5487                                                   &info->info24, pwd);
5488                         break;
5489
5490                 case 25:
5491                         encrypted =
5492                                 dcerpc_is_transport_encrypted(p->session_info);
5493                         if (lp_weak_crypto() == SAMBA_WEAK_CRYPTO_DISALLOWED &&
5494                             !encrypted) {
5495                                 status = NT_STATUS_ACCESS_DENIED;
5496                                 break;
5497                         }
5498
5499                         status = session_extract_session_key(p->session_info, &session_key, KEY_USE_16BYTES);
5500                         if(!NT_STATUS_IS_OK(status)) {
5501                                 break;
5502                         }
5503                         /*
5504                          * This can be allowed as it requires a session key
5505                          * which we only have if we have a SMB session.
5506                          */
5507                         GNUTLS_FIPS140_SET_LAX_MODE();
5508                         status = decode_rc4_passwd_buffer(&session_key,
5509                                         &info->info25.password);
5510                         GNUTLS_FIPS140_SET_STRICT_MODE();
5511                         if (!NT_STATUS_IS_OK(status)) {
5512                                 break;
5513                         }
5514
5515 #ifdef DEBUG_PASSWORD
5516                         dump_data(100, info->info25.password.data, 532);
5517 #endif
5518
5519                         status = set_user_info_25(p->mem_ctx,
5520                                                   rhost,
5521                                                   &info->info25, pwd);
5522                         break;
5523
5524                 case 26:
5525                         encrypted =
5526                                 dcerpc_is_transport_encrypted(p->session_info);
5527                         if (lp_weak_crypto() == SAMBA_WEAK_CRYPTO_DISALLOWED &&
5528                             !encrypted) {
5529                                 status = NT_STATUS_ACCESS_DENIED;
5530                                 break;
5531                         }
5532
5533                         status = session_extract_session_key(p->session_info, &session_key, KEY_USE_16BYTES);
5534                         if(!NT_STATUS_IS_OK(status)) {
5535                                 break;
5536                         }
5537                         /*
5538                          * This can be allowed as it requires a session key
5539                          * which we only have if we have a SMB session.
5540                          */
5541                         GNUTLS_FIPS140_SET_LAX_MODE();
5542                         status = decode_rc4_passwd_buffer(&session_key,
5543                                         &info->info26.password);
5544                         GNUTLS_FIPS140_SET_STRICT_MODE();
5545                         if (!NT_STATUS_IS_OK(status)) {
5546                                 break;
5547                         }
5548
5549 #ifdef DEBUG_PASSWORD
5550                         dump_data(100, info->info26.password.data, 516);
5551 #endif
5552
5553                         status = set_user_info_26(p->mem_ctx,
5554                                                   rhost,
5555                                                   &info->info26, pwd);
5556                         break;
5557
5558                 default:
5559                         status = NT_STATUS_INVALID_INFO_CLASS;
5560         }
5561
5562         TALLOC_FREE(pwd);
5563
5564         unbecome_root();
5565
5566         /* ================ END Privilege BLOCK ================ */
5567
5568         if (NT_STATUS_IS_OK(status)) {
5569                 force_flush_samr_cache(&uinfo->sid);
5570         }
5571
5572         return status;
5573 }
5574
5575 /*******************************************************************
5576  _samr_SetUserInfo2
5577  ********************************************************************/
5578
5579 NTSTATUS _samr_SetUserInfo2(struct pipes_struct *p,
5580                             struct samr_SetUserInfo2 *r)
5581 {
5582         struct samr_SetUserInfo q;
5583
5584         q.in.user_handle        = r->in.user_handle;
5585         q.in.level              = r->in.level;
5586         q.in.info               = r->in.info;
5587
5588         return _samr_SetUserInfo(p, &q);
5589 }
5590
5591 /*********************************************************************
5592  _samr_GetAliasMembership
5593 *********************************************************************/
5594
5595 NTSTATUS _samr_GetAliasMembership(struct pipes_struct *p,
5596                                   struct samr_GetAliasMembership *r)
5597 {
5598         size_t num_alias_rids;
5599         uint32_t *alias_rids;
5600         struct samr_info *dinfo;
5601         size_t i;
5602
5603         NTSTATUS status;
5604
5605         struct dom_sid *members;
5606
5607         DEBUG(5,("_samr_GetAliasMembership: %d\n", __LINE__));
5608
5609         dinfo = samr_policy_handle_find(p,
5610                                         r->in.domain_handle,
5611                                         SAMR_HANDLE_DOMAIN,
5612                                         SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS
5613                                         | SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
5614                                         NULL,
5615                                         &status);
5616         if (!NT_STATUS_IS_OK(status)) {
5617                 return status;
5618         }
5619
5620         if (!sid_check_is_our_sam(&dinfo->sid) &&
5621             !sid_check_is_builtin(&dinfo->sid))
5622                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
5623
5624         if (r->in.sids->num_sids) {
5625                 members = talloc_array(p->mem_ctx, struct dom_sid, r->in.sids->num_sids);
5626
5627                 if (members == NULL)
5628                         return NT_STATUS_NO_MEMORY;
5629         } else {
5630                 members = NULL;
5631         }
5632
5633         for (i=0; i<r->in.sids->num_sids; i++)
5634                 sid_copy(&members[i], r->in.sids->sids[i].sid);
5635
5636         alias_rids = NULL;
5637         num_alias_rids = 0;
5638
5639         become_root();
5640         status = pdb_enum_alias_memberships(p->mem_ctx, &dinfo->sid, members,
5641                                             r->in.sids->num_sids,
5642                                             &alias_rids, &num_alias_rids);
5643         unbecome_root();
5644
5645         if (!NT_STATUS_IS_OK(status)) {
5646                 return status;
5647         }
5648
5649         r->out.rids->count = num_alias_rids;
5650         r->out.rids->ids = alias_rids;
5651
5652         if (r->out.rids->ids == NULL) {
5653                 /* Windows domain clients don't accept a NULL ptr here */
5654                 r->out.rids->ids = talloc_zero(p->mem_ctx, uint32_t);
5655         }
5656         if (r->out.rids->ids == NULL) {
5657                 return NT_STATUS_NO_MEMORY;
5658         }
5659
5660         return NT_STATUS_OK;
5661 }
5662
5663 /*********************************************************************
5664  _samr_GetMembersInAlias
5665 *********************************************************************/
5666
5667 NTSTATUS _samr_GetMembersInAlias(struct pipes_struct *p,
5668                                  struct samr_GetMembersInAlias *r)
5669 {
5670         struct samr_info *ainfo;
5671         NTSTATUS status;
5672         size_t i;
5673         size_t num_sids = 0;
5674         struct lsa_SidPtr *sids = NULL;
5675         struct dom_sid *pdb_sids = NULL;
5676         struct dom_sid_buf buf;
5677
5678         ainfo = samr_policy_handle_find(p,
5679                                         r->in.alias_handle,
5680                                         SAMR_HANDLE_ALIAS,
5681                                         SAMR_ALIAS_ACCESS_GET_MEMBERS,
5682                                         NULL,
5683                                         &status);
5684         if (!NT_STATUS_IS_OK(status)) {
5685                 return status;
5686         }
5687
5688         DEBUG(10, ("sid is %s\n", dom_sid_str_buf(&ainfo->sid, &buf)));
5689
5690         become_root();
5691         status = pdb_enum_aliasmem(&ainfo->sid, talloc_tos(), &pdb_sids,
5692                                    &num_sids);
5693         unbecome_root();
5694
5695         if (!NT_STATUS_IS_OK(status)) {
5696                 return status;
5697         }
5698
5699         if (num_sids) {
5700                 sids = talloc_zero_array(p->mem_ctx, struct lsa_SidPtr, num_sids);
5701                 if (sids == NULL) {
5702                         TALLOC_FREE(pdb_sids);
5703                         return NT_STATUS_NO_MEMORY;
5704                 }
5705         }
5706
5707         for (i = 0; i < num_sids; i++) {
5708                 sids[i].sid = dom_sid_dup(p->mem_ctx, &pdb_sids[i]);
5709                 if (!sids[i].sid) {
5710                         TALLOC_FREE(pdb_sids);
5711                         return NT_STATUS_NO_MEMORY;
5712                 }
5713         }
5714
5715         r->out.sids->num_sids = num_sids;
5716         r->out.sids->sids = sids;
5717
5718         TALLOC_FREE(pdb_sids);
5719
5720         return NT_STATUS_OK;
5721 }
5722
5723 /*********************************************************************
5724  _samr_QueryGroupMember
5725 *********************************************************************/
5726
5727 NTSTATUS _samr_QueryGroupMember(struct pipes_struct *p,
5728                                 struct samr_QueryGroupMember *r)
5729 {
5730         struct samr_info *ginfo;
5731         size_t i, num_members;
5732
5733         uint32_t *rid=NULL;
5734         uint32_t *attr=NULL;
5735
5736         NTSTATUS status;
5737         struct samr_RidAttrArray *rids = NULL;
5738         struct dom_sid_buf buf;
5739
5740         ginfo = samr_policy_handle_find(p,
5741                                         r->in.group_handle,
5742                                         SAMR_HANDLE_GROUP,
5743                                         SAMR_GROUP_ACCESS_GET_MEMBERS,
5744                                         NULL,
5745                                         &status);
5746         if (!NT_STATUS_IS_OK(status)) {
5747                 return status;
5748         }
5749
5750         rids = talloc_zero(p->mem_ctx, struct samr_RidAttrArray);
5751         if (!rids) {
5752                 return NT_STATUS_NO_MEMORY;
5753         }
5754
5755         DEBUG(10, ("sid is %s\n", dom_sid_str_buf(&ginfo->sid, &buf)));
5756
5757         if (!sid_check_is_in_our_sam(&ginfo->sid)) {
5758                 DEBUG(3, ("sid %s is not in our domain\n",
5759                           dom_sid_str_buf(&ginfo->sid, &buf)));
5760                 return NT_STATUS_NO_SUCH_GROUP;
5761         }
5762
5763         DEBUG(10, ("lookup on Domain SID\n"));
5764
5765         become_root();
5766         status = pdb_enum_group_members(p->mem_ctx, &ginfo->sid,
5767                                         &rid, &num_members);
5768         unbecome_root();
5769
5770         if (!NT_STATUS_IS_OK(status))
5771                 return status;
5772
5773         if (num_members) {
5774                 attr=talloc_zero_array(p->mem_ctx, uint32_t, num_members);
5775                 if (attr == NULL) {
5776                         return NT_STATUS_NO_MEMORY;
5777                 }
5778         } else {
5779                 attr = NULL;
5780         }
5781
5782         for (i=0; i<num_members; i++) {
5783                 attr[i] = SE_GROUP_MANDATORY |
5784                           SE_GROUP_ENABLED_BY_DEFAULT |
5785                           SE_GROUP_ENABLED;
5786         }
5787
5788         rids->count = num_members;
5789         rids->attributes = attr;
5790         rids->rids = rid;
5791
5792         *r->out.rids = rids;
5793
5794         return NT_STATUS_OK;
5795 }
5796
5797 /*********************************************************************
5798  _samr_AddAliasMember
5799 *********************************************************************/
5800
5801 NTSTATUS _samr_AddAliasMember(struct pipes_struct *p,
5802                               struct samr_AddAliasMember *r)
5803 {
5804         struct samr_info *ainfo;
5805         struct dom_sid_buf buf;
5806         NTSTATUS status;
5807
5808         ainfo = samr_policy_handle_find(p,
5809                                         r->in.alias_handle,
5810                                         SAMR_HANDLE_ALIAS,
5811                                         SAMR_ALIAS_ACCESS_ADD_MEMBER,
5812                                         NULL,
5813                                         &status);
5814         if (!NT_STATUS_IS_OK(status)) {
5815                 return status;
5816         }
5817
5818         DEBUG(10, ("sid is %s\n", dom_sid_str_buf(&ainfo->sid, &buf)));
5819
5820         /******** BEGIN SeAddUsers BLOCK *********/
5821
5822         become_root();
5823         status = pdb_add_aliasmem(&ainfo->sid, r->in.sid);
5824         unbecome_root();
5825
5826         /******** END SeAddUsers BLOCK *********/
5827
5828         if (NT_STATUS_IS_OK(status)) {
5829                 force_flush_samr_cache(&ainfo->sid);
5830         }
5831
5832         return status;
5833 }
5834
5835 /*********************************************************************
5836  _samr_DeleteAliasMember
5837 *********************************************************************/
5838
5839 NTSTATUS _samr_DeleteAliasMember(struct pipes_struct *p,
5840                                  struct samr_DeleteAliasMember *r)
5841 {
5842         struct samr_info *ainfo;
5843         struct dom_sid_buf buf;
5844         NTSTATUS status;
5845
5846         ainfo = samr_policy_handle_find(p,
5847                                         r->in.alias_handle,
5848                                         SAMR_HANDLE_ALIAS,
5849                                         SAMR_ALIAS_ACCESS_REMOVE_MEMBER,
5850                                         NULL,
5851                                         &status);
5852         if (!NT_STATUS_IS_OK(status)) {
5853                 return status;
5854         }
5855
5856         DEBUG(10, ("_samr_del_aliasmem:sid is %s\n",
5857                    dom_sid_str_buf(&ainfo->sid, &buf)));
5858
5859         /******** BEGIN SeAddUsers BLOCK *********/
5860
5861         become_root();
5862         status = pdb_del_aliasmem(&ainfo->sid, r->in.sid);
5863         unbecome_root();
5864
5865         /******** END SeAddUsers BLOCK *********/
5866
5867         if (NT_STATUS_IS_OK(status)) {
5868                 force_flush_samr_cache(&ainfo->sid);
5869         }
5870
5871         return status;
5872 }
5873
5874 /*********************************************************************
5875  _samr_AddGroupMember
5876 *********************************************************************/
5877
5878 NTSTATUS _samr_AddGroupMember(struct pipes_struct *p,
5879                               struct samr_AddGroupMember *r)
5880 {
5881         struct samr_info *ginfo;
5882         struct dom_sid_buf buf;
5883         NTSTATUS status;
5884         uint32_t group_rid;
5885
5886         ginfo = samr_policy_handle_find(p,
5887                                         r->in.group_handle,
5888                                         SAMR_HANDLE_GROUP,
5889                                         SAMR_GROUP_ACCESS_ADD_MEMBER,
5890                                         NULL,
5891                                         &status);
5892         if (!NT_STATUS_IS_OK(status)) {
5893                 return status;
5894         }
5895
5896         DEBUG(10, ("sid is %s\n", dom_sid_str_buf(&ginfo->sid, &buf)));
5897
5898         if (!sid_peek_check_rid(get_global_sam_sid(), &ginfo->sid,
5899                                 &group_rid)) {
5900                 return NT_STATUS_INVALID_HANDLE;
5901         }
5902
5903         /******** BEGIN SeAddUsers BLOCK *********/
5904
5905         become_root();
5906         status = pdb_add_groupmem(p->mem_ctx, group_rid, r->in.rid);
5907         unbecome_root();
5908
5909         /******** END SeAddUsers BLOCK *********/
5910
5911         force_flush_samr_cache(&ginfo->sid);
5912
5913         return status;
5914 }
5915
5916 /*********************************************************************
5917  _samr_DeleteGroupMember
5918 *********************************************************************/
5919
5920 NTSTATUS _samr_DeleteGroupMember(struct pipes_struct *p,
5921                                  struct samr_DeleteGroupMember *r)
5922
5923 {
5924         struct samr_info *ginfo;
5925         NTSTATUS status;
5926         uint32_t group_rid;
5927
5928         /*
5929          * delete the group member named r->in.rid
5930          * who is a member of the sid associated with the handle
5931          * the rid is a user's rid as the group is a domain group.
5932          */
5933
5934         ginfo = samr_policy_handle_find(p,
5935                                         r->in.group_handle,
5936                                         SAMR_HANDLE_GROUP,
5937                                         SAMR_GROUP_ACCESS_REMOVE_MEMBER,
5938                                         NULL,
5939                                         &status);
5940         if (!NT_STATUS_IS_OK(status)) {
5941                 return status;
5942         }
5943
5944         if (!sid_peek_check_rid(get_global_sam_sid(), &ginfo->sid,
5945                                 &group_rid)) {
5946                 return NT_STATUS_INVALID_HANDLE;
5947         }
5948
5949         /******** BEGIN SeAddUsers BLOCK *********/
5950
5951         become_root();
5952         status = pdb_del_groupmem(p->mem_ctx, group_rid, r->in.rid);
5953         unbecome_root();
5954
5955         /******** END SeAddUsers BLOCK *********/
5956
5957         force_flush_samr_cache(&ginfo->sid);
5958
5959         return status;
5960 }
5961
5962 /*********************************************************************
5963  _samr_DeleteUser
5964 *********************************************************************/
5965
5966 NTSTATUS _samr_DeleteUser(struct pipes_struct *p,
5967                           struct samr_DeleteUser *r)
5968 {
5969         struct samr_info *uinfo;
5970         NTSTATUS status;
5971         struct samu *sam_pass=NULL;
5972         bool ret;
5973
5974         DEBUG(5, ("_samr_DeleteUser: %d\n", __LINE__));
5975
5976         uinfo = samr_policy_handle_find(p,
5977                                         r->in.user_handle,
5978                                         SAMR_HANDLE_USER,
5979                                         SEC_STD_DELETE,
5980                                         NULL,
5981                                         &status);
5982         if (!NT_STATUS_IS_OK(status)) {
5983                 return status;
5984         }
5985
5986         if (!sid_check_is_in_our_sam(&uinfo->sid))
5987                 return NT_STATUS_CANNOT_DELETE;
5988
5989         /* check if the user exists before trying to delete */
5990         if ( !(sam_pass = samu_new( NULL )) ) {
5991                 return NT_STATUS_NO_MEMORY;
5992         }
5993
5994         become_root();
5995         ret = pdb_getsampwsid(sam_pass, &uinfo->sid);
5996         unbecome_root();
5997
5998         if(!ret) {
5999                 struct dom_sid_buf buf;
6000                 DEBUG(5,("_samr_DeleteUser: User %s doesn't exist.\n",
6001                          dom_sid_str_buf(&uinfo->sid, &buf)));
6002                 TALLOC_FREE(sam_pass);
6003                 return NT_STATUS_NO_SUCH_USER;
6004         }
6005
6006         /******** BEGIN SeAddUsers BLOCK *********/
6007
6008         become_root();
6009         status = pdb_delete_user(p->mem_ctx, sam_pass);
6010         unbecome_root();
6011
6012         /******** END SeAddUsers BLOCK *********/
6013
6014         if ( !NT_STATUS_IS_OK(status) ) {
6015                 DEBUG(5,("_samr_DeleteUser: Failed to delete entry for "
6016                          "user %s: %s.\n", pdb_get_username(sam_pass),
6017                          nt_errstr(status)));
6018                 TALLOC_FREE(sam_pass);
6019                 return status;
6020         }
6021
6022
6023         TALLOC_FREE(sam_pass);
6024
6025         force_flush_samr_cache(&uinfo->sid);
6026
6027         if (!close_policy_hnd(p, r->in.user_handle))
6028                 return NT_STATUS_OBJECT_NAME_INVALID;
6029
6030         ZERO_STRUCTP(r->out.user_handle);
6031
6032         return NT_STATUS_OK;
6033 }
6034
6035 /*********************************************************************
6036  _samr_DeleteDomainGroup
6037 *********************************************************************/
6038
6039 NTSTATUS _samr_DeleteDomainGroup(struct pipes_struct *p,
6040                                  struct samr_DeleteDomainGroup *r)
6041 {
6042         struct samr_info *ginfo;
6043         struct dom_sid_buf buf;
6044         NTSTATUS status;
6045         uint32_t group_rid;
6046
6047         DEBUG(5, ("samr_DeleteDomainGroup: %d\n", __LINE__));
6048
6049         ginfo = samr_policy_handle_find(p,
6050                                         r->in.group_handle,
6051                                         SAMR_HANDLE_GROUP,
6052                                         SEC_STD_DELETE,
6053                                         NULL,
6054                                         &status);
6055         if (!NT_STATUS_IS_OK(status)) {
6056                 return status;
6057         }
6058
6059         DEBUG(10, ("sid is %s\n", dom_sid_str_buf(&ginfo->sid, &buf)));
6060
6061         if (!sid_peek_check_rid(get_global_sam_sid(), &ginfo->sid,
6062                                 &group_rid)) {
6063                 return NT_STATUS_NO_SUCH_GROUP;
6064         }
6065
6066         /******** BEGIN SeAddUsers BLOCK *********/
6067
6068         become_root();
6069         status = pdb_delete_dom_group(p->mem_ctx, group_rid);
6070         unbecome_root();
6071
6072         /******** END SeAddUsers BLOCK *********/
6073
6074         if ( !NT_STATUS_IS_OK(status) ) {
6075                 DEBUG(5,("_samr_DeleteDomainGroup: Failed to delete mapping "
6076                          "entry for group %s: %s\n",
6077                          dom_sid_str_buf(&ginfo->sid, &buf),
6078                          nt_errstr(status)));
6079                 return status;
6080         }
6081
6082         force_flush_samr_cache(&ginfo->sid);
6083
6084         if (!close_policy_hnd(p, r->in.group_handle))
6085                 return NT_STATUS_OBJECT_NAME_INVALID;
6086
6087         return NT_STATUS_OK;
6088 }
6089
6090 /*********************************************************************
6091  _samr_DeleteDomAlias
6092 *********************************************************************/
6093
6094 NTSTATUS _samr_DeleteDomAlias(struct pipes_struct *p,
6095                               struct samr_DeleteDomAlias *r)
6096 {
6097         struct samr_info *ainfo;
6098         struct dom_sid_buf buf;
6099         NTSTATUS status;
6100
6101         DEBUG(5, ("_samr_DeleteDomAlias: %d\n", __LINE__));
6102
6103         ainfo = samr_policy_handle_find(p,
6104                                         r->in.alias_handle,
6105                                         SAMR_HANDLE_ALIAS,
6106                                         SEC_STD_DELETE,
6107                                         NULL,
6108                                         &status);
6109         if (!NT_STATUS_IS_OK(status)) {
6110                 return status;
6111         }
6112
6113         DEBUG(10, ("sid is %s\n", dom_sid_str_buf(&ainfo->sid, &buf)));
6114
6115         /* Don't let Windows delete builtin groups */
6116
6117         if ( sid_check_is_in_builtin( &ainfo->sid ) ) {
6118                 return NT_STATUS_SPECIAL_ACCOUNT;
6119         }
6120
6121         if (!sid_check_is_in_our_sam(&ainfo->sid))
6122                 return NT_STATUS_NO_SUCH_ALIAS;
6123
6124         DEBUG(10, ("lookup on Local SID\n"));
6125
6126         /******** BEGIN SeAddUsers BLOCK *********/
6127
6128         become_root();
6129         /* Have passdb delete the alias */
6130         status = pdb_delete_alias(&ainfo->sid);
6131         unbecome_root();
6132
6133         /******** END SeAddUsers BLOCK *********/
6134
6135         if ( !NT_STATUS_IS_OK(status))
6136                 return status;
6137
6138         force_flush_samr_cache(&ainfo->sid);
6139
6140         if (!close_policy_hnd(p, r->in.alias_handle))
6141                 return NT_STATUS_OBJECT_NAME_INVALID;
6142
6143         return NT_STATUS_OK;
6144 }
6145
6146 /*********************************************************************
6147  _samr_CreateDomainGroup
6148 *********************************************************************/
6149
6150 NTSTATUS _samr_CreateDomainGroup(struct pipes_struct *p,
6151                                  struct samr_CreateDomainGroup *r)
6152
6153 {
6154         NTSTATUS status;
6155         const char *name;
6156         struct samr_info *dinfo;
6157         struct dom_sid sid;
6158
6159         dinfo = samr_policy_handle_find(p,
6160                                         r->in.domain_handle,
6161                                         SAMR_HANDLE_DOMAIN,
6162                                         SAMR_DOMAIN_ACCESS_CREATE_GROUP,
6163                                         NULL,
6164                                         &status);
6165         if (!NT_STATUS_IS_OK(status)) {
6166                 return status;
6167         }
6168
6169         if (!sid_check_is_our_sam(&dinfo->sid)) {
6170                 return NT_STATUS_ACCESS_DENIED;
6171         }
6172
6173         name = r->in.name->string;
6174         if (name == NULL) {
6175                 return NT_STATUS_NO_MEMORY;
6176         }
6177
6178         status = can_create(p->mem_ctx, name);
6179         if (!NT_STATUS_IS_OK(status)) {
6180                 return status;
6181         }
6182
6183         /******** BEGIN SeAddUsers BLOCK *********/
6184
6185         become_root();
6186         /* check that we successfully create the UNIX group */
6187         status = pdb_create_dom_group(p->mem_ctx, name, r->out.rid);
6188         unbecome_root();
6189
6190         /******** END SeAddUsers BLOCK *********/
6191
6192         /* check if we should bail out here */
6193
6194         if ( !NT_STATUS_IS_OK(status) )
6195                 return status;
6196
6197         sid_compose(&sid, &dinfo->sid, *r->out.rid);
6198
6199         status = create_samr_policy_handle(p->mem_ctx,
6200                                            p,
6201                                            SAMR_HANDLE_GROUP,
6202                                            GENERIC_RIGHTS_GROUP_ALL_ACCESS,
6203                                            &sid,
6204                                            NULL,
6205                                            r->out.group_handle);
6206         if (!NT_STATUS_IS_OK(status)) {
6207                 return status;
6208         }
6209
6210         force_flush_samr_cache(&dinfo->sid);
6211
6212         return NT_STATUS_OK;
6213 }
6214
6215 /*********************************************************************
6216  _samr_CreateDomAlias
6217 *********************************************************************/
6218
6219 NTSTATUS _samr_CreateDomAlias(struct pipes_struct *p,
6220                               struct samr_CreateDomAlias *r)
6221 {
6222         struct dom_sid info_sid;
6223         const char *name = NULL;
6224         struct samr_info *dinfo;
6225         gid_t gid;
6226         NTSTATUS result;
6227
6228         dinfo = samr_policy_handle_find(p,
6229                                         r->in.domain_handle,
6230                                         SAMR_HANDLE_DOMAIN,
6231                                         SAMR_DOMAIN_ACCESS_CREATE_ALIAS,
6232                                         NULL,
6233                                         &result);
6234         if (!NT_STATUS_IS_OK(result)) {
6235                 return result;
6236         }
6237
6238         if (!sid_check_is_our_sam(&dinfo->sid)) {
6239                 return NT_STATUS_ACCESS_DENIED;
6240         }
6241
6242         name = r->in.alias_name->string;
6243
6244         result = can_create(p->mem_ctx, name);
6245         if (!NT_STATUS_IS_OK(result)) {
6246                 return result;
6247         }
6248
6249         /******** BEGIN SeAddUsers BLOCK *********/
6250
6251         become_root();
6252         /* Have passdb create the alias */
6253         result = pdb_create_alias(name, r->out.rid);
6254         unbecome_root();
6255
6256         /******** END SeAddUsers BLOCK *********/
6257
6258         if (!NT_STATUS_IS_OK(result)) {
6259                 DEBUG(10, ("pdb_create_alias failed: %s\n",
6260                            nt_errstr(result)));
6261                 return result;
6262         }
6263
6264         sid_compose(&info_sid, &dinfo->sid, *r->out.rid);
6265
6266         if (!sid_to_gid(&info_sid, &gid)) {
6267                 DEBUG(10, ("Could not find alias just created\n"));
6268                 return NT_STATUS_ACCESS_DENIED;
6269         }
6270
6271         /* check if the group has been successfully created */
6272         if ( getgrgid(gid) == NULL ) {
6273                 DEBUG(1, ("getgrgid(%u) of just created alias failed\n",
6274                            (unsigned int)gid));
6275                 return NT_STATUS_ACCESS_DENIED;
6276         }
6277
6278         result = create_samr_policy_handle(p->mem_ctx,
6279                                            p,
6280                                            SAMR_HANDLE_ALIAS,
6281                                            GENERIC_RIGHTS_ALIAS_ALL_ACCESS,
6282                                            &info_sid,
6283                                            NULL,
6284                                            r->out.alias_handle);
6285         if (!NT_STATUS_IS_OK(result)) {
6286                 return result;
6287         }
6288
6289         force_flush_samr_cache(&info_sid);
6290
6291         return NT_STATUS_OK;
6292 }
6293
6294 /*********************************************************************
6295  _samr_QueryGroupInfo
6296 *********************************************************************/
6297
6298 NTSTATUS _samr_QueryGroupInfo(struct pipes_struct *p,
6299                               struct samr_QueryGroupInfo *r)
6300 {
6301         struct samr_info *ginfo;
6302         NTSTATUS status;
6303         GROUP_MAP *map;
6304         union samr_GroupInfo *info = NULL;
6305         bool ret;
6306         uint32_t attributes = SE_GROUP_MANDATORY |
6307                               SE_GROUP_ENABLED_BY_DEFAULT |
6308                               SE_GROUP_ENABLED;
6309         const char *group_name = NULL;
6310         const char *group_description = NULL;
6311
6312         ginfo = samr_policy_handle_find(p,
6313                                         r->in.group_handle,
6314                                         SAMR_HANDLE_GROUP,
6315                                         SAMR_GROUP_ACCESS_LOOKUP_INFO,
6316                                         NULL,
6317                                         &status);
6318         if (!NT_STATUS_IS_OK(status)) {
6319                 return status;
6320         }
6321
6322         map = talloc_zero(p->mem_ctx, GROUP_MAP);
6323         if (!map) {
6324                 return NT_STATUS_NO_MEMORY;
6325         }
6326
6327         become_root();
6328         ret = get_domain_group_from_sid(ginfo->sid, map);
6329         unbecome_root();
6330         if (!ret)
6331                 return NT_STATUS_INVALID_HANDLE;
6332
6333         group_name = talloc_move(r, &map->nt_name);
6334         group_description = talloc_move(r, &map->comment);
6335
6336         TALLOC_FREE(map);
6337
6338         info = talloc_zero(p->mem_ctx, union samr_GroupInfo);
6339         if (!info) {
6340                 return NT_STATUS_NO_MEMORY;
6341         }
6342
6343         switch (r->in.level) {
6344                 case 1: {
6345                         uint32_t *members;
6346                         size_t num_members;
6347
6348                         become_root();
6349                         status = pdb_enum_group_members(
6350                                 p->mem_ctx, &ginfo->sid, &members,
6351                                 &num_members);
6352                         unbecome_root();
6353
6354                         if (!NT_STATUS_IS_OK(status)) {
6355                                 return status;
6356                         }
6357
6358                         info->all.name.string           = group_name;
6359                         info->all.attributes            = attributes;
6360                         info->all.num_members           = num_members;
6361                         info->all.description.string    = group_description;
6362                         break;
6363                 }
6364                 case 2:
6365                         info->name.string = group_name;
6366                         break;
6367                 case 3:
6368                         info->attributes.attributes = attributes;
6369                         break;
6370                 case 4:
6371                         info->description.string = group_description;
6372                         break;
6373                 case 5: {
6374                         /*
6375                         uint32_t *members;
6376                         size_t num_members;
6377                         */
6378
6379                         /*
6380                         become_root();
6381                         status = pdb_enum_group_members(
6382                                 p->mem_ctx, &ginfo->sid, &members,
6383                                 &num_members);
6384                         unbecome_root();
6385
6386                         if (!NT_STATUS_IS_OK(status)) {
6387                                 return status;
6388                         }
6389                         */
6390                         info->all2.name.string          = group_name;
6391                         info->all2.attributes           = attributes;
6392                         info->all2.num_members          = 0; /* num_members - in w2k3 this is always 0 */
6393                         info->all2.description.string   = group_description;
6394
6395                         break;
6396                 }
6397                 default:
6398                         return NT_STATUS_INVALID_INFO_CLASS;
6399         }
6400
6401         *r->out.info = info;
6402
6403         return NT_STATUS_OK;
6404 }
6405
6406 /*********************************************************************
6407  _samr_SetGroupInfo
6408 *********************************************************************/
6409
6410 NTSTATUS _samr_SetGroupInfo(struct pipes_struct *p,
6411                             struct samr_SetGroupInfo *r)
6412 {
6413         struct samr_info *ginfo;
6414         GROUP_MAP *map;
6415         NTSTATUS status;
6416         bool ret;
6417
6418         ginfo = samr_policy_handle_find(p,
6419                                         r->in.group_handle,
6420                                         SAMR_HANDLE_GROUP,
6421                                         SAMR_GROUP_ACCESS_SET_INFO,
6422                                         NULL,
6423                                         &status);
6424         if (!NT_STATUS_IS_OK(status)) {
6425                 return status;
6426         }
6427
6428         map = talloc_zero(p->mem_ctx, GROUP_MAP);
6429         if (!map) {
6430                 return NT_STATUS_NO_MEMORY;
6431         }
6432
6433         become_root();
6434         ret = get_domain_group_from_sid(ginfo->sid, map);
6435         unbecome_root();
6436         if (!ret)
6437                 return NT_STATUS_NO_SUCH_GROUP;
6438
6439         switch (r->in.level) {
6440                 case 2:
6441                         map->nt_name = talloc_strdup(map,
6442                                                      r->in.info->name.string);
6443                         if (!map->nt_name) {
6444                                 return NT_STATUS_NO_MEMORY;
6445                         }
6446                         break;
6447                 case 3:
6448                         break;
6449                 case 4:
6450                         map->comment = talloc_strdup(map,
6451                                                 r->in.info->description.string);
6452                         if (!map->comment) {
6453                                 return NT_STATUS_NO_MEMORY;
6454                         }
6455                         break;
6456                 default:
6457                         return NT_STATUS_INVALID_INFO_CLASS;
6458         }
6459
6460         /******** BEGIN SeAddUsers BLOCK *********/
6461
6462         become_root();
6463         status = pdb_update_group_mapping_entry(map);
6464         unbecome_root();
6465
6466         /******** End SeAddUsers BLOCK *********/
6467
6468         TALLOC_FREE(map);
6469
6470         if (NT_STATUS_IS_OK(status)) {
6471                 force_flush_samr_cache(&ginfo->sid);
6472         }
6473
6474         return status;
6475 }
6476
6477 /*********************************************************************
6478  _samr_SetAliasInfo
6479 *********************************************************************/
6480
6481 NTSTATUS _samr_SetAliasInfo(struct pipes_struct *p,
6482                             struct samr_SetAliasInfo *r)
6483 {
6484         struct samr_info *ainfo;
6485         struct acct_info *info;
6486         NTSTATUS status;
6487
6488         ainfo = samr_policy_handle_find(p,
6489                                         r->in.alias_handle,
6490                                         SAMR_HANDLE_ALIAS,
6491                                         SAMR_ALIAS_ACCESS_SET_INFO,
6492                                         NULL,
6493                                         &status);
6494         if (!NT_STATUS_IS_OK(status)) {
6495                 return status;
6496         }
6497
6498         info = talloc_zero(p->mem_ctx, struct acct_info);
6499         if (!info) {
6500                 return NT_STATUS_NO_MEMORY;
6501         }
6502
6503         /* get the current group information */
6504
6505         become_root();
6506         status = pdb_get_aliasinfo(&ainfo->sid, info);
6507         unbecome_root();
6508
6509         if ( !NT_STATUS_IS_OK(status))
6510                 return status;
6511
6512         switch (r->in.level) {
6513                 case ALIASINFONAME:
6514                 {
6515                         char *group_name;
6516
6517                         /* We currently do not support renaming groups in the
6518                            the BUILTIN domain.  Refer to util_builtin.c to understand
6519                            why.  The eventually needs to be fixed to be like Windows
6520                            where you can rename builtin groups, just not delete them */
6521
6522                         if ( sid_check_is_in_builtin( &ainfo->sid ) ) {
6523                                 return NT_STATUS_SPECIAL_ACCOUNT;
6524                         }
6525
6526                         /* There has to be a valid name (and it has to be different) */
6527
6528                         if ( !r->in.info->name.string )
6529                                 return NT_STATUS_INVALID_PARAMETER;
6530
6531                         /* If the name is the same just reply "ok".  Yes this
6532                            doesn't allow you to change the case of a group name. */
6533
6534                         if (strequal(r->in.info->name.string, info->acct_name)) {
6535                                 return NT_STATUS_OK;
6536                         }
6537
6538                         talloc_free(info->acct_name);
6539                         info->acct_name = talloc_strdup(info, r->in.info->name.string);
6540                         if (!info->acct_name) {
6541                                 return NT_STATUS_NO_MEMORY;
6542                         }
6543
6544                         /* make sure the name doesn't already exist as a user
6545                            or local group */
6546
6547                         group_name = talloc_asprintf(p->mem_ctx,
6548                                                      "%s\\%s",
6549                                                      lp_netbios_name(),
6550                                                      info->acct_name);
6551                         if (group_name == NULL) {
6552                                 return NT_STATUS_NO_MEMORY;
6553                         }
6554
6555                         status = can_create( p->mem_ctx, group_name );
6556                         talloc_free(group_name);
6557                         if ( !NT_STATUS_IS_OK( status ) )
6558                                 return status;
6559                         break;
6560                 }
6561                 case ALIASINFODESCRIPTION:
6562                         TALLOC_FREE(info->acct_desc);
6563                         if (r->in.info->description.string) {
6564                                 info->acct_desc = talloc_strdup(info,
6565                                                                 r->in.info->description.string);
6566                         } else {
6567                                 info->acct_desc = talloc_strdup(info, "");
6568                         }
6569                         if (!info->acct_desc) {
6570                                 return NT_STATUS_NO_MEMORY;
6571                         }
6572                         break;
6573                 default:
6574                         return NT_STATUS_INVALID_INFO_CLASS;
6575         }
6576
6577         /******** BEGIN SeAddUsers BLOCK *********/
6578
6579         become_root();
6580         status = pdb_set_aliasinfo(&ainfo->sid, info);
6581         unbecome_root();
6582
6583         /******** End SeAddUsers BLOCK *********/
6584
6585         if (NT_STATUS_IS_OK(status))
6586                 force_flush_samr_cache(&ainfo->sid);
6587
6588         return status;
6589 }
6590
6591 /****************************************************************
6592  _samr_GetDomPwInfo
6593 ****************************************************************/
6594
6595 NTSTATUS _samr_GetDomPwInfo(struct pipes_struct *p,
6596                             struct samr_GetDomPwInfo *r)
6597 {
6598         const struct loadparm_substitution *lp_sub =
6599                 loadparm_s3_global_substitution();
6600         uint32_t min_password_length = 0;
6601         uint32_t password_properties = 0;
6602
6603         /* Perform access check.  Since this rpc does not require a
6604            policy handle it will not be caught by the access checks on
6605            SAMR_CONNECT or SAMR_CONNECT_ANON. */
6606
6607         if (!pipe_access_check(p)) {
6608                 DEBUG(3, ("access denied to _samr_GetDomPwInfo\n"));
6609                 return NT_STATUS_ACCESS_DENIED;
6610         }
6611
6612         become_root();
6613         pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN,
6614                                &min_password_length);
6615         pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
6616                                &password_properties);
6617         unbecome_root();
6618
6619         if (lp_check_password_script(talloc_tos(), lp_sub) && *lp_check_password_script(talloc_tos(), lp_sub)) {
6620                 password_properties |= DOMAIN_PASSWORD_COMPLEX;
6621         }
6622
6623         r->out.info->min_password_length = min_password_length;
6624         r->out.info->password_properties = password_properties;
6625
6626         return NT_STATUS_OK;
6627 }
6628
6629 /*********************************************************************
6630  _samr_OpenGroup
6631 *********************************************************************/
6632
6633 NTSTATUS _samr_OpenGroup(struct pipes_struct *p,
6634                          struct samr_OpenGroup *r)
6635
6636 {
6637         struct dom_sid info_sid;
6638         struct dom_sid_buf buf;
6639         GROUP_MAP *map;
6640         struct samr_info *dinfo;
6641         struct security_descriptor         *psd = NULL;
6642         uint32_t            acc_granted;
6643         uint32_t            des_access = r->in.access_mask;
6644         size_t            sd_size;
6645         NTSTATUS          status;
6646         bool ret;
6647
6648         dinfo = samr_policy_handle_find(p,
6649                                         r->in.domain_handle,
6650                                         SAMR_HANDLE_DOMAIN,
6651                                         SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
6652                                         NULL,
6653                                         &status);
6654         if (!NT_STATUS_IS_OK(status)) {
6655                 return status;
6656         }
6657
6658         /*check if access can be granted as requested by client. */
6659         map_max_allowed_access(p->session_info->security_token,
6660                                p->session_info->unix_token,
6661                                &des_access);
6662
6663         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &grp_generic_mapping, NULL, 0);
6664         se_map_generic(&des_access,&grp_generic_mapping);
6665
6666         status = access_check_object(psd, p->session_info->security_token,
6667                                      SEC_PRIV_ADD_USERS, SEC_PRIV_INVALID, GENERIC_RIGHTS_GROUP_ALL_ACCESS,
6668                                      des_access, &acc_granted, "_samr_OpenGroup");
6669
6670         if ( !NT_STATUS_IS_OK(status) )
6671                 return status;
6672
6673         /* this should not be hard-coded like this */
6674
6675         if (!sid_check_is_our_sam(&dinfo->sid)) {
6676                 return NT_STATUS_ACCESS_DENIED;
6677         }
6678
6679         sid_compose(&info_sid, &dinfo->sid, r->in.rid);
6680
6681         DEBUG(10, ("_samr_OpenGroup:Opening SID: %s\n",
6682                    dom_sid_str_buf(&info_sid, &buf)));
6683
6684         map = talloc_zero(p->mem_ctx, GROUP_MAP);
6685         if (!map) {
6686                 return NT_STATUS_NO_MEMORY;
6687         }
6688
6689         /* check if that group really exists */
6690         become_root();
6691         ret = get_domain_group_from_sid(info_sid, map);
6692         unbecome_root();
6693         if (!ret)
6694                 return NT_STATUS_NO_SUCH_GROUP;
6695
6696         TALLOC_FREE(map);
6697
6698         status = create_samr_policy_handle(p->mem_ctx,
6699                                            p,
6700                                            SAMR_HANDLE_GROUP,
6701                                            acc_granted,
6702                                            &info_sid,
6703                                            NULL,
6704                                            r->out.group_handle);
6705         if (!NT_STATUS_IS_OK(status)) {
6706                 return status;
6707         }
6708
6709         return NT_STATUS_OK;
6710 }
6711
6712 /*********************************************************************
6713  _samr_RemoveMemberFromForeignDomain
6714 *********************************************************************/
6715
6716 NTSTATUS _samr_RemoveMemberFromForeignDomain(struct pipes_struct *p,
6717                                              struct samr_RemoveMemberFromForeignDomain *r)
6718 {
6719         struct samr_info *dinfo;
6720         struct dom_sid_buf buf;
6721         NTSTATUS                result;
6722
6723         DEBUG(5,("_samr_RemoveMemberFromForeignDomain: removing SID [%s]\n",
6724                  dom_sid_str_buf(r->in.sid, &buf)));
6725
6726         /* Find the policy handle. Open a policy on it. */
6727
6728         dinfo = samr_policy_handle_find(p,
6729                                         r->in.domain_handle,
6730                                         SAMR_HANDLE_DOMAIN,
6731                                         SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
6732                                         NULL,
6733                                         &result);
6734         if (!NT_STATUS_IS_OK(result)) {
6735                 return result;
6736         }
6737
6738         DEBUG(8, ("_samr_RemoveMemberFromForeignDomain: sid is %s\n",
6739                   dom_sid_str_buf(&dinfo->sid, &buf)));
6740
6741         /* we can only delete a user from a group since we don't have
6742            nested groups anyways.  So in the latter case, just say OK */
6743
6744         /* TODO: The above comment nowadays is bogus. Since we have nested
6745          * groups now, and aliases members are never reported out of the unix
6746          * group membership, the "just say OK" makes this call a no-op. For
6747          * us. This needs fixing however. */
6748
6749         /* I've only ever seen this in the wild when deleting a user from
6750          * usrmgr.exe. domain_sid is the builtin domain, and the sid to delete
6751          * is the user about to be deleted. I very much suspect this is the
6752          * only application of this call. To verify this, let people report
6753          * other cases. */
6754
6755         if (!sid_check_is_builtin(&dinfo->sid)) {
6756                 struct dom_sid_buf buf2;
6757                 DEBUG(1,("_samr_RemoveMemberFromForeignDomain: domain_sid = %s, "
6758                          "global_sam_sid() = %s\n",
6759                          dom_sid_str_buf(&dinfo->sid, &buf),
6760                          dom_sid_str_buf(get_global_sam_sid(), &buf2)));
6761                 DEBUGADD(1,("please report to samba-technical@lists.samba.org!\n"));
6762                 return NT_STATUS_OK;
6763         }
6764
6765         force_flush_samr_cache(&dinfo->sid);
6766
6767         result = NT_STATUS_OK;
6768
6769         return result;
6770 }
6771
6772 /*******************************************************************
6773  _samr_QueryDomainInfo2
6774  ********************************************************************/
6775
6776 NTSTATUS _samr_QueryDomainInfo2(struct pipes_struct *p,
6777                                 struct samr_QueryDomainInfo2 *r)
6778 {
6779         struct samr_QueryDomainInfo q;
6780
6781         q.in.domain_handle      = r->in.domain_handle;
6782         q.in.level              = r->in.level;
6783
6784         q.out.info              = r->out.info;
6785
6786         return _samr_QueryDomainInfo(p, &q);
6787 }
6788
6789 /*******************************************************************
6790  ********************************************************************/
6791
6792 static NTSTATUS set_dom_info_1(TALLOC_CTX *mem_ctx,
6793                                struct samr_DomInfo1 *r)
6794 {
6795         time_t u_expire, u_min_age;
6796
6797         u_expire = nt_time_to_unix_abs((NTTIME *)&r->max_password_age);
6798         u_min_age = nt_time_to_unix_abs((NTTIME *)&r->min_password_age);
6799
6800         pdb_set_account_policy(PDB_POLICY_MIN_PASSWORD_LEN,
6801                                (uint32_t)r->min_password_length);
6802         pdb_set_account_policy(PDB_POLICY_PASSWORD_HISTORY,
6803                                (uint32_t)r->password_history_length);
6804         pdb_set_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
6805                                (uint32_t)r->password_properties);
6806         pdb_set_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, (int)u_expire);
6807         pdb_set_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, (int)u_min_age);
6808
6809         return NT_STATUS_OK;
6810 }
6811
6812 /*******************************************************************
6813  ********************************************************************/
6814
6815 static NTSTATUS set_dom_info_3(TALLOC_CTX *mem_ctx,
6816                                struct samr_DomInfo3 *r)
6817 {
6818         time_t u_logout;
6819
6820         u_logout = nt_time_to_unix_abs((NTTIME *)&r->force_logoff_time);
6821
6822         pdb_set_account_policy(PDB_POLICY_TIME_TO_LOGOUT, (int)u_logout);
6823
6824         return NT_STATUS_OK;
6825 }
6826
6827 /*******************************************************************
6828  ********************************************************************/
6829
6830 static NTSTATUS set_dom_info_12(TALLOC_CTX *mem_ctx,
6831                                 struct samr_DomInfo12 *r)
6832 {
6833         time_t u_lock_duration, u_reset_time;
6834
6835         /*
6836          * It is not possible to set lockout_duration < lockout_window.
6837          * (The test is the other way around since the negative numbers
6838          *  are stored...)
6839          *
6840          * This constraint is documented here for the samr rpc service:
6841          * MS-SAMR 3.1.1.6 Attribute Constraints for Originating Updates
6842          * http://msdn.microsoft.com/en-us/library/cc245667%28PROT.10%29.aspx
6843          *
6844          * And here for the ldap backend:
6845          * MS-ADTS 3.1.1.5.3.2 Constraints
6846          * http://msdn.microsoft.com/en-us/library/cc223462(PROT.10).aspx
6847          */
6848         if (r->lockout_duration > r->lockout_window) {
6849                 return NT_STATUS_INVALID_PARAMETER;
6850         }
6851
6852         u_lock_duration = nt_time_to_unix_abs((NTTIME *)&r->lockout_duration);
6853         if (u_lock_duration != -1) {
6854                 u_lock_duration /= 60;
6855         }
6856
6857         u_reset_time = nt_time_to_unix_abs((NTTIME *)&r->lockout_window)/60;
6858
6859         pdb_set_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
6860         pdb_set_account_policy(PDB_POLICY_RESET_COUNT_TIME, (int)u_reset_time);
6861         pdb_set_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT,
6862                                (uint32_t)r->lockout_threshold);
6863
6864         return NT_STATUS_OK;
6865 }
6866
6867 /*******************************************************************
6868  _samr_SetDomainInfo
6869  ********************************************************************/
6870
6871 NTSTATUS _samr_SetDomainInfo(struct pipes_struct *p,
6872                              struct samr_SetDomainInfo *r)
6873 {
6874         NTSTATUS status;
6875         uint32_t acc_required = 0;
6876
6877         DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
6878
6879         switch (r->in.level) {
6880         case 1: /* DomainPasswordInformation */
6881         case 12: /* DomainLockoutInformation */
6882                 /* DOMAIN_WRITE_PASSWORD_PARAMETERS */
6883                 acc_required = SAMR_DOMAIN_ACCESS_SET_INFO_1;
6884                 break;
6885         case 3: /* DomainLogoffInformation */
6886         case 4: /* DomainOemInformation */
6887                 /* DOMAIN_WRITE_OTHER_PARAMETERS */
6888                 acc_required = SAMR_DOMAIN_ACCESS_SET_INFO_2;
6889                 break;
6890         case 6: /* DomainReplicationInformation */
6891         case 9: /* DomainStateInformation */
6892         case 7: /* DomainServerRoleInformation */
6893                 /* DOMAIN_ADMINISTER_SERVER */
6894                 acc_required = SAMR_DOMAIN_ACCESS_SET_INFO_3;
6895                 break;
6896         default:
6897                 return NT_STATUS_INVALID_INFO_CLASS;
6898         }
6899
6900         (void)samr_policy_handle_find(p,
6901                                       r->in.domain_handle,
6902                                       SAMR_HANDLE_DOMAIN,
6903                                       acc_required,
6904                                       NULL,
6905                                       &status);
6906         if (!NT_STATUS_IS_OK(status)) {
6907                 return status;
6908         }
6909
6910         DEBUG(5,("_samr_SetDomainInfo: level: %d\n", r->in.level));
6911
6912         switch (r->in.level) {
6913                 case 1:
6914                         status = set_dom_info_1(p->mem_ctx, &r->in.info->info1);
6915                         break;
6916                 case 3:
6917                         status = set_dom_info_3(p->mem_ctx, &r->in.info->info3);
6918                         break;
6919                 case 4:
6920                         break;
6921                 case 6:
6922                         break;
6923                 case 7:
6924                         break;
6925                 case 9:
6926                         break;
6927                 case 12:
6928                         status = set_dom_info_12(p->mem_ctx, &r->in.info->info12);
6929                         break;
6930                 default:
6931                         return NT_STATUS_INVALID_INFO_CLASS;
6932         }
6933
6934         if (!NT_STATUS_IS_OK(status)) {
6935                 return status;
6936         }
6937
6938         DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
6939
6940         return NT_STATUS_OK;
6941 }
6942
6943 /****************************************************************
6944  _samr_GetDisplayEnumerationIndex
6945 ****************************************************************/
6946
6947 NTSTATUS _samr_GetDisplayEnumerationIndex(struct pipes_struct *p,
6948                                           struct samr_GetDisplayEnumerationIndex *r)
6949 {
6950         struct samr_info *dinfo;
6951         uint32_t max_entries = (uint32_t) -1;
6952         uint32_t enum_context = 0;
6953         uint32_t i, num_account = 0;
6954         struct samr_displayentry *entries = NULL;
6955         NTSTATUS status;
6956
6957         DEBUG(5,("_samr_GetDisplayEnumerationIndex: %d\n", __LINE__));
6958
6959         dinfo = samr_policy_handle_find(p,
6960                                         r->in.domain_handle,
6961                                         SAMR_HANDLE_DOMAIN,
6962                                         SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
6963                                         NULL,
6964                                         &status);
6965         if (!NT_STATUS_IS_OK(status)) {
6966                 return status;
6967         }
6968
6969         if ((r->in.level < 1) || (r->in.level > 3)) {
6970                 DEBUG(0,("_samr_GetDisplayEnumerationIndex: "
6971                         "Unknown info level (%u)\n",
6972                         r->in.level));
6973                 return NT_STATUS_INVALID_INFO_CLASS;
6974         }
6975
6976         become_root();
6977
6978         /* The following done as ROOT. Don't return without unbecome_root(). */
6979
6980         switch (r->in.level) {
6981         case 1:
6982                 if (dinfo->disp_info->users == NULL) {
6983                         dinfo->disp_info->users = pdb_search_users(
6984                                 dinfo->disp_info, ACB_NORMAL);
6985                         if (dinfo->disp_info->users == NULL) {
6986                                 unbecome_root();
6987                                 return NT_STATUS_ACCESS_DENIED;
6988                         }
6989                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6990                                 "starting user enumeration at index %u\n",
6991                                 (unsigned int)enum_context));
6992                 } else {
6993                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6994                                 "using cached user enumeration at index %u\n",
6995                                 (unsigned int)enum_context));
6996                 }
6997                 num_account = pdb_search_entries(dinfo->disp_info->users,
6998                                                  enum_context, max_entries,
6999                                                  &entries);
7000                 break;
7001         case 2:
7002                 if (dinfo->disp_info->machines == NULL) {
7003                         dinfo->disp_info->machines = pdb_search_users(
7004                                 dinfo->disp_info, ACB_WSTRUST|ACB_SVRTRUST);
7005                         if (dinfo->disp_info->machines == NULL) {
7006                                 unbecome_root();
7007                                 return NT_STATUS_ACCESS_DENIED;
7008                         }
7009                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
7010                                 "starting machine enumeration at index %u\n",
7011                                 (unsigned int)enum_context));
7012                 } else {
7013                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
7014                                 "using cached machine enumeration at index %u\n",
7015                                 (unsigned int)enum_context));
7016                 }
7017                 num_account = pdb_search_entries(dinfo->disp_info->machines,
7018                                                  enum_context, max_entries,
7019                                                  &entries);
7020                 break;
7021         case 3:
7022                 if (dinfo->disp_info->groups == NULL) {
7023                         dinfo->disp_info->groups = pdb_search_groups(
7024                                 dinfo->disp_info);
7025                         if (dinfo->disp_info->groups == NULL) {
7026                                 unbecome_root();
7027                                 return NT_STATUS_ACCESS_DENIED;
7028                         }
7029                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
7030                                 "starting group enumeration at index %u\n",
7031                                 (unsigned int)enum_context));
7032                 } else {
7033                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
7034                                 "using cached group enumeration at index %u\n",
7035                                 (unsigned int)enum_context));
7036                 }
7037                 num_account = pdb_search_entries(dinfo->disp_info->groups,
7038                                                  enum_context, max_entries,
7039                                                  &entries);
7040                 break;
7041         default:
7042                 unbecome_root();
7043                 smb_panic("info class changed");
7044                 break;
7045         }
7046
7047         unbecome_root();
7048
7049         /* Ensure we cache this enumeration. */
7050         set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
7051
7052         DEBUG(10,("_samr_GetDisplayEnumerationIndex: looking for :%s\n",
7053                 r->in.name->string));
7054
7055         for (i=0; i<num_account; i++) {
7056                 if (strequal(entries[i].account_name, r->in.name->string)) {
7057                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
7058                                 "found %s at idx %d\n",
7059                                 r->in.name->string, i));
7060                         *r->out.idx = i;
7061                         return NT_STATUS_OK;
7062                 }
7063         }
7064
7065         /* assuming account_name lives at the very end */
7066         *r->out.idx = num_account;
7067
7068         return NT_STATUS_NO_MORE_ENTRIES;
7069 }
7070
7071 /****************************************************************
7072  _samr_GetDisplayEnumerationIndex2
7073 ****************************************************************/
7074
7075 NTSTATUS _samr_GetDisplayEnumerationIndex2(struct pipes_struct *p,
7076                                            struct samr_GetDisplayEnumerationIndex2 *r)
7077 {
7078         struct samr_GetDisplayEnumerationIndex q;
7079
7080         q.in.domain_handle      = r->in.domain_handle;
7081         q.in.level              = r->in.level;
7082         q.in.name               = r->in.name;
7083
7084         q.out.idx               = r->out.idx;
7085
7086         return _samr_GetDisplayEnumerationIndex(p, &q);
7087 }
7088
7089 /****************************************************************
7090  _samr_RidToSid
7091 ****************************************************************/
7092
7093 NTSTATUS _samr_RidToSid(struct pipes_struct *p,
7094                         struct samr_RidToSid *r)
7095 {
7096         struct samr_info *dinfo;
7097         NTSTATUS status;
7098         struct dom_sid sid;
7099
7100         dinfo = samr_policy_handle_find(p,
7101                                         r->in.domain_handle,
7102                                         SAMR_HANDLE_DOMAIN,
7103                                         0,
7104                                         NULL,
7105                                         &status);
7106         if (!NT_STATUS_IS_OK(status)) {
7107                 return status;
7108         }
7109
7110         if (!sid_compose(&sid, &dinfo->sid, r->in.rid)) {
7111                 return NT_STATUS_NO_MEMORY;
7112         }
7113
7114         *r->out.sid = dom_sid_dup(p->mem_ctx, &sid);
7115         if (!*r->out.sid) {
7116                 return NT_STATUS_NO_MEMORY;
7117         }
7118
7119         return NT_STATUS_OK;
7120 }
7121
7122 /****************************************************************
7123 ****************************************************************/
7124
7125 static enum samr_ValidationStatus samr_ValidatePassword_Change(TALLOC_CTX *mem_ctx,
7126                                                                const struct samr_PwInfo *dom_pw_info,
7127                                                                const struct samr_ValidatePasswordReq2 *req,
7128                                                                struct samr_ValidatePasswordRepCtr *rep)
7129 {
7130         NTSTATUS status;
7131
7132         if (req->password.string == NULL) {
7133                 return SAMR_VALIDATION_STATUS_SUCCESS;
7134         }
7135         if (strlen(req->password.string) < dom_pw_info->min_password_length) {
7136                 ZERO_STRUCT(rep->info);
7137                 return SAMR_VALIDATION_STATUS_PWD_TOO_SHORT;
7138         }
7139         if (dom_pw_info->password_properties & DOMAIN_PASSWORD_COMPLEX) {
7140                 status = check_password_complexity(req->account.string,
7141                                                    NULL, /* full_name */
7142                                                    req->password.string,
7143                                                    NULL);
7144                 if (!NT_STATUS_IS_OK(status)) {
7145                         ZERO_STRUCT(rep->info);
7146                         return SAMR_VALIDATION_STATUS_NOT_COMPLEX_ENOUGH;
7147                 }
7148         }
7149
7150         return SAMR_VALIDATION_STATUS_SUCCESS;
7151 }
7152
7153 /****************************************************************
7154 ****************************************************************/
7155
7156 static enum samr_ValidationStatus samr_ValidatePassword_Reset(TALLOC_CTX *mem_ctx,
7157                                                               const struct samr_PwInfo *dom_pw_info,
7158                                                               const struct samr_ValidatePasswordReq3 *req,
7159                                                               struct samr_ValidatePasswordRepCtr *rep)
7160 {
7161         NTSTATUS status;
7162
7163         if (req->password.string == NULL) {
7164                 return SAMR_VALIDATION_STATUS_SUCCESS;
7165         }
7166         if (strlen(req->password.string) < dom_pw_info->min_password_length) {
7167                 ZERO_STRUCT(rep->info);
7168                 return SAMR_VALIDATION_STATUS_PWD_TOO_SHORT;
7169         }
7170         if (dom_pw_info->password_properties & DOMAIN_PASSWORD_COMPLEX) {
7171                 status = check_password_complexity(req->account.string,
7172                                                    NULL, /* full_name */
7173                                                    req->password.string,
7174                                                    NULL);
7175                 if (!NT_STATUS_IS_OK(status)) {
7176                         ZERO_STRUCT(rep->info);
7177                         return SAMR_VALIDATION_STATUS_NOT_COMPLEX_ENOUGH;
7178                 }
7179         }
7180
7181         return SAMR_VALIDATION_STATUS_SUCCESS;
7182 }
7183
7184 /****************************************************************
7185  _samr_ValidatePassword
7186 ****************************************************************/
7187
7188 NTSTATUS _samr_ValidatePassword(struct pipes_struct *p,
7189                                 struct samr_ValidatePassword *r)
7190 {
7191         union samr_ValidatePasswordRep *rep;
7192         NTSTATUS status;
7193         struct samr_GetDomPwInfo pw;
7194         struct samr_PwInfo dom_pw_info;
7195
7196         if (p->transport != NCACN_IP_TCP && p->transport != NCALRPC) {
7197                 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
7198                 return NT_STATUS_ACCESS_DENIED;
7199         }
7200
7201         if (p->auth.auth_level != DCERPC_AUTH_LEVEL_PRIVACY) {
7202                 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
7203                 return NT_STATUS_ACCESS_DENIED;
7204         }
7205
7206         if (r->in.level < 1 || r->in.level > 3) {
7207                 return NT_STATUS_INVALID_INFO_CLASS;
7208         }
7209
7210         pw.in.domain_name = NULL;
7211         pw.out.info = &dom_pw_info;
7212
7213         status = _samr_GetDomPwInfo(p, &pw);
7214         if (!NT_STATUS_IS_OK(status)) {
7215                 return status;
7216         }
7217
7218         rep = talloc_zero(p->mem_ctx, union samr_ValidatePasswordRep);
7219         if (!rep) {
7220                 return NT_STATUS_NO_MEMORY;
7221         }
7222
7223         switch (r->in.level) {
7224         case 1:
7225                 status = NT_STATUS_NOT_SUPPORTED;
7226                 break;
7227         case 2:
7228                 rep->ctr2.status = samr_ValidatePassword_Change(p->mem_ctx,
7229                                                                 &dom_pw_info,
7230                                                                 &r->in.req->req2,
7231                                                                 &rep->ctr2);
7232                 break;
7233         case 3:
7234                 rep->ctr3.status = samr_ValidatePassword_Reset(p->mem_ctx,
7235                                                                &dom_pw_info,
7236                                                                &r->in.req->req3,
7237                                                                &rep->ctr3);
7238                 break;
7239         default:
7240                 status = NT_STATUS_INVALID_INFO_CLASS;
7241                 break;
7242         }
7243
7244         if (!NT_STATUS_IS_OK(status)) {
7245                 talloc_free(rep);
7246                 return status;
7247         }
7248
7249         *r->out.rep = rep;
7250
7251         return NT_STATUS_OK;
7252 }
7253
7254 /****************************************************************
7255 ****************************************************************/
7256
7257 NTSTATUS _samr_Shutdown(struct pipes_struct *p,
7258                         struct samr_Shutdown *r)
7259 {
7260         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
7261         return NT_STATUS_NOT_IMPLEMENTED;
7262 }
7263
7264 /****************************************************************
7265 ****************************************************************/
7266
7267 NTSTATUS _samr_SetMemberAttributesOfGroup(struct pipes_struct *p,
7268                                           struct samr_SetMemberAttributesOfGroup *r)
7269 {
7270         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
7271         return NT_STATUS_NOT_IMPLEMENTED;
7272 }
7273
7274 /****************************************************************
7275 ****************************************************************/
7276
7277 NTSTATUS _samr_TestPrivateFunctionsDomain(struct pipes_struct *p,
7278                                           struct samr_TestPrivateFunctionsDomain *r)
7279 {
7280         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
7281         return NT_STATUS_NOT_IMPLEMENTED;
7282 }
7283
7284 /****************************************************************
7285 ****************************************************************/
7286
7287 NTSTATUS _samr_TestPrivateFunctionsUser(struct pipes_struct *p,
7288                                         struct samr_TestPrivateFunctionsUser *r)
7289 {
7290         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
7291         return NT_STATUS_NOT_IMPLEMENTED;
7292 }
7293
7294 /****************************************************************
7295 ****************************************************************/
7296
7297 NTSTATUS _samr_AddMultipleMembersToAlias(struct pipes_struct *p,
7298                                          struct samr_AddMultipleMembersToAlias *r)
7299 {
7300         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
7301         return NT_STATUS_NOT_IMPLEMENTED;
7302 }
7303
7304 /****************************************************************
7305 ****************************************************************/
7306
7307 NTSTATUS _samr_RemoveMultipleMembersFromAlias(struct pipes_struct *p,
7308                                               struct samr_RemoveMultipleMembersFromAlias *r)
7309 {
7310         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
7311         return NT_STATUS_NOT_IMPLEMENTED;
7312 }
7313
7314 /****************************************************************
7315 ****************************************************************/
7316
7317 NTSTATUS _samr_SetBootKeyInformation(struct pipes_struct *p,
7318                                      struct samr_SetBootKeyInformation *r)
7319 {
7320         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
7321         return NT_STATUS_NOT_IMPLEMENTED;
7322 }
7323
7324 /****************************************************************
7325 ****************************************************************/
7326
7327 NTSTATUS _samr_GetBootKeyInformation(struct pipes_struct *p,
7328                                      struct samr_GetBootKeyInformation *r)
7329 {
7330         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
7331         return NT_STATUS_NOT_IMPLEMENTED;
7332 }
7333
7334 /****************************************************************
7335 ****************************************************************/
7336
7337 NTSTATUS _samr_SetDsrmPassword(struct pipes_struct *p,
7338                                struct samr_SetDsrmPassword *r)
7339 {
7340         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
7341         return NT_STATUS_NOT_IMPLEMENTED;
7342 }
7343
7344 /* include the generated boilerplate */
7345 #include "librpc/gen_ndr/ndr_samr_scompat.c"