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