a946d2ed6d185aa402516fdfe30ddc66a3f9c386
[samba.git] / source / 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
36 #undef DBGC_CLASS
37 #define DBGC_CLASS DBGC_RPC_SRV
38
39 #define SAMR_USR_RIGHTS_WRITE_PW \
40                 ( READ_CONTROL_ACCESS           | \
41                   SAMR_USER_ACCESS_CHANGE_PASSWORD      | \
42                   SAMR_USER_ACCESS_SET_LOC_COM)
43 #define SAMR_USR_RIGHTS_CANT_WRITE_PW \
44                 ( READ_CONTROL_ACCESS | SAMR_USER_ACCESS_SET_LOC_COM )
45
46 #define DISP_INFO_CACHE_TIMEOUT 10
47
48 typedef struct disp_info {
49         DOM_SID sid; /* identify which domain this is. */
50         bool builtin_domain; /* Quick flag to check if this is the builtin domain. */
51         struct pdb_search *users; /* querydispinfo 1 and 4 */
52         struct pdb_search *machines; /* querydispinfo 2 */
53         struct pdb_search *groups; /* querydispinfo 3 and 5, enumgroups */
54         struct pdb_search *aliases; /* enumaliases */
55
56         uint16 enum_acb_mask;
57         struct pdb_search *enum_users; /* enumusers with a mask */
58
59         struct timed_event *cache_timeout_event; /* cache idle timeout
60                                                   * handler. */
61 } DISP_INFO;
62
63 /* We keep a static list of these by SID as modern clients close down
64    all resources between each request in a complete enumeration. */
65
66 struct samr_info {
67         /* for use by the \PIPE\samr policy */
68         DOM_SID sid;
69         bool builtin_domain; /* Quick flag to check if this is the builtin domain. */
70         uint32 status; /* some sort of flag.  best to record it.  comes from opnum 0x39 */
71         uint32 acc_granted;
72         DISP_INFO *disp_info;
73         TALLOC_CTX *mem_ctx;
74 };
75
76 static const struct generic_mapping sam_generic_mapping = {
77         GENERIC_RIGHTS_SAM_READ,
78         GENERIC_RIGHTS_SAM_WRITE,
79         GENERIC_RIGHTS_SAM_EXECUTE,
80         GENERIC_RIGHTS_SAM_ALL_ACCESS};
81 static const struct generic_mapping dom_generic_mapping = {
82         GENERIC_RIGHTS_DOMAIN_READ,
83         GENERIC_RIGHTS_DOMAIN_WRITE,
84         GENERIC_RIGHTS_DOMAIN_EXECUTE,
85         GENERIC_RIGHTS_DOMAIN_ALL_ACCESS};
86 static const struct generic_mapping usr_generic_mapping = {
87         GENERIC_RIGHTS_USER_READ,
88         GENERIC_RIGHTS_USER_WRITE,
89         GENERIC_RIGHTS_USER_EXECUTE,
90         GENERIC_RIGHTS_USER_ALL_ACCESS};
91 static const struct generic_mapping usr_nopwchange_generic_mapping = {
92         GENERIC_RIGHTS_USER_READ,
93         GENERIC_RIGHTS_USER_WRITE,
94         GENERIC_RIGHTS_USER_EXECUTE & ~SAMR_USER_ACCESS_CHANGE_PASSWORD,
95         GENERIC_RIGHTS_USER_ALL_ACCESS};
96 static const struct generic_mapping grp_generic_mapping = {
97         GENERIC_RIGHTS_GROUP_READ,
98         GENERIC_RIGHTS_GROUP_WRITE,
99         GENERIC_RIGHTS_GROUP_EXECUTE,
100         GENERIC_RIGHTS_GROUP_ALL_ACCESS};
101 static const struct generic_mapping ali_generic_mapping = {
102         GENERIC_RIGHTS_ALIAS_READ,
103         GENERIC_RIGHTS_ALIAS_WRITE,
104         GENERIC_RIGHTS_ALIAS_EXECUTE,
105         GENERIC_RIGHTS_ALIAS_ALL_ACCESS};
106
107 /*******************************************************************
108 *******************************************************************/
109
110 static NTSTATUS make_samr_object_sd( TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size,
111                                      const struct generic_mapping *map,
112                                      DOM_SID *sid, uint32 sid_access )
113 {
114         DOM_SID domadmin_sid;
115         SEC_ACE ace[5];         /* at most 5 entries */
116         size_t i = 0;
117
118         SEC_ACL *psa = NULL;
119
120         /* basic access for Everyone */
121
122         init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
123                         map->generic_execute | map->generic_read, 0);
124
125         /* add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
126
127         init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
128                         SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
129         init_sec_ace(&ace[i++], &global_sid_Builtin_Account_Operators,
130                         SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
131
132         /* Add Full Access for Domain Admins if we are a DC */
133
134         if ( IS_DC ) {
135                 sid_copy( &domadmin_sid, get_global_sam_sid() );
136                 sid_append_rid( &domadmin_sid, DOMAIN_GROUP_RID_ADMINS );
137                 init_sec_ace(&ace[i++], &domadmin_sid,
138                         SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
139         }
140
141         /* if we have a sid, give it some special access */
142
143         if ( sid ) {
144                 init_sec_ace(&ace[i++], sid, SEC_ACE_TYPE_ACCESS_ALLOWED, sid_access, 0);
145         }
146
147         /* create the security descriptor */
148
149         if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) == NULL)
150                 return NT_STATUS_NO_MEMORY;
151
152         if ((*psd = make_sec_desc(ctx, SECURITY_DESCRIPTOR_REVISION_1,
153                                   SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL,
154                                   psa, sd_size)) == NULL)
155                 return NT_STATUS_NO_MEMORY;
156
157         return NT_STATUS_OK;
158 }
159
160 /*******************************************************************
161  Checks if access to an object should be granted, and returns that
162  level of access for further checks.
163 ********************************************************************/
164
165 static NTSTATUS access_check_samr_object( SEC_DESC *psd, NT_USER_TOKEN *token,
166                                           SE_PRIV *rights, uint32 rights_mask,
167                                           uint32 des_access, uint32 *acc_granted,
168                                           const char *debug )
169 {
170         NTSTATUS status = NT_STATUS_ACCESS_DENIED;
171         uint32 saved_mask = 0;
172
173         /* check privileges; certain SAM access bits should be overridden
174            by privileges (mostly having to do with creating/modifying/deleting
175            users and groups) */
176
177         if ( rights && user_has_any_privilege( token, rights ) ) {
178
179                 saved_mask = (des_access & rights_mask);
180                 des_access &= ~saved_mask;
181
182                 DEBUG(4,("access_check_samr_object: user rights access mask [0x%x]\n",
183                         rights_mask));
184         }
185
186
187         /* check the security descriptor first */
188
189         status = se_access_check(psd, token, des_access, acc_granted);
190         if (NT_STATUS_IS_OK(status)) {
191                 goto done;
192         }
193
194         /* give root a free pass */
195
196         if ( geteuid() == sec_initial_uid() ) {
197
198                 DEBUG(4,("%s: ACCESS should be DENIED  (requested: %#010x)\n", debug, des_access));
199                 DEBUGADD(4,("but overritten by euid == sec_initial_uid()\n"));
200
201                 *acc_granted = des_access;
202
203                 status = NT_STATUS_OK;
204                 goto done;
205         }
206
207
208 done:
209         /* add in any bits saved during the privilege check (only
210            matters is status is ok) */
211
212         *acc_granted |= rights_mask;
213
214         DEBUG(4,("%s: access %s (requested: 0x%08x, granted: 0x%08x)\n",
215                 debug, NT_STATUS_IS_OK(status) ? "GRANTED" : "DENIED",
216                 des_access, *acc_granted));
217
218         return status;
219 }
220
221 /*******************************************************************
222  Checks if access to a function can be granted
223 ********************************************************************/
224
225 static NTSTATUS access_check_samr_function(uint32 acc_granted, uint32 acc_required, const char *debug)
226 {
227         DEBUG(5,("%s: access check ((granted: %#010x;  required: %#010x)\n",
228                 debug, acc_granted, acc_required));
229
230         /* check the security descriptor first */
231
232         if ( (acc_granted&acc_required) == acc_required )
233                 return NT_STATUS_OK;
234
235         /* give root a free pass */
236
237         if (geteuid() == sec_initial_uid()) {
238
239                 DEBUG(4,("%s: ACCESS should be DENIED (granted: %#010x;  required: %#010x)\n",
240                         debug, acc_granted, acc_required));
241                 DEBUGADD(4,("but overwritten by euid == 0\n"));
242
243                 return NT_STATUS_OK;
244         }
245
246         DEBUG(2,("%s: ACCESS DENIED (granted: %#010x;  required: %#010x)\n",
247                 debug, acc_granted, acc_required));
248
249         return NT_STATUS_ACCESS_DENIED;
250 }
251
252 /*******************************************************************
253  Map any MAXIMUM_ALLOWED_ACCESS request to a valid access set.
254 ********************************************************************/
255
256 static void map_max_allowed_access(const NT_USER_TOKEN *token,
257                                         uint32_t *pacc_requested)
258 {
259         if (!((*pacc_requested) & MAXIMUM_ALLOWED_ACCESS)) {
260                 return;
261         }
262         *pacc_requested &= ~MAXIMUM_ALLOWED_ACCESS;
263
264         /* At least try for generic read. */
265         *pacc_requested = GENERIC_READ_ACCESS;
266
267         /* root gets anything. */
268         if (geteuid() == sec_initial_uid()) {
269                 *pacc_requested |= GENERIC_ALL_ACCESS;
270                 return;
271         }
272
273         /* Full Access for 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
274
275         if (is_sid_in_token(token, &global_sid_Builtin_Administrators) ||
276                         is_sid_in_token(token, &global_sid_Builtin_Account_Operators)) {
277                 *pacc_requested |= GENERIC_ALL_ACCESS;
278                 return;
279         }
280
281         /* Full access for DOMAIN\Domain Admins. */
282         if ( IS_DC ) {
283                 DOM_SID domadmin_sid;
284                 sid_copy( &domadmin_sid, get_global_sam_sid() );
285                 sid_append_rid( &domadmin_sid, DOMAIN_GROUP_RID_ADMINS );
286                 if (is_sid_in_token(token, &domadmin_sid)) {
287                         *pacc_requested |= GENERIC_ALL_ACCESS;
288                         return;
289                 }
290         }
291         /* TODO ! Check privileges. */
292 }
293
294 /*******************************************************************
295  Fetch or create a dispinfo struct.
296 ********************************************************************/
297
298 static DISP_INFO *get_samr_dispinfo_by_sid(DOM_SID *psid)
299 {
300         /*
301          * We do a static cache for DISP_INFO's here. Explanation can be found
302          * in Jeremy's checkin message to r11793:
303          *
304          * Fix the SAMR cache so it works across completely insane
305          * client behaviour (ie.:
306          * open pipe/open SAMR handle/enumerate 0 - 1024
307          * close SAMR handle, close pipe.
308          * open pipe/open SAMR handle/enumerate 1024 - 2048...
309          * close SAMR handle, close pipe.
310          * And on ad-nausium. Amazing.... probably object-oriented
311          * client side programming in action yet again.
312          * This change should *massively* improve performance when
313          * enumerating users from an LDAP database.
314          * Jeremy.
315          *
316          * "Our" and the builtin domain are the only ones where we ever
317          * enumerate stuff, so just cache 2 entries.
318          */
319
320         static struct disp_info builtin_dispinfo;
321         static struct disp_info domain_dispinfo;
322
323         /* There are two cases to consider here:
324            1) The SID is a domain SID and we look for an equality match, or
325            2) This is an account SID and so we return the DISP_INFO* for our
326               domain */
327
328         if (psid == NULL) {
329                 return NULL;
330         }
331
332         if (sid_check_is_builtin(psid) || sid_check_is_in_builtin(psid)) {
333                 /*
334                  * Necessary only once, but it does not really hurt.
335                  */
336                 sid_copy(&builtin_dispinfo.sid, &global_sid_Builtin);
337
338                 return &builtin_dispinfo;
339         }
340
341         if (sid_check_is_domain(psid) || sid_check_is_in_our_domain(psid)) {
342                 /*
343                  * Necessary only once, but it does not really hurt.
344                  */
345                 sid_copy(&domain_dispinfo.sid, get_global_sam_sid());
346
347                 return &domain_dispinfo;
348         }
349
350         return NULL;
351 }
352
353 /*******************************************************************
354  Create a samr_info struct.
355 ********************************************************************/
356
357 static struct samr_info *get_samr_info_by_sid(DOM_SID *psid)
358 {
359         struct samr_info *info;
360         fstring sid_str;
361         TALLOC_CTX *mem_ctx;
362
363         if (psid) {
364                 sid_to_fstring(sid_str, psid);
365         } else {
366                 fstrcpy(sid_str,"(NULL)");
367         }
368
369         mem_ctx = talloc_init("samr_info for domain sid %s", sid_str);
370
371         if ((info = TALLOC_ZERO_P(mem_ctx, struct samr_info)) == NULL)
372                 return NULL;
373
374         DEBUG(10,("get_samr_info_by_sid: created new info for sid %s\n", sid_str));
375         if (psid) {
376                 sid_copy( &info->sid, psid);
377                 info->builtin_domain = sid_check_is_builtin(psid);
378         } else {
379                 DEBUG(10,("get_samr_info_by_sid: created new info for NULL sid.\n"));
380                 info->builtin_domain = False;
381         }
382         info->mem_ctx = mem_ctx;
383
384         info->disp_info = get_samr_dispinfo_by_sid(psid);
385
386         return info;
387 }
388
389 /*******************************************************************
390  Function to free the per SID data.
391  ********************************************************************/
392
393 static void free_samr_cache(DISP_INFO *disp_info)
394 {
395         DEBUG(10, ("free_samr_cache: deleting cache for SID %s\n",
396                    sid_string_dbg(&disp_info->sid)));
397
398         /* We need to become root here because the paged search might have to
399          * tell the LDAP server we're not interested in the rest anymore. */
400
401         become_root();
402
403         if (disp_info->users) {
404                 DEBUG(10,("free_samr_cache: deleting users cache\n"));
405                 pdb_search_destroy(disp_info->users);
406                 disp_info->users = NULL;
407         }
408         if (disp_info->machines) {
409                 DEBUG(10,("free_samr_cache: deleting machines cache\n"));
410                 pdb_search_destroy(disp_info->machines);
411                 disp_info->machines = NULL;
412         }
413         if (disp_info->groups) {
414                 DEBUG(10,("free_samr_cache: deleting groups cache\n"));
415                 pdb_search_destroy(disp_info->groups);
416                 disp_info->groups = NULL;
417         }
418         if (disp_info->aliases) {
419                 DEBUG(10,("free_samr_cache: deleting aliases cache\n"));
420                 pdb_search_destroy(disp_info->aliases);
421                 disp_info->aliases = NULL;
422         }
423         if (disp_info->enum_users) {
424                 DEBUG(10,("free_samr_cache: deleting enum_users cache\n"));
425                 pdb_search_destroy(disp_info->enum_users);
426                 disp_info->enum_users = NULL;
427         }
428         disp_info->enum_acb_mask = 0;
429
430         unbecome_root();
431 }
432
433 /*******************************************************************
434  Function to free the per handle data.
435  ********************************************************************/
436
437 static void free_samr_info(void *ptr)
438 {
439         struct samr_info *info=(struct samr_info *) ptr;
440
441         /* Only free the dispinfo cache if no one bothered to set up
442            a timeout. */
443
444         if (info->disp_info && info->disp_info->cache_timeout_event == NULL) {
445                 free_samr_cache(info->disp_info);
446         }
447
448         talloc_destroy(info->mem_ctx);
449 }
450
451 /*******************************************************************
452  Idle event handler. Throw away the disp info cache.
453  ********************************************************************/
454
455 static void disp_info_cache_idle_timeout_handler(struct event_context *ev_ctx,
456                                                  struct timed_event *te,
457                                                  struct timeval now,
458                                                  void *private_data)
459 {
460         DISP_INFO *disp_info = (DISP_INFO *)private_data;
461
462         TALLOC_FREE(disp_info->cache_timeout_event);
463
464         DEBUG(10, ("disp_info_cache_idle_timeout_handler: caching timed "
465                    "out\n"));
466         free_samr_cache(disp_info);
467 }
468
469 /*******************************************************************
470  Setup cache removal idle event handler.
471  ********************************************************************/
472
473 static void set_disp_info_cache_timeout(DISP_INFO *disp_info, time_t secs_fromnow)
474 {
475         /* Remove any pending timeout and update. */
476
477         TALLOC_FREE(disp_info->cache_timeout_event);
478
479         DEBUG(10,("set_disp_info_cache_timeout: caching enumeration for "
480                   "SID %s for %u seconds\n", sid_string_dbg(&disp_info->sid),
481                   (unsigned int)secs_fromnow ));
482
483         disp_info->cache_timeout_event = event_add_timed(
484                 smbd_event_context(), NULL,
485                 timeval_current_ofs(secs_fromnow, 0),
486                 disp_info_cache_idle_timeout_handler, (void *)disp_info);
487 }
488
489 /*******************************************************************
490  Force flush any cache. We do this on any samr_set_xxx call.
491  We must also remove the timeout handler.
492  ********************************************************************/
493
494 static void force_flush_samr_cache(DISP_INFO *disp_info)
495 {
496         if ((disp_info == NULL) || (disp_info->cache_timeout_event == NULL)) {
497                 return;
498         }
499
500         DEBUG(10,("force_flush_samr_cache: clearing idle event\n"));
501         TALLOC_FREE(disp_info->cache_timeout_event);
502         free_samr_cache(disp_info);
503 }
504
505 /*******************************************************************
506  Ensure password info is never given out. Paranioa... JRA.
507  ********************************************************************/
508
509 static void samr_clear_sam_passwd(struct samu *sam_pass)
510 {
511
512         if (!sam_pass)
513                 return;
514
515         /* These now zero out the old password */
516
517         pdb_set_lanman_passwd(sam_pass, NULL, PDB_DEFAULT);
518         pdb_set_nt_passwd(sam_pass, NULL, PDB_DEFAULT);
519 }
520
521 static uint32 count_sam_users(struct disp_info *info, uint32 acct_flags)
522 {
523         struct samr_displayentry *entry;
524
525         if (info->builtin_domain) {
526                 /* No users in builtin. */
527                 return 0;
528         }
529
530         if (info->users == NULL) {
531                 info->users = pdb_search_users(acct_flags);
532                 if (info->users == NULL) {
533                         return 0;
534                 }
535         }
536         /* Fetch the last possible entry, thus trigger an enumeration */
537         pdb_search_entries(info->users, 0xffffffff, 1, &entry);
538
539         /* Ensure we cache this enumeration. */
540         set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
541
542         return info->users->num_entries;
543 }
544
545 static uint32 count_sam_groups(struct disp_info *info)
546 {
547         struct samr_displayentry *entry;
548
549         if (info->builtin_domain) {
550                 /* No groups in builtin. */
551                 return 0;
552         }
553
554         if (info->groups == NULL) {
555                 info->groups = pdb_search_groups();
556                 if (info->groups == NULL) {
557                         return 0;
558                 }
559         }
560         /* Fetch the last possible entry, thus trigger an enumeration */
561         pdb_search_entries(info->groups, 0xffffffff, 1, &entry);
562
563         /* Ensure we cache this enumeration. */
564         set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
565
566         return info->groups->num_entries;
567 }
568
569 static uint32 count_sam_aliases(struct disp_info *info)
570 {
571         struct samr_displayentry *entry;
572
573         if (info->aliases == NULL) {
574                 info->aliases = pdb_search_aliases(&info->sid);
575                 if (info->aliases == NULL) {
576                         return 0;
577                 }
578         }
579         /* Fetch the last possible entry, thus trigger an enumeration */
580         pdb_search_entries(info->aliases, 0xffffffff, 1, &entry);
581
582         /* Ensure we cache this enumeration. */
583         set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
584
585         return info->aliases->num_entries;
586 }
587
588 /*******************************************************************
589  _samr_Close
590  ********************************************************************/
591
592 NTSTATUS _samr_Close(pipes_struct *p, struct samr_Close *r)
593 {
594         if (!close_policy_hnd(p, r->in.handle)) {
595                 return NT_STATUS_INVALID_HANDLE;
596         }
597
598         ZERO_STRUCTP(r->out.handle);
599
600         return NT_STATUS_OK;
601 }
602
603 /*******************************************************************
604  _samr_OpenDomain
605  ********************************************************************/
606
607 NTSTATUS _samr_OpenDomain(pipes_struct *p,
608                           struct samr_OpenDomain *r)
609 {
610         struct    samr_info *info;
611         SEC_DESC *psd = NULL;
612         uint32    acc_granted;
613         uint32    des_access = r->in.access_mask;
614         NTSTATUS  status;
615         size_t    sd_size;
616         SE_PRIV se_rights;
617
618         /* find the connection policy handle. */
619
620         if ( !find_policy_by_hnd(p, r->in.connect_handle, (void**)(void *)&info) )
621                 return NT_STATUS_INVALID_HANDLE;
622
623         status = access_check_samr_function(info->acc_granted,
624                                             SAMR_ACCESS_OPEN_DOMAIN,
625                                             "_samr_OpenDomain" );
626
627         if ( !NT_STATUS_IS_OK(status) )
628                 return status;
629
630         /*check if access can be granted as requested by client. */
631         map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
632
633         make_samr_object_sd( p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0 );
634         se_map_generic( &des_access, &dom_generic_mapping );
635
636         se_priv_copy( &se_rights, &se_machine_account );
637         se_priv_add( &se_rights, &se_add_users );
638
639         status = access_check_samr_object( psd, p->pipe_user.nt_user_token,
640                 &se_rights, GENERIC_RIGHTS_DOMAIN_WRITE, des_access,
641                 &acc_granted, "_samr_OpenDomain" );
642
643         if ( !NT_STATUS_IS_OK(status) )
644                 return status;
645
646         if (!sid_check_is_domain(r->in.sid) &&
647             !sid_check_is_builtin(r->in.sid)) {
648                 return NT_STATUS_NO_SUCH_DOMAIN;
649         }
650
651         /* associate the domain SID with the (unique) handle. */
652         if ((info = get_samr_info_by_sid(r->in.sid))==NULL)
653                 return NT_STATUS_NO_MEMORY;
654         info->acc_granted = acc_granted;
655
656         /* get a (unique) handle.  open a policy on it. */
657         if (!create_policy_hnd(p, r->out.domain_handle, free_samr_info, (void *)info))
658                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
659
660         DEBUG(5,("_samr_OpenDomain: %d\n", __LINE__));
661
662         return NT_STATUS_OK;
663 }
664
665 /*******************************************************************
666  _samr_GetUserPwInfo
667  ********************************************************************/
668
669 NTSTATUS _samr_GetUserPwInfo(pipes_struct *p,
670                              struct samr_GetUserPwInfo *r)
671 {
672         struct samr_info *info = NULL;
673         enum lsa_SidType sid_type;
674         uint32_t min_password_length = 0;
675         uint32_t password_properties = 0;
676         bool ret = false;
677         NTSTATUS status;
678
679         DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__));
680
681         /* find the policy handle.  open a policy on it. */
682         if (!find_policy_by_hnd(p, r->in.user_handle, (void **)(void *)&info)) {
683                 return NT_STATUS_INVALID_HANDLE;
684         }
685
686         status = access_check_samr_function(info->acc_granted,
687                                             SAMR_USER_ACCESS_GET_ATTRIBUTES,
688                                             "_samr_GetUserPwInfo" );
689         if (!NT_STATUS_IS_OK(status)) {
690                 return status;
691         }
692
693         if (!sid_check_is_in_our_domain(&info->sid)) {
694                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
695         }
696
697         become_root();
698         ret = lookup_sid(p->mem_ctx, &info->sid, NULL, NULL, &sid_type);
699         unbecome_root();
700         if (ret == false) {
701                 return NT_STATUS_NO_SUCH_USER;
702         }
703
704         switch (sid_type) {
705                 case SID_NAME_USER:
706                         become_root();
707                         pdb_get_account_policy(AP_MIN_PASSWORD_LEN,
708                                                &min_password_length);
709                         pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
710                                                &password_properties);
711                         unbecome_root();
712
713                         if (lp_check_password_script() && *lp_check_password_script()) {
714                                 password_properties |= DOMAIN_PASSWORD_COMPLEX;
715                         }
716
717                         break;
718                 default:
719                         break;
720         }
721
722         r->out.info->min_password_length = min_password_length;
723         r->out.info->password_properties = password_properties;
724
725         DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__));
726
727         return NT_STATUS_OK;
728 }
729
730 /*******************************************************************
731 ********************************************************************/
732
733 static bool get_lsa_policy_samr_sid( pipes_struct *p, POLICY_HND *pol,
734                                         DOM_SID *sid, uint32 *acc_granted,
735                                         DISP_INFO **ppdisp_info)
736 {
737         struct samr_info *info = NULL;
738
739         /* find the policy handle.  open a policy on it. */
740         if (!find_policy_by_hnd(p, pol, (void **)(void *)&info))
741                 return False;
742
743         if (!info)
744                 return False;
745
746         *sid = info->sid;
747         *acc_granted = info->acc_granted;
748         if (ppdisp_info) {
749                 *ppdisp_info = info->disp_info;
750         }
751
752         return True;
753 }
754
755 /*******************************************************************
756  _samr_SetSecurity
757  ********************************************************************/
758
759 NTSTATUS _samr_SetSecurity(pipes_struct *p,
760                            struct samr_SetSecurity *r)
761 {
762         DOM_SID pol_sid;
763         uint32 acc_granted, i;
764         SEC_ACL *dacl;
765         bool ret;
766         struct samu *sampass=NULL;
767         NTSTATUS status;
768
769         if (!get_lsa_policy_samr_sid(p, r->in.handle, &pol_sid, &acc_granted, NULL))
770                 return NT_STATUS_INVALID_HANDLE;
771
772         if (!(sampass = samu_new( p->mem_ctx))) {
773                 DEBUG(0,("No memory!\n"));
774                 return NT_STATUS_NO_MEMORY;
775         }
776
777         /* get the user record */
778         become_root();
779         ret = pdb_getsampwsid(sampass, &pol_sid);
780         unbecome_root();
781
782         if (!ret) {
783                 DEBUG(4, ("User %s not found\n", sid_string_dbg(&pol_sid)));
784                 TALLOC_FREE(sampass);
785                 return NT_STATUS_INVALID_HANDLE;
786         }
787
788         dacl = r->in.sdbuf->sd->dacl;
789         for (i=0; i < dacl->num_aces; i++) {
790                 if (sid_equal(&pol_sid, &dacl->aces[i].trustee)) {
791                         ret = pdb_set_pass_can_change(sampass,
792                                 (dacl->aces[i].access_mask &
793                                  SAMR_USER_ACCESS_CHANGE_PASSWORD) ?
794                                                       True: False);
795                         break;
796                 }
797         }
798
799         if (!ret) {
800                 TALLOC_FREE(sampass);
801                 return NT_STATUS_ACCESS_DENIED;
802         }
803
804         status = access_check_samr_function(acc_granted,
805                                             SAMR_USER_ACCESS_SET_ATTRIBUTES,
806                                             "_samr_SetSecurity");
807         if (NT_STATUS_IS_OK(status)) {
808                 become_root();
809                 status = pdb_update_sam_account(sampass);
810                 unbecome_root();
811         }
812
813         TALLOC_FREE(sampass);
814
815         return status;
816 }
817
818 /*******************************************************************
819   build correct perms based on policies and password times for _samr_query_sec_obj
820 *******************************************************************/
821 static bool check_change_pw_access(TALLOC_CTX *mem_ctx, DOM_SID *user_sid)
822 {
823         struct samu *sampass=NULL;
824         bool ret;
825
826         if ( !(sampass = samu_new( mem_ctx )) ) {
827                 DEBUG(0,("No memory!\n"));
828                 return False;
829         }
830
831         become_root();
832         ret = pdb_getsampwsid(sampass, user_sid);
833         unbecome_root();
834
835         if (ret == False) {
836                 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
837                 TALLOC_FREE(sampass);
838                 return False;
839         }
840
841         DEBUG(3,("User:[%s]\n",  pdb_get_username(sampass) ));
842
843         if (pdb_get_pass_can_change(sampass)) {
844                 TALLOC_FREE(sampass);
845                 return True;
846         }
847         TALLOC_FREE(sampass);
848         return False;
849 }
850
851
852 /*******************************************************************
853  _samr_QuerySecurity
854  ********************************************************************/
855
856 NTSTATUS _samr_QuerySecurity(pipes_struct *p,
857                              struct samr_QuerySecurity *r)
858 {
859         NTSTATUS status;
860         DOM_SID pol_sid;
861         SEC_DESC * psd = NULL;
862         uint32 acc_granted;
863         size_t sd_size;
864
865         /* Get the SID. */
866         if (!get_lsa_policy_samr_sid(p, r->in.handle, &pol_sid, &acc_granted, NULL))
867                 return NT_STATUS_INVALID_HANDLE;
868
869         DEBUG(10,("_samr_QuerySecurity: querying security on SID: %s\n",
870                   sid_string_dbg(&pol_sid)));
871
872         status = access_check_samr_function(acc_granted,
873                                             STD_RIGHT_READ_CONTROL_ACCESS,
874                                             "_samr_QuerySecurity");
875         if (!NT_STATUS_IS_OK(status)) {
876                 return status;
877         }
878
879         /* Check what typ of SID is beeing queried (e.g Domain SID, User SID, Group SID) */
880
881         /* To query the security of the SAM it self an invalid SID with S-0-0 is passed to this function */
882         if (pol_sid.sid_rev_num == 0) {
883                 DEBUG(5,("_samr_QuerySecurity: querying security on SAM\n"));
884                 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
885         } else if (sid_equal(&pol_sid,get_global_sam_sid())) {
886                 /* check if it is our domain SID */
887                 DEBUG(5,("_samr_QuerySecurity: querying security on Domain "
888                          "with SID: %s\n", sid_string_dbg(&pol_sid)));
889                 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0);
890         } else if (sid_equal(&pol_sid,&global_sid_Builtin)) {
891                 /* check if it is the Builtin  Domain */
892                 /* TODO: Builtin probably needs a different SD with restricted write access*/
893                 DEBUG(5,("_samr_QuerySecurity: querying security on Builtin "
894                          "Domain with SID: %s\n", sid_string_dbg(&pol_sid)));
895                 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0);
896         } else if (sid_check_is_in_our_domain(&pol_sid) ||
897                  sid_check_is_in_builtin(&pol_sid)) {
898                 /* TODO: different SDs have to be generated for aliases groups and users.
899                          Currently all three get a default user SD  */
900                 DEBUG(10,("_samr_QuerySecurity: querying security on Object "
901                           "with SID: %s\n", sid_string_dbg(&pol_sid)));
902                 if (check_change_pw_access(p->mem_ctx, &pol_sid)) {
903                         status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping,
904                                                           &pol_sid, SAMR_USR_RIGHTS_WRITE_PW);
905                 } else {
906                         status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_nopwchange_generic_mapping,
907                                                           &pol_sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
908                 }
909         } else {
910                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
911         }
912
913         if ((*r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
914                 return NT_STATUS_NO_MEMORY;
915
916         return status;
917 }
918
919 /*******************************************************************
920 makes a SAM_ENTRY / UNISTR2* structure from a user list.
921 ********************************************************************/
922
923 static NTSTATUS make_user_sam_entry_list(TALLOC_CTX *ctx,
924                                          struct samr_SamEntry **sam_pp,
925                                          uint32_t num_entries,
926                                          uint32_t start_idx,
927                                          struct samr_displayentry *entries)
928 {
929         uint32_t i;
930         struct samr_SamEntry *sam;
931
932         *sam_pp = NULL;
933
934         if (num_entries == 0) {
935                 return NT_STATUS_OK;
936         }
937
938         sam = TALLOC_ZERO_ARRAY(ctx, struct samr_SamEntry, num_entries);
939         if (sam == NULL) {
940                 DEBUG(0, ("make_user_sam_entry_list: TALLOC_ZERO failed!\n"));
941                 return NT_STATUS_NO_MEMORY;
942         }
943
944         for (i = 0; i < num_entries; i++) {
945 #if 0
946                 /*
947                  * usrmgr expects a non-NULL terminated string with
948                  * trust relationships
949                  */
950                 if (entries[i].acct_flags & ACB_DOMTRUST) {
951                         init_unistr2(&uni_temp_name, entries[i].account_name,
952                                      UNI_FLAGS_NONE);
953                 } else {
954                         init_unistr2(&uni_temp_name, entries[i].account_name,
955                                      UNI_STR_TERMINATE);
956                 }
957 #endif
958                 init_lsa_String(&sam[i].name, entries[i].account_name);
959                 sam[i].idx = entries[i].rid;
960         }
961
962         *sam_pp = sam;
963
964         return NT_STATUS_OK;
965 }
966
967 #define MAX_SAM_ENTRIES MAX_SAM_ENTRIES_W2K
968
969 /*******************************************************************
970  _samr_EnumDomainUsers
971  ********************************************************************/
972
973 NTSTATUS _samr_EnumDomainUsers(pipes_struct *p,
974                                struct samr_EnumDomainUsers *r)
975 {
976         NTSTATUS status;
977         struct samr_info *info = NULL;
978         int num_account;
979         uint32 enum_context = *r->in.resume_handle;
980         enum remote_arch_types ra_type = get_remote_arch();
981         int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
982         uint32 max_entries = max_sam_entries;
983         struct samr_displayentry *entries = NULL;
984         struct samr_SamArray *samr_array = NULL;
985         struct samr_SamEntry *samr_entries = NULL;
986
987         /* find the policy handle.  open a policy on it. */
988         if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
989                 return NT_STATUS_INVALID_HANDLE;
990
991         status = access_check_samr_function(info->acc_granted,
992                                             SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
993                                             "_samr_EnumDomainUsers");
994         if (!NT_STATUS_IS_OK(status)) {
995                 return status;
996         }
997
998         DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
999
1000         if (info->builtin_domain) {
1001                 /* No users in builtin. */
1002                 *r->out.resume_handle = *r->in.resume_handle;
1003                 DEBUG(5,("_samr_EnumDomainUsers: No users in BUILTIN\n"));
1004                 return status;
1005         }
1006
1007         samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
1008         if (!samr_array) {
1009                 return NT_STATUS_NO_MEMORY;
1010         }
1011         *r->out.sam = samr_array;
1012
1013         become_root();
1014
1015         /* AS ROOT !!!! */
1016
1017         if ((info->disp_info->enum_users != NULL) &&
1018             (info->disp_info->enum_acb_mask != r->in.acct_flags)) {
1019                 pdb_search_destroy(info->disp_info->enum_users);
1020                 info->disp_info->enum_users = NULL;
1021         }
1022
1023         if (info->disp_info->enum_users == NULL) {
1024                 info->disp_info->enum_users = pdb_search_users(r->in.acct_flags);
1025                 info->disp_info->enum_acb_mask = r->in.acct_flags;
1026         }
1027
1028         if (info->disp_info->enum_users == NULL) {
1029                 /* END AS ROOT !!!! */
1030                 unbecome_root();
1031                 return NT_STATUS_ACCESS_DENIED;
1032         }
1033
1034         num_account = pdb_search_entries(info->disp_info->enum_users,
1035                                          enum_context, max_entries,
1036                                          &entries);
1037
1038         /* END AS ROOT !!!! */
1039
1040         unbecome_root();
1041
1042         if (num_account == 0) {
1043                 DEBUG(5, ("_samr_EnumDomainUsers: enumeration handle over "
1044                           "total entries\n"));
1045                 *r->out.resume_handle = *r->in.resume_handle;
1046                 return NT_STATUS_OK;
1047         }
1048
1049         status = make_user_sam_entry_list(p->mem_ctx, &samr_entries,
1050                                           num_account, enum_context,
1051                                           entries);
1052         if (!NT_STATUS_IS_OK(status)) {
1053                 return status;
1054         }
1055
1056         if (max_entries <= num_account) {
1057                 status = STATUS_MORE_ENTRIES;
1058         } else {
1059                 status = NT_STATUS_OK;
1060         }
1061
1062         /* Ensure we cache this enumeration. */
1063         set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1064
1065         DEBUG(5, ("_samr_EnumDomainUsers: %d\n", __LINE__));
1066
1067         samr_array->count = num_account;
1068         samr_array->entries = samr_entries;
1069
1070         *r->out.resume_handle = *r->in.resume_handle + num_account;
1071         *r->out.num_entries = num_account;
1072
1073         DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
1074
1075         return status;
1076 }
1077
1078 /*******************************************************************
1079 makes a SAM_ENTRY / UNISTR2* structure from a group list.
1080 ********************************************************************/
1081
1082 static void make_group_sam_entry_list(TALLOC_CTX *ctx,
1083                                       struct samr_SamEntry **sam_pp,
1084                                       uint32_t num_sam_entries,
1085                                       struct samr_displayentry *entries)
1086 {
1087         struct samr_SamEntry *sam;
1088         uint32_t i;
1089
1090         *sam_pp = NULL;
1091
1092         if (num_sam_entries == 0) {
1093                 return;
1094         }
1095
1096         sam = TALLOC_ZERO_ARRAY(ctx, struct samr_SamEntry, num_sam_entries);
1097         if (sam == NULL) {
1098                 return;
1099         }
1100
1101         for (i = 0; i < num_sam_entries; i++) {
1102                 /*
1103                  * JRA. I think this should include the null. TNG does not.
1104                  */
1105                 init_lsa_String(&sam[i].name, entries[i].account_name);
1106                 sam[i].idx = entries[i].rid;
1107         }
1108
1109         *sam_pp = sam;
1110 }
1111
1112 /*******************************************************************
1113  _samr_EnumDomainGroups
1114  ********************************************************************/
1115
1116 NTSTATUS _samr_EnumDomainGroups(pipes_struct *p,
1117                                 struct samr_EnumDomainGroups *r)
1118 {
1119         NTSTATUS status;
1120         struct samr_info *info = NULL;
1121         struct samr_displayentry *groups;
1122         uint32 num_groups;
1123         struct samr_SamArray *samr_array = NULL;
1124         struct samr_SamEntry *samr_entries = NULL;
1125
1126         /* find the policy handle.  open a policy on it. */
1127         if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
1128                 return NT_STATUS_INVALID_HANDLE;
1129
1130         status = access_check_samr_function(info->acc_granted,
1131                                             SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
1132                                             "_samr_EnumDomainGroups");
1133         if (!NT_STATUS_IS_OK(status)) {
1134                 return status;
1135         }
1136
1137         DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
1138
1139         if (info->builtin_domain) {
1140                 /* No groups in builtin. */
1141                 *r->out.resume_handle = *r->in.resume_handle;
1142                 DEBUG(5,("_samr_EnumDomainGroups: No groups in BUILTIN\n"));
1143                 return status;
1144         }
1145
1146         samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
1147         if (!samr_array) {
1148                 return NT_STATUS_NO_MEMORY;
1149         }
1150
1151         /* the domain group array is being allocated in the function below */
1152
1153         become_root();
1154
1155         if (info->disp_info->groups == NULL) {
1156                 info->disp_info->groups = pdb_search_groups();
1157
1158                 if (info->disp_info->groups == NULL) {
1159                         unbecome_root();
1160                         return NT_STATUS_ACCESS_DENIED;
1161                 }
1162         }
1163
1164         num_groups = pdb_search_entries(info->disp_info->groups,
1165                                         *r->in.resume_handle,
1166                                         MAX_SAM_ENTRIES, &groups);
1167         unbecome_root();
1168
1169         /* Ensure we cache this enumeration. */
1170         set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1171
1172         make_group_sam_entry_list(p->mem_ctx, &samr_entries,
1173                                   num_groups, groups);
1174
1175         samr_array->count = num_groups;
1176         samr_array->entries = samr_entries;
1177
1178         *r->out.sam = samr_array;
1179         *r->out.num_entries = num_groups;
1180         *r->out.resume_handle = num_groups + *r->in.resume_handle;
1181
1182         DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
1183
1184         return status;
1185 }
1186
1187 /*******************************************************************
1188  _samr_EnumDomainAliases
1189  ********************************************************************/
1190
1191 NTSTATUS _samr_EnumDomainAliases(pipes_struct *p,
1192                                  struct samr_EnumDomainAliases *r)
1193 {
1194         NTSTATUS status;
1195         struct samr_info *info;
1196         struct samr_displayentry *aliases;
1197         uint32 num_aliases = 0;
1198         struct samr_SamArray *samr_array = NULL;
1199         struct samr_SamEntry *samr_entries = NULL;
1200
1201         /* find the policy handle.  open a policy on it. */
1202         if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
1203                 return NT_STATUS_INVALID_HANDLE;
1204
1205         DEBUG(5,("_samr_EnumDomainAliases: sid %s\n",
1206                  sid_string_dbg(&info->sid)));
1207
1208         status = access_check_samr_function(info->acc_granted,
1209                                             SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
1210                                             "_samr_EnumDomainAliases");
1211         if (!NT_STATUS_IS_OK(status)) {
1212                 return status;
1213         }
1214
1215         samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
1216         if (!samr_array) {
1217                 return NT_STATUS_NO_MEMORY;
1218         }
1219
1220         become_root();
1221
1222         if (info->disp_info->aliases == NULL) {
1223                 info->disp_info->aliases = pdb_search_aliases(&info->sid);
1224                 if (info->disp_info->aliases == NULL) {
1225                         unbecome_root();
1226                         return NT_STATUS_ACCESS_DENIED;
1227                 }
1228         }
1229
1230         num_aliases = pdb_search_entries(info->disp_info->aliases,
1231                                          *r->in.resume_handle,
1232                                          MAX_SAM_ENTRIES, &aliases);
1233         unbecome_root();
1234
1235         /* Ensure we cache this enumeration. */
1236         set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1237
1238         make_group_sam_entry_list(p->mem_ctx, &samr_entries,
1239                                   num_aliases, aliases);
1240
1241         DEBUG(5,("_samr_EnumDomainAliases: %d\n", __LINE__));
1242
1243         samr_array->count = num_aliases;
1244         samr_array->entries = samr_entries;
1245
1246         *r->out.sam = samr_array;
1247         *r->out.num_entries = num_aliases;
1248         *r->out.resume_handle = num_aliases + *r->in.resume_handle;
1249
1250         return status;
1251 }
1252
1253 /*******************************************************************
1254  inits a samr_DispInfoGeneral structure.
1255 ********************************************************************/
1256
1257 static NTSTATUS init_samr_dispinfo_1(TALLOC_CTX *ctx,
1258                                      struct samr_DispInfoGeneral *r,
1259                                      uint32_t num_entries,
1260                                      uint32_t start_idx,
1261                                      struct samr_displayentry *entries)
1262 {
1263         uint32 i;
1264
1265         DEBUG(10, ("init_samr_dispinfo_1: num_entries: %d\n", num_entries));
1266
1267         if (num_entries == 0) {
1268                 return NT_STATUS_OK;
1269         }
1270
1271         r->count = num_entries;
1272
1273         r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryGeneral, num_entries);
1274         if (!r->entries) {
1275                 return NT_STATUS_NO_MEMORY;
1276         }
1277
1278         for (i = 0; i < num_entries ; i++) {
1279
1280                 init_lsa_String(&r->entries[i].account_name,
1281                                 entries[i].account_name);
1282
1283                 init_lsa_String(&r->entries[i].description,
1284                                 entries[i].description);
1285
1286                 init_lsa_String(&r->entries[i].full_name,
1287                                 entries[i].fullname);
1288
1289                 r->entries[i].rid = entries[i].rid;
1290                 r->entries[i].acct_flags = entries[i].acct_flags;
1291                 r->entries[i].idx = start_idx+i+1;
1292         }
1293
1294         return NT_STATUS_OK;
1295 }
1296
1297 /*******************************************************************
1298  inits a samr_DispInfoFull structure.
1299 ********************************************************************/
1300
1301 static NTSTATUS init_samr_dispinfo_2(TALLOC_CTX *ctx,
1302                                      struct samr_DispInfoFull *r,
1303                                      uint32_t num_entries,
1304                                      uint32_t start_idx,
1305                                      struct samr_displayentry *entries)
1306 {
1307         uint32_t i;
1308
1309         DEBUG(10, ("init_samr_dispinfo_2: num_entries: %d\n", num_entries));
1310
1311         if (num_entries == 0) {
1312                 return NT_STATUS_OK;
1313         }
1314
1315         r->count = num_entries;
1316
1317         r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryFull, num_entries);
1318         if (!r->entries) {
1319                 return NT_STATUS_NO_MEMORY;
1320         }
1321
1322         for (i = 0; i < num_entries ; i++) {
1323
1324                 init_lsa_String(&r->entries[i].account_name,
1325                                 entries[i].account_name);
1326
1327                 init_lsa_String(&r->entries[i].description,
1328                                 entries[i].description);
1329
1330                 r->entries[i].rid = entries[i].rid;
1331                 r->entries[i].acct_flags = entries[i].acct_flags;
1332                 r->entries[i].idx = start_idx+i+1;
1333         }
1334
1335         return NT_STATUS_OK;
1336 }
1337
1338 /*******************************************************************
1339  inits a samr_DispInfoFullGroups structure.
1340 ********************************************************************/
1341
1342 static NTSTATUS init_samr_dispinfo_3(TALLOC_CTX *ctx,
1343                                      struct samr_DispInfoFullGroups *r,
1344                                      uint32_t num_entries,
1345                                      uint32_t start_idx,
1346                                      struct samr_displayentry *entries)
1347 {
1348         uint32_t i;
1349
1350         DEBUG(5, ("init_samr_dispinfo_3: num_entries: %d\n", num_entries));
1351
1352         if (num_entries == 0) {
1353                 return NT_STATUS_OK;
1354         }
1355
1356         r->count = num_entries;
1357
1358         r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryFullGroup, num_entries);
1359         if (!r->entries) {
1360                 return NT_STATUS_NO_MEMORY;
1361         }
1362
1363         for (i = 0; i < num_entries ; i++) {
1364
1365                 init_lsa_String(&r->entries[i].account_name,
1366                                 entries[i].account_name);
1367
1368                 init_lsa_String(&r->entries[i].description,
1369                                 entries[i].description);
1370
1371                 r->entries[i].rid = entries[i].rid;
1372                 r->entries[i].acct_flags = entries[i].acct_flags;
1373                 r->entries[i].idx = start_idx+i+1;
1374         }
1375
1376         return NT_STATUS_OK;
1377 }
1378
1379 /*******************************************************************
1380  inits a samr_DispInfoAscii structure.
1381 ********************************************************************/
1382
1383 static NTSTATUS init_samr_dispinfo_4(TALLOC_CTX *ctx,
1384                                      struct samr_DispInfoAscii *r,
1385                                      uint32_t num_entries,
1386                                      uint32_t start_idx,
1387                                      struct samr_displayentry *entries)
1388 {
1389         uint32_t i;
1390
1391         DEBUG(5, ("init_samr_dispinfo_4: num_entries: %d\n", num_entries));
1392
1393         if (num_entries == 0) {
1394                 return NT_STATUS_OK;
1395         }
1396
1397         r->count = num_entries;
1398
1399         r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryAscii, num_entries);
1400         if (!r->entries) {
1401                 return NT_STATUS_NO_MEMORY;
1402         }
1403
1404         for (i = 0; i < num_entries ; i++) {
1405
1406                 init_lsa_AsciiStringLarge(&r->entries[i].account_name,
1407                                           entries[i].account_name);
1408
1409                 r->entries[i].idx = start_idx+i+1;
1410         }
1411
1412         return NT_STATUS_OK;
1413 }
1414
1415 /*******************************************************************
1416  inits a samr_DispInfoAscii structure.
1417 ********************************************************************/
1418
1419 static NTSTATUS init_samr_dispinfo_5(TALLOC_CTX *ctx,
1420                                      struct samr_DispInfoAscii *r,
1421                                      uint32_t num_entries,
1422                                      uint32_t start_idx,
1423                                      struct samr_displayentry *entries)
1424 {
1425         uint32_t i;
1426
1427         DEBUG(5, ("init_samr_dispinfo_5: num_entries: %d\n", num_entries));
1428
1429         if (num_entries == 0) {
1430                 return NT_STATUS_OK;
1431         }
1432
1433         r->count = num_entries;
1434
1435         r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryAscii, num_entries);
1436         if (!r->entries) {
1437                 return NT_STATUS_NO_MEMORY;
1438         }
1439
1440         for (i = 0; i < num_entries ; i++) {
1441
1442                 init_lsa_AsciiStringLarge(&r->entries[i].account_name,
1443                                           entries[i].account_name);
1444
1445                 r->entries[i].idx = start_idx+i+1;
1446         }
1447
1448         return NT_STATUS_OK;
1449 }
1450
1451 /*******************************************************************
1452  _samr_QueryDisplayInfo
1453  ********************************************************************/
1454
1455 NTSTATUS _samr_QueryDisplayInfo(pipes_struct *p,
1456                                 struct samr_QueryDisplayInfo *r)
1457 {
1458         NTSTATUS status;
1459         struct samr_info *info = NULL;
1460         uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
1461
1462         uint32 max_entries = r->in.max_entries;
1463         uint32 enum_context = r->in.start_idx;
1464         uint32 max_size = r->in.buf_size;
1465
1466         union samr_DispInfo *disp_info = r->out.info;
1467
1468         uint32 temp_size=0, total_data_size=0;
1469         NTSTATUS disp_ret = NT_STATUS_UNSUCCESSFUL;
1470         uint32 num_account = 0;
1471         enum remote_arch_types ra_type = get_remote_arch();
1472         int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
1473         struct samr_displayentry *entries = NULL;
1474
1475         DEBUG(5,("_samr_QueryDisplayInfo: %d\n", __LINE__));
1476
1477         /* find the policy handle.  open a policy on it. */
1478         if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
1479                 return NT_STATUS_INVALID_HANDLE;
1480
1481         if (info->builtin_domain) {
1482                 DEBUG(5,("_samr_QueryDisplayInfo: Nothing in BUILTIN\n"));
1483                 return NT_STATUS_OK;
1484         }
1485
1486         status = access_check_samr_function(info->acc_granted,
1487                                             SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
1488                                             "_samr_QueryDisplayInfo");
1489         if (!NT_STATUS_IS_OK(status)) {
1490                 return status;
1491         }
1492
1493         /*
1494          * calculate how many entries we will return.
1495          * based on
1496          * - the number of entries the client asked
1497          * - our limit on that
1498          * - the starting point (enumeration context)
1499          * - the buffer size the client will accept
1500          */
1501
1502         /*
1503          * We are a lot more like W2K. Instead of reading the SAM
1504          * each time to find the records we need to send back,
1505          * we read it once and link that copy to the sam handle.
1506          * For large user list (over the MAX_SAM_ENTRIES)
1507          * it's a definitive win.
1508          * second point to notice: between enumerations
1509          * our sam is now the same as it's a snapshoot.
1510          * third point: got rid of the static SAM_USER_21 struct
1511          * no more intermediate.
1512          * con: it uses much more memory, as a full copy is stored
1513          * in memory.
1514          *
1515          * If you want to change it, think twice and think
1516          * of the second point , that's really important.
1517          *
1518          * JFM, 12/20/2001
1519          */
1520
1521         if ((r->in.level < 1) || (r->in.level > 5)) {
1522                 DEBUG(0,("_samr_QueryDisplayInfo: Unknown info level (%u)\n",
1523                          (unsigned int)r->in.level ));
1524                 return NT_STATUS_INVALID_INFO_CLASS;
1525         }
1526
1527         /* first limit the number of entries we will return */
1528         if(max_entries > max_sam_entries) {
1529                 DEBUG(5, ("_samr_QueryDisplayInfo: client requested %d "
1530                           "entries, limiting to %d\n", max_entries,
1531                           max_sam_entries));
1532                 max_entries = max_sam_entries;
1533         }
1534
1535         /* calculate the size and limit on the number of entries we will
1536          * return */
1537
1538         temp_size=max_entries*struct_size;
1539
1540         if (temp_size>max_size) {
1541                 max_entries=MIN((max_size/struct_size),max_entries);;
1542                 DEBUG(5, ("_samr_QueryDisplayInfo: buffer size limits to "
1543                           "only %d entries\n", max_entries));
1544         }
1545
1546         become_root();
1547
1548         /* THe following done as ROOT. Don't return without unbecome_root(). */
1549
1550         switch (r->in.level) {
1551         case 0x1:
1552         case 0x4:
1553                 if (info->disp_info->users == NULL) {
1554                         info->disp_info->users = pdb_search_users(ACB_NORMAL);
1555                         if (info->disp_info->users == NULL) {
1556                                 unbecome_root();
1557                                 return NT_STATUS_ACCESS_DENIED;
1558                         }
1559                         DEBUG(10,("_samr_QueryDisplayInfo: starting user enumeration at index %u\n",
1560                                 (unsigned  int)enum_context ));
1561                 } else {
1562                         DEBUG(10,("_samr_QueryDisplayInfo: using cached user enumeration at index %u\n",
1563                                 (unsigned  int)enum_context ));
1564                 }
1565
1566                 num_account = pdb_search_entries(info->disp_info->users,
1567                                                  enum_context, max_entries,
1568                                                  &entries);
1569                 break;
1570         case 0x2:
1571                 if (info->disp_info->machines == NULL) {
1572                         info->disp_info->machines =
1573                                 pdb_search_users(ACB_WSTRUST|ACB_SVRTRUST);
1574                         if (info->disp_info->machines == NULL) {
1575                                 unbecome_root();
1576                                 return NT_STATUS_ACCESS_DENIED;
1577                         }
1578                         DEBUG(10,("_samr_QueryDisplayInfo: starting machine enumeration at index %u\n",
1579                                 (unsigned  int)enum_context ));
1580                 } else {
1581                         DEBUG(10,("_samr_QueryDisplayInfo: using cached machine enumeration at index %u\n",
1582                                 (unsigned  int)enum_context ));
1583                 }
1584
1585                 num_account = pdb_search_entries(info->disp_info->machines,
1586                                                  enum_context, max_entries,
1587                                                  &entries);
1588                 break;
1589         case 0x3:
1590         case 0x5:
1591                 if (info->disp_info->groups == NULL) {
1592                         info->disp_info->groups = pdb_search_groups();
1593                         if (info->disp_info->groups == NULL) {
1594                                 unbecome_root();
1595                                 return NT_STATUS_ACCESS_DENIED;
1596                         }
1597                         DEBUG(10,("_samr_QueryDisplayInfo: starting group enumeration at index %u\n",
1598                                 (unsigned  int)enum_context ));
1599                 } else {
1600                         DEBUG(10,("_samr_QueryDisplayInfo: using cached group enumeration at index %u\n",
1601                                 (unsigned  int)enum_context ));
1602                 }
1603
1604                 num_account = pdb_search_entries(info->disp_info->groups,
1605                                                  enum_context, max_entries,
1606                                                  &entries);
1607                 break;
1608         default:
1609                 unbecome_root();
1610                 smb_panic("info class changed");
1611                 break;
1612         }
1613         unbecome_root();
1614
1615
1616         /* Now create reply structure */
1617         switch (r->in.level) {
1618         case 0x1:
1619                 disp_ret = init_samr_dispinfo_1(p->mem_ctx, &disp_info->info1,
1620                                                 num_account, enum_context,
1621                                                 entries);
1622                 break;
1623         case 0x2:
1624                 disp_ret = init_samr_dispinfo_2(p->mem_ctx, &disp_info->info2,
1625                                                 num_account, enum_context,
1626                                                 entries);
1627                 break;
1628         case 0x3:
1629                 disp_ret = init_samr_dispinfo_3(p->mem_ctx, &disp_info->info3,
1630                                                 num_account, enum_context,
1631                                                 entries);
1632                 break;
1633         case 0x4:
1634                 disp_ret = init_samr_dispinfo_4(p->mem_ctx, &disp_info->info4,
1635                                                 num_account, enum_context,
1636                                                 entries);
1637                 break;
1638         case 0x5:
1639                 disp_ret = init_samr_dispinfo_5(p->mem_ctx, &disp_info->info5,
1640                                                 num_account, enum_context,
1641                                                 entries);
1642                 break;
1643         default:
1644                 smb_panic("info class changed");
1645                 break;
1646         }
1647
1648         if (!NT_STATUS_IS_OK(disp_ret))
1649                 return disp_ret;
1650
1651         /* calculate the total size */
1652         total_data_size=num_account*struct_size;
1653
1654         if (max_entries <= num_account) {
1655                 status = STATUS_MORE_ENTRIES;
1656         } else {
1657                 status = NT_STATUS_OK;
1658         }
1659
1660         /* Ensure we cache this enumeration. */
1661         set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1662
1663         DEBUG(5, ("_samr_QueryDisplayInfo: %d\n", __LINE__));
1664
1665         *r->out.total_size = total_data_size;
1666         *r->out.returned_size = temp_size;
1667
1668         return status;
1669 }
1670
1671 /****************************************************************
1672  _samr_QueryDisplayInfo2
1673 ****************************************************************/
1674
1675 NTSTATUS _samr_QueryDisplayInfo2(pipes_struct *p,
1676                                  struct samr_QueryDisplayInfo2 *r)
1677 {
1678         struct samr_QueryDisplayInfo q;
1679
1680         q.in.domain_handle      = r->in.domain_handle;
1681         q.in.level              = r->in.level;
1682         q.in.start_idx          = r->in.start_idx;
1683         q.in.max_entries        = r->in.max_entries;
1684         q.in.buf_size           = r->in.buf_size;
1685
1686         q.out.total_size        = r->out.total_size;
1687         q.out.returned_size     = r->out.returned_size;
1688         q.out.info              = r->out.info;
1689
1690         return _samr_QueryDisplayInfo(p, &q);
1691 }
1692
1693 /****************************************************************
1694  _samr_QueryDisplayInfo3
1695 ****************************************************************/
1696
1697 NTSTATUS _samr_QueryDisplayInfo3(pipes_struct *p,
1698                                  struct samr_QueryDisplayInfo3 *r)
1699 {
1700         struct samr_QueryDisplayInfo q;
1701
1702         q.in.domain_handle      = r->in.domain_handle;
1703         q.in.level              = r->in.level;
1704         q.in.start_idx          = r->in.start_idx;
1705         q.in.max_entries        = r->in.max_entries;
1706         q.in.buf_size           = r->in.buf_size;
1707
1708         q.out.total_size        = r->out.total_size;
1709         q.out.returned_size     = r->out.returned_size;
1710         q.out.info              = r->out.info;
1711
1712         return _samr_QueryDisplayInfo(p, &q);
1713 }
1714
1715 /*******************************************************************
1716  _samr_QueryAliasInfo
1717  ********************************************************************/
1718
1719 NTSTATUS _samr_QueryAliasInfo(pipes_struct *p,
1720                               struct samr_QueryAliasInfo *r)
1721 {
1722         DOM_SID   sid;
1723         struct acct_info info;
1724         uint32    acc_granted;
1725         NTSTATUS status;
1726         union samr_AliasInfo *alias_info = NULL;
1727         const char *alias_name = NULL;
1728         const char *alias_description = NULL;
1729
1730         DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1731
1732         alias_info = TALLOC_ZERO_P(p->mem_ctx, union samr_AliasInfo);
1733         if (!alias_info) {
1734                 return NT_STATUS_NO_MEMORY;
1735         }
1736
1737         /* find the policy handle.  open a policy on it. */
1738         if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &sid, &acc_granted, NULL))
1739                 return NT_STATUS_INVALID_HANDLE;
1740
1741         status = access_check_samr_function(acc_granted,
1742                                             SAMR_ALIAS_ACCESS_LOOKUP_INFO,
1743                                             "_samr_QueryAliasInfo");
1744         if (!NT_STATUS_IS_OK(status)) {
1745                 return status;
1746         }
1747
1748         become_root();
1749         status = pdb_get_aliasinfo(&sid, &info);
1750         unbecome_root();
1751
1752         if ( !NT_STATUS_IS_OK(status))
1753                 return status;
1754
1755         /* FIXME: info contains fstrings */
1756         alias_name = talloc_strdup(r, info.acct_name);
1757         alias_description = talloc_strdup(r, info.acct_desc);
1758
1759         switch (r->in.level) {
1760         case ALIASINFOALL:
1761                 init_samr_alias_info1(&alias_info->all,
1762                                       alias_name,
1763                                       1,
1764                                       alias_description);
1765                 break;
1766         case ALIASINFODESCRIPTION:
1767                 init_samr_alias_info3(&alias_info->description,
1768                                       alias_description);
1769                 break;
1770         default:
1771                 return NT_STATUS_INVALID_INFO_CLASS;
1772         }
1773
1774         *r->out.info = alias_info;
1775
1776         DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1777
1778         return NT_STATUS_OK;
1779 }
1780
1781 /*******************************************************************
1782  _samr_LookupNames
1783  ********************************************************************/
1784
1785 NTSTATUS _samr_LookupNames(pipes_struct *p,
1786                            struct samr_LookupNames *r)
1787 {
1788         NTSTATUS status;
1789         uint32 *rid;
1790         enum lsa_SidType *type;
1791         int i;
1792         int num_rids = r->in.num_names;
1793         DOM_SID pol_sid;
1794         uint32  acc_granted;
1795         struct samr_Ids rids, types;
1796         uint32_t num_mapped = 0;
1797
1798         DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1799
1800         if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &pol_sid, &acc_granted, NULL)) {
1801                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1802         }
1803
1804         status = access_check_samr_function(acc_granted,
1805                                             0, /* Don't know the acc_bits yet */
1806                                             "_samr_LookupNames");
1807         if (!NT_STATUS_IS_OK(status)) {
1808                 return status;
1809         }
1810
1811         if (num_rids > MAX_SAM_ENTRIES) {
1812                 num_rids = MAX_SAM_ENTRIES;
1813                 DEBUG(5,("_samr_LookupNames: truncating entries to %d\n", num_rids));
1814         }
1815
1816         rid = talloc_array(p->mem_ctx, uint32, num_rids);
1817         NT_STATUS_HAVE_NO_MEMORY(rid);
1818
1819         type = talloc_array(p->mem_ctx, enum lsa_SidType, num_rids);
1820         NT_STATUS_HAVE_NO_MEMORY(type);
1821
1822         DEBUG(5,("_samr_LookupNames: looking name on SID %s\n",
1823                  sid_string_dbg(&pol_sid)));
1824
1825         for (i = 0; i < num_rids; i++) {
1826
1827                 status = NT_STATUS_NONE_MAPPED;
1828                 type[i] = SID_NAME_UNKNOWN;
1829
1830                 rid[i] = 0xffffffff;
1831
1832                 if (sid_check_is_builtin(&pol_sid)) {
1833                         if (lookup_builtin_name(r->in.names[i].string,
1834                                                 &rid[i]))
1835                         {
1836                                 type[i] = SID_NAME_ALIAS;
1837                         }
1838                 } else {
1839                         lookup_global_sam_name(r->in.names[i].string, 0,
1840                                                &rid[i], &type[i]);
1841                 }
1842
1843                 if (type[i] != SID_NAME_UNKNOWN) {
1844                         num_mapped++;
1845                 }
1846         }
1847
1848         if (num_mapped == num_rids) {
1849                 status = NT_STATUS_OK;
1850         } else if (num_mapped == 0) {
1851                 status = NT_STATUS_NONE_MAPPED;
1852         } else {
1853                 status = STATUS_SOME_UNMAPPED;
1854         }
1855
1856         rids.count = num_rids;
1857         rids.ids = rid;
1858
1859         types.count = num_rids;
1860         types.ids = type;
1861
1862         *r->out.rids = rids;
1863         *r->out.types = types;
1864
1865         DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1866
1867         return status;
1868 }
1869
1870 /*******************************************************************
1871  _samr_ChangePasswordUser2
1872  ********************************************************************/
1873
1874 NTSTATUS _samr_ChangePasswordUser2(pipes_struct *p,
1875                                    struct samr_ChangePasswordUser2 *r)
1876 {
1877         NTSTATUS status;
1878         fstring user_name;
1879         fstring wks;
1880
1881         DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1882
1883         fstrcpy(user_name, r->in.account->string);
1884         fstrcpy(wks, r->in.server->string);
1885
1886         DEBUG(5,("_samr_ChangePasswordUser2: user: %s wks: %s\n", user_name, wks));
1887
1888         /*
1889          * Pass the user through the NT -> unix user mapping
1890          * function.
1891          */
1892
1893         (void)map_username(user_name);
1894
1895         /*
1896          * UNIX username case mangling not required, pass_oem_change
1897          * is case insensitive.
1898          */
1899
1900         status = pass_oem_change(user_name,
1901                                  r->in.lm_password->data,
1902                                  r->in.lm_verifier->hash,
1903                                  r->in.nt_password->data,
1904                                  r->in.nt_verifier->hash,
1905                                  NULL);
1906
1907         DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1908
1909         return status;
1910 }
1911
1912 /*******************************************************************
1913  _samr_ChangePasswordUser3
1914  ********************************************************************/
1915
1916 NTSTATUS _samr_ChangePasswordUser3(pipes_struct *p,
1917                                    struct samr_ChangePasswordUser3 *r)
1918 {
1919         NTSTATUS status;
1920         fstring user_name;
1921         const char *wks = NULL;
1922         uint32 reject_reason;
1923         struct samr_DomInfo1 *dominfo = NULL;
1924         struct samr_ChangeReject *reject = NULL;
1925
1926         DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
1927
1928         fstrcpy(user_name, r->in.account->string);
1929         if (r->in.server && r->in.server->string) {
1930                 wks = r->in.server->string;
1931         }
1932
1933         DEBUG(5,("_samr_ChangePasswordUser3: user: %s wks: %s\n", user_name, wks));
1934
1935         /*
1936          * Pass the user through the NT -> unix user mapping
1937          * function.
1938          */
1939
1940         (void)map_username(user_name);
1941
1942         /*
1943          * UNIX username case mangling not required, pass_oem_change
1944          * is case insensitive.
1945          */
1946
1947         status = pass_oem_change(user_name,
1948                                  r->in.lm_password->data,
1949                                  r->in.lm_verifier->hash,
1950                                  r->in.nt_password->data,
1951                                  r->in.nt_verifier->hash,
1952                                  &reject_reason);
1953
1954         if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) ||
1955             NT_STATUS_EQUAL(status, NT_STATUS_ACCOUNT_RESTRICTION)) {
1956
1957                 uint32 min_pass_len,pass_hist,password_properties;
1958                 time_t u_expire, u_min_age;
1959                 NTTIME nt_expire, nt_min_age;
1960                 uint32 account_policy_temp;
1961
1962                 dominfo = TALLOC_ZERO_P(p->mem_ctx, struct samr_DomInfo1);
1963                 if (!dominfo) {
1964                         return NT_STATUS_NO_MEMORY;
1965                 }
1966
1967                 reject = TALLOC_ZERO_P(p->mem_ctx, struct samr_ChangeReject);
1968                 if (!reject) {
1969                         return NT_STATUS_NO_MEMORY;
1970                 }
1971
1972                 become_root();
1973
1974                 /* AS ROOT !!! */
1975
1976                 pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &account_policy_temp);
1977                 min_pass_len = account_policy_temp;
1978
1979                 pdb_get_account_policy(AP_PASSWORD_HISTORY, &account_policy_temp);
1980                 pass_hist = account_policy_temp;
1981
1982                 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
1983                 password_properties = account_policy_temp;
1984
1985                 pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
1986                 u_expire = account_policy_temp;
1987
1988                 pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
1989                 u_min_age = account_policy_temp;
1990
1991                 /* !AS ROOT */
1992
1993                 unbecome_root();
1994
1995                 unix_to_nt_time_abs(&nt_expire, u_expire);
1996                 unix_to_nt_time_abs(&nt_min_age, u_min_age);
1997
1998                 if (lp_check_password_script() && *lp_check_password_script()) {
1999                         password_properties |= DOMAIN_PASSWORD_COMPLEX;
2000                 }
2001
2002                 init_samr_DomInfo1(dominfo,
2003                                    min_pass_len,
2004                                    pass_hist,
2005                                    password_properties,
2006                                    u_expire,
2007                                    u_min_age);
2008
2009                 reject->reason = reject_reason;
2010
2011                 *r->out.dominfo = dominfo;
2012                 *r->out.reject = reject;
2013         }
2014
2015         DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
2016
2017         return status;
2018 }
2019
2020 /*******************************************************************
2021 makes a SAMR_R_LOOKUP_RIDS structure.
2022 ********************************************************************/
2023
2024 static bool make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names,
2025                                   const char **names,
2026                                   struct lsa_String **lsa_name_array_p)
2027 {
2028         struct lsa_String *lsa_name_array = NULL;
2029         uint32_t i;
2030
2031         *lsa_name_array_p = NULL;
2032
2033         if (num_names != 0) {
2034                 lsa_name_array = TALLOC_ZERO_ARRAY(ctx, struct lsa_String, num_names);
2035                 if (!lsa_name_array) {
2036                         return false;
2037                 }
2038         }
2039
2040         for (i = 0; i < num_names; i++) {
2041                 DEBUG(10, ("names[%d]:%s\n", i, names[i] && *names[i] ? names[i] : ""));
2042                 init_lsa_String(&lsa_name_array[i], names[i]);
2043         }
2044
2045         *lsa_name_array_p = lsa_name_array;
2046
2047         return true;
2048 }
2049
2050 /*******************************************************************
2051  _samr_LookupRids
2052  ********************************************************************/
2053
2054 NTSTATUS _samr_LookupRids(pipes_struct *p,
2055                           struct samr_LookupRids *r)
2056 {
2057         NTSTATUS status;
2058         const char **names;
2059         enum lsa_SidType *attrs = NULL;
2060         uint32 *wire_attrs = NULL;
2061         DOM_SID pol_sid;
2062         int num_rids = (int)r->in.num_rids;
2063         uint32 acc_granted;
2064         int i;
2065         struct lsa_Strings names_array;
2066         struct samr_Ids types_array;
2067         struct lsa_String *lsa_names = NULL;
2068
2069         DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2070
2071         /* find the policy handle.  open a policy on it. */
2072         if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &pol_sid, &acc_granted, NULL))
2073                 return NT_STATUS_INVALID_HANDLE;
2074
2075         status = access_check_samr_function(acc_granted,
2076                                             0, /* Don't know the acc_bits yet */
2077                                             "_samr_LookupRids");
2078         if (!NT_STATUS_IS_OK(status)) {
2079                 return status;
2080         }
2081
2082         if (num_rids > 1000) {
2083                 DEBUG(0, ("Got asked for %d rids (more than 1000) -- according "
2084                           "to samba4 idl this is not possible\n", num_rids));
2085                 return NT_STATUS_UNSUCCESSFUL;
2086         }
2087
2088         if (num_rids) {
2089                 names = TALLOC_ZERO_ARRAY(p->mem_ctx, const char *, num_rids);
2090                 attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, enum lsa_SidType, num_rids);
2091                 wire_attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_rids);
2092
2093                 if ((names == NULL) || (attrs == NULL) || (wire_attrs==NULL))
2094                         return NT_STATUS_NO_MEMORY;
2095         } else {
2096                 names = NULL;
2097                 attrs = NULL;
2098                 wire_attrs = NULL;
2099         }
2100
2101         become_root();  /* lookup_sid can require root privs */
2102         status = pdb_lookup_rids(&pol_sid, num_rids, r->in.rids,
2103                                  names, attrs);
2104         unbecome_root();
2105
2106         if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED) && (num_rids == 0)) {
2107                 status = NT_STATUS_OK;
2108         }
2109
2110         if (!make_samr_lookup_rids(p->mem_ctx, num_rids, names,
2111                                    &lsa_names)) {
2112                 return NT_STATUS_NO_MEMORY;
2113         }
2114
2115         /* Convert from enum lsa_SidType to uint32 for wire format. */
2116         for (i = 0; i < num_rids; i++) {
2117                 wire_attrs[i] = (uint32)attrs[i];
2118         }
2119
2120         names_array.count = num_rids;
2121         names_array.names = lsa_names;
2122
2123         types_array.count = num_rids;
2124         types_array.ids = wire_attrs;
2125
2126         *r->out.names = names_array;
2127         *r->out.types = types_array;
2128
2129         DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2130
2131         return status;
2132 }
2133
2134 /*******************************************************************
2135  _samr_OpenUser
2136 ********************************************************************/
2137
2138 NTSTATUS _samr_OpenUser(pipes_struct *p,
2139                         struct samr_OpenUser *r)
2140 {
2141         struct samu *sampass=NULL;
2142         DOM_SID sid;
2143         POLICY_HND domain_pol = *r->in.domain_handle;
2144         POLICY_HND *user_pol = r->out.user_handle;
2145         struct samr_info *info = NULL;
2146         SEC_DESC *psd = NULL;
2147         uint32    acc_granted;
2148         uint32    des_access = r->in.access_mask;
2149         size_t    sd_size;
2150         bool ret;
2151         NTSTATUS nt_status;
2152         SE_PRIV se_rights;
2153
2154         /* find the domain policy handle and get domain SID / access bits in the domain policy. */
2155
2156         if ( !get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted, NULL) )
2157                 return NT_STATUS_INVALID_HANDLE;
2158
2159         nt_status = access_check_samr_function(acc_granted,
2160                                                SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
2161                                                "_samr_OpenUser" );
2162
2163         if ( !NT_STATUS_IS_OK(nt_status) )
2164                 return nt_status;
2165
2166         if ( !(sampass = samu_new( p->mem_ctx )) ) {
2167                 return NT_STATUS_NO_MEMORY;
2168         }
2169
2170         /* append the user's RID to it */
2171
2172         if (!sid_append_rid(&sid, r->in.rid))
2173                 return NT_STATUS_NO_SUCH_USER;
2174
2175         /* check if access can be granted as requested by client. */
2176
2177         map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
2178
2179         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &sid, SAMR_USR_RIGHTS_WRITE_PW);
2180         se_map_generic(&des_access, &usr_generic_mapping);
2181
2182         se_priv_copy( &se_rights, &se_machine_account );
2183         se_priv_add( &se_rights, &se_add_users );
2184
2185         nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
2186                 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
2187                 &acc_granted, "_samr_OpenUser");
2188
2189         if ( !NT_STATUS_IS_OK(nt_status) )
2190                 return nt_status;
2191
2192         become_root();
2193         ret=pdb_getsampwsid(sampass, &sid);
2194         unbecome_root();
2195
2196         /* check that the SID exists in our domain. */
2197         if (ret == False) {
2198                 return NT_STATUS_NO_SUCH_USER;
2199         }
2200
2201         TALLOC_FREE(sampass);
2202
2203         /* associate the user's SID and access bits with the new handle. */
2204         if ((info = get_samr_info_by_sid(&sid)) == NULL)
2205                 return NT_STATUS_NO_MEMORY;
2206         info->acc_granted = acc_granted;
2207
2208         /* get a (unique) handle.  open a policy on it. */
2209         if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info))
2210                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2211
2212         return NT_STATUS_OK;
2213 }
2214
2215 /*************************************************************************
2216  *************************************************************************/
2217
2218 static NTSTATUS init_samr_parameters_string(TALLOC_CTX *mem_ctx,
2219                                             DATA_BLOB *blob,
2220                                             struct lsa_BinaryString **_r)
2221 {
2222         struct lsa_BinaryString *r;
2223
2224         if (!blob || !_r) {
2225                 return NT_STATUS_INVALID_PARAMETER;
2226         }
2227
2228         r = TALLOC_ZERO_P(mem_ctx, struct lsa_BinaryString);
2229         if (!r) {
2230                 return NT_STATUS_NO_MEMORY;
2231         }
2232
2233         r->array = TALLOC_ZERO_ARRAY(mem_ctx, uint16_t, blob->length/2);
2234         if (!r->array) {
2235                 return NT_STATUS_NO_MEMORY;
2236         }
2237         memcpy(r->array, blob->data, blob->length);
2238         r->size = blob->length;
2239         r->length = blob->length;
2240
2241         if (!r->array) {
2242                 return NT_STATUS_NO_MEMORY;
2243         }
2244
2245         *_r = r;
2246
2247         return NT_STATUS_OK;
2248 }
2249
2250 static NTSTATUS get_user_info_5(TALLOC_CTX *mem_ctx,
2251                                 struct samr_UserInfo5 *r,
2252                                 struct samu *pw,
2253                                 DOM_SID *domain_sid)
2254 {
2255         const DOM_SID *sid_user, *sid_group;
2256         uint32_t rid, primary_gid;
2257         NTTIME last_logon, last_logoff, last_password_change,
2258                acct_expiry;
2259         const char *account_name, *full_name, *home_directory, *home_drive,
2260                    *logon_script, *profile_path, *description,
2261                    *workstations, *comment;
2262         struct samr_LogonHours logon_hours;
2263
2264         ZERO_STRUCTP(r);
2265
2266         sid_user = pdb_get_user_sid(pw);
2267
2268         if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2269                 DEBUG(0, ("get_user_info_5: User %s has SID %s, \nwhich conflicts with "
2270                           "the domain sid %s.  Failing operation.\n",
2271                           pdb_get_username(pw), sid_string_dbg(sid_user),
2272                           sid_string_dbg(domain_sid)));
2273                 return NT_STATUS_UNSUCCESSFUL;
2274         }
2275
2276         become_root();
2277         sid_group = pdb_get_group_sid(pw);
2278         unbecome_root();
2279
2280         if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2281                 DEBUG(0, ("get_user_info_5: User %s has Primary Group SID %s, \n"
2282                           "which conflicts with the domain sid %s.  Failing operation.\n",
2283                           pdb_get_username(pw), sid_string_dbg(sid_group),
2284                           sid_string_dbg(domain_sid)));
2285                 return NT_STATUS_UNSUCCESSFUL;
2286         }
2287
2288         unix_to_nt_time(&last_logon, pdb_get_logon_time(pw));
2289         unix_to_nt_time(&last_logoff, pdb_get_logoff_time(pw));
2290         unix_to_nt_time(&acct_expiry, pdb_get_kickoff_time(pw));
2291         unix_to_nt_time(&last_password_change, pdb_get_pass_last_set_time(pw));
2292
2293         account_name = talloc_strdup(mem_ctx, pdb_get_username(pw));
2294         full_name = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2295         home_directory = talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2296         home_drive = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2297         logon_script = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2298         profile_path = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2299         description = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2300         workstations = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2301         comment = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2302
2303         logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2304
2305         init_samr_user_info5(r,
2306                              account_name,
2307                              full_name,
2308                              rid,
2309                              primary_gid,
2310                              home_directory,
2311                              home_drive,
2312                              logon_script,
2313                              profile_path,
2314                              description,
2315                              workstations,
2316                              last_logon,
2317                              last_logoff,
2318                              logon_hours,
2319                              pdb_get_bad_password_count(pw),
2320                              pdb_get_logon_count(pw),
2321                              last_password_change,
2322                              acct_expiry,
2323                              pdb_get_acct_ctrl(pw));
2324
2325         return NT_STATUS_OK;
2326 }
2327
2328 /*************************************************************************
2329  get_user_info_7. Safe. Only gives out account_name.
2330  *************************************************************************/
2331
2332 static NTSTATUS get_user_info_7(TALLOC_CTX *mem_ctx,
2333                                 struct samr_UserInfo7 *r,
2334                                 struct samu *smbpass)
2335 {
2336         const char *account_name = NULL;
2337
2338         ZERO_STRUCTP(r);
2339
2340         account_name = talloc_strdup(mem_ctx, pdb_get_username(smbpass));
2341         if (!account_name) {
2342                 return NT_STATUS_NO_MEMORY;
2343         }
2344
2345         init_samr_user_info7(r, account_name);
2346
2347         return NT_STATUS_OK;
2348 }
2349
2350 /*************************************************************************
2351  get_user_info_9. Only gives out primary group SID.
2352  *************************************************************************/
2353
2354 static NTSTATUS get_user_info_9(TALLOC_CTX *mem_ctx,
2355                                 struct samr_UserInfo9 *r,
2356                                 struct samu *smbpass)
2357 {
2358         ZERO_STRUCTP(r);
2359
2360         init_samr_user_info9(r, pdb_get_group_rid(smbpass));
2361
2362         return NT_STATUS_OK;
2363 }
2364
2365 /*************************************************************************
2366  get_user_info_16. Safe. Only gives out acb bits.
2367  *************************************************************************/
2368
2369 static NTSTATUS get_user_info_16(TALLOC_CTX *mem_ctx,
2370                                  struct samr_UserInfo16 *r,
2371                                  struct samu *smbpass)
2372 {
2373         ZERO_STRUCTP(r);
2374
2375         init_samr_user_info16(r, pdb_get_acct_ctrl(smbpass));
2376
2377         return NT_STATUS_OK;
2378 }
2379
2380 /*************************************************************************
2381  get_user_info_18. OK - this is the killer as it gives out password info.
2382  Ensure that this is only allowed on an encrypted connection with a root
2383  user. JRA.
2384  *************************************************************************/
2385
2386 static NTSTATUS get_user_info_18(pipes_struct *p,
2387                                  TALLOC_CTX *mem_ctx,
2388                                  struct samr_UserInfo18 *r,
2389                                  DOM_SID *user_sid)
2390 {
2391         struct samu *smbpass=NULL;
2392         bool ret;
2393
2394         ZERO_STRUCTP(r);
2395
2396         if (p->auth.auth_type != PIPE_AUTH_TYPE_NTLMSSP || p->auth.auth_type != PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) {
2397                 return NT_STATUS_ACCESS_DENIED;
2398         }
2399
2400         if (p->auth.auth_level != PIPE_AUTH_LEVEL_PRIVACY) {
2401                 return NT_STATUS_ACCESS_DENIED;
2402         }
2403
2404         /*
2405          * Do *NOT* do become_root()/unbecome_root() here ! JRA.
2406          */
2407
2408         if ( !(smbpass = samu_new( mem_ctx )) ) {
2409                 return NT_STATUS_NO_MEMORY;
2410         }
2411
2412         ret = pdb_getsampwsid(smbpass, user_sid);
2413
2414         if (ret == False) {
2415                 DEBUG(4, ("User %s not found\n", sid_string_dbg(user_sid)));
2416                 TALLOC_FREE(smbpass);
2417                 return (geteuid() == (uid_t)0) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
2418         }
2419
2420         DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
2421
2422         if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
2423                 TALLOC_FREE(smbpass);
2424                 return NT_STATUS_ACCOUNT_DISABLED;
2425         }
2426
2427         init_samr_user_info18(r,
2428                               pdb_get_lanman_passwd(smbpass),
2429                               pdb_get_nt_passwd(smbpass),
2430                               0 /* FIXME */);
2431
2432         TALLOC_FREE(smbpass);
2433
2434         return NT_STATUS_OK;
2435 }
2436
2437 /*************************************************************************
2438  get_user_info_20
2439  *************************************************************************/
2440
2441 static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx,
2442                                  struct samr_UserInfo20 *r,
2443                                  struct samu *sampass)
2444 {
2445         const char *munged_dial = NULL;
2446         DATA_BLOB blob;
2447         NTSTATUS status;
2448         struct lsa_BinaryString *parameters = NULL;
2449
2450         ZERO_STRUCTP(r);
2451
2452         munged_dial = pdb_get_munged_dial(sampass);
2453
2454         DEBUG(3,("User:[%s] has [%s] (length: %d)\n", pdb_get_username(sampass),
2455                 munged_dial, (int)strlen(munged_dial)));
2456
2457         if (munged_dial) {
2458                 blob = base64_decode_data_blob(munged_dial);
2459         } else {
2460                 blob = data_blob_string_const("");
2461         }
2462
2463         status = init_samr_parameters_string(mem_ctx, &blob, &parameters);
2464         data_blob_free(&blob);
2465         if (!NT_STATUS_IS_OK(status)) {
2466                 return status;
2467         }
2468
2469         init_samr_user_info20(r, parameters);
2470
2471         return NT_STATUS_OK;
2472 }
2473
2474
2475 /*************************************************************************
2476  get_user_info_21
2477  *************************************************************************/
2478
2479 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx,
2480                                  struct samr_UserInfo21 *r,
2481                                  struct samu *pw,
2482                                  DOM_SID *domain_sid)
2483 {
2484         NTSTATUS status;
2485         const DOM_SID *sid_user, *sid_group;
2486         uint32_t rid, primary_gid;
2487         NTTIME last_logon, last_logoff, last_password_change,
2488                acct_expiry, allow_password_change, force_password_change;
2489         time_t must_change_time;
2490         uint8_t password_expired;
2491         const char *account_name, *full_name, *home_directory, *home_drive,
2492                    *logon_script, *profile_path, *description,
2493                    *workstations, *comment;
2494         struct samr_LogonHours logon_hours;
2495         struct lsa_BinaryString *parameters = NULL;
2496         const char *munged_dial = NULL;
2497         DATA_BLOB blob;
2498
2499         ZERO_STRUCTP(r);
2500
2501         sid_user = pdb_get_user_sid(pw);
2502
2503         if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2504                 DEBUG(0, ("get_user_info_21: User %s has SID %s, \nwhich conflicts with "
2505                           "the domain sid %s.  Failing operation.\n",
2506                           pdb_get_username(pw), sid_string_dbg(sid_user),
2507                           sid_string_dbg(domain_sid)));
2508                 return NT_STATUS_UNSUCCESSFUL;
2509         }
2510
2511         become_root();
2512         sid_group = pdb_get_group_sid(pw);
2513         unbecome_root();
2514
2515         if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2516                 DEBUG(0, ("get_user_info_21: User %s has Primary Group SID %s, \n"
2517                           "which conflicts with the domain sid %s.  Failing operation.\n",
2518                           pdb_get_username(pw), sid_string_dbg(sid_group),
2519                           sid_string_dbg(domain_sid)));
2520                 return NT_STATUS_UNSUCCESSFUL;
2521         }
2522
2523         unix_to_nt_time(&last_logon, pdb_get_logon_time(pw));
2524         unix_to_nt_time(&last_logoff, pdb_get_logoff_time(pw));
2525         unix_to_nt_time(&acct_expiry, pdb_get_kickoff_time(pw));
2526         unix_to_nt_time(&last_password_change, pdb_get_pass_last_set_time(pw));
2527         unix_to_nt_time(&allow_password_change, pdb_get_pass_can_change_time(pw));
2528
2529         must_change_time = pdb_get_pass_must_change_time(pw);
2530         if (must_change_time == get_time_t_max()) {
2531                 unix_to_nt_time_abs(&force_password_change, must_change_time);
2532         } else {
2533                 unix_to_nt_time(&force_password_change, must_change_time);
2534         }
2535
2536         if (pdb_get_pass_must_change_time(pw) == 0) {
2537                 password_expired = PASS_MUST_CHANGE_AT_NEXT_LOGON;
2538         } else {
2539                 password_expired = 0;
2540         }
2541
2542         munged_dial = pdb_get_munged_dial(pw);
2543         if (munged_dial) {
2544                 blob = base64_decode_data_blob(munged_dial);
2545         } else {
2546                 blob = data_blob_string_const("");
2547         }
2548
2549         status = init_samr_parameters_string(mem_ctx, &blob, &parameters);
2550         data_blob_free(&blob);
2551         if (!NT_STATUS_IS_OK(status)) {
2552                 return status;
2553         }
2554
2555         account_name = talloc_strdup(mem_ctx, pdb_get_username(pw));
2556         full_name = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2557         home_directory = talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2558         home_drive = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2559         logon_script = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2560         profile_path = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2561         description = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2562         workstations = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2563         comment = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2564
2565         logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2566 #if 0
2567
2568         /*
2569           Look at a user on a real NT4 PDC with usrmgr, press
2570           'ok'. Then you will see that fields_present is set to
2571           0x08f827fa. Look at the user immediately after that again,
2572           and you will see that 0x00fffff is returned. This solves
2573           the problem that you get access denied after having looked
2574           at the user.
2575           -- Volker
2576         */
2577
2578 #endif
2579
2580         init_samr_user_info21(r,
2581                               last_logon,
2582                               last_logoff,
2583                               last_password_change,
2584                               acct_expiry,
2585                               allow_password_change,
2586                               force_password_change,
2587                               account_name,
2588                               full_name,
2589                               home_directory,
2590                               home_drive,
2591                               logon_script,
2592                               profile_path,
2593                               description,
2594                               workstations,
2595                               comment,
2596                               parameters,
2597                               rid,
2598                               primary_gid,
2599                               pdb_get_acct_ctrl(pw),
2600                               pdb_build_fields_present(pw),
2601                               logon_hours,
2602                               pdb_get_bad_password_count(pw),
2603                               pdb_get_logon_count(pw),
2604                               0, /* country_code */
2605                               0, /* code_page */
2606                               0, /* lm_password_set */
2607                               0, /* nt_password_set */
2608                               password_expired);
2609
2610         return NT_STATUS_OK;
2611 }
2612
2613 /*******************************************************************
2614  _samr_QueryUserInfo
2615  ********************************************************************/
2616
2617 NTSTATUS _samr_QueryUserInfo(pipes_struct *p,
2618                              struct samr_QueryUserInfo *r)
2619 {
2620         NTSTATUS status;
2621         union samr_UserInfo *user_info = NULL;
2622         struct samr_info *info = NULL;
2623         DOM_SID domain_sid;
2624         uint32 rid;
2625         bool ret = false;
2626         struct samu *pwd = NULL;
2627
2628         /* search for the handle */
2629         if (!find_policy_by_hnd(p, r->in.user_handle, (void **)(void *)&info))
2630                 return NT_STATUS_INVALID_HANDLE;
2631
2632         status = access_check_samr_function(info->acc_granted,
2633                                             SAMR_USER_ACCESS_GET_ATTRIBUTES,
2634                                             "_samr_QueryUserInfo");
2635         if (!NT_STATUS_IS_OK(status)) {
2636                 return status;
2637         }
2638
2639         domain_sid = info->sid;
2640
2641         sid_split_rid(&domain_sid, &rid);
2642
2643         if (!sid_check_is_in_our_domain(&info->sid))
2644                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2645
2646         DEBUG(5,("_samr_QueryUserInfo: sid:%s\n",
2647                  sid_string_dbg(&info->sid)));
2648
2649         user_info = TALLOC_ZERO_P(p->mem_ctx, union samr_UserInfo);
2650         if (!user_info) {
2651                 return NT_STATUS_NO_MEMORY;
2652         }
2653
2654         DEBUG(5,("_samr_QueryUserInfo: user info level: %d\n", r->in.level));
2655
2656         if (!(pwd = samu_new(p->mem_ctx))) {
2657                 return NT_STATUS_NO_MEMORY;
2658         }
2659
2660         become_root();
2661         ret = pdb_getsampwsid(pwd, &info->sid);
2662         unbecome_root();
2663
2664         if (ret == false) {
2665                 DEBUG(4,("User %s not found\n", sid_string_dbg(&info->sid)));
2666                 TALLOC_FREE(pwd);
2667                 return NT_STATUS_NO_SUCH_USER;
2668         }
2669
2670         DEBUG(3,("User:[%s]\n", pdb_get_username(pwd)));
2671
2672         samr_clear_sam_passwd(pwd);
2673
2674         switch (r->in.level) {
2675         case 5:
2676                 status = get_user_info_5(p->mem_ctx, &user_info->info5, pwd, &domain_sid);
2677                 break;
2678         case 7:
2679                 status = get_user_info_7(p->mem_ctx, &user_info->info7, pwd);
2680                 break;
2681         case 9:
2682                 status = get_user_info_9(p->mem_ctx, &user_info->info9, pwd);
2683                 break;
2684         case 16:
2685                 status = get_user_info_16(p->mem_ctx, &user_info->info16, pwd);
2686                 break;
2687         case 18:
2688                 /* level 18 is special */
2689                 status = get_user_info_18(p, p->mem_ctx, &user_info->info18, &info->sid);
2690                 break;
2691         case 20:
2692                 status = get_user_info_20(p->mem_ctx, &user_info->info20, pwd);
2693                 break;
2694         case 21:
2695                 status = get_user_info_21(p->mem_ctx, &user_info->info21, pwd, &domain_sid);
2696                 break;
2697         default:
2698                 status = NT_STATUS_INVALID_INFO_CLASS;
2699                 break;
2700         }
2701
2702         TALLOC_FREE(pwd);
2703
2704         *r->out.info = user_info;
2705
2706         DEBUG(5,("_samr_QueryUserInfo: %d\n", __LINE__));
2707
2708         return status;
2709 }
2710
2711 /****************************************************************
2712 ****************************************************************/
2713
2714 NTSTATUS _samr_QueryUserInfo2(pipes_struct *p,
2715                               struct samr_QueryUserInfo2 *r)
2716 {
2717         struct samr_QueryUserInfo u;
2718
2719         u.in.user_handle        = r->in.user_handle;
2720         u.in.level              = r->in.level;
2721         u.out.info              = r->out.info;
2722
2723         return _samr_QueryUserInfo(p, &u);
2724 }
2725
2726 /*******************************************************************
2727  _samr_GetGroupsForUser
2728  ********************************************************************/
2729
2730 NTSTATUS _samr_GetGroupsForUser(pipes_struct *p,
2731                                 struct samr_GetGroupsForUser *r)
2732 {
2733         struct samu *sam_pass=NULL;
2734         DOM_SID  sid;
2735         DOM_SID *sids;
2736         struct samr_RidWithAttribute dom_gid;
2737         struct samr_RidWithAttribute *gids = NULL;
2738         uint32 primary_group_rid;
2739         size_t num_groups = 0;
2740         gid_t *unix_gids;
2741         size_t i, num_gids;
2742         uint32 acc_granted;
2743         bool ret;
2744         NTSTATUS result;
2745         bool success = False;
2746
2747         struct samr_RidWithAttributeArray *rids = NULL;
2748
2749         /*
2750          * from the SID in the request:
2751          * we should send back the list of DOMAIN GROUPS
2752          * the user is a member of
2753          *
2754          * and only the DOMAIN GROUPS
2755          * no ALIASES !!! neither aliases of the domain
2756          * nor aliases of the builtin SID
2757          *
2758          * JFM, 12/2/2001
2759          */
2760
2761         DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
2762
2763         rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidWithAttributeArray);
2764         if (!rids) {
2765                 return NT_STATUS_NO_MEMORY;
2766         }
2767
2768         /* find the policy handle.  open a policy on it. */
2769         if (!get_lsa_policy_samr_sid(p, r->in.user_handle, &sid, &acc_granted, NULL))
2770                 return NT_STATUS_INVALID_HANDLE;
2771
2772         result = access_check_samr_function(acc_granted,
2773                                             SAMR_USER_ACCESS_GET_GROUPS,
2774                                             "_samr_GetGroupsForUser");
2775         if (!NT_STATUS_IS_OK(result)) {
2776                 return result;
2777         }
2778
2779         if (!sid_check_is_in_our_domain(&sid))
2780                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2781
2782         if ( !(sam_pass = samu_new( p->mem_ctx )) ) {
2783                 return NT_STATUS_NO_MEMORY;
2784         }
2785
2786         become_root();
2787         ret = pdb_getsampwsid(sam_pass, &sid);
2788         unbecome_root();
2789
2790         if (!ret) {
2791                 DEBUG(10, ("pdb_getsampwsid failed for %s\n",
2792                            sid_string_dbg(&sid)));
2793                 return NT_STATUS_NO_SUCH_USER;
2794         }
2795
2796         sids = NULL;
2797
2798         /* make both calls inside the root block */
2799         become_root();
2800         result = pdb_enum_group_memberships(p->mem_ctx, sam_pass,
2801                                             &sids, &unix_gids, &num_groups);
2802         if ( NT_STATUS_IS_OK(result) ) {
2803                 success = sid_peek_check_rid(get_global_sam_sid(),
2804                                              pdb_get_group_sid(sam_pass),
2805                                              &primary_group_rid);
2806         }
2807         unbecome_root();
2808
2809         if (!NT_STATUS_IS_OK(result)) {
2810                 DEBUG(10, ("pdb_enum_group_memberships failed for %s\n",
2811                            sid_string_dbg(&sid)));
2812                 return result;
2813         }
2814
2815         if ( !success ) {
2816                 DEBUG(5, ("Group sid %s for user %s not in our domain\n",
2817                           sid_string_dbg(pdb_get_group_sid(sam_pass)),
2818                           pdb_get_username(sam_pass)));
2819                 TALLOC_FREE(sam_pass);
2820                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2821         }
2822
2823         gids = NULL;
2824         num_gids = 0;
2825
2826         dom_gid.attributes = (SE_GROUP_MANDATORY|SE_GROUP_ENABLED_BY_DEFAULT|
2827                               SE_GROUP_ENABLED);
2828         dom_gid.rid = primary_group_rid;
2829         ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
2830
2831         for (i=0; i<num_groups; i++) {
2832
2833                 if (!sid_peek_check_rid(get_global_sam_sid(),
2834                                         &(sids[i]), &dom_gid.rid)) {
2835                         DEBUG(10, ("Found sid %s not in our domain\n",
2836                                    sid_string_dbg(&sids[i])));
2837                         continue;
2838                 }
2839
2840                 if (dom_gid.rid == primary_group_rid) {
2841                         /* We added the primary group directly from the
2842                          * sam_account. The other SIDs are unique from
2843                          * enum_group_memberships */
2844                         continue;
2845                 }
2846
2847                 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
2848         }
2849
2850         rids->count = num_gids;
2851         rids->rids = gids;
2852
2853         *r->out.rids = rids;
2854
2855         DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
2856
2857         return result;
2858 }
2859
2860 /*******************************************************************
2861  _samr_QueryDomainInfo
2862  ********************************************************************/
2863
2864 NTSTATUS _samr_QueryDomainInfo(pipes_struct *p,
2865                                struct samr_QueryDomainInfo *r)
2866 {
2867         NTSTATUS status = NT_STATUS_OK;
2868         struct samr_info *info = NULL;
2869         union samr_DomainInfo *dom_info;
2870         uint32 min_pass_len,pass_hist,password_properties;
2871         time_t u_expire, u_min_age;
2872         NTTIME nt_expire, nt_min_age;
2873
2874         time_t u_lock_duration, u_reset_time;
2875         NTTIME nt_lock_duration, nt_reset_time;
2876         uint32 lockout;
2877         time_t u_logout;
2878         NTTIME nt_logout;
2879
2880         uint32 account_policy_temp;
2881
2882         time_t seq_num;
2883         uint32 server_role;
2884
2885         uint32 num_users=0, num_groups=0, num_aliases=0;
2886
2887         DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__));
2888
2889         dom_info = TALLOC_ZERO_P(p->mem_ctx, union samr_DomainInfo);
2890         if (!dom_info) {
2891                 return NT_STATUS_NO_MEMORY;
2892         }
2893
2894         /* find the policy handle.  open a policy on it. */
2895         if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info)) {
2896                 return NT_STATUS_INVALID_HANDLE;
2897         }
2898
2899         status = access_check_samr_function(info->acc_granted,
2900                                             SAMR_ACCESS_OPEN_DOMAIN,
2901                                             "_samr_QueryDomainInfo" );
2902
2903         if ( !NT_STATUS_IS_OK(status) )
2904                 return status;
2905
2906         switch (r->in.level) {
2907                 case 0x01:
2908
2909                         become_root();
2910
2911                         /* AS ROOT !!! */
2912
2913                         pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &account_policy_temp);
2914                         min_pass_len = account_policy_temp;
2915
2916                         pdb_get_account_policy(AP_PASSWORD_HISTORY, &account_policy_temp);
2917                         pass_hist = account_policy_temp;
2918
2919                         pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
2920                         password_properties = account_policy_temp;
2921
2922                         pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
2923                         u_expire = account_policy_temp;
2924
2925                         pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
2926                         u_min_age = account_policy_temp;
2927
2928                         /* !AS ROOT */
2929
2930                         unbecome_root();
2931
2932                         unix_to_nt_time_abs(&nt_expire, u_expire);
2933                         unix_to_nt_time_abs(&nt_min_age, u_min_age);
2934
2935                         if (lp_check_password_script() && *lp_check_password_script()) {
2936                                 password_properties |= DOMAIN_PASSWORD_COMPLEX;
2937                         }
2938
2939                         init_samr_DomInfo1(&dom_info->info1,
2940                                            (uint16)min_pass_len,
2941                                            (uint16)pass_hist,
2942                                            password_properties,
2943                                            nt_expire,
2944                                            nt_min_age);
2945                         break;
2946                 case 0x02:
2947
2948                         become_root();
2949
2950                         /* AS ROOT !!! */
2951
2952                         num_users = count_sam_users(info->disp_info, ACB_NORMAL);
2953                         num_groups = count_sam_groups(info->disp_info);
2954                         num_aliases = count_sam_aliases(info->disp_info);
2955
2956                         pdb_get_account_policy(AP_TIME_TO_LOGOUT, &account_policy_temp);
2957                         u_logout = account_policy_temp;
2958
2959                         unix_to_nt_time_abs(&nt_logout, u_logout);
2960
2961                         if (!pdb_get_seq_num(&seq_num))
2962                                 seq_num = time(NULL);
2963
2964                         /* !AS ROOT */
2965
2966                         unbecome_root();
2967
2968                         server_role = ROLE_DOMAIN_PDC;
2969                         if (lp_server_role() == ROLE_DOMAIN_BDC)
2970                                 server_role = ROLE_DOMAIN_BDC;
2971
2972                         init_samr_DomInfo2(&dom_info->info2,
2973                                            nt_logout,
2974                                            lp_serverstring(),
2975                                            lp_workgroup(),
2976                                            global_myname(),
2977                                            seq_num,
2978                                            1,
2979                                            server_role,
2980                                            1,
2981                                            num_users,
2982                                            num_groups,
2983                                            num_aliases);
2984                         break;
2985                 case 0x03:
2986
2987                         become_root();
2988
2989                         /* AS ROOT !!! */
2990
2991                         {
2992                                 uint32 ul;
2993                                 pdb_get_account_policy(AP_TIME_TO_LOGOUT, &ul);
2994                                 u_logout = (time_t)ul;
2995                         }
2996
2997                         /* !AS ROOT */
2998
2999                         unbecome_root();
3000
3001                         unix_to_nt_time_abs(&nt_logout, u_logout);
3002
3003                         init_samr_DomInfo3(&dom_info->info3,
3004                                            nt_logout);
3005
3006                         break;
3007                 case 0x04:
3008                         init_samr_DomInfo4(&dom_info->info4,
3009                                            lp_serverstring());
3010                         break;
3011                 case 0x05:
3012                         init_samr_DomInfo5(&dom_info->info5,
3013                                            get_global_sam_name());
3014                         break;
3015                 case 0x06:
3016                         /* NT returns its own name when a PDC. win2k and later
3017                          * only the name of the PDC if itself is a BDC (samba4
3018                          * idl) */
3019                         init_samr_DomInfo6(&dom_info->info6,
3020                                            global_myname());
3021                         break;
3022                 case 0x07:
3023                         server_role = ROLE_DOMAIN_PDC;
3024                         if (lp_server_role() == ROLE_DOMAIN_BDC)
3025                                 server_role = ROLE_DOMAIN_BDC;
3026
3027                         init_samr_DomInfo7(&dom_info->info7,
3028                                            server_role);
3029                         break;
3030                 case 0x08:
3031
3032                         become_root();
3033
3034                         /* AS ROOT !!! */
3035
3036                         if (!pdb_get_seq_num(&seq_num)) {
3037                                 seq_num = time(NULL);
3038                         }
3039
3040                         /* !AS ROOT */
3041
3042                         unbecome_root();
3043
3044                         init_samr_DomInfo8(&dom_info->info8,
3045                                            seq_num,
3046                                            0);
3047                         break;
3048                 case 0x0c:
3049
3050                         become_root();
3051
3052                         /* AS ROOT !!! */
3053
3054                         pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
3055                         u_lock_duration = account_policy_temp;
3056                         if (u_lock_duration != -1) {
3057                                 u_lock_duration *= 60;
3058                         }
3059
3060                         pdb_get_account_policy(AP_RESET_COUNT_TIME, &account_policy_temp);
3061                         u_reset_time = account_policy_temp * 60;
3062
3063                         pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
3064                         lockout = account_policy_temp;
3065
3066                         /* !AS ROOT */
3067
3068                         unbecome_root();
3069
3070                         unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
3071                         unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
3072
3073                         init_samr_DomInfo12(&dom_info->info12,
3074                                             nt_lock_duration,
3075                                             nt_reset_time,
3076                                             (uint16)lockout);
3077                         break;
3078                 default:
3079                         return NT_STATUS_INVALID_INFO_CLASS;
3080         }
3081
3082         *r->out.info = dom_info;
3083
3084         DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__));
3085
3086         return status;
3087 }
3088
3089 /* W2k3 seems to use the same check for all 3 objects that can be created via
3090  * SAMR, if you try to create for example "Dialup" as an alias it says
3091  * "NT_STATUS_USER_EXISTS". This is racy, but we can't really lock the user
3092  * database. */
3093
3094 static NTSTATUS can_create(TALLOC_CTX *mem_ctx, const char *new_name)
3095 {
3096         enum lsa_SidType type;
3097         bool result;
3098
3099         DEBUG(10, ("Checking whether [%s] can be created\n", new_name));
3100
3101         become_root();
3102         /* Lookup in our local databases (LOOKUP_NAME_REMOTE not set)
3103          * whether the name already exists */
3104         result = lookup_name(mem_ctx, new_name, LOOKUP_NAME_LOCAL,
3105                              NULL, NULL, NULL, &type);
3106         unbecome_root();
3107
3108         if (!result) {
3109                 DEBUG(10, ("%s does not exist, can create it\n", new_name));
3110                 return NT_STATUS_OK;
3111         }
3112
3113         DEBUG(5, ("trying to create %s, exists as %s\n",
3114                   new_name, sid_type_lookup(type)));
3115
3116         if (type == SID_NAME_DOM_GRP) {
3117                 return NT_STATUS_GROUP_EXISTS;
3118         }
3119         if (type == SID_NAME_ALIAS) {
3120                 return NT_STATUS_ALIAS_EXISTS;
3121         }
3122
3123         /* Yes, the default is NT_STATUS_USER_EXISTS */
3124         return NT_STATUS_USER_EXISTS;
3125 }
3126
3127 /*******************************************************************
3128  _samr_CreateUser2
3129  ********************************************************************/
3130
3131 NTSTATUS _samr_CreateUser2(pipes_struct *p,
3132                            struct samr_CreateUser2 *r)
3133 {
3134         const char *account = NULL;
3135         DOM_SID sid;
3136         POLICY_HND dom_pol = *r->in.domain_handle;
3137         uint32_t acb_info = r->in.acct_flags;
3138         POLICY_HND *user_pol = r->out.user_handle;
3139         struct samr_info *info = NULL;
3140         NTSTATUS nt_status;
3141         uint32 acc_granted;
3142         SEC_DESC *psd;
3143         size_t    sd_size;
3144         /* check this, when giving away 'add computer to domain' privs */
3145         uint32    des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
3146         bool can_add_account = False;
3147         SE_PRIV se_rights;
3148         DISP_INFO *disp_info = NULL;
3149
3150         /* Get the domain SID stored in the domain policy */
3151         if (!get_lsa_policy_samr_sid(p, &dom_pol, &sid, &acc_granted,
3152                                      &disp_info))
3153                 return NT_STATUS_INVALID_HANDLE;
3154
3155         if (disp_info->builtin_domain) {
3156                 DEBUG(5,("_samr_CreateUser2: Refusing user create in BUILTIN\n"));
3157                 return NT_STATUS_ACCESS_DENIED;
3158         }
3159
3160         nt_status = access_check_samr_function(acc_granted,
3161                                                SAMR_DOMAIN_ACCESS_CREATE_USER,
3162                                                "_samr_CreateUser2");
3163         if (!NT_STATUS_IS_OK(nt_status)) {
3164                 return nt_status;
3165         }
3166
3167         if (!(acb_info == ACB_NORMAL || acb_info == ACB_DOMTRUST ||
3168               acb_info == ACB_WSTRUST || acb_info == ACB_SVRTRUST)) {
3169                 /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if
3170                    this parameter is not an account type */
3171                 return NT_STATUS_INVALID_PARAMETER;
3172         }
3173
3174         account = r->in.account_name->string;
3175         if (account == NULL) {
3176                 return NT_STATUS_NO_MEMORY;
3177         }
3178
3179         nt_status = can_create(p->mem_ctx, account);
3180         if (!NT_STATUS_IS_OK(nt_status)) {
3181                 return nt_status;
3182         }
3183
3184         /* determine which user right we need to check based on the acb_info */
3185
3186         if ( acb_info & ACB_WSTRUST )
3187         {
3188                 se_priv_copy( &se_rights, &se_machine_account );
3189                 can_add_account = user_has_privileges(
3190                         p->pipe_user.nt_user_token, &se_rights );
3191         }
3192         /* usrmgr.exe (and net rpc trustdom grant) creates a normal user
3193            account for domain trusts and changes the ACB flags later */
3194         else if ( acb_info & ACB_NORMAL &&
3195                   (account[strlen(account)-1] != '$') )
3196         {
3197                 se_priv_copy( &se_rights, &se_add_users );
3198                 can_add_account = user_has_privileges(
3199                         p->pipe_user.nt_user_token, &se_rights );
3200         }
3201         else    /* implicit assumption of a BDC or domain trust account here
3202                  * (we already check the flags earlier) */
3203         {
3204                 if ( lp_enable_privileges() ) {
3205                         /* only Domain Admins can add a BDC or domain trust */
3206                         se_priv_copy( &se_rights, &se_priv_none );
3207                         can_add_account = nt_token_check_domain_rid(
3208                                 p->pipe_user.nt_user_token,
3209                                 DOMAIN_GROUP_RID_ADMINS );
3210                 }
3211         }
3212
3213         DEBUG(5, ("_samr_CreateUser2: %s can add this account : %s\n",
3214                   uidtoname(p->pipe_user.ut.uid),
3215                   can_add_account ? "True":"False" ));
3216
3217         /********** BEGIN Admin BLOCK **********/
3218
3219         if ( can_add_account )
3220                 become_root();
3221
3222         nt_status = pdb_create_user(p->mem_ctx, account, acb_info,
3223                                     r->out.rid);
3224
3225         if ( can_add_account )
3226                 unbecome_root();
3227
3228         /********** END Admin BLOCK **********/
3229
3230         /* now check for failure */
3231
3232         if ( !NT_STATUS_IS_OK(nt_status) )
3233                 return nt_status;
3234
3235         /* Get the user's SID */
3236
3237         sid_compose(&sid, get_global_sam_sid(), *r->out.rid);
3238
3239         map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
3240
3241         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping,
3242                             &sid, SAMR_USR_RIGHTS_WRITE_PW);
3243         se_map_generic(&des_access, &usr_generic_mapping);
3244
3245         nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3246                 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
3247                 &acc_granted, "_samr_CreateUser2");
3248
3249         if ( !NT_STATUS_IS_OK(nt_status) ) {
3250                 return nt_status;
3251         }
3252
3253         /* associate the user's SID with the new handle. */
3254         if ((info = get_samr_info_by_sid(&sid)) == NULL) {
3255                 return NT_STATUS_NO_MEMORY;
3256         }
3257
3258         ZERO_STRUCTP(info);
3259         info->sid = sid;
3260         info->acc_granted = acc_granted;
3261
3262         /* get a (unique) handle.  open a policy on it. */
3263         if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info)) {
3264                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3265         }
3266
3267         /* After a "set" ensure we have no cached display info. */
3268         force_flush_samr_cache(info->disp_info);
3269
3270         *r->out.access_granted = acc_granted;
3271
3272         return NT_STATUS_OK;
3273 }
3274
3275 /****************************************************************
3276 ****************************************************************/
3277
3278 NTSTATUS _samr_CreateUser(pipes_struct *p,
3279                           struct samr_CreateUser *r)
3280 {
3281         struct samr_CreateUser2 c;
3282         uint32_t access_granted;
3283
3284         c.in.domain_handle      = r->in.domain_handle;
3285         c.in.account_name       = r->in.account_name;
3286         c.in.acct_flags         = ACB_NORMAL;
3287         c.in.access_mask        = r->in.access_mask;
3288         c.out.user_handle       = r->out.user_handle;
3289         c.out.access_granted    = &access_granted;
3290         c.out.rid               = r->out.rid;
3291
3292         return _samr_CreateUser2(p, &c);
3293 }
3294
3295 /*******************************************************************
3296  _samr_Connect
3297  ********************************************************************/
3298
3299 NTSTATUS _samr_Connect(pipes_struct *p,
3300                        struct samr_Connect *r)
3301 {
3302         struct samr_info *info = NULL;
3303         uint32    des_access = r->in.access_mask;
3304
3305         /* Access check */
3306
3307         if (!pipe_access_check(p)) {
3308                 DEBUG(3, ("access denied to _samr_Connect\n"));
3309                 return NT_STATUS_ACCESS_DENIED;
3310         }
3311
3312         /* set up the SAMR connect_anon response */
3313
3314         /* associate the user's SID with the new handle. */
3315         if ((info = get_samr_info_by_sid(NULL)) == NULL)
3316                 return NT_STATUS_NO_MEMORY;
3317
3318         /* don't give away the farm but this is probably ok.  The SAMR_ACCESS_ENUM_DOMAINS
3319            was observed from a win98 client trying to enumerate users (when configured
3320            user level access control on shares)   --jerry */
3321
3322         map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
3323
3324         se_map_generic( &des_access, &sam_generic_mapping );
3325         info->acc_granted = des_access & (SAMR_ACCESS_ENUM_DOMAINS|SAMR_ACCESS_OPEN_DOMAIN);
3326
3327         /* get a (unique) handle.  open a policy on it. */
3328         if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info))
3329                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3330
3331         return NT_STATUS_OK;
3332 }
3333
3334 /*******************************************************************
3335  _samr_Connect2
3336  ********************************************************************/
3337
3338 NTSTATUS _samr_Connect2(pipes_struct *p,
3339                         struct samr_Connect2 *r)
3340 {
3341         struct samr_info *info = NULL;
3342         SEC_DESC *psd = NULL;
3343         uint32    acc_granted;
3344         uint32    des_access = r->in.access_mask;
3345         NTSTATUS  nt_status;
3346         size_t    sd_size;
3347         const char *fn = "_samr_Connect2";
3348
3349         switch (p->hdr_req.opnum) {
3350         case NDR_SAMR_CONNECT2:
3351                 fn = "_samr_Connect2";
3352                 break;
3353         case NDR_SAMR_CONNECT4:
3354                 fn = "_samr_Connect4";
3355                 break;
3356         case NDR_SAMR_CONNECT5:
3357                 fn = "_samr_Connect5";
3358                 break;
3359         }
3360
3361         DEBUG(5,("%s: %d\n", fn, __LINE__));
3362
3363         /* Access check */
3364
3365         if (!pipe_access_check(p)) {
3366                 DEBUG(3, ("access denied to %s\n", fn));
3367                 return NT_STATUS_ACCESS_DENIED;
3368         }
3369
3370         map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
3371
3372         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
3373         se_map_generic(&des_access, &sam_generic_mapping);
3374
3375         nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3376                 NULL, 0, des_access, &acc_granted, fn);
3377
3378         if ( !NT_STATUS_IS_OK(nt_status) )
3379                 return nt_status;
3380
3381         /* associate the user's SID and access granted with the new handle. */
3382         if ((info = get_samr_info_by_sid(NULL)) == NULL)
3383                 return NT_STATUS_NO_MEMORY;
3384
3385         info->acc_granted = acc_granted;
3386         info->status = r->in.access_mask; /* this looks so wrong... - gd */
3387
3388         /* get a (unique) handle.  open a policy on it. */
3389         if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info))
3390                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3391
3392         DEBUG(5,("%s: %d\n", fn, __LINE__));
3393
3394         return nt_status;
3395 }
3396
3397 /*******************************************************************
3398  _samr_Connect4
3399  ********************************************************************/
3400
3401 NTSTATUS _samr_Connect4(pipes_struct *p,
3402                         struct samr_Connect4 *r)
3403 {
3404         struct samr_Connect2 c;
3405
3406         c.in.system_name        = r->in.system_name;
3407         c.in.access_mask        = r->in.access_mask;
3408         c.out.connect_handle    = r->out.connect_handle;
3409
3410         return _samr_Connect2(p, &c);
3411 }
3412
3413 /*******************************************************************
3414  _samr_Connect5
3415  ********************************************************************/
3416
3417 NTSTATUS _samr_Connect5(pipes_struct *p,
3418                         struct samr_Connect5 *r)
3419 {
3420         NTSTATUS status;
3421         struct samr_Connect2 c;
3422         struct samr_ConnectInfo1 info1;
3423
3424         info1.client_version = SAMR_CONNECT_AFTER_W2K;
3425         info1.unknown2 = 0;
3426
3427         c.in.system_name        = r->in.system_name;
3428         c.in.access_mask        = r->in.access_mask;
3429         c.out.connect_handle    = r->out.connect_handle;
3430
3431         status = _samr_Connect2(p, &c);
3432         if (!NT_STATUS_IS_OK(status)) {
3433                 return status;
3434         }
3435
3436         *r->out.level_out = 1;
3437         r->out.info_out->info1 = info1;
3438
3439         return NT_STATUS_OK;
3440 }
3441
3442 /**********************************************************************
3443  _samr_LookupDomain
3444  **********************************************************************/
3445
3446 NTSTATUS _samr_LookupDomain(pipes_struct *p,
3447                             struct samr_LookupDomain *r)
3448 {
3449         NTSTATUS status = NT_STATUS_OK;
3450         struct samr_info *info;
3451         const char *domain_name;
3452         DOM_SID *sid = NULL;
3453
3454         if (!find_policy_by_hnd(p, r->in.connect_handle, (void**)(void *)&info))
3455                 return NT_STATUS_INVALID_HANDLE;
3456
3457         /* win9x user manager likes to use SAMR_ACCESS_ENUM_DOMAINS here.
3458            Reverted that change so we will work with RAS servers again */
3459
3460         status = access_check_samr_function(info->acc_granted,
3461                                             SAMR_ACCESS_OPEN_DOMAIN,
3462                                             "_samr_LookupDomain");
3463         if (!NT_STATUS_IS_OK(status)) {
3464                 return status;
3465         }
3466
3467         domain_name = r->in.domain_name->string;
3468         if (!domain_name) {
3469                 return NT_STATUS_INVALID_PARAMETER;
3470         }
3471
3472         sid = TALLOC_ZERO_P(p->mem_ctx, struct dom_sid2);
3473         if (!sid) {
3474                 return NT_STATUS_NO_MEMORY;
3475         }
3476
3477         if (strequal(domain_name, builtin_domain_name())) {
3478                 sid_copy(sid, &global_sid_Builtin);
3479         } else {
3480                 if (!secrets_fetch_domain_sid(domain_name, sid)) {
3481                         status = NT_STATUS_NO_SUCH_DOMAIN;
3482                 }
3483         }
3484
3485         DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name,
3486                  sid_string_dbg(sid)));
3487
3488         *r->out.sid = sid;
3489
3490         return status;
3491 }
3492
3493 /**********************************************************************
3494  _samr_EnumDomains
3495  **********************************************************************/
3496
3497 NTSTATUS _samr_EnumDomains(pipes_struct *p,
3498                            struct samr_EnumDomains *r)
3499 {
3500         NTSTATUS status;
3501         struct samr_info *info;
3502         uint32_t num_entries = 2;
3503         struct samr_SamEntry *entry_array = NULL;
3504         struct samr_SamArray *sam;
3505
3506         if (!find_policy_by_hnd(p, r->in.connect_handle, (void**)(void *)&info))
3507                 return NT_STATUS_INVALID_HANDLE;
3508
3509         status = access_check_samr_function(info->acc_granted,
3510                                             SAMR_ACCESS_ENUM_DOMAINS,
3511                                             "_samr_EnumDomains");
3512         if (!NT_STATUS_IS_OK(status)) {
3513                 return status;
3514         }
3515
3516         sam = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
3517         if (!sam) {
3518                 return NT_STATUS_NO_MEMORY;
3519         }
3520
3521         entry_array = TALLOC_ZERO_ARRAY(p->mem_ctx,
3522                                         struct samr_SamEntry,
3523                                         num_entries);
3524         if (!entry_array) {
3525                 return NT_STATUS_NO_MEMORY;
3526         }
3527
3528         entry_array[0].idx = 0;
3529         init_lsa_String(&entry_array[0].name, get_global_sam_name());
3530
3531         entry_array[1].idx = 1;
3532         init_lsa_String(&entry_array[1].name, "Builtin");
3533
3534         sam->count = num_entries;
3535         sam->entries = entry_array;
3536
3537         *r->out.sam = sam;
3538         *r->out.num_entries = num_entries;
3539
3540         return status;
3541 }
3542
3543 /*******************************************************************
3544  _samr_OpenAlias
3545  ********************************************************************/
3546
3547 NTSTATUS _samr_OpenAlias(pipes_struct *p,
3548                          struct samr_OpenAlias *r)
3549 {
3550         DOM_SID sid;
3551         POLICY_HND domain_pol = *r->in.domain_handle;
3552         uint32 alias_rid = r->in.rid;
3553         POLICY_HND *alias_pol = r->out.alias_handle;
3554         struct    samr_info *info = NULL;
3555         SEC_DESC *psd = NULL;
3556         uint32    acc_granted;
3557         uint32    des_access = r->in.access_mask;
3558         size_t    sd_size;
3559         NTSTATUS  status;
3560         SE_PRIV se_rights;
3561
3562         /* find the domain policy and get the SID / access bits stored in the domain policy */
3563
3564         if ( !get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted, NULL) )
3565                 return NT_STATUS_INVALID_HANDLE;
3566
3567         status = access_check_samr_function(acc_granted,
3568                                             SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
3569                                             "_samr_OpenAlias");
3570
3571         if ( !NT_STATUS_IS_OK(status) )
3572                 return status;
3573
3574         /* append the alias' RID to it */
3575
3576         if (!sid_append_rid(&sid, alias_rid))
3577                 return NT_STATUS_NO_SUCH_ALIAS;
3578
3579         /*check if access can be granted as requested by client. */
3580
3581         map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
3582
3583         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &ali_generic_mapping, NULL, 0);
3584         se_map_generic(&des_access,&ali_generic_mapping);
3585
3586         se_priv_copy( &se_rights, &se_add_users );
3587
3588
3589         status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3590                 &se_rights, GENERIC_RIGHTS_ALIAS_WRITE, des_access,
3591                 &acc_granted, "_samr_OpenAlias");
3592
3593         if ( !NT_STATUS_IS_OK(status) )
3594                 return status;
3595
3596         {
3597                 /* Check we actually have the requested alias */
3598                 enum lsa_SidType type;
3599                 bool result;
3600                 gid_t gid;
3601
3602                 become_root();
3603                 result = lookup_sid(NULL, &sid, NULL, NULL, &type);
3604                 unbecome_root();
3605
3606                 if (!result || (type != SID_NAME_ALIAS)) {
3607                         return NT_STATUS_NO_SUCH_ALIAS;
3608                 }
3609
3610                 /* make sure there is a mapping */
3611
3612                 if ( !sid_to_gid( &sid, &gid ) ) {
3613                         return NT_STATUS_NO_SUCH_ALIAS;
3614                 }
3615
3616         }
3617
3618         /* associate the alias SID with the new handle. */
3619         if ((info = get_samr_info_by_sid(&sid)) == NULL)
3620                 return NT_STATUS_NO_MEMORY;
3621
3622         info->acc_granted = acc_granted;
3623
3624         /* get a (unique) handle.  open a policy on it. */
3625         if (!create_policy_hnd(p, alias_pol, free_samr_info, (void *)info))
3626                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3627
3628         return NT_STATUS_OK;
3629 }
3630
3631 /*******************************************************************
3632  set_user_info_7
3633  ********************************************************************/
3634
3635 static NTSTATUS set_user_info_7(TALLOC_CTX *mem_ctx,
3636                                 struct samr_UserInfo7 *id7,
3637                                 struct samu *pwd)
3638 {
3639         NTSTATUS rc;
3640
3641         if (id7 == NULL) {
3642                 DEBUG(5, ("set_user_info_7: NULL id7\n"));
3643                 return NT_STATUS_ACCESS_DENIED;
3644         }
3645
3646         if (!id7->account_name.string) {
3647                 DEBUG(5, ("set_user_info_7: failed to get new username\n"));
3648                 return NT_STATUS_ACCESS_DENIED;
3649         }
3650
3651         /* check to see if the new username already exists.  Note: we can't
3652            reliably lock all backends, so there is potentially the
3653            possibility that a user can be created in between this check and
3654            the rename.  The rename should fail, but may not get the
3655            exact same failure status code.  I think this is small enough
3656            of a window for this type of operation and the results are
3657            simply that the rename fails with a slightly different status
3658            code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
3659
3660         rc = can_create(mem_ctx, id7->account_name.string);
3661         if (!NT_STATUS_IS_OK(rc)) {
3662                 return rc;
3663         }
3664
3665         rc = pdb_rename_sam_account(pwd, id7->account_name.string);
3666
3667         return rc;
3668 }
3669
3670 /*******************************************************************
3671  set_user_info_16
3672  ********************************************************************/
3673
3674 static bool set_user_info_16(struct samr_UserInfo16 *id16,
3675                              struct samu *pwd)
3676 {
3677         if (id16 == NULL) {
3678                 DEBUG(5, ("set_user_info_16: NULL id16\n"));
3679                 return False;
3680         }
3681
3682         /* FIX ME: check if the value is really changed --metze */
3683         if (!pdb_set_acct_ctrl(pwd, id16->acct_flags, PDB_CHANGED)) {
3684                 return False;
3685         }
3686
3687         if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3688                 return False;
3689         }
3690
3691         return True;
3692 }
3693
3694 /*******************************************************************
3695  set_user_info_18
3696  ********************************************************************/
3697
3698 static NTSTATUS set_user_info_18(struct samr_UserInfo18 *id18,
3699                                  TALLOC_CTX *mem_ctx,
3700                                  DATA_BLOB *session_key,
3701                                  struct samu *pwd)
3702 {
3703         if (id18 == NULL) {
3704                 DEBUG(2, ("set_user_info_18: id18 is NULL\n"));
3705                 return NT_STATUS_INVALID_PARAMETER;
3706         }
3707
3708         if (id18->nt_pwd_active || id18->lm_pwd_active) {
3709                 if (!session_key->length) {
3710                         return NT_STATUS_NO_USER_SESSION_KEY;
3711                 }
3712         }
3713
3714         if (id18->nt_pwd_active) {
3715
3716                 DATA_BLOB in, out;
3717
3718                 in = data_blob_const(id18->nt_pwd.hash, 16);
3719                 out = data_blob_talloc_zero(mem_ctx, 16);
3720
3721                 sess_crypt_blob(&out, &in, session_key, false);
3722
3723                 if (!pdb_set_nt_passwd(pwd, out.data, PDB_CHANGED)) {
3724                         return NT_STATUS_ACCESS_DENIED;
3725                 }
3726
3727                 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
3728         }
3729
3730         if (id18->lm_pwd_active) {
3731
3732                 DATA_BLOB in, out;
3733
3734                 in = data_blob_const(id18->lm_pwd.hash, 16);
3735                 out = data_blob_talloc_zero(mem_ctx, 16);
3736
3737                 sess_crypt_blob(&out, &in, session_key, false);
3738
3739                 if (!pdb_set_lanman_passwd(pwd, out.data, PDB_CHANGED)) {
3740                         return NT_STATUS_ACCESS_DENIED;
3741                 }
3742
3743                 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
3744         }
3745
3746         copy_id18_to_sam_passwd(pwd, id18);
3747
3748         return pdb_update_sam_account(pwd);
3749 }
3750
3751 /*******************************************************************
3752  set_user_info_20
3753  ********************************************************************/
3754
3755 static bool set_user_info_20(struct samr_UserInfo20 *id20,
3756                              struct samu *pwd)
3757 {
3758         if (id20 == NULL) {
3759                 DEBUG(5, ("set_user_info_20: NULL id20\n"));
3760                 return False;
3761         }
3762
3763         copy_id20_to_sam_passwd(pwd, id20);
3764
3765         /* write the change out */
3766         if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3767                 return False;
3768         }
3769
3770         return True;
3771 }
3772
3773 /*******************************************************************
3774  set_user_info_21
3775  ********************************************************************/
3776
3777 static NTSTATUS set_user_info_21(TALLOC_CTX *mem_ctx,
3778                                  struct samr_UserInfo21 *id21,
3779                                  struct samu *pwd)
3780 {
3781         NTSTATUS status;
3782
3783         if (id21 == NULL) {
3784                 DEBUG(5, ("set_user_info_21: NULL id21\n"));
3785                 return NT_STATUS_INVALID_PARAMETER;
3786         }
3787
3788         if (id21->fields_present == 0) {
3789                 return NT_STATUS_INVALID_PARAMETER;
3790         }
3791
3792         if (id21->fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
3793                 return NT_STATUS_ACCESS_DENIED;
3794         }
3795
3796         /* we need to separately check for an account rename first */
3797
3798         if (id21->account_name.string &&
3799             (!strequal(id21->account_name.string, pdb_get_username(pwd))))
3800         {
3801
3802                 /* check to see if the new username already exists.  Note: we can't
3803                    reliably lock all backends, so there is potentially the
3804                    possibility that a user can be created in between this check and
3805                    the rename.  The rename should fail, but may not get the
3806                    exact same failure status code.  I think this is small enough
3807                    of a window for this type of operation and the results are
3808                    simply that the rename fails with a slightly different status
3809                    code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
3810
3811                 status = can_create(mem_ctx, id21->account_name.string);
3812                 if (!NT_STATUS_IS_OK(status)) {
3813                         return status;
3814                 }
3815
3816                 status = pdb_rename_sam_account(pwd, id21->account_name.string);
3817
3818                 if (!NT_STATUS_IS_OK(status)) {
3819                         DEBUG(0,("set_user_info_21: failed to rename account: %s\n",
3820                                 nt_errstr(status)));
3821                         return status;
3822                 }
3823
3824                 /* set the new username so that later
3825                    functions can work on the new account */
3826                 pdb_set_username(pwd, id21->account_name.string, PDB_SET);
3827         }
3828
3829         copy_id21_to_sam_passwd("INFO_21", pwd, id21);
3830
3831         /*
3832          * The funny part about the previous two calls is
3833          * that pwd still has the password hashes from the
3834          * passdb entry.  These have not been updated from
3835          * id21.  I don't know if they need to be set.    --jerry
3836          */
3837
3838         if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
3839                 status = pdb_set_unix_primary_group(mem_ctx, pwd);
3840                 if ( !NT_STATUS_IS_OK(status) ) {
3841                         return status;
3842                 }
3843         }
3844
3845         /* Don't worry about writing out the user account since the
3846            primary group SID is generated solely from the user's Unix
3847            primary group. */
3848
3849         /* write the change out */
3850         if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
3851                 return status;
3852         }
3853
3854         return NT_STATUS_OK;
3855 }
3856
3857 /*******************************************************************
3858  set_user_info_23
3859  ********************************************************************/
3860
3861 static NTSTATUS set_user_info_23(TALLOC_CTX *mem_ctx,
3862                                  struct samr_UserInfo23 *id23,
3863                                  struct samu *pwd)
3864 {
3865         char *plaintext_buf = NULL;
3866         uint32 len = 0;
3867         uint32_t acct_ctrl;
3868         NTSTATUS status;
3869
3870         if (id23 == NULL) {
3871                 DEBUG(5, ("set_user_info_23: NULL id23\n"));
3872                 return NT_STATUS_INVALID_PARAMETER;
3873         }
3874
3875         if (id23->info.fields_present == 0) {
3876                 return NT_STATUS_INVALID_PARAMETER;
3877         }
3878
3879         if (id23->info.fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
3880                 return NT_STATUS_ACCESS_DENIED;
3881         }
3882
3883         if ((id23->info.fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3884             (id23->info.fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT)) {
3885
3886                 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
3887                           pdb_get_username(pwd)));
3888
3889                 if (!decode_pw_buffer(mem_ctx,
3890                                       id23->password.data,
3891                                       &plaintext_buf,
3892                                       &len,
3893                                       STR_UNICODE)) {
3894                         return NT_STATUS_WRONG_PASSWORD;
3895                 }
3896
3897                 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
3898                         return NT_STATUS_ACCESS_DENIED;
3899                 }
3900         }
3901
3902         copy_id23_to_sam_passwd(pwd, id23);
3903
3904         acct_ctrl = pdb_get_acct_ctrl(pwd);
3905
3906         /* if it's a trust account, don't update /etc/passwd */
3907         if (    ( (acct_ctrl &  ACB_DOMTRUST) == ACB_DOMTRUST ) ||
3908                 ( (acct_ctrl &  ACB_WSTRUST) ==  ACB_WSTRUST) ||
3909                 ( (acct_ctrl &  ACB_SVRTRUST) ==  ACB_SVRTRUST) ) {
3910                 DEBUG(5, ("Changing trust account.  Not updating /etc/passwd\n"));
3911         } else if (plaintext_buf) {
3912                 /* update the UNIX password */
3913                 if (lp_unix_password_sync() ) {
3914                         struct passwd *passwd;
3915                         if (pdb_get_username(pwd) == NULL) {
3916                                 DEBUG(1, ("chgpasswd: User without name???\n"));