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