s3-samr: fix enum_acb_mask type (uint32 instead of uint16).
[ira/wip.git] / source3 / rpc_server / srv_samr_nt.c
1 /*
2  *  Unix SMB/CIFS implementation.
3  *  RPC Pipe client / server routines
4  *  Copyright (C) Andrew Tridgell                   1992-1997,
5  *  Copyright (C) Luke Kenneth Casson Leighton      1996-1997,
6  *  Copyright (C) Paul Ashton                       1997,
7  *  Copyright (C) Marc Jacobsen                     1999,
8  *  Copyright (C) Jeremy Allison                    2001-2008,
9  *  Copyright (C) Jean Fran├žois Micouleau           1998-2001,
10  *  Copyright (C) Jim McDonough <jmcd@us.ibm.com>   2002,
11  *  Copyright (C) Gerald (Jerry) Carter             2003-2004,
12  *  Copyright (C) Simo Sorce                        2003.
13  *  Copyright (C) Volker Lendecke                   2005.
14  *  Copyright (C) Guenther Deschner                 2008.
15  *
16  *  This program is free software; you can redistribute it and/or modify
17  *  it under the terms of the GNU General Public License as published by
18  *  the Free Software Foundation; either version 3 of the License, or
19  *  (at your option) any later version.
20  *
21  *  This program is distributed in the hope that it will be useful,
22  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
23  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24  *  GNU General Public License for more details.
25  *
26  *  You should have received a copy of the GNU General Public License
27  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
28  */
29
30 /*
31  * This is the implementation of the SAMR code.
32  */
33
34 #include "includes.h"
35 #include "smbd/globals.h"
36 #include "../libcli/auth/libcli_auth.h"
37
38 #undef DBGC_CLASS
39 #define DBGC_CLASS DBGC_RPC_SRV
40
41 #define SAMR_USR_RIGHTS_WRITE_PW \
42                 ( READ_CONTROL_ACCESS           | \
43                   SAMR_USER_ACCESS_CHANGE_PASSWORD      | \
44                   SAMR_USER_ACCESS_SET_LOC_COM)
45 #define SAMR_USR_RIGHTS_CANT_WRITE_PW \
46                 ( READ_CONTROL_ACCESS | SAMR_USER_ACCESS_SET_LOC_COM )
47
48 #define DISP_INFO_CACHE_TIMEOUT 10
49
50 #define MAX_SAM_ENTRIES_W2K 0x400 /* 1024 */
51 #define MAX_SAM_ENTRIES_W95 50
52
53 struct samr_connect_info {
54         uint8_t dummy;
55 };
56
57 struct samr_domain_info {
58         struct dom_sid sid;
59         struct disp_info *disp_info;
60 };
61
62 struct samr_user_info {
63         struct dom_sid sid;
64 };
65
66 struct samr_group_info {
67         struct dom_sid sid;
68 };
69
70 struct samr_alias_info {
71         struct dom_sid sid;
72 };
73
74 typedef struct disp_info {
75         DOM_SID sid; /* identify which domain this is. */
76         struct pdb_search *users; /* querydispinfo 1 and 4 */
77         struct pdb_search *machines; /* querydispinfo 2 */
78         struct pdb_search *groups; /* querydispinfo 3 and 5, enumgroups */
79         struct pdb_search *aliases; /* enumaliases */
80
81         uint32_t enum_acb_mask;
82         struct pdb_search *enum_users; /* enumusers with a mask */
83
84         struct timed_event *cache_timeout_event; /* cache idle timeout
85                                                   * handler. */
86 } DISP_INFO;
87
88 static const struct generic_mapping sam_generic_mapping = {
89         GENERIC_RIGHTS_SAM_READ,
90         GENERIC_RIGHTS_SAM_WRITE,
91         GENERIC_RIGHTS_SAM_EXECUTE,
92         GENERIC_RIGHTS_SAM_ALL_ACCESS};
93 static const struct generic_mapping dom_generic_mapping = {
94         GENERIC_RIGHTS_DOMAIN_READ,
95         GENERIC_RIGHTS_DOMAIN_WRITE,
96         GENERIC_RIGHTS_DOMAIN_EXECUTE,
97         GENERIC_RIGHTS_DOMAIN_ALL_ACCESS};
98 static const struct generic_mapping usr_generic_mapping = {
99         GENERIC_RIGHTS_USER_READ,
100         GENERIC_RIGHTS_USER_WRITE,
101         GENERIC_RIGHTS_USER_EXECUTE,
102         GENERIC_RIGHTS_USER_ALL_ACCESS};
103 static const struct generic_mapping usr_nopwchange_generic_mapping = {
104         GENERIC_RIGHTS_USER_READ,
105         GENERIC_RIGHTS_USER_WRITE,
106         GENERIC_RIGHTS_USER_EXECUTE & ~SAMR_USER_ACCESS_CHANGE_PASSWORD,
107         GENERIC_RIGHTS_USER_ALL_ACCESS};
108 static const struct generic_mapping grp_generic_mapping = {
109         GENERIC_RIGHTS_GROUP_READ,
110         GENERIC_RIGHTS_GROUP_WRITE,
111         GENERIC_RIGHTS_GROUP_EXECUTE,
112         GENERIC_RIGHTS_GROUP_ALL_ACCESS};
113 static const struct generic_mapping ali_generic_mapping = {
114         GENERIC_RIGHTS_ALIAS_READ,
115         GENERIC_RIGHTS_ALIAS_WRITE,
116         GENERIC_RIGHTS_ALIAS_EXECUTE,
117         GENERIC_RIGHTS_ALIAS_ALL_ACCESS};
118
119 /*******************************************************************
120 *******************************************************************/
121
122 static NTSTATUS make_samr_object_sd( TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size,
123                                      const struct generic_mapping *map,
124                                      DOM_SID *sid, uint32 sid_access )
125 {
126         DOM_SID domadmin_sid;
127         SEC_ACE ace[5];         /* at most 5 entries */
128         size_t i = 0;
129
130         SEC_ACL *psa = NULL;
131
132         /* basic access for Everyone */
133
134         init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
135                         map->generic_execute | map->generic_read, 0);
136
137         /* add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
138
139         init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
140                         SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
141         init_sec_ace(&ace[i++], &global_sid_Builtin_Account_Operators,
142                         SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
143
144         /* Add Full Access for Domain Admins if we are a DC */
145
146         if ( IS_DC ) {
147                 sid_copy( &domadmin_sid, get_global_sam_sid() );
148                 sid_append_rid( &domadmin_sid, DOMAIN_GROUP_RID_ADMINS );
149                 init_sec_ace(&ace[i++], &domadmin_sid,
150                         SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
151         }
152
153         /* if we have a sid, give it some special access */
154
155         if ( sid ) {
156                 init_sec_ace(&ace[i++], sid, SEC_ACE_TYPE_ACCESS_ALLOWED, sid_access, 0);
157         }
158
159         /* create the security descriptor */
160
161         if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) == NULL)
162                 return NT_STATUS_NO_MEMORY;
163
164         if ((*psd = make_sec_desc(ctx, SECURITY_DESCRIPTOR_REVISION_1,
165                                   SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL,
166                                   psa, sd_size)) == NULL)
167                 return NT_STATUS_NO_MEMORY;
168
169         return NT_STATUS_OK;
170 }
171
172 /*******************************************************************
173  Checks if access to an object should be granted, and returns that
174  level of access for further checks.
175 ********************************************************************/
176
177 NTSTATUS access_check_object( SEC_DESC *psd, NT_USER_TOKEN *token,
178                                           SE_PRIV *rights, uint32 rights_mask,
179                                           uint32 des_access, uint32 *acc_granted,
180                                           const char *debug )
181 {
182         NTSTATUS status = NT_STATUS_ACCESS_DENIED;
183         uint32 saved_mask = 0;
184
185         /* check privileges; certain SAM access bits should be overridden
186            by privileges (mostly having to do with creating/modifying/deleting
187            users and groups) */
188
189         if (rights && !se_priv_equal(rights, &se_priv_none) &&
190                         user_has_any_privilege(token, rights)) {
191
192                 saved_mask = (des_access & rights_mask);
193                 des_access &= ~saved_mask;
194
195                 DEBUG(4,("access_check_object: user rights access mask [0x%x]\n",
196                         rights_mask));
197         }
198
199
200         /* check the security descriptor first */
201
202         status = se_access_check(psd, token, des_access, acc_granted);
203         if (NT_STATUS_IS_OK(status)) {
204                 goto done;
205         }
206
207         /* give root a free pass */
208
209         if ( geteuid() == sec_initial_uid() ) {
210
211                 DEBUG(4,("%s: ACCESS should be DENIED  (requested: %#010x)\n", debug, des_access));
212                 DEBUGADD(4,("but overritten by euid == sec_initial_uid()\n"));
213
214                 *acc_granted = des_access;
215
216                 status = NT_STATUS_OK;
217                 goto done;
218         }
219
220
221 done:
222         /* add in any bits saved during the privilege check (only
223            matters is status is ok) */
224
225         *acc_granted |= rights_mask;
226
227         DEBUG(4,("%s: access %s (requested: 0x%08x, granted: 0x%08x)\n",
228                 debug, NT_STATUS_IS_OK(status) ? "GRANTED" : "DENIED",
229                 des_access, *acc_granted));
230
231         return status;
232 }
233
234
235 /*******************************************************************
236  Map any MAXIMUM_ALLOWED_ACCESS request to a valid access set.
237 ********************************************************************/
238
239 void map_max_allowed_access(const NT_USER_TOKEN *token,
240                                         uint32_t *pacc_requested)
241 {
242         if (!((*pacc_requested) & MAXIMUM_ALLOWED_ACCESS)) {
243                 return;
244         }
245         *pacc_requested &= ~MAXIMUM_ALLOWED_ACCESS;
246
247         /* At least try for generic read|execute - Everyone gets that. */
248         *pacc_requested = GENERIC_READ_ACCESS|GENERIC_EXECUTE_ACCESS;
249
250         /* root gets anything. */
251         if (geteuid() == sec_initial_uid()) {
252                 *pacc_requested |= GENERIC_ALL_ACCESS;
253                 return;
254         }
255
256         /* Full Access for 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
257
258         if (is_sid_in_token(token, &global_sid_Builtin_Administrators) ||
259                         is_sid_in_token(token, &global_sid_Builtin_Account_Operators)) {
260                 *pacc_requested |= GENERIC_ALL_ACCESS;
261                 return;
262         }
263
264         /* Full access for DOMAIN\Domain Admins. */
265         if ( IS_DC ) {
266                 DOM_SID domadmin_sid;
267                 sid_copy( &domadmin_sid, get_global_sam_sid() );
268                 sid_append_rid( &domadmin_sid, DOMAIN_GROUP_RID_ADMINS );
269                 if (is_sid_in_token(token, &domadmin_sid)) {
270                         *pacc_requested |= GENERIC_ALL_ACCESS;
271                         return;
272                 }
273         }
274         /* TODO ! Check privileges. */
275 }
276
277 /*******************************************************************
278  Fetch or create a dispinfo struct.
279 ********************************************************************/
280
281 static DISP_INFO *get_samr_dispinfo_by_sid(const struct dom_sid *psid)
282 {
283         /*
284          * We do a static cache for DISP_INFO's here. Explanation can be found
285          * in Jeremy's checkin message to r11793:
286          *
287          * Fix the SAMR cache so it works across completely insane
288          * client behaviour (ie.:
289          * open pipe/open SAMR handle/enumerate 0 - 1024
290          * close SAMR handle, close pipe.
291          * open pipe/open SAMR handle/enumerate 1024 - 2048...
292          * close SAMR handle, close pipe.
293          * And on ad-nausium. Amazing.... probably object-oriented
294          * client side programming in action yet again.
295          * This change should *massively* improve performance when
296          * enumerating users from an LDAP database.
297          * Jeremy.
298          *
299          * "Our" and the builtin domain are the only ones where we ever
300          * enumerate stuff, so just cache 2 entries.
301          */
302
303         static struct disp_info *builtin_dispinfo;
304         static struct disp_info *domain_dispinfo;
305
306         /* There are two cases to consider here:
307            1) The SID is a domain SID and we look for an equality match, or
308            2) This is an account SID and so we return the DISP_INFO* for our
309               domain */
310
311         if (psid == NULL) {
312                 return NULL;
313         }
314
315         if (sid_check_is_builtin(psid) || sid_check_is_in_builtin(psid)) {
316                 /*
317                  * Necessary only once, but it does not really hurt.
318                  */
319                 if (builtin_dispinfo == NULL) {
320                         builtin_dispinfo = talloc_zero(
321                                 talloc_autofree_context(), struct disp_info);
322                         if (builtin_dispinfo == NULL) {
323                                 return NULL;
324                         }
325                 }
326                 sid_copy(&builtin_dispinfo->sid, &global_sid_Builtin);
327
328                 return builtin_dispinfo;
329         }
330
331         if (sid_check_is_domain(psid) || sid_check_is_in_our_domain(psid)) {
332                 /*
333                  * Necessary only once, but it does not really hurt.
334                  */
335                 if (domain_dispinfo == NULL) {
336                         domain_dispinfo = talloc_zero(
337                                 talloc_autofree_context(), struct disp_info);
338                         if (domain_dispinfo == NULL) {
339                                 return NULL;
340                         }
341                 }
342                 sid_copy(&domain_dispinfo->sid, get_global_sam_sid());
343
344                 return domain_dispinfo;
345         }
346
347         return NULL;
348 }
349
350 /*******************************************************************
351  Function to free the per SID data.
352  ********************************************************************/
353
354 static void free_samr_cache(DISP_INFO *disp_info)
355 {
356         DEBUG(10, ("free_samr_cache: deleting cache for SID %s\n",
357                    sid_string_dbg(&disp_info->sid)));
358
359         /* We need to become root here because the paged search might have to
360          * tell the LDAP server we're not interested in the rest anymore. */
361
362         become_root();
363
364         TALLOC_FREE(disp_info->users);
365         TALLOC_FREE(disp_info->machines);
366         TALLOC_FREE(disp_info->groups);
367         TALLOC_FREE(disp_info->aliases);
368         TALLOC_FREE(disp_info->enum_users);
369
370         unbecome_root();
371 }
372
373 /*******************************************************************
374  Idle event handler. Throw away the disp info cache.
375  ********************************************************************/
376
377 static void disp_info_cache_idle_timeout_handler(struct event_context *ev_ctx,
378                                                  struct timed_event *te,
379                                                  struct timeval now,
380                                                  void *private_data)
381 {
382         DISP_INFO *disp_info = (DISP_INFO *)private_data;
383
384         TALLOC_FREE(disp_info->cache_timeout_event);
385
386         DEBUG(10, ("disp_info_cache_idle_timeout_handler: caching timed "
387                    "out\n"));
388         free_samr_cache(disp_info);
389 }
390
391 /*******************************************************************
392  Setup cache removal idle event handler.
393  ********************************************************************/
394
395 static void set_disp_info_cache_timeout(DISP_INFO *disp_info, time_t secs_fromnow)
396 {
397         /* Remove any pending timeout and update. */
398
399         TALLOC_FREE(disp_info->cache_timeout_event);
400
401         DEBUG(10,("set_disp_info_cache_timeout: caching enumeration for "
402                   "SID %s for %u seconds\n", sid_string_dbg(&disp_info->sid),
403                   (unsigned int)secs_fromnow ));
404
405         disp_info->cache_timeout_event = event_add_timed(
406                 smbd_event_context(), NULL,
407                 timeval_current_ofs(secs_fromnow, 0),
408                 disp_info_cache_idle_timeout_handler, (void *)disp_info);
409 }
410
411 /*******************************************************************
412  Force flush any cache. We do this on any samr_set_xxx call.
413  We must also remove the timeout handler.
414  ********************************************************************/
415
416 static void force_flush_samr_cache(const struct dom_sid *sid)
417 {
418         struct disp_info *disp_info = get_samr_dispinfo_by_sid(sid);
419
420         if ((disp_info == NULL) || (disp_info->cache_timeout_event == NULL)) {
421                 return;
422         }
423
424         DEBUG(10,("force_flush_samr_cache: clearing idle event\n"));
425         TALLOC_FREE(disp_info->cache_timeout_event);
426         free_samr_cache(disp_info);
427 }
428
429 /*******************************************************************
430  Ensure password info is never given out. Paranioa... JRA.
431  ********************************************************************/
432
433 static void samr_clear_sam_passwd(struct samu *sam_pass)
434 {
435
436         if (!sam_pass)
437                 return;
438
439         /* These now zero out the old password */
440
441         pdb_set_lanman_passwd(sam_pass, NULL, PDB_DEFAULT);
442         pdb_set_nt_passwd(sam_pass, NULL, PDB_DEFAULT);
443 }
444
445 static uint32 count_sam_users(struct disp_info *info, uint32 acct_flags)
446 {
447         struct samr_displayentry *entry;
448
449         if (sid_check_is_builtin(&info->sid)) {
450                 /* No users in builtin. */
451                 return 0;
452         }
453
454         if (info->users == NULL) {
455                 info->users = pdb_search_users(info, acct_flags);
456                 if (info->users == NULL) {
457                         return 0;
458                 }
459         }
460         /* Fetch the last possible entry, thus trigger an enumeration */
461         pdb_search_entries(info->users, 0xffffffff, 1, &entry);
462
463         /* Ensure we cache this enumeration. */
464         set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
465
466         return info->users->num_entries;
467 }
468
469 static uint32 count_sam_groups(struct disp_info *info)
470 {
471         struct samr_displayentry *entry;
472
473         if (sid_check_is_builtin(&info->sid)) {
474                 /* No groups in builtin. */
475                 return 0;
476         }
477
478         if (info->groups == NULL) {
479                 info->groups = pdb_search_groups(info);
480                 if (info->groups == NULL) {
481                         return 0;
482                 }
483         }
484         /* Fetch the last possible entry, thus trigger an enumeration */
485         pdb_search_entries(info->groups, 0xffffffff, 1, &entry);
486
487         /* Ensure we cache this enumeration. */
488         set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
489
490         return info->groups->num_entries;
491 }
492
493 static uint32 count_sam_aliases(struct disp_info *info)
494 {
495         struct samr_displayentry *entry;
496
497         if (info->aliases == NULL) {
498                 info->aliases = pdb_search_aliases(info, &info->sid);
499                 if (info->aliases == NULL) {
500                         return 0;
501                 }
502         }
503         /* Fetch the last possible entry, thus trigger an enumeration */
504         pdb_search_entries(info->aliases, 0xffffffff, 1, &entry);
505
506         /* Ensure we cache this enumeration. */
507         set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
508
509         return info->aliases->num_entries;
510 }
511
512 /*******************************************************************
513  _samr_Close
514  ********************************************************************/
515
516 NTSTATUS _samr_Close(pipes_struct *p, struct samr_Close *r)
517 {
518         if (!close_policy_hnd(p, r->in.handle)) {
519                 return NT_STATUS_INVALID_HANDLE;
520         }
521
522         ZERO_STRUCTP(r->out.handle);
523
524         return NT_STATUS_OK;
525 }
526
527 /*******************************************************************
528  _samr_OpenDomain
529  ********************************************************************/
530
531 NTSTATUS _samr_OpenDomain(pipes_struct *p,
532                           struct samr_OpenDomain *r)
533 {
534         struct samr_connect_info *cinfo;
535         struct samr_domain_info *dinfo;
536         SEC_DESC *psd = NULL;
537         uint32    acc_granted;
538         uint32    des_access = r->in.access_mask;
539         NTSTATUS  status;
540         size_t    sd_size;
541         uint32_t extra_access = SAMR_DOMAIN_ACCESS_CREATE_USER;
542         SE_PRIV se_rights;
543
544         /* find the connection policy handle. */
545
546         cinfo = policy_handle_find(p, r->in.connect_handle, 0, NULL,
547                                    struct samr_connect_info, &status);
548         if (!NT_STATUS_IS_OK(status)) {
549                 return status;
550         }
551
552         /*check if access can be granted as requested by client. */
553         map_max_allowed_access(p->server_info->ptok, &des_access);
554
555         make_samr_object_sd( p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0 );
556         se_map_generic( &des_access, &dom_generic_mapping );
557
558         /*
559          * Users with SeMachineAccount or SeAddUser get additional
560          * SAMR_DOMAIN_ACCESS_CREATE_USER access.
561          */
562         se_priv_copy( &se_rights, &se_machine_account );
563         se_priv_add( &se_rights, &se_add_users );
564
565         /*
566          * Users with SeAddUser get the ability to manipulate groups
567          * and aliases.
568          */
569         if (user_has_any_privilege(p->server_info->ptok, &se_add_users)) {
570                 extra_access |= (SAMR_DOMAIN_ACCESS_CREATE_GROUP |
571                                 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS |
572                                 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
573                                 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS |
574                                 SAMR_DOMAIN_ACCESS_CREATE_ALIAS);
575         }
576
577         status = access_check_object( psd, p->server_info->ptok,
578                 &se_rights, extra_access, des_access,
579                 &acc_granted, "_samr_OpenDomain" );
580
581         if ( !NT_STATUS_IS_OK(status) )
582                 return status;
583
584         if (!sid_check_is_domain(r->in.sid) &&
585             !sid_check_is_builtin(r->in.sid)) {
586                 return NT_STATUS_NO_SUCH_DOMAIN;
587         }
588
589         dinfo = policy_handle_create(p, r->out.domain_handle, acc_granted,
590                                      struct samr_domain_info, &status);
591         if (!NT_STATUS_IS_OK(status)) {
592                 return status;
593         }
594         dinfo->sid = *r->in.sid;
595         dinfo->disp_info = get_samr_dispinfo_by_sid(r->in.sid);
596
597         DEBUG(5,("_samr_OpenDomain: %d\n", __LINE__));
598
599         return NT_STATUS_OK;
600 }
601
602 /*******************************************************************
603  _samr_GetUserPwInfo
604  ********************************************************************/
605
606 NTSTATUS _samr_GetUserPwInfo(pipes_struct *p,
607                              struct samr_GetUserPwInfo *r)
608 {
609         struct samr_user_info *uinfo;
610         enum lsa_SidType sid_type;
611         uint32_t min_password_length = 0;
612         uint32_t password_properties = 0;
613         bool ret = false;
614         NTSTATUS status;
615
616         DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__));
617
618         uinfo = policy_handle_find(p, r->in.user_handle,
619                                    SAMR_USER_ACCESS_GET_ATTRIBUTES, NULL,
620                                    struct samr_user_info, &status);
621         if (!NT_STATUS_IS_OK(status)) {
622                 return status;
623         }
624
625         if (!sid_check_is_in_our_domain(&uinfo->sid)) {
626                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
627         }
628
629         become_root();
630         ret = lookup_sid(p->mem_ctx, &uinfo->sid, NULL, NULL, &sid_type);
631         unbecome_root();
632         if (ret == false) {
633                 return NT_STATUS_NO_SUCH_USER;
634         }
635
636         switch (sid_type) {
637                 case SID_NAME_USER:
638                         become_root();
639                         pdb_get_account_policy(AP_MIN_PASSWORD_LEN,
640                                                &min_password_length);
641                         pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
642                                                &password_properties);
643                         unbecome_root();
644
645                         if (lp_check_password_script() && *lp_check_password_script()) {
646                                 password_properties |= DOMAIN_PASSWORD_COMPLEX;
647                         }
648
649                         break;
650                 default:
651                         break;
652         }
653
654         r->out.info->min_password_length = min_password_length;
655         r->out.info->password_properties = password_properties;
656
657         DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__));
658
659         return NT_STATUS_OK;
660 }
661
662 /*******************************************************************
663  _samr_SetSecurity
664  ********************************************************************/
665
666 NTSTATUS _samr_SetSecurity(pipes_struct *p,
667                            struct samr_SetSecurity *r)
668 {
669         struct samr_user_info *uinfo;
670         uint32 i;
671         SEC_ACL *dacl;
672         bool ret;
673         struct samu *sampass=NULL;
674         NTSTATUS status;
675
676         uinfo = policy_handle_find(p, r->in.handle,
677                                    SAMR_USER_ACCESS_SET_ATTRIBUTES, NULL,
678                                    struct samr_user_info, &status);
679         if (!NT_STATUS_IS_OK(status)) {
680                 return status;
681         }
682
683         if (!(sampass = samu_new( p->mem_ctx))) {
684                 DEBUG(0,("No memory!\n"));
685                 return NT_STATUS_NO_MEMORY;
686         }
687
688         /* get the user record */
689         become_root();
690         ret = pdb_getsampwsid(sampass, &uinfo->sid);
691         unbecome_root();
692
693         if (!ret) {
694                 DEBUG(4, ("User %s not found\n",
695                           sid_string_dbg(&uinfo->sid)));
696                 TALLOC_FREE(sampass);
697                 return NT_STATUS_INVALID_HANDLE;
698         }
699
700         dacl = r->in.sdbuf->sd->dacl;
701         for (i=0; i < dacl->num_aces; i++) {
702                 if (sid_equal(&uinfo->sid, &dacl->aces[i].trustee)) {
703                         ret = pdb_set_pass_can_change(sampass,
704                                 (dacl->aces[i].access_mask &
705                                  SAMR_USER_ACCESS_CHANGE_PASSWORD) ?
706                                                       True: False);
707                         break;
708                 }
709         }
710
711         if (!ret) {
712                 TALLOC_FREE(sampass);
713                 return NT_STATUS_ACCESS_DENIED;
714         }
715
716         become_root();
717         status = pdb_update_sam_account(sampass);
718         unbecome_root();
719
720         TALLOC_FREE(sampass);
721
722         return status;
723 }
724
725 /*******************************************************************
726   build correct perms based on policies and password times for _samr_query_sec_obj
727 *******************************************************************/
728 static bool check_change_pw_access(TALLOC_CTX *mem_ctx, DOM_SID *user_sid)
729 {
730         struct samu *sampass=NULL;
731         bool ret;
732
733         if ( !(sampass = samu_new( mem_ctx )) ) {
734                 DEBUG(0,("No memory!\n"));
735                 return False;
736         }
737
738         become_root();
739         ret = pdb_getsampwsid(sampass, user_sid);
740         unbecome_root();
741
742         if (ret == False) {
743                 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
744                 TALLOC_FREE(sampass);
745                 return False;
746         }
747
748         DEBUG(3,("User:[%s]\n",  pdb_get_username(sampass) ));
749
750         if (pdb_get_pass_can_change(sampass)) {
751                 TALLOC_FREE(sampass);
752                 return True;
753         }
754         TALLOC_FREE(sampass);
755         return False;
756 }
757
758
759 /*******************************************************************
760  _samr_QuerySecurity
761  ********************************************************************/
762
763 NTSTATUS _samr_QuerySecurity(pipes_struct *p,
764                              struct samr_QuerySecurity *r)
765 {
766         struct samr_connect_info *cinfo;
767         struct samr_domain_info *dinfo;
768         struct samr_user_info *uinfo;
769         struct samr_group_info *ginfo;
770         struct samr_alias_info *ainfo;
771         NTSTATUS status;
772         SEC_DESC * psd = NULL;
773         size_t sd_size;
774
775         cinfo = policy_handle_find(p, r->in.handle,
776                                    STD_RIGHT_READ_CONTROL_ACCESS, NULL,
777                                    struct samr_connect_info, &status);
778         if (NT_STATUS_IS_OK(status)) {
779                 DEBUG(5,("_samr_QuerySecurity: querying security on SAM\n"));
780                 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size,
781                                              &sam_generic_mapping, NULL, 0);
782                 goto done;
783         }
784
785         dinfo = policy_handle_find(p, r->in.handle,
786                                    STD_RIGHT_READ_CONTROL_ACCESS, NULL,
787                                    struct samr_domain_info, &status);
788         if (NT_STATUS_IS_OK(status)) {
789                 DEBUG(5,("_samr_QuerySecurity: querying security on Domain "
790                          "with SID: %s\n", sid_string_dbg(&dinfo->sid)));
791                 /*
792                  * TODO: Builtin probably needs a different SD with restricted
793                  * write access
794                  */
795                 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size,
796                                              &dom_generic_mapping, NULL, 0);
797                 goto done;
798         }
799
800         uinfo = policy_handle_find(p, r->in.handle,
801                                    STD_RIGHT_READ_CONTROL_ACCESS, NULL,
802                                    struct samr_user_info, &status);
803         if (NT_STATUS_IS_OK(status)) {
804                 DEBUG(10,("_samr_QuerySecurity: querying security on user "
805                           "Object with SID: %s\n",
806                           sid_string_dbg(&uinfo->sid)));
807                 if (check_change_pw_access(p->mem_ctx, &uinfo->sid)) {
808                         status = make_samr_object_sd(
809                                 p->mem_ctx, &psd, &sd_size,
810                                 &usr_generic_mapping,
811                                 &uinfo->sid, SAMR_USR_RIGHTS_WRITE_PW);
812                 } else {
813                         status = make_samr_object_sd(
814                                 p->mem_ctx, &psd, &sd_size,
815                                 &usr_nopwchange_generic_mapping,
816                                 &uinfo->sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
817                 }
818                 goto done;
819         }
820
821         ginfo = policy_handle_find(p, r->in.handle,
822                                    STD_RIGHT_READ_CONTROL_ACCESS, NULL,
823                                    struct samr_group_info, &status);
824         if (NT_STATUS_IS_OK(status)) {
825                 /*
826                  * TODO: different SDs have to be generated for aliases groups
827                  * and users.  Currently all three get a default user SD
828                  */
829                 DEBUG(10,("_samr_QuerySecurity: querying security on group "
830                           "Object with SID: %s\n",
831                           sid_string_dbg(&ginfo->sid)));
832                 status = make_samr_object_sd(
833                         p->mem_ctx, &psd, &sd_size,
834                         &usr_nopwchange_generic_mapping,
835                         &ginfo->sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
836                 goto done;
837         }
838
839         ainfo = policy_handle_find(p, r->in.handle,
840                                    STD_RIGHT_READ_CONTROL_ACCESS, NULL,
841                                    struct samr_alias_info, &status);
842         if (NT_STATUS_IS_OK(status)) {
843                 /*
844                  * TODO: different SDs have to be generated for aliases groups
845                  * and users.  Currently all three get a default user SD
846                  */
847                 DEBUG(10,("_samr_QuerySecurity: querying security on alias "
848                           "Object with SID: %s\n",
849                           sid_string_dbg(&ainfo->sid)));
850                 status = make_samr_object_sd(
851                         p->mem_ctx, &psd, &sd_size,
852                         &usr_nopwchange_generic_mapping,
853                         &ainfo->sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
854                 goto done;
855         }
856
857         return NT_STATUS_OBJECT_TYPE_MISMATCH;
858 done:
859         if ((*r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
860                 return NT_STATUS_NO_MEMORY;
861
862         return status;
863 }
864
865 /*******************************************************************
866 makes a SAM_ENTRY / UNISTR2* structure from a user list.
867 ********************************************************************/
868
869 static NTSTATUS make_user_sam_entry_list(TALLOC_CTX *ctx,
870                                          struct samr_SamEntry **sam_pp,
871                                          uint32_t num_entries,
872                                          uint32_t start_idx,
873                                          struct samr_displayentry *entries)
874 {
875         uint32_t i;
876         struct samr_SamEntry *sam;
877
878         *sam_pp = NULL;
879
880         if (num_entries == 0) {
881                 return NT_STATUS_OK;
882         }
883
884         sam = TALLOC_ZERO_ARRAY(ctx, struct samr_SamEntry, num_entries);
885         if (sam == NULL) {
886                 DEBUG(0, ("make_user_sam_entry_list: TALLOC_ZERO failed!\n"));
887                 return NT_STATUS_NO_MEMORY;
888         }
889
890         for (i = 0; i < num_entries; i++) {
891 #if 0
892                 /*
893                  * usrmgr expects a non-NULL terminated string with
894                  * trust relationships
895                  */
896                 if (entries[i].acct_flags & ACB_DOMTRUST) {
897                         init_unistr2(&uni_temp_name, entries[i].account_name,
898                                      UNI_FLAGS_NONE);
899                 } else {
900                         init_unistr2(&uni_temp_name, entries[i].account_name,
901                                      UNI_STR_TERMINATE);
902                 }
903 #endif
904                 init_lsa_String(&sam[i].name, entries[i].account_name);
905                 sam[i].idx = entries[i].rid;
906         }
907
908         *sam_pp = sam;
909
910         return NT_STATUS_OK;
911 }
912
913 #define MAX_SAM_ENTRIES MAX_SAM_ENTRIES_W2K
914
915 /*******************************************************************
916  _samr_EnumDomainUsers
917  ********************************************************************/
918
919 NTSTATUS _samr_EnumDomainUsers(pipes_struct *p,
920                                struct samr_EnumDomainUsers *r)
921 {
922         NTSTATUS status;
923         struct samr_domain_info *dinfo;
924         int num_account;
925         uint32 enum_context = *r->in.resume_handle;
926         enum remote_arch_types ra_type = get_remote_arch();
927         int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
928         uint32 max_entries = max_sam_entries;
929         struct samr_displayentry *entries = NULL;
930         struct samr_SamArray *samr_array = NULL;
931         struct samr_SamEntry *samr_entries = NULL;
932
933         DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
934
935         dinfo = policy_handle_find(p, r->in.domain_handle,
936                                    SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
937                                    struct samr_domain_info, &status);
938         if (!NT_STATUS_IS_OK(status)) {
939                 return status;
940         }
941
942         samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
943         if (!samr_array) {
944                 return NT_STATUS_NO_MEMORY;
945         }
946         *r->out.sam = samr_array;
947
948         if (sid_check_is_builtin(&dinfo->sid)) {
949                 /* No users in builtin. */
950                 *r->out.resume_handle = *r->in.resume_handle;
951                 DEBUG(5,("_samr_EnumDomainUsers: No users in BUILTIN\n"));
952                 return status;
953         }
954
955         become_root();
956
957         /* AS ROOT !!!! */
958
959         if ((dinfo->disp_info->enum_users != NULL) &&
960             (dinfo->disp_info->enum_acb_mask != r->in.acct_flags)) {
961                 TALLOC_FREE(dinfo->disp_info->enum_users);
962         }
963
964         if (dinfo->disp_info->enum_users == NULL) {
965                 dinfo->disp_info->enum_users = pdb_search_users(
966                         dinfo->disp_info, r->in.acct_flags);
967                 dinfo->disp_info->enum_acb_mask = r->in.acct_flags;
968         }
969
970         if (dinfo->disp_info->enum_users == NULL) {
971                 /* END AS ROOT !!!! */
972                 unbecome_root();
973                 return NT_STATUS_ACCESS_DENIED;
974         }
975
976         num_account = pdb_search_entries(dinfo->disp_info->enum_users,
977                                          enum_context, max_entries,
978                                          &entries);
979
980         /* END AS ROOT !!!! */
981
982         unbecome_root();
983
984         if (num_account == 0) {
985                 DEBUG(5, ("_samr_EnumDomainUsers: enumeration handle over "
986                           "total entries\n"));
987                 *r->out.resume_handle = *r->in.resume_handle;
988                 return NT_STATUS_OK;
989         }
990
991         status = make_user_sam_entry_list(p->mem_ctx, &samr_entries,
992                                           num_account, enum_context,
993                                           entries);
994         if (!NT_STATUS_IS_OK(status)) {
995                 return status;
996         }
997
998         if (max_entries <= num_account) {
999                 status = STATUS_MORE_ENTRIES;
1000         } else {
1001                 status = NT_STATUS_OK;
1002         }
1003
1004         /* Ensure we cache this enumeration. */
1005         set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
1006
1007         DEBUG(5, ("_samr_EnumDomainUsers: %d\n", __LINE__));
1008
1009         samr_array->count = num_account;
1010         samr_array->entries = samr_entries;
1011
1012         *r->out.resume_handle = *r->in.resume_handle + num_account;
1013         *r->out.num_entries = num_account;
1014
1015         DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
1016
1017         return status;
1018 }
1019
1020 /*******************************************************************
1021 makes a SAM_ENTRY / UNISTR2* structure from a group list.
1022 ********************************************************************/
1023
1024 static void make_group_sam_entry_list(TALLOC_CTX *ctx,
1025                                       struct samr_SamEntry **sam_pp,
1026                                       uint32_t num_sam_entries,
1027                                       struct samr_displayentry *entries)
1028 {
1029         struct samr_SamEntry *sam;
1030         uint32_t i;
1031
1032         *sam_pp = NULL;
1033
1034         if (num_sam_entries == 0) {
1035                 return;
1036         }
1037
1038         sam = TALLOC_ZERO_ARRAY(ctx, struct samr_SamEntry, num_sam_entries);
1039         if (sam == NULL) {
1040                 return;
1041         }
1042
1043         for (i = 0; i < num_sam_entries; i++) {
1044                 /*
1045                  * JRA. I think this should include the null. TNG does not.
1046                  */
1047                 init_lsa_String(&sam[i].name, entries[i].account_name);
1048                 sam[i].idx = entries[i].rid;
1049         }
1050
1051         *sam_pp = sam;
1052 }
1053
1054 /*******************************************************************
1055  _samr_EnumDomainGroups
1056  ********************************************************************/
1057
1058 NTSTATUS _samr_EnumDomainGroups(pipes_struct *p,
1059                                 struct samr_EnumDomainGroups *r)
1060 {
1061         NTSTATUS status;
1062         struct samr_domain_info *dinfo;
1063         struct samr_displayentry *groups;
1064         uint32 num_groups;
1065         struct samr_SamArray *samr_array = NULL;
1066         struct samr_SamEntry *samr_entries = NULL;
1067
1068         dinfo = policy_handle_find(p, r->in.domain_handle,
1069                                    SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
1070                                    struct samr_domain_info, &status);
1071         if (!NT_STATUS_IS_OK(status)) {
1072                 return status;
1073         }
1074
1075         DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
1076
1077         samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
1078         if (!samr_array) {
1079                 return NT_STATUS_NO_MEMORY;
1080         }
1081         *r->out.sam = samr_array;
1082
1083         if (sid_check_is_builtin(&dinfo->sid)) {
1084                 /* No groups in builtin. */
1085                 *r->out.resume_handle = *r->in.resume_handle;
1086                 DEBUG(5,("_samr_EnumDomainGroups: No groups in BUILTIN\n"));
1087                 return status;
1088         }
1089
1090         /* the domain group array is being allocated in the function below */
1091
1092         become_root();
1093
1094         if (dinfo->disp_info->groups == NULL) {
1095                 dinfo->disp_info->groups = pdb_search_groups(dinfo->disp_info);
1096
1097                 if (dinfo->disp_info->groups == NULL) {
1098                         unbecome_root();
1099                         return NT_STATUS_ACCESS_DENIED;
1100                 }
1101         }
1102
1103         num_groups = pdb_search_entries(dinfo->disp_info->groups,
1104                                         *r->in.resume_handle,
1105                                         MAX_SAM_ENTRIES, &groups);
1106         unbecome_root();
1107
1108         /* Ensure we cache this enumeration. */
1109         set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
1110
1111         make_group_sam_entry_list(p->mem_ctx, &samr_entries,
1112                                   num_groups, groups);
1113
1114         if (MAX_SAM_ENTRIES <= num_groups) {
1115                 status = STATUS_MORE_ENTRIES;
1116         } else {
1117                 status = NT_STATUS_OK;
1118         }
1119
1120         samr_array->count = num_groups;
1121         samr_array->entries = samr_entries;
1122
1123         *r->out.num_entries = num_groups;
1124         *r->out.resume_handle = num_groups + *r->in.resume_handle;
1125
1126         DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
1127
1128         return status;
1129 }
1130
1131 /*******************************************************************
1132  _samr_EnumDomainAliases
1133  ********************************************************************/
1134
1135 NTSTATUS _samr_EnumDomainAliases(pipes_struct *p,
1136                                  struct samr_EnumDomainAliases *r)
1137 {
1138         NTSTATUS status;
1139         struct samr_domain_info *dinfo;
1140         struct samr_displayentry *aliases;
1141         uint32 num_aliases = 0;
1142         struct samr_SamArray *samr_array = NULL;
1143         struct samr_SamEntry *samr_entries = NULL;
1144
1145         dinfo = policy_handle_find(p, r->in.domain_handle,
1146                                    SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
1147                                    struct samr_domain_info, &status);
1148         if (!NT_STATUS_IS_OK(status)) {
1149                 return status;
1150         }
1151
1152         DEBUG(5,("_samr_EnumDomainAliases: sid %s\n",
1153                  sid_string_dbg(&dinfo->sid)));
1154
1155         samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
1156         if (!samr_array) {
1157                 return NT_STATUS_NO_MEMORY;
1158         }
1159
1160         become_root();
1161
1162         if (dinfo->disp_info->aliases == NULL) {
1163                 dinfo->disp_info->aliases = pdb_search_aliases(
1164                         dinfo->disp_info, &dinfo->sid);
1165                 if (dinfo->disp_info->aliases == NULL) {
1166                         unbecome_root();
1167                         return NT_STATUS_ACCESS_DENIED;
1168                 }
1169         }
1170
1171         num_aliases = pdb_search_entries(dinfo->disp_info->aliases,
1172                                          *r->in.resume_handle,
1173                                          MAX_SAM_ENTRIES, &aliases);
1174         unbecome_root();
1175
1176         /* Ensure we cache this enumeration. */
1177         set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
1178
1179         make_group_sam_entry_list(p->mem_ctx, &samr_entries,
1180                                   num_aliases, aliases);
1181
1182         DEBUG(5,("_samr_EnumDomainAliases: %d\n", __LINE__));
1183
1184         if (MAX_SAM_ENTRIES <= num_aliases) {
1185                 status = STATUS_MORE_ENTRIES;
1186         } else {
1187                 status = NT_STATUS_OK;
1188         }
1189
1190         samr_array->count = num_aliases;
1191         samr_array->entries = samr_entries;
1192
1193         *r->out.sam = samr_array;
1194         *r->out.num_entries = num_aliases;
1195         *r->out.resume_handle = num_aliases + *r->in.resume_handle;
1196
1197         return status;
1198 }
1199
1200 /*******************************************************************
1201  inits a samr_DispInfoGeneral structure.
1202 ********************************************************************/
1203
1204 static NTSTATUS init_samr_dispinfo_1(TALLOC_CTX *ctx,
1205                                      struct samr_DispInfoGeneral *r,
1206                                      uint32_t num_entries,
1207                                      uint32_t start_idx,
1208                                      struct samr_displayentry *entries)
1209 {
1210         uint32 i;
1211
1212         DEBUG(10, ("init_samr_dispinfo_1: num_entries: %d\n", num_entries));
1213
1214         if (num_entries == 0) {
1215                 return NT_STATUS_OK;
1216         }
1217
1218         r->count = num_entries;
1219
1220         r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryGeneral, num_entries);
1221         if (!r->entries) {
1222                 return NT_STATUS_NO_MEMORY;
1223         }
1224
1225         for (i = 0; i < num_entries ; i++) {
1226
1227                 init_lsa_String(&r->entries[i].account_name,
1228                                 entries[i].account_name);
1229
1230                 init_lsa_String(&r->entries[i].description,
1231                                 entries[i].description);
1232
1233                 init_lsa_String(&r->entries[i].full_name,
1234                                 entries[i].fullname);
1235
1236                 r->entries[i].rid = entries[i].rid;
1237                 r->entries[i].acct_flags = entries[i].acct_flags;
1238                 r->entries[i].idx = start_idx+i+1;
1239         }
1240
1241         return NT_STATUS_OK;
1242 }
1243
1244 /*******************************************************************
1245  inits a samr_DispInfoFull structure.
1246 ********************************************************************/
1247
1248 static NTSTATUS init_samr_dispinfo_2(TALLOC_CTX *ctx,
1249                                      struct samr_DispInfoFull *r,
1250                                      uint32_t num_entries,
1251                                      uint32_t start_idx,
1252                                      struct samr_displayentry *entries)
1253 {
1254         uint32_t i;
1255
1256         DEBUG(10, ("init_samr_dispinfo_2: num_entries: %d\n", num_entries));
1257
1258         if (num_entries == 0) {
1259                 return NT_STATUS_OK;
1260         }
1261
1262         r->count = num_entries;
1263
1264         r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryFull, num_entries);
1265         if (!r->entries) {
1266                 return NT_STATUS_NO_MEMORY;
1267         }
1268
1269         for (i = 0; i < num_entries ; i++) {
1270
1271                 init_lsa_String(&r->entries[i].account_name,
1272                                 entries[i].account_name);
1273
1274                 init_lsa_String(&r->entries[i].description,
1275                                 entries[i].description);
1276
1277                 r->entries[i].rid = entries[i].rid;
1278                 r->entries[i].acct_flags = entries[i].acct_flags;
1279                 r->entries[i].idx = start_idx+i+1;
1280         }
1281
1282         return NT_STATUS_OK;
1283 }
1284
1285 /*******************************************************************
1286  inits a samr_DispInfoFullGroups structure.
1287 ********************************************************************/
1288
1289 static NTSTATUS init_samr_dispinfo_3(TALLOC_CTX *ctx,
1290                                      struct samr_DispInfoFullGroups *r,
1291                                      uint32_t num_entries,
1292                                      uint32_t start_idx,
1293                                      struct samr_displayentry *entries)
1294 {
1295         uint32_t i;
1296
1297         DEBUG(5, ("init_samr_dispinfo_3: num_entries: %d\n", num_entries));
1298
1299         if (num_entries == 0) {
1300                 return NT_STATUS_OK;
1301         }
1302
1303         r->count = num_entries;
1304
1305         r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryFullGroup, num_entries);
1306         if (!r->entries) {
1307                 return NT_STATUS_NO_MEMORY;
1308         }
1309
1310         for (i = 0; i < num_entries ; i++) {
1311
1312                 init_lsa_String(&r->entries[i].account_name,
1313                                 entries[i].account_name);
1314
1315                 init_lsa_String(&r->entries[i].description,
1316                                 entries[i].description);
1317
1318                 r->entries[i].rid = entries[i].rid;
1319                 r->entries[i].acct_flags = entries[i].acct_flags;
1320                 r->entries[i].idx = start_idx+i+1;
1321         }
1322
1323         return NT_STATUS_OK;
1324 }
1325
1326 /*******************************************************************
1327  inits a samr_DispInfoAscii structure.
1328 ********************************************************************/
1329
1330 static NTSTATUS init_samr_dispinfo_4(TALLOC_CTX *ctx,
1331                                      struct samr_DispInfoAscii *r,
1332                                      uint32_t num_entries,
1333                                      uint32_t start_idx,
1334                                      struct samr_displayentry *entries)
1335 {
1336         uint32_t i;
1337
1338         DEBUG(5, ("init_samr_dispinfo_4: num_entries: %d\n", num_entries));
1339
1340         if (num_entries == 0) {
1341                 return NT_STATUS_OK;
1342         }
1343
1344         r->count = num_entries;
1345
1346         r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryAscii, num_entries);
1347         if (!r->entries) {
1348                 return NT_STATUS_NO_MEMORY;
1349         }
1350
1351         for (i = 0; i < num_entries ; i++) {
1352
1353                 init_lsa_AsciiStringLarge(&r->entries[i].account_name,
1354                                           entries[i].account_name);
1355
1356                 r->entries[i].idx = start_idx+i+1;
1357         }
1358
1359         return NT_STATUS_OK;
1360 }
1361
1362 /*******************************************************************
1363  inits a samr_DispInfoAscii structure.
1364 ********************************************************************/
1365
1366 static NTSTATUS init_samr_dispinfo_5(TALLOC_CTX *ctx,
1367                                      struct samr_DispInfoAscii *r,
1368                                      uint32_t num_entries,
1369                                      uint32_t start_idx,
1370                                      struct samr_displayentry *entries)
1371 {
1372         uint32_t i;
1373
1374         DEBUG(5, ("init_samr_dispinfo_5: num_entries: %d\n", num_entries));
1375
1376         if (num_entries == 0) {
1377                 return NT_STATUS_OK;
1378         }
1379
1380         r->count = num_entries;
1381
1382         r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryAscii, num_entries);
1383         if (!r->entries) {
1384                 return NT_STATUS_NO_MEMORY;
1385         }
1386
1387         for (i = 0; i < num_entries ; i++) {
1388
1389                 init_lsa_AsciiStringLarge(&r->entries[i].account_name,
1390                                           entries[i].account_name);
1391
1392                 r->entries[i].idx = start_idx+i+1;
1393         }
1394
1395         return NT_STATUS_OK;
1396 }
1397
1398 /*******************************************************************
1399  _samr_QueryDisplayInfo
1400  ********************************************************************/
1401
1402 NTSTATUS _samr_QueryDisplayInfo(pipes_struct *p,
1403                                 struct samr_QueryDisplayInfo *r)
1404 {
1405         NTSTATUS status;
1406         struct samr_domain_info *dinfo;
1407         uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
1408
1409         uint32 max_entries = r->in.max_entries;
1410
1411         union samr_DispInfo *disp_info = r->out.info;
1412
1413         uint32 temp_size=0;
1414         NTSTATUS disp_ret = NT_STATUS_UNSUCCESSFUL;
1415         uint32 num_account = 0;
1416         enum remote_arch_types ra_type = get_remote_arch();
1417         int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
1418         struct samr_displayentry *entries = NULL;
1419
1420         DEBUG(5,("_samr_QueryDisplayInfo: %d\n", __LINE__));
1421
1422         dinfo = policy_handle_find(p, r->in.domain_handle,
1423                                    SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
1424                                    struct samr_domain_info, &status);
1425         if (!NT_STATUS_IS_OK(status)) {
1426                 return status;
1427         }
1428
1429         if (sid_check_is_builtin(&dinfo->sid)) {
1430                 DEBUG(5,("_samr_QueryDisplayInfo: no users in BUILTIN\n"));
1431                 return NT_STATUS_OK;
1432         }
1433
1434         /*
1435          * calculate how many entries we will return.
1436          * based on
1437          * - the number of entries the client asked
1438          * - our limit on that
1439          * - the starting point (enumeration context)
1440          * - the buffer size the client will accept
1441          */
1442
1443         /*
1444          * We are a lot more like W2K. Instead of reading the SAM
1445          * each time to find the records we need to send back,
1446          * we read it once and link that copy to the sam handle.
1447          * For large user list (over the MAX_SAM_ENTRIES)
1448          * it's a definitive win.
1449          * second point to notice: between enumerations
1450          * our sam is now the same as it's a snapshoot.
1451          * third point: got rid of the static SAM_USER_21 struct
1452          * no more intermediate.
1453          * con: it uses much more memory, as a full copy is stored
1454          * in memory.
1455          *
1456          * If you want to change it, think twice and think
1457          * of the second point , that's really important.
1458          *
1459          * JFM, 12/20/2001
1460          */
1461
1462         if ((r->in.level < 1) || (r->in.level > 5)) {
1463                 DEBUG(0,("_samr_QueryDisplayInfo: Unknown info level (%u)\n",
1464                          (unsigned int)r->in.level ));
1465                 return NT_STATUS_INVALID_INFO_CLASS;
1466         }
1467
1468         /* first limit the number of entries we will return */
1469         if (r->in.max_entries > max_sam_entries) {
1470                 DEBUG(5, ("_samr_QueryDisplayInfo: client requested %d "
1471                           "entries, limiting to %d\n", r->in.max_entries,
1472                           max_sam_entries));
1473                 max_entries = max_sam_entries;
1474         }
1475
1476         /* calculate the size and limit on the number of entries we will
1477          * return */
1478
1479         temp_size=max_entries*struct_size;
1480
1481         if (temp_size > r->in.buf_size) {
1482                 max_entries = MIN((r->in.buf_size / struct_size),max_entries);;
1483                 DEBUG(5, ("_samr_QueryDisplayInfo: buffer size limits to "
1484                           "only %d entries\n", max_entries));
1485         }
1486
1487         become_root();
1488
1489         /* THe following done as ROOT. Don't return without unbecome_root(). */
1490
1491         switch (r->in.level) {
1492         case 1:
1493         case 4:
1494                 if (dinfo->disp_info->users == NULL) {
1495                         dinfo->disp_info->users = pdb_search_users(
1496                                 dinfo->disp_info, ACB_NORMAL);
1497                         if (dinfo->disp_info->users == NULL) {
1498                                 unbecome_root();
1499                                 return NT_STATUS_ACCESS_DENIED;
1500                         }
1501                         DEBUG(10,("_samr_QueryDisplayInfo: starting user enumeration at index %u\n",
1502                                 (unsigned  int)r->in.start_idx));
1503                 } else {
1504                         DEBUG(10,("_samr_QueryDisplayInfo: using cached user enumeration at index %u\n",
1505                                 (unsigned  int)r->in.start_idx));
1506                 }
1507
1508                 num_account = pdb_search_entries(dinfo->disp_info->users,
1509                                                  r->in.start_idx, max_entries,
1510                                                  &entries);
1511                 break;
1512         case 2:
1513                 if (dinfo->disp_info->machines == NULL) {
1514                         dinfo->disp_info->machines = pdb_search_users(
1515                                 dinfo->disp_info, ACB_WSTRUST|ACB_SVRTRUST);
1516                         if (dinfo->disp_info->machines == NULL) {
1517                                 unbecome_root();
1518                                 return NT_STATUS_ACCESS_DENIED;
1519                         }
1520                         DEBUG(10,("_samr_QueryDisplayInfo: starting machine enumeration at index %u\n",
1521                                 (unsigned  int)r->in.start_idx));
1522                 } else {
1523                         DEBUG(10,("_samr_QueryDisplayInfo: using cached machine enumeration at index %u\n",
1524                                 (unsigned  int)r->in.start_idx));
1525                 }
1526
1527                 num_account = pdb_search_entries(dinfo->disp_info->machines,
1528                                                  r->in.start_idx, max_entries,
1529                                                  &entries);
1530                 break;
1531         case 3:
1532         case 5:
1533                 if (dinfo->disp_info->groups == NULL) {
1534                         dinfo->disp_info->groups = pdb_search_groups(
1535                                 dinfo->disp_info);
1536                         if (dinfo->disp_info->groups == NULL) {
1537                                 unbecome_root();
1538                                 return NT_STATUS_ACCESS_DENIED;
1539                         }
1540                         DEBUG(10,("_samr_QueryDisplayInfo: starting group enumeration at index %u\n",
1541                                 (unsigned  int)r->in.start_idx));
1542                 } else {
1543                         DEBUG(10,("_samr_QueryDisplayInfo: using cached group enumeration at index %u\n",
1544                                 (unsigned  int)r->in.start_idx));
1545                 }
1546
1547                 num_account = pdb_search_entries(dinfo->disp_info->groups,
1548                                                  r->in.start_idx, max_entries,
1549                                                  &entries);
1550                 break;
1551         default:
1552                 unbecome_root();
1553                 smb_panic("info class changed");
1554                 break;
1555         }
1556         unbecome_root();
1557
1558
1559         /* Now create reply structure */
1560         switch (r->in.level) {
1561         case 1:
1562                 disp_ret = init_samr_dispinfo_1(p->mem_ctx, &disp_info->info1,
1563                                                 num_account, r->in.start_idx,
1564                                                 entries);
1565                 break;
1566         case 2:
1567                 disp_ret = init_samr_dispinfo_2(p->mem_ctx, &disp_info->info2,
1568                                                 num_account, r->in.start_idx,
1569                                                 entries);
1570                 break;
1571         case 3:
1572                 disp_ret = init_samr_dispinfo_3(p->mem_ctx, &disp_info->info3,
1573                                                 num_account, r->in.start_idx,
1574                                                 entries);
1575                 break;
1576         case 4:
1577                 disp_ret = init_samr_dispinfo_4(p->mem_ctx, &disp_info->info4,
1578                                                 num_account, r->in.start_idx,
1579                                                 entries);
1580                 break;
1581         case 5:
1582                 disp_ret = init_samr_dispinfo_5(p->mem_ctx, &disp_info->info5,
1583                                                 num_account, r->in.start_idx,
1584                                                 entries);
1585                 break;
1586         default:
1587                 smb_panic("info class changed");
1588                 break;
1589         }
1590
1591         if (!NT_STATUS_IS_OK(disp_ret))
1592                 return disp_ret;
1593
1594         if (max_entries <= num_account) {
1595                 status = STATUS_MORE_ENTRIES;
1596         } else {
1597                 status = NT_STATUS_OK;
1598         }
1599
1600         /* Ensure we cache this enumeration. */
1601         set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
1602
1603         DEBUG(5, ("_samr_QueryDisplayInfo: %d\n", __LINE__));
1604
1605         *r->out.total_size = num_account * struct_size;
1606         *r->out.returned_size = num_account ? temp_size : 0;
1607
1608         return status;
1609 }
1610
1611 /****************************************************************
1612  _samr_QueryDisplayInfo2
1613 ****************************************************************/
1614
1615 NTSTATUS _samr_QueryDisplayInfo2(pipes_struct *p,
1616                                  struct samr_QueryDisplayInfo2 *r)
1617 {
1618         struct samr_QueryDisplayInfo q;
1619
1620         q.in.domain_handle      = r->in.domain_handle;
1621         q.in.level              = r->in.level;
1622         q.in.start_idx          = r->in.start_idx;
1623         q.in.max_entries        = r->in.max_entries;
1624         q.in.buf_size           = r->in.buf_size;
1625
1626         q.out.total_size        = r->out.total_size;
1627         q.out.returned_size     = r->out.returned_size;
1628         q.out.info              = r->out.info;
1629
1630         return _samr_QueryDisplayInfo(p, &q);
1631 }
1632
1633 /****************************************************************
1634  _samr_QueryDisplayInfo3
1635 ****************************************************************/
1636
1637 NTSTATUS _samr_QueryDisplayInfo3(pipes_struct *p,
1638                                  struct samr_QueryDisplayInfo3 *r)
1639 {
1640         struct samr_QueryDisplayInfo q;
1641
1642         q.in.domain_handle      = r->in.domain_handle;
1643         q.in.level              = r->in.level;
1644         q.in.start_idx          = r->in.start_idx;
1645         q.in.max_entries        = r->in.max_entries;
1646         q.in.buf_size           = r->in.buf_size;
1647
1648         q.out.total_size        = r->out.total_size;
1649         q.out.returned_size     = r->out.returned_size;
1650         q.out.info              = r->out.info;
1651
1652         return _samr_QueryDisplayInfo(p, &q);
1653 }
1654
1655 /*******************************************************************
1656  _samr_QueryAliasInfo
1657  ********************************************************************/
1658
1659 NTSTATUS _samr_QueryAliasInfo(pipes_struct *p,
1660                               struct samr_QueryAliasInfo *r)
1661 {
1662         struct samr_alias_info *ainfo;
1663         struct acct_info info;
1664         NTSTATUS status;
1665         union samr_AliasInfo *alias_info = NULL;
1666         const char *alias_name = NULL;
1667         const char *alias_description = NULL;
1668
1669         DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1670
1671         ainfo = policy_handle_find(p, r->in.alias_handle,
1672                                    SAMR_ALIAS_ACCESS_LOOKUP_INFO, NULL,
1673                                    struct samr_alias_info, &status);
1674         if (!NT_STATUS_IS_OK(status)) {
1675                 return status;
1676         }
1677
1678         alias_info = TALLOC_ZERO_P(p->mem_ctx, union samr_AliasInfo);
1679         if (!alias_info) {
1680                 return NT_STATUS_NO_MEMORY;
1681         }
1682
1683         become_root();
1684         status = pdb_get_aliasinfo(&ainfo->sid, &info);
1685         unbecome_root();
1686
1687         if ( !NT_STATUS_IS_OK(status))
1688                 return status;
1689
1690         /* FIXME: info contains fstrings */
1691         alias_name = talloc_strdup(r, info.acct_name);
1692         alias_description = talloc_strdup(r, info.acct_desc);
1693
1694         switch (r->in.level) {
1695         case ALIASINFOALL:
1696                 alias_info->all.name.string             = alias_name;
1697                 alias_info->all.num_members             = 1; /* ??? */
1698                 alias_info->all.description.string      = alias_description;
1699                 break;
1700         case ALIASINFONAME:
1701                 alias_info->name.string                 = alias_name;
1702                 break;
1703         case ALIASINFODESCRIPTION:
1704                 alias_info->description.string          = alias_description;
1705                 break;
1706         default:
1707                 return NT_STATUS_INVALID_INFO_CLASS;
1708         }
1709
1710         *r->out.info = alias_info;
1711
1712         DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1713
1714         return NT_STATUS_OK;
1715 }
1716
1717 /*******************************************************************
1718  _samr_LookupNames
1719  ********************************************************************/
1720
1721 NTSTATUS _samr_LookupNames(pipes_struct *p,
1722                            struct samr_LookupNames *r)
1723 {
1724         struct samr_domain_info *dinfo;
1725         NTSTATUS status;
1726         uint32 *rid;
1727         enum lsa_SidType *type;
1728         int i;
1729         int num_rids = r->in.num_names;
1730         struct samr_Ids rids, types;
1731         uint32_t num_mapped = 0;
1732
1733         DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1734
1735         dinfo = policy_handle_find(p, r->in.domain_handle,
1736                                    0 /* Don't know the acc_bits yet */, NULL,
1737                                    struct samr_domain_info, &status);
1738         if (!NT_STATUS_IS_OK(status)) {
1739                 return status;
1740         }
1741
1742         if (num_rids > MAX_SAM_ENTRIES) {
1743                 num_rids = MAX_SAM_ENTRIES;
1744                 DEBUG(5,("_samr_LookupNames: truncating entries to %d\n", num_rids));
1745         }
1746
1747         rid = talloc_array(p->mem_ctx, uint32, num_rids);
1748         NT_STATUS_HAVE_NO_MEMORY(rid);
1749
1750         type = talloc_array(p->mem_ctx, enum lsa_SidType, num_rids);
1751         NT_STATUS_HAVE_NO_MEMORY(type);
1752
1753         DEBUG(5,("_samr_LookupNames: looking name on SID %s\n",
1754                  sid_string_dbg(&dinfo->sid)));
1755
1756         for (i = 0; i < num_rids; i++) {
1757
1758                 status = NT_STATUS_NONE_MAPPED;
1759                 type[i] = SID_NAME_UNKNOWN;
1760
1761                 rid[i] = 0xffffffff;
1762
1763                 if (sid_check_is_builtin(&dinfo->sid)) {
1764                         if (lookup_builtin_name(r->in.names[i].string,
1765                                                 &rid[i]))
1766                         {
1767                                 type[i] = SID_NAME_ALIAS;
1768                         }
1769                 } else {
1770                         lookup_global_sam_name(r->in.names[i].string, 0,
1771                                                &rid[i], &type[i]);
1772                 }
1773
1774                 if (type[i] != SID_NAME_UNKNOWN) {
1775                         num_mapped++;
1776                 }
1777         }
1778
1779         if (num_mapped == num_rids) {
1780                 status = NT_STATUS_OK;
1781         } else if (num_mapped == 0) {
1782                 status = NT_STATUS_NONE_MAPPED;
1783         } else {
1784                 status = STATUS_SOME_UNMAPPED;
1785         }
1786
1787         rids.count = num_rids;
1788         rids.ids = rid;
1789
1790         types.count = num_rids;
1791         types.ids = type;
1792
1793         *r->out.rids = rids;
1794         *r->out.types = types;
1795
1796         DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1797
1798         return status;
1799 }
1800
1801 /****************************************************************
1802  _samr_ChangePasswordUser
1803 ****************************************************************/
1804
1805 NTSTATUS _samr_ChangePasswordUser(pipes_struct *p,
1806                                   struct samr_ChangePasswordUser *r)
1807 {
1808         NTSTATUS status;
1809         bool ret = false;
1810         struct samr_user_info *uinfo;
1811         struct samu *pwd;
1812         struct samr_Password new_lmPwdHash, new_ntPwdHash, checkHash;
1813         struct samr_Password lm_pwd, nt_pwd;
1814
1815         uinfo = policy_handle_find(p, r->in.user_handle,
1816                                    SAMR_USER_ACCESS_SET_PASSWORD, NULL,
1817                                    struct samr_user_info, &status);
1818         if (!NT_STATUS_IS_OK(status)) {
1819                 return status;
1820         }
1821
1822         DEBUG(5,("_samr_ChangePasswordUser: sid:%s\n",
1823                   sid_string_dbg(&uinfo->sid)));
1824
1825         if (!(pwd = samu_new(NULL))) {
1826                 return NT_STATUS_NO_MEMORY;
1827         }
1828
1829         become_root();
1830         ret = pdb_getsampwsid(pwd, &uinfo->sid);
1831         unbecome_root();
1832
1833         if (!ret) {
1834                 TALLOC_FREE(pwd);
1835                 return NT_STATUS_WRONG_PASSWORD;
1836         }
1837
1838         {
1839                 const uint8_t *lm_pass, *nt_pass;
1840
1841                 lm_pass = pdb_get_lanman_passwd(pwd);
1842                 nt_pass = pdb_get_nt_passwd(pwd);
1843
1844                 if (!lm_pass || !nt_pass) {
1845                         status = NT_STATUS_WRONG_PASSWORD;
1846                         goto out;
1847                 }
1848
1849                 memcpy(&lm_pwd.hash, lm_pass, sizeof(lm_pwd.hash));
1850                 memcpy(&nt_pwd.hash, nt_pass, sizeof(nt_pwd.hash));
1851         }
1852
1853         /* basic sanity checking on parameters.  Do this before any database ops */
1854         if (!r->in.lm_present || !r->in.nt_present ||
1855             !r->in.old_lm_crypted || !r->in.new_lm_crypted ||
1856             !r->in.old_nt_crypted || !r->in.new_nt_crypted) {
1857                 /* we should really handle a change with lm not
1858                    present */
1859                 status = NT_STATUS_INVALID_PARAMETER_MIX;
1860                 goto out;
1861         }
1862
1863         /* decrypt and check the new lm hash */
1864         D_P16(lm_pwd.hash, r->in.new_lm_crypted->hash, new_lmPwdHash.hash);
1865         D_P16(new_lmPwdHash.hash, r->in.old_lm_crypted->hash, checkHash.hash);
1866         if (memcmp(checkHash.hash, lm_pwd.hash, 16) != 0) {
1867                 status = NT_STATUS_WRONG_PASSWORD;
1868                 goto out;
1869         }
1870
1871         /* decrypt and check the new nt hash */
1872         D_P16(nt_pwd.hash, r->in.new_nt_crypted->hash, new_ntPwdHash.hash);
1873         D_P16(new_ntPwdHash.hash, r->in.old_nt_crypted->hash, checkHash.hash);
1874         if (memcmp(checkHash.hash, nt_pwd.hash, 16) != 0) {
1875                 status = NT_STATUS_WRONG_PASSWORD;
1876                 goto out;
1877         }
1878
1879         /* The NT Cross is not required by Win2k3 R2, but if present
1880            check the nt cross hash */
1881         if (r->in.cross1_present && r->in.nt_cross) {
1882                 D_P16(lm_pwd.hash, r->in.nt_cross->hash, checkHash.hash);
1883                 if (memcmp(checkHash.hash, new_ntPwdHash.hash, 16) != 0) {
1884                         status = NT_STATUS_WRONG_PASSWORD;
1885                         goto out;
1886                 }
1887         }
1888
1889         /* The LM Cross is not required by Win2k3 R2, but if present
1890            check the lm cross hash */
1891         if (r->in.cross2_present && r->in.lm_cross) {
1892                 D_P16(nt_pwd.hash, r->in.lm_cross->hash, checkHash.hash);
1893                 if (memcmp(checkHash.hash, new_lmPwdHash.hash, 16) != 0) {
1894                         status = NT_STATUS_WRONG_PASSWORD;
1895                         goto out;
1896                 }
1897         }
1898
1899         if (!pdb_set_nt_passwd(pwd, new_ntPwdHash.hash, PDB_CHANGED) ||
1900             !pdb_set_lanman_passwd(pwd, new_lmPwdHash.hash, PDB_CHANGED)) {
1901                 status = NT_STATUS_ACCESS_DENIED;
1902                 goto out;
1903         }
1904
1905         status = pdb_update_sam_account(pwd);
1906  out:
1907         TALLOC_FREE(pwd);
1908
1909         return status;
1910 }
1911
1912 /*******************************************************************
1913  _samr_ChangePasswordUser2
1914  ********************************************************************/
1915
1916 NTSTATUS _samr_ChangePasswordUser2(pipes_struct *p,
1917                                    struct samr_ChangePasswordUser2 *r)
1918 {
1919         struct smbd_server_connection *sconn = smbd_server_conn;
1920         NTSTATUS status;
1921         fstring user_name;
1922         fstring wks;
1923
1924         DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1925
1926         fstrcpy(user_name, r->in.account->string);
1927         fstrcpy(wks, r->in.server->string);
1928
1929         DEBUG(5,("_samr_ChangePasswordUser2: user: %s wks: %s\n", user_name, wks));
1930
1931         /*
1932          * Pass the user through the NT -> unix user mapping
1933          * function.
1934          */
1935
1936         (void)map_username(sconn, user_name);
1937
1938         /*
1939          * UNIX username case mangling not required, pass_oem_change
1940          * is case insensitive.
1941          */
1942
1943         status = pass_oem_change(user_name,
1944                                  r->in.lm_password->data,
1945                                  r->in.lm_verifier->hash,
1946                                  r->in.nt_password->data,
1947                                  r->in.nt_verifier->hash,
1948                                  NULL);
1949
1950         DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1951
1952         if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
1953                 return NT_STATUS_WRONG_PASSWORD;
1954         }
1955
1956         return status;
1957 }
1958
1959 /****************************************************************
1960  _samr_OemChangePasswordUser2
1961 ****************************************************************/
1962
1963 NTSTATUS _samr_OemChangePasswordUser2(pipes_struct *p,
1964                                       struct samr_OemChangePasswordUser2 *r)
1965 {
1966         struct smbd_server_connection *sconn = smbd_server_conn;
1967         NTSTATUS status;
1968         fstring user_name;
1969         const char *wks = NULL;
1970
1971         DEBUG(5,("_samr_OemChangePasswordUser2: %d\n", __LINE__));
1972
1973         fstrcpy(user_name, r->in.account->string);
1974         if (r->in.server && r->in.server->string) {
1975                 wks = r->in.server->string;
1976         }
1977
1978         DEBUG(5,("_samr_OemChangePasswordUser2: user: %s wks: %s\n", user_name, wks));
1979
1980         /*
1981          * Pass the user through the NT -> unix user mapping
1982          * function.
1983          */
1984
1985         (void)map_username(sconn, user_name);
1986
1987         /*
1988          * UNIX username case mangling not required, pass_oem_change
1989          * is case insensitive.
1990          */
1991
1992         if (!r->in.hash || !r->in.password) {
1993                 return NT_STATUS_INVALID_PARAMETER;
1994         }
1995
1996         status = pass_oem_change(user_name,
1997                                  r->in.password->data,
1998                                  r->in.hash->hash,
1999                                  0,
2000                                  0,
2001                                  NULL);
2002
2003         if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
2004                 return NT_STATUS_WRONG_PASSWORD;
2005         }
2006
2007         DEBUG(5,("_samr_OemChangePasswordUser2: %d\n", __LINE__));
2008
2009         return status;
2010 }
2011
2012 /*******************************************************************
2013  _samr_ChangePasswordUser3
2014  ********************************************************************/
2015
2016 NTSTATUS _samr_ChangePasswordUser3(pipes_struct *p,
2017                                    struct samr_ChangePasswordUser3 *r)
2018 {
2019         struct smbd_server_connection *sconn = smbd_server_conn;
2020         NTSTATUS status;
2021         fstring user_name;
2022         const char *wks = NULL;
2023         uint32 reject_reason;
2024         struct samr_DomInfo1 *dominfo = NULL;
2025         struct samr_ChangeReject *reject = NULL;
2026         uint32_t tmp;
2027
2028         DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
2029
2030         fstrcpy(user_name, r->in.account->string);
2031         if (r->in.server && r->in.server->string) {
2032                 wks = r->in.server->string;
2033         }
2034
2035         DEBUG(5,("_samr_ChangePasswordUser3: user: %s wks: %s\n", user_name, wks));
2036
2037         /*
2038          * Pass the user through the NT -> unix user mapping
2039          * function.
2040          */
2041
2042         (void)map_username(sconn, user_name);
2043
2044         /*
2045          * UNIX username case mangling not required, pass_oem_change
2046          * is case insensitive.
2047          */
2048
2049         status = pass_oem_change(user_name,
2050                                  r->in.lm_password->data,
2051                                  r->in.lm_verifier->hash,
2052                                  r->in.nt_password->data,
2053                                  r->in.nt_verifier->hash,
2054                                  &reject_reason);
2055         if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
2056                 return NT_STATUS_WRONG_PASSWORD;
2057         }
2058
2059         if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) ||
2060             NT_STATUS_EQUAL(status, NT_STATUS_ACCOUNT_RESTRICTION)) {
2061
2062                 time_t u_expire, u_min_age;
2063                 uint32 account_policy_temp;
2064
2065                 dominfo = TALLOC_ZERO_P(p->mem_ctx, struct samr_DomInfo1);
2066                 if (!dominfo) {
2067                         return NT_STATUS_NO_MEMORY;
2068                 }
2069
2070                 reject = TALLOC_ZERO_P(p->mem_ctx, struct samr_ChangeReject);
2071                 if (!reject) {
2072                         return NT_STATUS_NO_MEMORY;
2073                 }
2074
2075                 become_root();
2076
2077                 /* AS ROOT !!! */
2078
2079                 pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &tmp);
2080                 dominfo->min_password_length = tmp;
2081
2082                 pdb_get_account_policy(AP_PASSWORD_HISTORY, &tmp);
2083                 dominfo->password_history_length = tmp;
2084
2085                 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
2086                                        &dominfo->password_properties);
2087
2088                 pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
2089                 u_expire = account_policy_temp;
2090
2091                 pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
2092                 u_min_age = account_policy_temp;
2093
2094                 /* !AS ROOT */
2095
2096                 unbecome_root();
2097
2098                 unix_to_nt_time_abs((NTTIME *)&dominfo->max_password_age, u_expire);
2099                 unix_to_nt_time_abs((NTTIME *)&dominfo->min_password_age, u_min_age);
2100
2101                 if (lp_check_password_script() && *lp_check_password_script()) {
2102                         dominfo->password_properties |= DOMAIN_PASSWORD_COMPLEX;
2103                 }
2104
2105                 reject->reason = reject_reason;
2106
2107                 *r->out.dominfo = dominfo;
2108                 *r->out.reject = reject;
2109         }
2110
2111         DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
2112
2113         return status;
2114 }
2115
2116 /*******************************************************************
2117 makes a SAMR_R_LOOKUP_RIDS structure.
2118 ********************************************************************/
2119
2120 static bool make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names,
2121                                   const char **names,
2122                                   struct lsa_String **lsa_name_array_p)
2123 {
2124         struct lsa_String *lsa_name_array = NULL;
2125         uint32_t i;
2126
2127         *lsa_name_array_p = NULL;
2128
2129         if (num_names != 0) {
2130                 lsa_name_array = TALLOC_ZERO_ARRAY(ctx, struct lsa_String, num_names);
2131                 if (!lsa_name_array) {
2132                         return false;
2133                 }
2134         }
2135
2136         for (i = 0; i < num_names; i++) {
2137                 DEBUG(10, ("names[%d]:%s\n", i, names[i] && *names[i] ? names[i] : ""));
2138                 init_lsa_String(&lsa_name_array[i], names[i]);
2139         }
2140
2141         *lsa_name_array_p = lsa_name_array;
2142
2143         return true;
2144 }
2145
2146 /*******************************************************************
2147  _samr_LookupRids
2148  ********************************************************************/
2149
2150 NTSTATUS _samr_LookupRids(pipes_struct *p,
2151                           struct samr_LookupRids *r)
2152 {
2153         struct samr_domain_info *dinfo;
2154         NTSTATUS status;
2155         const char **names;
2156         enum lsa_SidType *attrs = NULL;
2157         uint32 *wire_attrs = NULL;
2158         int num_rids = (int)r->in.num_rids;
2159         int i;
2160         struct lsa_Strings names_array;
2161         struct samr_Ids types_array;
2162         struct lsa_String *lsa_names = NULL;
2163
2164         DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2165
2166         dinfo = policy_handle_find(p, r->in.domain_handle,
2167                                    0 /* Don't know the acc_bits yet */, NULL,
2168                                    struct samr_domain_info, &status);
2169         if (!NT_STATUS_IS_OK(status)) {
2170                 return status;
2171         }
2172
2173         if (num_rids > 1000) {
2174                 DEBUG(0, ("Got asked for %d rids (more than 1000) -- according "
2175                           "to samba4 idl this is not possible\n", num_rids));
2176                 return NT_STATUS_UNSUCCESSFUL;
2177         }
2178
2179         if (num_rids) {
2180                 names = TALLOC_ZERO_ARRAY(p->mem_ctx, const char *, num_rids);
2181                 attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, enum lsa_SidType, num_rids);
2182                 wire_attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_rids);
2183
2184                 if ((names == NULL) || (attrs == NULL) || (wire_attrs==NULL))
2185                         return NT_STATUS_NO_MEMORY;
2186         } else {
2187                 names = NULL;
2188                 attrs = NULL;
2189                 wire_attrs = NULL;
2190         }
2191
2192         become_root();  /* lookup_sid can require root privs */
2193         status = pdb_lookup_rids(&dinfo->sid, num_rids, r->in.rids,
2194                                  names, attrs);
2195         unbecome_root();
2196
2197         if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED) && (num_rids == 0)) {
2198                 status = NT_STATUS_OK;
2199         }
2200
2201         if (!make_samr_lookup_rids(p->mem_ctx, num_rids, names,
2202                                    &lsa_names)) {
2203                 return NT_STATUS_NO_MEMORY;
2204         }
2205
2206         /* Convert from enum lsa_SidType to uint32 for wire format. */
2207         for (i = 0; i < num_rids; i++) {
2208                 wire_attrs[i] = (uint32)attrs[i];
2209         }
2210
2211         names_array.count = num_rids;
2212         names_array.names = lsa_names;
2213
2214         types_array.count = num_rids;
2215         types_array.ids = wire_attrs;
2216
2217         *r->out.names = names_array;
2218         *r->out.types = types_array;
2219
2220         DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2221
2222         return status;
2223 }
2224
2225 /*******************************************************************
2226  _samr_OpenUser
2227 ********************************************************************/
2228
2229 NTSTATUS _samr_OpenUser(pipes_struct *p,
2230                         struct samr_OpenUser *r)
2231 {
2232         struct samu *sampass=NULL;
2233         DOM_SID sid;
2234         struct samr_domain_info *dinfo;
2235         struct samr_user_info *uinfo;
2236         SEC_DESC *psd = NULL;
2237         uint32    acc_granted;
2238         uint32    des_access = r->in.access_mask;
2239         uint32_t extra_access = 0;
2240         size_t    sd_size;
2241         bool ret;
2242         NTSTATUS nt_status;
2243         SE_PRIV se_rights;
2244         NTSTATUS status;
2245
2246         dinfo = policy_handle_find(p, r->in.domain_handle,
2247                                    SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
2248                                    struct samr_domain_info, &status);
2249         if (!NT_STATUS_IS_OK(status)) {
2250                 return status;
2251         }
2252
2253         if ( !(sampass = samu_new( p->mem_ctx )) ) {
2254                 return NT_STATUS_NO_MEMORY;
2255         }
2256
2257         /* append the user's RID to it */
2258
2259         if (!sid_compose(&sid, &dinfo->sid, r->in.rid))
2260                 return NT_STATUS_NO_SUCH_USER;
2261
2262         /* check if access can be granted as requested by client. */
2263
2264         map_max_allowed_access(p->server_info->ptok, &des_access);
2265
2266         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &sid, SAMR_USR_RIGHTS_WRITE_PW);
2267         se_map_generic(&des_access, &usr_generic_mapping);
2268
2269         /*
2270          * Get the sampass first as we need to check privilages
2271          * based on what kind of user object this is.
2272          * But don't reveal info too early if it didn't exist.
2273          */
2274
2275         become_root();
2276         ret=pdb_getsampwsid(sampass, &sid);
2277         unbecome_root();
2278
2279         se_priv_copy(&se_rights, &se_priv_none);
2280
2281         /*
2282          * We do the override access checks on *open*, not at
2283          * SetUserInfo time.
2284          */
2285         if (ret) {
2286                 uint32_t acb_info = pdb_get_acct_ctrl(sampass);
2287
2288                 if ((acb_info & ACB_WSTRUST) &&
2289                                 user_has_any_privilege(p->server_info->ptok,
2290                                                 &se_machine_account)) {
2291                         /*
2292                          * SeMachineAccount is needed to add
2293                          * GENERIC_RIGHTS_USER_WRITE to a machine
2294                          * account.
2295                          */
2296                         se_priv_add(&se_rights, &se_machine_account);
2297                         DEBUG(10,("_samr_OpenUser: adding machine account "
2298                                 "rights to handle for user %s\n",
2299                                 pdb_get_username(sampass) ));
2300                 }
2301                 if ((acb_info & ACB_NORMAL) &&
2302                                 user_has_any_privilege(p->server_info->ptok,
2303                                                 &se_add_users)) {
2304                         /*
2305                          * SeAddUsers is needed to add
2306                          * GENERIC_RIGHTS_USER_WRITE to a normal
2307                          * account.
2308                          */
2309                         se_priv_add(&se_rights, &se_add_users);
2310                         DEBUG(10,("_samr_OpenUser: adding add user "
2311                                 "rights to handle for user %s\n",
2312                                 pdb_get_username(sampass) ));
2313                 }
2314                 /*
2315                  * Cheat - allow GENERIC_RIGHTS_USER_WRITE if pipe user is
2316                  * in DOMAIN_GROUP_RID_ADMINS. This is almost certainly not
2317                  * what Windows does but is a hack for people who haven't
2318                  * set up privilages on groups in Samba.
2319                  */
2320                 if (acb_info & (ACB_SVRTRUST|ACB_DOMTRUST)) {
2321                         if (lp_enable_privileges() && nt_token_check_domain_rid(p->server_info->ptok,
2322                                                         DOMAIN_GROUP_RID_ADMINS)) {
2323                                 des_access &= ~GENERIC_RIGHTS_USER_WRITE;
2324                                 extra_access = GENERIC_RIGHTS_USER_WRITE;
2325                                 DEBUG(4,("_samr_OpenUser: Allowing "
2326                                         "GENERIC_RIGHTS_USER_WRITE for "
2327                                         "rid admins\n"));
2328                         }
2329                 }
2330         }
2331
2332         TALLOC_FREE(sampass);
2333
2334         nt_status = access_check_object(psd, p->server_info->ptok,
2335                 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
2336                 &acc_granted, "_samr_OpenUser");
2337
2338         if ( !NT_STATUS_IS_OK(nt_status) )
2339                 return nt_status;
2340
2341         /* check that the SID exists in our domain. */
2342         if (ret == False) {
2343                 return NT_STATUS_NO_SUCH_USER;
2344         }
2345
2346         /* If we did the rid admins hack above, allow access. */
2347         acc_granted |= extra_access;
2348
2349         uinfo = policy_handle_create(p, r->out.user_handle, acc_granted,
2350                                      struct samr_user_info, &nt_status);
2351         if (!NT_STATUS_IS_OK(nt_status)) {
2352                 return nt_status;
2353         }
2354         uinfo->sid = sid;
2355
2356         return NT_STATUS_OK;
2357 }
2358
2359 /*************************************************************************
2360  *************************************************************************/
2361
2362 static NTSTATUS init_samr_parameters_string(TALLOC_CTX *mem_ctx,
2363                                             DATA_BLOB *blob,
2364                                             struct lsa_BinaryString **_r)
2365 {
2366         struct lsa_BinaryString *r;
2367
2368         if (!blob || !_r) {
2369                 return NT_STATUS_INVALID_PARAMETER;
2370         }
2371
2372         r = TALLOC_ZERO_P(mem_ctx, struct lsa_BinaryString);
2373         if (!r) {
2374                 return NT_STATUS_NO_MEMORY;
2375         }
2376
2377         r->array = TALLOC_ZERO_ARRAY(mem_ctx, uint16_t, blob->length/2);
2378         if (!r->array) {
2379                 return NT_STATUS_NO_MEMORY;
2380         }
2381         memcpy(r->array, blob->data, blob->length);
2382         r->size = blob->length;
2383         r->length = blob->length;
2384
2385         if (!r->array) {
2386                 return NT_STATUS_NO_MEMORY;
2387         }
2388
2389         *_r = r;
2390
2391         return NT_STATUS_OK;
2392 }
2393
2394 /*************************************************************************
2395  get_user_info_1.
2396  *************************************************************************/
2397
2398 static NTSTATUS get_user_info_1(TALLOC_CTX *mem_ctx,
2399                                 struct samr_UserInfo1 *r,
2400                                 struct samu *pw,
2401                                 DOM_SID *domain_sid)
2402 {
2403         const DOM_SID *sid_group;
2404         uint32_t primary_gid;
2405
2406         become_root();
2407         sid_group = pdb_get_group_sid(pw);
2408         unbecome_root();
2409
2410         if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2411                 DEBUG(0, ("get_user_info_1: User %s has Primary Group SID %s, \n"
2412                           "which conflicts with the domain sid %s.  Failing operation.\n",
2413                           pdb_get_username(pw), sid_string_dbg(sid_group),
2414                           sid_string_dbg(domain_sid)));
2415                 return NT_STATUS_UNSUCCESSFUL;
2416         }
2417
2418         r->account_name.string          = talloc_strdup(mem_ctx, pdb_get_username(pw));
2419         r->full_name.string             = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2420         r->primary_gid                  = primary_gid;
2421         r->description.string           = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2422         r->comment.string               = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2423
2424         return NT_STATUS_OK;
2425 }
2426
2427 /*************************************************************************
2428  get_user_info_2.
2429  *************************************************************************/
2430
2431 static NTSTATUS get_user_info_2(TALLOC_CTX *mem_ctx,
2432                                 struct samr_UserInfo2 *r,
2433                                 struct samu *pw)
2434 {
2435         r->comment.string               = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2436         r->unknown.string               = NULL;
2437         r->country_code                 = 0;
2438         r->code_page                    = 0;
2439
2440         return NT_STATUS_OK;
2441 }
2442
2443 /*************************************************************************
2444  get_user_info_3.
2445  *************************************************************************/
2446
2447 static NTSTATUS get_user_info_3(TALLOC_CTX *mem_ctx,
2448                                 struct samr_UserInfo3 *r,
2449                                 struct samu *pw,
2450                                 DOM_SID *domain_sid)
2451 {
2452         const DOM_SID *sid_user, *sid_group;
2453         uint32_t rid, primary_gid;
2454
2455         sid_user = pdb_get_user_sid(pw);
2456
2457         if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2458                 DEBUG(0, ("get_user_info_3: User %s has SID %s, \nwhich conflicts with "
2459                           "the domain sid %s.  Failing operation.\n",
2460                           pdb_get_username(pw), sid_string_dbg(sid_user),
2461                           sid_string_dbg(domain_sid)));
2462                 return NT_STATUS_UNSUCCESSFUL;
2463         }
2464
2465         become_root();
2466         sid_group = pdb_get_group_sid(pw);
2467         unbecome_root();
2468
2469         if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2470                 DEBUG(0, ("get_user_info_3: User %s has Primary Group SID %s, \n"
2471                           "which conflicts with the domain sid %s.  Failing operation.\n",
2472                           pdb_get_username(pw), sid_string_dbg(sid_group),
2473                           sid_string_dbg(domain_sid)));
2474                 return NT_STATUS_UNSUCCESSFUL;
2475         }
2476
2477         unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2478         unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2479         unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2480         unix_to_nt_time(&r->allow_password_change, pdb_get_pass_can_change_time(pw));
2481         unix_to_nt_time(&r->force_password_change, pdb_get_pass_must_change_time(pw));
2482
2483         r->account_name.string  = talloc_strdup(mem_ctx, pdb_get_username(pw));
2484         r->full_name.string     = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2485         r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2486         r->home_drive.string    = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2487         r->logon_script.string  = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2488         r->profile_path.string  = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2489         r->workstations.string  = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2490
2491         r->logon_hours          = get_logon_hours_from_pdb(mem_ctx, pw);
2492         r->rid                  = rid;
2493         r->primary_gid          = primary_gid;
2494         r->acct_flags           = pdb_get_acct_ctrl(pw);
2495         r->bad_password_count   = pdb_get_bad_password_count(pw);
2496         r->logon_count          = pdb_get_logon_count(pw);
2497
2498         return NT_STATUS_OK;
2499 }
2500
2501 /*************************************************************************
2502  get_user_info_4.
2503  *************************************************************************/
2504
2505 static NTSTATUS get_user_info_4(TALLOC_CTX *mem_ctx,
2506                                 struct samr_UserInfo4 *r,
2507                                 struct samu *pw)
2508 {
2509         r->logon_hours          = get_logon_hours_from_pdb(mem_ctx, pw);
2510
2511         return NT_STATUS_OK;
2512 }
2513
2514 /*************************************************************************
2515  get_user_info_5.
2516  *************************************************************************/
2517
2518 static NTSTATUS get_user_info_5(TALLOC_CTX *mem_ctx,
2519                                 struct samr_UserInfo5 *r,
2520                                 struct samu *pw,
2521                                 DOM_SID *domain_sid)
2522 {
2523         const DOM_SID *sid_user, *sid_group;
2524         uint32_t rid, primary_gid;
2525
2526         sid_user = pdb_get_user_sid(pw);
2527
2528         if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2529                 DEBUG(0, ("get_user_info_5: User %s has SID %s, \nwhich conflicts with "
2530                           "the domain sid %s.  Failing operation.\n",
2531                           pdb_get_username(pw), sid_string_dbg(sid_user),
2532                           sid_string_dbg(domain_sid)));
2533                 return NT_STATUS_UNSUCCESSFUL;
2534         }
2535
2536         become_root();
2537         sid_group = pdb_get_group_sid(pw);
2538         unbecome_root();
2539
2540         if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2541                 DEBUG(0, ("get_user_info_5: User %s has Primary Group SID %s, \n"
2542                           "which conflicts with the domain sid %s.  Failing operation.\n",
2543                           pdb_get_username(pw), sid_string_dbg(sid_group),
2544                           sid_string_dbg(domain_sid)));
2545                 return NT_STATUS_UNSUCCESSFUL;
2546         }
2547
2548         unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2549         unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2550         unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2551         unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2552
2553         r->account_name.string  = talloc_strdup(mem_ctx, pdb_get_username(pw));
2554         r->full_name.string     = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2555         r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2556         r->home_drive.string    = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2557         r->logon_script.string  = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2558         r->profile_path.string  = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2559         r->description.string   = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2560         r->workstations.string  = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2561
2562         r->logon_hours          = get_logon_hours_from_pdb(mem_ctx, pw);
2563         r->rid                  = rid;
2564         r->primary_gid          = primary_gid;
2565         r->acct_flags           = pdb_get_acct_ctrl(pw);
2566         r->bad_password_count   = pdb_get_bad_password_count(pw);
2567         r->logon_count          = pdb_get_logon_count(pw);
2568
2569         return NT_STATUS_OK;
2570 }
2571
2572 /*************************************************************************
2573  get_user_info_6.
2574  *************************************************************************/
2575
2576 static NTSTATUS get_user_info_6(TALLOC_CTX *mem_ctx,
2577                                 struct samr_UserInfo6 *r,
2578                                 struct samu *pw)
2579 {
2580         r->account_name.string  = talloc_strdup(mem_ctx, pdb_get_username(pw));
2581         r->full_name.string     = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2582
2583         return NT_STATUS_OK;
2584 }
2585
2586 /*************************************************************************
2587  get_user_info_7. Safe. Only gives out account_name.
2588  *************************************************************************/
2589
2590 static NTSTATUS get_user_info_7(TALLOC_CTX *mem_ctx,
2591                                 struct samr_UserInfo7 *r,
2592                                 struct samu *smbpass)
2593 {
2594         r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(smbpass));
2595         if (!r->account_name.string) {
2596                 return NT_STATUS_NO_MEMORY;
2597         }
2598
2599         return NT_STATUS_OK;
2600 }
2601
2602 /*************************************************************************
2603  get_user_info_8.
2604  *************************************************************************/
2605
2606 static NTSTATUS get_user_info_8(TALLOC_CTX *mem_ctx,
2607                                 struct samr_UserInfo8 *r,
2608                                 struct samu *pw)
2609 {
2610         r->full_name.string     = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2611
2612         return NT_STATUS_OK;
2613 }
2614
2615 /*************************************************************************
2616  get_user_info_9. Only gives out primary group SID.
2617  *************************************************************************/
2618
2619 static NTSTATUS get_user_info_9(TALLOC_CTX *mem_ctx,
2620                                 struct samr_UserInfo9 *r,
2621                                 struct samu *smbpass)
2622 {
2623         r->primary_gid = pdb_get_group_rid(smbpass);
2624
2625         return NT_STATUS_OK;
2626 }
2627
2628 /*************************************************************************
2629  get_user_info_10.
2630  *************************************************************************/
2631
2632 static NTSTATUS get_user_info_10(TALLOC_CTX *mem_ctx,
2633                                  struct samr_UserInfo10 *r,
2634                                  struct samu *pw)
2635 {
2636         r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2637         r->home_drive.string    = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2638
2639         return NT_STATUS_OK;
2640 }
2641
2642 /*************************************************************************
2643  get_user_info_11.
2644  *************************************************************************/
2645
2646 static NTSTATUS get_user_info_11(TALLOC_CTX *mem_ctx,
2647                                  struct samr_UserInfo11 *r,
2648                                  struct samu *pw)
2649 {
2650         r->logon_script.string  = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2651
2652         return NT_STATUS_OK;
2653 }
2654
2655 /*************************************************************************
2656  get_user_info_12.
2657  *************************************************************************/
2658
2659 static NTSTATUS get_user_info_12(TALLOC_CTX *mem_ctx,
2660                                  struct samr_UserInfo12 *r,
2661                                  struct samu *pw)
2662 {
2663         r->profile_path.string  = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2664
2665         return NT_STATUS_OK;
2666 }
2667
2668 /*************************************************************************
2669  get_user_info_13.
2670  *************************************************************************/
2671
2672 static NTSTATUS get_user_info_13(TALLOC_CTX *mem_ctx,
2673                                  struct samr_UserInfo13 *r,
2674                                  struct samu *pw)
2675 {
2676         r->description.string   = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2677
2678         return NT_STATUS_OK;
2679 }
2680
2681 /*************************************************************************
2682  get_user_info_14.
2683  *************************************************************************/
2684
2685 static NTSTATUS get_user_info_14(TALLOC_CTX *mem_ctx,
2686                                  struct samr_UserInfo14 *r,
2687                                  struct samu *pw)
2688 {
2689         r->workstations.string  = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2690
2691         return NT_STATUS_OK;
2692 }
2693
2694 /*************************************************************************
2695  get_user_info_16. Safe. Only gives out acb bits.
2696  *************************************************************************/
2697
2698 static NTSTATUS get_user_info_16(TALLOC_CTX *mem_ctx,
2699                                  struct samr_UserInfo16 *r,
2700                                  struct samu *smbpass)
2701 {
2702         r->acct_flags = pdb_get_acct_ctrl(smbpass);
2703
2704         return NT_STATUS_OK;
2705 }
2706
2707 /*************************************************************************
2708  get_user_info_17.
2709  *************************************************************************/
2710
2711 static NTSTATUS get_user_info_17(TALLOC_CTX *mem_ctx,
2712                                  struct samr_UserInfo17 *r,
2713                                  struct samu *pw)
2714 {
2715         unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2716
2717         return NT_STATUS_OK;
2718 }
2719
2720 /*************************************************************************
2721  get_user_info_18. OK - this is the killer as it gives out password info.
2722  Ensure that this is only allowed on an encrypted connection with a root
2723  user. JRA.
2724  *************************************************************************/
2725
2726 static NTSTATUS get_user_info_18(pipes_struct *p,
2727                                  TALLOC_CTX *mem_ctx,
2728                                  struct samr_UserInfo18 *r,
2729                                  DOM_SID *user_sid)
2730 {
2731         struct samu *smbpass=NULL;
2732         bool ret;
2733
2734         ZERO_STRUCTP(r);
2735
2736         if (p->auth.auth_type != PIPE_AUTH_TYPE_NTLMSSP || p->auth.auth_type != PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) {
2737                 return NT_STATUS_ACCESS_DENIED;
2738         }
2739
2740         if (p->auth.auth_level != PIPE_AUTH_LEVEL_PRIVACY) {
2741                 return NT_STATUS_ACCESS_DENIED;
2742         }
2743
2744         /*
2745          * Do *NOT* do become_root()/unbecome_root() here ! JRA.
2746          */
2747
2748         if ( !(smbpass = samu_new( mem_ctx )) ) {
2749                 return NT_STATUS_NO_MEMORY;
2750         }
2751
2752         ret = pdb_getsampwsid(smbpass, user_sid);
2753
2754         if (ret == False) {
2755                 DEBUG(4, ("User %s not found\n", sid_string_dbg(user_sid)));
2756                 TALLOC_FREE(smbpass);
2757                 return (geteuid() == sec_initial_uid()) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
2758         }
2759
2760         DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
2761
2762         if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
2763                 TALLOC_FREE(smbpass);
2764                 return NT_STATUS_ACCOUNT_DISABLED;
2765         }
2766
2767         r->lm_pwd_active = true;
2768         r->nt_pwd_active = true;
2769         memcpy(r->lm_pwd.hash, pdb_get_lanman_passwd(smbpass), 16);
2770         memcpy(r->nt_pwd.hash, pdb_get_nt_passwd(smbpass), 16);
2771         r->password_expired = 0; /* FIXME */
2772
2773         TALLOC_FREE(smbpass);
2774
2775         return NT_STATUS_OK;
2776 }
2777
2778 /*************************************************************************
2779  get_user_info_20
2780  *************************************************************************/
2781
2782 static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx,
2783                                  struct samr_UserInfo20 *r,
2784                                  struct samu *sampass)
2785 {
2786         const char *munged_dial = NULL;
2787         DATA_BLOB blob;
2788         NTSTATUS status;
2789         struct lsa_BinaryString *parameters = NULL;
2790
2791         ZERO_STRUCTP(r);
2792
2793         munged_dial = pdb_get_munged_dial(sampass);
2794
2795         DEBUG(3,("User:[%s] has [%s] (length: %d)\n", pdb_get_username(sampass),
2796                 munged_dial, (int)strlen(munged_dial)));
2797
2798         if (munged_dial) {
2799                 blob = base64_decode_data_blob(munged_dial);
2800         } else {
2801                 blob = data_blob_string_const_null("");
2802         }
2803
2804         status = init_samr_parameters_string(mem_ctx, &blob, &parameters);
2805         data_blob_free(&blob);
2806         if (!NT_STATUS_IS_OK(status)) {
2807                 return status;
2808         }
2809
2810         r->parameters = *parameters;
2811
2812         return NT_STATUS_OK;
2813 }
2814
2815
2816 /*************************************************************************
2817  get_user_info_21
2818  *************************************************************************/
2819
2820 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx,
2821                                  struct samr_UserInfo21 *r,
2822                                  struct samu *pw,
2823                                  DOM_SID *domain_sid,
2824                                  uint32_t acc_granted)
2825 {
2826         NTSTATUS status;
2827         const DOM_SID *sid_user, *sid_group;
2828         uint32_t rid, primary_gid;
2829         NTTIME force_password_change;
2830         time_t must_change_time;
2831         struct lsa_BinaryString *parameters = NULL;
2832         const char *munged_dial = NULL;
2833         DATA_BLOB blob;
2834
2835         ZERO_STRUCTP(r);
2836
2837         sid_user = pdb_get_user_sid(pw);
2838
2839         if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2840                 DEBUG(0, ("get_user_info_21: User %s has SID %s, \nwhich conflicts with "
2841                           "the domain sid %s.  Failing operation.\n",
2842                           pdb_get_username(pw), sid_string_dbg(sid_user),
2843                           sid_string_dbg(domain_sid)));
2844                 return NT_STATUS_UNSUCCESSFUL;
2845         }
2846
2847         become_root();
2848         sid_group = pdb_get_group_sid(pw);
2849         unbecome_root();
2850
2851         if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2852                 DEBUG(0, ("get_user_info_21: User %s has Primary Group SID %s, \n"
2853                           "which conflicts with the domain sid %s.  Failing operation.\n",
2854                           pdb_get_username(pw), sid_string_dbg(sid_group),
2855                           sid_string_dbg(domain_sid)));
2856                 return NT_STATUS_UNSUCCESSFUL;
2857         }
2858
2859         unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2860         unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2861         unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2862         unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2863         unix_to_nt_time(&r->allow_password_change, pdb_get_pass_can_change_time(pw));
2864
2865         must_change_time = pdb_get_pass_must_change_time(pw);
2866         if (must_change_time == get_time_t_max()) {
2867                 unix_to_nt_time_abs(&force_password_change, must_change_time);
2868         } else {
2869                 unix_to_nt_time(&force_password_change, must_change_time);
2870         }
2871
2872         munged_dial = pdb_get_munged_dial(pw);
2873         if (munged_dial) {
2874                 blob = base64_decode_data_blob(munged_dial);
2875         } else {
2876                 blob = data_blob_string_const_null("");
2877         }
2878
2879         status = init_samr_parameters_string(mem_ctx, &blob, &parameters);
2880         data_blob_free(&blob);
2881         if (!NT_STATUS_IS_OK(status)) {
2882                 return status;
2883         }
2884
2885         r->force_password_change        = force_password_change;
2886
2887         r->account_name.string          = talloc_strdup(mem_ctx, pdb_get_username(pw));
2888         r->full_name.string             = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2889         r->home_directory.string        = talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2890         r->home_drive.string            = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2891         r->logon_script.string          = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2892         r->profile_path.string          = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2893         r->description.string           = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2894         r->workstations.string          = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2895         r->comment.string               = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2896
2897         r->logon_hours                  = get_logon_hours_from_pdb(mem_ctx, pw);
2898         r->parameters                   = *parameters;
2899         r->rid                          = rid;
2900         r->primary_gid                  = primary_gid;
2901         r->acct_flags                   = pdb_get_acct_ctrl(pw);
2902         r->bad_password_count           = pdb_get_bad_password_count(pw);
2903         r->logon_count                  = pdb_get_logon_count(pw);
2904         r->fields_present               = pdb_build_fields_present(pw);
2905         r->password_expired             = (pdb_get_pass_must_change_time(pw) == 0) ?
2906                                                 PASS_MUST_CHANGE_AT_NEXT_LOGON : 0;
2907         r->country_code                 = 0;
2908         r->code_page                    = 0;
2909         r->lm_password_set              = 0;
2910         r->nt_password_set              = 0;
2911
2912 #if 0
2913
2914         /*
2915           Look at a user on a real NT4 PDC with usrmgr, press
2916           'ok'. Then you will see that fields_present is set to
2917           0x08f827fa. Look at the user immediately after that again,
2918           and you will see that 0x00fffff is returned. This solves
2919           the problem that you get access denied after having looked
2920           at the user.
2921           -- Volker
2922         */
2923
2924 #endif
2925
2926
2927         return NT_STATUS_OK;
2928 }
2929
2930 /*******************************************************************
2931  _samr_QueryUserInfo
2932  ********************************************************************/
2933
2934 NTSTATUS _samr_QueryUserInfo(pipes_struct *p,
2935                              struct samr_QueryUserInfo *r)
2936 {
2937         NTSTATUS status;
2938         union samr_UserInfo *user_info = NULL;
2939         struct samr_user_info *uinfo;
2940         DOM_SID domain_sid;
2941         uint32 rid;
2942         bool ret = false;
2943         struct samu *pwd = NULL;
2944         uint32_t acc_required, acc_granted;
2945
2946         switch (r->in.level) {
2947         case 1: /* UserGeneralInformation */
2948                 /* USER_READ_GENERAL */
2949                 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC;
2950                 break;
2951         case 2: /* UserPreferencesInformation */
2952                 /* USER_READ_PREFERENCES | USER_READ_GENERAL */
2953                 acc_required = SAMR_USER_ACCESS_GET_LOCALE |
2954                                SAMR_USER_ACCESS_GET_NAME_ETC;
2955                 break;
2956         case 3: /* UserLogonInformation */
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 4: /* UserLogonHoursInformation */
2964                 /* USER_READ_LOGON */
2965                 acc_required = SAMR_USER_ACCESS_GET_LOGONINFO;
2966                 break;
2967         case 5: /* UserAccountInformation */
2968                 /* USER_READ_GENERAL | USER_READ_PREFERENCES | USER_READ_LOGON | USER_READ_ACCOUNT */
2969                 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC |
2970                                SAMR_USER_ACCESS_GET_LOCALE |
2971                                SAMR_USER_ACCESS_GET_LOGONINFO |
2972                                SAMR_USER_ACCESS_GET_ATTRIBUTES;
2973                 break;
2974         case 6: /* UserNameInformation */
2975         case 7: /* UserAccountNameInformation */
2976         case 8: /* UserFullNameInformation */
2977         case 9: /* UserPrimaryGroupInformation */
2978         case 13: /* UserAdminCommentInformation */
2979                 /* USER_READ_GENERAL */
2980                 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC;
2981                 break;
2982         case 10: /* UserHomeInformation */
2983         case 11: /* UserScriptInformation */
2984         case 12: /* UserProfileInformation */
2985         case 14: /* UserWorkStationsInformation */
2986                 /* USER_READ_LOGON */
2987                 acc_required = SAMR_USER_ACCESS_GET_LOGONINFO;
2988                 break;
2989         case 16: /* UserControlInformation */
2990         case 17: /* UserExpiresInformation */
2991         case 20: /* UserParametersInformation */
2992                 /* USER_READ_ACCOUNT */
2993                 acc_required = SAMR_USER_ACCESS_GET_ATTRIBUTES;
2994                 break;
2995         case 21: /* UserAllInformation */
2996                 /* FIXME! - gd */
2997                 acc_required = SAMR_USER_ACCESS_GET_ATTRIBUTES;
2998                 break;
2999         case 18: /* UserInternal1Information */
3000                 /* FIXME! - gd */
3001                 acc_required = SAMR_USER_ACCESS_GET_ATTRIBUTES;
3002                 break;
3003         case 23: /* UserInternal4Information */
3004         case 24: /* UserInternal4InformationNew */
3005         case 25: /* UserInternal4InformationNew */
3006         case 26: /* UserInternal5InformationNew */
3007         default:
3008                 return NT_STATUS_INVALID_INFO_CLASS;
3009                 break;
3010         }
3011
3012         uinfo = policy_handle_find(p, r->in.user_handle,
3013                                    acc_required, &acc_granted,
3014                                    struct samr_user_info, &status);
3015         if (!NT_STATUS_IS_OK(status)) {
3016                 return status;
3017         }
3018
3019         domain_sid = uinfo->sid;
3020
3021         sid_split_rid(&domain_sid, &rid);
3022
3023         if (!sid_check_is_in_our_domain(&uinfo->sid))
3024                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
3025
3026         DEBUG(5,("_samr_QueryUserInfo: sid:%s\n",
3027                  sid_string_dbg(&uinfo->sid)));
3028
3029         user_info = TALLOC_ZERO_P(p->mem_ctx, union samr_UserInfo);
3030         if (!user_info) {
3031                 return NT_STATUS_NO_MEMORY;
3032         }
3033
3034         DEBUG(5,("_samr_QueryUserInfo: user info level: %d\n", r->in.level));
3035
3036         if (!(pwd = samu_new(p->mem_ctx))) {
3037                 return NT_STATUS_NO_MEMORY;
3038         }
3039
3040         become_root();
3041         ret = pdb_getsampwsid(pwd, &uinfo->sid);
3042         unbecome_root();
3043
3044         if (ret == false) {
3045                 DEBUG(4,("User %s not found\n", sid_string_dbg(&uinfo->sid)));
3046                 TALLOC_FREE(pwd);
3047                 return NT_STATUS_NO_SUCH_USER;
3048         }
3049
3050         DEBUG(3,("User:[%s]\n", pdb_get_username(pwd)));
3051
3052         samr_clear_sam_passwd(pwd);
3053
3054         switch (r->in.level) {
3055         case 1:
3056                 status = get_user_info_1(p->mem_ctx, &user_info->info1, pwd, &domain_sid);
3057                 break;
3058         case 2:
3059                 status = get_user_info_2(p->mem_ctx, &user_info->info2, pwd);
3060                 break;
3061         case 3:
3062                 status = get_user_info_3(p->mem_ctx, &user_info->info3, pwd, &domain_sid);
3063                 break;
3064         case 4:
3065                 status = get_user_info_4(p->mem_ctx, &user_info->info4, pwd);
3066                 break;
3067         case 5:
3068                 status = get_user_info_5(p->mem_ctx, &user_info->info5, pwd, &domain_sid);
3069                 break;
3070         case 6:
3071                 status = get_user_info_6(p->mem_ctx, &user_info->info6, pwd);
3072                 break;
3073         case 7:
3074                 status = get_user_info_7(p->mem_ctx, &user_info->info7, pwd);
3075                 break;
3076         case 8:
3077                 status = get_user_info_8(p->mem_ctx, &user_info->info8, pwd);
3078                 break;
3079         case 9:
3080                 status = get_user_info_9(p->mem_ctx, &user_info->info9, pwd);
3081                 break;
3082         case 10:
3083                 status = get_user_info_10(p->mem_ctx, &user_info->info10, pwd);
3084                 break;
3085         case 11:
3086                 status = get_user_info_11(p->mem_ctx, &user_info->info11, pwd);
3087                 break;
3088         case 12:
3089                 status = get_user_info_12(p->mem_ctx, &user_info->info12, pwd);
3090                 break;
3091         case 13:
3092                 status = get_user_info_13(p->mem_ctx, &user_info->info13, pwd);
3093                 break;
3094         case 14:
3095                 status = get_user_info_14(p->mem_ctx, &user_info->info14, pwd);
3096                 break;
3097         case 16:
3098                 status = get_user_info_16(p->mem_ctx, &user_info->info16, pwd);
3099                 break;
3100         case 17:
3101                 status = get_user_info_17(p->mem_ctx, &user_info->info17, pwd);
3102                 break;
3103         case 18:
3104                 /* level 18 is special */
3105                 status = get_user_info_18(p, p->mem_ctx, &user_info->info18,
3106                                           &uinfo->sid);
3107                 break;
3108         case 20:
3109                 status = get_user_info_20(p->mem_ctx, &user_info->info20, pwd);
3110                 break;
3111         case 21:
3112                 status = get_user_info_21(p->mem_ctx, &user_info->info21, pwd, &domain_sid, acc_granted);
3113                 break;
3114         default:
3115                 status = NT_STATUS_INVALID_INFO_CLASS;
3116                 break;
3117         }
3118
3119         if (!NT_STATUS_IS_OK(status)) {
3120                 goto done;
3121         }
3122
3123         *r->out.info = user_info;
3124
3125  done:
3126         TALLOC_FREE(pwd);
3127
3128         DEBUG(5,("_samr_QueryUserInfo: %d\n", __LINE__));
3129
3130         return status;
3131 }
3132
3133 /****************************************************************
3134 ****************************************************************/
3135
3136 NTSTATUS _samr_QueryUserInfo2(pipes_struct *p,
3137                               struct samr_QueryUserInfo2 *r)
3138 {
3139         struct samr_QueryUserInfo u;
3140
3141         u.in.user_handle        = r->in.user_handle;
3142         u.in.level              = r->in.level;
3143         u.out.info              = r->out.info;
3144
3145         return _samr_QueryUserInfo(p, &u);
3146 }
3147
3148 /*******************************************************************
3149  _samr_GetGroupsForUser
3150  ********************************************************************/
3151
3152 NTSTATUS _samr_GetGroupsForUser(pipes_struct *p,
3153                                 struct samr_GetGroupsForUser *r)
3154 {
3155         struct samr_user_info *uinfo;
3156         struct samu *sam_pass=NULL;
3157         DOM_SID *sids;
3158         struct samr_RidWithAttribute dom_gid;
3159         struct samr_RidWithAttribute *gids = NULL;
3160         uint32 primary_group_rid;
3161         size_t num_groups = 0;
3162         gid_t *unix_gids;
3163         size_t i, num_gids;
3164         bool ret;
3165         NTSTATUS result;
3166         bool success = False;
3167
3168         struct samr_RidWithAttributeArray *rids = NULL;
3169
3170         /*
3171          * from the SID in the request:
3172          * we should send back the list of DOMAIN GROUPS
3173          * the user is a member of
3174          *
3175          * and only the DOMAIN GROUPS
3176          * no ALIASES !!! neither aliases of the domain
3177          * nor aliases of the builtin SID
3178          *
3179          * JFM, 12/2/2001
3180          */
3181
3182         DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
3183
3184         uinfo = policy_handle_find(p, r->in.user_handle,
3185                                    SAMR_USER_ACCESS_GET_GROUPS, NULL,
3186                                    struct samr_user_info, &result);
3187         if (!NT_STATUS_IS_OK(result)) {
3188                 return result;
3189         }
3190
3191         rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidWithAttributeArray);
3192         if (!rids) {
3193                 return NT_STATUS_NO_MEMORY;
3194         }
3195
3196         if (!sid_check_is_in_our_domain(&uinfo->sid))
3197                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
3198
3199         if ( !(sam_pass = samu_new( p->mem_ctx )) ) {
3200                 return NT_STATUS_NO_MEMORY;
3201         }
3202
3203         become_root();
3204         ret = pdb_getsampwsid(sam_pass, &uinfo->sid);
3205         unbecome_root();
3206
3207         if (!ret) {
3208                 DEBUG(10, ("pdb_getsampwsid failed for %s\n",
3209                            sid_string_dbg(&uinfo->sid)));
3210                 return NT_STATUS_NO_SUCH_USER;
3211         }
3212
3213         sids = NULL;
3214
3215         /* make both calls inside the root block */
3216         become_root();
3217         result = pdb_enum_group_memberships(p->mem_ctx, sam_pass,
3218                                  &nbs