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