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