s3-samr: fix _samr_QueryGroupMember().
[samba.git] / source3 / rpc_server / srv_samr_nt.c
1 /*
2  *  Unix SMB/CIFS implementation.
3  *  RPC Pipe client / server routines
4  *  Copyright (C) Andrew Tridgell                   1992-1997,
5  *  Copyright (C) Luke Kenneth Casson Leighton      1996-1997,
6  *  Copyright (C) Paul Ashton                       1997,
7  *  Copyright (C) Marc Jacobsen                     1999,
8  *  Copyright (C) Jeremy Allison                    2001-2008,
9  *  Copyright (C) Jean François Micouleau           1998-2001,
10  *  Copyright (C) Jim McDonough <jmcd@us.ibm.com>   2002,
11  *  Copyright (C) Gerald (Jerry) Carter             2003-2004,
12  *  Copyright (C) Simo Sorce                        2003.
13  *  Copyright (C) Volker Lendecke                   2005.
14  *  Copyright (C) Guenther Deschner                 2008.
15  *
16  *  This program is free software; you can redistribute it and/or modify
17  *  it under the terms of the GNU General Public License as published by
18  *  the Free Software Foundation; either version 3 of the License, or
19  *  (at your option) any later version.
20  *
21  *  This program is distributed in the hope that it will be useful,
22  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
23  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24  *  GNU General Public License for more details.
25  *
26  *  You should have received a copy of the GNU General Public License
27  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
28  */
29
30 /*
31  * This is the implementation of the SAMR code.
32  */
33
34 #include "includes.h"
35 #include "smbd/globals.h"
36 #include "../libcli/auth/libcli_auth.h"
37 #include "../librpc/gen_ndr/srv_samr.h"
38 #include "rpc_server/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/dom_sid.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 (is_sid_in_token(nt_token, &global_sid_Builtin_Administrators) ||
273                         is_sid_in_token(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 (is_sid_in_token(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->ptok,
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->ptok, 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->ptok,
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         fstring user_name;
1937         fstring wks;
1938
1939         DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1940
1941         fstrcpy(user_name, r->in.account->string);
1942         fstrcpy(wks, r->in.server->string);
1943
1944         DEBUG(5,("_samr_ChangePasswordUser2: user: %s wks: %s\n", user_name, wks));
1945
1946         /*
1947          * Pass the user through the NT -> unix user mapping
1948          * function.
1949          */
1950
1951         (void)map_username(user_name);
1952
1953         /*
1954          * UNIX username case mangling not required, pass_oem_change
1955          * is case insensitive.
1956          */
1957
1958         status = pass_oem_change(user_name,
1959                                  p->client_id->name,
1960                                  r->in.lm_password->data,
1961                                  r->in.lm_verifier->hash,
1962                                  r->in.nt_password->data,
1963                                  r->in.nt_verifier->hash,
1964                                  NULL);
1965
1966         DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1967
1968         if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
1969                 return NT_STATUS_WRONG_PASSWORD;
1970         }
1971
1972         return status;
1973 }
1974
1975 /****************************************************************
1976  _samr_OemChangePasswordUser2
1977 ****************************************************************/
1978
1979 NTSTATUS _samr_OemChangePasswordUser2(struct pipes_struct *p,
1980                                       struct samr_OemChangePasswordUser2 *r)
1981 {
1982         NTSTATUS status;
1983         fstring user_name;
1984         const char *wks = NULL;
1985
1986         DEBUG(5,("_samr_OemChangePasswordUser2: %d\n", __LINE__));
1987
1988         fstrcpy(user_name, r->in.account->string);
1989         if (r->in.server && r->in.server->string) {
1990                 wks = r->in.server->string;
1991         }
1992
1993         DEBUG(5,("_samr_OemChangePasswordUser2: user: %s wks: %s\n", user_name, wks));
1994
1995         /*
1996          * Pass the user through the NT -> unix user mapping
1997          * function.
1998          */
1999
2000         (void)map_username(user_name);
2001
2002         /*
2003          * UNIX username case mangling not required, pass_oem_change
2004          * is case insensitive.
2005          */
2006
2007         if (!r->in.hash || !r->in.password) {
2008                 return NT_STATUS_INVALID_PARAMETER;
2009         }
2010
2011         status = pass_oem_change(user_name,
2012                                  p->client_id->name,
2013                                  r->in.password->data,
2014                                  r->in.hash->hash,
2015                                  0,
2016                                  0,
2017                                  NULL);
2018
2019         if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
2020                 return NT_STATUS_WRONG_PASSWORD;
2021         }
2022
2023         DEBUG(5,("_samr_OemChangePasswordUser2: %d\n", __LINE__));
2024
2025         return status;
2026 }
2027
2028 /*******************************************************************
2029  _samr_ChangePasswordUser3
2030  ********************************************************************/
2031
2032 NTSTATUS _samr_ChangePasswordUser3(struct pipes_struct *p,
2033                                    struct samr_ChangePasswordUser3 *r)
2034 {
2035         NTSTATUS status;
2036         fstring user_name;
2037         const char *wks = NULL;
2038         enum samPwdChangeReason reject_reason;
2039         struct samr_DomInfo1 *dominfo = NULL;
2040         struct userPwdChangeFailureInformation *reject = NULL;
2041         uint32_t tmp;
2042
2043         DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
2044
2045         fstrcpy(user_name, r->in.account->string);
2046         if (r->in.server && r->in.server->string) {
2047                 wks = r->in.server->string;
2048         }
2049
2050         DEBUG(5,("_samr_ChangePasswordUser3: user: %s wks: %s\n", user_name, wks));
2051
2052         /*
2053          * Pass the user through the NT -> unix user mapping
2054          * function.
2055          */
2056
2057         (void)map_username(user_name);
2058
2059         /*
2060          * UNIX username case mangling not required, pass_oem_change
2061          * is case insensitive.
2062          */
2063
2064         status = pass_oem_change(user_name,
2065                                  p->client_id->name,
2066                                  r->in.lm_password->data,
2067                                  r->in.lm_verifier->hash,
2068                                  r->in.nt_password->data,
2069                                  r->in.nt_verifier->hash,
2070                                  &reject_reason);
2071         if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
2072                 return NT_STATUS_WRONG_PASSWORD;
2073         }
2074
2075         if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) ||
2076             NT_STATUS_EQUAL(status, NT_STATUS_ACCOUNT_RESTRICTION)) {
2077
2078                 time_t u_expire, u_min_age;
2079                 uint32 account_policy_temp;
2080
2081                 dominfo = TALLOC_ZERO_P(p->mem_ctx, struct samr_DomInfo1);
2082                 if (!dominfo) {
2083                         return NT_STATUS_NO_MEMORY;
2084                 }
2085
2086                 reject = TALLOC_ZERO_P(p->mem_ctx,
2087                                 struct userPwdChangeFailureInformation);
2088                 if (!reject) {
2089                         return NT_STATUS_NO_MEMORY;
2090                 }
2091
2092                 become_root();
2093
2094                 /* AS ROOT !!! */
2095
2096                 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN, &tmp);
2097                 dominfo->min_password_length = tmp;
2098
2099                 pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &tmp);
2100                 dominfo->password_history_length = tmp;
2101
2102                 pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
2103                                        &dominfo->password_properties);
2104
2105                 pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, &account_policy_temp);
2106                 u_expire = account_policy_temp;
2107
2108                 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, &account_policy_temp);
2109                 u_min_age = account_policy_temp;
2110
2111                 /* !AS ROOT */
2112
2113                 unbecome_root();
2114
2115                 unix_to_nt_time_abs((NTTIME *)&dominfo->max_password_age, u_expire);
2116                 unix_to_nt_time_abs((NTTIME *)&dominfo->min_password_age, u_min_age);
2117
2118                 if (lp_check_password_script() && *lp_check_password_script()) {
2119                         dominfo->password_properties |= DOMAIN_PASSWORD_COMPLEX;
2120                 }
2121
2122                 reject->extendedFailureReason = reject_reason;
2123
2124                 *r->out.dominfo = dominfo;
2125                 *r->out.reject = reject;
2126         }
2127
2128         DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
2129
2130         return status;
2131 }
2132
2133 /*******************************************************************
2134 makes a SAMR_R_LOOKUP_RIDS structure.
2135 ********************************************************************/
2136
2137 static bool make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names,
2138                                   const char **names,
2139                                   struct lsa_String **lsa_name_array_p)
2140 {
2141         struct lsa_String *lsa_name_array = NULL;
2142         uint32_t i;
2143
2144         *lsa_name_array_p = NULL;
2145
2146         if (num_names != 0) {
2147                 lsa_name_array = TALLOC_ZERO_ARRAY(ctx, struct lsa_String, num_names);
2148                 if (!lsa_name_array) {
2149                         return false;
2150                 }
2151         }
2152
2153         for (i = 0; i < num_names; i++) {
2154                 DEBUG(10, ("names[%d]:%s\n", i, names[i] && *names[i] ? names[i] : ""));
2155                 init_lsa_String(&lsa_name_array[i], names[i]);
2156         }
2157
2158         *lsa_name_array_p = lsa_name_array;
2159
2160         return true;
2161 }
2162
2163 /*******************************************************************
2164  _samr_LookupRids
2165  ********************************************************************/
2166
2167 NTSTATUS _samr_LookupRids(struct pipes_struct *p,
2168                           struct samr_LookupRids *r)
2169 {
2170         struct samr_domain_info *dinfo;
2171         NTSTATUS status;
2172         const char **names;
2173         enum lsa_SidType *attrs = NULL;
2174         uint32 *wire_attrs = NULL;
2175         int num_rids = (int)r->in.num_rids;
2176         int i;
2177         struct lsa_Strings names_array;
2178         struct samr_Ids types_array;
2179         struct lsa_String *lsa_names = NULL;
2180
2181         DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2182
2183         dinfo = policy_handle_find(p, r->in.domain_handle,
2184                                    0 /* Don't know the acc_bits yet */, NULL,
2185                                    struct samr_domain_info, &status);
2186         if (!NT_STATUS_IS_OK(status)) {
2187                 return status;
2188         }
2189
2190         if (num_rids > 1000) {
2191                 DEBUG(0, ("Got asked for %d rids (more than 1000) -- according "
2192                           "to samba4 idl this is not possible\n", num_rids));
2193                 return NT_STATUS_UNSUCCESSFUL;
2194         }
2195
2196         if (num_rids) {
2197                 names = TALLOC_ZERO_ARRAY(p->mem_ctx, const char *, num_rids);
2198                 attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, enum lsa_SidType, num_rids);
2199                 wire_attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_rids);
2200
2201                 if ((names == NULL) || (attrs == NULL) || (wire_attrs==NULL))
2202                         return NT_STATUS_NO_MEMORY;
2203         } else {
2204                 names = NULL;
2205                 attrs = NULL;
2206                 wire_attrs = NULL;
2207         }
2208
2209         become_root();  /* lookup_sid can require root privs */
2210         status = pdb_lookup_rids(&dinfo->sid, num_rids, r->in.rids,
2211                                  names, attrs);
2212         unbecome_root();
2213
2214         if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED) && (num_rids == 0)) {
2215                 status = NT_STATUS_OK;
2216         }
2217
2218         if (!make_samr_lookup_rids(p->mem_ctx, num_rids, names,
2219                                    &lsa_names)) {
2220                 return NT_STATUS_NO_MEMORY;
2221         }
2222
2223         /* Convert from enum lsa_SidType to uint32 for wire format. */
2224         for (i = 0; i < num_rids; i++) {
2225                 wire_attrs[i] = (uint32)attrs[i];
2226         }
2227
2228         names_array.count = num_rids;
2229         names_array.names = lsa_names;
2230
2231         types_array.count = num_rids;
2232         types_array.ids = wire_attrs;
2233
2234         *r->out.names = names_array;
2235         *r->out.types = types_array;
2236
2237         DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2238
2239         return status;
2240 }
2241
2242 /*******************************************************************
2243  _samr_OpenUser
2244 ********************************************************************/
2245
2246 NTSTATUS _samr_OpenUser(struct pipes_struct *p,
2247                         struct samr_OpenUser *r)
2248 {
2249         struct samu *sampass=NULL;
2250         struct dom_sid sid;
2251         struct samr_domain_info *dinfo;
2252         struct samr_user_info *uinfo;
2253         struct security_descriptor *psd = NULL;
2254         uint32    acc_granted;
2255         uint32    des_access = r->in.access_mask;
2256         uint32_t extra_access = 0;
2257         size_t    sd_size;
2258         bool ret;
2259         NTSTATUS nt_status;
2260
2261         /* These two privileges, if != SEC_PRIV_INVALID, indicate
2262          * privileges that the user must have to complete this
2263          * operation in defience of the fixed ACL */
2264         enum sec_privilege needed_priv_1, needed_priv_2;
2265         NTSTATUS status;
2266
2267         dinfo = policy_handle_find(p, r->in.domain_handle,
2268                                    SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
2269                                    struct samr_domain_info, &status);
2270         if (!NT_STATUS_IS_OK(status)) {
2271                 return status;
2272         }
2273
2274         if ( !(sampass = samu_new( p->mem_ctx )) ) {
2275                 return NT_STATUS_NO_MEMORY;
2276         }
2277
2278         /* append the user's RID to it */
2279
2280         if (!sid_compose(&sid, &dinfo->sid, r->in.rid))
2281                 return NT_STATUS_NO_SUCH_USER;
2282
2283         /* check if access can be granted as requested by client. */
2284         map_max_allowed_access(p->server_info->ptok,
2285                                &p->server_info->utok,
2286                                &des_access);
2287
2288         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &sid, SAMR_USR_RIGHTS_WRITE_PW);
2289         se_map_generic(&des_access, &usr_generic_mapping);
2290
2291         /*
2292          * Get the sampass first as we need to check privileges
2293          * based on what kind of user object this is.
2294          * But don't reveal info too early if it didn't exist.
2295          */
2296
2297         become_root();
2298         ret=pdb_getsampwsid(sampass, &sid);
2299         unbecome_root();
2300
2301         needed_priv_1 = SEC_PRIV_INVALID;
2302         needed_priv_2 = SEC_PRIV_INVALID;
2303         /*
2304          * We do the override access checks on *open*, not at
2305          * SetUserInfo time.
2306          */
2307         if (ret) {
2308                 uint32_t acb_info = pdb_get_acct_ctrl(sampass);
2309
2310                 if (acb_info & ACB_WSTRUST) {
2311                         /*
2312                          * SeMachineAccount is needed to add
2313                          * GENERIC_RIGHTS_USER_WRITE to a machine
2314                          * account.
2315                          */
2316                         needed_priv_1 = SEC_PRIV_MACHINE_ACCOUNT;
2317                 }
2318                 if (acb_info & ACB_NORMAL) {
2319                         /*
2320                          * SeAddUsers is needed to add
2321                          * GENERIC_RIGHTS_USER_WRITE to a normal
2322                          * account.
2323                          */
2324                         needed_priv_1 = SEC_PRIV_ADD_USERS;
2325                 }
2326                 /*
2327                  * Cheat - we have not set a specific privilege for
2328                  * server (BDC) or domain trust account, so allow
2329                  * GENERIC_RIGHTS_USER_WRITE if pipe user is in
2330                  * DOMAIN_RID_ADMINS.
2331                  */
2332                 if (acb_info & (ACB_SVRTRUST|ACB_DOMTRUST)) {
2333                         if (lp_enable_privileges() && nt_token_check_domain_rid(p->server_info->ptok,
2334                                                         DOMAIN_RID_ADMINS)) {
2335                                 des_access &= ~GENERIC_RIGHTS_USER_WRITE;
2336                                 extra_access = GENERIC_RIGHTS_USER_WRITE;
2337                                 DEBUG(4,("_samr_OpenUser: Allowing "
2338                                         "GENERIC_RIGHTS_USER_WRITE for "
2339                                         "rid admins\n"));
2340                         }
2341                 }
2342         }
2343
2344         TALLOC_FREE(sampass);
2345
2346         nt_status = access_check_object(psd, p->server_info->ptok,
2347                                         needed_priv_1, needed_priv_2,
2348                                         GENERIC_RIGHTS_USER_WRITE, des_access,
2349                                         &acc_granted, "_samr_OpenUser");
2350
2351         if ( !NT_STATUS_IS_OK(nt_status) )
2352                 return nt_status;
2353
2354         /* check that the SID exists in our domain. */
2355         if (ret == False) {
2356                 return NT_STATUS_NO_SUCH_USER;
2357         }
2358
2359         /* If we did the rid admins hack above, allow access. */
2360         acc_granted |= extra_access;
2361
2362         uinfo = policy_handle_create(p, r->out.user_handle, acc_granted,
2363                                      struct samr_user_info, &nt_status);
2364         if (!NT_STATUS_IS_OK(nt_status)) {
2365                 return nt_status;
2366         }
2367         uinfo->sid = sid;
2368
2369         return NT_STATUS_OK;
2370 }
2371
2372 /*************************************************************************
2373  *************************************************************************/
2374
2375 static NTSTATUS init_samr_parameters_string(TALLOC_CTX *mem_ctx,
2376                                             DATA_BLOB *blob,
2377                                             struct lsa_BinaryString **_r)
2378 {
2379         struct lsa_BinaryString *r;
2380
2381         if (!blob || !_r) {
2382                 return NT_STATUS_INVALID_PARAMETER;
2383         }
2384
2385         r = TALLOC_ZERO_P(mem_ctx, struct lsa_BinaryString);
2386         if (!r) {
2387                 return NT_STATUS_NO_MEMORY;
2388         }
2389
2390         r->array = TALLOC_ZERO_ARRAY(mem_ctx, uint16_t, blob->length/2);
2391         if (!r->array) {
2392                 return NT_STATUS_NO_MEMORY;
2393         }
2394         memcpy(r->array, blob->data, blob->length);
2395         r->size = blob->length;
2396         r->length = blob->length;
2397
2398         if (!r->array) {
2399                 return NT_STATUS_NO_MEMORY;
2400         }
2401
2402         *_r = r;
2403
2404         return NT_STATUS_OK;
2405 }
2406
2407 /*************************************************************************
2408  *************************************************************************/
2409
2410 static struct samr_LogonHours get_logon_hours_from_pdb(TALLOC_CTX *mem_ctx,
2411                                                        struct samu *pw)
2412 {
2413         struct samr_LogonHours hours;
2414         const int units_per_week = 168;
2415
2416         ZERO_STRUCT(hours);
2417         hours.bits = talloc_array(mem_ctx, uint8_t, units_per_week);
2418         if (!hours.bits) {
2419                 return hours;
2420         }
2421
2422         hours.units_per_week = units_per_week;
2423         memset(hours.bits, 0xFF, units_per_week);
2424
2425         if (pdb_get_hours(pw)) {
2426                 memcpy(hours.bits, pdb_get_hours(pw),
2427                        MIN(pdb_get_hours_len(pw), units_per_week));
2428         }
2429
2430         return hours;
2431 }
2432
2433 /*************************************************************************
2434  get_user_info_1.
2435  *************************************************************************/
2436
2437 static NTSTATUS get_user_info_1(TALLOC_CTX *mem_ctx,
2438                                 struct samr_UserInfo1 *r,
2439                                 struct samu *pw,
2440                                 struct dom_sid *domain_sid)
2441 {
2442         const struct dom_sid *sid_group;
2443         uint32_t primary_gid;
2444
2445         become_root();
2446         sid_group = pdb_get_group_sid(pw);
2447         unbecome_root();
2448
2449         if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2450                 DEBUG(0, ("get_user_info_1: User %s has Primary Group SID %s, \n"
2451                           "which conflicts with the domain sid %s.  Failing operation.\n",
2452                           pdb_get_username(pw), sid_string_dbg(sid_group),
2453                           sid_string_dbg(domain_sid)));
2454                 return NT_STATUS_UNSUCCESSFUL;
2455         }
2456
2457         r->account_name.string          = talloc_strdup(mem_ctx, pdb_get_username(pw));
2458         r->full_name.string             = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2459         r->primary_gid                  = primary_gid;
2460         r->description.string           = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2461         r->comment.string               = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2462
2463         return NT_STATUS_OK;
2464 }
2465
2466 /*************************************************************************
2467  get_user_info_2.
2468  *************************************************************************/
2469
2470 static NTSTATUS get_user_info_2(TALLOC_CTX *mem_ctx,
2471                                 struct samr_UserInfo2 *r,
2472                                 struct samu *pw)
2473 {
2474         r->comment.string               = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2475         r->reserved.string              = NULL;
2476         r->country_code                 = 0;
2477         r->code_page                    = 0;
2478
2479         return NT_STATUS_OK;
2480 }
2481
2482 /*************************************************************************
2483  get_user_info_3.
2484  *************************************************************************/
2485
2486 static NTSTATUS get_user_info_3(TALLOC_CTX *mem_ctx,
2487                                 struct samr_UserInfo3 *r,
2488                                 struct samu *pw,
2489                                 struct dom_sid *domain_sid)
2490 {
2491         const struct dom_sid *sid_user, *sid_group;
2492         uint32_t rid, primary_gid;
2493
2494         sid_user = pdb_get_user_sid(pw);
2495
2496         if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2497                 DEBUG(0, ("get_user_info_3: User %s has SID %s, \nwhich conflicts with "
2498                           "the domain sid %s.  Failing operation.\n",
2499                           pdb_get_username(pw), sid_string_dbg(sid_user),
2500                           sid_string_dbg(domain_sid)));
2501                 return NT_STATUS_UNSUCCESSFUL;
2502         }
2503
2504         become_root();
2505         sid_group = pdb_get_group_sid(pw);
2506         unbecome_root();
2507
2508         if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2509                 DEBUG(0, ("get_user_info_3: User %s has Primary Group SID %s, \n"
2510                           "which conflicts with the domain sid %s.  Failing operation.\n",
2511                           pdb_get_username(pw), sid_string_dbg(sid_group),
2512                           sid_string_dbg(domain_sid)));
2513                 return NT_STATUS_UNSUCCESSFUL;
2514         }
2515
2516         unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2517         unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2518         unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2519         unix_to_nt_time(&r->allow_password_change, pdb_get_pass_can_change_time(pw));
2520         unix_to_nt_time(&r->force_password_change, pdb_get_pass_must_change_time(pw));
2521
2522         r->account_name.string  = talloc_strdup(mem_ctx, pdb_get_username(pw));
2523         r->full_name.string     = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2524         r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2525         r->home_drive.string    = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2526         r->logon_script.string  = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2527         r->profile_path.string  = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2528         r->workstations.string  = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2529
2530         r->logon_hours          = get_logon_hours_from_pdb(mem_ctx, pw);
2531         r->rid                  = rid;
2532         r->primary_gid          = primary_gid;
2533         r->acct_flags           = pdb_get_acct_ctrl(pw);
2534         r->bad_password_count   = pdb_get_bad_password_count(pw);
2535         r->logon_count          = pdb_get_logon_count(pw);
2536
2537         return NT_STATUS_OK;
2538 }
2539
2540 /*************************************************************************
2541  get_user_info_4.
2542  *************************************************************************/
2543
2544 static NTSTATUS get_user_info_4(TALLOC_CTX *mem_ctx,
2545                                 struct samr_UserInfo4 *r,
2546                                 struct samu *pw)
2547 {
2548         r->logon_hours          = get_logon_hours_from_pdb(mem_ctx, pw);
2549
2550         return NT_STATUS_OK;
2551 }
2552
2553 /*************************************************************************
2554  get_user_info_5.
2555  *************************************************************************/
2556
2557 static NTSTATUS get_user_info_5(TALLOC_CTX *mem_ctx,
2558                                 struct samr_UserInfo5 *r,
2559                                 struct samu *pw,
2560                                 struct dom_sid *domain_sid)
2561 {
2562         const struct dom_sid *sid_user, *sid_group;
2563         uint32_t rid, primary_gid;
2564
2565         sid_user = pdb_get_user_sid(pw);
2566
2567         if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2568                 DEBUG(0, ("get_user_info_5: User %s has SID %s, \nwhich conflicts with "
2569                           "the domain sid %s.  Failing operation.\n",
2570                           pdb_get_username(pw), sid_string_dbg(sid_user),
2571                           sid_string_dbg(domain_sid)));
2572                 return NT_STATUS_UNSUCCESSFUL;
2573         }
2574
2575         become_root();
2576         sid_group = pdb_get_group_sid(pw);
2577         unbecome_root();
2578
2579         if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2580                 DEBUG(0, ("get_user_info_5: User %s has Primary Group SID %s, \n"
2581                           "which conflicts with the domain sid %s.  Failing operation.\n",
2582                           pdb_get_username(pw), sid_string_dbg(sid_group),
2583                           sid_string_dbg(domain_sid)));
2584                 return NT_STATUS_UNSUCCESSFUL;
2585         }
2586
2587         unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2588         unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2589         unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2590         unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2591
2592         r->account_name.string  = talloc_strdup(mem_ctx, pdb_get_username(pw));
2593         r->full_name.string     = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2594         r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2595         r->home_drive.string    = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2596         r->logon_script.string  = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2597         r->profile_path.string  = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2598         r->description.string   = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2599         r->workstations.string  = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2600
2601         r->logon_hours          = get_logon_hours_from_pdb(mem_ctx, pw);
2602         r->rid                  = rid;
2603         r->primary_gid          = primary_gid;
2604         r->acct_flags           = pdb_get_acct_ctrl(pw);
2605         r->bad_password_count   = pdb_get_bad_password_count(pw);
2606         r->logon_count          = pdb_get_logon_count(pw);
2607
2608         return NT_STATUS_OK;
2609 }
2610
2611 /*************************************************************************
2612  get_user_info_6.
2613  *************************************************************************/
2614
2615 static NTSTATUS get_user_info_6(TALLOC_CTX *mem_ctx,
2616                                 struct samr_UserInfo6 *r,
2617                                 struct samu *pw)
2618 {
2619         r->account_name.string  = talloc_strdup(mem_ctx, pdb_get_username(pw));
2620         r->full_name.string     = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2621
2622         return NT_STATUS_OK;
2623 }
2624
2625 /*************************************************************************
2626  get_user_info_7. Safe. Only gives out account_name.
2627  *************************************************************************/
2628
2629 static NTSTATUS get_user_info_7(TALLOC_CTX *mem_ctx,
2630                                 struct samr_UserInfo7 *r,
2631                                 struct samu *smbpass)
2632 {
2633         r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(smbpass));
2634         if (!r->account_name.string) {
2635                 return NT_STATUS_NO_MEMORY;
2636         }
2637
2638         return NT_STATUS_OK;
2639 }
2640
2641 /*************************************************************************
2642  get_user_info_8.
2643  *************************************************************************/
2644
2645 static NTSTATUS get_user_info_8(TALLOC_CTX *mem_ctx,
2646                                 struct samr_UserInfo8 *r,
2647                                 struct samu *pw)
2648 {
2649         r->full_name.string     = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2650
2651         return NT_STATUS_OK;
2652 }
2653
2654 /*************************************************************************
2655  get_user_info_9. Only gives out primary group SID.
2656  *************************************************************************/
2657
2658 static NTSTATUS get_user_info_9(TALLOC_CTX *mem_ctx,
2659                                 struct samr_UserInfo9 *r,
2660                                 struct samu *smbpass)
2661 {
2662         r->primary_gid = pdb_get_group_rid(smbpass);
2663
2664         return NT_STATUS_OK;
2665 }
2666
2667 /*************************************************************************
2668  get_user_info_10.
2669  *************************************************************************/
2670
2671 static NTSTATUS get_user_info_10(TALLOC_CTX *mem_ctx,
2672                                  struct samr_UserInfo10 *r,
2673                                  struct samu *pw)
2674 {
2675         r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2676         r->home_drive.string    = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2677
2678         return NT_STATUS_OK;
2679 }
2680
2681 /*************************************************************************
2682  get_user_info_11.
2683  *************************************************************************/
2684
2685 static NTSTATUS get_user_info_11(TALLOC_CTX *mem_ctx,
2686                                  struct samr_UserInfo11 *r,
2687                                  struct samu *pw)
2688 {
2689         r->logon_script.string  = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2690
2691         return NT_STATUS_OK;
2692 }
2693
2694 /*************************************************************************
2695  get_user_info_12.
2696  *************************************************************************/
2697
2698 static NTSTATUS get_user_info_12(TALLOC_CTX *mem_ctx,
2699                                  struct samr_UserInfo12 *r,
2700                                  struct samu *pw)
2701 {
2702         r->profile_path.string  = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2703
2704         return NT_STATUS_OK;
2705 }
2706
2707 /*************************************************************************
2708  get_user_info_13.
2709  *************************************************************************/
2710
2711 static NTSTATUS get_user_info_13(TALLOC_CTX *mem_ctx,
2712                                  struct samr_UserInfo13 *r,
2713                                  struct samu *pw)
2714 {
2715         r->description.string   = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2716
2717         return NT_STATUS_OK;
2718 }
2719
2720 /*************************************************************************
2721  get_user_info_14.
2722  *************************************************************************/
2723
2724 static NTSTATUS get_user_info_14(TALLOC_CTX *mem_ctx,
2725                                  struct samr_UserInfo14 *r,
2726                                  struct samu *pw)
2727 {
2728         r->workstations.string  = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2729
2730         return NT_STATUS_OK;
2731 }
2732
2733 /*************************************************************************
2734  get_user_info_16. Safe. Only gives out acb bits.
2735  *************************************************************************/
2736
2737 static NTSTATUS get_user_info_16(TALLOC_CTX *mem_ctx,
2738                                  struct samr_UserInfo16 *r,
2739                                  struct samu *smbpass)
2740 {
2741         r->acct_flags = pdb_get_acct_ctrl(smbpass);
2742
2743         return NT_STATUS_OK;
2744 }
2745
2746 /*************************************************************************
2747  get_user_info_17.
2748  *************************************************************************/
2749
2750 static NTSTATUS get_user_info_17(TALLOC_CTX *mem_ctx,
2751                                  struct samr_UserInfo17 *r,
2752                                  struct samu *pw)
2753 {
2754         unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2755
2756         return NT_STATUS_OK;
2757 }
2758
2759 /*************************************************************************
2760  get_user_info_18. OK - this is the killer as it gives out password info.
2761  Ensure that this is only allowed on an encrypted connection with a root
2762  user. JRA.
2763  *************************************************************************/
2764
2765 static NTSTATUS get_user_info_18(struct pipes_struct *p,
2766                                  TALLOC_CTX *mem_ctx,
2767                                  struct samr_UserInfo18 *r,
2768                                  struct dom_sid *user_sid)
2769 {
2770         struct samu *smbpass=NULL;
2771         bool ret;
2772         const uint8_t *nt_pass = NULL;
2773         const uint8_t *lm_pass = NULL;
2774
2775         ZERO_STRUCTP(r);
2776
2777         if (p->server_info->system) {
2778                 goto query;
2779         }
2780
2781         if ((p->auth.auth_type != DCERPC_AUTH_TYPE_NTLMSSP) ||
2782             (p->auth.auth_type != DCERPC_AUTH_TYPE_KRB5) ||
2783             (p->auth.auth_type != DCERPC_AUTH_TYPE_SPNEGO)) {
2784                 return NT_STATUS_ACCESS_DENIED;
2785         }
2786
2787         if (p->auth.auth_level != DCERPC_AUTH_LEVEL_PRIVACY) {
2788                 return NT_STATUS_ACCESS_DENIED;
2789         }
2790
2791  query:
2792         /*
2793          * Do *NOT* do become_root()/unbecome_root() here ! JRA.
2794          */
2795
2796         if ( !(smbpass = samu_new( mem_ctx )) ) {
2797                 return NT_STATUS_NO_MEMORY;
2798         }
2799
2800         ret = pdb_getsampwsid(smbpass, user_sid);
2801
2802         if (ret == False) {
2803                 DEBUG(4, ("User %s not found\n", sid_string_dbg(user_sid)));
2804                 TALLOC_FREE(smbpass);
2805                 return (geteuid() == sec_initial_uid()) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
2806         }
2807
2808         DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
2809
2810         if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
2811                 TALLOC_FREE(smbpass);
2812                 return NT_STATUS_ACCOUNT_DISABLED;
2813         }
2814
2815         lm_pass = pdb_get_lanman_passwd(smbpass);
2816         if (lm_pass != NULL) {
2817                 memcpy(r->lm_pwd.hash, lm_pass, 16);
2818                 r->lm_pwd_active = true;
2819         }
2820
2821         nt_pass = pdb_get_nt_passwd(smbpass);
2822         if (nt_pass != NULL) {
2823                 memcpy(r->nt_pwd.hash, nt_pass, 16);
2824                 r->nt_pwd_active = true;
2825         }
2826         r->password_expired = 0; /* FIXME */
2827
2828         TALLOC_FREE(smbpass);
2829
2830         return NT_STATUS_OK;
2831 }
2832
2833 /*************************************************************************
2834  get_user_info_20
2835  *************************************************************************/
2836
2837 static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx,
2838                                  struct samr_UserInfo20 *r,
2839                                  struct samu *sampass)
2840 {
2841         const char *munged_dial = NULL;
2842         DATA_BLOB blob;
2843         NTSTATUS status;
2844         struct lsa_BinaryString *parameters = NULL;
2845
2846         ZERO_STRUCTP(r);
2847
2848         munged_dial = pdb_get_munged_dial(sampass);
2849
2850         DEBUG(3,("User:[%s] has [%s] (length: %d)\n", pdb_get_username(sampass),
2851                 munged_dial, (int)strlen(munged_dial)));
2852
2853         if (munged_dial) {
2854                 blob = base64_decode_data_blob(munged_dial);
2855         } else {
2856                 blob = data_blob_string_const_null("");
2857         }
2858
2859         status = init_samr_parameters_string(mem_ctx, &blob, &parameters);
2860         data_blob_free(&blob);
2861         if (!NT_STATUS_IS_OK(status)) {
2862                 return status;
2863         }
2864
2865         r->parameters = *parameters;
2866
2867         return NT_STATUS_OK;
2868 }
2869
2870
2871 /*************************************************************************
2872  get_user_info_21
2873  *************************************************************************/
2874
2875 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx,
2876                                  struct samr_UserInfo21 *r,
2877                                  struct samu *pw,
2878                                  struct dom_sid *domain_sid,
2879                                  uint32_t acc_granted)
2880 {
2881         NTSTATUS status;
2882         const struct dom_sid *sid_user, *sid_group;
2883         uint32_t rid, primary_gid;
2884         NTTIME force_password_change;
2885         time_t must_change_time;
2886         struct lsa_BinaryString *parameters = NULL;
2887         const char *munged_dial = NULL;
2888         DATA_BLOB blob;
2889
2890         ZERO_STRUCTP(r);
2891
2892         sid_user = pdb_get_user_sid(pw);
2893
2894         if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2895                 DEBUG(0, ("get_user_info_21: User %s has SID %s, \nwhich conflicts with "
2896                           "the domain sid %s.  Failing operation.\n",
2897                           pdb_get_username(pw), sid_string_dbg(sid_user),
2898                           sid_string_dbg(domain_sid)));
2899                 return NT_STATUS_UNSUCCESSFUL;
2900         }
2901
2902         become_root();
2903         sid_group = pdb_get_group_sid(pw);
2904         unbecome_root();
2905
2906         if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2907                 DEBUG(0, ("get_user_info_21: User %s has Primary Group SID %s, \n"
2908                           "which conflicts with the domain sid %s.  Failing operation.\n",
2909                           pdb_get_username(pw), sid_string_dbg(sid_group),
2910                           sid_string_dbg(domain_sid)));
2911                 return NT_STATUS_UNSUCCESSFUL;
2912         }
2913
2914         unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2915         unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2916         unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2917         unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2918         unix_to_nt_time(&r->allow_password_change, pdb_get_pass_can_change_time(pw));
2919
2920         must_change_time = pdb_get_pass_must_change_time(pw);
2921         if (must_change_time == get_time_t_max()) {
2922                 unix_to_nt_time_abs(&force_password_change, must_change_time);
2923         } else {
2924                 unix_to_nt_time(&force_password_change, must_change_time);
2925         }
2926
2927         munged_dial = pdb_get_munged_dial(pw);
2928         if (munged_dial) {
2929                 blob = base64_decode_data_blob(munged_dial);
2930         } else {
2931                 blob = data_blob_string_const_null("");
2932         }
2933
2934         status = init_samr_parameters_string(mem_ctx, &blob, &parameters);
2935         data_blob_free(&blob);
2936         if (!NT_STATUS_IS_OK(status)) {
2937                 return status;
2938         }
2939
2940         r->force_password_change        = force_password_change;
2941
2942         r->account_name.string          = talloc_strdup(mem_ctx, pdb_get_username(pw));
2943         r->full_name.string             = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2944         r->home_directory.string        = talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2945         r->home_drive.string            = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2946         r->logon_script.string          = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2947         r->profile_path.string          = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2948         r->description.string           = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2949         r->workstations.string          = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2950         r->comment.string               = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2951
2952         r->logon_hours                  = get_logon_hours_from_pdb(mem_ctx, pw);
2953         r->parameters                   = *parameters;
2954         r->rid                          = rid;
2955         r->primary_gid                  = primary_gid;
2956         r->acct_flags                   = pdb_get_acct_ctrl(pw);
2957         r->bad_password_count           = pdb_get_bad_password_count(pw);
2958         r->logon_count                  = pdb_get_logon_count(pw);
2959         r->fields_present               = pdb_build_fields_present(pw);
2960         r->password_expired             = (pdb_get_pass_must_change_time(pw) == 0) ?
2961                                                 PASS_MUST_CHANGE_AT_NEXT_LOGON : 0;
2962         r->country_code                 = 0;
2963         r->code_page                    = 0;
2964         r->lm_password_set              = 0;
2965         r->nt_password_set              = 0;
2966
2967 #if 0
2968
2969         /*
2970           Look at a user on a real NT4 PDC with usrmgr, press
2971           'ok'. Then you will see that fields_present is set to
2972           0x08f827fa. Look at the user immediately after that again,
2973           and you will see that 0x00fffff is returned. This solves
2974           the problem that you get access denied after having looked
2975           at the user.
2976           -- Volker
2977         */
2978
2979 #endif
2980
2981
2982         return NT_STATUS_OK;
2983 }
2984
2985 /*******************************************************************
2986  _samr_QueryUserInfo
2987  ********************************************************************/
2988
2989 NTSTATUS _samr_QueryUserInfo(struct pipes_struct *p,
2990                              struct samr_QueryUserInfo *r)
2991 {
2992         NTSTATUS status;
2993         union samr_UserInfo *user_info = NULL;
2994         struct samr_user_info *uinfo;
2995         struct dom_sid domain_sid;
2996         uint32 rid;
2997         bool ret = false;
2998         struct samu *pwd = NULL;
2999         uint32_t acc_required, acc_granted;
3000
3001         switch (r->in.level) {
3002         case 1: /* UserGeneralInformation */
3003                 /* USER_READ_GENERAL */
3004                 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC;
3005                 break;
3006         case 2: /* UserPreferencesInformation */
3007                 /* USER_READ_PREFERENCES | USER_READ_GENERAL */
3008                 acc_required = SAMR_USER_ACCESS_GET_LOCALE |
3009                                SAMR_USER_ACCESS_GET_NAME_ETC;
3010                 break;
3011         case 3: /* UserLogonInformation */
3012                 /* USER_READ_GENERAL | USER_READ_PREFERENCES | USER_READ_LOGON | USER_READ_ACCOUNT */
3013                 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC |
3014                                SAMR_USER_ACCESS_GET_LOCALE |
3015                                SAMR_USER_ACCESS_GET_LOGONINFO |
3016                                SAMR_USER_ACCESS_GET_ATTRIBUTES;
3017                 break;
3018         case 4: /* UserLogonHoursInformation */
3019                 /* USER_READ_LOGON */
3020                 acc_required = SAMR_USER_ACCESS_GET_LOGONINFO;
3021                 break;
3022         case 5: /* UserAccountInformation */
3023                 /* USER_READ_GENERAL | USER_READ_PREFERENCES | USER_READ_LOGON | USER_READ_ACCOUNT */
3024                 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC |
3025                                SAMR_USER_ACCESS_GET_LOCALE |
3026                                SAMR_USER_ACCESS_GET_LOGONINFO |
3027                                SAMR_USER_ACCESS_GET_ATTRIBUTES;
3028                 break;
3029         case 6: /* UserNameInformation */
3030         case 7: /* UserAccountNameInformation */
3031         case 8: /* UserFullNameInformation */
3032         case 9: /* UserPrimaryGroupInformation */
3033         case 13: /* UserAdminCommentInformation */
3034                 /* USER_READ_GENERAL */
3035                 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC;
3036                 break;
3037         case 10: /* UserHomeInformation */
3038         case 11: /* UserScriptInformation */
3039         case 12: /* UserProfileInformation */
3040         case 14: /* UserWorkStationsInformation */
3041                 /* USER_READ_LOGON */
3042                 acc_required = SAMR_USER_ACCESS_GET_LOGONINFO;
3043                 break;
3044         case 16: /* UserControlInformation */
3045         case 17: /* UserExpiresInformation */
3046         case 20: /* UserParametersInformation */
3047                 /* USER_READ_ACCOUNT */
3048                 acc_required = SAMR_USER_ACCESS_GET_ATTRIBUTES;
3049                 break;
3050         case 21: /* UserAllInformation */
3051                 /* FIXME! - gd */
3052                 acc_required = SAMR_USER_ACCESS_GET_ATTRIBUTES;
3053                 break;
3054         case 18: /* UserInternal1Information */
3055                 /* FIXME! - gd */
3056                 acc_required = SAMR_USER_ACCESS_GET_ATTRIBUTES;
3057                 break;
3058         case 23: /* UserInternal4Information */
3059         case 24: /* UserInternal4InformationNew */
3060         case 25: /* UserInternal4InformationNew */
3061         case 26: /* UserInternal5InformationNew */
3062         default:
3063                 return NT_STATUS_INVALID_INFO_CLASS;
3064                 break;
3065         }
3066
3067         uinfo = policy_handle_find(p, r->in.user_handle,
3068                                    acc_required, &acc_granted,
3069                                    struct samr_user_info, &status);
3070         if (!NT_STATUS_IS_OK(status)) {
3071                 return status;
3072         }
3073
3074         domain_sid = uinfo->sid;
3075
3076         sid_split_rid(&domain_sid, &rid);
3077
3078         if (!sid_check_is_in_our_domain(&uinfo->sid))
3079                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
3080
3081         DEBUG(5,("_samr_QueryUserInfo: sid:%s\n",
3082                  sid_string_dbg(&uinfo->sid)));
3083
3084         user_info = TALLOC_ZERO_P(p->mem_ctx, union samr_UserInfo);
3085         if (!user_info) {
3086                 return NT_STATUS_NO_MEMORY;
3087         }
3088
3089         DEBUG(5,("_samr_QueryUserInfo: user info level: %d\n", r->in.level));
3090
3091         if (!(pwd = samu_new(p->mem_ctx))) {
3092                 return NT_STATUS_NO_MEMORY;
3093         }
3094
3095         become_root();
3096         ret = pdb_getsampwsid(pwd, &uinfo->sid);
3097         unbecome_root();
3098
3099         if (ret == false) {
3100                 DEBUG(4,("User %s not found\n", sid_string_dbg(&uinfo->sid)));
3101                 TALLOC_FREE(pwd);
3102                 return NT_STATUS_NO_SUCH_USER;
3103         }
3104
3105         DEBUG(3,("User:[%s]\n", pdb_get_username(pwd)));
3106
3107         samr_clear_sam_passwd(pwd);
3108
3109         switch (r->in.level) {
3110         case 1:
3111                 status = get_user_info_1(p->mem_ctx, &user_info->info1, pwd, &domain_sid);
3112                 break;
3113         case 2:
3114                 status = get_user_info_2(p->mem_ctx, &user_info->info2, pwd);
3115                 break;
3116         case 3:
3117                 status = get_user_info_3(p->mem_ctx, &user_info->info3, pwd, &domain_sid);
3118                 break;
3119         case 4:
3120                 status = get_user_info_4(p->mem_ctx, &user_info->info4, pwd);
3121                 break;
3122         case 5:
3123                 status = get_user_info_5(p->mem_ctx, &user_info->info5, pwd, &domain_sid);
3124                 break;
3125         case 6:
3126                 status = get_user_info_6(p->mem_ctx, &user_info->info6, pwd);
3127                 break;
3128         case 7:
3129                 status = get_user_info_7(p->mem_ctx, &user_info->info7, pwd);
3130                 break;
3131         case 8:
3132                 status = get_user_info_8(p->mem_ctx, &user_info->info8, pwd);
3133                 break;
3134         case 9:
3135                 status = get_user_info_9(p->mem_ctx, &user_info->info9, pwd);
3136                 break;
3137         case 10:
3138                 status = get_user_info_10(p->mem_ctx, &user_info->info10, pwd);
3139                 break;
3140         case 11:
3141                 status = get_user_info_11(p->mem_ctx, &user_info->info11, pwd);
3142                 break;
3143         case 12:
3144                 status = get_user_info_12(p->mem_ctx, &user_info->info12, pwd);
3145                 break;
3146         case 13:
3147                 status = get_user_info_13(p->mem_ctx, &user_info->info13, pwd);
3148                 break;
3149         case 14:
3150                 status = get_user_info_14(p->mem_ctx, &user_info->info14, pwd);
3151                 break;
3152         case 16:
3153                 status = get_user_info_16(p->mem_ctx, &user_info->info16, pwd);
3154                 break;
3155         case 17:
3156                 status = get_user_info_17(p->mem_ctx, &user_info->info17, pwd);
3157                 break;
3158         case 18:
3159                 /* level 18 is special */
3160                 status = get_user_info_18(p, p->mem_ctx, &user_info->info18,
3161                                           &uinfo->sid);
3162                 break;
3163         case 20:
3164                 status = get_user_info_20(p->mem_ctx, &user_info->info20, pwd);
3165                 break;
3166         case 21:
3167                 status = get_user_info_21(p->mem_ctx, &user_info->info21, pwd, &domain_sid, acc_granted);
3168                 break;
3169         default:
3170                 status = NT_STATUS_INVALID_INFO_CLASS;
3171                 break;
3172         }
3173
3174         if (!NT_STATUS_IS_OK(status)) {
3175                 goto done;
3176         }
3177
3178         *r->out.info = user_info;
3179
3180  done:
3181         TALLOC_FREE(pwd);
3182
3183         DEBUG(5,("_samr_QueryUserInfo: %d\n", __LINE__));
3184
3185         return status;
3186 }
3187
3188 /****************************************************************
3189 ****************************************************************/
3190
3191 NTSTATUS _samr_QueryUserInfo2(struct pipes_struct *p,
3192                               struct samr_QueryUserInfo2 *r)
3193 {
3194         struct samr_QueryUserInfo u;
3195
3196         u.in.user_handle        = r->in.user_handle;
3197         u.in.level              = r->in.level;
3198         u.out.info              = r->out.info;
3199
3200         return _samr_QueryUserInfo(p, &u);
3201 }
3202
3203 /*******************************************************************
3204  _samr_GetGroupsForUser
3205  ********************************************************************/
3206
3207 NTSTATUS _samr_GetGroupsForUser(struct pipes_struct *p,
3208                                 struct samr_GetGroupsForUser *r)
3209 {
3210         struct samr_user_info *uinfo;
3211         struct samu *sam_pass=NULL;
3212         struct dom_sid *sids;
3213         struct samr_RidWithAttribute dom_gid;
3214         struct samr_RidWithAttribute *gids = NULL;
3215         uint32 primary_group_rid;
3216         size_t num_groups = 0;
3217         gid_t *unix_gids;
3218         size_t i, num_gids;
3219         bool ret;
3220         NTSTATUS result;
3221         bool success = False;
3222
3223         struct samr_RidWithAttributeArray *rids = NULL;
3224
3225         /*
3226          * from the SID in the request:
3227          * we should send back the list of DOMAIN GROUPS
3228          * the user is a member of
3229          *
3230          * and only the DOMAIN GROUPS
3231          * no ALIASES !!! neither aliases of the domain
3232          * nor aliases of the builtin SID
3233          *
3234          * JFM, 12/2/2001
3235          */
3236
3237         DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
3238
3239         uinfo = policy_handle_find(p, r->in.user_handle,
3240                                    SAMR_USER_ACCESS_GET_GROUPS, NULL,
3241                                    struct samr_user_info, &result);
3242         if (!NT_STATUS_IS_OK(result)) {
3243                 return result;
3244         }
3245
3246         rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidWithAttributeArray);
3247         if (!rids) {
3248                 return NT_STATUS_NO_MEMORY;
3249         }
3250
3251         if (!sid_check_is_in_our_domain(&uinfo->sid))
3252                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
3253
3254         if ( !(sam_pass = samu_new( p->mem_ctx )) ) {
3255                 return NT_STATUS_NO_MEMORY;
3256         }
3257
3258         become_root();
3259         ret = pdb_getsampwsid(sam_pass, &uinfo->sid);
3260         unbecome_root();
3261
3262         if (!ret) {
3263                 DEBUG(10, ("pdb_getsampwsid failed for %s\n",
3264                            sid_string_dbg(&uinfo->sid)));
3265                 return NT_STATUS_NO_SUCH_USER;
3266         }
3267
3268         sids = NULL;
3269
3270         /* make both calls inside the root block */
3271         become_root();
3272         result = pdb_enum_group_memberships(p->mem_ctx, sam_pass,
3273                                             &sids, &unix_gids, &num_groups);
3274         if ( NT_STATUS_IS_OK(result) ) {
3275                 success = sid_peek_check_rid(get_global_sam_sid(),
3276                                              pdb_get_group_sid(sam_pass),
3277                                              &primary_group_rid);
3278         }
3279         unbecome_root();
3280
3281         if (!NT_STATUS_IS_OK(result)) {
3282                 DEBUG(10, ("pdb_enum_group_memberships failed for %s\n",
3283                            sid_string_dbg(&uinfo->sid)));
3284                 return result;
3285         }
3286
3287         if ( !success ) {
3288                 DEBUG(5, ("Group sid %s for user %s not in our domain\n",
3289                           sid_string_dbg(pdb_get_group_sid(sam_pass)),
3290                           pdb_get_username(sam_pass)));
3291                 TALLOC_FREE(sam_pass);
3292                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
3293         }
3294
3295         gids = NULL;
3296         num_gids = 0;
3297
3298         dom_gid.attributes = (SE_GROUP_MANDATORY|SE_GROUP_ENABLED_BY_DEFAULT|
3299                               SE_GROUP_ENABLED);
3300         dom_gid.rid = primary_group_rid;
3301         ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
3302
3303         for (i=0; i<num_groups; i++) {
3304
3305                 if (!sid_peek_check_rid(get_global_sam_sid(),
3306                                         &(sids[i]), &dom_gid.rid)) {
3307                         DEBUG(10, ("Found sid %s not in our domain\n",
3308                                    sid_string_dbg(&sids[i])));
3309                         continue;
3310                 }
3311
3312                 if (dom_gid.rid == primary_group_rid) {
3313                         /* We added the primary group directly from the
3314                          * sam_account. The other SIDs are unique from
3315                          * enum_group_memberships */
3316                         continue;
3317                 }
3318
3319                 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
3320         }
3321
3322         rids->count = num_gids;
3323         rids->rids = gids;
3324
3325         *r->out.rids = rids;
3326
3327         DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
3328
3329         return result;
3330 }
3331
3332 /*******************************************************************
3333  ********************************************************************/
3334
3335 static uint32_t samr_get_server_role(void)
3336 {
3337         uint32_t role = ROLE_DOMAIN_PDC;
3338
3339         if (lp_server_role() == ROLE_DOMAIN_BDC) {
3340                 role = ROLE_DOMAIN_BDC;
3341         }
3342
3343         return role;
3344 }
3345
3346 /*******************************************************************
3347  ********************************************************************/
3348
3349 static NTSTATUS query_dom_info_1(TALLOC_CTX *mem_ctx,
3350                                  struct samr_DomInfo1 *r)
3351 {
3352         uint32_t account_policy_temp;
3353         time_t u_expire, u_min_age;
3354
3355         become_root();
3356
3357         /* AS ROOT !!! */
3358
3359         pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN, &account_policy_temp);
3360         r->min_password_length = account_policy_temp;
3361
3362         pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &account_policy_temp);
3363         r->password_history_length = account_policy_temp;
3364
3365         pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
3366                                &r->password_properties);
3367
3368         pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, &account_policy_temp);
3369         u_expire = account_policy_temp;
3370
3371         pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, &account_policy_temp);
3372         u_min_age = account_policy_temp;
3373
3374         /* !AS ROOT */
3375
3376         unbecome_root();
3377
3378         unix_to_nt_time_abs((NTTIME *)&r->max_password_age, u_expire);
3379         unix_to_nt_time_abs((NTTIME *)&r->min_password_age, u_min_age);
3380
3381         if (lp_check_password_script() && *lp_check_password_script()) {
3382                 r->password_properties |= DOMAIN_PASSWORD_COMPLEX;
3383         }
3384
3385         return NT_STATUS_OK;
3386 }
3387
3388 /*******************************************************************
3389  ********************************************************************/
3390
3391 static NTSTATUS query_dom_info_2(TALLOC_CTX *mem_ctx,
3392                                  struct samr_DomGeneralInformation *r,
3393                                  struct samr_domain_info *dinfo)
3394 {
3395         uint32_t u_logout;
3396         time_t seq_num;
3397
3398         become_root();
3399
3400         /* AS ROOT !!! */
3401
3402         r->num_users    = count_sam_users(dinfo->disp_info, ACB_NORMAL);
3403         r->num_groups   = count_sam_groups(dinfo->disp_info);
3404         r->num_aliases  = count_sam_aliases(dinfo->disp_info);
3405
3406         pdb_get_account_policy(PDB_POLICY_TIME_TO_LOGOUT, &u_logout);
3407
3408         unix_to_nt_time_abs(&r->force_logoff_time, u_logout);
3409
3410         if (!pdb_get_seq_num(&seq_num)) {
3411                 seq_num = time(NULL);
3412         }
3413
3414         /* !AS ROOT */
3415
3416         unbecome_root();
3417
3418         r->oem_information.string       = lp_serverstring();
3419         r->domain_name.string           = lp_workgroup();
3420         r->primary.string               = global_myname();
3421         r->sequence_num                 = seq_num;
3422         r->domain_server_state          = DOMAIN_SERVER_ENABLED;
3423         r->role                         = (enum samr_Role) samr_get_server_role();
3424         r->unknown3                     = 1;
3425
3426         return NT_STATUS_OK;
3427 }
3428
3429 /*******************************************************************
3430  ********************************************************************/
3431
3432 static NTSTATUS query_dom_info_3(TALLOC_CTX *mem_ctx,
3433                                  struct samr_DomInfo3 *r)
3434 {
3435         uint32_t u_logout;
3436
3437         become_root();
3438
3439         /* AS ROOT !!! */
3440
3441         {
3442                 uint32_t ul;
3443                 pdb_get_account_policy(PDB_POLICY_TIME_TO_LOGOUT, &ul);
3444                 u_logout = (time_t)ul;
3445         }
3446
3447         /* !AS ROOT */
3448
3449         unbecome_root();
3450
3451         unix_to_nt_time_abs(&r->force_logoff_time, u_logout);
3452
3453         return NT_STATUS_OK;
3454 }
3455
3456 /*******************************************************************
3457  ********************************************************************/
3458
3459 static NTSTATUS query_dom_info_4(TALLOC_CTX *mem_ctx,
3460                                  struct samr_DomOEMInformation *r)
3461 {
3462         r->oem_information.string = lp_serverstring();
3463
3464         return NT_STATUS_OK;
3465 }
3466
3467 /*******************************************************************
3468  ********************************************************************/
3469
3470 static NTSTATUS query_dom_info_5(TALLOC_CTX *mem_ctx,
3471                                  struct samr_DomInfo5 *r)
3472 {
3473         r->domain_name.string = get_global_sam_name();
3474
3475         return NT_STATUS_OK;
3476 }
3477
3478 /*******************************************************************
3479  ********************************************************************/
3480
3481 static NTSTATUS query_dom_info_6(TALLOC_CTX *mem_ctx,
3482                                  struct samr_DomInfo6 *r)
3483 {
3484         /* NT returns its own name when a PDC. win2k and later
3485          * only the name of the PDC if itself is a BDC (samba4
3486          * idl) */
3487         r->primary.string = global_myname();
3488
3489         return NT_STATUS_OK;
3490 }
3491
3492 /*******************************************************************
3493  ********************************************************************/
3494
3495 static NTSTATUS query_dom_info_7(TALLOC_CTX *mem_ctx,
3496                                  struct samr_DomInfo7 *r)
3497 {
3498         r->role = (enum samr_Role) samr_get_server_role();
3499
3500         return NT_STATUS_OK;
3501 }
3502
3503 /*******************************************************************
3504  ********************************************************************/
3505
3506 static NTSTATUS query_dom_info_8(TALLOC_CTX *mem_ctx,
3507                                  struct samr_DomInfo8 *r)
3508 {
3509         time_t seq_num;
3510
3511         become_root();
3512
3513         /* AS ROOT !!! */
3514
3515         if (!pdb_get_seq_num(&seq_num)) {
3516                 seq_num = time(NULL);
3517         }
3518
3519         /* !AS ROOT */
3520
3521         unbecome_root();
3522
3523         r->sequence_num = seq_num;
3524         r->domain_create_time = 0;
3525
3526         return NT_STATUS_OK;
3527 }
3528
3529 /*******************************************************************
3530  ********************************************************************/
3531
3532 static NTSTATUS query_dom_info_9(TALLOC_CTX *mem_ctx,
3533                                  struct samr_DomInfo9 *r)
3534 {
3535         r->domain_server_state = DOMAIN_SERVER_ENABLED;
3536
3537         return NT_STATUS_OK;
3538 }
3539
3540 /*******************************************************************
3541  ********************************************************************/
3542
3543 static NTSTATUS query_dom_info_11(TALLOC_CTX *mem_ctx,
3544                                   struct samr_DomGeneralInformation2 *r,
3545                                   struct samr_domain_info *dinfo)
3546 {
3547         NTSTATUS status;
3548         uint32_t account_policy_temp;
3549         time_t u_lock_duration, u_reset_time;
3550
3551         status = query_dom_info_2(mem_ctx, &r->general, dinfo);
3552         if (!NT_STATUS_IS_OK(status)) {
3553                 return status;
3554         }
3555
3556         /* AS ROOT !!! */
3557
3558         become_root();
3559
3560         pdb_get_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, &account_policy_temp);
3561         u_lock_duration = account_policy_temp;
3562         if (u_lock_duration != -1) {
3563                 u_lock_duration *= 60;
3564         }
3565
3566         pdb_get_account_policy(PDB_POLICY_RESET_COUNT_TIME, &account_policy_temp);
3567         u_reset_time = account_policy_temp * 60;
3568
3569         pdb_get_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
3570         r->lockout_threshold = account_policy_temp;
3571
3572         /* !AS ROOT */
3573
3574         unbecome_root();
3575
3576         unix_to_nt_time_abs(&r->lockout_duration, u_lock_duration);
3577         unix_to_nt_time_abs(&r->lockout_window, u_reset_time);
3578
3579         return NT_STATUS_OK;
3580 }
3581
3582 /*******************************************************************
3583  ********************************************************************/
3584
3585 static NTSTATUS query_dom_info_12(TALLOC_CTX *mem_ctx,
3586                                   struct samr_DomInfo12 *r)
3587 {
3588         uint32_t account_policy_temp;
3589         time_t u_lock_duration, u_reset_time;
3590
3591         become_root();
3592
3593         /* AS ROOT !!! */
3594
3595         pdb_get_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, &account_policy_temp);
3596         u_lock_duration = account_policy_temp;
3597         if (u_lock_duration != -1) {
3598                 u_lock_duration *= 60;
3599         }
3600
3601         pdb_get_account_policy(PDB_POLICY_RESET_COUNT_TIME, &account_policy_temp);
3602         u_reset_time = account_policy_temp * 60;
3603
3604         pdb_get_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
3605         r->lockout_threshold = account_policy_temp;
3606
3607         /* !AS ROOT */
3608
3609         unbecome_root();
3610
3611         unix_to_nt_time_abs(&r->lockout_duration, u_lock_duration);
3612         unix_to_nt_time_abs(&r->lockout_window, u_reset_time);
3613
3614         return NT_STATUS_OK;
3615 }
3616
3617 /*******************************************************************
3618  ********************************************************************/
3619
3620 static NTSTATUS query_dom_info_13(TALLOC_CTX *mem_ctx,
3621                                   struct samr_DomInfo13 *r)
3622 {
3623         time_t seq_num;
3624
3625         become_root();
3626
3627         /* AS ROOT !!! */
3628
3629         if (!pdb_get_seq_num(&seq_num)) {
3630                 seq_num = time(NULL);
3631         }
3632
3633         /* !AS ROOT */
3634
3635         unbecome_root();
3636
3637         r->sequence_num = seq_num;
3638         r->domain_create_time = 0;
3639         r->modified_count_at_last_promotion = 0;
3640
3641         return NT_STATUS_OK;
3642 }
3643
3644 /*******************************************************************
3645  _samr_QueryDomainInfo
3646  ********************************************************************/
3647
3648 NTSTATUS _samr_QueryDomainInfo(struct pipes_struct *p,
3649                                struct samr_QueryDomainInfo *r)
3650 {
3651         NTSTATUS status = NT_STATUS_OK;
3652         struct samr_domain_info *dinfo;
3653         union samr_DomainInfo *dom_info;
3654
3655         uint32_t acc_required;
3656
3657         DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__));
3658
3659         switch (r->in.level) {
3660         case 1: /* DomainPasswordInformation */
3661         case 12: /* DomainLockoutInformation */
3662                 /* DOMAIN_READ_PASSWORD_PARAMETERS */
3663                 acc_required = SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1;
3664                 break;
3665         case 11: /* DomainGeneralInformation2 */
3666                 /* DOMAIN_READ_PASSWORD_PARAMETERS |
3667                  * DOMAIN_READ_OTHER_PARAMETERS */
3668                 acc_required = SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
3669                                SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2;
3670                 break;
3671         case 2: /* DomainGeneralInformation */
3672         case 3: /* DomainLogoffInformation */
3673         case 4: /* DomainOemInformation */
3674         case 5: /* DomainReplicationInformation */
3675         case 6: /* DomainReplicationInformation */
3676         case 7: /* DomainServerRoleInformation */
3677         case 8: /* DomainModifiedInformation */
3678         case 9: /* DomainStateInformation */
3679         case 10: /* DomainUasInformation */
3680         case 13: /* DomainModifiedInformation2 */
3681                 /* DOMAIN_READ_OTHER_PARAMETERS */
3682                 acc_required = SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2;
3683                 break;
3684         default:
3685                 return NT_STATUS_INVALID_INFO_CLASS;
3686         }
3687
3688         dinfo = policy_handle_find(p, r->in.domain_handle,
3689                                    acc_required, NULL,
3690                                    struct samr_domain_info, &status);
3691         if (!NT_STATUS_IS_OK(status)) {
3692                 return status;
3693         }
3694
3695         dom_info = TALLOC_ZERO_P(p->mem_ctx, union samr_DomainInfo);
3696         if (!dom_info) {
3697                 return NT_STATUS_NO_MEMORY;
3698         }
3699
3700         switch (r->in.level) {
3701                 case 1:
3702                         status = query_dom_info_1(p->mem_ctx, &dom_info->info1);
3703                         break;
3704                 case 2:
3705                         status = query_dom_info_2(p->mem_ctx, &dom_info->general, dinfo);
3706                         break;
3707                 case 3:
3708                         status = query_dom_info_3(p->mem_ctx, &dom_info->info3);
3709                         break;
3710                 case 4:
3711                         status = query_dom_info_4(p->mem_ctx, &dom_info->oem);
3712                         break;
3713                 case 5:
3714                         status = query_dom_info_5(p->mem_ctx, &dom_info->info5);
3715                         break;
3716                 case 6:
3717                         status = query_dom_info_6(p->mem_ctx, &dom_info->info6);
3718                         break;
3719                 case 7:
3720                         status = query_dom_info_7(p->mem_ctx, &dom_info->info7);
3721                         break;
3722                 case 8:
3723                         status = query_dom_info_8(p->mem_ctx, &dom_info->info8);
3724                         break;
3725                 case 9:
3726                         status = query_dom_info_9(p->mem_ctx, &dom_info->info9);
3727                         break;
3728                 case 11:
3729                         status = query_dom_info_11(p->mem_ctx, &dom_info->general2, dinfo);
3730                         break;
3731                 case 12:
3732                         status = query_dom_info_12(p->mem_ctx, &dom_info->info12);
3733                         break;
3734                 case 13:
3735                         status = query_dom_info_13(p->mem_ctx, &dom_info->info13);
3736                         break;
3737                 default:
3738                         return NT_STATUS_INVALID_INFO_CLASS;
3739         }
3740
3741         if (!NT_STATUS_IS_OK(status)) {
3742                 return status;
3743         }
3744
3745         *r->out.info = dom_info;
3746
3747         DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__));
3748
3749         return status;
3750 }
3751
3752 /* W2k3 seems to use the same check for all 3 objects that can be created via
3753  * SAMR, if you try to create for example "Dialup" as an alias it says
3754  * "NT_STATUS_USER_EXISTS". This is racy, but we can't really lock the user
3755  * database. */
3756
3757 static NTSTATUS can_create(TALLOC_CTX *mem_ctx, const char *new_name)
3758 {
3759         enum lsa_SidType type;
3760         bool result;
3761
3762         DEBUG(10, ("Checking whether [%s] can be created\n", new_name));
3763
3764         become_root();
3765         /* Lookup in our local databases (LOOKUP_NAME_REMOTE not set)
3766          * whether the name already exists */
3767         result = lookup_name(mem_ctx, new_name, LOOKUP_NAME_LOCAL,
3768                              NULL, NULL, NULL, &type);
3769         unbecome_root();
3770
3771         if (!result) {
3772                 DEBUG(10, ("%s does not exist, can create it\n", new_name));
3773                 return NT_STATUS_OK;
3774         }
3775
3776         DEBUG(5, ("trying to create %s, exists as %s\n",
3777                   new_name, sid_type_lookup(type)));
3778
3779         if (type == SID_NAME_DOM_GRP) {
3780                 return NT_STATUS_GROUP_EXISTS;
3781         }
3782         if (type == SID_NAME_ALIAS) {
3783                 return NT_STATUS_ALIAS_EXISTS;
3784         }
3785
3786         /* Yes, the default is NT_STATUS_USER_EXISTS */
3787         return NT_STATUS_USER_EXISTS;
3788 }
3789
3790 /*******************************************************************
3791  _samr_CreateUser2
3792  ********************************************************************/
3793
3794 NTSTATUS _samr_CreateUser2(struct pipes_struct *p,
3795                            struct samr_CreateUser2 *r)
3796 {
3797         const char *account = NULL;
3798         struct dom_sid sid;
3799         uint32_t acb_info = r->in.acct_flags;
3800         struct samr_domain_info *dinfo;
3801         struct samr_user_info *uinfo;
3802         NTSTATUS nt_status;
3803         uint32 acc_granted;
3804         struct security_descriptor *psd;
3805         size_t    sd_size;
3806         /* check this, when giving away 'add computer to domain' privs */
3807         uint32    des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
3808         bool can_add_account = False;
3809
3810         /* Which privilege is needed to override the ACL? */
3811         enum sec_privilege needed_priv = SEC_PRIV_INVALID;
3812
3813         dinfo = policy_handle_find(p, r->in.domain_handle,
3814                                    SAMR_DOMAIN_ACCESS_CREATE_USER, NULL,
3815                                    struct samr_domain_info, &nt_status);
3816         if (!NT_STATUS_IS_OK(nt_status)) {
3817                 return nt_status;
3818         }
3819
3820         if (sid_check_is_builtin(&dinfo->sid)) {
3821                 DEBUG(5,("_samr_CreateUser2: Refusing user create in BUILTIN\n"));
3822                 return NT_STATUS_ACCESS_DENIED;
3823         }
3824
3825         if (!(acb_info == ACB_NORMAL || acb_info == ACB_DOMTRUST ||
3826               acb_info == ACB_WSTRUST || acb_info == ACB_SVRTRUST)) {
3827                 /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if
3828                    this parameter is not an account type */
3829                 return NT_STATUS_INVALID_PARAMETER;
3830         }
3831
3832         account = r->in.account_name->string;
3833         if (account == NULL) {
3834                 return NT_STATUS_NO_MEMORY;
3835         }
3836
3837         nt_status = can_create(p->mem_ctx, account);
3838         if (!NT_STATUS_IS_OK(nt_status)) {
3839                 return nt_status;
3840         }
3841
3842         /* determine which user right we need to check based on the acb_info */
3843
3844         if (geteuid() == sec_initial_uid()) {
3845                 can_add_account = true;
3846         } else if (acb_info & ACB_WSTRUST) {
3847                 needed_priv = SEC_PRIV_MACHINE_ACCOUNT;
3848                 can_add_account = security_token_has_privilege(p->server_info->ptok, SEC_PRIV_MACHINE_ACCOUNT);
3849         } else if (acb_info & ACB_NORMAL &&
3850                   (account[strlen(account)-1] != '$')) {
3851                 /* usrmgr.exe (and net rpc trustdom grant) creates a normal user
3852                    account for domain trusts and changes the ACB flags later */
3853                 needed_priv = SEC_PRIV_ADD_USERS;
3854                 can_add_account = security_token_has_privilege(p->server_info->ptok, SEC_PRIV_ADD_USERS);
3855         } else if (lp_enable_privileges()) {
3856                 /* implicit assumption of a BDC or domain trust account here
3857                  * (we already check the flags earlier) */
3858                 /* only Domain Admins can add a BDC or domain trust */
3859                 can_add_account = nt_token_check_domain_rid(
3860                         p->server_info->ptok,
3861                         DOMAIN_RID_ADMINS );
3862         }
3863
3864         DEBUG(5, ("_samr_CreateUser2: %s can add this account : %s\n",
3865                   uidtoname(p->server_info->utok.uid),
3866                   can_add_account ? "True":"False" ));
3867
3868         if (!can_add_account) {
3869                 return NT_STATUS_ACCESS_DENIED;
3870         }
3871
3872         /********** BEGIN Admin BLOCK **********/
3873
3874         become_root();
3875         nt_status = pdb_create_user(p->mem_ctx, account, acb_info,
3876                                     r->out.rid);
3877         unbecome_root();
3878
3879         /********** END Admin BLOCK **********/
3880
3881         /* now check for failure */
3882
3883         if ( !NT_STATUS_IS_OK(nt_status) )
3884                 return nt_status;
3885
3886         /* Get the user's SID */
3887
3888         sid_compose(&sid, get_global_sam_sid(), *r->out.rid);
3889
3890         map_max_allowed_access(p->server_info->ptok,
3891                                &p->server_info->utok,
3892                                &des_access);
3893
3894         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping,
3895                             &sid, SAMR_USR_RIGHTS_WRITE_PW);
3896         se_map_generic(&des_access, &usr_generic_mapping);
3897
3898         /*
3899          * JRA - TESTME. We just created this user so we
3900          * had rights to create them. Do we need to check
3901          * any further access on this object ? Can't we
3902          * just assume we have all the rights we need ?
3903          */
3904
3905         nt_status = access_check_object(psd, p->server_info->ptok,
3906                                         needed_priv, SEC_PRIV_INVALID,
3907                                         GENERIC_RIGHTS_USER_WRITE, des_access,
3908                 &acc_granted, "_samr_CreateUser2");
3909
3910         if ( !NT_STATUS_IS_OK(nt_status) ) {
3911                 return nt_status;
3912         }
3913
3914         uinfo = policy_handle_create(p, r->out.user_handle, acc_granted,
3915                                      struct samr_user_info, &nt_status);
3916         if (!NT_STATUS_IS_OK(nt_status)) {
3917                 return nt_status;
3918         }
3919         uinfo->sid = sid;
3920
3921         /* After a "set" ensure we have no cached display info. */
3922         force_flush_samr_cache(&sid);
3923
3924         *r->out.access_granted = acc_granted;
3925
3926         return NT_STATUS_OK;
3927 }
3928
3929 /****************************************************************
3930 ****************************************************************/
3931
3932 NTSTATUS _samr_CreateUser(struct pipes_struct *p,
3933                           struct samr_CreateUser *r)
3934 {
3935         struct samr_CreateUser2 c;
3936         uint32_t access_granted;
3937
3938         c.in.domain_handle      = r->in.domain_handle;
3939         c.in.account_name       = r->in.account_name;
3940         c.in.acct_flags         = ACB_NORMAL;
3941         c.in.access_mask        = r->in.access_mask;
3942         c.out.user_handle       = r->out.user_handle;
3943         c.out.access_granted    = &access_granted;
3944         c.out.rid               = r->out.rid;
3945
3946         return _samr_CreateUser2(p, &c);
3947 }
3948
3949 /*******************************************************************
3950  _samr_Connect
3951  ********************************************************************/
3952
3953 NTSTATUS _samr_Connect(struct pipes_struct *p,
3954                        struct samr_Connect *r)
3955 {
3956         struct samr_connect_info *info;
3957         uint32_t acc_granted;
3958         struct policy_handle hnd;
3959         uint32    des_access = r->in.access_mask;
3960         NTSTATUS status;
3961
3962         /* Access check */
3963
3964         if (!pipe_access_check(p)) {
3965                 DEBUG(3, ("access denied to _samr_Connect\n"));
3966                 return NT_STATUS_ACCESS_DENIED;
3967         }
3968
3969         /* don't give away the farm but this is probably ok.  The SAMR_ACCESS_ENUM_DOMAINS
3970            was observed from a win98 client trying to enumerate users (when configured
3971            user level access control on shares)   --jerry */
3972
3973         map_max_allowed_access(p->server_info->ptok,
3974                                &p->server_info->utok,
3975                                &des_access);
3976
3977         se_map_generic( &des_access, &sam_generic_mapping );
3978
3979         acc_granted = des_access & (SAMR_ACCESS_ENUM_DOMAINS
3980                                     |SAMR_ACCESS_LOOKUP_DOMAIN);
3981
3982         /* set up the SAMR connect_anon response */
3983
3984         info = policy_handle_create(p, &hnd, acc_granted,
3985                                     struct samr_connect_info,
3986                                     &status);
3987         if (!NT_STATUS_IS_OK(status)) {
3988                 return status;
3989         }
3990
3991         *r->out.connect_handle = hnd;
3992         return NT_STATUS_OK;
3993 }
3994
3995 /*******************************************************************
3996  _samr_Connect2
3997  ********************************************************************/
3998
3999 NTSTATUS _samr_Connect2(struct pipes_struct *p,
4000                         struct samr_Connect2 *r)
4001 {
4002         struct samr_connect_info *info = NULL;
4003         struct policy_handle hnd;
4004         struct security_descriptor *psd = NULL;
4005         uint32    acc_granted;
4006         uint32    des_access = r->in.access_mask;
4007         NTSTATUS  nt_status;
4008         size_t    sd_size;
4009         const char *fn = "_samr_Connect2";
4010
4011         switch (p->opnum) {
4012         case NDR_SAMR_CONNECT2:
4013                 fn = "_samr_Connect2";
4014                 break;
4015         case NDR_SAMR_CONNECT3:
4016                 fn = "_samr_Connect3";
4017                 break;
4018         case NDR_SAMR_CONNECT4:
4019                 fn = "_samr_Connect4";
4020                 break;
4021         case NDR_SAMR_CONNECT5:
4022                 fn = "_samr_Connect5";
4023                 break;
4024         }
4025
4026         DEBUG(5,("%s: %d\n", fn, __LINE__));
4027
4028         /* Access check */
4029
4030         if (!pipe_access_check(p)) {
4031                 DEBUG(3, ("access denied to %s\n", fn));
4032                 return NT_STATUS_ACCESS_DENIED;
4033         }
4034
4035         map_max_allowed_access(p->server_info->ptok,
4036                                &p->server_info->utok,
4037                                &des_access);
4038
4039         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
4040         se_map_generic(&des_access, &sam_generic_mapping);
4041
4042         nt_status = access_check_object(psd, p->server_info->ptok,
4043                                         SEC_PRIV_INVALID, SEC_PRIV_INVALID,
4044                                         0, des_access, &acc_granted, fn);
4045
4046         if ( !NT_STATUS_IS_OK(nt_status) )
4047                 return nt_status;
4048
4049         info = policy_handle_create(p, &hnd, acc_granted,
4050                                     struct samr_connect_info, &nt_status);
4051         if (!NT_STATUS_IS_OK(nt_status)) {
4052                 return nt_status;
4053         }
4054
4055         DEBUG(5,("%s: %d\n", fn, __LINE__));
4056
4057         *r->out.connect_handle = hnd;
4058         return NT_STATUS_OK;
4059 }
4060
4061 /****************************************************************
4062  _samr_Connect3
4063 ****************************************************************/
4064
4065 NTSTATUS _samr_Connect3(struct pipes_struct *p,
4066                         struct samr_Connect3 *r)
4067 {
4068         struct samr_Connect2 c;
4069
4070         c.in.system_name        = r->in.system_name;
4071         c.in.access_mask        = r->in.access_mask;
4072         c.out.connect_handle    = r->out.connect_handle;
4073
4074         return _samr_Connect2(p, &c);
4075 }
4076
4077 /*******************************************************************
4078  _samr_Connect4
4079  ********************************************************************/
4080
4081 NTSTATUS _samr_Connect4(struct pipes_struct *p,
4082                         struct samr_Connect4 *r)
4083 {
4084         struct samr_Connect2 c;
4085
4086         c.in.system_name        = r->in.system_name;
4087         c.in.access_mask        = r->in.access_mask;
4088         c.out.connect_handle    = r->out.connect_handle;
4089
4090         return _samr_Connect2(p, &c);
4091 }
4092
4093 /*******************************************************************
4094  _samr_Connect5
4095  ********************************************************************/
4096
4097 NTSTATUS _samr_Connect5(struct pipes_struct *p,
4098                         struct samr_Connect5 *r)
4099 {
4100         NTSTATUS status;
4101         struct samr_Connect2 c;
4102         struct samr_ConnectInfo1 info1;
4103
4104         info1.client_version = SAMR_CONNECT_AFTER_W2K;
4105         info1.unknown2 = 0;
4106
4107         c.in.system_name        = r->in.system_name;
4108         c.in.access_mask        = r->in.access_mask;
4109         c.out.connect_handle    = r->out.connect_handle;
4110
4111         *r->out.level_out = 1;
4112
4113         status = _samr_Connect2(p, &c);
4114         if (!NT_STATUS_IS_OK(status)) {
4115                 return status;
4116         }
4117
4118         r->out.info_out->info1 = info1;
4119
4120         return NT_STATUS_OK;
4121 }
4122
4123 /**********************************************************************
4124  _samr_LookupDomain
4125  **********************************************************************/
4126
4127 NTSTATUS _samr_LookupDomain(struct pipes_struct *p,
4128                             struct samr_LookupDomain *r)
4129 {
4130         NTSTATUS status;
4131         struct samr_connect_info *info;
4132         const char *domain_name;
4133         struct dom_sid *sid = NULL;
4134
4135         /* win9x user manager likes to use SAMR_ACCESS_ENUM_DOMAINS here.
4136            Reverted that change so we will work with RAS servers again */
4137
4138         info = policy_handle_find(p, r->in.connect_handle,
4139                                   SAMR_ACCESS_LOOKUP_DOMAIN, NULL,
4140                                   struct samr_connect_info,
4141                                   &status);
4142         if (!NT_STATUS_IS_OK(status)) {
4143                 return status;
4144         }
4145
4146         domain_name = r->in.domain_name->string;
4147         if (!domain_name) {
4148                 return NT_STATUS_INVALID_PARAMETER;
4149         }
4150
4151         sid = TALLOC_ZERO_P(p->mem_ctx, struct dom_sid2);
4152         if (!sid) {
4153                 return NT_STATUS_NO_MEMORY;
4154         }
4155
4156         if (strequal(domain_name, builtin_domain_name())) {
4157                 sid_copy(sid, &global_sid_Builtin);
4158         } else {
4159                 if (!secrets_fetch_domain_sid(domain_name, sid)) {
4160                         status = NT_STATUS_NO_SUCH_DOMAIN;
4161                 }
4162         }
4163
4164         DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name,
4165                  sid_string_dbg(sid)));
4166
4167         *r->out.sid = sid;
4168
4169         return status;
4170 }
4171
4172 /**********************************************************************
4173  _samr_EnumDomains
4174  **********************************************************************/
4175
4176 NTSTATUS _samr_EnumDomains(struct pipes_struct *p,
4177                            struct samr_EnumDomains *r)
4178 {
4179         NTSTATUS status;
4180         struct samr_connect_info *info;
4181         uint32_t num_entries = 2;
4182         struct samr_SamEntry *entry_array = NULL;
4183         struct samr_SamArray *sam;
4184
4185         info = policy_handle_find(p, r->in.connect_handle,
4186                                   SAMR_ACCESS_ENUM_DOMAINS, NULL,
4187                                   struct samr_connect_info, &status);
4188         if (!NT_STATUS_IS_OK(status)) {
4189                 return status;
4190         }
4191
4192         sam = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
4193         if (!sam) {
4194                 return NT_STATUS_NO_MEMORY;
4195         }
4196
4197         entry_array = TALLOC_ZERO_ARRAY(p->mem_ctx,
4198                                         struct samr_SamEntry,
4199                                         num_entries);
4200         if (!entry_array) {
4201                 return NT_STATUS_NO_MEMORY;
4202         }
4203
4204         entry_array[0].idx = 0;
4205         init_lsa_String(&entry_array[0].name, get_global_sam_name());
4206
4207         entry_array[1].idx = 1;
4208         init_lsa_String(&entry_array[1].name, "Builtin");
4209
4210         sam->count = num_entries;
4211         sam->entries = entry_array;
4212
4213         *r->out.sam = sam;
4214         *r->out.num_entries = num_entries;
4215
4216         return status;
4217 }
4218
4219 /*******************************************************************
4220  _samr_OpenAlias
4221  ********************************************************************/
4222
4223 NTSTATUS _samr_OpenAlias(struct pipes_struct *p,
4224                          struct samr_OpenAlias *r)
4225 {
4226         struct dom_sid sid;
4227         uint32 alias_rid = r->in.rid;
4228         struct samr_alias_info *ainfo;
4229         struct samr_domain_info *dinfo;
4230         struct security_descriptor *psd = NULL;
4231         uint32    acc_granted;
4232         uint32    des_access = r->in.access_mask;
4233         size_t    sd_size;
4234         NTSTATUS  status;
4235
4236         dinfo = policy_handle_find(p, r->in.domain_handle,
4237                                    SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
4238                                    struct samr_domain_info, &status);
4239         if (!NT_STATUS_IS_OK(status)) {
4240                 return status;
4241         }
4242
4243         /* append the alias' RID to it */
4244
4245         if (!sid_compose(&sid, &dinfo->sid, alias_rid))
4246                 return NT_STATUS_NO_SUCH_ALIAS;
4247
4248         /*check if access can be granted as requested by client. */
4249
4250         map_max_allowed_access(p->server_info->ptok,
4251                                &p->server_info->utok,
4252                                &des_access);
4253
4254         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &ali_generic_mapping, NULL, 0);
4255         se_map_generic(&des_access,&ali_generic_mapping);
4256
4257         status = access_check_object(psd, p->server_info->ptok,
4258                                      SEC_PRIV_ADD_USERS, SEC_PRIV_INVALID,
4259                                      GENERIC_RIGHTS_ALIAS_ALL_ACCESS,
4260                                      des_access, &acc_granted, "_samr_OpenAlias");
4261
4262         if ( !NT_STATUS_IS_OK(status) )
4263                 return status;
4264
4265         {
4266                 /* Check we actually have the requested alias */
4267                 enum lsa_SidType type;
4268                 bool result;
4269                 gid_t gid;
4270
4271                 become_root();
4272                 result = lookup_sid(NULL, &sid, NULL, NULL, &type);
4273                 unbecome_root();
4274
4275                 if (!result || (type != SID_NAME_ALIAS)) {
4276                         return NT_STATUS_NO_SUCH_ALIAS;
4277                 }
4278
4279                 /* make sure there is a mapping */
4280
4281                 if ( !sid_to_gid( &sid, &gid ) ) {
4282                         return NT_STATUS_NO_SUCH_ALIAS;
4283                 }
4284
4285         }
4286
4287         ainfo = policy_handle_create(p, r->out.alias_handle, acc_granted,
4288                                      struct samr_alias_info, &status);
4289         if (!NT_STATUS_IS_OK(status)) {
4290                 return status;
4291         }
4292         ainfo->sid = sid;
4293
4294         return NT_STATUS_OK;
4295 }
4296
4297 /*******************************************************************
4298  set_user_info_2
4299  ********************************************************************/
4300
4301 static NTSTATUS set_user_info_2(TALLOC_CTX *mem_ctx,
4302                                 struct samr_UserInfo2 *id2,
4303                                 struct samu *pwd)
4304 {
4305         if (id2 == NULL) {
4306                 DEBUG(5,("set_user_info_2: NULL id2\n"));
4307                 return NT_STATUS_ACCESS_DENIED;
4308         }
4309
4310         copy_id2_to_sam_passwd(pwd, id2);
4311
4312         return pdb_update_sam_account(pwd);
4313 }
4314
4315 /*******************************************************************
4316  set_user_info_4
4317  ********************************************************************/
4318
4319 static NTSTATUS set_user_info_4(TALLOC_CTX *mem_ctx,
4320                                 struct samr_UserInfo4 *id4,
4321                                 struct samu *pwd)
4322 {
4323         if (id4 == NULL) {
4324                 DEBUG(5,("set_user_info_2: NULL id4\n"));
4325                 return NT_STATUS_ACCESS_DENIED;
4326         }
4327
4328         copy_id4_to_sam_passwd(pwd, id4);
4329
4330         return pdb_update_sam_account(pwd);
4331 }
4332
4333 /*******************************************************************
4334  set_user_info_6
4335  ********************************************************************/
4336
4337 static NTSTATUS set_user_info_6(TALLOC_CTX *mem_ctx,
4338                                 struct samr_UserInfo6 *id6,
4339                                 struct samu *pwd)
4340 {
4341         if (id6 == NULL) {
4342                 DEBUG(5,("set_user_info_6: NULL id6\n"));
4343                 return NT_STATUS_ACCESS_DENIED;
4344         }
4345
4346         copy_id6_to_sam_passwd(pwd, id6);
4347
4348         return pdb_update_sam_account(pwd);
4349 }
4350
4351 /*******************************************************************
4352  set_user_info_7
4353  ********************************************************************/
4354
4355 static NTSTATUS set_user_info_7(TALLOC_CTX *mem_ctx,
4356                                 struct samr_UserInfo7 *id7,
4357                                 struct samu *pwd)
4358 {
4359         NTSTATUS rc;
4360
4361         if (id7 == NULL) {
4362                 DEBUG(5, ("set_user_info_7: NULL id7\n"));
4363                 return NT_STATUS_ACCESS_DENIED;
4364         }
4365
4366         if (!id7->account_name.string) {
4367                 DEBUG(5, ("set_user_info_7: failed to get new username\n"));
4368                 return NT_STATUS_ACCESS_DENIED;
4369         }
4370
4371         /* check to see if the new username already exists.  Note: we can't
4372            reliably lock all backends, so there is potentially the
4373            possibility that a user can be created in between this check and
4374            the rename.  The rename should fail, but may not get the
4375            exact same failure status code.  I think this is small enough
4376            of a window for this type of operation and the results are
4377            simply that the rename fails with a slightly different status
4378            code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
4379
4380         rc = can_create(mem_ctx, id7->account_name.string);
4381
4382         /* when there is nothing to change, we're done here */
4383         if (NT_STATUS_EQUAL(rc, NT_STATUS_USER_EXISTS) &&
4384             strequal(id7->account_name.string, pdb_get_username(pwd))) {
4385                 return NT_STATUS_OK;
4386         }
4387         if (!NT_STATUS_IS_OK(rc)) {
4388                 return rc;
4389         }
4390
4391         rc = pdb_rename_sam_account(pwd, id7->account_name.string);
4392
4393         return rc;
4394 }
4395
4396 /*******************************************************************
4397  set_user_info_8
4398  ********************************************************************/
4399
4400 static NTSTATUS set_user_info_8(TALLOC_CTX *mem_ctx,
4401                                 struct samr_UserInfo8 *id8,
4402                                 struct samu *pwd)
4403 {
4404         if (id8 == NULL) {
4405                 DEBUG(5,("set_user_info_8: NULL id8\n"));
4406                 return NT_STATUS_ACCESS_DENIED;
4407         }
4408
4409         copy_id8_to_sam_passwd(pwd, id8);
4410
4411         return pdb_update_sam_account(pwd);
4412 }
4413
4414 /*******************************************************************
4415  set_user_info_10
4416  ********************************************************************/
4417
4418 static NTSTATUS set_user_info_10(TALLOC_CTX *mem_ctx,
4419                                  struct samr_UserInfo10 *id10,
4420                                  struct samu *pwd)
4421 {
4422         if (id10 == NULL) {
4423                 DEBUG(5,("set_user_info_8: NULL id10\n"));
4424                 return NT_STATUS_ACCESS_DENIED;
4425         }
4426
4427         copy_id10_to_sam_passwd(pwd, id10);
4428
4429         return pdb_update_sam_account(pwd);
4430 }
4431
4432 /*******************************************************************
4433  set_user_info_11
4434  ********************************************************************/
4435
4436 static NTSTATUS set_user_info_11(TALLOC_CTX *mem_ctx,
4437                                  struct samr_UserInfo11 *id11,
4438                                  struct samu *pwd)
4439 {
4440         if (id11 == NULL) {
4441                 DEBUG(5,("set_user_info_11: NULL id11\n"));
4442                 return NT_STATUS_ACCESS_DENIED;
4443         }
4444
4445         copy_id11_to_sam_passwd(pwd, id11);
4446
4447         return pdb_update_sam_account(pwd);
4448 }
4449
4450 /*******************************************************************
4451  set_user_info_12
4452  ********************************************************************/
4453
4454 static NTSTATUS set_user_info_12(TALLOC_CTX *mem_ctx,
4455                                  struct samr_UserInfo12 *id12,
4456                                  struct samu *pwd)
4457 {
4458         if (id12 == NULL) {
4459                 DEBUG(5,("set_user_info_12: NULL id12\n"));
4460                 return NT_STATUS_ACCESS_DENIED;
4461         }
4462
4463         copy_id12_to_sam_passwd(pwd, id12);
4464
4465         return pdb_update_sam_account(pwd);
4466 }
4467
4468 /*******************************************************************
4469  set_user_info_13
4470  ********************************************************************/
4471
4472 static NTSTATUS set_user_info_13(TALLOC_CTX *mem_ctx,
4473                                  struct samr_UserInfo13 *id13,
4474                                  struct samu *pwd)
4475 {
4476         if (id13 == NULL) {
4477                 DEBUG(5,("set_user_info_13: NULL id13\n"));
4478                 return NT_STATUS_ACCESS_DENIED;
4479         }
4480
4481         copy_id13_to_sam_passwd(pwd, id13);
4482
4483         return pdb_update_sam_account(pwd);
4484 }
4485
4486 /*******************************************************************
4487  set_user_info_14
4488  ********************************************************************/
4489
4490 static NTSTATUS set_user_info_14(TALLOC_CTX *mem_ctx,
4491                                  struct samr_UserInfo14 *id14,
4492                                  struct samu *pwd)
4493 {
4494         if (id14 == NULL) {
4495                 DEBUG(5,("set_user_info_14: NULL id14\n"));
4496                 return NT_STATUS_ACCESS_DENIED;
4497         }
4498
4499         copy_id14_to_sam_passwd(pwd, id14);
4500
4501         return pdb_update_sam_account(pwd);
4502 }
4503
4504 /*******************************************************************
4505  set_user_info_16
4506  ********************************************************************/
4507
4508 static NTSTATUS set_user_info_16(TALLOC_CTX *mem_ctx,
4509                                  struct samr_UserInfo16 *id16,
4510                                  struct samu *pwd)
4511 {
4512         if (id16 == NULL) {
4513                 DEBUG(5,("set_user_info_16: NULL id16\n"));
4514                 return NT_STATUS_ACCESS_DENIED;
4515         }
4516
4517         copy_id16_to_sam_passwd(pwd, id16);
4518
4519         return pdb_update_sam_account(pwd);
4520 }
4521
4522 /*******************************************************************
4523  set_user_info_17
4524  ********************************************************************/
4525
4526 static NTSTATUS set_user_info_17(TALLOC_CTX *mem_ctx,
4527                                  struct samr_UserInfo17 *id17,
4528                                  struct samu *pwd)
4529 {
4530         if (id17 == NULL) {
4531                 DEBUG(5,("set_user_info_17: NULL id17\n"));
4532                 return NT_STATUS_ACCESS_DENIED;
4533         }
4534
4535         copy_id17_to_sam_passwd(pwd, id17);
4536
4537         return pdb_update_sam_account(pwd);
4538 }
4539
4540 /*******************************************************************
4541  set_user_info_18
4542  ********************************************************************/
4543
4544 static NTSTATUS set_user_info_18(struct samr_UserInfo18 *id18,
4545                                  TALLOC_CTX *mem_ctx,
4546                                  DATA_BLOB *session_key,
4547                                  struct samu *pwd)
4548 {
4549         if (id18 == NULL) {
4550                 DEBUG(2, ("set_user_info_18: id18 is NULL\n"));
4551                 return NT_STATUS_INVALID_PARAMETER;
4552         }
4553
4554         if (id18->nt_pwd_active || id18->lm_pwd_active) {
4555                 if (!session_key->length) {
4556                         return NT_STATUS_NO_USER_SESSION_KEY;
4557                 }
4558         }
4559
4560         if (id18->nt_pwd_active) {
4561
4562                 DATA_BLOB in, out;
4563
4564                 in = data_blob_const(id18->nt_pwd.hash, 16);
4565                 out = data_blob_talloc_zero(mem_ctx, 16);
4566
4567                 sess_crypt_blob(&out, &in, session_key, false);
4568
4569                 if (!pdb_set_nt_passwd(pwd, out.data, PDB_CHANGED)) {
4570                         return NT_STATUS_ACCESS_DENIED;
4571                 }
4572
4573                 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4574         }
4575
4576         if (id18->lm_pwd_active) {
4577
4578                 DATA_BLOB in, out;
4579
4580                 in = data_blob_const(id18->lm_pwd.hash, 16);
4581                 out = data_blob_talloc_zero(mem_ctx, 16);
4582
4583                 sess_crypt_blob(&out, &in, session_key, false);
4584
4585                 if (!pdb_set_lanman_passwd(pwd, out.data, PDB_CHANGED)) {
4586                         return NT_STATUS_ACCESS_DENIED;
4587                 }
4588
4589                 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4590         }
4591
4592         copy_id18_to_sam_passwd(pwd, id18);
4593
4594         return pdb_update_sam_account(pwd);
4595 }
4596
4597 /*******************************************************************
4598  set_user_info_20
4599  ********************************************************************/
4600
4601 static NTSTATUS set_user_info_20(TALLOC_CTX *mem_ctx,
4602                                  struct samr_UserInfo20 *id20,
4603                                  struct samu *pwd)
4604 {
4605         if (id20 == NULL) {
4606                 DEBUG(5,("set_user_info_20: NULL id20\n"));
4607                 return NT_STATUS_ACCESS_DENIED;
4608         }
4609
4610         copy_id20_to_sam_passwd(pwd, id20);
4611
4612         return pdb_update_sam_account(pwd);
4613 }
4614
4615 /*******************************************************************
4616  set_user_info_21
4617  ********************************************************************/
4618
4619 static NTSTATUS set_user_info_21(struct samr_UserInfo21 *id21,
4620                                  TALLOC_CTX *mem_ctx,
4621                                  DATA_BLOB *session_key,
4622                                  struct samu *pwd)
4623 {
4624         NTSTATUS status;
4625
4626         if (id21 == NULL) {
4627                 DEBUG(5, ("set_user_info_21: NULL id21\n"));
4628                 return NT_STATUS_INVALID_PARAMETER;
4629         }
4630
4631         if (id21->fields_present == 0) {
4632                 return NT_STATUS_INVALID_PARAMETER;
4633         }
4634
4635         if (id21->fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
4636                 return NT_STATUS_ACCESS_DENIED;
4637         }
4638
4639         if (id21->fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
4640                 if (id21->nt_password_set) {
4641                         DATA_BLOB in, out;
4642
4643                         if ((id21->nt_owf_password.length != 16) ||
4644                             (id21->nt_owf_password.size != 16)) {
4645                                 return NT_STATUS_INVALID_PARAMETER;
4646                         }
4647
4648                         if (!session_key->length) {
4649                                 return NT_STATUS_NO_USER_SESSION_KEY;
4650                         }
4651
4652                         in = data_blob_const(id21->nt_owf_password.array, 16);
4653                         out = data_blob_talloc_zero(mem_ctx, 16);
4654
4655                         sess_crypt_blob(&out, &in, session_key, false);
4656
4657                         pdb_set_nt_passwd(pwd, out.data, PDB_CHANGED);
4658                         pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4659                 }
4660         }
4661
4662         if (id21->fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
4663                 if (id21->lm_password_set) {
4664                         DATA_BLOB in, out;
4665
4666                         if ((id21->lm_owf_password.length != 16) ||
4667                             (id21->lm_owf_password.size != 16)) {
4668                                 return NT_STATUS_INVALID_PARAMETER;
4669                         }
4670
4671                         if (!session_key->length) {
4672                                 return NT_STATUS_NO_USER_SESSION_KEY;
4673                         }
4674
4675                         in = data_blob_const(id21->lm_owf_password.array, 16);
4676                         out = data_blob_talloc_zero(mem_ctx, 16);
4677
4678                         sess_crypt_blob(&out, &in, session_key, false);
4679
4680                         pdb_set_lanman_passwd(pwd, out.data, PDB_CHANGED);
4681                         pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4682                 }
4683         }
4684
4685         /* we need to separately check for an account rename first */
4686
4687         if (id21->account_name.string &&
4688             (!strequal(id21->account_name.string, pdb_get_username(pwd))))
4689         {
4690
4691                 /* check to see if the new username already exists.  Note: we can't
4692                    reliably lock all backends, so there is potentially the
4693                    possibility that a user can be created in between this check and
4694                    the rename.  The rename should fail, but may not get the
4695                    exact same failure status code.  I think this is small enough
4696                    of a window for this type of operation and the results are
4697                    simply that the rename fails with a slightly different status
4698                    code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
4699
4700                 status = can_create(mem_ctx, id21->account_name.string);
4701                 if (!NT_STATUS_IS_OK(status)) {
4702                         return status;
4703                 }
4704
4705                 status = pdb_rename_sam_account(pwd, id21->account_name.string);
4706
4707                 if (!NT_STATUS_IS_OK(status)) {
4708                         DEBUG(0,("set_user_info_21: failed to rename account: %s\n",
4709                                 nt_errstr(status)));
4710                         return status;
4711                 }
4712
4713                 /* set the new username so that later
4714                    functions can work on the new account */
4715                 pdb_set_username(pwd, id21->account_name.string, PDB_SET);
4716         }
4717
4718         copy_id21_to_sam_passwd("INFO_21", pwd, id21);
4719
4720         /*
4721          * The funny part about the previous two calls is
4722          * that pwd still has the password hashes from the
4723          * passdb entry.  These have not been updated from
4724          * id21.  I don't know if they need to be set.    --jerry
4725          */
4726
4727         if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
4728                 status = pdb_set_unix_primary_group(mem_ctx, pwd);
4729                 if ( !NT_STATUS_IS_OK(status) ) {
4730                         return status;
4731                 }
4732         }
4733
4734         /* Don't worry about writing out the user account since the
4735            primary group SID is generated solely from the user's Unix
4736            primary group. */
4737
4738         /* write the change out */
4739         if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4740                 return status;
4741         }
4742
4743         return NT_STATUS_OK;
4744 }
4745
4746 /*******************************************************************
4747  set_user_info_23
4748  ********************************************************************/
4749
4750 static NTSTATUS set_user_info_23(TALLOC_CTX *mem_ctx,
4751                                  struct samr_UserInfo23 *id23,
4752                                  const char *rhost,
4753                                  struct samu *pwd)
4754 {
4755         char *plaintext_buf = NULL;
4756         size_t len = 0;
4757         uint32_t acct_ctrl;
4758         NTSTATUS status;
4759
4760         if (id23 == NULL) {
4761                 DEBUG(5, ("set_user_info_23: NULL id23\n"));
4762                 return NT_STATUS_INVALID_PARAMETER;
4763         }
4764
4765         if (id23->info.fields_present == 0) {
4766                 return NT_STATUS_INVALID_PARAMETER;
4767         }
4768
4769         if (id23->info.fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
4770                 return NT_STATUS_ACCESS_DENIED;
4771         }
4772
4773         if ((id23->info.fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
4774             (id23->info.fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT)) {
4775
4776                 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
4777                           pdb_get_username(pwd)));
4778
4779                 if (!decode_pw_buffer(mem_ctx,
4780                                       id23->password.data,
4781                                       &plaintext_buf,
4782                                       &len,
4783                                       CH_UTF16)) {
4784                         return NT_STATUS_WRONG_PASSWORD;
4785                 }
4786
4787                 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
4788                         return NT_STATUS_ACCESS_DENIED;
4789                 }
4790         }
4791
4792         copy_id23_to_sam_passwd(pwd, id23);
4793
4794         acct_ctrl = pdb_get_acct_ctrl(pwd);
4795
4796         /* if it's a trust account, don't update /etc/passwd */
4797         if (    ( (acct_ctrl &  ACB_DOMTRUST) == ACB_DOMTRUST ) ||
4798                 ( (acct_ctrl &  ACB_WSTRUST) ==  ACB_WSTRUST) ||
4799                 ( (acct_ctrl &  ACB_SVRTRUST) ==  ACB_SVRTRUST) ) {
4800                 DEBUG(5, ("Changing trust account.  Not updating /etc/passwd\n"));
4801         } else if (plaintext_buf) {
4802                 /* update the UNIX password */
4803                 if (lp_unix_password_sync() ) {
4804                         struct passwd *passwd;
4805                         if (pdb_get_username(pwd) == NULL) {
4806                                 DEBUG(1, ("chgpasswd: User without name???\n"));
4807                                 return NT_STATUS_ACCESS_DENIED;
4808                         }
4809
4810                         passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
4811                         if (passwd == NULL) {
4812                                 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
4813                         }
4814
4815                         if(!chgpasswd(pdb_get_username(pwd), rhost,
4816                                       passwd, "", plaintext_buf, True)) {
4817                                 return NT_STATUS_ACCESS_DENIED;
4818                         }
4819                         TALLOC_FREE(passwd);
4820                 }
4821         }
4822
4823         if (plaintext_buf) {
4824                 memset(plaintext_buf, '\0', strlen(plaintext_buf));
4825         }
4826
4827         if (IS_SAM_CHANGED(pwd, PDB_GROUPSID) &&
4828             (!NT_STATUS_IS_OK(status =  pdb_set_unix_primary_group(mem_ctx,
4829                                                                    pwd)))) {
4830                 return status;
4831         }
4832
4833         if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4834                 return status;
4835         }
4836
4837         return NT_STATUS_OK;
4838 }
4839
4840 /*******************************************************************
4841  set_user_info_pw
4842  ********************************************************************/
4843
4844 static bool set_user_info_pw(uint8 *pass, const char *rhost, struct samu *pwd)
4845 {
4846         size_t len = 0;
4847         char *plaintext_buf = NULL;
4848         uint32 acct_ctrl;
4849
4850         DEBUG(5, ("Attempting administrator password change for user %s\n",
4851                   pdb_get_username(pwd)));
4852
4853         acct_ctrl = pdb_get_acct_ctrl(pwd);
4854
4855         if (!decode_pw_buffer(talloc_tos(),
4856                                 pass,
4857                                 &plaintext_buf,
4858                                 &len,
4859                                 CH_UTF16)) {
4860                 return False;
4861         }
4862
4863         if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
4864                 return False;
4865         }
4866
4867         /* if it's a trust account, don't update /etc/passwd */
4868         if ( ( (acct_ctrl &  ACB_DOMTRUST) == ACB_DOMTRUST ) ||
4869                 ( (acct_ctrl &  ACB_WSTRUST) ==  ACB_WSTRUST) ||
4870                 ( (acct_ctrl &  ACB_SVRTRUST) ==  ACB_SVRTRUST) ) {
4871                 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
4872         } else {
4873                 /* update the UNIX password */
4874                 if (lp_unix_password_sync()) {
4875                         struct passwd *passwd;
4876
4877                         if (pdb_get_username(pwd) == NULL) {
4878                                 DEBUG(1, ("chgpasswd: User without name???\n"));
4879                                 return False;
4880                         }
4881
4882                         passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
4883                         if (passwd == NULL) {
4884                                 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
4885                         }
4886
4887                         if(!chgpasswd(pdb_get_username(pwd), rhost, passwd,
4888                                       "", plaintext_buf, True)) {
4889                                 return False;
4890                         }
4891                         TALLOC_FREE(passwd);
4892                 }
4893         }
4894
4895         memset(plaintext_buf, '\0', strlen(plaintext_buf));
4896
4897         DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
4898
4899         return True;
4900 }
4901
4902 /*******************************************************************
4903  set_user_info_24
4904  ********************************************************************/
4905
4906 static NTSTATUS set_user_info_24(TALLOC_CTX *mem_ctx,
4907                                  const char *rhost,
4908                                  struct samr_UserInfo24 *id24,
4909                                  struct samu *pwd)
4910 {
4911         NTSTATUS status;
4912
4913         if (id24 == NULL) {
4914                 DEBUG(5, ("set_user_info_24: NULL id24\n"));
4915                 return NT_STATUS_INVALID_PARAMETER;
4916         }
4917
4918         if (!set_user_info_pw(id24->password.data, rhost, pwd)) {
4919                 return NT_STATUS_WRONG_PASSWORD;
4920         }
4921
4922         copy_id24_to_sam_passwd(pwd, id24);
4923
4924         status = pdb_update_sam_account(pwd);
4925         if (!NT_STATUS_IS_OK(status)) {
4926                 return status;
4927         }
4928
4929         return NT_STATUS_OK;
4930 }
4931
4932 /*******************************************************************
4933  set_user_info_25
4934  ********************************************************************/
4935
4936 static NTSTATUS set_user_info_25(TALLOC_CTX *mem_ctx,
4937                                  const char *rhost,
4938                                  struct samr_UserInfo25 *id25,
4939                                  struct samu *pwd)
4940 {
4941         NTSTATUS status;
4942
4943         if (id25 == NULL) {
4944                 DEBUG(5, ("set_user_info_25: NULL id25\n"));
4945                 return NT_STATUS_INVALID_PARAMETER;
4946         }
4947
4948         if (id25->info.fields_present == 0) {
4949                 return NT_STATUS_INVALID_PARAMETER;
4950         }
4951
4952         if (id25->info.fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
4953                 return NT_STATUS_ACCESS_DENIED;
4954         }
4955
4956         if ((id25->info.fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
4957             (id25->info.fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT)) {
4958
4959                 if (!set_user_info_pw(id25->password.data, rhost, pwd)) {
4960                         return NT_STATUS_WRONG_PASSWORD;
4961                 }
4962         }
4963
4964         copy_id25_to_sam_passwd(pwd, id25);
4965
4966         /* write the change out */
4967         if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4968                 return status;
4969         }
4970
4971         /*
4972          * We need to "pdb_update_sam_account" before the unix primary group
4973          * is set, because the idealx scripts would also change the
4974          * sambaPrimaryGroupSid using the ldap replace method. pdb_ldap uses
4975          * the delete explicit / add explicit, which would then fail to find
4976          * the previous primaryGroupSid value.
4977          */
4978
4979         if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
4980                 status = pdb_set_unix_primary_group(mem_ctx, pwd);
4981                 if ( !NT_STATUS_IS_OK(status) ) {
4982                         return status;
4983                 }
4984         }
4985
4986         return NT_STATUS_OK;
4987 }
4988
4989 /*******************************************************************
4990  set_user_info_26
4991  ********************************************************************/
4992
4993 static NTSTATUS set_user_info_26(TALLOC_CTX *mem_ctx,
4994                                  const char *rhost,
4995                                  struct samr_UserInfo26 *id26,
4996                                  struct samu *pwd)
4997 {
4998         NTSTATUS status;
4999
5000         if (id26 == NULL) {
5001                 DEBUG(5, ("set_user_info_26: NULL id26\n"));
5002                 return NT_STATUS_INVALID_PARAMETER;
5003         }
5004
5005         if (!set_user_info_pw(id26->password.data, rhost, pwd)) {
5006                 return NT_STATUS_WRONG_PASSWORD;
5007         }
5008
5009         copy_id26_to_sam_passwd(pwd, id26);
5010
5011         status = pdb_update_sam_account(pwd);
5012         if (!NT_STATUS_IS_OK(status)) {
5013                 return status;
5014         }
5015
5016         return NT_STATUS_OK;
5017 }
5018
5019 /*************************************************************
5020 **************************************************************/
5021
5022 static uint32_t samr_set_user_info_map_fields_to_access_mask(uint32_t fields)
5023 {
5024         uint32_t acc_required = 0;
5025
5026         /* USER_ALL_USERNAME */
5027         if (fields & SAMR_FIELD_ACCOUNT_NAME)
5028                 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5029         /* USER_ALL_FULLNAME */
5030         if (fields & SAMR_FIELD_FULL_NAME)
5031                 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5032         /* USER_ALL_PRIMARYGROUPID */
5033         if (fields & SAMR_FIELD_PRIMARY_GID)
5034                 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5035         /* USER_ALL_HOMEDIRECTORY */
5036         if (fields & SAMR_FIELD_HOME_DIRECTORY)
5037                 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5038         /* USER_ALL_HOMEDIRECTORYDRIVE */
5039         if (fields & SAMR_FIELD_HOME_DRIVE)
5040                 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5041         /* USER_ALL_SCRIPTPATH */
5042         if (fields & SAMR_FIELD_LOGON_SCRIPT)
5043                 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5044         /* USER_ALL_PROFILEPATH */
5045         if (fields & SAMR_FIELD_PROFILE_PATH)
5046                 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5047         /* USER_ALL_ADMINCOMMENT */
5048         if (fields & SAMR_FIELD_COMMENT)
5049                 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5050         /* USER_ALL_WORKSTATIONS */
5051         if (fields & SAMR_FIELD_WORKSTATIONS)
5052                 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5053         /* USER_ALL_LOGONHOURS */
5054         if (fields & SAMR_FIELD_LOGON_HOURS)
5055                 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5056         /* USER_ALL_ACCOUNTEXPIRES */
5057         if (fields & SAMR_FIELD_ACCT_EXPIRY)
5058                 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5059         /* USER_ALL_USERACCOUNTCONTROL */
5060         if (fields & SAMR_FIELD_ACCT_FLAGS)
5061                 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5062         /* USER_ALL_PARAMETERS */
5063         if (fields & SAMR_FIELD_PARAMETERS)
5064                 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5065         /* USER_ALL_USERCOMMENT */
5066         if (fields & SAMR_FIELD_COMMENT)
5067                 acc_required |= SAMR_USER_ACCESS_SET_LOC_COM;
5068         /* USER_ALL_COUNTRYCODE */
5069         if (fields & SAMR_FIELD_COUNTRY_CODE)
5070                 acc_required |= SAMR_USER_ACCESS_SET_LOC_COM;
5071         /* USER_ALL_CODEPAGE */
5072         if (fields & SAMR_FIELD_CODE_PAGE)
5073                 acc_required |= SAMR_USER_ACCESS_SET_LOC_COM;
5074         /* USER_ALL_NTPASSWORDPRESENT */
5075         if (fields & SAMR_FIELD_NT_PASSWORD_PRESENT)
5076                 acc_required |= SAMR_USER_ACCESS_SET_PASSWORD;
5077         /* USER_ALL_LMPASSWORDPRESENT */
5078         if (fields & SAMR_FIELD_LM_PASSWORD_PRESENT)
5079                 acc_required |= SAMR_USER_ACCESS_SET_PASSWORD;
5080         /* USER_ALL_PASSWORDEXPIRED */
5081         if (fields & SAMR_FIELD_EXPIRED_FLAG)
5082                 acc_required |= SAMR_USER_ACCESS_SET_PASSWORD;
5083
5084         return acc_required;
5085 }
5086
5087 /*******************************************************************
5088  samr_SetUserInfo
5089  ********************************************************************/
5090
5091 NTSTATUS _samr_SetUserInfo(struct pipes_struct *p,
5092                            struct samr_SetUserInfo *r)
5093 {
5094         struct samr_user_info *uinfo;
5095         NTSTATUS status;
5096         struct samu *pwd = NULL;
5097         union samr_UserInfo *info = r->in.info;
5098         uint32_t acc_required = 0;
5099         uint32_t fields = 0;
5100         bool ret;
5101
5102         DEBUG(5,("_samr_SetUserInfo: %d\n", __LINE__));
5103
5104         /* This is tricky.  A WinXP domain join sets
5105           (SAMR_USER_ACCESS_SET_PASSWORD|SAMR_USER_ACCESS_SET_ATTRIBUTES|SAMR_USER_ACCESS_GET_ATTRIBUTES)
5106           The MMC lusrmgr plugin includes these perms and more in the SamrOpenUser().  But the
5107           standard Win32 API calls just ask for SAMR_USER_ACCESS_SET_PASSWORD in the SamrOpenUser().
5108           This should be enough for levels 18, 24, 25,& 26.  Info level 23 can set more so
5109           we'll use the set from the WinXP join as the basis. */
5110
5111         switch (r->in.level) {
5112         case 2: /* UserPreferencesInformation */
5113                 /* USER_WRITE_ACCOUNT | USER_WRITE_PREFERENCES */
5114                 acc_required = SAMR_USER_ACCESS_SET_ATTRIBUTES | SAMR_USER_ACCESS_SET_LOC_COM;
5115                 break;
5116         case 4: /* UserLogonHoursInformation */
5117         case 6: /* UserNameInformation */
5118         case 7: /* UserAccountNameInformation */
5119         case 8: /* UserFullNameInformation */
5120         case 9: /* UserPrimaryGroupInformation */
5121         case 10: /* UserHomeInformation */
5122         case 11: /* UserScriptInformation */
5123         case 12: /* UserProfileInformation */
5124         case 13: /* UserAdminCommentInformation */
5125         case 14: /* UserWorkStationsInformation */
5126         case 16: /* UserControlInformation */
5127         case 17: /* UserExpiresInformation */
5128         case 20: /* UserParametersInformation */
5129                 /* USER_WRITE_ACCOUNT */
5130                 acc_required = SAMR_USER_ACCESS_SET_ATTRIBUTES;
5131                 break;
5132         case 18: /* UserInternal1Information */
5133                 /* FIXME: gd, this is a guess */
5134                 acc_required = SAMR_USER_ACCESS_SET_PASSWORD;
5135                 break;
5136         case 21: /* UserAllInformation */
5137                 fields = info->info21.fields_present;
5138                 acc_required = samr_set_user_info_map_fields_to_access_mask(fields);
5139                 break;
5140         case 23: /* UserInternal4Information */
5141                 fields = info->info23.info.fields_present;
5142                 acc_required = samr_set_user_info_map_fields_to_access_mask(fields);
5143                 break;
5144         case 25: /* UserInternal4InformationNew */
5145                 fields = info->info25.info.fields_present;
5146                 acc_required = samr_set_user_info_map_fields_to_access_mask(fields);
5147                 break;
5148         case 24: /* UserInternal5Information */
5149         case 26: /* UserInternal5InformationNew */
5150                 acc_required = SAMR_USER_ACCESS_SET_PASSWORD;
5151                 break;
5152         default:
5153                 return NT_STATUS_INVALID_INFO_CLASS;
5154         }
5155
5156         uinfo = policy_handle_find(p, r->in.user_handle, acc_required, NULL,
5157                                    struct samr_user_info, &status);
5158         if (!NT_STATUS_IS_OK(status)) {
5159                 return status;
5160         }
5161
5162         DEBUG(5, ("_samr_SetUserInfo: sid:%s, level:%d\n",
5163                   sid_string_dbg(&uinfo->sid), r->in.level));
5164
5165         if (info == NULL) {
5166                 DEBUG(5, ("_samr_SetUserInfo: NULL info level\n"));
5167                 return NT_STATUS_INVALID_INFO_CLASS;
5168         }
5169
5170         if (!(pwd = samu_new(NULL))) {
5171                 return NT_STATUS_NO_MEMORY;
5172         }
5173
5174         become_root();
5175         ret = pdb_getsampwsid(pwd, &uinfo->sid);
5176         unbecome_root();
5177
5178         if (!ret) {
5179                 TALLOC_FREE(pwd);
5180                 return NT_STATUS_NO_SUCH_USER;
5181         }
5182
5183         /* ================ BEGIN Privilege BLOCK ================ */
5184
5185         become_root();
5186
5187         /* ok!  user info levels (lots: see MSDEV help), off we go... */
5188
5189         switch (r->in.level) {
5190
5191                 case 2:
5192                         status = set_user_info_2(p->mem_ctx,
5193                                                  &info->info2, pwd);
5194                         break;
5195
5196                 case 4:
5197                         status = set_user_info_4(p->mem_ctx,
5198                                                  &info->info4, pwd);
5199                         break;
5200
5201                 case 6:
5202                         status = set_user_info_6(p->mem_ctx,
5203                                                  &info->info6, pwd);
5204                         break;
5205
5206                 case 7:
5207                         status = set_user_info_7(p->mem_ctx,
5208                                                  &info->info7, pwd);
5209                         break;
5210
5211                 case 8:
5212                         status = set_user_info_8(p->mem_ctx,
5213                                                  &info->info8, pwd);
5214                         break;
5215
5216                 case 10:
5217                         status = set_user_info_10(p->mem_ctx,
5218                                                   &info->info10, pwd);
5219                         break;
5220
5221                 case 11:
5222                         status = set_user_info_11(p->mem_ctx,
5223                                                   &info->info11, pwd);
5224                         break;
5225
5226                 case 12:
5227                         status = set_user_info_12(p->mem_ctx,
5228                                                   &info->info12, pwd);
5229                         break;
5230
5231                 case 13:
5232                         status = set_user_info_13(p->mem_ctx,
5233                                                   &info->info13, pwd);
5234                         break;
5235
5236                 case 14:
5237                         status = set_user_info_14(p->mem_ctx,
5238                                                   &info->info14, pwd);
5239                         break;
5240
5241                 case 16:
5242                         status = set_user_info_16(p->mem_ctx,
5243                                                   &info->info16, pwd);
5244                         break;
5245
5246                 case 17:
5247                         status = set_user_info_17(p->mem_ctx,
5248                                                   &info->info17, pwd);
5249                         break;
5250
5251                 case 18:
5252                         /* Used by AS/U JRA. */
5253                         status = set_user_info_18(&info->info18,
5254                                                   p->mem_ctx,
5255                                                   &p->server_info->user_session_key,
5256                                                   pwd);
5257                         break;
5258
5259                 case 20:
5260                         status = set_user_info_20(p->mem_ctx,
5261                                                   &info->info20, pwd);
5262                         break;
5263
5264                 case 21:
5265                         status = set_user_info_21(&info->info21,
5266                                                   p->mem_ctx,
5267                                                   &p->server_info->user_session_key,
5268                                                   pwd);
5269                         break;
5270
5271                 case 23:
5272                         if (!p->server_info->user_session_key.length) {
5273                                 status = NT_STATUS_NO_USER_SESSION_KEY;
5274                         }
5275                         arcfour_crypt_blob(info->info23.password.data, 516,
5276                                            &p->server_info->user_session_key);
5277
5278                         dump_data(100, info->info23.password.data, 516);
5279
5280                         status = set_user_info_23(p->mem_ctx,
5281                                                   &info->info23,
5282                                                   p->client_id->name,
5283                                                   pwd);
5284                         break;
5285
5286                 case 24:
5287                         if (!p->server_info->user_session_key.length) {
5288                                 status = NT_STATUS_NO_USER_SESSION_KEY;
5289                         }
5290                         arcfour_crypt_blob(info->info24.password.data,
5291                                            516,
5292                                            &p->server_info->user_session_key);
5293
5294                         dump_data(100, info->info24.password.data, 516);
5295
5296                         status = set_user_info_24(p->mem_ctx,
5297                                                   p->client_id->name,
5298                                                   &info->info24, pwd);
5299                         break;
5300
5301                 case 25:
5302                         if (!p->server_info->user_session_key.length) {
5303                                 status = NT_STATUS_NO_USER_SESSION_KEY;
5304                         }
5305                         encode_or_decode_arc4_passwd_buffer(
5306                                 info->info25.password.data,
5307                                 &p->server_info->user_session_key);
5308
5309                         dump_data(100, info->info25.password.data, 532);
5310
5311                         status = set_user_info_25(p->mem_ctx,
5312                                                   p->client_id->name,
5313                                                   &info->info25, pwd);
5314                         break;
5315
5316                 case 26:
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->info26.password.data,
5322                                 &p->server_info->user_session_key);
5323
5324                         dump_data(100, info->info26.password.data, 516);
5325
5326                         status = set_user_info_26(p->mem_ctx,
5327                                                   p->client_id->name,
5328                                                   &info->info26, pwd);
5329                         break;
5330
5331                 default:
5332                         status = NT_STATUS_INVALID_INFO_CLASS;
5333         }
5334
5335         TALLOC_FREE(pwd);
5336
5337         unbecome_root();
5338
5339         /* ================ END Privilege BLOCK ================ */
5340
5341         if (NT_STATUS_IS_OK(status)) {
5342                 force_flush_samr_cache(&uinfo->sid);
5343         }
5344
5345         return status;
5346 }
5347
5348 /*******************************************************************
5349  _samr_SetUserInfo2
5350  ********************************************************************/
5351
5352 NTSTATUS _samr_SetUserInfo2(struct pipes_struct *p,
5353                             struct samr_SetUserInfo2 *r)
5354 {
5355         struct samr_SetUserInfo q;
5356
5357         q.in.user_handle        = r->in.user_handle;
5358         q.in.level              = r->in.level;
5359         q.in.info               = r->in.info;
5360
5361         return _samr_SetUserInfo(p, &q);
5362 }
5363
5364 /*********************************************************************
5365  _samr_GetAliasMembership
5366 *********************************************************************/
5367
5368 NTSTATUS _samr_GetAliasMembership(struct pipes_struct *p,
5369                                   struct samr_GetAliasMembership *r)
5370 {
5371         size_t num_alias_rids;
5372         uint32 *alias_rids;
5373         struct samr_domain_info *dinfo;
5374         size_t i;
5375
5376         NTSTATUS status;
5377
5378         struct dom_sid *members;
5379
5380         DEBUG(5,("_samr_GetAliasMembership: %d\n", __LINE__));
5381
5382         dinfo = policy_handle_find(p, r->in.domain_handle,
5383                                    SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS
5384                                    | SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
5385                                    struct samr_domain_info, &status);
5386         if (!NT_STATUS_IS_OK(status)) {
5387                 return status;
5388         }
5389
5390         if (!sid_check_is_domain(&dinfo->sid) &&
5391             !sid_check_is_builtin(&dinfo->sid))
5392                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
5393
5394         if (r->in.sids->num_sids) {
5395                 members = TALLOC_ARRAY(p->mem_ctx, struct dom_sid, r->in.sids->num_sids);
5396
5397                 if (members == NULL)
5398                         return NT_STATUS_NO_MEMORY;
5399         } else {
5400                 members = NULL;
5401         }
5402
5403         for (i=0; i<r->in.sids->num_sids; i++)
5404                 sid_copy(&members[i], r->in.sids->sids[i].sid);
5405
5406         alias_rids = NULL;
5407         num_alias_rids = 0;
5408
5409         become_root();
5410         status = pdb_enum_alias_memberships(p->mem_ctx, &dinfo->sid, members,
5411                                             r->in.sids->num_sids,
5412                                             &alias_rids, &num_alias_rids);
5413         unbecome_root();
5414
5415         if (!NT_STATUS_IS_OK(status)) {
5416                 return status;
5417         }
5418
5419         r->out.rids->count = num_alias_rids;
5420         r->out.rids->ids = alias_rids;
5421
5422         if (r->out.rids->ids == NULL) {
5423                 /* Windows domain clients don't accept a NULL ptr here */
5424                 r->out.rids->ids = talloc_zero(p->mem_ctx, uint32_t);
5425         }
5426         if (r->out.rids->ids == NULL) {
5427                 return NT_STATUS_NO_MEMORY;
5428         }
5429
5430         return NT_STATUS_OK;
5431 }
5432
5433 /*********************************************************************
5434  _samr_GetMembersInAlias
5435 *********************************************************************/
5436
5437 NTSTATUS _samr_GetMembersInAlias(struct pipes_struct *p,
5438                                  struct samr_GetMembersInAlias *r)
5439 {
5440         struct samr_alias_info *ainfo;
5441         NTSTATUS status;
5442         size_t i;
5443         size_t num_sids = 0;
5444         struct lsa_SidPtr *sids = NULL;
5445         struct dom_sid *pdb_sids = NULL;
5446
5447         ainfo = policy_handle_find(p, r->in.alias_handle,
5448                                    SAMR_ALIAS_ACCESS_GET_MEMBERS, NULL,
5449                                    struct samr_alias_info, &status);
5450         if (!NT_STATUS_IS_OK(status)) {
5451                 return status;
5452         }
5453
5454         DEBUG(10, ("sid is %s\n", sid_string_dbg(&ainfo->sid)));
5455
5456         become_root();
5457         status = pdb_enum_aliasmem(&ainfo->sid, talloc_tos(), &pdb_sids,
5458                                    &num_sids);
5459         unbecome_root();
5460
5461         if (!NT_STATUS_IS_OK(status)) {
5462                 return status;
5463         }
5464
5465         if (num_sids) {
5466                 sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_SidPtr, num_sids);
5467                 if (sids == NULL) {
5468                         TALLOC_FREE(pdb_sids);
5469                         return NT_STATUS_NO_MEMORY;
5470                 }
5471         }
5472
5473         for (i = 0; i < num_sids; i++) {
5474                 sids[i].sid = dom_sid_dup(p->mem_ctx, &pdb_sids[i]);
5475                 if (!sids[i].sid) {
5476                         TALLOC_FREE(pdb_sids);
5477                         return NT_STATUS_NO_MEMORY;
5478                 }
5479         }
5480
5481         r->out.sids->num_sids = num_sids;
5482         r->out.sids->sids = sids;
5483
5484         TALLOC_FREE(pdb_sids);
5485
5486         return NT_STATUS_OK;
5487 }
5488
5489 /*********************************************************************
5490  _samr_QueryGroupMember
5491 *********************************************************************/
5492
5493 NTSTATUS _samr_QueryGroupMember(struct pipes_struct *p,
5494                                 struct samr_QueryGroupMember *r)
5495 {
5496         struct samr_group_info *ginfo;
5497         size_t i, num_members;
5498
5499         uint32 *rid=NULL;
5500         uint32 *attr=NULL;
5501
5502         NTSTATUS status;
5503         struct samr_RidTypeArray *rids = NULL;
5504
5505         ginfo = policy_handle_find(p, r->in.group_handle,
5506                                    SAMR_GROUP_ACCESS_GET_MEMBERS, NULL,
5507                                    struct samr_group_info, &status);
5508         if (!NT_STATUS_IS_OK(status)) {
5509                 return status;
5510         }
5511
5512         rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidTypeArray);
5513         if (!rids) {
5514                 return NT_STATUS_NO_MEMORY;
5515         }
5516
5517         DEBUG(10, ("sid is %s\n", sid_string_dbg(&ginfo->sid)));
5518
5519         if (!sid_check_is_in_our_domain(&ginfo->sid)) {
5520                 DEBUG(3, ("sid %s is not in our domain\n",
5521                           sid_string_dbg(&ginfo->sid)));
5522                 return NT_STATUS_NO_SUCH_GROUP;
5523         }
5524
5525         DEBUG(10, ("lookup on Domain SID\n"));
5526
5527         become_root();
5528         status = pdb_enum_group_members(p->mem_ctx, &ginfo->sid,
5529                                         &rid, &num_members);
5530         unbecome_root();
5531
5532         if (!NT_STATUS_IS_OK(status))
5533                 return status;
5534
5535         if (num_members) {
5536                 attr=TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_members);
5537                 if (attr == NULL) {
5538                         return NT_STATUS_NO_MEMORY;
5539                 }
5540         } else {
5541                 attr = NULL;
5542         }
5543
5544         for (i=0; i<num_members; i++) {
5545                 attr[i] = SE_GROUP_MANDATORY |
5546                           SE_GROUP_ENABLED_BY_DEFAULT |
5547                           SE_GROUP_ENABLED;
5548         }
5549
5550         rids->count = num_members;
5551         rids->types = attr;
5552         rids->rids = rid;
5553
5554         *r->out.rids = rids;
5555
5556         return NT_STATUS_OK;
5557 }
5558
5559 /*********************************************************************
5560  _samr_AddAliasMember
5561 *********************************************************************/
5562
5563 NTSTATUS _samr_AddAliasMember(struct pipes_struct *p,
5564                               struct samr_AddAliasMember *r)
5565 {
5566         struct samr_alias_info *ainfo;
5567         NTSTATUS status;
5568
5569         ainfo = policy_handle_find(p, r->in.alias_handle,
5570                                    SAMR_ALIAS_ACCESS_ADD_MEMBER, NULL,
5571                                    struct samr_alias_info, &status);
5572         if (!NT_STATUS_IS_OK(status)) {
5573                 return status;
5574         }
5575
5576         DEBUG(10, ("sid is %s\n", sid_string_dbg(&ainfo->sid)));
5577
5578         /******** BEGIN SeAddUsers BLOCK *********/
5579
5580         become_root();
5581         status = pdb_add_aliasmem(&ainfo->sid, r->in.sid);
5582         unbecome_root();
5583
5584         /******** END SeAddUsers BLOCK *********/
5585
5586         if (NT_STATUS_IS_OK(status)) {
5587                 force_flush_samr_cache(&ainfo->sid);
5588         }
5589
5590         return status;
5591 }
5592
5593 /*********************************************************************
5594  _samr_DeleteAliasMember
5595 *********************************************************************/
5596
5597 NTSTATUS _samr_DeleteAliasMember(struct pipes_struct *p,
5598                                  struct samr_DeleteAliasMember *r)
5599 {
5600         struct samr_alias_info *ainfo;
5601         NTSTATUS status;
5602
5603         ainfo = policy_handle_find(p, r->in.alias_handle,
5604                                    SAMR_ALIAS_ACCESS_REMOVE_MEMBER, NULL,
5605                                    struct samr_alias_info, &status);
5606         if (!NT_STATUS_IS_OK(status)) {
5607                 return status;
5608         }
5609
5610         DEBUG(10, ("_samr_del_aliasmem:sid is %s\n",
5611                    sid_string_dbg(&ainfo->sid)));
5612
5613         /******** BEGIN SeAddUsers BLOCK *********/
5614
5615         become_root();
5616         status = pdb_del_aliasmem(&ainfo->sid, r->in.sid);
5617         unbecome_root();
5618
5619         /******** END SeAddUsers BLOCK *********/
5620
5621         if (NT_STATUS_IS_OK(status)) {
5622                 force_flush_samr_cache(&ainfo->sid);
5623         }
5624
5625         return status;
5626 }
5627
5628 /*********************************************************************
5629  _samr_AddGroupMember
5630 *********************************************************************/
5631
5632 NTSTATUS _samr_AddGroupMember(struct pipes_struct *p,
5633                               struct samr_AddGroupMember *r)
5634 {
5635         struct samr_group_info *ginfo;
5636         NTSTATUS status;
5637         uint32 group_rid;
5638
5639         ginfo = policy_handle_find(p, r->in.group_handle,
5640                                    SAMR_GROUP_ACCESS_ADD_MEMBER, NULL,
5641                                    struct samr_group_info, &status);
5642         if (!NT_STATUS_IS_OK(status)) {
5643                 return status;
5644         }
5645
5646         DEBUG(10, ("sid is %s\n", sid_string_dbg(&ginfo->sid)));
5647
5648         if (!sid_peek_check_rid(get_global_sam_sid(), &ginfo->sid,
5649                                 &group_rid)) {
5650                 return NT_STATUS_INVALID_HANDLE;
5651         }
5652
5653         /******** BEGIN SeAddUsers BLOCK *********/
5654
5655         become_root();
5656         status = pdb_add_groupmem(p->mem_ctx, group_rid, r->in.rid);
5657         unbecome_root();
5658
5659         /******** END SeAddUsers BLOCK *********/
5660
5661         force_flush_samr_cache(&ginfo->sid);
5662
5663         return status;
5664 }
5665
5666 /*********************************************************************
5667  _samr_DeleteGroupMember
5668 *********************************************************************/
5669
5670 NTSTATUS _samr_DeleteGroupMember(struct pipes_struct *p,
5671                                  struct samr_DeleteGroupMember *r)
5672
5673 {
5674         struct samr_group_info *ginfo;
5675         NTSTATUS status;
5676         uint32 group_rid;
5677
5678         /*
5679          * delete the group member named r->in.rid
5680          * who is a member of the sid associated with the handle
5681          * the rid is a user's rid as the group is a domain group.
5682          */
5683
5684         ginfo = policy_handle_find(p, r->in.group_handle,
5685                                    SAMR_GROUP_ACCESS_REMOVE_MEMBER, NULL,
5686                                    struct samr_group_info, &status);
5687         if (!NT_STATUS_IS_OK(status)) {
5688                 return status;
5689         }
5690
5691         if (!sid_peek_check_rid(get_global_sam_sid(), &ginfo->sid,
5692                                 &group_rid)) {
5693                 return NT_STATUS_INVALID_HANDLE;
5694         }
5695
5696         /******** BEGIN SeAddUsers BLOCK *********/
5697
5698         become_root();
5699         status = pdb_del_groupmem(p->mem_ctx, group_rid, r->in.rid);
5700         unbecome_root();
5701
5702         /******** END SeAddUsers BLOCK *********/
5703
5704         force_flush_samr_cache(&ginfo->sid);
5705
5706         return status;
5707 }
5708
5709 /*********************************************************************
5710  _samr_DeleteUser
5711 *********************************************************************/
5712
5713 NTSTATUS _samr_DeleteUser(struct pipes_struct *p,
5714                           struct samr_DeleteUser *r)
5715 {
5716         struct samr_user_info *uinfo;
5717         NTSTATUS status;
5718         struct samu *sam_pass=NULL;
5719         bool ret;
5720
5721         DEBUG(5, ("_samr_DeleteUser: %d\n", __LINE__));
5722
5723         uinfo = policy_handle_find(p, r->in.user_handle,
5724                                    SEC_STD_DELETE, NULL,
5725                                    struct samr_user_info, &status);
5726         if (!NT_STATUS_IS_OK(status)) {
5727                 return status;
5728         }
5729
5730         if (!sid_check_is_in_our_domain(&uinfo->sid))
5731                 return NT_STATUS_CANNOT_DELETE;
5732
5733         /* check if the user exists before trying to delete */
5734         if ( !(sam_pass = samu_new( NULL )) ) {
5735                 return NT_STATUS_NO_MEMORY;
5736         }
5737
5738         become_root();
5739         ret = pdb_getsampwsid(sam_pass, &uinfo->sid);
5740         unbecome_root();
5741
5742         if(!ret) {
5743                 DEBUG(5,("_samr_DeleteUser: User %s doesn't exist.\n",
5744                         sid_string_dbg(&uinfo->sid)));
5745                 TALLOC_FREE(sam_pass);
5746                 return NT_STATUS_NO_SUCH_USER;
5747         }
5748
5749         /******** BEGIN SeAddUsers BLOCK *********/
5750
5751         become_root();
5752         status = pdb_delete_user(p->mem_ctx, sam_pass);
5753         unbecome_root();
5754
5755         /******** END SeAddUsers BLOCK *********/
5756
5757         if ( !NT_STATUS_IS_OK(status) ) {
5758                 DEBUG(5,("_samr_DeleteUser: Failed to delete entry for "
5759                          "user %s: %s.\n", pdb_get_username(sam_pass),
5760                          nt_errstr(status)));
5761                 TALLOC_FREE(sam_pass);
5762                 return status;
5763         }
5764
5765
5766         TALLOC_FREE(sam_pass);
5767
5768         force_flush_samr_cache(&uinfo->sid);
5769
5770         if (!close_policy_hnd(p, r->in.user_handle))
5771                 return NT_STATUS_OBJECT_NAME_INVALID;
5772
5773         ZERO_STRUCTP(r->out.user_handle);
5774
5775         return NT_STATUS_OK;
5776 }
5777
5778 /*********************************************************************
5779  _samr_DeleteDomainGroup
5780 *********************************************************************/
5781
5782 NTSTATUS _samr_DeleteDomainGroup(struct pipes_struct *p,
5783                                  struct samr_DeleteDomainGroup *r)
5784 {
5785         struct samr_group_info *ginfo;
5786         NTSTATUS status;
5787         uint32 group_rid;
5788
5789         DEBUG(5, ("samr_DeleteDomainGroup: %d\n", __LINE__));
5790
5791         ginfo = policy_handle_find(p, r->in.group_handle,
5792                                    SEC_STD_DELETE, NULL,
5793                                    struct samr_group_info, &status);
5794         if (!NT_STATUS_IS_OK(status)) {
5795                 return status;
5796         }
5797
5798         DEBUG(10, ("sid is %s\n", sid_string_dbg(&ginfo->sid)));
5799
5800         if (!sid_peek_check_rid(get_global_sam_sid(), &ginfo->sid,
5801                                 &group_rid)) {
5802                 return NT_STATUS_NO_SUCH_GROUP;
5803         }
5804
5805         /******** BEGIN SeAddUsers BLOCK *********/
5806
5807         become_root();
5808         status = pdb_delete_dom_group(p->mem_ctx, group_rid);
5809         unbecome_root();
5810
5811         /******** END SeAddUsers BLOCK *********/
5812
5813         if ( !NT_STATUS_IS_OK(status) ) {
5814                 DEBUG(5,("_samr_DeleteDomainGroup: Failed to delete mapping "
5815                          "entry for group %s: %s\n",
5816                          sid_string_dbg(&ginfo->sid),
5817                          nt_errstr(status)));
5818                 return status;
5819         }
5820
5821         force_flush_samr_cache(&ginfo->sid);
5822
5823         if (!close_policy_hnd(p, r->in.group_handle))
5824                 return NT_STATUS_OBJECT_NAME_INVALID;
5825
5826         return NT_STATUS_OK;
5827 }
5828
5829 /*********************************************************************
5830  _samr_DeleteDomAlias
5831 *********************************************************************/
5832
5833 NTSTATUS _samr_DeleteDomAlias(struct pipes_struct *p,
5834                               struct samr_DeleteDomAlias *r)
5835 {
5836         struct samr_alias_info *ainfo;
5837         NTSTATUS status;
5838
5839         DEBUG(5, ("_samr_DeleteDomAlias: %d\n", __LINE__));
5840
5841         ainfo = policy_handle_find(p, r->in.alias_handle,
5842                                    SEC_STD_DELETE, NULL,
5843                                    struct samr_alias_info, &status);
5844         if (!NT_STATUS_IS_OK(status)) {
5845                 return status;
5846         }
5847
5848         DEBUG(10, ("sid is %s\n", sid_string_dbg(&ainfo->sid)));
5849
5850         /* Don't let Windows delete builtin groups */
5851
5852         if ( sid_check_is_in_builtin( &ainfo->sid ) ) {
5853                 return NT_STATUS_SPECIAL_ACCOUNT;
5854         }
5855
5856         if (!sid_check_is_in_our_domain(&ainfo->sid))
5857                 return NT_STATUS_NO_SUCH_ALIAS;
5858
5859         DEBUG(10, ("lookup on Local SID\n"));
5860
5861         /******** BEGIN SeAddUsers BLOCK *********/
5862
5863         become_root();
5864         /* Have passdb delete the alias */
5865         status = pdb_delete_alias(&ainfo->sid);
5866         unbecome_root();
5867
5868         /******** END SeAddUsers BLOCK *********/
5869
5870         if ( !NT_STATUS_IS_OK(status))
5871                 return status;
5872
5873         force_flush_samr_cache(&ainfo->sid);
5874
5875         if (!close_policy_hnd(p, r->in.alias_handle))
5876                 return NT_STATUS_OBJECT_NAME_INVALID;
5877
5878         return NT_STATUS_OK;
5879 }
5880
5881 /*********************************************************************
5882  _samr_CreateDomainGroup
5883 *********************************************************************/
5884
5885 NTSTATUS _samr_CreateDomainGroup(struct pipes_struct *p,
5886                                  struct samr_CreateDomainGroup *r)
5887
5888 {
5889         NTSTATUS status;
5890         const char *name;
5891         struct samr_domain_info *dinfo;
5892         struct samr_group_info *ginfo;
5893
5894         dinfo = policy_handle_find(p, r->in.domain_handle,
5895                                    SAMR_DOMAIN_ACCESS_CREATE_GROUP, NULL,
5896                                    struct samr_domain_info, &status);
5897         if (!NT_STATUS_IS_OK(status)) {
5898                 return status;
5899         }
5900
5901         if (!sid_check_is_domain(&dinfo->sid)) {
5902                 return NT_STATUS_ACCESS_DENIED;
5903         }
5904
5905         name = r->in.name->string;
5906         if (name == NULL) {
5907                 return NT_STATUS_NO_MEMORY;
5908         }
5909
5910         status = can_create(p->mem_ctx, name);
5911         if (!NT_STATUS_IS_OK(status)) {
5912                 return status;
5913         }
5914
5915         /******** BEGIN SeAddUsers BLOCK *********/
5916
5917         become_root();
5918         /* check that we successfully create the UNIX group */
5919         status = pdb_create_dom_group(p->mem_ctx, name, r->out.rid);
5920         unbecome_root();
5921
5922         /******** END SeAddUsers BLOCK *********/
5923
5924         /* check if we should bail out here */
5925
5926         if ( !NT_STATUS_IS_OK(status) )
5927                 return status;
5928
5929         ginfo = policy_handle_create(p, r->out.group_handle,
5930                                      GENERIC_RIGHTS_GROUP_ALL_ACCESS,
5931                                      struct samr_group_info, &status);
5932         if (!NT_STATUS_IS_OK(status)) {
5933                 return status;
5934         }
5935         sid_compose(&ginfo->sid, &dinfo->sid, *r->out.rid);
5936
5937         force_flush_samr_cache(&dinfo->sid);
5938
5939         return NT_STATUS_OK;
5940 }
5941
5942 /*********************************************************************
5943  _samr_CreateDomAlias
5944 *********************************************************************/
5945
5946 NTSTATUS _samr_CreateDomAlias(struct pipes_struct *p,
5947                               struct samr_CreateDomAlias *r)
5948 {
5949         struct dom_sid info_sid;
5950         const char *name = NULL;
5951         struct samr_domain_info *dinfo;
5952         struct samr_alias_info *ainfo;
5953         gid_t gid;
5954         NTSTATUS result;
5955
5956         dinfo = policy_handle_find(p, r->in.domain_handle,
5957                                    SAMR_DOMAIN_ACCESS_CREATE_ALIAS, NULL,
5958                                    struct samr_domain_info, &result);
5959         if (!NT_STATUS_IS_OK(result)) {
5960                 return result;
5961         }
5962
5963         if (!sid_check_is_domain(&dinfo->sid)) {
5964                 return NT_STATUS_ACCESS_DENIED;
5965         }
5966
5967         name = r->in.alias_name->string;
5968
5969         result = can_create(p->mem_ctx, name);
5970         if (!NT_STATUS_IS_OK(result)) {
5971                 return result;
5972         }
5973
5974         /******** BEGIN SeAddUsers BLOCK *********/
5975
5976         become_root();
5977         /* Have passdb create the alias */
5978         result = pdb_create_alias(name, r->out.rid);
5979         unbecome_root();
5980
5981         /******** END SeAddUsers BLOCK *********/
5982
5983         if (!NT_STATUS_IS_OK(result)) {
5984                 DEBUG(10, ("pdb_create_alias failed: %s\n",
5985                            nt_errstr(result)));
5986                 return result;
5987         }
5988
5989         sid_compose(&info_sid, &dinfo->sid, *r->out.rid);
5990
5991         if (!sid_to_gid(&info_sid, &gid)) {
5992                 DEBUG(10, ("Could not find alias just created\n"));
5993                 return NT_STATUS_ACCESS_DENIED;
5994         }
5995
5996         /* check if the group has been successfully created */
5997         if ( getgrgid(gid) == NULL ) {
5998                 DEBUG(10, ("getgrgid(%u) of just created alias failed\n",
5999                            (unsigned int)gid));
6000                 return NT_STATUS_ACCESS_DENIED;
6001         }
6002
6003         ainfo = policy_handle_create(p, r->out.alias_handle,
6004                                      GENERIC_RIGHTS_ALIAS_ALL_ACCESS,
6005                                      struct samr_alias_info, &result);
6006         if (!NT_STATUS_IS_OK(result)) {
6007                 return result;
6008         }
6009         ainfo->sid = info_sid;
6010
6011         force_flush_samr_cache(&info_sid);
6012
6013         return NT_STATUS_OK;
6014 }
6015
6016 /*********************************************************************
6017  _samr_QueryGroupInfo
6018 *********************************************************************/
6019
6020 NTSTATUS _samr_QueryGroupInfo(struct pipes_struct *p,
6021                               struct samr_QueryGroupInfo *r)
6022 {
6023         struct samr_group_info *ginfo;
6024         NTSTATUS status;
6025         GROUP_MAP map;
6026         union samr_GroupInfo *info = NULL;
6027         bool ret;
6028         uint32_t attributes = SE_GROUP_MANDATORY |
6029                               SE_GROUP_ENABLED_BY_DEFAULT |
6030                               SE_GROUP_ENABLED;
6031         const char *group_name = NULL;
6032         const char *group_description = NULL;
6033
6034         ginfo = policy_handle_find(p, r->in.group_handle,
6035                                    SAMR_GROUP_ACCESS_LOOKUP_INFO, NULL,
6036                                    struct samr_group_info, &status);
6037         if (!NT_STATUS_IS_OK(status)) {
6038                 return status;
6039         }
6040
6041         become_root();
6042         ret = get_domain_group_from_sid(ginfo->sid, &map);
6043         unbecome_root();
6044         if (!ret)
6045                 return NT_STATUS_INVALID_HANDLE;
6046
6047         /* FIXME: map contains fstrings */
6048         group_name = talloc_strdup(r, map.nt_name);
6049         group_description = talloc_strdup(r, map.comment);
6050
6051         info = TALLOC_ZERO_P(p->mem_ctx, union samr_GroupInfo);
6052         if (!info) {
6053                 return NT_STATUS_NO_MEMORY;
6054         }
6055
6056         switch (r->in.level) {
6057                 case 1: {
6058                         uint32 *members;
6059                         size_t num_members;
6060
6061                         become_root();
6062                         status = pdb_enum_group_members(
6063                                 p->mem_ctx, &ginfo->sid, &members,
6064                                 &num_members);
6065                         unbecome_root();
6066
6067                         if (!NT_STATUS_IS_OK(status)) {
6068                                 return status;
6069                         }
6070
6071                         info->all.name.string           = group_name;
6072                         info->all.attributes            = attributes;
6073                         info->all.num_members           = num_members;
6074                         info->all.description.string    = group_description;
6075                         break;
6076                 }
6077                 case 2:
6078                         info->name.string = group_name;
6079                         break;
6080                 case 3:
6081                         info->attributes.attributes = attributes;
6082                         break;
6083                 case 4:
6084                         info->description.string = group_description;
6085                         break;
6086                 case 5: {
6087                         /*
6088                         uint32 *members;
6089                         size_t num_members;
6090                         */
6091
6092                         /*
6093                         become_root();
6094                         status = pdb_enum_group_members(
6095                                 p->mem_ctx, &ginfo->sid, &members,
6096                                 &num_members);
6097                         unbecome_root();
6098
6099                         if (!NT_STATUS_IS_OK(status)) {
6100                                 return status;
6101                         }
6102                         */
6103                         info->all2.name.string          = group_name;
6104                         info->all2.attributes           = attributes;
6105                         info->all2.num_members          = 0; /* num_members - in w2k3 this is always 0 */
6106                         info->all2.description.string   = group_description;
6107
6108                         break;
6109                 }
6110                 default:
6111                         return NT_STATUS_INVALID_INFO_CLASS;
6112         }
6113
6114         *r->out.info = info;
6115
6116         return NT_STATUS_OK;
6117 }
6118
6119 /*********************************************************************
6120  _samr_SetGroupInfo
6121 *********************************************************************/
6122
6123 NTSTATUS _samr_SetGroupInfo(struct pipes_struct *p,
6124                             struct samr_SetGroupInfo *r)
6125 {
6126         struct samr_group_info *ginfo;
6127         GROUP_MAP map;
6128         NTSTATUS status;
6129         bool ret;
6130
6131         ginfo = policy_handle_find(p, r->in.group_handle,
6132                                    SAMR_GROUP_ACCESS_SET_INFO, NULL,
6133                                    struct samr_group_info, &status);
6134         if (!NT_STATUS_IS_OK(status)) {
6135                 return status;
6136         }
6137
6138         become_root();
6139         ret = get_domain_group_from_sid(ginfo->sid, &map);
6140         unbecome_root();
6141         if (!ret)
6142                 return NT_STATUS_NO_SUCH_GROUP;
6143
6144         switch (r->in.level) {
6145                 case 2:
6146                         fstrcpy(map.nt_name, r->in.info->name.string);
6147                         break;
6148                 case 3:
6149                         break;
6150                 case 4:
6151                         fstrcpy(map.comment, r->in.info->description.string);
6152                         break;
6153                 default:
6154                         return NT_STATUS_INVALID_INFO_CLASS;
6155         }
6156
6157         /******** BEGIN SeAddUsers BLOCK *********/
6158
6159         become_root();
6160         status = pdb_update_group_mapping_entry(&map);
6161         unbecome_root();
6162
6163         /******** End SeAddUsers BLOCK *********/
6164
6165         if (NT_STATUS_IS_OK(status)) {
6166                 force_flush_samr_cache(&ginfo->sid);
6167         }
6168
6169         return status;
6170 }
6171
6172 /*********************************************************************
6173  _samr_SetAliasInfo
6174 *********************************************************************/
6175
6176 NTSTATUS _samr_SetAliasInfo(struct pipes_struct *p,
6177                             struct samr_SetAliasInfo *r)
6178 {
6179         struct samr_alias_info *ainfo;
6180         struct acct_info info;
6181         NTSTATUS status;
6182
6183         ainfo = policy_handle_find(p, r->in.alias_handle,
6184                                    SAMR_ALIAS_ACCESS_SET_INFO, NULL,
6185                                    struct samr_alias_info, &status);
6186         if (!NT_STATUS_IS_OK(status)) {
6187                 return status;
6188         }
6189
6190         /* get the current group information */
6191
6192         become_root();
6193         status = pdb_get_aliasinfo( &ainfo->sid, &info );
6194         unbecome_root();
6195
6196         if ( !NT_STATUS_IS_OK(status))
6197                 return status;
6198
6199         switch (r->in.level) {
6200                 case ALIASINFONAME:
6201                 {
6202                         fstring group_name;
6203
6204                         /* We currently do not support renaming groups in the
6205                            the BUILTIN domain.  Refer to util_builtin.c to understand
6206                            why.  The eventually needs to be fixed to be like Windows
6207                            where you can rename builtin groups, just not delete them */
6208
6209                         if ( sid_check_is_in_builtin( &ainfo->sid ) ) {
6210                                 return NT_STATUS_SPECIAL_ACCOUNT;
6211                         }
6212
6213                         /* There has to be a valid name (and it has to be different) */
6214
6215                         if ( !r->in.info->name.string )
6216                                 return NT_STATUS_INVALID_PARAMETER;
6217
6218                         /* If the name is the same just reply "ok".  Yes this
6219                            doesn't allow you to change the case of a group name. */
6220
6221                         if ( strequal( r->in.info->name.string, info.acct_name ) )
6222                                 return NT_STATUS_OK;
6223
6224                         fstrcpy( info.acct_name, r->in.info->name.string);
6225
6226                         /* make sure the name doesn't already exist as a user
6227                            or local group */
6228
6229                         fstr_sprintf( group_name, "%s\\%s", global_myname(), info.acct_name );
6230                         status = can_create( p->mem_ctx, group_name );
6231                         if ( !NT_STATUS_IS_OK( status ) )
6232                                 return status;
6233                         break;
6234                 }
6235                 case ALIASINFODESCRIPTION:
6236                         if (r->in.info->description.string) {
6237                                 fstrcpy(info.acct_desc,
6238                                         r->in.info->description.string);
6239                         } else {
6240                                 fstrcpy( info.acct_desc, "" );
6241                         }
6242                         break;
6243                 default:
6244                         return NT_STATUS_INVALID_INFO_CLASS;
6245         }
6246
6247         /******** BEGIN SeAddUsers BLOCK *********/
6248
6249         become_root();
6250         status = pdb_set_aliasinfo( &ainfo->sid, &info );
6251         unbecome_root();
6252
6253         /******** End SeAddUsers BLOCK *********/
6254
6255         if (NT_STATUS_IS_OK(status))
6256                 force_flush_samr_cache(&ainfo->sid);
6257
6258         return status;
6259 }
6260
6261 /****************************************************************
6262  _samr_GetDomPwInfo
6263 ****************************************************************/
6264
6265 NTSTATUS _samr_GetDomPwInfo(struct pipes_struct *p,
6266                             struct samr_GetDomPwInfo *r)
6267 {
6268         uint32_t min_password_length = 0;
6269         uint32_t password_properties = 0;
6270
6271         /* Perform access check.  Since this rpc does not require a
6272            policy handle it will not be caught by the access checks on
6273            SAMR_CONNECT or SAMR_CONNECT_ANON. */
6274
6275         if (!pipe_access_check(p)) {
6276                 DEBUG(3, ("access denied to _samr_GetDomPwInfo\n"));
6277                 return NT_STATUS_ACCESS_DENIED;
6278         }
6279
6280         become_root();
6281         pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN,
6282                                &min_password_length);
6283         pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
6284                                &password_properties);
6285         unbecome_root();
6286
6287         if (lp_check_password_script() && *lp_check_password_script()) {
6288                 password_properties |= DOMAIN_PASSWORD_COMPLEX;
6289         }
6290
6291         r->out.info->min_password_length = min_password_length;
6292         r->out.info->password_properties = password_properties;
6293
6294         return NT_STATUS_OK;
6295 }
6296
6297 /*********************************************************************
6298  _samr_OpenGroup
6299 *********************************************************************/
6300
6301 NTSTATUS _samr_OpenGroup(struct pipes_struct *p,
6302                          struct samr_OpenGroup *r)
6303
6304 {
6305         struct dom_sid info_sid;
6306         GROUP_MAP map;
6307         struct samr_domain_info *dinfo;
6308         struct samr_group_info *ginfo;
6309         struct security_descriptor         *psd = NULL;
6310         uint32            acc_granted;
6311         uint32            des_access = r->in.access_mask;
6312         size_t            sd_size;
6313         NTSTATUS          status;
6314         bool ret;
6315
6316         dinfo = policy_handle_find(p, r->in.domain_handle,
6317                                    SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
6318                                    struct samr_domain_info, &status);
6319         if (!NT_STATUS_IS_OK(status)) {
6320                 return status;
6321         }
6322
6323         /*check if access can be granted as requested by client. */
6324         map_max_allowed_access(p->server_info->ptok,
6325                                &p->server_info->utok,
6326                                &des_access);
6327
6328         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &grp_generic_mapping, NULL, 0);
6329         se_map_generic(&des_access,&grp_generic_mapping);
6330
6331         status = access_check_object(psd, p->server_info->ptok,
6332                                      SEC_PRIV_ADD_USERS, SEC_PRIV_INVALID, GENERIC_RIGHTS_GROUP_ALL_ACCESS,
6333                                      des_access, &acc_granted, "_samr_OpenGroup");
6334
6335         if ( !NT_STATUS_IS_OK(status) )
6336                 return status;
6337
6338         /* this should not be hard-coded like this */
6339
6340         if (!sid_check_is_domain(&dinfo->sid)) {
6341                 return NT_STATUS_ACCESS_DENIED;
6342         }
6343
6344         sid_compose(&info_sid, &dinfo->sid, r->in.rid);
6345
6346         DEBUG(10, ("_samr_OpenGroup:Opening SID: %s\n",
6347                    sid_string_dbg(&info_sid)));
6348
6349         /* check if that group really exists */
6350         become_root();
6351         ret = get_domain_group_from_sid(info_sid, &map);
6352         unbecome_root();
6353         if (!ret)
6354                 return NT_STATUS_NO_SUCH_GROUP;
6355
6356         ginfo = policy_handle_create(p, r->out.group_handle,
6357                                      acc_granted,
6358                                      struct samr_group_info, &status);
6359         if (!NT_STATUS_IS_OK(status)) {
6360                 return status;
6361         }
6362         ginfo->sid = info_sid;
6363
6364         return NT_STATUS_OK;
6365 }
6366
6367 /*********************************************************************
6368  _samr_RemoveMemberFromForeignDomain
6369 *********************************************************************/
6370
6371 NTSTATUS _samr_RemoveMemberFromForeignDomain(struct pipes_struct *p,
6372                                              struct samr_RemoveMemberFromForeignDomain *r)
6373 {
6374         struct samr_domain_info *dinfo;
6375         NTSTATUS                result;
6376
6377         DEBUG(5,("_samr_RemoveMemberFromForeignDomain: removing SID [%s]\n",
6378                  sid_string_dbg(r->in.sid)));
6379
6380         /* Find the policy handle. Open a policy on it. */
6381
6382         dinfo = policy_handle_find(p, r->in.domain_handle,
6383                                    SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
6384                                    struct samr_domain_info, &result);
6385         if (!NT_STATUS_IS_OK(result)) {
6386                 return result;
6387         }
6388
6389         DEBUG(8, ("_samr_RemoveMemberFromForeignDomain: sid is %s\n",
6390                   sid_string_dbg(&dinfo->sid)));
6391
6392         /* we can only delete a user from a group since we don't have
6393            nested groups anyways.  So in the latter case, just say OK */
6394
6395         /* TODO: The above comment nowadays is bogus. Since we have nested
6396          * groups now, and aliases members are never reported out of the unix
6397          * group membership, the "just say OK" makes this call a no-op. For
6398          * us. This needs fixing however. */
6399
6400         /* I've only ever seen this in the wild when deleting a user from
6401          * usrmgr.exe. domain_sid is the builtin domain, and the sid to delete
6402          * is the user about to be deleted. I very much suspect this is the
6403          * only application of this call. To verify this, let people report
6404          * other cases. */
6405
6406         if (!sid_check_is_builtin(&dinfo->sid)) {
6407                 DEBUG(1,("_samr_RemoveMemberFromForeignDomain: domain_sid = %s, "
6408                          "global_sam_sid() = %s\n",
6409                          sid_string_dbg(&dinfo->sid),
6410                          sid_string_dbg(get_global_sam_sid())));
6411                 DEBUGADD(1,("please report to samba-technical@samba.org!\n"));
6412                 return NT_STATUS_OK;
6413         }
6414
6415         force_flush_samr_cache(&dinfo->sid);
6416
6417         result = NT_STATUS_OK;
6418
6419         return result;
6420 }
6421
6422 /*******************************************************************
6423  _samr_QueryDomainInfo2
6424  ********************************************************************/
6425
6426 NTSTATUS _samr_QueryDomainInfo2(struct pipes_struct *p,
6427                                 struct samr_QueryDomainInfo2 *r)
6428 {
6429         struct samr_QueryDomainInfo q;
6430
6431         q.in.domain_handle      = r->in.domain_handle;
6432         q.in.level              = r->in.level;
6433
6434         q.out.info              = r->out.info;
6435
6436         return _samr_QueryDomainInfo(p, &q);
6437 }
6438
6439 /*******************************************************************
6440  ********************************************************************/
6441
6442 static NTSTATUS set_dom_info_1(TALLOC_CTX *mem_ctx,
6443                                struct samr_DomInfo1 *r)
6444 {
6445         time_t u_expire, u_min_age;
6446
6447         u_expire = nt_time_to_unix_abs((NTTIME *)&r->max_password_age);
6448         u_min_age = nt_time_to_unix_abs((NTTIME *)&r->min_password_age);
6449
6450         pdb_set_account_policy(PDB_POLICY_MIN_PASSWORD_LEN,
6451                                (uint32_t)r->min_password_length);
6452         pdb_set_account_policy(PDB_POLICY_PASSWORD_HISTORY,
6453                                (uint32_t)r->password_history_length);
6454         pdb_set_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
6455                                (uint32_t)r->password_properties);
6456         pdb_set_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, (int)u_expire);
6457         pdb_set_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, (int)u_min_age);
6458
6459         return NT_STATUS_OK;
6460 }
6461
6462 /*******************************************************************
6463  ********************************************************************/
6464
6465 static NTSTATUS set_dom_info_3(TALLOC_CTX *mem_ctx,
6466                                struct samr_DomInfo3 *r)
6467 {
6468         time_t u_logout;
6469
6470         u_logout = nt_time_to_unix_abs((NTTIME *)&r->force_logoff_time);
6471
6472         pdb_set_account_policy(PDB_POLICY_TIME_TO_LOGOUT, (int)u_logout);
6473
6474         return NT_STATUS_OK;
6475 }
6476
6477 /*******************************************************************
6478  ********************************************************************/
6479
6480 static NTSTATUS set_dom_info_12(TALLOC_CTX *mem_ctx,
6481                                 struct samr_DomInfo12 *r)
6482 {
6483         time_t u_lock_duration, u_reset_time;
6484
6485         u_lock_duration = nt_time_to_unix_abs((NTTIME *)&r->lockout_duration);
6486         if (u_lock_duration != -1) {
6487                 u_lock_duration /= 60;
6488         }
6489
6490         u_reset_time = nt_time_to_unix_abs((NTTIME *)&r->lockout_window)/60;
6491
6492         pdb_set_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
6493         pdb_set_account_policy(PDB_POLICY_RESET_COUNT_TIME, (int)u_reset_time);
6494         pdb_set_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT,
6495                                (uint32_t)r->lockout_threshold);
6496
6497         return NT_STATUS_OK;
6498 }
6499
6500 /*******************************************************************
6501  _samr_SetDomainInfo
6502  ********************************************************************/
6503
6504 NTSTATUS _samr_SetDomainInfo(struct pipes_struct *p,
6505                              struct samr_SetDomainInfo *r)
6506 {
6507         struct samr_domain_info *dinfo;
6508         NTSTATUS status;
6509         uint32_t acc_required = 0;
6510
6511         DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
6512
6513         switch (r->in.level) {
6514         case 1: /* DomainPasswordInformation */
6515         case 12: /* DomainLockoutInformation */
6516                 /* DOMAIN_WRITE_PASSWORD_PARAMETERS */
6517                 acc_required = SAMR_DOMAIN_ACCESS_SET_INFO_1;
6518                 break;
6519         case 3: /* DomainLogoffInformation */
6520         case 4: /* DomainOemInformation */
6521                 /* DOMAIN_WRITE_OTHER_PARAMETERS */
6522                 acc_required = SAMR_DOMAIN_ACCESS_SET_INFO_2;
6523                 break;
6524         case 6: /* DomainReplicationInformation */
6525         case 9: /* DomainStateInformation */
6526         case 7: /* DomainServerRoleInformation */
6527                 /* DOMAIN_ADMINISTER_SERVER */
6528                 acc_required = SAMR_DOMAIN_ACCESS_SET_INFO_3;
6529                 break;
6530         default:
6531                 return NT_STATUS_INVALID_INFO_CLASS;
6532         }
6533
6534         dinfo = policy_handle_find(p, r->in.domain_handle,
6535                                    acc_required, NULL,
6536                                    struct samr_domain_info, &status);
6537         if (!NT_STATUS_IS_OK(status)) {
6538                 return status;
6539         }
6540
6541         DEBUG(5,("_samr_SetDomainInfo: level: %d\n", r->in.level));
6542
6543         switch (r->in.level) {
6544                 case 1:
6545                         status = set_dom_info_1(p->mem_ctx, &r->in.info->info1);
6546                         break;
6547                 case 3:
6548                         status = set_dom_info_3(p->mem_ctx, &r->in.info->info3);
6549                         break;
6550                 case 4:
6551                         break;
6552                 case 6:
6553                         break;
6554                 case 7:
6555                         break;
6556                 case 9:
6557                         break;
6558                 case 12:
6559                         status = set_dom_info_12(p->mem_ctx, &r->in.info->info12);
6560                         break;
6561                 default:
6562                         return NT_STATUS_INVALID_INFO_CLASS;
6563         }
6564
6565         if (!NT_STATUS_IS_OK(status)) {
6566                 return status;
6567         }
6568
6569         DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
6570
6571         return NT_STATUS_OK;
6572 }
6573
6574 /****************************************************************
6575  _samr_GetDisplayEnumerationIndex
6576 ****************************************************************/
6577
6578 NTSTATUS _samr_GetDisplayEnumerationIndex(struct pipes_struct *p,
6579                                           struct samr_GetDisplayEnumerationIndex *r)
6580 {
6581         struct samr_domain_info *dinfo;
6582         uint32_t max_entries = (uint32_t) -1;
6583         uint32_t enum_context = 0;
6584         int i;
6585         uint32_t num_account = 0;
6586         struct samr_displayentry *entries = NULL;
6587         NTSTATUS status;
6588
6589         DEBUG(5,("_samr_GetDisplayEnumerationIndex: %d\n", __LINE__));
6590
6591         dinfo = policy_handle_find(p, r->in.domain_handle,
6592                                    SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
6593                                    struct samr_domain_info, &status);
6594         if (!NT_STATUS_IS_OK(status)) {
6595                 return status;
6596         }
6597
6598         if ((r->in.level < 1) || (r->in.level > 3)) {
6599                 DEBUG(0,("_samr_GetDisplayEnumerationIndex: "
6600                         "Unknown info level (%u)\n",
6601                         r->in.level));
6602                 return NT_STATUS_INVALID_INFO_CLASS;
6603         }
6604
6605         become_root();
6606
6607         /* The following done as ROOT. Don't return without unbecome_root(). */
6608
6609         switch (r->in.level) {
6610         case 1:
6611                 if (dinfo->disp_info->users == NULL) {
6612                         dinfo->disp_info->users = pdb_search_users(
6613                                 dinfo->disp_info, ACB_NORMAL);
6614                         if (dinfo->disp_info->users == NULL) {
6615                                 unbecome_root();
6616                                 return NT_STATUS_ACCESS_DENIED;
6617                         }
6618                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6619                                 "starting user enumeration at index %u\n",
6620                                 (unsigned int)enum_context));
6621                 } else {
6622                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6623                                 "using cached user enumeration at index %u\n",
6624                                 (unsigned int)enum_context));
6625                 }
6626                 num_account = pdb_search_entries(dinfo->disp_info->users,
6627                                                  enum_context, max_entries,
6628                                                  &entries);
6629                 break;
6630         case 2:
6631                 if (dinfo->disp_info->machines == NULL) {
6632                         dinfo->disp_info->machines = pdb_search_users(
6633                                 dinfo->disp_info, ACB_WSTRUST|ACB_SVRTRUST);
6634                         if (dinfo->disp_info->machines == NULL) {
6635                                 unbecome_root();
6636                                 return NT_STATUS_ACCESS_DENIED;
6637                         }
6638                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6639                                 "starting machine enumeration at index %u\n",
6640                                 (unsigned int)enum_context));
6641                 } else {
6642                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6643                                 "using cached machine enumeration at index %u\n",
6644                                 (unsigned int)enum_context));
6645                 }
6646                 num_account = pdb_search_entries(dinfo->disp_info->machines,
6647                                                  enum_context, max_entries,
6648                                                  &entries);
6649                 break;
6650         case 3:
6651                 if (dinfo->disp_info->groups == NULL) {
6652                         dinfo->disp_info->groups = pdb_search_groups(
6653                                 dinfo->disp_info);
6654                         if (dinfo->disp_info->groups == NULL) {
6655                                 unbecome_root();
6656                                 return NT_STATUS_ACCESS_DENIED;
6657                         }
6658                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6659                                 "starting group enumeration at index %u\n",
6660                                 (unsigned int)enum_context));
6661                 } else {
6662                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6663                                 "using cached group enumeration at index %u\n",
6664                                 (unsigned int)enum_context));
6665                 }
6666                 num_account = pdb_search_entries(dinfo->disp_info->groups,
6667                                                  enum_context, max_entries,
6668                                                  &entries);
6669                 break;
6670         default:
6671                 unbecome_root();
6672                 smb_panic("info class changed");
6673                 break;
6674         }
6675
6676         unbecome_root();
6677
6678         /* Ensure we cache this enumeration. */
6679         set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
6680
6681         DEBUG(10,("_samr_GetDisplayEnumerationIndex: looking for :%s\n",
6682                 r->in.name->string));
6683
6684         for (i=0; i<num_account; i++) {
6685                 if (strequal(entries[i].account_name, r->in.name->string)) {
6686                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6687                                 "found %s at idx %d\n",
6688                                 r->in.name->string, i));
6689                         *r->out.idx = i;
6690                         return NT_STATUS_OK;
6691                 }
6692         }
6693
6694         /* assuming account_name lives at the very end */
6695         *r->out.idx = num_account;
6696
6697         return NT_STATUS_NO_MORE_ENTRIES;
6698 }
6699
6700 /****************************************************************
6701  _samr_GetDisplayEnumerationIndex2
6702 ****************************************************************/
6703
6704 NTSTATUS _samr_GetDisplayEnumerationIndex2(struct pipes_struct *p,
6705                                            struct samr_GetDisplayEnumerationIndex2 *r)
6706 {
6707         struct samr_GetDisplayEnumerationIndex q;
6708
6709         q.in.domain_handle      = r->in.domain_handle;
6710         q.in.level              = r->in.level;
6711         q.in.name               = r->in.name;
6712
6713         q.out.idx               = r->out.idx;
6714
6715         return _samr_GetDisplayEnumerationIndex(p, &q);
6716 }
6717
6718 /****************************************************************
6719  _samr_RidToSid
6720 ****************************************************************/
6721
6722 NTSTATUS _samr_RidToSid(struct pipes_struct *p,
6723                         struct samr_RidToSid *r)
6724 {
6725         struct samr_domain_info *dinfo;
6726         NTSTATUS status;
6727         struct dom_sid sid;
6728
6729         dinfo = policy_handle_find(p, r->in.domain_handle,
6730                                    0, NULL,
6731                                    struct samr_domain_info, &status);
6732         if (!NT_STATUS_IS_OK(status)) {
6733                 return status;
6734         }
6735
6736         if (!sid_compose(&sid, &dinfo->sid, r->in.rid)) {
6737                 return NT_STATUS_NO_MEMORY;
6738         }
6739
6740         *r->out.sid = dom_sid_dup(p->mem_ctx, &sid);
6741         if (!*r->out.sid) {
6742                 return NT_STATUS_NO_MEMORY;
6743         }
6744
6745         return NT_STATUS_OK;
6746 }
6747
6748 /****************************************************************
6749 ****************************************************************/
6750
6751 static enum samr_ValidationStatus samr_ValidatePassword_Change(TALLOC_CTX *mem_ctx,
6752                                                                const struct samr_PwInfo *dom_pw_info,
6753                                                                const struct samr_ValidatePasswordReq2 *req,
6754                                                                struct samr_ValidatePasswordRepCtr *rep)
6755 {
6756         NTSTATUS status;
6757
6758         if (req->password.string == NULL) {
6759                 return SAMR_VALIDATION_STATUS_SUCCESS;
6760         }
6761         if (strlen(req->password.string) < dom_pw_info->min_password_length) {
6762                 ZERO_STRUCT(rep->info);
6763                 return SAMR_VALIDATION_STATUS_PWD_TOO_SHORT;
6764         }
6765         if (dom_pw_info->password_properties & DOMAIN_PASSWORD_COMPLEX) {
6766                 status = check_password_complexity(req->account.string,
6767                                                    req->password.string,
6768                                                    NULL);
6769                 if (!NT_STATUS_IS_OK(status)) {
6770                         ZERO_STRUCT(rep->info);
6771                         return SAMR_VALIDATION_STATUS_NOT_COMPLEX_ENOUGH;
6772                 }
6773         }
6774
6775         return SAMR_VALIDATION_STATUS_SUCCESS;
6776 }
6777
6778 /****************************************************************
6779 ****************************************************************/
6780
6781 static enum samr_ValidationStatus samr_ValidatePassword_Reset(TALLOC_CTX *mem_ctx,
6782                                                               const struct samr_PwInfo *dom_pw_info,
6783                                                               const struct samr_ValidatePasswordReq3 *req,
6784                                                               struct samr_ValidatePasswordRepCtr *rep)
6785 {
6786         NTSTATUS status;
6787
6788         if (req->password.string == NULL) {
6789                 return SAMR_VALIDATION_STATUS_SUCCESS;
6790         }
6791         if (strlen(req->password.string) < dom_pw_info->min_password_length) {
6792                 ZERO_STRUCT(rep->info);
6793                 return SAMR_VALIDATION_STATUS_PWD_TOO_SHORT;
6794         }
6795         if (dom_pw_info->password_properties & DOMAIN_PASSWORD_COMPLEX) {
6796                 status = check_password_complexity(req->account.string,
6797                                                    req->password.string,
6798                                                    NULL);
6799                 if (!NT_STATUS_IS_OK(status)) {
6800                         ZERO_STRUCT(rep->info);
6801                         return SAMR_VALIDATION_STATUS_NOT_COMPLEX_ENOUGH;
6802                 }
6803         }
6804
6805         return SAMR_VALIDATION_STATUS_SUCCESS;
6806 }
6807
6808 /****************************************************************
6809  _samr_ValidatePassword
6810 ****************************************************************/
6811
6812 NTSTATUS _samr_ValidatePassword(struct pipes_struct *p,
6813                                 struct samr_ValidatePassword *r)
6814 {
6815         union samr_ValidatePasswordRep *rep;
6816         NTSTATUS status;
6817         struct samr_GetDomPwInfo pw;
6818         struct samr_PwInfo dom_pw_info;
6819
6820         if (r->in.level < 1 || r->in.level > 3) {
6821                 return NT_STATUS_INVALID_INFO_CLASS;
6822         }
6823
6824         pw.in.domain_name = NULL;
6825         pw.out.info = &dom_pw_info;
6826
6827         status = _samr_GetDomPwInfo(p, &pw);
6828         if (!NT_STATUS_IS_OK(status)) {
6829                 return status;
6830         }
6831
6832         rep = talloc_zero(p->mem_ctx, union samr_ValidatePasswordRep);
6833         if (!rep) {
6834                 return NT_STATUS_NO_MEMORY;
6835         }
6836
6837         switch (r->in.level) {
6838         case 1:
6839                 status = NT_STATUS_NOT_SUPPORTED;
6840                 break;
6841         case 2:
6842                 rep->ctr2.status = samr_ValidatePassword_Change(p->mem_ctx,
6843                                                                 &dom_pw_info,
6844                                                                 &r->in.req->req2,
6845                                                                 &rep->ctr2);
6846                 break;
6847         case 3:
6848                 rep->ctr3.status = samr_ValidatePassword_Reset(p->mem_ctx,
6849                                                                &dom_pw_info,
6850                                                                &r->in.req->req3,
6851                                                                &rep->ctr3);
6852                 break;
6853         default:
6854                 status = NT_STATUS_INVALID_INFO_CLASS;
6855                 break;
6856         }
6857
6858         if (!NT_STATUS_IS_OK(status)) {
6859                 talloc_free(rep);
6860                 return status;
6861         }
6862
6863         *r->out.rep = rep;
6864
6865         return NT_STATUS_OK;
6866 }
6867
6868 /****************************************************************
6869 ****************************************************************/
6870
6871 NTSTATUS _samr_Shutdown(struct pipes_struct *p,
6872                         struct samr_Shutdown *r)
6873 {
6874         p->rng_fault_state = true;
6875         return NT_STATUS_NOT_IMPLEMENTED;
6876 }
6877
6878 /****************************************************************
6879 ****************************************************************/
6880
6881 NTSTATUS _samr_SetMemberAttributesOfGroup(struct pipes_struct *p,
6882                                           struct samr_SetMemberAttributesOfGroup *r)
6883 {
6884         p->rng_fault_state = true;
6885         return NT_STATUS_NOT_IMPLEMENTED;
6886 }
6887
6888 /****************************************************************
6889 ****************************************************************/
6890
6891 NTSTATUS _samr_TestPrivateFunctionsDomain(struct pipes_struct *p,
6892                                           struct samr_TestPrivateFunctionsDomain *r)
6893 {
6894         return NT_STATUS_NOT_IMPLEMENTED;
6895 }
6896
6897 /****************************************************************
6898 ****************************************************************/
6899
6900 NTSTATUS _samr_TestPrivateFunctionsUser(struct pipes_struct *p,
6901                                         struct samr_TestPrivateFunctionsUser *r)
6902 {
6903         return NT_STATUS_NOT_IMPLEMENTED;
6904 }
6905
6906 /****************************************************************
6907 ****************************************************************/
6908
6909 NTSTATUS _samr_AddMultipleMembersToAlias(struct pipes_struct *p,
6910                                          struct samr_AddMultipleMembersToAlias *r)
6911 {
6912         p->rng_fault_state = true;
6913         return NT_STATUS_NOT_IMPLEMENTED;
6914 }
6915
6916 /****************************************************************
6917 ****************************************************************/
6918
6919 NTSTATUS _samr_RemoveMultipleMembersFromAlias(struct pipes_struct *p,
6920                                               struct samr_RemoveMultipleMembersFromAlias *r)
6921 {
6922         p->rng_fault_state = true;
6923         return NT_STATUS_NOT_IMPLEMENTED;
6924 }
6925
6926 /****************************************************************
6927 ****************************************************************/
6928
6929 NTSTATUS _samr_SetBootKeyInformation(struct pipes_struct *p,
6930                                      struct samr_SetBootKeyInformation *r)
6931 {
6932         p->rng_fault_state = true;
6933         return NT_STATUS_NOT_IMPLEMENTED;
6934 }
6935
6936 /****************************************************************
6937 ****************************************************************/
6938
6939 NTSTATUS _samr_GetBootKeyInformation(struct pipes_struct *p,
6940                                      struct samr_GetBootKeyInformation *r)
6941 {
6942         p->rng_fault_state = true;
6943         return NT_STATUS_NOT_IMPLEMENTED;
6944 }
6945
6946 /****************************************************************
6947 ****************************************************************/
6948
6949 NTSTATUS _samr_SetDsrmPassword(struct pipes_struct *p,
6950                                struct samr_SetDsrmPassword *r)
6951 {
6952         p->rng_fault_state = true;
6953         return NT_STATUS_NOT_IMPLEMENTED;
6954 }