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