Add extra abilities for a user with SeAddUsers, so they
[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