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