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