6bd58b8ab1e40bc76977298d49c5ba0167cfbc30
[ira/wip.git] / source3 / rpc_server / srv_samr_nt.c
1 /*
2  *  Unix SMB/CIFS implementation.
3  *  RPC Pipe client / server routines
4  *  Copyright (C) Andrew Tridgell                   1992-1997,
5  *  Copyright (C) Luke Kenneth Casson Leighton      1996-1997,
6  *  Copyright (C) Paul Ashton                       1997,
7  *  Copyright (C) Marc Jacobsen                     1999,
8  *  Copyright (C) Jeremy Allison                    2001-2008,
9  *  Copyright (C) Jean Fran├žois Micouleau           1998-2001,
10  *  Copyright (C) Jim McDonough <jmcd@us.ibm.com>   2002,
11  *  Copyright (C) Gerald (Jerry) Carter             2003-2004,
12  *  Copyright (C) Simo Sorce                        2003.
13  *  Copyright (C) Volker Lendecke                   2005.
14  *  Copyright (C) Guenther Deschner                 2008.
15  *
16  *  This program is free software; you can redistribute it and/or modify
17  *  it under the terms of the GNU General Public License as published by
18  *  the Free Software Foundation; either version 3 of the License, or
19  *  (at your option) any later version.
20  *
21  *  This program is distributed in the hope that it will be useful,
22  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
23  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24  *  GNU General Public License for more details.
25  *
26  *  You should have received a copy of the GNU General Public License
27  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
28  */
29
30 /*
31  * This is the implementation of the SAMR code.
32  */
33
34 #include "includes.h"
35
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                                                  const 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",
487                 disp_info_cache_idle_timeout_handler, (void *)disp_info);
488 }
489
490 /*******************************************************************
491  Force flush any cache. We do this on any samr_set_xxx call.
492  We must also remove the timeout handler.
493  ********************************************************************/
494
495 static void force_flush_samr_cache(DISP_INFO *disp_info)
496 {
497         if ((disp_info == NULL) || (disp_info->cache_timeout_event == NULL)) {
498                 return;
499         }
500
501         DEBUG(10,("force_flush_samr_cache: clearing idle event\n"));
502         TALLOC_FREE(disp_info->cache_timeout_event);
503         free_samr_cache(disp_info);
504 }
505
506 /*******************************************************************
507  Ensure password info is never given out. Paranioa... JRA.
508  ********************************************************************/
509
510 static void samr_clear_sam_passwd(struct samu *sam_pass)
511 {
512
513         if (!sam_pass)
514                 return;
515
516         /* These now zero out the old password */
517
518         pdb_set_lanman_passwd(sam_pass, NULL, PDB_DEFAULT);
519         pdb_set_nt_passwd(sam_pass, NULL, PDB_DEFAULT);
520 }
521
522 static uint32 count_sam_users(struct disp_info *info, uint32 acct_flags)
523 {
524         struct samr_displayentry *entry;
525
526         if (info->builtin_domain) {
527                 /* No users in builtin. */
528                 return 0;
529         }
530
531         if (info->users == NULL) {
532                 info->users = pdb_search_users(acct_flags);
533                 if (info->users == NULL) {
534                         return 0;
535                 }
536         }
537         /* Fetch the last possible entry, thus trigger an enumeration */
538         pdb_search_entries(info->users, 0xffffffff, 1, &entry);
539
540         /* Ensure we cache this enumeration. */
541         set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
542
543         return info->users->num_entries;
544 }
545
546 static uint32 count_sam_groups(struct disp_info *info)
547 {
548         struct samr_displayentry *entry;
549
550         if (info->builtin_domain) {
551                 /* No groups in builtin. */
552                 return 0;
553         }
554
555         if (info->groups == NULL) {
556                 info->groups = pdb_search_groups();
557                 if (info->groups == NULL) {
558                         return 0;
559                 }
560         }
561         /* Fetch the last possible entry, thus trigger an enumeration */
562         pdb_search_entries(info->groups, 0xffffffff, 1, &entry);
563
564         /* Ensure we cache this enumeration. */
565         set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
566
567         return info->groups->num_entries;
568 }
569
570 static uint32 count_sam_aliases(struct disp_info *info)
571 {
572         struct samr_displayentry *entry;
573
574         if (info->aliases == NULL) {
575                 info->aliases = pdb_search_aliases(&info->sid);
576                 if (info->aliases == NULL) {
577                         return 0;
578                 }
579         }
580         /* Fetch the last possible entry, thus trigger an enumeration */
581         pdb_search_entries(info->aliases, 0xffffffff, 1, &entry);
582
583         /* Ensure we cache this enumeration. */
584         set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
585
586         return info->aliases->num_entries;
587 }
588
589 /*******************************************************************
590  _samr_Close
591  ********************************************************************/
592
593 NTSTATUS _samr_Close(pipes_struct *p, struct samr_Close *r)
594 {
595         if (!close_policy_hnd(p, r->in.handle)) {
596                 return NT_STATUS_INVALID_HANDLE;
597         }
598
599         ZERO_STRUCTP(r->out.handle);
600
601         return NT_STATUS_OK;
602 }
603
604 /*******************************************************************
605  _samr_OpenDomain
606  ********************************************************************/
607
608 NTSTATUS _samr_OpenDomain(pipes_struct *p,
609                           struct samr_OpenDomain *r)
610 {
611         struct    samr_info *info;
612         SEC_DESC *psd = NULL;
613         uint32    acc_granted;
614         uint32    des_access = r->in.access_mask;
615         NTSTATUS  status;
616         size_t    sd_size;
617         SE_PRIV se_rights;
618
619         /* find the connection policy handle. */
620
621         if ( !find_policy_by_hnd(p, r->in.connect_handle, (void**)(void *)&info) )
622                 return NT_STATUS_INVALID_HANDLE;
623
624         status = access_check_samr_function(info->acc_granted,
625                                             SAMR_ACCESS_OPEN_DOMAIN,
626                                             "_samr_OpenDomain" );
627
628         if ( !NT_STATUS_IS_OK(status) )
629                 return status;
630
631         /*check if access can be granted as requested by client. */
632         map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
633
634         make_samr_object_sd( p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0 );
635         se_map_generic( &des_access, &dom_generic_mapping );
636
637         se_priv_copy( &se_rights, &se_machine_account );
638         se_priv_add( &se_rights, &se_add_users );
639
640         status = access_check_samr_object( psd, p->pipe_user.nt_user_token,
641                 &se_rights, GENERIC_RIGHTS_DOMAIN_WRITE, des_access,
642                 &acc_granted, "_samr_OpenDomain" );
643
644         if ( !NT_STATUS_IS_OK(status) )
645                 return status;
646
647         if (!sid_check_is_domain(r->in.sid) &&
648             !sid_check_is_builtin(r->in.sid)) {
649                 return NT_STATUS_NO_SUCH_DOMAIN;
650         }
651
652         /* associate the domain SID with the (unique) handle. */
653         if ((info = get_samr_info_by_sid(r->in.sid))==NULL)
654                 return NT_STATUS_NO_MEMORY;
655         info->acc_granted = acc_granted;
656
657         /* get a (unique) handle.  open a policy on it. */
658         if (!create_policy_hnd(p, r->out.domain_handle, free_samr_info, (void *)info))
659                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
660
661         DEBUG(5,("_samr_OpenDomain: %d\n", __LINE__));
662
663         return NT_STATUS_OK;
664 }
665
666 /*******************************************************************
667  _samr_GetUserPwInfo
668  ********************************************************************/
669
670 NTSTATUS _samr_GetUserPwInfo(pipes_struct *p,
671                              struct samr_GetUserPwInfo *r)
672 {
673         struct samr_info *info = NULL;
674         enum lsa_SidType sid_type;
675         uint32_t min_password_length = 0;
676         uint32_t password_properties = 0;
677         bool ret = false;
678         NTSTATUS status;
679
680         DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__));
681
682         /* find the policy handle.  open a policy on it. */
683         if (!find_policy_by_hnd(p, r->in.user_handle, (void **)(void *)&info)) {
684                 return NT_STATUS_INVALID_HANDLE;
685         }
686
687         status = access_check_samr_function(info->acc_granted,
688                                             SAMR_USER_ACCESS_GET_ATTRIBUTES,
689                                             "_samr_GetUserPwInfo" );
690         if (!NT_STATUS_IS_OK(status)) {
691                 return status;
692         }
693
694         if (!sid_check_is_in_our_domain(&info->sid)) {
695                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
696         }
697
698         become_root();
699         ret = lookup_sid(p->mem_ctx, &info->sid, NULL, NULL, &sid_type);
700         unbecome_root();
701         if (ret == false) {
702                 return NT_STATUS_NO_SUCH_USER;
703         }
704
705         switch (sid_type) {
706                 case SID_NAME_USER:
707                         become_root();
708                         pdb_get_account_policy(AP_MIN_PASSWORD_LEN,
709                                                &min_password_length);
710                         pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
711                                                &password_properties);
712                         unbecome_root();
713
714                         if (lp_check_password_script() && *lp_check_password_script()) {
715                                 password_properties |= DOMAIN_PASSWORD_COMPLEX;
716                         }
717
718                         break;
719                 default:
720                         break;
721         }
722
723         r->out.info->min_password_length = min_password_length;
724         r->out.info->password_properties = password_properties;
725
726         DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__));
727
728         return NT_STATUS_OK;
729 }
730
731 /*******************************************************************
732 ********************************************************************/
733
734 static bool get_lsa_policy_samr_sid( pipes_struct *p, POLICY_HND *pol,
735                                         DOM_SID *sid, uint32 *acc_granted,
736                                         DISP_INFO **ppdisp_info)
737 {
738         struct samr_info *info = NULL;
739
740         /* find the policy handle.  open a policy on it. */
741         if (!find_policy_by_hnd(p, pol, (void **)(void *)&info))
742                 return False;
743
744         if (!info)
745                 return False;
746
747         *sid = info->sid;
748         *acc_granted = info->acc_granted;
749         if (ppdisp_info) {
750                 *ppdisp_info = info->disp_info;
751         }
752
753         return True;
754 }
755
756 /*******************************************************************
757  _samr_SetSecurity
758  ********************************************************************/
759
760 NTSTATUS _samr_SetSecurity(pipes_struct *p,
761                            struct samr_SetSecurity *r)
762 {
763         DOM_SID pol_sid;
764         uint32 acc_granted, i;
765         SEC_ACL *dacl;
766         bool ret;
767         struct samu *sampass=NULL;
768         NTSTATUS status;
769
770         if (!get_lsa_policy_samr_sid(p, r->in.handle, &pol_sid, &acc_granted, NULL))
771                 return NT_STATUS_INVALID_HANDLE;
772
773         if (!(sampass = samu_new( p->mem_ctx))) {
774                 DEBUG(0,("No memory!\n"));
775                 return NT_STATUS_NO_MEMORY;
776         }
777
778         /* get the user record */
779         become_root();
780         ret = pdb_getsampwsid(sampass, &pol_sid);
781         unbecome_root();
782
783         if (!ret) {
784                 DEBUG(4, ("User %s not found\n", sid_string_dbg(&pol_sid)));
785                 TALLOC_FREE(sampass);
786                 return NT_STATUS_INVALID_HANDLE;
787         }
788
789         dacl = r->in.sdbuf->sd->dacl;
790         for (i=0; i < dacl->num_aces; i++) {
791                 if (sid_equal(&pol_sid, &dacl->aces[i].trustee)) {
792                         ret = pdb_set_pass_can_change(sampass,
793                                 (dacl->aces[i].access_mask &
794                                  SAMR_USER_ACCESS_CHANGE_PASSWORD) ?
795                                                       True: False);
796                         break;
797                 }
798         }
799
800         if (!ret) {
801                 TALLOC_FREE(sampass);
802                 return NT_STATUS_ACCESS_DENIED;
803         }
804
805         status = access_check_samr_function(acc_granted,
806                                             SAMR_USER_ACCESS_SET_ATTRIBUTES,
807                                             "_samr_SetSecurity");
808         if (NT_STATUS_IS_OK(status)) {
809                 become_root();
810                 status = pdb_update_sam_account(sampass);
811                 unbecome_root();
812         }
813
814         TALLOC_FREE(sampass);
815
816         return status;
817 }
818
819 /*******************************************************************
820   build correct perms based on policies and password times for _samr_query_sec_obj
821 *******************************************************************/
822 static bool check_change_pw_access(TALLOC_CTX *mem_ctx, DOM_SID *user_sid)
823 {
824         struct samu *sampass=NULL;
825         bool ret;
826
827         if ( !(sampass = samu_new( mem_ctx )) ) {
828                 DEBUG(0,("No memory!\n"));
829                 return False;
830         }
831
832         become_root();
833         ret = pdb_getsampwsid(sampass, user_sid);
834         unbecome_root();
835
836         if (ret == False) {
837                 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
838                 TALLOC_FREE(sampass);
839                 return False;
840         }
841
842         DEBUG(3,("User:[%s]\n",  pdb_get_username(sampass) ));
843
844         if (pdb_get_pass_can_change(sampass)) {
845                 TALLOC_FREE(sampass);
846                 return True;
847         }
848         TALLOC_FREE(sampass);
849         return False;
850 }
851
852
853 /*******************************************************************
854  _samr_QuerySecurity
855  ********************************************************************/
856
857 NTSTATUS _samr_QuerySecurity(pipes_struct *p,
858                              struct samr_QuerySecurity *r)
859 {
860         NTSTATUS status;
861         DOM_SID pol_sid;
862         SEC_DESC * psd = NULL;
863         uint32 acc_granted;
864         size_t sd_size;
865
866         /* Get the SID. */
867         if (!get_lsa_policy_samr_sid(p, r->in.handle, &pol_sid, &acc_granted, NULL))
868                 return NT_STATUS_INVALID_HANDLE;
869
870         DEBUG(10,("_samr_QuerySecurity: querying security on SID: %s\n",
871                   sid_string_dbg(&pol_sid)));
872
873         status = access_check_samr_function(acc_granted,
874                                             STD_RIGHT_READ_CONTROL_ACCESS,
875                                             "_samr_QuerySecurity");
876         if (!NT_STATUS_IS_OK(status)) {
877                 return status;
878         }
879
880         /* Check what typ of SID is beeing queried (e.g Domain SID, User SID, Group SID) */
881
882         /* To query the security of the SAM it self an invalid SID with S-0-0 is passed to this function */
883         if (pol_sid.sid_rev_num == 0) {
884                 DEBUG(5,("_samr_QuerySecurity: querying security on SAM\n"));
885                 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
886         } else if (sid_equal(&pol_sid,get_global_sam_sid())) {
887                 /* check if it is our domain SID */
888                 DEBUG(5,("_samr_QuerySecurity: querying security on Domain "
889                          "with SID: %s\n", sid_string_dbg(&pol_sid)));
890                 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0);
891         } else if (sid_equal(&pol_sid,&global_sid_Builtin)) {
892                 /* check if it is the Builtin  Domain */
893                 /* TODO: Builtin probably needs a different SD with restricted write access*/
894                 DEBUG(5,("_samr_QuerySecurity: querying security on Builtin "
895                          "Domain with SID: %s\n", sid_string_dbg(&pol_sid)));
896                 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0);
897         } else if (sid_check_is_in_our_domain(&pol_sid) ||
898                  sid_check_is_in_builtin(&pol_sid)) {
899                 /* TODO: different SDs have to be generated for aliases groups and users.
900                          Currently all three get a default user SD  */
901                 DEBUG(10,("_samr_QuerySecurity: querying security on Object "
902                           "with SID: %s\n", sid_string_dbg(&pol_sid)));
903                 if (check_change_pw_access(p->mem_ctx, &pol_sid)) {
904                         status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping,
905                                                           &pol_sid, SAMR_USR_RIGHTS_WRITE_PW);
906                 } else {
907                         status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_nopwchange_generic_mapping,
908                                                           &pol_sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
909                 }
910         } else {
911                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
912         }
913
914         if ((*r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
915                 return NT_STATUS_NO_MEMORY;
916
917         return status;
918 }
919
920 /*******************************************************************
921 makes a SAM_ENTRY / UNISTR2* structure from a user list.
922 ********************************************************************/
923
924 static NTSTATUS make_user_sam_entry_list(TALLOC_CTX *ctx,
925                                          struct samr_SamEntry **sam_pp,
926                                          uint32_t num_entries,
927                                          uint32_t start_idx,
928                                          struct samr_displayentry *entries)
929 {
930         uint32_t i;
931         struct samr_SamEntry *sam;
932
933         *sam_pp = NULL;
934
935         if (num_entries == 0) {
936                 return NT_STATUS_OK;
937         }
938
939         sam = TALLOC_ZERO_ARRAY(ctx, struct samr_SamEntry, num_entries);
940         if (sam == NULL) {
941                 DEBUG(0, ("make_user_sam_entry_list: TALLOC_ZERO failed!\n"));
942                 return NT_STATUS_NO_MEMORY;
943         }
944
945         for (i = 0; i < num_entries; i++) {
946 #if 0
947                 /*
948                  * usrmgr expects a non-NULL terminated string with
949                  * trust relationships
950                  */
951                 if (entries[i].acct_flags & ACB_DOMTRUST) {
952                         init_unistr2(&uni_temp_name, entries[i].account_name,
953                                      UNI_FLAGS_NONE);
954                 } else {
955                         init_unistr2(&uni_temp_name, entries[i].account_name,
956                                      UNI_STR_TERMINATE);
957                 }
958 #endif
959                 init_lsa_String(&sam[i].name, entries[i].account_name);
960                 sam[i].idx = entries[i].rid;
961         }
962
963         *sam_pp = sam;
964
965         return NT_STATUS_OK;
966 }
967
968 #define MAX_SAM_ENTRIES MAX_SAM_ENTRIES_W2K
969
970 /*******************************************************************
971  _samr_EnumDomainUsers
972  ********************************************************************/
973
974 NTSTATUS _samr_EnumDomainUsers(pipes_struct *p,
975                                struct samr_EnumDomainUsers *r)
976 {
977         NTSTATUS status;
978         struct samr_info *info = NULL;
979         int num_account;
980         uint32 enum_context = *r->in.resume_handle;
981         enum remote_arch_types ra_type = get_remote_arch();
982         int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
983         uint32 max_entries = max_sam_entries;
984         struct samr_displayentry *entries = NULL;
985         struct samr_SamArray *samr_array = NULL;
986         struct samr_SamEntry *samr_entries = NULL;
987
988         /* find the policy handle.  open a policy on it. */
989         if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
990                 return NT_STATUS_INVALID_HANDLE;
991
992         status = access_check_samr_function(info->acc_granted,
993                                             SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
994                                             "_samr_EnumDomainUsers");
995         if (!NT_STATUS_IS_OK(status)) {
996                 return status;
997         }
998
999         DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
1000
1001         if (info->builtin_domain) {
1002                 /* No users in builtin. */
1003                 *r->out.resume_handle = *r->in.resume_handle;
1004                 DEBUG(5,("_samr_EnumDomainUsers: No users in BUILTIN\n"));
1005                 return status;
1006         }
1007
1008         samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
1009         if (!samr_array) {
1010                 return NT_STATUS_NO_MEMORY;
1011         }
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.sam = samr_array;
1072         *r->out.num_entries = num_account;
1073
1074         DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
1075
1076         return status;
1077 }
1078
1079 /*******************************************************************
1080 makes a SAM_ENTRY / UNISTR2* structure from a group list.
1081 ********************************************************************/
1082
1083 static void make_group_sam_entry_list(TALLOC_CTX *ctx,
1084                                       struct samr_SamEntry **sam_pp,
1085                                       uint32_t num_sam_entries,
1086                                       struct samr_displayentry *entries)
1087 {
1088         struct samr_SamEntry *sam;
1089         uint32_t i;
1090
1091         *sam_pp = NULL;
1092
1093         if (num_sam_entries == 0) {
1094                 return;
1095         }
1096
1097         sam = TALLOC_ZERO_ARRAY(ctx, struct samr_SamEntry, num_sam_entries);
1098         if (sam == NULL) {
1099                 return;
1100         }
1101
1102         for (i = 0; i < num_sam_entries; i++) {
1103                 /*
1104                  * JRA. I think this should include the null. TNG does not.
1105                  */
1106                 init_lsa_String(&sam[i].name, entries[i].account_name);
1107                 sam[i].idx = entries[i].rid;
1108         }
1109
1110         *sam_pp = sam;
1111 }
1112
1113 /*******************************************************************
1114  _samr_EnumDomainGroups
1115  ********************************************************************/
1116
1117 NTSTATUS _samr_EnumDomainGroups(pipes_struct *p,
1118                                 struct samr_EnumDomainGroups *r)
1119 {
1120         NTSTATUS status;
1121         struct samr_info *info = NULL;
1122         struct samr_displayentry *groups;
1123         uint32 num_groups;
1124         struct samr_SamArray *samr_array = NULL;
1125         struct samr_SamEntry *samr_entries = NULL;
1126
1127         /* find the policy handle.  open a policy on it. */
1128         if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
1129                 return NT_STATUS_INVALID_HANDLE;
1130
1131         status = access_check_samr_function(info->acc_granted,
1132                                             SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
1133                                             "_samr_EnumDomainGroups");
1134         if (!NT_STATUS_IS_OK(status)) {
1135                 return status;
1136         }
1137
1138         DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
1139
1140         if (info->builtin_domain) {
1141                 /* No groups in builtin. */
1142                 *r->out.resume_handle = *r->in.resume_handle;
1143                 DEBUG(5,("_samr_EnumDomainGroups: No groups in BUILTIN\n"));
1144                 return status;
1145         }
1146
1147         samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
1148         if (!samr_array) {
1149                 return NT_STATUS_NO_MEMORY;
1150         }
1151
1152         /* the domain group array is being allocated in the function below */
1153
1154         become_root();
1155
1156         if (info->disp_info->groups == NULL) {
1157                 info->disp_info->groups = pdb_search_groups();
1158
1159                 if (info->disp_info->groups == NULL) {
1160                         unbecome_root();
1161                         return NT_STATUS_ACCESS_DENIED;
1162                 }
1163         }
1164
1165         num_groups = pdb_search_entries(info->disp_info->groups,
1166                                         *r->in.resume_handle,
1167                                         MAX_SAM_ENTRIES, &groups);
1168         unbecome_root();
1169
1170         /* Ensure we cache this enumeration. */
1171         set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1172
1173         make_group_sam_entry_list(p->mem_ctx, &samr_entries,
1174                                   num_groups, groups);
1175
1176         samr_array->count = num_groups;
1177         samr_array->entries = samr_entries;
1178
1179         *r->out.sam = samr_array;
1180         *r->out.num_entries = num_groups;
1181         /* this was missing, IMHO:
1182         *r->out.resume_handle = num_groups + *r->in.resume_handle;
1183         */
1184
1185         DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
1186
1187         return status;
1188 }
1189
1190 /*******************************************************************
1191  _samr_EnumDomainAliases
1192  ********************************************************************/
1193
1194 NTSTATUS _samr_EnumDomainAliases(pipes_struct *p,
1195                                  struct samr_EnumDomainAliases *r)
1196 {
1197         NTSTATUS status;
1198         struct samr_info *info;
1199         struct samr_displayentry *aliases;
1200         uint32 num_aliases = 0;
1201         struct samr_SamArray *samr_array = NULL;
1202         struct samr_SamEntry *samr_entries = NULL;
1203
1204         /* find the policy handle.  open a policy on it. */
1205         if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
1206                 return NT_STATUS_INVALID_HANDLE;
1207
1208         DEBUG(5,("_samr_EnumDomainAliases: sid %s\n",
1209                  sid_string_dbg(&info->sid)));
1210
1211         status = access_check_samr_function(info->acc_granted,
1212                                             SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
1213                                             "_samr_EnumDomainAliases");
1214         if (!NT_STATUS_IS_OK(status)) {
1215                 return status;
1216         }
1217
1218         samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
1219         if (!samr_array) {
1220                 return NT_STATUS_NO_MEMORY;
1221         }
1222
1223         become_root();
1224
1225         if (info->disp_info->aliases == NULL) {
1226                 info->disp_info->aliases = pdb_search_aliases(&info->sid);
1227                 if (info->disp_info->aliases == NULL) {
1228                         unbecome_root();
1229                         return NT_STATUS_ACCESS_DENIED;
1230                 }
1231         }
1232
1233         num_aliases = pdb_search_entries(info->disp_info->aliases,
1234                                          *r->in.resume_handle,
1235                                          MAX_SAM_ENTRIES, &aliases);
1236         unbecome_root();
1237
1238         /* Ensure we cache this enumeration. */
1239         set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1240
1241         make_group_sam_entry_list(p->mem_ctx, &samr_entries,
1242                                   num_aliases, aliases);
1243
1244         DEBUG(5,("_samr_EnumDomainAliases: %d\n", __LINE__));
1245
1246         samr_array->count = num_aliases;
1247         samr_array->entries = samr_entries;
1248
1249         *r->out.sam = samr_array;
1250         *r->out.num_entries = num_aliases;
1251         *r->out.resume_handle = num_aliases + *r->in.resume_handle;
1252
1253         return status;
1254 }
1255
1256 /*******************************************************************
1257  inits a samr_DispInfoGeneral structure.
1258 ********************************************************************/
1259
1260 static NTSTATUS init_samr_dispinfo_1(TALLOC_CTX *ctx,
1261                                      struct samr_DispInfoGeneral *r,
1262                                      uint32_t num_entries,
1263                                      uint32_t start_idx,
1264                                      struct samr_displayentry *entries)
1265 {
1266         uint32 i;
1267
1268         DEBUG(10, ("init_samr_dispinfo_1: num_entries: %d\n", num_entries));
1269
1270         if (num_entries == 0) {
1271                 return NT_STATUS_OK;
1272         }
1273
1274         r->count = num_entries;
1275
1276         r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryGeneral, num_entries);
1277         if (!r->entries) {
1278                 return NT_STATUS_NO_MEMORY;
1279         }
1280
1281         for (i = 0; i < num_entries ; i++) {
1282
1283                 init_lsa_String(&r->entries[i].account_name,
1284                                 entries[i].account_name);
1285
1286                 init_lsa_String(&r->entries[i].description,
1287                                 entries[i].description);
1288
1289                 init_lsa_String(&r->entries[i].full_name,
1290                                 entries[i].fullname);
1291
1292                 r->entries[i].rid = entries[i].rid;
1293                 r->entries[i].acct_flags = entries[i].acct_flags;
1294                 r->entries[i].idx = start_idx+i+1;
1295         }
1296
1297         return NT_STATUS_OK;
1298 }
1299
1300 /*******************************************************************
1301  inits a samr_DispInfoFull structure.
1302 ********************************************************************/
1303
1304 static NTSTATUS init_samr_dispinfo_2(TALLOC_CTX *ctx,
1305                                      struct samr_DispInfoFull *r,
1306                                      uint32_t num_entries,
1307                                      uint32_t start_idx,
1308                                      struct samr_displayentry *entries)
1309 {
1310         uint32_t i;
1311
1312         DEBUG(10, ("init_samr_dispinfo_2: num_entries: %d\n", num_entries));
1313
1314         if (num_entries == 0) {
1315                 return NT_STATUS_OK;
1316         }
1317
1318         r->count = num_entries;
1319
1320         r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryFull, num_entries);
1321         if (!r->entries) {
1322                 return NT_STATUS_NO_MEMORY;
1323         }
1324
1325         for (i = 0; i < num_entries ; i++) {
1326
1327                 init_lsa_String(&r->entries[i].account_name,
1328                                 entries[i].account_name);
1329
1330                 init_lsa_String(&r->entries[i].description,
1331                                 entries[i].description);
1332
1333                 r->entries[i].rid = entries[i].rid;
1334                 r->entries[i].acct_flags = entries[i].acct_flags;
1335                 r->entries[i].idx = start_idx+i+1;
1336         }
1337
1338         return NT_STATUS_OK;
1339 }
1340
1341 /*******************************************************************
1342  inits a samr_DispInfoFullGroups structure.
1343 ********************************************************************/
1344
1345 static NTSTATUS init_samr_dispinfo_3(TALLOC_CTX *ctx,
1346                                      struct samr_DispInfoFullGroups *r,
1347                                      uint32_t num_entries,
1348                                      uint32_t start_idx,
1349                                      struct samr_displayentry *entries)
1350 {
1351         uint32_t i;
1352
1353         DEBUG(5, ("init_samr_dispinfo_3: num_entries: %d\n", num_entries));
1354
1355         if (num_entries == 0) {
1356                 return NT_STATUS_OK;
1357         }
1358
1359         r->count = num_entries;
1360
1361         r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryFullGroup, num_entries);
1362         if (!r->entries) {
1363                 return NT_STATUS_NO_MEMORY;
1364         }
1365
1366         for (i = 0; i < num_entries ; i++) {
1367
1368                 init_lsa_String(&r->entries[i].account_name,
1369                                 entries[i].account_name);
1370
1371                 init_lsa_String(&r->entries[i].description,
1372                                 entries[i].description);
1373
1374                 r->entries[i].rid = entries[i].rid;
1375                 r->entries[i].acct_flags = entries[i].acct_flags;
1376                 r->entries[i].idx = start_idx+i+1;
1377         }
1378
1379         return NT_STATUS_OK;
1380 }
1381
1382 /*******************************************************************
1383  inits a samr_DispInfoAscii structure.
1384 ********************************************************************/
1385
1386 static NTSTATUS init_samr_dispinfo_4(TALLOC_CTX *ctx,
1387                                      struct samr_DispInfoAscii *r,
1388                                      uint32_t num_entries,
1389                                      uint32_t start_idx,
1390                                      struct samr_displayentry *entries)
1391 {
1392         uint32_t i;
1393
1394         DEBUG(5, ("init_samr_dispinfo_4: num_entries: %d\n", num_entries));
1395
1396         if (num_entries == 0) {
1397                 return NT_STATUS_OK;
1398         }
1399
1400         r->count = num_entries;
1401
1402         r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryAscii, num_entries);
1403         if (!r->entries) {
1404                 return NT_STATUS_NO_MEMORY;
1405         }
1406
1407         for (i = 0; i < num_entries ; i++) {
1408
1409                 init_lsa_AsciiStringLarge(&r->entries[i].account_name,
1410                                           entries[i].account_name);
1411
1412                 r->entries[i].idx = start_idx+i+1;
1413         }
1414
1415         return NT_STATUS_OK;
1416 }
1417
1418 /*******************************************************************
1419  inits a samr_DispInfoAscii structure.
1420 ********************************************************************/
1421
1422 static NTSTATUS init_samr_dispinfo_5(TALLOC_CTX *ctx,
1423                                      struct samr_DispInfoAscii *r,
1424                                      uint32_t num_entries,
1425                                      uint32_t start_idx,
1426                                      struct samr_displayentry *entries)
1427 {
1428         uint32_t i;
1429
1430         DEBUG(5, ("init_samr_dispinfo_5: num_entries: %d\n", num_entries));
1431
1432         if (num_entries == 0) {
1433                 return NT_STATUS_OK;
1434         }
1435
1436         r->count = num_entries;
1437
1438         r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryAscii, num_entries);
1439         if (!r->entries) {
1440                 return NT_STATUS_NO_MEMORY;
1441         }
1442
1443         for (i = 0; i < num_entries ; i++) {
1444
1445                 init_lsa_AsciiStringLarge(&r->entries[i].account_name,
1446                                           entries[i].account_name);
1447
1448                 r->entries[i].idx = start_idx+i+1;
1449         }
1450
1451         return NT_STATUS_OK;
1452 }
1453
1454 /*******************************************************************
1455  _samr_QueryDisplayInfo
1456  ********************************************************************/
1457
1458 NTSTATUS _samr_QueryDisplayInfo(pipes_struct *p,
1459                                 struct samr_QueryDisplayInfo *r)
1460 {
1461         NTSTATUS status;
1462         struct samr_info *info = NULL;
1463         uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
1464
1465         uint32 max_entries = r->in.max_entries;
1466         uint32 enum_context = r->in.start_idx;
1467         uint32 max_size = r->in.buf_size;
1468
1469         union samr_DispInfo *disp_info = r->out.info;
1470
1471         uint32 temp_size=0, total_data_size=0;
1472         NTSTATUS disp_ret = NT_STATUS_UNSUCCESSFUL;
1473         uint32 num_account = 0;
1474         enum remote_arch_types ra_type = get_remote_arch();
1475         int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
1476         struct samr_displayentry *entries = NULL;
1477
1478         DEBUG(5,("_samr_QueryDisplayInfo: %d\n", __LINE__));
1479
1480         /* find the policy handle.  open a policy on it. */
1481         if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
1482                 return NT_STATUS_INVALID_HANDLE;
1483
1484         status = access_check_samr_function(info->acc_granted,
1485                                             SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
1486                                             "_samr_QueryDisplayInfo");
1487         if (!NT_STATUS_IS_OK(status)) {
1488                 return status;
1489         }
1490
1491         /*
1492          * calculate how many entries we will return.
1493          * based on
1494          * - the number of entries the client asked
1495          * - our limit on that
1496          * - the starting point (enumeration context)
1497          * - the buffer size the client will accept
1498          */
1499
1500         /*
1501          * We are a lot more like W2K. Instead of reading the SAM
1502          * each time to find the records we need to send back,
1503          * we read it once and link that copy to the sam handle.
1504          * For large user list (over the MAX_SAM_ENTRIES)
1505          * it's a definitive win.
1506          * second point to notice: between enumerations
1507          * our sam is now the same as it's a snapshoot.
1508          * third point: got rid of the static SAM_USER_21 struct
1509          * no more intermediate.
1510          * con: it uses much more memory, as a full copy is stored
1511          * in memory.
1512          *
1513          * If you want to change it, think twice and think
1514          * of the second point , that's really important.
1515          *
1516          * JFM, 12/20/2001
1517          */
1518
1519         if ((r->in.level < 1) || (r->in.level > 5)) {
1520                 DEBUG(0,("_samr_QueryDisplayInfo: Unknown info level (%u)\n",
1521                          (unsigned int)r->in.level ));
1522                 return NT_STATUS_INVALID_INFO_CLASS;
1523         }
1524
1525         /* first limit the number of entries we will return */
1526         if(max_entries > max_sam_entries) {
1527                 DEBUG(5, ("_samr_QueryDisplayInfo: client requested %d "
1528                           "entries, limiting to %d\n", max_entries,
1529                           max_sam_entries));
1530                 max_entries = max_sam_entries;
1531         }
1532
1533         /* calculate the size and limit on the number of entries we will
1534          * return */
1535
1536         temp_size=max_entries*struct_size;
1537
1538         if (temp_size>max_size) {
1539                 max_entries=MIN((max_size/struct_size),max_entries);;
1540                 DEBUG(5, ("_samr_QueryDisplayInfo: buffer size limits to "
1541                           "only %d entries\n", max_entries));
1542         }
1543
1544         become_root();
1545
1546         /* THe following done as ROOT. Don't return without unbecome_root(). */
1547
1548         switch (r->in.level) {
1549         case 0x1:
1550         case 0x4:
1551                 if (info->disp_info->users == NULL) {
1552                         info->disp_info->users = pdb_search_users(ACB_NORMAL);
1553                         if (info->disp_info->users == NULL) {
1554                                 unbecome_root();
1555                                 return NT_STATUS_ACCESS_DENIED;
1556                         }
1557                         DEBUG(10,("_samr_QueryDisplayInfo: starting user enumeration at index %u\n",
1558                                 (unsigned  int)enum_context ));
1559                 } else {
1560                         DEBUG(10,("_samr_QueryDisplayInfo: using cached user enumeration at index %u\n",
1561                                 (unsigned  int)enum_context ));
1562                 }
1563
1564                 num_account = pdb_search_entries(info->disp_info->users,
1565                                                  enum_context, max_entries,
1566                                                  &entries);
1567                 break;
1568         case 0x2:
1569                 if (info->disp_info->machines == NULL) {
1570                         info->disp_info->machines =
1571                                 pdb_search_users(ACB_WSTRUST|ACB_SVRTRUST);
1572                         if (info->disp_info->machines == NULL) {
1573                                 unbecome_root();
1574                                 return NT_STATUS_ACCESS_DENIED;
1575                         }
1576                         DEBUG(10,("_samr_QueryDisplayInfo: starting machine enumeration at index %u\n",
1577                                 (unsigned  int)enum_context ));
1578                 } else {
1579                         DEBUG(10,("_samr_QueryDisplayInfo: using cached machine enumeration at index %u\n",
1580                                 (unsigned  int)enum_context ));
1581                 }
1582
1583                 num_account = pdb_search_entries(info->disp_info->machines,
1584                                                  enum_context, max_entries,
1585                                                  &entries);
1586                 break;
1587         case 0x3:
1588         case 0x5:
1589                 if (info->disp_info->groups == NULL) {
1590                         info->disp_info->groups = pdb_search_groups();
1591                         if (info->disp_info->groups == NULL) {
1592                                 unbecome_root();
1593                                 return NT_STATUS_ACCESS_DENIED;
1594                         }
1595                         DEBUG(10,("_samr_QueryDisplayInfo: starting group enumeration at index %u\n",
1596                                 (unsigned  int)enum_context ));
1597                 } else {
1598                         DEBUG(10,("_samr_QueryDisplayInfo: using cached group enumeration at index %u\n",
1599                                 (unsigned  int)enum_context ));
1600                 }
1601
1602                 num_account = pdb_search_entries(info->disp_info->groups,
1603                                                  enum_context, max_entries,
1604                                                  &entries);
1605                 break;
1606         default:
1607                 unbecome_root();
1608                 smb_panic("info class changed");
1609                 break;
1610         }
1611         unbecome_root();
1612
1613
1614         /* Now create reply structure */
1615         switch (r->in.level) {
1616         case 0x1:
1617                 disp_ret = init_samr_dispinfo_1(p->mem_ctx, &disp_info->info1,
1618                                                 num_account, enum_context,
1619                                                 entries);
1620                 break;
1621         case 0x2:
1622                 disp_ret = init_samr_dispinfo_2(p->mem_ctx, &disp_info->info2,
1623                                                 num_account, enum_context,
1624                                                 entries);
1625                 break;
1626         case 0x3:
1627                 disp_ret = init_samr_dispinfo_3(p->mem_ctx, &disp_info->info3,
1628                                                 num_account, enum_context,
1629                                                 entries);
1630                 break;
1631         case 0x4:
1632                 disp_ret = init_samr_dispinfo_4(p->mem_ctx, &disp_info->info4,
1633                                                 num_account, enum_context,
1634                                                 entries);
1635                 break;
1636         case 0x5:
1637                 disp_ret = init_samr_dispinfo_5(p->mem_ctx, &disp_info->info5,
1638                                                 num_account, enum_context,
1639                                                 entries);
1640                 break;
1641         default:
1642                 smb_panic("info class changed");
1643                 break;
1644         }
1645
1646         if (!NT_STATUS_IS_OK(disp_ret))
1647                 return disp_ret;
1648
1649         /* calculate the total size */
1650         total_data_size=num_account*struct_size;
1651
1652         if (max_entries <= num_account) {
1653                 status = STATUS_MORE_ENTRIES;
1654         } else {
1655                 status = NT_STATUS_OK;
1656         }
1657
1658         /* Ensure we cache this enumeration. */
1659         set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1660
1661         DEBUG(5, ("_samr_QueryDisplayInfo: %d\n", __LINE__));
1662
1663         *r->out.total_size = total_data_size;
1664         *r->out.returned_size = temp_size;
1665
1666         return status;
1667 }
1668
1669 /****************************************************************
1670  _samr_QueryDisplayInfo2
1671 ****************************************************************/
1672
1673 NTSTATUS _samr_QueryDisplayInfo2(pipes_struct *p,
1674                                  struct samr_QueryDisplayInfo2 *r)
1675 {
1676         struct samr_QueryDisplayInfo q;
1677
1678         q.in.domain_handle      = r->in.domain_handle;
1679         q.in.level              = r->in.level;
1680         q.in.start_idx          = r->in.start_idx;
1681         q.in.max_entries        = r->in.max_entries;
1682         q.in.buf_size           = r->in.buf_size;
1683
1684         q.out.total_size        = r->out.total_size;
1685         q.out.returned_size     = r->out.returned_size;
1686         q.out.info              = r->out.info;
1687
1688         return _samr_QueryDisplayInfo(p, &q);
1689 }
1690
1691 /****************************************************************
1692  _samr_QueryDisplayInfo3
1693 ****************************************************************/
1694
1695 NTSTATUS _samr_QueryDisplayInfo3(pipes_struct *p,
1696                                  struct samr_QueryDisplayInfo3 *r)
1697 {
1698         struct samr_QueryDisplayInfo q;
1699
1700         q.in.domain_handle      = r->in.domain_handle;
1701         q.in.level              = r->in.level;
1702         q.in.start_idx          = r->in.start_idx;
1703         q.in.max_entries        = r->in.max_entries;
1704         q.in.buf_size           = r->in.buf_size;
1705
1706         q.out.total_size        = r->out.total_size;
1707         q.out.returned_size     = r->out.returned_size;
1708         q.out.info              = r->out.info;
1709
1710         return _samr_QueryDisplayInfo(p, &q);
1711 }
1712
1713 /*******************************************************************
1714  _samr_QueryAliasInfo
1715  ********************************************************************/
1716
1717 NTSTATUS _samr_QueryAliasInfo(pipes_struct *p,
1718                               struct samr_QueryAliasInfo *r)
1719 {
1720         DOM_SID   sid;
1721         struct acct_info info;
1722         uint32    acc_granted;
1723         NTSTATUS status;
1724         union samr_AliasInfo *alias_info = NULL;
1725         const char *alias_name = NULL;
1726         const char *alias_description = NULL;
1727
1728         DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1729
1730         alias_info = TALLOC_ZERO_P(p->mem_ctx, union samr_AliasInfo);
1731         if (!alias_info) {
1732                 return NT_STATUS_NO_MEMORY;
1733         }
1734
1735         /* find the policy handle.  open a policy on it. */
1736         if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &sid, &acc_granted, NULL))
1737                 return NT_STATUS_INVALID_HANDLE;
1738
1739         status = access_check_samr_function(acc_granted,
1740                                             SA_RIGHT_ALIAS_LOOKUP_INFO,
1741                                             "_samr_QueryAliasInfo");
1742         if (!NT_STATUS_IS_OK(status)) {
1743                 return status;
1744         }
1745
1746         become_root();
1747         status = pdb_get_aliasinfo(&sid, &info);
1748         unbecome_root();
1749
1750         if ( !NT_STATUS_IS_OK(status))
1751                 return status;
1752
1753         /* FIXME: info contains fstrings */
1754         alias_name = talloc_strdup(r, info.acct_name);
1755         alias_description = talloc_strdup(r, info.acct_desc);
1756
1757         switch (r->in.level) {
1758         case ALIASINFOALL:
1759                 init_samr_alias_info1(&alias_info->all,
1760                                       alias_name,
1761                                       1,
1762                                       alias_description);
1763                 break;
1764         case ALIASINFODESCRIPTION:
1765                 init_samr_alias_info3(&alias_info->description,
1766                                       alias_description);
1767                 break;
1768         default:
1769                 return NT_STATUS_INVALID_INFO_CLASS;
1770         }
1771
1772         *r->out.info = alias_info;
1773
1774         DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1775
1776         return NT_STATUS_OK;
1777 }
1778
1779 /*******************************************************************
1780  _samr_LookupNames
1781  ********************************************************************/
1782
1783 NTSTATUS _samr_LookupNames(pipes_struct *p,
1784                            struct samr_LookupNames *r)
1785 {
1786         NTSTATUS status;
1787         uint32 *rid;
1788         enum lsa_SidType *type;
1789         int i;
1790         int num_rids = r->in.num_names;
1791         DOM_SID pol_sid;
1792         uint32  acc_granted;
1793         struct samr_Ids rids, types;
1794
1795         DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1796
1797         if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &pol_sid, &acc_granted, NULL)) {
1798                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1799         }
1800
1801         status = access_check_samr_function(acc_granted,
1802                                             0, /* Don't know the acc_bits yet */
1803                                             "_samr_LookupNames");
1804         if (!NT_STATUS_IS_OK(status)) {
1805                 return status;
1806         }
1807
1808         if (num_rids > MAX_SAM_ENTRIES) {
1809                 num_rids = MAX_SAM_ENTRIES;
1810                 DEBUG(5,("_samr_LookupNames: truncating entries to %d\n", num_rids));
1811         }
1812
1813         rid = talloc_array(p->mem_ctx, uint32, num_rids);
1814         NT_STATUS_HAVE_NO_MEMORY(rid);
1815
1816         type = talloc_array(p->mem_ctx, enum lsa_SidType, num_rids);
1817         NT_STATUS_HAVE_NO_MEMORY(type);
1818
1819         DEBUG(5,("_samr_LookupNames: looking name on SID %s\n",
1820                  sid_string_dbg(&pol_sid)));
1821
1822         for (i = 0; i < num_rids; i++) {
1823
1824                 status = NT_STATUS_NONE_MAPPED;
1825                 type[i] = SID_NAME_UNKNOWN;
1826
1827                 rid[i] = 0xffffffff;
1828
1829                 if (sid_check_is_builtin(&pol_sid)) {
1830                         if (lookup_builtin_name(r->in.names[i].string,
1831                                                 &rid[i]))
1832                         {
1833                                 type[i] = SID_NAME_ALIAS;
1834                         }
1835                 } else {
1836                         lookup_global_sam_name(r->in.names[i].string, 0,
1837                                                &rid[i], &type[i]);
1838                 }
1839
1840                 if (type[i] != SID_NAME_UNKNOWN) {
1841                         status = NT_STATUS_OK;
1842                 }
1843         }
1844
1845         rids.count = num_rids;
1846         rids.ids = rid;
1847
1848         types.count = num_rids;
1849         types.ids = type;
1850
1851         *r->out.rids = rids;
1852         *r->out.types = types;
1853
1854         DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1855
1856         return status;
1857 }
1858
1859 /*******************************************************************
1860  _samr_ChangePasswordUser2
1861  ********************************************************************/
1862
1863 NTSTATUS _samr_ChangePasswordUser2(pipes_struct *p,
1864                                    struct samr_ChangePasswordUser2 *r)
1865 {
1866         NTSTATUS status;
1867         fstring user_name;
1868         fstring wks;
1869
1870         DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1871
1872         fstrcpy(user_name, r->in.account->string);
1873         fstrcpy(wks, r->in.server->string);
1874
1875         DEBUG(5,("_samr_ChangePasswordUser2: user: %s wks: %s\n", user_name, wks));
1876
1877         /*
1878          * Pass the user through the NT -> unix user mapping
1879          * function.
1880          */
1881
1882         (void)map_username(user_name);
1883
1884         /*
1885          * UNIX username case mangling not required, pass_oem_change
1886          * is case insensitive.
1887          */
1888
1889         status = pass_oem_change(user_name,
1890                                  r->in.lm_password->data,
1891                                  r->in.lm_verifier->hash,
1892                                  r->in.nt_password->data,
1893                                  r->in.nt_verifier->hash,
1894                                  NULL);
1895
1896         DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1897
1898         return status;
1899 }
1900
1901 /*******************************************************************
1902  _samr_ChangePasswordUser3
1903  ********************************************************************/
1904
1905 NTSTATUS _samr_ChangePasswordUser3(pipes_struct *p,
1906                                    struct samr_ChangePasswordUser3 *r)
1907 {
1908         NTSTATUS status;
1909         fstring user_name;
1910         const char *wks = NULL;
1911         uint32 reject_reason;
1912         struct samr_DomInfo1 *dominfo = NULL;
1913         struct samr_ChangeReject *reject = NULL;
1914
1915         DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
1916
1917         fstrcpy(user_name, r->in.account->string);
1918         if (r->in.server && r->in.server->string) {
1919                 wks = r->in.server->string;
1920         }
1921
1922         DEBUG(5,("_samr_ChangePasswordUser3: user: %s wks: %s\n", user_name, wks));
1923
1924         /*
1925          * Pass the user through the NT -> unix user mapping
1926          * function.
1927          */
1928
1929         (void)map_username(user_name);
1930
1931         /*
1932          * UNIX username case mangling not required, pass_oem_change
1933          * is case insensitive.
1934          */
1935
1936         status = pass_oem_change(user_name,
1937                                  r->in.lm_password->data,
1938                                  r->in.lm_verifier->hash,
1939                                  r->in.nt_password->data,
1940                                  r->in.nt_verifier->hash,
1941                                  &reject_reason);
1942
1943         if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) ||
1944             NT_STATUS_EQUAL(status, NT_STATUS_ACCOUNT_RESTRICTION)) {
1945
1946                 uint32 min_pass_len,pass_hist,password_properties;
1947                 time_t u_expire, u_min_age;
1948                 NTTIME nt_expire, nt_min_age;
1949                 uint32 account_policy_temp;
1950
1951                 dominfo = TALLOC_ZERO_P(p->mem_ctx, struct samr_DomInfo1);
1952                 if (!dominfo) {
1953                         return NT_STATUS_NO_MEMORY;
1954                 }
1955
1956                 reject = TALLOC_ZERO_P(p->mem_ctx, struct samr_ChangeReject);
1957                 if (!reject) {
1958                         return NT_STATUS_NO_MEMORY;
1959                 }
1960
1961                 become_root();
1962
1963                 /* AS ROOT !!! */
1964
1965                 pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &account_policy_temp);
1966                 min_pass_len = account_policy_temp;
1967
1968                 pdb_get_account_policy(AP_PASSWORD_HISTORY, &account_policy_temp);
1969                 pass_hist = account_policy_temp;
1970
1971                 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
1972                 password_properties = account_policy_temp;
1973
1974                 pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
1975                 u_expire = account_policy_temp;
1976
1977                 pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
1978                 u_min_age = account_policy_temp;
1979
1980                 /* !AS ROOT */
1981
1982                 unbecome_root();
1983
1984                 unix_to_nt_time_abs(&nt_expire, u_expire);
1985                 unix_to_nt_time_abs(&nt_min_age, u_min_age);
1986
1987                 if (lp_check_password_script() && *lp_check_password_script()) {
1988                         password_properties |= DOMAIN_PASSWORD_COMPLEX;
1989                 }
1990
1991                 init_samr_DomInfo1(dominfo,
1992                                    min_pass_len,
1993                                    pass_hist,
1994                                    password_properties,
1995                                    u_expire,
1996                                    u_min_age);
1997
1998                 reject->reason = reject_reason;
1999
2000                 *r->out.dominfo = dominfo;
2001                 *r->out.reject = reject;
2002         }
2003
2004         DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
2005
2006         return status;
2007 }
2008
2009 /*******************************************************************
2010 makes a SAMR_R_LOOKUP_RIDS structure.
2011 ********************************************************************/
2012
2013 static bool make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names,
2014                                   const char **names,
2015                                   struct lsa_String **lsa_name_array_p)
2016 {
2017         struct lsa_String *lsa_name_array = NULL;
2018         uint32_t i;
2019
2020         *lsa_name_array_p = NULL;
2021
2022         if (num_names != 0) {
2023                 lsa_name_array = TALLOC_ZERO_ARRAY(ctx, struct lsa_String, num_names);
2024                 if (!lsa_name_array) {
2025                         return false;
2026                 }
2027         }
2028
2029         for (i = 0; i < num_names; i++) {
2030                 DEBUG(10, ("names[%d]:%s\n", i, names[i] && *names[i] ? names[i] : ""));
2031                 init_lsa_String(&lsa_name_array[i], names[i]);
2032         }
2033
2034         *lsa_name_array_p = lsa_name_array;
2035
2036         return true;
2037 }
2038
2039 /*******************************************************************
2040  _samr_LookupRids
2041  ********************************************************************/
2042
2043 NTSTATUS _samr_LookupRids(pipes_struct *p,
2044                           struct samr_LookupRids *r)
2045 {
2046         NTSTATUS status;
2047         const char **names;
2048         enum lsa_SidType *attrs = NULL;
2049         uint32 *wire_attrs = NULL;
2050         DOM_SID pol_sid;
2051         int num_rids = (int)r->in.num_rids;
2052         uint32 acc_granted;
2053         int i;
2054         struct lsa_Strings names_array;
2055         struct samr_Ids types_array;
2056         struct lsa_String *lsa_names = NULL;
2057
2058         DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2059
2060         /* find the policy handle.  open a policy on it. */
2061         if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &pol_sid, &acc_granted, NULL))
2062                 return NT_STATUS_INVALID_HANDLE;
2063
2064         status = access_check_samr_function(acc_granted,
2065                                             SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
2066                                             "_samr_LookupRids");
2067         if (!NT_STATUS_IS_OK(status)) {
2068                 return status;
2069         }
2070
2071         if (num_rids > 1000) {
2072                 DEBUG(0, ("Got asked for %d rids (more than 1000) -- according "
2073                           "to samba4 idl this is not possible\n", num_rids));
2074                 return NT_STATUS_UNSUCCESSFUL;
2075         }
2076
2077         if (num_rids) {
2078                 names = TALLOC_ZERO_ARRAY(p->mem_ctx, const char *, num_rids);
2079                 attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, enum lsa_SidType, num_rids);
2080                 wire_attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_rids);
2081
2082                 if ((names == NULL) || (attrs == NULL) || (wire_attrs==NULL))
2083                         return NT_STATUS_NO_MEMORY;
2084         } else {
2085                 names = NULL;
2086                 attrs = NULL;
2087                 wire_attrs = NULL;
2088         }
2089
2090         become_root();  /* lookup_sid can require root privs */
2091         status = pdb_lookup_rids(&pol_sid, num_rids, r->in.rids,
2092                                  names, attrs);
2093         unbecome_root();
2094
2095         if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED) && (num_rids == 0)) {
2096                 status = NT_STATUS_OK;
2097         }
2098
2099         if (!make_samr_lookup_rids(p->mem_ctx, num_rids, names,
2100                                    &lsa_names)) {
2101                 return NT_STATUS_NO_MEMORY;
2102         }
2103
2104         /* Convert from enum lsa_SidType to uint32 for wire format. */
2105         for (i = 0; i < num_rids; i++) {
2106                 wire_attrs[i] = (uint32)attrs[i];
2107         }
2108
2109         names_array.count = num_rids;
2110         names_array.names = lsa_names;
2111
2112         types_array.count = num_rids;
2113         types_array.ids = wire_attrs;
2114
2115         *r->out.names = names_array;
2116         *r->out.types = types_array;
2117
2118         DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2119
2120         return status;
2121 }
2122
2123 /*******************************************************************
2124  _samr_OpenUser
2125 ********************************************************************/
2126
2127 NTSTATUS _samr_OpenUser(pipes_struct *p,
2128                         struct samr_OpenUser *r)
2129 {
2130         struct samu *sampass=NULL;
2131         DOM_SID sid;
2132         POLICY_HND domain_pol = *r->in.domain_handle;
2133         POLICY_HND *user_pol = r->out.user_handle;
2134         struct samr_info *info = NULL;
2135         SEC_DESC *psd = NULL;
2136         uint32    acc_granted;
2137         uint32    des_access = r->in.access_mask;
2138         size_t    sd_size;
2139         bool ret;
2140         NTSTATUS nt_status;
2141         SE_PRIV se_rights;
2142
2143         /* find the domain policy handle and get domain SID / access bits in the domain policy. */
2144
2145         if ( !get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted, NULL) )
2146                 return NT_STATUS_INVALID_HANDLE;
2147
2148         nt_status = access_check_samr_function(acc_granted,
2149                                                SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
2150                                                "_samr_OpenUser" );
2151
2152         if ( !NT_STATUS_IS_OK(nt_status) )
2153                 return nt_status;
2154
2155         if ( !(sampass = samu_new( p->mem_ctx )) ) {
2156                 return NT_STATUS_NO_MEMORY;
2157         }
2158
2159         /* append the user's RID to it */
2160
2161         if (!sid_append_rid(&sid, r->in.rid))
2162                 return NT_STATUS_NO_SUCH_USER;
2163
2164         /* check if access can be granted as requested by client. */
2165
2166         map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
2167
2168         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &sid, SAMR_USR_RIGHTS_WRITE_PW);
2169         se_map_generic(&des_access, &usr_generic_mapping);
2170
2171         se_priv_copy( &se_rights, &se_machine_account );
2172         se_priv_add( &se_rights, &se_add_users );
2173
2174         nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
2175                 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
2176                 &acc_granted, "_samr_OpenUser");
2177
2178         if ( !NT_STATUS_IS_OK(nt_status) )
2179                 return nt_status;
2180
2181         become_root();
2182         ret=pdb_getsampwsid(sampass, &sid);
2183         unbecome_root();
2184
2185         /* check that the SID exists in our domain. */
2186         if (ret == False) {
2187                 return NT_STATUS_NO_SUCH_USER;
2188         }
2189
2190         TALLOC_FREE(sampass);
2191
2192         /* associate the user's SID and access bits with the new handle. */
2193         if ((info = get_samr_info_by_sid(&sid)) == NULL)
2194                 return NT_STATUS_NO_MEMORY;
2195         info->acc_granted = acc_granted;
2196
2197         /* get a (unique) handle.  open a policy on it. */
2198         if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info))
2199                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2200
2201         return NT_STATUS_OK;
2202 }
2203
2204 /*************************************************************************
2205  *************************************************************************/
2206
2207 static NTSTATUS init_samr_parameters_string(TALLOC_CTX *mem_ctx,
2208                                             DATA_BLOB *blob,
2209                                             struct lsa_BinaryString **_r)
2210 {
2211         struct lsa_BinaryString *r;
2212
2213         if (!blob || !_r) {
2214                 return NT_STATUS_INVALID_PARAMETER;
2215         }
2216
2217         r = TALLOC_ZERO_P(mem_ctx, struct lsa_BinaryString);
2218         if (!r) {
2219                 return NT_STATUS_NO_MEMORY;
2220         }
2221
2222         r->array = TALLOC_ZERO_ARRAY(mem_ctx, uint16_t, blob->length/2);
2223         if (!r->array) {
2224                 return NT_STATUS_NO_MEMORY;
2225         }
2226         memcpy(r->array, blob->data, blob->length);
2227         r->size = blob->length;
2228         r->length = blob->length;
2229
2230         if (!r->array) {
2231                 return NT_STATUS_NO_MEMORY;
2232         }
2233
2234         *_r = r;
2235
2236         return NT_STATUS_OK;
2237 }
2238
2239 /*************************************************************************
2240  get_user_info_7. Safe. Only gives out account_name.
2241  *************************************************************************/
2242
2243 static NTSTATUS get_user_info_7(TALLOC_CTX *mem_ctx,
2244                                 struct samr_UserInfo7 *r,
2245                                 DOM_SID *user_sid)
2246 {
2247         struct samu *smbpass=NULL;
2248         bool ret;
2249         const char *account_name = NULL;
2250
2251         ZERO_STRUCTP(r);
2252
2253         if ( !(smbpass = samu_new( mem_ctx )) ) {
2254                 return NT_STATUS_NO_MEMORY;
2255         }
2256
2257         become_root();
2258         ret = pdb_getsampwsid(smbpass, user_sid);
2259         unbecome_root();
2260
2261         if ( !ret ) {
2262                 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
2263                 return NT_STATUS_NO_SUCH_USER;
2264         }
2265
2266         account_name = talloc_strdup(mem_ctx, pdb_get_username(smbpass));
2267         if (!account_name) {
2268                 TALLOC_FREE(smbpass);
2269                 return NT_STATUS_NO_MEMORY;
2270         }
2271         TALLOC_FREE(smbpass);
2272
2273         DEBUG(3,("User:[%s]\n", account_name));
2274
2275         init_samr_user_info7(r, account_name);
2276
2277         return NT_STATUS_OK;
2278 }
2279
2280 /*************************************************************************
2281  get_user_info_9. Only gives out primary group SID.
2282  *************************************************************************/
2283
2284 static NTSTATUS get_user_info_9(TALLOC_CTX *mem_ctx,
2285                                 struct samr_UserInfo9 *r,
2286                                 DOM_SID *user_sid)
2287 {
2288         struct samu *smbpass=NULL;
2289         bool ret;
2290
2291         ZERO_STRUCTP(r);
2292
2293         if ( !(smbpass = samu_new( mem_ctx )) ) {
2294                 return NT_STATUS_NO_MEMORY;
2295         }
2296
2297         become_root();
2298         ret = pdb_getsampwsid(smbpass, user_sid);
2299         unbecome_root();
2300
2301         if (ret==False) {
2302                 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
2303                 TALLOC_FREE(smbpass);
2304                 return NT_STATUS_NO_SUCH_USER;
2305         }
2306
2307         DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
2308
2309         init_samr_user_info9(r, pdb_get_group_rid(smbpass));
2310
2311         TALLOC_FREE(smbpass);
2312
2313         return NT_STATUS_OK;
2314 }
2315
2316 /*************************************************************************
2317  get_user_info_16. Safe. Only gives out acb bits.
2318  *************************************************************************/
2319
2320 static NTSTATUS get_user_info_16(TALLOC_CTX *mem_ctx,
2321                                  struct samr_UserInfo16 *r,
2322                                  DOM_SID *user_sid)
2323 {
2324         struct samu *smbpass=NULL;
2325         bool ret;
2326
2327         ZERO_STRUCTP(r);
2328
2329         if ( !(smbpass = samu_new( mem_ctx )) ) {
2330                 return NT_STATUS_NO_MEMORY;
2331         }
2332
2333         become_root();
2334         ret = pdb_getsampwsid(smbpass, user_sid);
2335         unbecome_root();
2336
2337         if (ret==False) {
2338                 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
2339                 TALLOC_FREE(smbpass);
2340                 return NT_STATUS_NO_SUCH_USER;
2341         }
2342
2343         DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
2344
2345         init_samr_user_info16(r, pdb_get_acct_ctrl(smbpass));
2346
2347         TALLOC_FREE(smbpass);
2348
2349         return NT_STATUS_OK;
2350 }
2351
2352 /*************************************************************************
2353  get_user_info_18. OK - this is the killer as it gives out password info.
2354  Ensure that this is only allowed on an encrypted connection with a root
2355  user. JRA.
2356  *************************************************************************/
2357
2358 static NTSTATUS get_user_info_18(pipes_struct *p,
2359                                  TALLOC_CTX *mem_ctx,
2360                                  struct samr_UserInfo18 *r,
2361                                  DOM_SID *user_sid)
2362 {
2363         struct samu *smbpass=NULL;
2364         bool ret;
2365
2366         ZERO_STRUCTP(r);
2367
2368         if (p->auth.auth_type != PIPE_AUTH_TYPE_NTLMSSP || p->auth.auth_type != PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) {
2369                 return NT_STATUS_ACCESS_DENIED;
2370         }
2371
2372         if (p->auth.auth_level != PIPE_AUTH_LEVEL_PRIVACY) {
2373                 return NT_STATUS_ACCESS_DENIED;
2374         }
2375
2376         /*
2377          * Do *NOT* do become_root()/unbecome_root() here ! JRA.
2378          */
2379
2380         if ( !(smbpass = samu_new( mem_ctx )) ) {
2381                 return NT_STATUS_NO_MEMORY;
2382         }
2383
2384         ret = pdb_getsampwsid(smbpass, user_sid);
2385
2386         if (ret == False) {
2387                 DEBUG(4, ("User %s not found\n", sid_string_dbg(user_sid)));
2388                 TALLOC_FREE(smbpass);
2389                 return (geteuid() == (uid_t)0) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
2390         }
2391
2392         DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
2393
2394         if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
2395                 TALLOC_FREE(smbpass);
2396                 return NT_STATUS_ACCOUNT_DISABLED;
2397         }
2398
2399         init_samr_user_info18(r, pdb_get_lanman_passwd(smbpass),
2400                               pdb_get_nt_passwd(smbpass));
2401
2402         TALLOC_FREE(smbpass);
2403
2404         return NT_STATUS_OK;
2405 }
2406
2407 /*************************************************************************
2408  get_user_info_20
2409  *************************************************************************/
2410
2411 static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx,
2412                                  struct samr_UserInfo20 *r,
2413                                  DOM_SID *user_sid)
2414 {
2415         struct samu *sampass=NULL;
2416         bool ret;
2417         const char *munged_dial = NULL;
2418         DATA_BLOB blob;
2419         NTSTATUS status;
2420         struct lsa_BinaryString *parameters = NULL;
2421
2422         ZERO_STRUCTP(r);
2423
2424         if ( !(sampass = samu_new( mem_ctx )) ) {
2425                 return NT_STATUS_NO_MEMORY;
2426         }
2427
2428         become_root();
2429         ret = pdb_getsampwsid(sampass, user_sid);
2430         unbecome_root();
2431
2432         if (ret == False) {
2433                 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
2434                 TALLOC_FREE(sampass);
2435                 return NT_STATUS_NO_SUCH_USER;
2436         }
2437
2438         munged_dial = pdb_get_munged_dial(sampass);
2439
2440         samr_clear_sam_passwd(sampass);
2441
2442         DEBUG(3,("User:[%s] has [%s] (length: %d)\n", pdb_get_username(sampass),
2443                 munged_dial, (int)strlen(munged_dial)));
2444
2445         if (munged_dial) {
2446                 blob = base64_decode_data_blob(munged_dial);
2447         } else {
2448                 blob = data_blob_string_const_null("");
2449         }
2450
2451         status = init_samr_parameters_string(mem_ctx, &blob, &parameters);
2452         data_blob_free(&blob);
2453         TALLOC_FREE(sampass);
2454         if (!NT_STATUS_IS_OK(status)) {
2455                 return status;
2456         }
2457
2458         init_samr_user_info20(r, parameters);
2459
2460         return NT_STATUS_OK;
2461 }
2462
2463
2464 /*************************************************************************
2465  get_user_info_21
2466  *************************************************************************/
2467
2468 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx,
2469                                  struct samr_UserInfo21 *r,
2470                                  DOM_SID *user_sid,
2471                                  DOM_SID *domain_sid)
2472 {
2473         NTSTATUS status;
2474         struct samu *pw = NULL;
2475         bool ret;
2476         const DOM_SID *sid_user, *sid_group;
2477         uint32_t rid, primary_gid;
2478         NTTIME last_logon, last_logoff, last_password_change,
2479                acct_expiry, allow_password_change, force_password_change;
2480         time_t must_change_time;
2481         uint8_t password_expired;
2482         const char *account_name, *full_name, *home_directory, *home_drive,
2483                    *logon_script, *profile_path, *description,
2484                    *workstations, *comment;
2485         struct samr_LogonHours logon_hours;
2486         struct lsa_BinaryString *parameters = NULL;
2487         const char *munged_dial = NULL;
2488         DATA_BLOB blob;
2489
2490         ZERO_STRUCTP(r);
2491
2492         if (!(pw = samu_new(mem_ctx))) {
2493                 return NT_STATUS_NO_MEMORY;
2494         }
2495
2496         become_root();
2497         ret = pdb_getsampwsid(pw, user_sid);
2498         unbecome_root();
2499
2500         if (ret == False) {
2501                 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
2502                 TALLOC_FREE(pw);
2503                 return NT_STATUS_NO_SUCH_USER;
2504         }
2505
2506         samr_clear_sam_passwd(pw);
2507
2508         DEBUG(3,("User:[%s]\n", pdb_get_username(pw)));
2509
2510         sid_user = pdb_get_user_sid(pw);
2511
2512         if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2513                 DEBUG(0, ("get_user_info_21: User %s has SID %s, \nwhich conflicts with "
2514                           "the domain sid %s.  Failing operation.\n",
2515                           pdb_get_username(pw), sid_string_dbg(sid_user),
2516                           sid_string_dbg(domain_sid)));
2517                 TALLOC_FREE(pw);
2518                 return NT_STATUS_UNSUCCESSFUL;
2519         }
2520
2521         become_root();
2522         sid_group = pdb_get_group_sid(pw);
2523         unbecome_root();
2524
2525         if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2526                 DEBUG(0, ("get_user_info_21: User %s has Primary Group SID %s, \n"
2527                           "which conflicts with the domain sid %s.  Failing operation.\n",
2528                           pdb_get_username(pw), sid_string_dbg(sid_group),
2529                           sid_string_dbg(domain_sid)));
2530                 TALLOC_FREE(pw);
2531                 return NT_STATUS_UNSUCCESSFUL;
2532         }
2533
2534         unix_to_nt_time(&last_logon, pdb_get_logon_time(pw));
2535         unix_to_nt_time(&last_logoff, pdb_get_logoff_time(pw));
2536         unix_to_nt_time(&acct_expiry, pdb_get_kickoff_time(pw));
2537         unix_to_nt_time(&last_password_change, pdb_get_pass_last_set_time(pw));
2538         unix_to_nt_time(&allow_password_change, pdb_get_pass_can_change_time(pw));
2539
2540         must_change_time = pdb_get_pass_must_change_time(pw);
2541         if (must_change_time == get_time_t_max()) {
2542                 unix_to_nt_time_abs(&force_password_change, must_change_time);
2543         } else {
2544                 unix_to_nt_time(&force_password_change, must_change_time);
2545         }
2546
2547         if (pdb_get_pass_must_change_time(pw) == 0) {
2548                 password_expired = PASS_MUST_CHANGE_AT_NEXT_LOGON;
2549         } else {
2550                 password_expired = 0;
2551         }
2552
2553         munged_dial = pdb_get_munged_dial(pw);
2554         if (munged_dial) {
2555                 blob = base64_decode_data_blob(munged_dial);
2556         } else {
2557                 blob = data_blob_string_const_null("");
2558         }
2559
2560         status = init_samr_parameters_string(mem_ctx, &blob, &parameters);
2561         data_blob_free(&blob);
2562         if (!NT_STATUS_IS_OK(status)) {
2563                 TALLOC_FREE(pw);
2564                 return status;
2565         }
2566
2567         account_name = talloc_strdup(mem_ctx, pdb_get_username(pw));
2568         full_name = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2569         home_directory = talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2570         home_drive = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2571         logon_script = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2572         profile_path = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2573         description = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2574         workstations = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2575         comment = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2576
2577         logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2578 #if 0
2579
2580         /*
2581           Look at a user on a real NT4 PDC with usrmgr, press
2582           'ok'. Then you will see that fields_present is set to
2583           0x08f827fa. Look at the user immediately after that again,
2584           and you will see that 0x00fffff is returned. This solves
2585           the problem that you get access denied after having looked
2586           at the user.
2587           -- Volker
2588         */
2589
2590 #endif
2591
2592         init_samr_user_info21(r,
2593                               last_logon,
2594                               last_logoff,
2595                               last_password_change,
2596                               acct_expiry,
2597                               allow_password_change,
2598                               force_password_change,
2599                               account_name,
2600                               full_name,
2601                               home_directory,
2602                               home_drive,
2603                               logon_script,
2604                               profile_path,
2605                               description,
2606                               workstations,
2607                               comment,
2608                               parameters,
2609                               rid,
2610                               primary_gid,
2611                               pdb_get_acct_ctrl(pw),
2612                               pdb_build_fields_present(pw),
2613                               logon_hours,
2614                               pdb_get_bad_password_count(pw),
2615                               pdb_get_logon_count(pw),
2616                               0, /* country_code */
2617                               0, /* code_page */
2618                               0, /* nt_password_set */
2619                               0, /* lm_password_set */
2620                               password_expired);
2621         TALLOC_FREE(pw);
2622
2623         return NT_STATUS_OK;
2624 }
2625
2626 /*******************************************************************
2627  _samr_QueryUserInfo
2628  ********************************************************************/
2629
2630 NTSTATUS _samr_QueryUserInfo(pipes_struct *p,
2631                              struct samr_QueryUserInfo *r)
2632 {
2633         NTSTATUS status;
2634         union samr_UserInfo *user_info = NULL;
2635         struct samr_info *info = NULL;
2636         DOM_SID domain_sid;
2637         uint32 rid;
2638
2639         /* search for the handle */
2640         if (!find_policy_by_hnd(p, r->in.user_handle, (void **)(void *)&info))
2641                 return NT_STATUS_INVALID_HANDLE;
2642
2643         status = access_check_samr_function(info->acc_granted,
2644                                             SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
2645                                             "_samr_QueryUserInfo");
2646         if (!NT_STATUS_IS_OK(status)) {
2647                 return status;
2648         }
2649
2650         domain_sid = info->sid;
2651
2652         sid_split_rid(&domain_sid, &rid);
2653
2654         if (!sid_check_is_in_our_domain(&info->sid))
2655                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2656
2657         DEBUG(5,("_samr_QueryUserInfo: sid:%s\n",
2658                  sid_string_dbg(&info->sid)));
2659
2660         user_info = TALLOC_ZERO_P(p->mem_ctx, union samr_UserInfo);
2661         if (!user_info) {
2662                 return NT_STATUS_NO_MEMORY;
2663         }
2664
2665         DEBUG(5,("_samr_QueryUserInfo: user info level: %d\n", r->in.level));
2666
2667         switch (r->in.level) {
2668         case 7:
2669                 status = get_user_info_7(p->mem_ctx, &user_info->info7, &info->sid);
2670                 if (!NT_STATUS_IS_OK(status)) {
2671                         return status;
2672                 }
2673                 break;
2674         case 9:
2675                 status = get_user_info_9(p->mem_ctx, &user_info->info9, &info->sid);
2676                 if (!NT_STATUS_IS_OK(status)) {
2677                         return status;
2678                 }
2679                 break;
2680         case 16:
2681                 status = get_user_info_16(p->mem_ctx, &user_info->info16, &info->sid);
2682                 if (!NT_STATUS_IS_OK(status)) {
2683                         return status;
2684                 }
2685                 break;
2686
2687         case 18:
2688                 status = get_user_info_18(p, p->mem_ctx, &user_info->info18, &info->sid);
2689                 if (!NT_STATUS_IS_OK(status)) {
2690                         return status;
2691                 }
2692                 break;
2693
2694         case 20:
2695                 status = get_user_info_20(p->mem_ctx, &user_info->info20, &info->sid);
2696                 if (!NT_STATUS_IS_OK(status)) {
2697                         return status;
2698                 }
2699                 break;
2700
2701         case 21:
2702                 status = get_user_info_21(p->mem_ctx, &user_info->info21,
2703                                           &info->sid, &domain_sid);
2704                 if (!NT_STATUS_IS_OK(status)) {
2705                         return status;
2706                 }
2707                 break;
2708
2709         default:
2710                 return NT_STATUS_INVALID_INFO_CLASS;
2711         }
2712
2713         *r->out.info = user_info;
2714
2715         DEBUG(5,("_samr_QueryUserInfo: %d\n", __LINE__));
2716
2717         return status;
2718 }
2719
2720 /*******************************************************************
2721  _samr_GetGroupsForUser
2722  ********************************************************************/
2723
2724 NTSTATUS _samr_GetGroupsForUser(pipes_struct *p,
2725                                 struct samr_GetGroupsForUser *r)
2726 {
2727         struct samu *sam_pass=NULL;
2728         DOM_SID  sid;
2729         DOM_SID *sids;
2730         struct samr_RidWithAttribute dom_gid;
2731         struct samr_RidWithAttribute *gids = NULL;
2732         uint32 primary_group_rid;
2733         size_t num_groups = 0;
2734         gid_t *unix_gids;
2735         size_t i, num_gids;
2736         uint32 acc_granted;
2737         bool ret;
2738         NTSTATUS result;
2739         bool success = False;
2740
2741         struct samr_RidWithAttributeArray *rids = NULL;
2742
2743         /*
2744          * from the SID in the request:
2745          * we should send back the list of DOMAIN GROUPS
2746          * the user is a member of
2747          *
2748          * and only the DOMAIN GROUPS
2749          * no ALIASES !!! neither aliases of the domain
2750          * nor aliases of the builtin SID
2751          *
2752          * JFM, 12/2/2001
2753          */
2754
2755         DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
2756
2757         rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidWithAttributeArray);
2758         if (!rids) {
2759                 return NT_STATUS_NO_MEMORY;
2760         }
2761
2762         /* find the policy handle.  open a policy on it. */
2763         if (!get_lsa_policy_samr_sid(p, r->in.user_handle, &sid, &acc_granted, NULL))
2764                 return NT_STATUS_INVALID_HANDLE;
2765
2766         result = access_check_samr_function(acc_granted,
2767                                             SAMR_USER_ACCESS_GET_GROUPS,
2768                                             "_samr_GetGroupsForUser");
2769         if (!NT_STATUS_IS_OK(result)) {
2770                 return result;
2771         }
2772
2773         if (!sid_check_is_in_our_domain(&sid))
2774                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2775
2776         if ( !(sam_pass = samu_new( p->mem_ctx )) ) {
2777                 return NT_STATUS_NO_MEMORY;
2778         }
2779
2780         become_root();
2781         ret = pdb_getsampwsid(sam_pass, &sid);
2782         unbecome_root();
2783
2784         if (!ret) {
2785                 DEBUG(10, ("pdb_getsampwsid failed for %s\n",
2786                            sid_string_dbg(&sid)));
2787                 return NT_STATUS_NO_SUCH_USER;
2788         }
2789
2790         sids = NULL;
2791
2792         /* make both calls inside the root block */
2793         become_root();
2794         result = pdb_enum_group_memberships(p->mem_ctx, sam_pass,
2795                                             &sids, &unix_gids, &num_groups);
2796         if ( NT_STATUS_IS_OK(result) ) {
2797                 success = sid_peek_check_rid(get_global_sam_sid(),
2798                                              pdb_get_group_sid(sam_pass),
2799                                              &primary_group_rid);
2800         }
2801         unbecome_root();
2802
2803         if (!NT_STATUS_IS_OK(result)) {
2804                 DEBUG(10, ("pdb_enum_group_memberships failed for %s\n",
2805                            sid_string_dbg(&sid)));
2806                 return result;
2807         }
2808
2809         if ( !success ) {
2810                 DEBUG(5, ("Group sid %s for user %s not in our domain\n",
2811                           sid_string_dbg(pdb_get_group_sid(sam_pass)),
2812                           pdb_get_username(sam_pass)));
2813                 TALLOC_FREE(sam_pass);
2814                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2815         }
2816
2817         gids = NULL;
2818         num_gids = 0;
2819
2820         dom_gid.attributes = (SE_GROUP_MANDATORY|SE_GROUP_ENABLED_BY_DEFAULT|
2821                               SE_GROUP_ENABLED);
2822         dom_gid.rid = primary_group_rid;
2823         ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
2824
2825         for (i=0; i<num_groups; i++) {
2826
2827                 if (!sid_peek_check_rid(get_global_sam_sid(),
2828                                         &(sids[i]), &dom_gid.rid)) {
2829                         DEBUG(10, ("Found sid %s not in our domain\n",
2830                                    sid_string_dbg(&sids[i])));
2831                         continue;
2832                 }
2833
2834                 if (dom_gid.rid == primary_group_rid) {
2835                         /* We added the primary group directly from the
2836                          * sam_account. The other SIDs are unique from
2837                          * enum_group_memberships */
2838                         continue;
2839                 }
2840
2841                 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
2842         }
2843
2844         rids->count = num_gids;
2845         rids->rids = gids;
2846
2847         *r->out.rids = rids;
2848
2849         DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
2850
2851         return result;
2852 }
2853
2854 /*******************************************************************
2855  _samr_QueryDomainInfo
2856  ********************************************************************/
2857
2858 NTSTATUS _samr_QueryDomainInfo(pipes_struct *p,
2859                                struct samr_QueryDomainInfo *r)
2860 {
2861         NTSTATUS status = NT_STATUS_OK;
2862         struct samr_info *info = NULL;
2863         union samr_DomainInfo *dom_info;
2864         uint32 min_pass_len,pass_hist,password_properties;
2865         time_t u_expire, u_min_age;
2866         NTTIME nt_expire, nt_min_age;
2867
2868         time_t u_lock_duration, u_reset_time;
2869         NTTIME nt_lock_duration, nt_reset_time;
2870         uint32 lockout;
2871         time_t u_logout;
2872         NTTIME nt_logout;
2873
2874         uint32 account_policy_temp;
2875
2876         time_t seq_num;
2877         uint32 server_role;
2878
2879         uint32 num_users=0, num_groups=0, num_aliases=0;
2880
2881         DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__));
2882
2883         dom_info = TALLOC_ZERO_P(p->mem_ctx, union samr_DomainInfo);
2884         if (!dom_info) {
2885                 return NT_STATUS_NO_MEMORY;
2886         }
2887
2888         /* find the policy handle.  open a policy on it. */
2889         if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info)) {
2890                 return NT_STATUS_INVALID_HANDLE;
2891         }
2892
2893         status = access_check_samr_function(info->acc_granted,
2894                                             SAMR_ACCESS_OPEN_DOMAIN,
2895                                             "_samr_QueryDomainInfo" );
2896
2897         if ( !NT_STATUS_IS_OK(status) )
2898                 return status;
2899
2900         switch (r->in.level) {
2901                 case 0x01:
2902
2903                         become_root();
2904
2905                         /* AS ROOT !!! */
2906
2907                         pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &account_policy_temp);
2908                         min_pass_len = account_policy_temp;
2909
2910                         pdb_get_account_policy(AP_PASSWORD_HISTORY, &account_policy_temp);
2911                         pass_hist = account_policy_temp;
2912
2913                         pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
2914                         password_properties = account_policy_temp;
2915
2916                         pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
2917                         u_expire = account_policy_temp;
2918
2919                         pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
2920                         u_min_age = account_policy_temp;
2921
2922                         /* !AS ROOT */
2923
2924                         unbecome_root();
2925
2926                         unix_to_nt_time_abs(&nt_expire, u_expire);
2927                         unix_to_nt_time_abs(&nt_min_age, u_min_age);
2928
2929                         if (lp_check_password_script() && *lp_check_password_script()) {
2930                                 password_properties |= DOMAIN_PASSWORD_COMPLEX;
2931                         }
2932
2933                         init_samr_DomInfo1(&dom_info->info1,
2934                                            (uint16)min_pass_len,
2935                                            (uint16)pass_hist,
2936                                            password_properties,
2937                                            nt_expire,
2938                                            nt_min_age);
2939                         break;
2940                 case 0x02:
2941
2942                         become_root();
2943
2944                         /* AS ROOT !!! */
2945
2946                         num_users = count_sam_users(info->disp_info, ACB_NORMAL);
2947                         num_groups = count_sam_groups(info->disp_info);
2948                         num_aliases = count_sam_aliases(info->disp_info);
2949
2950                         pdb_get_account_policy(AP_TIME_TO_LOGOUT, &account_policy_temp);
2951                         u_logout = account_policy_temp;
2952
2953                         unix_to_nt_time_abs(&nt_logout, u_logout);
2954
2955                         if (!pdb_get_seq_num(&seq_num))
2956                                 seq_num = time(NULL);
2957
2958                         /* !AS ROOT */
2959
2960                         unbecome_root();
2961
2962                         server_role = ROLE_DOMAIN_PDC;
2963                         if (lp_server_role() == ROLE_DOMAIN_BDC)
2964                                 server_role = ROLE_DOMAIN_BDC;
2965
2966                         init_samr_DomGeneralInformation(&dom_info->general,
2967                                                         nt_logout,
2968                                                         lp_serverstring(),
2969                                                         lp_workgroup(),
2970                                                         global_myname(),
2971                                                         seq_num,
2972                                                         1,
2973                                                         server_role,
2974                                                         1,
2975                                                         num_users,
2976                                                         num_groups,
2977                                                         num_aliases);
2978                         break;
2979                 case 0x03:
2980
2981                         become_root();
2982
2983                         /* AS ROOT !!! */
2984
2985                         {
2986                                 uint32 ul;
2987                                 pdb_get_account_policy(AP_TIME_TO_LOGOUT, &ul);
2988                                 u_logout = (time_t)ul;
2989                         }
2990
2991                         /* !AS ROOT */
2992
2993                         unbecome_root();
2994
2995                         unix_to_nt_time_abs(&nt_logout, u_logout);
2996
2997                         init_samr_DomInfo3(&dom_info->info3,
2998                                            nt_logout);
2999
3000                         break;
3001                 case 0x04:
3002                         init_samr_DomOEMInformation(&dom_info->oem,
3003                                                     lp_serverstring());
3004                         break;
3005                 case 0x05:
3006                         init_samr_DomInfo5(&dom_info->info5,
3007                                            get_global_sam_name());
3008                         break;
3009                 case 0x06:
3010                         /* NT returns its own name when a PDC. win2k and later
3011                          * only the name of the PDC if itself is a BDC (samba4
3012                          * idl) */
3013                         init_samr_DomInfo6(&dom_info->info6,
3014                                            global_myname());
3015                         break;
3016                 case 0x07:
3017                         server_role = ROLE_DOMAIN_PDC;
3018                         if (lp_server_role() == ROLE_DOMAIN_BDC)
3019                                 server_role = ROLE_DOMAIN_BDC;
3020
3021                         init_samr_DomInfo7(&dom_info->info7,
3022                                            server_role);
3023                         break;
3024                 case 0x08:
3025
3026                         become_root();
3027
3028                         /* AS ROOT !!! */
3029
3030                         if (!pdb_get_seq_num(&seq_num)) {
3031                                 seq_num = time(NULL);
3032                         }
3033
3034                         /* !AS ROOT */
3035
3036                         unbecome_root();
3037
3038                         init_samr_DomInfo8(&dom_info->info8,
3039                                            seq_num,
3040                                            0);
3041                         break;
3042                 case 0x0c:
3043
3044                         become_root();
3045
3046                         /* AS ROOT !!! */
3047
3048                         pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
3049                         u_lock_duration = account_policy_temp;
3050                         if (u_lock_duration != -1) {
3051                                 u_lock_duration *= 60;
3052                         }
3053
3054                         pdb_get_account_policy(AP_RESET_COUNT_TIME, &account_policy_temp);
3055                         u_reset_time = account_policy_temp * 60;
3056
3057                         pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
3058                         lockout = account_policy_temp;
3059
3060                         /* !AS ROOT */
3061
3062                         unbecome_root();
3063
3064                         unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
3065                         unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
3066
3067                         init_samr_DomInfo12(&dom_info->info12,
3068                                             nt_lock_duration,
3069                                             nt_reset_time,
3070                                             (uint16)lockout);
3071                         break;
3072                 default:
3073                         return NT_STATUS_INVALID_INFO_CLASS;
3074         }
3075
3076         *r->out.info = dom_info;
3077
3078         DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__));
3079
3080         return status;
3081 }
3082
3083 /* W2k3 seems to use the same check for all 3 objects that can be created via
3084  * SAMR, if you try to create for example "Dialup" as an alias it says
3085  * "NT_STATUS_USER_EXISTS". This is racy, but we can't really lock the user
3086  * database. */
3087
3088 static NTSTATUS can_create(TALLOC_CTX *mem_ctx, const char *new_name)
3089 {
3090         enum lsa_SidType type;
3091         bool result;
3092
3093         DEBUG(10, ("Checking whether [%s] can be created\n", new_name));
3094
3095         become_root();
3096         /* Lookup in our local databases (LOOKUP_NAME_REMOTE not set)
3097          * whether the name already exists */
3098         result = lookup_name(mem_ctx, new_name, LOOKUP_NAME_LOCAL,
3099                              NULL, NULL, NULL, &type);
3100         unbecome_root();
3101
3102         if (!result) {
3103                 DEBUG(10, ("%s does not exist, can create it\n", new_name));
3104                 return NT_STATUS_OK;
3105         }
3106
3107         DEBUG(5, ("trying to create %s, exists as %s\n",
3108                   new_name, sid_type_lookup(type)));
3109
3110         if (type == SID_NAME_DOM_GRP) {
3111                 return NT_STATUS_GROUP_EXISTS;
3112         }
3113         if (type == SID_NAME_ALIAS) {
3114                 return NT_STATUS_ALIAS_EXISTS;
3115         }
3116
3117         /* Yes, the default is NT_STATUS_USER_EXISTS */
3118         return NT_STATUS_USER_EXISTS;
3119 }
3120
3121 /*******************************************************************
3122  _samr_CreateUser2
3123  ********************************************************************/
3124
3125 NTSTATUS _samr_CreateUser2(pipes_struct *p,
3126                            struct samr_CreateUser2 *r)
3127 {
3128         const char *account = NULL;
3129         DOM_SID sid;
3130         POLICY_HND dom_pol = *r->in.domain_handle;
3131         uint32_t acb_info = r->in.acct_flags;
3132         POLICY_HND *user_pol = r->out.user_handle;
3133         struct samr_info *info = NULL;
3134         NTSTATUS nt_status;
3135         uint32 acc_granted;
3136         SEC_DESC *psd;
3137         size_t    sd_size;
3138         /* check this, when giving away 'add computer to domain' privs */
3139         uint32    des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
3140         bool can_add_account = False;
3141         SE_PRIV se_rights;
3142         DISP_INFO *disp_info = NULL;
3143
3144         /* Get the domain SID stored in the domain policy */
3145         if (!get_lsa_policy_samr_sid(p, &dom_pol, &sid, &acc_granted,
3146                                      &disp_info))
3147                 return NT_STATUS_INVALID_HANDLE;
3148
3149         nt_status = access_check_samr_function(acc_granted,
3150                                                SAMR_DOMAIN_ACCESS_CREATE_USER,
3151                                                "_samr_CreateUser2");
3152         if (!NT_STATUS_IS_OK(nt_status)) {
3153                 return nt_status;
3154         }
3155
3156         if (!(acb_info == ACB_NORMAL || acb_info == ACB_DOMTRUST ||
3157               acb_info == ACB_WSTRUST || acb_info == ACB_SVRTRUST)) {
3158                 /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if
3159                    this parameter is not an account type */
3160                 return NT_STATUS_INVALID_PARAMETER;
3161         }
3162
3163         account = r->in.account_name->string;
3164         if (account == NULL) {
3165                 return NT_STATUS_NO_MEMORY;
3166         }
3167
3168         nt_status = can_create(p->mem_ctx, account);
3169         if (!NT_STATUS_IS_OK(nt_status)) {
3170                 return nt_status;
3171         }
3172
3173         /* determine which user right we need to check based on the acb_info */
3174
3175         if ( acb_info & ACB_WSTRUST )
3176         {
3177                 se_priv_copy( &se_rights, &se_machine_account );
3178                 can_add_account = user_has_privileges(
3179                         p->pipe_user.nt_user_token, &se_rights );
3180         }
3181         /* usrmgr.exe (and net rpc trustdom grant) creates a normal user
3182            account for domain trusts and changes the ACB flags later */
3183         else if ( acb_info & ACB_NORMAL &&
3184                   (account[strlen(account)-1] != '$') )
3185         {
3186                 se_priv_copy( &se_rights, &se_add_users );
3187                 can_add_account = user_has_privileges(
3188                         p->pipe_user.nt_user_token, &se_rights );
3189         }
3190         else    /* implicit assumption of a BDC or domain trust account here
3191                  * (we already check the flags earlier) */
3192         {
3193                 if ( lp_enable_privileges() ) {
3194                         /* only Domain Admins can add a BDC or domain trust */
3195                         se_priv_copy( &se_rights, &se_priv_none );
3196                         can_add_account = nt_token_check_domain_rid(
3197                                 p->pipe_user.nt_user_token,
3198                                 DOMAIN_GROUP_RID_ADMINS );
3199                 }
3200         }
3201
3202         DEBUG(5, ("_samr_CreateUser2: %s can add this account : %s\n",
3203                   uidtoname(p->pipe_user.ut.uid),
3204                   can_add_account ? "True":"False" ));
3205
3206         /********** BEGIN Admin BLOCK **********/
3207
3208         if ( can_add_account )
3209                 become_root();
3210
3211         nt_status = pdb_create_user(p->mem_ctx, account, acb_info,
3212                                     r->out.rid);
3213
3214         if ( can_add_account )
3215                 unbecome_root();
3216
3217         /********** END Admin BLOCK **********/
3218
3219         /* now check for failure */
3220
3221         if ( !NT_STATUS_IS_OK(nt_status) )
3222                 return nt_status;
3223
3224         /* Get the user's SID */
3225
3226         sid_compose(&sid, get_global_sam_sid(), *r->out.rid);
3227
3228         map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
3229
3230         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping,
3231                             &sid, SAMR_USR_RIGHTS_WRITE_PW);
3232         se_map_generic(&des_access, &usr_generic_mapping);
3233
3234         nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3235                 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
3236                 &acc_granted, "_samr_CreateUser2");
3237
3238         if ( !NT_STATUS_IS_OK(nt_status) ) {
3239                 return nt_status;
3240         }
3241
3242         /* associate the user's SID with the new handle. */
3243         if ((info = get_samr_info_by_sid(&sid)) == NULL) {
3244                 return NT_STATUS_NO_MEMORY;
3245         }
3246
3247         ZERO_STRUCTP(info);
3248         info->sid = sid;
3249         info->acc_granted = acc_granted;
3250
3251         /* get a (unique) handle.  open a policy on it. */
3252         if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info)) {
3253                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3254         }
3255
3256         /* After a "set" ensure we have no cached display info. */
3257         force_flush_samr_cache(info->disp_info);
3258
3259         *r->out.access_granted = acc_granted;
3260
3261         return NT_STATUS_OK;
3262 }
3263
3264 /*******************************************************************
3265  _samr_Connect
3266  ********************************************************************/
3267
3268 NTSTATUS _samr_Connect(pipes_struct *p,
3269                        struct samr_Connect *r)
3270 {
3271         struct samr_info *info = NULL;
3272         uint32    des_access = r->in.access_mask;
3273
3274         /* Access check */
3275
3276         if (!pipe_access_check(p)) {
3277                 DEBUG(3, ("access denied to _samr_Connect\n"));
3278                 return NT_STATUS_ACCESS_DENIED;
3279         }
3280
3281         /* set up the SAMR connect_anon response */
3282
3283         /* associate the user's SID with the new handle. */
3284         if ((info = get_samr_info_by_sid(NULL)) == NULL)
3285                 return NT_STATUS_NO_MEMORY;
3286
3287         /* don't give away the farm but this is probably ok.  The SAMR_ACCESS_ENUM_DOMAINS
3288            was observed from a win98 client trying to enumerate users (when configured
3289            user level access control on shares)   --jerry */
3290
3291         map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
3292
3293         se_map_generic( &des_access, &sam_generic_mapping );
3294         info->acc_granted = des_access & (SAMR_ACCESS_ENUM_DOMAINS|SAMR_ACCESS_OPEN_DOMAIN);
3295
3296         /* get a (unique) handle.  open a policy on it. */
3297         if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info))
3298                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3299
3300         return NT_STATUS_OK;
3301 }
3302
3303 /*******************************************************************
3304  _samr_Connect2
3305  ********************************************************************/
3306
3307 NTSTATUS _samr_Connect2(pipes_struct *p,
3308                         struct samr_Connect2 *r)
3309 {
3310         struct samr_info *info = NULL;
3311         SEC_DESC *psd = NULL;
3312         uint32    acc_granted;
3313         uint32    des_access = r->in.access_mask;
3314         NTSTATUS  nt_status;
3315         size_t    sd_size;
3316
3317
3318         DEBUG(5,("_samr_Connect2: %d\n", __LINE__));
3319
3320         /* Access check */
3321
3322         if (!pipe_access_check(p)) {
3323                 DEBUG(3, ("access denied to _samr_Connect2\n"));
3324                 return NT_STATUS_ACCESS_DENIED;
3325         }
3326
3327         map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
3328
3329         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
3330         se_map_generic(&des_access, &sam_generic_mapping);
3331
3332         nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3333                 NULL, 0, des_access, &acc_granted, "_samr_Connect2");
3334
3335         if ( !NT_STATUS_IS_OK(nt_status) )
3336                 return nt_status;
3337
3338         /* associate the user's SID and access granted with the new handle. */
3339         if ((info = get_samr_info_by_sid(NULL)) == NULL)
3340                 return NT_STATUS_NO_MEMORY;
3341
3342         info->acc_granted = acc_granted;
3343         info->status = r->in.access_mask; /* this looks so wrong... - gd */
3344
3345         /* get a (unique) handle.  open a policy on it. */
3346         if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info))
3347                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3348
3349         DEBUG(5,("_samr_Connect2: %d\n", __LINE__));
3350
3351         return nt_status;
3352 }
3353
3354 /*******************************************************************
3355  _samr_Connect4
3356  ********************************************************************/
3357
3358 NTSTATUS _samr_Connect4(pipes_struct *p,
3359                         struct samr_Connect4 *r)
3360 {
3361         struct samr_info *info = NULL;
3362         SEC_DESC *psd = NULL;
3363         uint32    acc_granted;
3364         uint32    des_access = r->in.access_mask;
3365         NTSTATUS  nt_status;
3366         size_t    sd_size;
3367
3368
3369         DEBUG(5,("_samr_Connect4: %d\n", __LINE__));
3370
3371         /* Access check */
3372
3373         if (!pipe_access_check(p)) {
3374                 DEBUG(3, ("access denied to samr_Connect4\n"));
3375                 return NT_STATUS_ACCESS_DENIED;
3376         }
3377
3378         map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
3379
3380         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
3381         se_map_generic(&des_access, &sam_generic_mapping);
3382
3383         nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3384                 NULL, 0, des_access, &acc_granted, "_samr_Connect4");
3385
3386         if ( !NT_STATUS_IS_OK(nt_status) )
3387                 return nt_status;
3388
3389         /* associate the user's SID and access granted with the new handle. */
3390         if ((info = get_samr_info_by_sid(NULL)) == NULL)
3391                 return NT_STATUS_NO_MEMORY;
3392
3393         info->acc_granted = acc_granted;
3394         info->status = r->in.access_mask; /* ??? */
3395
3396         /* get a (unique) handle.  open a policy on it. */
3397         if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info))
3398                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3399
3400         DEBUG(5,("_samr_Connect4: %d\n", __LINE__));
3401
3402         return NT_STATUS_OK;
3403 }
3404
3405 /*******************************************************************
3406  _samr_Connect5
3407  ********************************************************************/
3408
3409 NTSTATUS _samr_Connect5(pipes_struct *p,
3410                         struct samr_Connect5 *r)
3411 {
3412         struct samr_info *info = NULL;
3413         SEC_DESC *psd = NULL;
3414         uint32    acc_granted;
3415         uint32    des_access = r->in.access_mask;
3416         NTSTATUS  nt_status;
3417         size_t    sd_size;
3418         struct samr_ConnectInfo1 info1;
3419
3420         DEBUG(5,("_samr_Connect5: %d\n", __LINE__));
3421
3422         /* Access check */
3423
3424         if (!pipe_access_check(p)) {
3425                 DEBUG(3, ("access denied to samr_Connect5\n"));
3426                 return NT_STATUS_ACCESS_DENIED;
3427         }
3428
3429         map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
3430
3431         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
3432         se_map_generic(&des_access, &sam_generic_mapping);
3433
3434         nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3435                 NULL, 0, des_access, &acc_granted, "_samr_Connect5");
3436
3437         if ( !NT_STATUS_IS_OK(nt_status) )
3438                 return nt_status;
3439
3440         /* associate the user's SID and access granted with the new handle. */
3441         if ((info = get_samr_info_by_sid(NULL)) == NULL)
3442                 return NT_STATUS_NO_MEMORY;
3443
3444         info->acc_granted = acc_granted;
3445         info->status = r->in.access_mask; /* ??? */
3446
3447         /* get a (unique) handle.  open a policy on it. */
3448         if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info))
3449                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3450
3451         DEBUG(5,("_samr_Connect5: %d\n", __LINE__));
3452
3453         info1.client_version = SAMR_CONNECT_AFTER_W2K;
3454         info1.unknown2 = 0;
3455
3456         *r->out.level_out = 1;
3457         r->out.info_out->info1 = info1;
3458
3459         return NT_STATUS_OK;
3460 }
3461
3462 /**********************************************************************
3463  _samr_LookupDomain
3464  **********************************************************************/
3465
3466 NTSTATUS _samr_LookupDomain(pipes_struct *p,
3467                             struct samr_LookupDomain *r)
3468 {
3469         NTSTATUS status = NT_STATUS_OK;
3470         struct samr_info *info;
3471         const char *domain_name;
3472         DOM_SID *sid = NULL;
3473
3474         if (!find_policy_by_hnd(p, r->in.connect_handle, (void**)(void *)&info))
3475                 return NT_STATUS_INVALID_HANDLE;
3476
3477         /* win9x user manager likes to use SAMR_ACCESS_ENUM_DOMAINS here.
3478            Reverted that change so we will work with RAS servers again */
3479
3480         status = access_check_samr_function(info->acc_granted,
3481                                             SAMR_ACCESS_OPEN_DOMAIN,
3482                                             "_samr_LookupDomain");
3483         if (!NT_STATUS_IS_OK(status)) {
3484                 return status;
3485         }
3486
3487         domain_name = r->in.domain_name->string;
3488
3489         sid = TALLOC_ZERO_P(p->mem_ctx, struct dom_sid2);
3490         if (!sid) {
3491                 return NT_STATUS_NO_MEMORY;
3492         }
3493
3494         if (strequal(domain_name, builtin_domain_name())) {
3495                 sid_copy(sid, &global_sid_Builtin);
3496         } else {
3497                 if (!secrets_fetch_domain_sid(domain_name, sid)) {
3498                         status = NT_STATUS_NO_SUCH_DOMAIN;
3499                 }
3500         }
3501
3502         DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name,
3503                  sid_string_dbg(sid)));
3504
3505         *r->out.sid = sid;
3506
3507         return status;
3508 }
3509
3510 /**********************************************************************
3511  _samr_EnumDomains
3512  **********************************************************************/
3513
3514 NTSTATUS _samr_EnumDomains(pipes_struct *p,
3515                            struct samr_EnumDomains *r)
3516 {
3517         NTSTATUS status;
3518         struct samr_info *info;
3519         uint32_t num_entries = 2;
3520         struct samr_SamEntry *entry_array = NULL;
3521         struct samr_SamArray *sam;
3522
3523         if (!find_policy_by_hnd(p, r->in.connect_handle, (void**)(void *)&info))
3524                 return NT_STATUS_INVALID_HANDLE;
3525
3526         status = access_check_samr_function(info->acc_granted,
3527                                             SAMR_ACCESS_ENUM_DOMAINS,
3528                                             "_samr_EnumDomains");
3529         if (!NT_STATUS_IS_OK(status)) {
3530                 return status;
3531         }
3532
3533         sam = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
3534         if (!sam) {
3535                 return NT_STATUS_NO_MEMORY;
3536         }
3537
3538         entry_array = TALLOC_ZERO_ARRAY(p->mem_ctx,
3539                                         struct samr_SamEntry,
3540                                         num_entries);
3541         if (!entry_array) {
3542                 return NT_STATUS_NO_MEMORY;
3543         }
3544
3545         entry_array[0].idx = 0;
3546         init_lsa_String(&entry_array[0].name, get_global_sam_name());
3547
3548         entry_array[1].idx = 1;
3549         init_lsa_String(&entry_array[1].name, "Builtin");
3550
3551         sam->count = num_entries;
3552         sam->entries = entry_array;
3553
3554         *r->out.sam = sam;
3555         *r->out.num_entries = num_entries;
3556
3557         return status;
3558 }
3559
3560 /*******************************************************************
3561  _samr_OpenAlias
3562  ********************************************************************/
3563
3564 NTSTATUS _samr_OpenAlias(pipes_struct *p,
3565                          struct samr_OpenAlias *r)
3566 {
3567         DOM_SID sid;
3568         POLICY_HND domain_pol = *r->in.domain_handle;
3569         uint32 alias_rid = r->in.rid;
3570         POLICY_HND *alias_pol = r->out.alias_handle;
3571         struct    samr_info *info = NULL;
3572         SEC_DESC *psd = NULL;
3573         uint32    acc_granted;
3574         uint32    des_access = r->in.access_mask;
3575         size_t    sd_size;
3576         NTSTATUS  status;
3577         SE_PRIV se_rights;
3578
3579         /* find the domain policy and get the SID / access bits stored in the domain policy */
3580
3581         if ( !get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted, NULL) )
3582                 return NT_STATUS_INVALID_HANDLE;
3583
3584         status = access_check_samr_function(acc_granted,
3585                                             SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
3586                                             "_samr_OpenAlias");
3587
3588         if ( !NT_STATUS_IS_OK(status) )
3589                 return status;
3590
3591         /* append the alias' RID to it */
3592
3593         if (!sid_append_rid(&sid, alias_rid))
3594                 return NT_STATUS_NO_SUCH_ALIAS;
3595
3596         /*check if access can be granted as requested by client. */
3597
3598         map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
3599
3600         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &ali_generic_mapping, NULL, 0);
3601         se_map_generic(&des_access,&ali_generic_mapping);
3602
3603         se_priv_copy( &se_rights, &se_add_users );
3604
3605
3606         status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3607                 &se_rights, GENERIC_RIGHTS_ALIAS_WRITE, des_access,
3608                 &acc_granted, "_samr_OpenAlias");
3609
3610         if ( !NT_STATUS_IS_OK(status) )
3611                 return status;
3612
3613         {
3614                 /* Check we actually have the requested alias */
3615                 enum lsa_SidType type;
3616                 bool result;
3617                 gid_t gid;
3618
3619                 become_root();
3620                 result = lookup_sid(NULL, &sid, NULL, NULL, &type);
3621                 unbecome_root();
3622
3623                 if (!result || (type != SID_NAME_ALIAS)) {
3624                         return NT_STATUS_NO_SUCH_ALIAS;
3625                 }
3626
3627                 /* make sure there is a mapping */
3628
3629                 if ( !sid_to_gid( &sid, &gid ) ) {
3630                         return NT_STATUS_NO_SUCH_ALIAS;
3631                 }
3632
3633         }
3634
3635         /* associate the alias SID with the new handle. */
3636         if ((info = get_samr_info_by_sid(&sid)) == NULL)
3637                 return NT_STATUS_NO_MEMORY;
3638
3639         info->acc_granted = acc_granted;
3640
3641         /* get a (unique) handle.  open a policy on it. */
3642         if (!create_policy_hnd(p, alias_pol, free_samr_info, (void *)info))
3643                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3644
3645         return NT_STATUS_OK;
3646 }
3647
3648 /*******************************************************************
3649  set_user_info_7
3650  ********************************************************************/
3651
3652 static NTSTATUS set_user_info_7(TALLOC_CTX *mem_ctx,
3653                                 struct samr_UserInfo7 *id7,
3654                                 struct samu *pwd)
3655 {
3656         NTSTATUS rc;
3657
3658         if (id7 == NULL) {
3659                 DEBUG(5, ("set_user_info_7: NULL id7\n"));
3660                 TALLOC_FREE(pwd);
3661                 return NT_STATUS_ACCESS_DENIED;
3662         }
3663
3664         if (!id7->account_name.string) {
3665                 DEBUG(5, ("set_user_info_7: failed to get new username\n"));
3666                 TALLOC_FREE(pwd);
3667                 return NT_STATUS_ACCESS_DENIED;
3668         }
3669
3670         /* check to see if the new username already exists.  Note: we can't
3671            reliably lock all backends, so there is potentially the
3672            possibility that a user can be created in between this check and
3673            the rename.  The rename should fail, but may not get the
3674            exact same failure status code.  I think this is small enough
3675            of a window for this type of operation and the results are
3676            simply that the rename fails with a slightly different status
3677            code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
3678
3679         rc = can_create(mem_ctx, id7->account_name.string);
3680         if (!NT_STATUS_IS_OK(rc)) {
3681                 return rc;
3682         }
3683
3684         rc = pdb_rename_sam_account(pwd, id7->account_name.string);
3685
3686         TALLOC_FREE(pwd);
3687         return rc;
3688 }
3689
3690 /*******************************************************************
3691  set_user_info_16
3692  ********************************************************************/
3693
3694 static bool set_user_info_16(struct samr_UserInfo16 *id16,
3695                              struct samu *pwd)
3696 {
3697         if (id16 == NULL) {
3698                 DEBUG(5, ("set_user_info_16: NULL id16\n"));
3699                 TALLOC_FREE(pwd);
3700                 return False;
3701         }
3702
3703         /* FIX ME: check if the value is really changed --metze */
3704         if (!pdb_set_acct_ctrl(pwd, id16->acct_flags, PDB_CHANGED)) {
3705                 TALLOC_FREE(pwd);
3706                 return False;
3707         }
3708
3709         if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3710                 TALLOC_FREE(pwd);
3711                 return False;
3712         }
3713
3714         TALLOC_FREE(pwd);
3715
3716         return True;
3717 }
3718
3719 /*******************************************************************
3720  set_user_info_18
3721  ********************************************************************/
3722
3723 static bool set_user_info_18(struct samr_UserInfo18 *id18,
3724                              struct samu *pwd)
3725 {
3726         if (id18 == NULL) {
3727                 DEBUG(2, ("set_user_info_18: id18 is NULL\n"));
3728                 TALLOC_FREE(pwd);
3729                 return False;
3730         }
3731
3732         if (!pdb_set_lanman_passwd (pwd, id18->lm_pwd.hash, PDB_CHANGED)) {
3733                 TALLOC_FREE(pwd);
3734                 return False;
3735         }
3736         if (!pdb_set_nt_passwd     (pwd, id18->nt_pwd.hash, PDB_CHANGED)) {
3737                 TALLOC_FREE(pwd);
3738                 return False;
3739         }
3740         if (!pdb_set_pass_last_set_time (pwd, time(NULL), PDB_CHANGED)) {
3741                 TALLOC_FREE(pwd);
3742                 return False;
3743         }
3744
3745         if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3746                 TALLOC_FREE(pwd);
3747                 return False;