s3-samr: fix samr callers of samr_UserInfo18.
[samba.git] / source / rpc_server / srv_samr_nt.c
1 /*
2  *  Unix SMB/CIFS implementation.
3  *  RPC Pipe client / server routines
4  *  Copyright (C) Andrew Tridgell                   1992-1997,
5  *  Copyright (C) Luke Kenneth Casson Leighton      1996-1997,
6  *  Copyright (C) Paul Ashton                       1997,
7  *  Copyright (C) Marc Jacobsen                     1999,
8  *  Copyright (C) Jeremy Allison                    2001-2008,
9  *  Copyright (C) Jean François Micouleau           1998-2001,
10  *  Copyright (C) Jim McDonough <jmcd@us.ibm.com>   2002,
11  *  Copyright (C) Gerald (Jerry) Carter             2003-2004,
12  *  Copyright (C) Simo Sorce                        2003.
13  *  Copyright (C) Volker Lendecke                   2005.
14  *  Copyright (C) Guenther Deschner                 2008.
15  *
16  *  This program is free software; you can redistribute it and/or modify
17  *  it under the terms of the GNU General Public License as published by
18  *  the Free Software Foundation; either version 3 of the License, or
19  *  (at your option) any later version.
20  *
21  *  This program is distributed in the hope that it will be useful,
22  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
23  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24  *  GNU General Public License for more details.
25  *
26  *  You should have received a copy of the GNU General Public License
27  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
28  */
29
30 /*
31  * This is the implementation of the SAMR code.
32  */
33
34 #include "includes.h"
35
36 #undef DBGC_CLASS
37 #define DBGC_CLASS DBGC_RPC_SRV
38
39 #define SAMR_USR_RIGHTS_WRITE_PW \
40                 ( READ_CONTROL_ACCESS           | \
41                   SAMR_USER_ACCESS_CHANGE_PASSWORD      | \
42                   SAMR_USER_ACCESS_SET_LOC_COM)
43 #define SAMR_USR_RIGHTS_CANT_WRITE_PW \
44                 ( READ_CONTROL_ACCESS | SAMR_USER_ACCESS_SET_LOC_COM )
45
46 #define DISP_INFO_CACHE_TIMEOUT 10
47
48 typedef struct disp_info {
49         DOM_SID sid; /* identify which domain this is. */
50         bool builtin_domain; /* Quick flag to check if this is the builtin domain. */
51         struct pdb_search *users; /* querydispinfo 1 and 4 */
52         struct pdb_search *machines; /* querydispinfo 2 */
53         struct pdb_search *groups; /* querydispinfo 3 and 5, enumgroups */
54         struct pdb_search *aliases; /* enumaliases */
55
56         uint16 enum_acb_mask;
57         struct pdb_search *enum_users; /* enumusers with a mask */
58
59         struct timed_event *cache_timeout_event; /* cache idle timeout
60                                                   * handler. */
61 } DISP_INFO;
62
63 /* We keep a static list of these by SID as modern clients close down
64    all resources between each request in a complete enumeration. */
65
66 struct samr_info {
67         /* for use by the \PIPE\samr policy */
68         DOM_SID sid;
69         bool builtin_domain; /* Quick flag to check if this is the builtin domain. */
70         uint32 status; /* some sort of flag.  best to record it.  comes from opnum 0x39 */
71         uint32 acc_granted;
72         DISP_INFO *disp_info;
73         TALLOC_CTX *mem_ctx;
74 };
75
76 static const struct generic_mapping sam_generic_mapping = {
77         GENERIC_RIGHTS_SAM_READ,
78         GENERIC_RIGHTS_SAM_WRITE,
79         GENERIC_RIGHTS_SAM_EXECUTE,
80         GENERIC_RIGHTS_SAM_ALL_ACCESS};
81 static const struct generic_mapping dom_generic_mapping = {
82         GENERIC_RIGHTS_DOMAIN_READ,
83         GENERIC_RIGHTS_DOMAIN_WRITE,
84         GENERIC_RIGHTS_DOMAIN_EXECUTE,
85         GENERIC_RIGHTS_DOMAIN_ALL_ACCESS};
86 static const struct generic_mapping usr_generic_mapping = {
87         GENERIC_RIGHTS_USER_READ,
88         GENERIC_RIGHTS_USER_WRITE,
89         GENERIC_RIGHTS_USER_EXECUTE,
90         GENERIC_RIGHTS_USER_ALL_ACCESS};
91 static const struct generic_mapping usr_nopwchange_generic_mapping = {
92         GENERIC_RIGHTS_USER_READ,
93         GENERIC_RIGHTS_USER_WRITE,
94         GENERIC_RIGHTS_USER_EXECUTE & ~SAMR_USER_ACCESS_CHANGE_PASSWORD,
95         GENERIC_RIGHTS_USER_ALL_ACCESS};
96 static const struct generic_mapping grp_generic_mapping = {
97         GENERIC_RIGHTS_GROUP_READ,
98         GENERIC_RIGHTS_GROUP_WRITE,
99         GENERIC_RIGHTS_GROUP_EXECUTE,
100         GENERIC_RIGHTS_GROUP_ALL_ACCESS};
101 static const struct generic_mapping ali_generic_mapping = {
102         GENERIC_RIGHTS_ALIAS_READ,
103         GENERIC_RIGHTS_ALIAS_WRITE,
104         GENERIC_RIGHTS_ALIAS_EXECUTE,
105         GENERIC_RIGHTS_ALIAS_ALL_ACCESS};
106
107 /*******************************************************************
108 *******************************************************************/
109
110 static NTSTATUS make_samr_object_sd( TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size,
111                                      const struct generic_mapping *map,
112                                      DOM_SID *sid, uint32 sid_access )
113 {
114         DOM_SID domadmin_sid;
115         SEC_ACE ace[5];         /* at most 5 entries */
116         size_t i = 0;
117
118         SEC_ACL *psa = NULL;
119
120         /* basic access for Everyone */
121
122         init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
123                         map->generic_execute | map->generic_read, 0);
124
125         /* add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
126
127         init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
128                         SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
129         init_sec_ace(&ace[i++], &global_sid_Builtin_Account_Operators,
130                         SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
131
132         /* Add Full Access for Domain Admins if we are a DC */
133
134         if ( IS_DC ) {
135                 sid_copy( &domadmin_sid, get_global_sam_sid() );
136                 sid_append_rid( &domadmin_sid, DOMAIN_GROUP_RID_ADMINS );
137                 init_sec_ace(&ace[i++], &domadmin_sid,
138                         SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
139         }
140
141         /* if we have a sid, give it some special access */
142
143         if ( sid ) {
144                 init_sec_ace(&ace[i++], sid, SEC_ACE_TYPE_ACCESS_ALLOWED, sid_access, 0);
145         }
146
147         /* create the security descriptor */
148
149         if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) == NULL)
150                 return NT_STATUS_NO_MEMORY;
151
152         if ((*psd = make_sec_desc(ctx, SECURITY_DESCRIPTOR_REVISION_1,
153                                   SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL,
154                                   psa, sd_size)) == NULL)
155                 return NT_STATUS_NO_MEMORY;
156
157         return NT_STATUS_OK;
158 }
159
160 /*******************************************************************
161  Checks if access to an object should be granted, and returns that
162  level of access for further checks.
163 ********************************************************************/
164
165 static NTSTATUS access_check_samr_object( SEC_DESC *psd, NT_USER_TOKEN *token,
166                                           SE_PRIV *rights, uint32 rights_mask,
167                                           uint32 des_access, uint32 *acc_granted,
168                                           const char *debug )
169 {
170         NTSTATUS status = NT_STATUS_ACCESS_DENIED;
171         uint32 saved_mask = 0;
172
173         /* check privileges; certain SAM access bits should be overridden
174            by privileges (mostly having to do with creating/modifying/deleting
175            users and groups) */
176
177         if ( rights && user_has_any_privilege( token, rights ) ) {
178
179                 saved_mask = (des_access & rights_mask);
180                 des_access &= ~saved_mask;
181
182                 DEBUG(4,("access_check_samr_object: user rights access mask [0x%x]\n",
183                         rights_mask));
184         }
185
186
187         /* check the security descriptor first */
188
189         status = se_access_check(psd, token, des_access, acc_granted);
190         if (NT_STATUS_IS_OK(status)) {
191                 goto done;
192         }
193
194         /* give root a free pass */
195
196         if ( geteuid() == sec_initial_uid() ) {
197
198                 DEBUG(4,("%s: ACCESS should be DENIED  (requested: %#010x)\n", debug, des_access));
199                 DEBUGADD(4,("but overritten by euid == sec_initial_uid()\n"));
200
201                 *acc_granted = des_access;
202
203                 status = NT_STATUS_OK;
204                 goto done;
205         }
206
207
208 done:
209         /* add in any bits saved during the privilege check (only
210            matters is status is ok) */
211
212         *acc_granted |= rights_mask;
213
214         DEBUG(4,("%s: access %s (requested: 0x%08x, granted: 0x%08x)\n",
215                 debug, NT_STATUS_IS_OK(status) ? "GRANTED" : "DENIED",
216                 des_access, *acc_granted));
217
218         return status;
219 }
220
221 /*******************************************************************
222  Checks if access to a function can be granted
223 ********************************************************************/
224
225 static NTSTATUS access_check_samr_function(uint32 acc_granted, uint32 acc_required, const char *debug)
226 {
227         DEBUG(5,("%s: access check ((granted: %#010x;  required: %#010x)\n",
228                 debug, acc_granted, acc_required));
229
230         /* check the security descriptor first */
231
232         if ( (acc_granted&acc_required) == acc_required )
233                 return NT_STATUS_OK;
234
235         /* give root a free pass */
236
237         if (geteuid() == sec_initial_uid()) {
238
239                 DEBUG(4,("%s: ACCESS should be DENIED (granted: %#010x;  required: %#010x)\n",
240                         debug, acc_granted, acc_required));
241                 DEBUGADD(4,("but overwritten by euid == 0\n"));
242
243                 return NT_STATUS_OK;
244         }
245
246         DEBUG(2,("%s: ACCESS DENIED (granted: %#010x;  required: %#010x)\n",
247                 debug, acc_granted, acc_required));
248
249         return NT_STATUS_ACCESS_DENIED;
250 }
251
252 /*******************************************************************
253  Map any MAXIMUM_ALLOWED_ACCESS request to a valid access set.
254 ********************************************************************/
255
256 static void map_max_allowed_access(const NT_USER_TOKEN *token,
257                                         uint32_t *pacc_requested)
258 {
259         if (!((*pacc_requested) & MAXIMUM_ALLOWED_ACCESS)) {
260                 return;
261         }
262         *pacc_requested &= ~MAXIMUM_ALLOWED_ACCESS;
263
264         /* At least try for generic read. */
265         *pacc_requested = GENERIC_READ_ACCESS;
266
267         /* root gets anything. */
268         if (geteuid() == sec_initial_uid()) {
269                 *pacc_requested |= GENERIC_ALL_ACCESS;
270                 return;
271         }
272
273         /* Full Access for 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
274
275         if (is_sid_in_token(token, &global_sid_Builtin_Administrators) ||
276                         is_sid_in_token(token, &global_sid_Builtin_Account_Operators)) {
277                 *pacc_requested |= GENERIC_ALL_ACCESS;
278                 return;
279         }
280
281         /* Full access for DOMAIN\Domain Admins. */
282         if ( IS_DC ) {
283                 DOM_SID domadmin_sid;
284                 sid_copy( &domadmin_sid, get_global_sam_sid() );
285                 sid_append_rid( &domadmin_sid, DOMAIN_GROUP_RID_ADMINS );
286                 if (is_sid_in_token(token, &domadmin_sid)) {
287                         *pacc_requested |= GENERIC_ALL_ACCESS;
288                         return;
289                 }
290         }
291         /* TODO ! Check privileges. */
292 }
293
294 /*******************************************************************
295  Fetch or create a dispinfo struct.
296 ********************************************************************/
297
298 static DISP_INFO *get_samr_dispinfo_by_sid(DOM_SID *psid)
299 {
300         /*
301          * We do a static cache for DISP_INFO's here. Explanation can be found
302          * in Jeremy's checkin message to r11793:
303          *
304          * Fix the SAMR cache so it works across completely insane
305          * client behaviour (ie.:
306          * open pipe/open SAMR handle/enumerate 0 - 1024
307          * close SAMR handle, close pipe.
308          * open pipe/open SAMR handle/enumerate 1024 - 2048...
309          * close SAMR handle, close pipe.
310          * And on ad-nausium. Amazing.... probably object-oriented
311          * client side programming in action yet again.
312          * This change should *massively* improve performance when
313          * enumerating users from an LDAP database.
314          * Jeremy.
315          *
316          * "Our" and the builtin domain are the only ones where we ever
317          * enumerate stuff, so just cache 2 entries.
318          */
319
320         static struct disp_info builtin_dispinfo;
321         static struct disp_info domain_dispinfo;
322
323         /* There are two cases to consider here:
324            1) The SID is a domain SID and we look for an equality match, or
325            2) This is an account SID and so we return the DISP_INFO* for our
326               domain */
327
328         if (psid == NULL) {
329                 return NULL;
330         }
331
332         if (sid_check_is_builtin(psid) || sid_check_is_in_builtin(psid)) {
333                 /*
334                  * Necessary only once, but it does not really hurt.
335                  */
336                 sid_copy(&builtin_dispinfo.sid, &global_sid_Builtin);
337
338                 return &builtin_dispinfo;
339         }
340
341         if (sid_check_is_domain(psid) || sid_check_is_in_our_domain(psid)) {
342                 /*
343                  * Necessary only once, but it does not really hurt.
344                  */
345                 sid_copy(&domain_dispinfo.sid, get_global_sam_sid());
346
347                 return &domain_dispinfo;
348         }
349
350         return NULL;
351 }
352
353 /*******************************************************************
354  Create a samr_info struct.
355 ********************************************************************/
356
357 static struct samr_info *get_samr_info_by_sid(DOM_SID *psid)
358 {
359         struct samr_info *info;
360         fstring sid_str;
361         TALLOC_CTX *mem_ctx;
362
363         if (psid) {
364                 sid_to_fstring(sid_str, psid);
365         } else {
366                 fstrcpy(sid_str,"(NULL)");
367         }
368
369         mem_ctx = talloc_init("samr_info for domain sid %s", sid_str);
370
371         if ((info = TALLOC_ZERO_P(mem_ctx, struct samr_info)) == NULL)
372                 return NULL;
373
374         DEBUG(10,("get_samr_info_by_sid: created new info for sid %s\n", sid_str));
375         if (psid) {
376                 sid_copy( &info->sid, psid);
377                 info->builtin_domain = sid_check_is_builtin(psid);
378         } else {
379                 DEBUG(10,("get_samr_info_by_sid: created new info for NULL sid.\n"));
380                 info->builtin_domain = False;
381         }
382         info->mem_ctx = mem_ctx;
383
384         info->disp_info = get_samr_dispinfo_by_sid(psid);
385
386         return info;
387 }
388
389 /*******************************************************************
390  Function to free the per SID data.
391  ********************************************************************/
392
393 static void free_samr_cache(DISP_INFO *disp_info)
394 {
395         DEBUG(10, ("free_samr_cache: deleting cache for SID %s\n",
396                    sid_string_dbg(&disp_info->sid)));
397
398         /* We need to become root here because the paged search might have to
399          * tell the LDAP server we're not interested in the rest anymore. */
400
401         become_root();
402
403         if (disp_info->users) {
404                 DEBUG(10,("free_samr_cache: deleting users cache\n"));
405                 pdb_search_destroy(disp_info->users);
406                 disp_info->users = NULL;
407         }
408         if (disp_info->machines) {
409                 DEBUG(10,("free_samr_cache: deleting machines cache\n"));
410                 pdb_search_destroy(disp_info->machines);
411                 disp_info->machines = NULL;
412         }
413         if (disp_info->groups) {
414                 DEBUG(10,("free_samr_cache: deleting groups cache\n"));
415                 pdb_search_destroy(disp_info->groups);
416                 disp_info->groups = NULL;
417         }
418         if (disp_info->aliases) {
419                 DEBUG(10,("free_samr_cache: deleting aliases cache\n"));
420                 pdb_search_destroy(disp_info->aliases);
421                 disp_info->aliases = NULL;
422         }
423         if (disp_info->enum_users) {
424                 DEBUG(10,("free_samr_cache: deleting enum_users cache\n"));
425                 pdb_search_destroy(disp_info->enum_users);
426                 disp_info->enum_users = NULL;
427         }
428         disp_info->enum_acb_mask = 0;
429
430         unbecome_root();
431 }
432
433 /*******************************************************************
434  Function to free the per handle data.
435  ********************************************************************/
436
437 static void free_samr_info(void *ptr)
438 {
439         struct samr_info *info=(struct samr_info *) ptr;
440
441         /* Only free the dispinfo cache if no one bothered to set up
442            a timeout. */
443
444         if (info->disp_info && info->disp_info->cache_timeout_event == NULL) {
445                 free_samr_cache(info->disp_info);
446         }
447
448         talloc_destroy(info->mem_ctx);
449 }
450
451 /*******************************************************************
452  Idle event handler. Throw away the disp info cache.
453  ********************************************************************/
454
455 static void disp_info_cache_idle_timeout_handler(struct event_context *ev_ctx,
456                                                  struct timed_event *te,
457                                                  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         *r->out.sam = samr_array;
1013
1014         become_root();
1015
1016         /* AS ROOT !!!! */
1017
1018         if ((info->disp_info->enum_users != NULL) &&
1019             (info->disp_info->enum_acb_mask != r->in.acct_flags)) {
1020                 pdb_search_destroy(info->disp_info->enum_users);
1021                 info->disp_info->enum_users = NULL;
1022         }
1023
1024         if (info->disp_info->enum_users == NULL) {
1025                 info->disp_info->enum_users = pdb_search_users(r->in.acct_flags);
1026                 info->disp_info->enum_acb_mask = r->in.acct_flags;
1027         }
1028
1029         if (info->disp_info->enum_users == NULL) {
1030                 /* END AS ROOT !!!! */
1031                 unbecome_root();
1032                 return NT_STATUS_ACCESS_DENIED;
1033         }
1034
1035         num_account = pdb_search_entries(info->disp_info->enum_users,
1036                                          enum_context, max_entries,
1037                                          &entries);
1038
1039         /* END AS ROOT !!!! */
1040
1041         unbecome_root();
1042
1043         if (num_account == 0) {
1044                 DEBUG(5, ("_samr_EnumDomainUsers: enumeration handle over "
1045                           "total entries\n"));
1046                 *r->out.resume_handle = *r->in.resume_handle;
1047                 return NT_STATUS_OK;
1048         }
1049
1050         status = make_user_sam_entry_list(p->mem_ctx, &samr_entries,
1051                                           num_account, enum_context,
1052                                           entries);
1053         if (!NT_STATUS_IS_OK(status)) {
1054                 return status;
1055         }
1056
1057         if (max_entries <= num_account) {
1058                 status = STATUS_MORE_ENTRIES;
1059         } else {
1060                 status = NT_STATUS_OK;
1061         }
1062
1063         /* Ensure we cache this enumeration. */
1064         set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1065
1066         DEBUG(5, ("_samr_EnumDomainUsers: %d\n", __LINE__));
1067
1068         samr_array->count = num_account;
1069         samr_array->entries = samr_entries;
1070
1071         *r->out.resume_handle = *r->in.resume_handle + num_account;
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         if (info->builtin_domain) {
1485                 DEBUG(5,("_samr_QueryDisplayInfo: Nothing in BUILTIN\n"));
1486                 return NT_STATUS_OK;
1487         }
1488
1489         status = access_check_samr_function(info->acc_granted,
1490                                             SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
1491                                             "_samr_QueryDisplayInfo");
1492         if (!NT_STATUS_IS_OK(status)) {
1493                 return status;
1494         }
1495
1496         /*
1497          * calculate how many entries we will return.
1498          * based on
1499          * - the number of entries the client asked
1500          * - our limit on that
1501          * - the starting point (enumeration context)
1502          * - the buffer size the client will accept
1503          */
1504
1505         /*
1506          * We are a lot more like W2K. Instead of reading the SAM
1507          * each time to find the records we need to send back,
1508          * we read it once and link that copy to the sam handle.
1509          * For large user list (over the MAX_SAM_ENTRIES)
1510          * it's a definitive win.
1511          * second point to notice: between enumerations
1512          * our sam is now the same as it's a snapshoot.
1513          * third point: got rid of the static SAM_USER_21 struct
1514          * no more intermediate.
1515          * con: it uses much more memory, as a full copy is stored
1516          * in memory.
1517          *
1518          * If you want to change it, think twice and think
1519          * of the second point , that's really important.
1520          *
1521          * JFM, 12/20/2001
1522          */
1523
1524         if ((r->in.level < 1) || (r->in.level > 5)) {
1525                 DEBUG(0,("_samr_QueryDisplayInfo: Unknown info level (%u)\n",
1526                          (unsigned int)r->in.level ));
1527                 return NT_STATUS_INVALID_INFO_CLASS;
1528         }
1529
1530         /* first limit the number of entries we will return */
1531         if(max_entries > max_sam_entries) {
1532                 DEBUG(5, ("_samr_QueryDisplayInfo: client requested %d "
1533                           "entries, limiting to %d\n", max_entries,
1534                           max_sam_entries));
1535                 max_entries = max_sam_entries;
1536         }
1537
1538         /* calculate the size and limit on the number of entries we will
1539          * return */
1540
1541         temp_size=max_entries*struct_size;
1542
1543         if (temp_size>max_size) {
1544                 max_entries=MIN((max_size/struct_size),max_entries);;
1545                 DEBUG(5, ("_samr_QueryDisplayInfo: buffer size limits to "
1546                           "only %d entries\n", max_entries));
1547         }
1548
1549         become_root();
1550
1551         /* THe following done as ROOT. Don't return without unbecome_root(). */
1552
1553         switch (r->in.level) {
1554         case 0x1:
1555         case 0x4:
1556                 if (info->disp_info->users == NULL) {
1557                         info->disp_info->users = pdb_search_users(ACB_NORMAL);
1558                         if (info->disp_info->users == NULL) {
1559                                 unbecome_root();
1560                                 return NT_STATUS_ACCESS_DENIED;
1561                         }
1562                         DEBUG(10,("_samr_QueryDisplayInfo: starting user enumeration at index %u\n",
1563                                 (unsigned  int)enum_context ));
1564                 } else {
1565                         DEBUG(10,("_samr_QueryDisplayInfo: using cached user enumeration at index %u\n",
1566                                 (unsigned  int)enum_context ));
1567                 }
1568
1569                 num_account = pdb_search_entries(info->disp_info->users,
1570                                                  enum_context, max_entries,
1571                                                  &entries);
1572                 break;
1573         case 0x2:
1574                 if (info->disp_info->machines == NULL) {
1575                         info->disp_info->machines =
1576                                 pdb_search_users(ACB_WSTRUST|ACB_SVRTRUST);
1577                         if (info->disp_info->machines == NULL) {
1578                                 unbecome_root();
1579                                 return NT_STATUS_ACCESS_DENIED;
1580                         }
1581                         DEBUG(10,("_samr_QueryDisplayInfo: starting machine enumeration at index %u\n",
1582                                 (unsigned  int)enum_context ));
1583                 } else {
1584                         DEBUG(10,("_samr_QueryDisplayInfo: using cached machine enumeration at index %u\n",
1585                                 (unsigned  int)enum_context ));
1586                 }
1587
1588                 num_account = pdb_search_entries(info->disp_info->machines,
1589                                                  enum_context, max_entries,
1590                                                  &entries);
1591                 break;
1592         case 0x3:
1593         case 0x5:
1594                 if (info->disp_info->groups == NULL) {
1595                         info->disp_info->groups = pdb_search_groups();
1596                         if (info->disp_info->groups == NULL) {
1597                                 unbecome_root();
1598                                 return NT_STATUS_ACCESS_DENIED;
1599                         }
1600                         DEBUG(10,("_samr_QueryDisplayInfo: starting group enumeration at index %u\n",
1601                                 (unsigned  int)enum_context ));
1602                 } else {
1603                         DEBUG(10,("_samr_QueryDisplayInfo: using cached group enumeration at index %u\n",
1604                                 (unsigned  int)enum_context ));
1605                 }
1606
1607                 num_account = pdb_search_entries(info->disp_info->groups,
1608                                                  enum_context, max_entries,
1609                                                  &entries);
1610                 break;
1611         default:
1612                 unbecome_root();
1613                 smb_panic("info class changed");
1614                 break;
1615         }
1616         unbecome_root();
1617
1618
1619         /* Now create reply structure */
1620         switch (r->in.level) {
1621         case 0x1:
1622                 disp_ret = init_samr_dispinfo_1(p->mem_ctx, &disp_info->info1,
1623                                                 num_account, enum_context,
1624                                                 entries);
1625                 break;
1626         case 0x2:
1627                 disp_ret = init_samr_dispinfo_2(p->mem_ctx, &disp_info->info2,
1628                                                 num_account, enum_context,
1629                                                 entries);
1630                 break;
1631         case 0x3:
1632                 disp_ret = init_samr_dispinfo_3(p->mem_ctx, &disp_info->info3,
1633                                                 num_account, enum_context,
1634                                                 entries);
1635                 break;
1636         case 0x4:
1637                 disp_ret = init_samr_dispinfo_4(p->mem_ctx, &disp_info->info4,
1638                                                 num_account, enum_context,
1639                                                 entries);
1640                 break;
1641         case 0x5:
1642                 disp_ret = init_samr_dispinfo_5(p->mem_ctx, &disp_info->info5,
1643                                                 num_account, enum_context,
1644                                                 entries);
1645                 break;
1646         default:
1647                 smb_panic("info class changed");
1648                 break;
1649         }
1650
1651         if (!NT_STATUS_IS_OK(disp_ret))
1652                 return disp_ret;
1653
1654         /* calculate the total size */
1655         total_data_size=num_account*struct_size;
1656
1657         if (max_entries <= num_account) {
1658                 status = STATUS_MORE_ENTRIES;
1659         } else {
1660                 status = NT_STATUS_OK;
1661         }
1662
1663         /* Ensure we cache this enumeration. */
1664         set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1665
1666         DEBUG(5, ("_samr_QueryDisplayInfo: %d\n", __LINE__));
1667
1668         *r->out.total_size = total_data_size;
1669         *r->out.returned_size = temp_size;
1670
1671         return status;
1672 }
1673
1674 /****************************************************************
1675  _samr_QueryDisplayInfo2
1676 ****************************************************************/
1677
1678 NTSTATUS _samr_QueryDisplayInfo2(pipes_struct *p,
1679                                  struct samr_QueryDisplayInfo2 *r)
1680 {
1681         struct samr_QueryDisplayInfo q;
1682
1683         q.in.domain_handle      = r->in.domain_handle;
1684         q.in.level              = r->in.level;
1685         q.in.start_idx          = r->in.start_idx;
1686         q.in.max_entries        = r->in.max_entries;
1687         q.in.buf_size           = r->in.buf_size;
1688
1689         q.out.total_size        = r->out.total_size;
1690         q.out.returned_size     = r->out.returned_size;
1691         q.out.info              = r->out.info;
1692
1693         return _samr_QueryDisplayInfo(p, &q);
1694 }
1695
1696 /****************************************************************
1697  _samr_QueryDisplayInfo3
1698 ****************************************************************/
1699
1700 NTSTATUS _samr_QueryDisplayInfo3(pipes_struct *p,
1701                                  struct samr_QueryDisplayInfo3 *r)
1702 {
1703         struct samr_QueryDisplayInfo q;
1704
1705         q.in.domain_handle      = r->in.domain_handle;
1706         q.in.level              = r->in.level;
1707         q.in.start_idx          = r->in.start_idx;
1708         q.in.max_entries        = r->in.max_entries;
1709         q.in.buf_size           = r->in.buf_size;
1710
1711         q.out.total_size        = r->out.total_size;
1712         q.out.returned_size     = r->out.returned_size;
1713         q.out.info              = r->out.info;
1714
1715         return _samr_QueryDisplayInfo(p, &q);
1716 }
1717
1718 /*******************************************************************
1719  _samr_QueryAliasInfo
1720  ********************************************************************/
1721
1722 NTSTATUS _samr_QueryAliasInfo(pipes_struct *p,
1723                               struct samr_QueryAliasInfo *r)
1724 {
1725         DOM_SID   sid;
1726         struct acct_info info;
1727         uint32    acc_granted;
1728         NTSTATUS status;
1729         union samr_AliasInfo *alias_info = NULL;
1730         const char *alias_name = NULL;
1731         const char *alias_description = NULL;
1732
1733         DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1734
1735         alias_info = TALLOC_ZERO_P(p->mem_ctx, union samr_AliasInfo);
1736         if (!alias_info) {
1737                 return NT_STATUS_NO_MEMORY;
1738         }
1739
1740         /* find the policy handle.  open a policy on it. */
1741         if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &sid, &acc_granted, NULL))
1742                 return NT_STATUS_INVALID_HANDLE;
1743
1744         status = access_check_samr_function(acc_granted,
1745                                             SAMR_ALIAS_ACCESS_LOOKUP_INFO,
1746                                             "_samr_QueryAliasInfo");
1747         if (!NT_STATUS_IS_OK(status)) {
1748                 return status;
1749         }
1750
1751         become_root();
1752         status = pdb_get_aliasinfo(&sid, &info);
1753         unbecome_root();
1754
1755         if ( !NT_STATUS_IS_OK(status))
1756                 return status;
1757
1758         /* FIXME: info contains fstrings */
1759         alias_name = talloc_strdup(r, info.acct_name);
1760         alias_description = talloc_strdup(r, info.acct_desc);
1761
1762         switch (r->in.level) {
1763         case ALIASINFOALL:
1764                 init_samr_alias_info1(&alias_info->all,
1765                                       alias_name,
1766                                       1,
1767                                       alias_description);
1768                 break;
1769         case ALIASINFODESCRIPTION:
1770                 init_samr_alias_info3(&alias_info->description,
1771                                       alias_description);
1772                 break;
1773         default:
1774                 return NT_STATUS_INVALID_INFO_CLASS;
1775         }
1776
1777         *r->out.info = alias_info;
1778
1779         DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1780
1781         return NT_STATUS_OK;
1782 }
1783
1784 #if 0
1785 /*******************************************************************
1786  samr_reply_lookup_ids
1787  ********************************************************************/
1788
1789  uint32 _samr_lookup_ids(pipes_struct *p, SAMR_Q_LOOKUP_IDS *q_u, SAMR_R_LOOKUP_IDS *r_u)
1790 {
1791     uint32 rid[MAX_SAM_ENTRIES];
1792     int num_rids = q_u->num_sids1;
1793
1794     r_u->status = NT_STATUS_OK;
1795
1796     DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1797
1798     if (num_rids > MAX_SAM_ENTRIES) {
1799         num_rids = MAX_SAM_ENTRIES;
1800         DEBUG(5,("_samr_lookup_ids: truncating entries to %d\n", num_rids));
1801     }
1802
1803 #if 0
1804     int i;
1805     SMB_ASSERT_ARRAY(q_u->uni_user_name, num_rids);
1806
1807     for (i = 0; i < num_rids && status == 0; i++)
1808     {
1809         struct sam_passwd *sam_pass;
1810         fstring user_name;
1811
1812
1813         fstrcpy(user_name, unistrn2(q_u->uni_user_name[i].buffer,
1814                                     q_u->uni_user_name[i].uni_str_len));
1815
1816         /* find the user account */
1817         become_root();
1818         sam_pass = get_smb21pwd_entry(user_name, 0);
1819         unbecome_root();
1820
1821         if (sam_pass == NULL)
1822         {
1823             status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1824             rid[i] = 0;
1825         }
1826         else
1827         {
1828             rid[i] = sam_pass->user_rid;
1829         }
1830     }
1831 #endif
1832
1833     num_rids = 1;
1834     rid[0] = BUILTIN_ALIAS_RID_USERS;
1835
1836     init_samr_r_lookup_ids(&r_u, num_rids, rid, NT_STATUS_OK);
1837
1838     DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1839
1840     return r_u->status;
1841 }
1842 #endif
1843
1844 /*******************************************************************
1845  _samr_LookupNames
1846  ********************************************************************/
1847
1848 NTSTATUS _samr_LookupNames(pipes_struct *p,
1849                            struct samr_LookupNames *r)
1850 {
1851         NTSTATUS status;
1852         uint32 *rid;
1853         enum lsa_SidType *type;
1854         int i;
1855         int num_rids = r->in.num_names;
1856         DOM_SID pol_sid;
1857         uint32  acc_granted;
1858         struct samr_Ids rids, types;
1859         uint32_t num_mapped = 0;
1860
1861         DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1862
1863         if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &pol_sid, &acc_granted, NULL)) {
1864                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1865         }
1866
1867         status = access_check_samr_function(acc_granted,
1868                                             0, /* Don't know the acc_bits yet */
1869                                             "_samr_LookupNames");
1870         if (!NT_STATUS_IS_OK(status)) {
1871                 return status;
1872         }
1873
1874         if (num_rids > MAX_SAM_ENTRIES) {
1875                 num_rids = MAX_SAM_ENTRIES;
1876                 DEBUG(5,("_samr_LookupNames: truncating entries to %d\n", num_rids));
1877         }
1878
1879         rid = talloc_array(p->mem_ctx, uint32, num_rids);
1880         NT_STATUS_HAVE_NO_MEMORY(rid);
1881
1882         type = talloc_array(p->mem_ctx, enum lsa_SidType, num_rids);
1883         NT_STATUS_HAVE_NO_MEMORY(type);
1884
1885         DEBUG(5,("_samr_LookupNames: looking name on SID %s\n",
1886                  sid_string_dbg(&pol_sid)));
1887
1888         for (i = 0; i < num_rids; i++) {
1889
1890                 status = NT_STATUS_NONE_MAPPED;
1891                 type[i] = SID_NAME_UNKNOWN;
1892
1893                 rid[i] = 0xffffffff;
1894
1895                 if (sid_check_is_builtin(&pol_sid)) {
1896                         if (lookup_builtin_name(r->in.names[i].string,
1897                                                 &rid[i]))
1898                         {
1899                                 type[i] = SID_NAME_ALIAS;
1900                         }
1901                 } else {
1902                         lookup_global_sam_name(r->in.names[i].string, 0,
1903                                                &rid[i], &type[i]);
1904                 }
1905
1906                 if (type[i] != SID_NAME_UNKNOWN) {
1907                         num_mapped++;
1908                 }
1909         }
1910
1911         if (num_mapped == num_rids) {
1912                 status = NT_STATUS_OK;
1913         } else if (num_mapped == 0) {
1914                 status = NT_STATUS_NONE_MAPPED;
1915         } else {
1916                 status = STATUS_SOME_UNMAPPED;
1917         }
1918
1919         rids.count = num_rids;
1920         rids.ids = rid;
1921
1922         types.count = num_rids;
1923         types.ids = type;
1924
1925         *r->out.rids = rids;
1926         *r->out.types = types;
1927
1928         DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1929
1930         return status;
1931 }
1932
1933 /*******************************************************************
1934  _samr_ChangePasswordUser2
1935  ********************************************************************/
1936
1937 NTSTATUS _samr_ChangePasswordUser2(pipes_struct *p,
1938                                    struct samr_ChangePasswordUser2 *r)
1939 {
1940         NTSTATUS status;
1941         fstring user_name;
1942         fstring wks;
1943
1944         DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1945
1946         fstrcpy(user_name, r->in.account->string);
1947         fstrcpy(wks, r->in.server->string);
1948
1949         DEBUG(5,("_samr_ChangePasswordUser2: user: %s wks: %s\n", user_name, wks));
1950
1951         /*
1952          * Pass the user through the NT -> unix user mapping
1953          * function.
1954          */
1955
1956         (void)map_username(user_name);
1957
1958         /*
1959          * UNIX username case mangling not required, pass_oem_change
1960          * is case insensitive.
1961          */
1962
1963         status = pass_oem_change(user_name,
1964                                  r->in.lm_password->data,
1965                                  r->in.lm_verifier->hash,
1966                                  r->in.nt_password->data,
1967                                  r->in.nt_verifier->hash,
1968                                  NULL);
1969
1970         DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1971
1972         return status;
1973 }
1974
1975 /*******************************************************************
1976  _samr_ChangePasswordUser3
1977  ********************************************************************/
1978
1979 NTSTATUS _samr_ChangePasswordUser3(pipes_struct *p,
1980                                    struct samr_ChangePasswordUser3 *r)
1981 {
1982         NTSTATUS status;
1983         fstring user_name;
1984         const char *wks = NULL;
1985         uint32 reject_reason;
1986         struct samr_DomInfo1 *dominfo = NULL;
1987         struct samr_ChangeReject *reject = NULL;
1988
1989         DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
1990
1991         fstrcpy(user_name, r->in.account->string);
1992         if (r->in.server && r->in.server->string) {
1993                 wks = r->in.server->string;
1994         }
1995
1996         DEBUG(5,("_samr_ChangePasswordUser3: user: %s wks: %s\n", user_name, wks));
1997
1998         /*
1999          * Pass the user through the NT -> unix user mapping
2000          * function.
2001          */
2002
2003         (void)map_username(user_name);
2004
2005         /*
2006          * UNIX username case mangling not required, pass_oem_change
2007          * is case insensitive.
2008          */
2009
2010         status = pass_oem_change(user_name,
2011                                  r->in.lm_password->data,
2012                                  r->in.lm_verifier->hash,
2013                                  r->in.nt_password->data,
2014                                  r->in.nt_verifier->hash,
2015                                  &reject_reason);
2016
2017         if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) ||
2018             NT_STATUS_EQUAL(status, NT_STATUS_ACCOUNT_RESTRICTION)) {
2019
2020                 uint32 min_pass_len,pass_hist,password_properties;
2021                 time_t u_expire, u_min_age;
2022                 NTTIME nt_expire, nt_min_age;
2023                 uint32 account_policy_temp;
2024
2025                 dominfo = TALLOC_ZERO_P(p->mem_ctx, struct samr_DomInfo1);
2026                 if (!dominfo) {
2027                         return NT_STATUS_NO_MEMORY;
2028                 }
2029
2030                 reject = TALLOC_ZERO_P(p->mem_ctx, struct samr_ChangeReject);
2031                 if (!reject) {
2032                         return NT_STATUS_NO_MEMORY;
2033                 }
2034
2035                 become_root();
2036
2037                 /* AS ROOT !!! */
2038
2039                 pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &account_policy_temp);
2040                 min_pass_len = account_policy_temp;
2041
2042                 pdb_get_account_policy(AP_PASSWORD_HISTORY, &account_policy_temp);
2043                 pass_hist = account_policy_temp;
2044
2045                 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
2046                 password_properties = account_policy_temp;
2047
2048                 pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
2049                 u_expire = account_policy_temp;
2050
2051                 pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
2052                 u_min_age = account_policy_temp;
2053
2054                 /* !AS ROOT */
2055
2056                 unbecome_root();
2057
2058                 unix_to_nt_time_abs(&nt_expire, u_expire);
2059                 unix_to_nt_time_abs(&nt_min_age, u_min_age);
2060
2061                 if (lp_check_password_script() && *lp_check_password_script()) {
2062                         password_properties |= DOMAIN_PASSWORD_COMPLEX;
2063                 }
2064
2065                 init_samr_DomInfo1(dominfo,
2066                                    min_pass_len,
2067                                    pass_hist,
2068                                    password_properties,
2069                                    u_expire,
2070                                    u_min_age);
2071
2072                 reject->reason = reject_reason;
2073
2074                 *r->out.dominfo = dominfo;
2075                 *r->out.reject = reject;
2076         }
2077
2078         DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
2079
2080         return status;
2081 }
2082
2083 /*******************************************************************
2084 makes a SAMR_R_LOOKUP_RIDS structure.
2085 ********************************************************************/
2086
2087 static bool make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names,
2088                                   const char **names,
2089                                   struct lsa_String **lsa_name_array_p)
2090 {
2091         struct lsa_String *lsa_name_array = NULL;
2092         uint32_t i;
2093
2094         *lsa_name_array_p = NULL;
2095
2096         if (num_names != 0) {
2097                 lsa_name_array = TALLOC_ZERO_ARRAY(ctx, struct lsa_String, num_names);
2098                 if (!lsa_name_array) {
2099                         return false;
2100                 }
2101         }
2102
2103         for (i = 0; i < num_names; i++) {
2104                 DEBUG(10, ("names[%d]:%s\n", i, names[i] && *names[i] ? names[i] : ""));
2105                 init_lsa_String(&lsa_name_array[i], names[i]);
2106         }
2107
2108         *lsa_name_array_p = lsa_name_array;
2109
2110         return true;
2111 }
2112
2113 /*******************************************************************
2114  _samr_LookupRids
2115  ********************************************************************/
2116
2117 NTSTATUS _samr_LookupRids(pipes_struct *p,
2118                           struct samr_LookupRids *r)
2119 {
2120         NTSTATUS status;
2121         const char **names;
2122         enum lsa_SidType *attrs = NULL;
2123         uint32 *wire_attrs = NULL;
2124         DOM_SID pol_sid;
2125         int num_rids = (int)r->in.num_rids;
2126         uint32 acc_granted;
2127         int i;
2128         struct lsa_Strings names_array;
2129         struct samr_Ids types_array;
2130         struct lsa_String *lsa_names = NULL;
2131
2132         DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2133
2134         /* find the policy handle.  open a policy on it. */
2135         if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &pol_sid, &acc_granted, NULL))
2136                 return NT_STATUS_INVALID_HANDLE;
2137
2138         status = access_check_samr_function(acc_granted,
2139                                             0, /* Don't know the acc_bits yet */
2140                                             "_samr_LookupRids");
2141         if (!NT_STATUS_IS_OK(status)) {
2142                 return status;
2143         }
2144
2145         if (num_rids > 1000) {
2146                 DEBUG(0, ("Got asked for %d rids (more than 1000) -- according "
2147                           "to samba4 idl this is not possible\n", num_rids));
2148                 return NT_STATUS_UNSUCCESSFUL;
2149         }
2150
2151         if (num_rids) {
2152                 names = TALLOC_ZERO_ARRAY(p->mem_ctx, const char *, num_rids);
2153                 attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, enum lsa_SidType, num_rids);
2154                 wire_attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_rids);
2155
2156                 if ((names == NULL) || (attrs == NULL) || (wire_attrs==NULL))
2157                         return NT_STATUS_NO_MEMORY;
2158         } else {
2159                 names = NULL;
2160                 attrs = NULL;
2161                 wire_attrs = NULL;
2162         }
2163
2164         become_root();  /* lookup_sid can require root privs */
2165         status = pdb_lookup_rids(&pol_sid, num_rids, r->in.rids,
2166                                  names, attrs);
2167         unbecome_root();
2168
2169         if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED) && (num_rids == 0)) {
2170                 status = NT_STATUS_OK;
2171         }
2172
2173         if (!make_samr_lookup_rids(p->mem_ctx, num_rids, names,
2174                                    &lsa_names)) {
2175                 return NT_STATUS_NO_MEMORY;
2176         }
2177
2178         /* Convert from enum lsa_SidType to uint32 for wire format. */
2179         for (i = 0; i < num_rids; i++) {
2180                 wire_attrs[i] = (uint32)attrs[i];
2181         }
2182
2183         names_array.count = num_rids;
2184         names_array.names = lsa_names;
2185
2186         types_array.count = num_rids;
2187         types_array.ids = wire_attrs;
2188
2189         *r->out.names = names_array;
2190         *r->out.types = types_array;
2191
2192         DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2193
2194         return status;
2195 }
2196
2197 /*******************************************************************
2198  _samr_OpenUser
2199 ********************************************************************/
2200
2201 NTSTATUS _samr_OpenUser(pipes_struct *p,
2202                         struct samr_OpenUser *r)
2203 {
2204         struct samu *sampass=NULL;
2205         DOM_SID sid;
2206         POLICY_HND domain_pol = *r->in.domain_handle;
2207         POLICY_HND *user_pol = r->out.user_handle;
2208         struct samr_info *info = NULL;
2209         SEC_DESC *psd = NULL;
2210         uint32    acc_granted;
2211         uint32    des_access = r->in.access_mask;
2212         size_t    sd_size;
2213         bool ret;
2214         NTSTATUS nt_status;
2215         SE_PRIV se_rights;
2216
2217         /* find the domain policy handle and get domain SID / access bits in the domain policy. */
2218
2219         if ( !get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted, NULL) )
2220                 return NT_STATUS_INVALID_HANDLE;
2221
2222         nt_status = access_check_samr_function(acc_granted,
2223                                                SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
2224                                                "_samr_OpenUser" );
2225
2226         if ( !NT_STATUS_IS_OK(nt_status) )
2227                 return nt_status;
2228
2229         if ( !(sampass = samu_new( p->mem_ctx )) ) {
2230                 return NT_STATUS_NO_MEMORY;
2231         }
2232
2233         /* append the user's RID to it */
2234
2235         if (!sid_append_rid(&sid, r->in.rid))
2236                 return NT_STATUS_NO_SUCH_USER;
2237
2238         /* check if access can be granted as requested by client. */
2239
2240         map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
2241
2242         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &sid, SAMR_USR_RIGHTS_WRITE_PW);
2243         se_map_generic(&des_access, &usr_generic_mapping);
2244
2245         se_priv_copy( &se_rights, &se_machine_account );
2246         se_priv_add( &se_rights, &se_add_users );
2247
2248         nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
2249                 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
2250                 &acc_granted, "_samr_OpenUser");
2251
2252         if ( !NT_STATUS_IS_OK(nt_status) )
2253                 return nt_status;
2254
2255         become_root();
2256         ret=pdb_getsampwsid(sampass, &sid);
2257         unbecome_root();
2258
2259         /* check that the SID exists in our domain. */
2260         if (ret == False) {
2261                 return NT_STATUS_NO_SUCH_USER;
2262         }
2263
2264         TALLOC_FREE(sampass);
2265
2266         /* associate the user's SID and access bits with the new handle. */
2267         if ((info = get_samr_info_by_sid(&sid)) == NULL)
2268                 return NT_STATUS_NO_MEMORY;
2269         info->acc_granted = acc_granted;
2270
2271         /* get a (unique) handle.  open a policy on it. */
2272         if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info))
2273                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2274
2275         return NT_STATUS_OK;
2276 }
2277
2278 /*************************************************************************
2279  *************************************************************************/
2280
2281 static NTSTATUS init_samr_parameters_string(TALLOC_CTX *mem_ctx,
2282                                             DATA_BLOB *blob,
2283                                             struct lsa_BinaryString **_r)
2284 {
2285         struct lsa_BinaryString *r;
2286
2287         if (!blob || !_r) {
2288                 return NT_STATUS_INVALID_PARAMETER;
2289         }
2290
2291         r = TALLOC_ZERO_P(mem_ctx, struct lsa_BinaryString);
2292         if (!r) {
2293                 return NT_STATUS_NO_MEMORY;
2294         }
2295
2296         r->array = TALLOC_ZERO_ARRAY(mem_ctx, uint16_t, blob->length/2);
2297         if (!r->array) {
2298                 return NT_STATUS_NO_MEMORY;
2299         }
2300         memcpy(r->array, blob->data, blob->length);
2301         r->size = blob->length;
2302         r->length = blob->length;
2303
2304         if (!r->array) {
2305                 return NT_STATUS_NO_MEMORY;
2306         }
2307
2308         *_r = r;
2309
2310         return NT_STATUS_OK;
2311 }
2312
2313 static NTSTATUS get_user_info_5(TALLOC_CTX *mem_ctx,
2314                                 struct samr_UserInfo5 *r,
2315                                 struct samu *pw,
2316                                 DOM_SID *domain_sid)
2317 {
2318         const DOM_SID *sid_user, *sid_group;
2319         uint32_t rid, primary_gid;
2320         NTTIME last_logon, last_logoff, last_password_change,
2321                acct_expiry;
2322         const char *account_name, *full_name, *home_directory, *home_drive,
2323                    *logon_script, *profile_path, *description,
2324                    *workstations, *comment;
2325         struct samr_LogonHours logon_hours;
2326
2327         ZERO_STRUCTP(r);
2328
2329         sid_user = pdb_get_user_sid(pw);
2330
2331         if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2332                 DEBUG(0, ("get_user_info_5: User %s has SID %s, \nwhich conflicts with "
2333                           "the domain sid %s.  Failing operation.\n",
2334                           pdb_get_username(pw), sid_string_dbg(sid_user),
2335                           sid_string_dbg(domain_sid)));
2336                 return NT_STATUS_UNSUCCESSFUL;
2337         }
2338
2339         become_root();
2340         sid_group = pdb_get_group_sid(pw);
2341         unbecome_root();
2342
2343         if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2344                 DEBUG(0, ("get_user_info_5: User %s has Primary Group SID %s, \n"
2345                           "which conflicts with the domain sid %s.  Failing operation.\n",
2346                           pdb_get_username(pw), sid_string_dbg(sid_group),
2347                           sid_string_dbg(domain_sid)));
2348                 return NT_STATUS_UNSUCCESSFUL;
2349         }
2350
2351         unix_to_nt_time(&last_logon, pdb_get_logon_time(pw));
2352         unix_to_nt_time(&last_logoff, pdb_get_logoff_time(pw));
2353         unix_to_nt_time(&acct_expiry, pdb_get_kickoff_time(pw));
2354         unix_to_nt_time(&last_password_change, pdb_get_pass_last_set_time(pw));
2355
2356         account_name = talloc_strdup(mem_ctx, pdb_get_username(pw));
2357         full_name = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2358         home_directory = talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2359         home_drive = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2360         logon_script = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2361         profile_path = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2362         description = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2363         workstations = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2364         comment = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2365
2366         logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2367
2368         init_samr_user_info5(r,
2369                              account_name,
2370                              full_name,
2371                              rid,
2372                              primary_gid,
2373                              home_directory,
2374                              home_drive,
2375                              logon_script,
2376                              profile_path,
2377                              description,
2378                              workstations,
2379                              last_logon,
2380                              last_logoff,
2381                              logon_hours,
2382                              pdb_get_bad_password_count(pw),
2383                              pdb_get_logon_count(pw),
2384                              last_password_change,
2385                              acct_expiry,
2386                              pdb_get_acct_ctrl(pw));
2387
2388         return NT_STATUS_OK;
2389 }
2390
2391 /*************************************************************************
2392  get_user_info_7. Safe. Only gives out account_name.
2393  *************************************************************************/
2394
2395 static NTSTATUS get_user_info_7(TALLOC_CTX *mem_ctx,
2396                                 struct samr_UserInfo7 *r,
2397                                 struct samu *smbpass)
2398 {
2399         const char *account_name = NULL;
2400
2401         ZERO_STRUCTP(r);
2402
2403         account_name = talloc_strdup(mem_ctx, pdb_get_username(smbpass));
2404         if (!account_name) {
2405                 return NT_STATUS_NO_MEMORY;
2406         }
2407
2408         init_samr_user_info7(r, account_name);
2409
2410         return NT_STATUS_OK;
2411 }
2412
2413 /*************************************************************************
2414  get_user_info_9. Only gives out primary group SID.
2415  *************************************************************************/
2416
2417 static NTSTATUS get_user_info_9(TALLOC_CTX *mem_ctx,
2418                                 struct samr_UserInfo9 *r,
2419                                 struct samu *smbpass)
2420 {
2421         ZERO_STRUCTP(r);
2422
2423         init_samr_user_info9(r, pdb_get_group_rid(smbpass));
2424
2425         return NT_STATUS_OK;
2426 }
2427
2428 /*************************************************************************
2429  get_user_info_16. Safe. Only gives out acb bits.
2430  *************************************************************************/
2431
2432 static NTSTATUS get_user_info_16(TALLOC_CTX *mem_ctx,
2433                                  struct samr_UserInfo16 *r,
2434                                  struct samu *smbpass)
2435 {
2436         ZERO_STRUCTP(r);
2437
2438         init_samr_user_info16(r, pdb_get_acct_ctrl(smbpass));
2439
2440         return NT_STATUS_OK;
2441 }
2442
2443 /*************************************************************************
2444  get_user_info_18. OK - this is the killer as it gives out password info.
2445  Ensure that this is only allowed on an encrypted connection with a root
2446  user. JRA.
2447  *************************************************************************/
2448
2449 static NTSTATUS get_user_info_18(pipes_struct *p,
2450                                  TALLOC_CTX *mem_ctx,
2451                                  struct samr_UserInfo18 *r,
2452                                  DOM_SID *user_sid)
2453 {
2454         struct samu *smbpass=NULL;
2455         bool ret;
2456
2457         ZERO_STRUCTP(r);
2458
2459         if (p->auth.auth_type != PIPE_AUTH_TYPE_NTLMSSP || p->auth.auth_type != PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) {
2460                 return NT_STATUS_ACCESS_DENIED;
2461         }
2462
2463         if (p->auth.auth_level != PIPE_AUTH_LEVEL_PRIVACY) {
2464                 return NT_STATUS_ACCESS_DENIED;
2465         }
2466
2467         /*
2468          * Do *NOT* do become_root()/unbecome_root() here ! JRA.
2469          */
2470
2471         if ( !(smbpass = samu_new( mem_ctx )) ) {
2472                 return NT_STATUS_NO_MEMORY;
2473         }
2474
2475         ret = pdb_getsampwsid(smbpass, user_sid);
2476
2477         if (ret == False) {
2478                 DEBUG(4, ("User %s not found\n", sid_string_dbg(user_sid)));
2479                 TALLOC_FREE(smbpass);
2480                 return (geteuid() == (uid_t)0) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
2481         }
2482
2483         DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
2484
2485         if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
2486                 TALLOC_FREE(smbpass);
2487                 return NT_STATUS_ACCOUNT_DISABLED;
2488         }
2489
2490         init_samr_user_info18(r,
2491                               pdb_get_lanman_passwd(smbpass),
2492                               pdb_get_nt_passwd(smbpass),
2493                               0 /* FIXME */);
2494
2495         TALLOC_FREE(smbpass);
2496
2497         return NT_STATUS_OK;
2498 }
2499
2500 /*************************************************************************
2501  get_user_info_20
2502  *************************************************************************/
2503
2504 static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx,
2505                                  struct samr_UserInfo20 *r,
2506                                  struct samu *sampass)
2507 {
2508         const char *munged_dial = NULL;
2509         DATA_BLOB blob;
2510         NTSTATUS status;
2511         struct lsa_BinaryString *parameters = NULL;
2512
2513         ZERO_STRUCTP(r);
2514
2515         munged_dial = pdb_get_munged_dial(sampass);
2516
2517         DEBUG(3,("User:[%s] has [%s] (length: %d)\n", pdb_get_username(sampass),
2518                 munged_dial, (int)strlen(munged_dial)));
2519
2520         if (munged_dial) {
2521                 blob = base64_decode_data_blob(munged_dial);
2522         } else {
2523                 blob = data_blob_string_const("");
2524         }
2525
2526         status = init_samr_parameters_string(mem_ctx, &blob, &parameters);
2527         data_blob_free(&blob);
2528         if (!NT_STATUS_IS_OK(status)) {
2529                 return status;
2530         }
2531
2532         init_samr_user_info20(r, parameters);
2533
2534         return NT_STATUS_OK;
2535 }
2536
2537
2538 /*************************************************************************
2539  get_user_info_21
2540  *************************************************************************/
2541
2542 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx,
2543                                  struct samr_UserInfo21 *r,
2544                                  struct samu *pw,
2545                                  DOM_SID *domain_sid)
2546 {
2547         NTSTATUS status;
2548         const DOM_SID *sid_user, *sid_group;
2549         uint32_t rid, primary_gid;
2550         NTTIME last_logon, last_logoff, last_password_change,
2551                acct_expiry, allow_password_change, force_password_change;
2552         time_t must_change_time;
2553         uint8_t password_expired;
2554         const char *account_name, *full_name, *home_directory, *home_drive,
2555                    *logon_script, *profile_path, *description,
2556                    *workstations, *comment;
2557         struct samr_LogonHours logon_hours;
2558         struct lsa_BinaryString *parameters = NULL;
2559         const char *munged_dial = NULL;
2560         DATA_BLOB blob;
2561
2562         ZERO_STRUCTP(r);
2563
2564         sid_user = pdb_get_user_sid(pw);
2565
2566         if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2567                 DEBUG(0, ("get_user_info_21: User %s has SID %s, \nwhich conflicts with "
2568                           "the domain sid %s.  Failing operation.\n",
2569                           pdb_get_username(pw), sid_string_dbg(sid_user),
2570                           sid_string_dbg(domain_sid)));
2571                 return NT_STATUS_UNSUCCESSFUL;
2572         }
2573
2574         become_root();
2575         sid_group = pdb_get_group_sid(pw);
2576         unbecome_root();
2577
2578         if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2579                 DEBUG(0, ("get_user_info_21: User %s has Primary Group SID %s, \n"
2580                           "which conflicts with the domain sid %s.  Failing operation.\n",
2581                           pdb_get_username(pw), sid_string_dbg(sid_group),
2582                           sid_string_dbg(domain_sid)));
2583                 return NT_STATUS_UNSUCCESSFUL;
2584         }
2585
2586         unix_to_nt_time(&last_logon, pdb_get_logon_time(pw));
2587         unix_to_nt_time(&last_logoff, pdb_get_logoff_time(pw));
2588         unix_to_nt_time(&acct_expiry, pdb_get_kickoff_time(pw));
2589         unix_to_nt_time(&last_password_change, pdb_get_pass_last_set_time(pw));
2590         unix_to_nt_time(&allow_password_change, pdb_get_pass_can_change_time(pw));
2591
2592         must_change_time = pdb_get_pass_must_change_time(pw);
2593         if (must_change_time == get_time_t_max()) {
2594                 unix_to_nt_time_abs(&force_password_change, must_change_time);
2595         } else {
2596                 unix_to_nt_time(&force_password_change, must_change_time);
2597         }
2598
2599         if (pdb_get_pass_must_change_time(pw) == 0) {
2600                 password_expired = PASS_MUST_CHANGE_AT_NEXT_LOGON;
2601         } else {
2602                 password_expired = 0;
2603         }
2604
2605         munged_dial = pdb_get_munged_dial(pw);
2606         if (munged_dial) {
2607                 blob = base64_decode_data_blob(munged_dial);
2608         } else {
2609                 blob = data_blob_string_const("");
2610         }
2611
2612         status = init_samr_parameters_string(mem_ctx, &blob, &parameters);
2613         data_blob_free(&blob);
2614         if (!NT_STATUS_IS_OK(status)) {
2615                 return status;
2616         }
2617
2618         account_name = talloc_strdup(mem_ctx, pdb_get_username(pw));
2619         full_name = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2620         home_directory = talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2621         home_drive = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2622         logon_script = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2623         profile_path = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2624         description = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2625         workstations = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2626         comment = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2627
2628         logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2629 #if 0
2630
2631         /*
2632           Look at a user on a real NT4 PDC with usrmgr, press
2633           'ok'. Then you will see that fields_present is set to
2634           0x08f827fa. Look at the user immediately after that again,
2635           and you will see that 0x00fffff is returned. This solves
2636           the problem that you get access denied after having looked
2637           at the user.
2638           -- Volker
2639         */
2640
2641 #endif
2642
2643         init_samr_user_info21(r,
2644                               last_logon,
2645                               last_logoff,
2646                               last_password_change,
2647                               acct_expiry,
2648                               allow_password_change,
2649                               force_password_change,
2650                               account_name,
2651                               full_name,
2652                               home_directory,
2653                               home_drive,
2654                               logon_script,
2655                               profile_path,
2656                               description,
2657                               workstations,
2658                               comment,
2659                               parameters,
2660                               rid,
2661                               primary_gid,
2662                               pdb_get_acct_ctrl(pw),
2663                               pdb_build_fields_present(pw),
2664                               logon_hours,
2665                               pdb_get_bad_password_count(pw),
2666                               pdb_get_logon_count(pw),
2667                               0, /* country_code */
2668                               0, /* code_page */
2669                               0, /* nt_password_set */
2670                               0, /* lm_password_set */
2671                               password_expired);
2672
2673         return NT_STATUS_OK;
2674 }
2675
2676 /*******************************************************************
2677  _samr_QueryUserInfo
2678  ********************************************************************/
2679
2680 NTSTATUS _samr_QueryUserInfo(pipes_struct *p,
2681                              struct samr_QueryUserInfo *r)
2682 {
2683         NTSTATUS status;
2684         union samr_UserInfo *user_info = NULL;
2685         struct samr_info *info = NULL;
2686         DOM_SID domain_sid;
2687         uint32 rid;
2688         bool ret = false;
2689         struct samu *pwd = NULL;
2690
2691         /* search for the handle */
2692         if (!find_policy_by_hnd(p, r->in.user_handle, (void **)(void *)&info))
2693                 return NT_STATUS_INVALID_HANDLE;
2694
2695         status = access_check_samr_function(info->acc_granted,
2696                                             SAMR_USER_ACCESS_GET_ATTRIBUTES,
2697                                             "_samr_QueryUserInfo");
2698         if (!NT_STATUS_IS_OK(status)) {
2699                 return status;
2700         }
2701
2702         domain_sid = info->sid;
2703
2704         sid_split_rid(&domain_sid, &rid);
2705
2706         if (!sid_check_is_in_our_domain(&info->sid))
2707                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2708
2709         DEBUG(5,("_samr_QueryUserInfo: sid:%s\n",
2710                  sid_string_dbg(&info->sid)));
2711
2712         user_info = TALLOC_ZERO_P(p->mem_ctx, union samr_UserInfo);
2713         if (!user_info) {
2714                 return NT_STATUS_NO_MEMORY;
2715         }
2716
2717         DEBUG(5,("_samr_QueryUserInfo: user info level: %d\n", r->in.level));
2718
2719         if (!(pwd = samu_new(p->mem_ctx))) {
2720                 return NT_STATUS_NO_MEMORY;
2721         }
2722
2723         become_root();
2724         ret = pdb_getsampwsid(pwd, &info->sid);
2725         unbecome_root();
2726
2727         if (ret == false) {
2728                 DEBUG(4,("User %s not found\n", sid_string_dbg(&info->sid)));
2729                 TALLOC_FREE(pwd);
2730                 return NT_STATUS_NO_SUCH_USER;
2731         }
2732
2733         DEBUG(3,("User:[%s]\n", pdb_get_username(pwd)));
2734
2735         samr_clear_sam_passwd(pwd);
2736
2737         switch (r->in.level) {
2738         case 5:
2739                 status = get_user_info_5(p->mem_ctx, &user_info->info5, pwd, &domain_sid);
2740                 break;
2741         case 7:
2742                 status = get_user_info_7(p->mem_ctx, &user_info->info7, pwd);
2743                 break;
2744         case 9:
2745                 status = get_user_info_9(p->mem_ctx, &user_info->info9, pwd);
2746                 break;
2747         case 16:
2748                 status = get_user_info_16(p->mem_ctx, &user_info->info16, pwd);
2749                 break;
2750         case 18:
2751                 /* level 18 is special */
2752                 status = get_user_info_18(p, p->mem_ctx, &user_info->info18, &info->sid);
2753                 break;
2754         case 20:
2755                 status = get_user_info_20(p->mem_ctx, &user_info->info20, pwd);
2756                 break;
2757         case 21:
2758                 status = get_user_info_21(p->mem_ctx, &user_info->info21, pwd, &domain_sid);
2759                 break;
2760         default:
2761                 status = NT_STATUS_INVALID_INFO_CLASS;
2762                 break;
2763         }
2764
2765         TALLOC_FREE(pwd);
2766
2767         *r->out.info = user_info;
2768
2769         DEBUG(5,("_samr_QueryUserInfo: %d\n", __LINE__));
2770
2771         return status;
2772 }
2773
2774 /****************************************************************
2775 ****************************************************************/
2776
2777 NTSTATUS _samr_QueryUserInfo2(pipes_struct *p,
2778                               struct samr_QueryUserInfo2 *r)
2779 {
2780         struct samr_QueryUserInfo u;
2781
2782         u.in.user_handle        = r->in.user_handle;
2783         u.in.level              = r->in.level;
2784         u.out.info              = r->out.info;
2785
2786         return _samr_QueryUserInfo(p, &u);
2787 }
2788
2789 /*******************************************************************
2790  _samr_GetGroupsForUser
2791  ********************************************************************/
2792
2793 NTSTATUS _samr_GetGroupsForUser(pipes_struct *p,
2794                                 struct samr_GetGroupsForUser *r)
2795 {
2796         struct samu *sam_pass=NULL;
2797         DOM_SID  sid;
2798         DOM_SID *sids;
2799         struct samr_RidWithAttribute dom_gid;
2800         struct samr_RidWithAttribute *gids = NULL;
2801         uint32 primary_group_rid;
2802         size_t num_groups = 0;
2803         gid_t *unix_gids;
2804         size_t i, num_gids;
2805         uint32 acc_granted;
2806         bool ret;
2807         NTSTATUS result;
2808         bool success = False;
2809
2810         struct samr_RidWithAttributeArray *rids = NULL;
2811
2812         /*
2813          * from the SID in the request:
2814          * we should send back the list of DOMAIN GROUPS
2815          * the user is a member of
2816          *
2817          * and only the DOMAIN GROUPS
2818          * no ALIASES !!! neither aliases of the domain
2819          * nor aliases of the builtin SID
2820          *
2821          * JFM, 12/2/2001
2822          */
2823
2824         DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
2825
2826         rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidWithAttributeArray);
2827         if (!rids) {
2828                 return NT_STATUS_NO_MEMORY;
2829         }
2830
2831         /* find the policy handle.  open a policy on it. */
2832         if (!get_lsa_policy_samr_sid(p, r->in.user_handle, &sid, &acc_granted, NULL))
2833                 return NT_STATUS_INVALID_HANDLE;
2834
2835         result = access_check_samr_function(acc_granted,
2836                                             SAMR_USER_ACCESS_GET_GROUPS,
2837                                             "_samr_GetGroupsForUser");
2838         if (!NT_STATUS_IS_OK(result)) {
2839                 return result;
2840         }
2841
2842         if (!sid_check_is_in_our_domain(&sid))
2843                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2844
2845         if ( !(sam_pass = samu_new( p->mem_ctx )) ) {
2846                 return NT_STATUS_NO_MEMORY;
2847         }
2848
2849         become_root();
2850         ret = pdb_getsampwsid(sam_pass, &sid);
2851         unbecome_root();
2852
2853         if (!ret) {
2854                 DEBUG(10, ("pdb_getsampwsid failed for %s\n",
2855                            sid_string_dbg(&sid)));
2856                 return NT_STATUS_NO_SUCH_USER;
2857         }
2858
2859         sids = NULL;
2860
2861         /* make both calls inside the root block */
2862         become_root();
2863         result = pdb_enum_group_memberships(p->mem_ctx, sam_pass,
2864                                             &sids, &unix_gids, &num_groups);
2865         if ( NT_STATUS_IS_OK(result) ) {
2866                 success = sid_peek_check_rid(get_global_sam_sid(),
2867                                              pdb_get_group_sid(sam_pass),
2868                                              &primary_group_rid);
2869         }
2870         unbecome_root();
2871
2872         if (!NT_STATUS_IS_OK(result)) {
2873                 DEBUG(10, ("pdb_enum_group_memberships failed for %s\n",
2874                            sid_string_dbg(&sid)));
2875                 return result;
2876         }
2877
2878         if ( !success ) {
2879                 DEBUG(5, ("Group sid %s for user %s not in our domain\n",
2880                           sid_string_dbg(pdb_get_group_sid(sam_pass)),
2881                           pdb_get_username(sam_pass)));
2882                 TALLOC_FREE(sam_pass);
2883                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2884         }
2885
2886         gids = NULL;
2887         num_gids = 0;
2888
2889         dom_gid.attributes = (SE_GROUP_MANDATORY|SE_GROUP_ENABLED_BY_DEFAULT|
2890                               SE_GROUP_ENABLED);
2891         dom_gid.rid = primary_group_rid;
2892         ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
2893
2894         for (i=0; i<num_groups; i++) {
2895
2896                 if (!sid_peek_check_rid(get_global_sam_sid(),
2897                                         &(sids[i]), &dom_gid.rid)) {
2898                         DEBUG(10, ("Found sid %s not in our domain\n",
2899                                    sid_string_dbg(&sids[i])));
2900                         continue;
2901                 }
2902
2903                 if (dom_gid.rid == primary_group_rid) {
2904                         /* We added the primary group directly from the
2905                          * sam_account. The other SIDs are unique from
2906                          * enum_group_memberships */
2907                         continue;
2908                 }
2909
2910                 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
2911         }
2912
2913         rids->count = num_gids;
2914         rids->rids = gids;
2915
2916         *r->out.rids = rids;
2917
2918         DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
2919
2920         return result;
2921 }
2922
2923 /*******************************************************************
2924  _samr_QueryDomainInfo
2925  ********************************************************************/
2926
2927 NTSTATUS _samr_QueryDomainInfo(pipes_struct *p,
2928                                struct samr_QueryDomainInfo *r)
2929 {
2930         NTSTATUS status = NT_STATUS_OK;
2931         struct samr_info *info = NULL;
2932         union samr_DomainInfo *dom_info;
2933         uint32 min_pass_len,pass_hist,password_properties;
2934         time_t u_expire, u_min_age;
2935         NTTIME nt_expire, nt_min_age;
2936
2937         time_t u_lock_duration, u_reset_time;
2938         NTTIME nt_lock_duration, nt_reset_time;
2939         uint32 lockout;
2940         time_t u_logout;
2941         NTTIME nt_logout;
2942
2943         uint32 account_policy_temp;
2944
2945         time_t seq_num;
2946         uint32 server_role;
2947
2948         uint32 num_users=0, num_groups=0, num_aliases=0;
2949
2950         DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__));
2951
2952         dom_info = TALLOC_ZERO_P(p->mem_ctx, union samr_DomainInfo);
2953         if (!dom_info) {
2954                 return NT_STATUS_NO_MEMORY;
2955         }
2956
2957         /* find the policy handle.  open a policy on it. */
2958         if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info)) {
2959                 return NT_STATUS_INVALID_HANDLE;
2960         }
2961
2962         status = access_check_samr_function(info->acc_granted,
2963                                             SAMR_ACCESS_OPEN_DOMAIN,
2964                                             "_samr_QueryDomainInfo" );
2965
2966         if ( !NT_STATUS_IS_OK(status) )
2967                 return status;
2968
2969         switch (r->in.level) {
2970                 case 0x01:
2971
2972                         become_root();
2973
2974                         /* AS ROOT !!! */
2975
2976                         pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &account_policy_temp);
2977                         min_pass_len = account_policy_temp;
2978
2979                         pdb_get_account_policy(AP_PASSWORD_HISTORY, &account_policy_temp);
2980                         pass_hist = account_policy_temp;
2981
2982                         pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
2983                         password_properties = account_policy_temp;
2984
2985                         pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
2986                         u_expire = account_policy_temp;
2987
2988                         pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
2989                         u_min_age = account_policy_temp;
2990
2991                         /* !AS ROOT */
2992
2993                         unbecome_root();
2994
2995                         unix_to_nt_time_abs(&nt_expire, u_expire);
2996                         unix_to_nt_time_abs(&nt_min_age, u_min_age);
2997
2998                         if (lp_check_password_script() && *lp_check_password_script()) {
2999                                 password_properties |= DOMAIN_PASSWORD_COMPLEX;
3000                         }
3001
3002                         init_samr_DomInfo1(&dom_info->info1,
3003                                            (uint16)min_pass_len,
3004                                            (uint16)pass_hist,
3005                                            password_properties,
3006                                            nt_expire,
3007                                            nt_min_age);
3008                         break;
3009                 case 0x02:
3010
3011                         become_root();
3012
3013                         /* AS ROOT !!! */
3014
3015                         num_users = count_sam_users(info->disp_info, ACB_NORMAL);
3016                         num_groups = count_sam_groups(info->disp_info);
3017                         num_aliases = count_sam_aliases(info->disp_info);
3018
3019                         pdb_get_account_policy(AP_TIME_TO_LOGOUT, &account_policy_temp);
3020                         u_logout = account_policy_temp;
3021
3022                         unix_to_nt_time_abs(&nt_logout, u_logout);
3023
3024                         if (!pdb_get_seq_num(&seq_num))
3025                                 seq_num = time(NULL);
3026
3027                         /* !AS ROOT */
3028
3029                         unbecome_root();
3030
3031                         server_role = ROLE_DOMAIN_PDC;
3032                         if (lp_server_role() == ROLE_DOMAIN_BDC)
3033                                 server_role = ROLE_DOMAIN_BDC;
3034
3035                         init_samr_DomInfo2(&dom_info->info2,
3036                                            nt_logout,
3037                                            lp_serverstring(),
3038                                            lp_workgroup(),
3039                                            global_myname(),
3040                                            seq_num,
3041                                            1,
3042                                            server_role,
3043                                            1,
3044                                            num_users,
3045                                            num_groups,
3046                                            num_aliases);
3047                         break;
3048                 case 0x03:
3049
3050                         become_root();
3051
3052                         /* AS ROOT !!! */
3053
3054                         {
3055                                 uint32 ul;
3056                                 pdb_get_account_policy(AP_TIME_TO_LOGOUT, &ul);
3057                                 u_logout = (time_t)ul;
3058                         }
3059
3060                         /* !AS ROOT */
3061
3062                         unbecome_root();
3063
3064                         unix_to_nt_time_abs(&nt_logout, u_logout);
3065
3066                         init_samr_DomInfo3(&dom_info->info3,
3067                                            nt_logout);
3068
3069                         break;
3070                 case 0x04:
3071                         init_samr_DomInfo4(&dom_info->info4,
3072                                            lp_serverstring());
3073                         break;
3074                 case 0x05:
3075                         init_samr_DomInfo5(&dom_info->info5,
3076                                            get_global_sam_name());
3077                         break;
3078                 case 0x06:
3079                         /* NT returns its own name when a PDC. win2k and later
3080                          * only the name of the PDC if itself is a BDC (samba4
3081                          * idl) */
3082                         init_samr_DomInfo6(&dom_info->info6,
3083                                            global_myname());
3084                         break;
3085                 case 0x07:
3086                         server_role = ROLE_DOMAIN_PDC;
3087                         if (lp_server_role() == ROLE_DOMAIN_BDC)
3088                                 server_role = ROLE_DOMAIN_BDC;
3089
3090                         init_samr_DomInfo7(&dom_info->info7,
3091                                            server_role);
3092                         break;
3093                 case 0x08:
3094
3095                         become_root();
3096
3097                         /* AS ROOT !!! */
3098
3099                         if (!pdb_get_seq_num(&seq_num)) {
3100                                 seq_num = time(NULL);
3101                         }
3102
3103                         /* !AS ROOT */
3104
3105                         unbecome_root();
3106
3107                         init_samr_DomInfo8(&dom_info->info8,
3108                                            seq_num,
3109                                            0);
3110                         break;
3111                 case 0x0c:
3112
3113                         become_root();
3114
3115                         /* AS ROOT !!! */
3116
3117                         pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
3118                         u_lock_duration = account_policy_temp;
3119                         if (u_lock_duration != -1) {
3120                                 u_lock_duration *= 60;
3121                         }
3122
3123                         pdb_get_account_policy(AP_RESET_COUNT_TIME, &account_policy_temp);
3124                         u_reset_time = account_policy_temp * 60;
3125
3126                         pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
3127                         lockout = account_policy_temp;
3128
3129                         /* !AS ROOT */
3130
3131                         unbecome_root();
3132
3133                         unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
3134                         unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
3135
3136                         init_samr_DomInfo12(&dom_info->info12,
3137                                             nt_lock_duration,
3138                                             nt_reset_time,
3139                                             (uint16)lockout);
3140                         break;
3141                 default:
3142                         return NT_STATUS_INVALID_INFO_CLASS;
3143         }
3144
3145         *r->out.info = dom_info;
3146
3147         DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__));
3148
3149         return status;
3150 }
3151
3152 /* W2k3 seems to use the same check for all 3 objects that can be created via
3153  * SAMR, if you try to create for example "Dialup" as an alias it says
3154  * "NT_STATUS_USER_EXISTS". This is racy, but we can't really lock the user
3155  * database. */
3156
3157 static NTSTATUS can_create(TALLOC_CTX *mem_ctx, const char *new_name)
3158 {
3159         enum lsa_SidType type;
3160         bool result;
3161
3162         DEBUG(10, ("Checking whether [%s] can be created\n", new_name));
3163
3164         become_root();
3165         /* Lookup in our local databases (LOOKUP_NAME_REMOTE not set)
3166          * whether the name already exists */
3167         result = lookup_name(mem_ctx, new_name, LOOKUP_NAME_LOCAL,
3168                              NULL, NULL, NULL, &type);
3169         unbecome_root();
3170
3171         if (!result) {
3172                 DEBUG(10, ("%s does not exist, can create it\n", new_name));
3173                 return NT_STATUS_OK;
3174         }
3175
3176         DEBUG(5, ("trying to create %s, exists as %s\n",
3177                   new_name, sid_type_lookup(type)));
3178
3179         if (type == SID_NAME_DOM_GRP) {
3180                 return NT_STATUS_GROUP_EXISTS;
3181         }
3182         if (type == SID_NAME_ALIAS) {
3183                 return NT_STATUS_ALIAS_EXISTS;
3184         }
3185
3186         /* Yes, the default is NT_STATUS_USER_EXISTS */
3187         return NT_STATUS_USER_EXISTS;
3188 }
3189
3190 /*******************************************************************
3191  _samr_CreateUser2
3192  ********************************************************************/
3193
3194 NTSTATUS _samr_CreateUser2(pipes_struct *p,
3195                            struct samr_CreateUser2 *r)
3196 {
3197         const char *account = NULL;
3198         DOM_SID sid;
3199         POLICY_HND dom_pol = *r->in.domain_handle;
3200         uint32_t acb_info = r->in.acct_flags;
3201         POLICY_HND *user_pol = r->out.user_handle;
3202         struct samr_info *info = NULL;
3203         NTSTATUS nt_status;
3204         uint32 acc_granted;
3205         SEC_DESC *psd;
3206         size_t    sd_size;
3207         /* check this, when giving away 'add computer to domain' privs */
3208         uint32    des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
3209         bool can_add_account = False;
3210         SE_PRIV se_rights;
3211         DISP_INFO *disp_info = NULL;
3212
3213         /* Get the domain SID stored in the domain policy */
3214         if (!get_lsa_policy_samr_sid(p, &dom_pol, &sid, &acc_granted,
3215                                      &disp_info))
3216                 return NT_STATUS_INVALID_HANDLE;
3217
3218         if (disp_info->builtin_domain) {
3219                 DEBUG(5,("_samr_CreateUser2: Refusing user create in BUILTIN\n"));
3220                 return NT_STATUS_ACCESS_DENIED;
3221         }
3222
3223         nt_status = access_check_samr_function(acc_granted,
3224                                                SAMR_DOMAIN_ACCESS_CREATE_USER,
3225                                                "_samr_CreateUser2");
3226         if (!NT_STATUS_IS_OK(nt_status)) {
3227                 return nt_status;
3228         }
3229
3230         if (!(acb_info == ACB_NORMAL || acb_info == ACB_DOMTRUST ||
3231               acb_info == ACB_WSTRUST || acb_info == ACB_SVRTRUST)) {
3232                 /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if
3233                    this parameter is not an account type */
3234                 return NT_STATUS_INVALID_PARAMETER;
3235         }
3236
3237         account = r->in.account_name->string;
3238         if (account == NULL) {
3239                 return NT_STATUS_NO_MEMORY;
3240         }
3241
3242         nt_status = can_create(p->mem_ctx, account);
3243         if (!NT_STATUS_IS_OK(nt_status)) {
3244                 return nt_status;
3245         }
3246
3247         /* determine which user right we need to check based on the acb_info */
3248
3249         if ( acb_info & ACB_WSTRUST )
3250         {
3251                 se_priv_copy( &se_rights, &se_machine_account );
3252                 can_add_account = user_has_privileges(
3253                         p->pipe_user.nt_user_token, &se_rights );
3254         }
3255         /* usrmgr.exe (and net rpc trustdom grant) creates a normal user
3256            account for domain trusts and changes the ACB flags later */
3257         else if ( acb_info & ACB_NORMAL &&
3258                   (account[strlen(account)-1] != '$') )
3259         {
3260                 se_priv_copy( &se_rights, &se_add_users );
3261                 can_add_account = user_has_privileges(
3262                         p->pipe_user.nt_user_token, &se_rights );
3263         }
3264         else    /* implicit assumption of a BDC or domain trust account here
3265                  * (we already check the flags earlier) */
3266         {
3267                 if ( lp_enable_privileges() ) {
3268                         /* only Domain Admins can add a BDC or domain trust */
3269                         se_priv_copy( &se_rights, &se_priv_none );
3270                         can_add_account = nt_token_check_domain_rid(
3271                                 p->pipe_user.nt_user_token,
3272                                 DOMAIN_GROUP_RID_ADMINS );
3273                 }
3274         }
3275
3276         DEBUG(5, ("_samr_CreateUser2: %s can add this account : %s\n",
3277                   uidtoname(p->pipe_user.ut.uid),
3278                   can_add_account ? "True":"False" ));
3279
3280         /********** BEGIN Admin BLOCK **********/
3281
3282         if ( can_add_account )
3283                 become_root();
3284
3285         nt_status = pdb_create_user(p->mem_ctx, account, acb_info,
3286                                     r->out.rid);
3287
3288         if ( can_add_account )
3289                 unbecome_root();
3290
3291         /********** END Admin BLOCK **********/
3292
3293         /* now check for failure */
3294
3295         if ( !NT_STATUS_IS_OK(nt_status) )
3296                 return nt_status;
3297
3298         /* Get the user's SID */
3299
3300         sid_compose(&sid, get_global_sam_sid(), *r->out.rid);
3301
3302         map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
3303
3304         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping,
3305                             &sid, SAMR_USR_RIGHTS_WRITE_PW);
3306         se_map_generic(&des_access, &usr_generic_mapping);
3307
3308         nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3309                 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
3310                 &acc_granted, "_samr_CreateUser2");
3311
3312         if ( !NT_STATUS_IS_OK(nt_status) ) {
3313                 return nt_status;
3314         }
3315
3316         /* associate the user's SID with the new handle. */
3317         if ((info = get_samr_info_by_sid(&sid)) == NULL) {
3318                 return NT_STATUS_NO_MEMORY;
3319         }
3320
3321         ZERO_STRUCTP(info);
3322         info->sid = sid;
3323         info->acc_granted = acc_granted;
3324
3325         /* get a (unique) handle.  open a policy on it. */
3326         if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info)) {
3327                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3328         }
3329
3330         /* After a "set" ensure we have no cached display info. */
3331         force_flush_samr_cache(info->disp_info);
3332
3333         *r->out.access_granted = acc_granted;
3334
3335         return NT_STATUS_OK;
3336 }
3337
3338 /****************************************************************
3339 ****************************************************************/
3340
3341 NTSTATUS _samr_CreateUser(pipes_struct *p,
3342                           struct samr_CreateUser *r)
3343 {
3344         struct samr_CreateUser2 c;
3345         uint32_t access_granted;
3346
3347         c.in.domain_handle      = r->in.domain_handle;
3348         c.in.account_name       = r->in.account_name;
3349         c.in.acct_flags         = ACB_NORMAL;
3350         c.in.access_mask        = r->in.access_mask;
3351         c.out.user_handle       = r->out.user_handle;
3352         c.out.access_granted    = &access_granted;
3353         c.out.rid               = r->out.rid;
3354
3355         return _samr_CreateUser2(p, &c);
3356 }
3357
3358 /*******************************************************************
3359  _samr_Connect
3360  ********************************************************************/
3361
3362 NTSTATUS _samr_Connect(pipes_struct *p,
3363                        struct samr_Connect *r)
3364 {
3365         struct samr_info *info = NULL;
3366         uint32    des_access = r->in.access_mask;
3367
3368         /* Access check */
3369
3370         if (!pipe_access_check(p)) {
3371                 DEBUG(3, ("access denied to _samr_Connect\n"));
3372                 return NT_STATUS_ACCESS_DENIED;
3373         }
3374
3375         /* set up the SAMR connect_anon response */
3376
3377         /* associate the user's SID with the new handle. */
3378         if ((info = get_samr_info_by_sid(NULL)) == NULL)
3379                 return NT_STATUS_NO_MEMORY;
3380
3381         /* don't give away the farm but this is probably ok.  The SAMR_ACCESS_ENUM_DOMAINS
3382            was observed from a win98 client trying to enumerate users (when configured
3383            user level access control on shares)   --jerry */
3384
3385         map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
3386
3387         se_map_generic( &des_access, &sam_generic_mapping );
3388         info->acc_granted = des_access & (SAMR_ACCESS_ENUM_DOMAINS|SAMR_ACCESS_OPEN_DOMAIN);
3389
3390         /* get a (unique) handle.  open a policy on it. */
3391         if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info))
3392                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3393
3394         return NT_STATUS_OK;
3395 }
3396
3397 /*******************************************************************
3398  _samr_Connect2
3399  ********************************************************************/
3400
3401 NTSTATUS _samr_Connect2(pipes_struct *p,
3402                         struct samr_Connect2 *r)
3403 {
3404         struct samr_info *info = NULL;
3405         SEC_DESC *psd = NULL;
3406         uint32    acc_granted;
3407         uint32    des_access = r->in.access_mask;
3408         NTSTATUS  nt_status;
3409         size_t    sd_size;
3410
3411
3412         DEBUG(5,("_samr_Connect2: %d\n", __LINE__));
3413
3414         /* Access check */
3415
3416         if (!pipe_access_check(p)) {
3417                 DEBUG(3, ("access denied to _samr_Connect2\n"));
3418                 return NT_STATUS_ACCESS_DENIED;
3419         }
3420
3421         map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
3422
3423         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
3424         se_map_generic(&des_access, &sam_generic_mapping);
3425
3426         nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3427                 NULL, 0, des_access, &acc_granted, "_samr_Connect2");
3428
3429         if ( !NT_STATUS_IS_OK(nt_status) )
3430                 return nt_status;
3431
3432         /* associate the user's SID and access granted with the new handle. */
3433         if ((info = get_samr_info_by_sid(NULL)) == NULL)
3434                 return NT_STATUS_NO_MEMORY;
3435
3436         info->acc_granted = acc_granted;
3437         info->status = r->in.access_mask; /* this looks so wrong... - gd */
3438
3439         /* get a (unique) handle.  open a policy on it. */
3440         if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info))
3441                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3442
3443         DEBUG(5,("_samr_Connect2: %d\n", __LINE__));
3444
3445         return nt_status;
3446 }
3447
3448 /*******************************************************************
3449  _samr_Connect4
3450  ********************************************************************/
3451
3452 NTSTATUS _samr_Connect4(pipes_struct *p,
3453                         struct samr_Connect4 *r)
3454 {
3455         struct samr_info *info = NULL;
3456         SEC_DESC *psd = NULL;
3457         uint32    acc_granted;
3458         uint32    des_access = r->in.access_mask;
3459         NTSTATUS  nt_status;
3460         size_t    sd_size;
3461
3462
3463         DEBUG(5,("_samr_Connect4: %d\n", __LINE__));
3464
3465         /* Access check */
3466
3467         if (!pipe_access_check(p)) {
3468                 DEBUG(3, ("access denied to samr_Connect4\n"));
3469                 return NT_STATUS_ACCESS_DENIED;
3470         }
3471
3472         map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
3473
3474         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
3475         se_map_generic(&des_access, &sam_generic_mapping);
3476
3477         nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3478                 NULL, 0, des_access, &acc_granted, "_samr_Connect4");
3479
3480         if ( !NT_STATUS_IS_OK(nt_status) )
3481                 return nt_status;
3482
3483         /* associate the user's SID and access granted with the new handle. */
3484         if ((info = get_samr_info_by_sid(NULL)) == NULL)
3485                 return NT_STATUS_NO_MEMORY;
3486
3487         info->acc_granted = acc_granted;
3488         info->status = r->in.access_mask; /* ??? */
3489
3490         /* get a (unique) handle.  open a policy on it. */
3491         if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info))
3492                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3493
3494         DEBUG(5,("_samr_Connect4: %d\n", __LINE__));
3495
3496         return NT_STATUS_OK;
3497 }
3498
3499 /*******************************************************************
3500  _samr_Connect5
3501  ********************************************************************/
3502
3503 NTSTATUS _samr_Connect5(pipes_struct *p,
3504                         struct samr_Connect5 *r)
3505 {
3506         struct samr_info *info = NULL;
3507         SEC_DESC *psd = NULL;
3508         uint32    acc_granted;
3509         uint32    des_access = r->in.access_mask;
3510         NTSTATUS  nt_status;
3511         size_t    sd_size;
3512         struct samr_ConnectInfo1 info1;
3513
3514         DEBUG(5,("_samr_Connect5: %d\n", __LINE__));
3515
3516         /* Access check */
3517
3518         if (!pipe_access_check(p)) {
3519                 DEBUG(3, ("access denied to samr_Connect5\n"));
3520                 return NT_STATUS_ACCESS_DENIED;
3521         }
3522
3523         map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
3524
3525         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
3526         se_map_generic(&des_access, &sam_generic_mapping);
3527
3528         nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3529                 NULL, 0, des_access, &acc_granted, "_samr_Connect5");
3530
3531         if ( !NT_STATUS_IS_OK(nt_status) )
3532                 return nt_status;
3533
3534         /* associate the user's SID and access granted with the new handle. */
3535         if ((info = get_samr_info_by_sid(NULL)) == NULL)
3536                 return NT_STATUS_NO_MEMORY;
3537
3538         info->acc_granted = acc_granted;
3539         info->status = r->in.access_mask; /* ??? */
3540
3541         /* get a (unique) handle.  open a policy on it. */
3542         if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info))
3543                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3544
3545         DEBUG(5,("_samr_Connect5: %d\n", __LINE__));
3546
3547         info1.client_version = SAMR_CONNECT_AFTER_W2K;
3548         info1.unknown2 = 0;
3549
3550         *r->out.level_out = 1;
3551         r->out.info_out->info1 = info1;
3552
3553         return NT_STATUS_OK;
3554 }
3555
3556 /**********************************************************************
3557  _samr_LookupDomain
3558  **********************************************************************/
3559
3560 NTSTATUS _samr_LookupDomain(pipes_struct *p,
3561                             struct samr_LookupDomain *r)
3562 {
3563         NTSTATUS status = NT_STATUS_OK;
3564         struct samr_info *info;
3565         const char *domain_name;
3566         DOM_SID *sid = NULL;
3567
3568         if (!find_policy_by_hnd(p, r->in.connect_handle, (void**)(void *)&info))
3569                 return NT_STATUS_INVALID_HANDLE;
3570
3571         /* win9x user manager likes to use SAMR_ACCESS_ENUM_DOMAINS here.
3572            Reverted that change so we will work with RAS servers again */
3573
3574         status = access_check_samr_function(info->acc_granted,
3575                                             SAMR_ACCESS_OPEN_DOMAIN,
3576                                             "_samr_LookupDomain");
3577         if (!NT_STATUS_IS_OK(status)) {
3578                 return status;
3579         }
3580
3581         domain_name = r->in.domain_name->string;
3582         if (!domain_name) {
3583                 return NT_STATUS_INVALID_PARAMETER;
3584         }
3585
3586         sid = TALLOC_ZERO_P(p->mem_ctx, struct dom_sid2);
3587         if (!sid) {
3588                 return NT_STATUS_NO_MEMORY;
3589         }
3590
3591         if (strequal(domain_name, builtin_domain_name())) {
3592                 sid_copy(sid, &global_sid_Builtin);
3593         } else {
3594                 if (!secrets_fetch_domain_sid(domain_name, sid)) {
3595                         status = NT_STATUS_NO_SUCH_DOMAIN;
3596                 }
3597         }
3598
3599         DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name,
3600                  sid_string_dbg(sid)));
3601
3602         *r->out.sid = sid;
3603
3604         return status;
3605 }
3606
3607 /**********************************************************************
3608  _samr_EnumDomains
3609  **********************************************************************/
3610
3611 NTSTATUS _samr_EnumDomains(pipes_struct *p,
3612                            struct samr_EnumDomains *r)
3613 {
3614         NTSTATUS status;
3615         struct samr_info *info;
3616         uint32_t num_entries = 2;
3617         struct samr_SamEntry *entry_array = NULL;
3618         struct samr_SamArray *sam;
3619
3620         if (!find_policy_by_hnd(p, r->in.connect_handle, (void**)(void *)&info))
3621                 return NT_STATUS_INVALID_HANDLE;
3622
3623         status = access_check_samr_function(info->acc_granted,
3624                                             SAMR_ACCESS_ENUM_DOMAINS,
3625                                             "_samr_EnumDomains");
3626         if (!NT_STATUS_IS_OK(status)) {
3627                 return status;
3628         }
3629
3630         sam = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
3631         if (!sam) {
3632                 return NT_STATUS_NO_MEMORY;
3633         }
3634
3635         entry_array = TALLOC_ZERO_ARRAY(p->mem_ctx,
3636                                         struct samr_SamEntry,
3637                                         num_entries);
3638         if (!entry_array) {
3639                 return NT_STATUS_NO_MEMORY;
3640         }
3641
3642         entry_array[0].idx = 0;
3643         init_lsa_String(&entry_array[0].name, get_global_sam_name());
3644
3645         entry_array[1].idx = 1;
3646         init_lsa_String(&entry_array[1].name, "Builtin");
3647
3648         sam->count = num_entries;
3649         sam->entries = entry_array;
3650
3651         *r->out.sam = sam;
3652         *r->out.num_entries = num_entries;
3653
3654         return status;
3655 }
3656
3657 /*******************************************************************
3658  _samr_OpenAlias
3659  ********************************************************************/
3660
3661 NTSTATUS _samr_OpenAlias(pipes_struct *p,
3662                          struct samr_OpenAlias *r)
3663 {
3664         DOM_SID sid;
3665         POLICY_HND domain_pol = *r->in.domain_handle;
3666         uint32 alias_rid = r->in.rid;
3667         POLICY_HND *alias_pol = r->out.alias_handle;
3668         struct    samr_info *info = NULL;
3669         SEC_DESC *psd = NULL;
3670         uint32    acc_granted;
3671         uint32    des_access = r->in.access_mask;
3672         size_t    sd_size;
3673         NTSTATUS  status;
3674         SE_PRIV se_rights;
3675
3676         /* find the domain policy and get the SID / access bits stored in the domain policy */
3677
3678         if ( !get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted, NULL) )
3679                 return NT_STATUS_INVALID_HANDLE;
3680
3681         status = access_check_samr_function(acc_granted,
3682                                             SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
3683                                             "_samr_OpenAlias");
3684
3685         if ( !NT_STATUS_IS_OK(status) )
3686                 return status;
3687
3688         /* append the alias' RID to it */
3689
3690         if (!sid_append_rid(&sid, alias_rid))
3691                 return NT_STATUS_NO_SUCH_ALIAS;
3692
3693         /*check if access can be granted as requested by client. */
3694
3695         map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
3696
3697         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &ali_generic_mapping, NULL, 0);
3698         se_map_generic(&des_access,&ali_generic_mapping);
3699
3700         se_priv_copy( &se_rights, &se_add_users );
3701
3702
3703         status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3704                 &se_rights, GENERIC_RIGHTS_ALIAS_WRITE, des_access,
3705                 &acc_granted, "_samr_OpenAlias");
3706
3707         if ( !NT_STATUS_IS_OK(status) )
3708                 return status;
3709
3710         {
3711                 /* Check we actually have the requested alias */
3712                 enum lsa_SidType type;
3713                 bool result;
3714                 gid_t gid;
3715
3716                 become_root();
3717                 result = lookup_sid(NULL, &sid, NULL, NULL, &type);
3718                 unbecome_root();
3719
3720                 if (!result || (type != SID_NAME_ALIAS)) {
3721                         return NT_STATUS_NO_SUCH_ALIAS;
3722                 }
3723
3724                 /* make sure there is a mapping */
3725
3726                 if ( !sid_to_gid( &sid, &gid ) ) {
3727                         return NT_STATUS_NO_SUCH_ALIAS;
3728                 }
3729
3730         }
3731
3732         /* associate the alias SID with the new handle. */
3733         if ((info = get_samr_info_by_sid(&sid)) == NULL)
3734                 return NT_STATUS_NO_MEMORY;
3735
3736         info->acc_granted = acc_granted;
3737
3738         /* get a (unique) handle.  open a policy on it. */
3739         if (!create_policy_hnd(p, alias_pol, free_samr_info, (void *)info))
3740                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3741
3742         return NT_STATUS_OK;
3743 }
3744
3745 /*******************************************************************
3746  set_user_info_7
3747  ********************************************************************/
3748
3749 static NTSTATUS set_user_info_7(TALLOC_CTX *mem_ctx,
3750                                 struct samr_UserInfo7 *id7,
3751                                 struct samu *pwd)
3752 {
3753         NTSTATUS rc;
3754
3755         if (id7 == NULL) {
3756                 DEBUG(5, ("set_user_info_7: NULL id7\n"));
3757                 return NT_STATUS_ACCESS_DENIED;
3758         }
3759
3760         if (!id7->account_name.string) {
3761                 DEBUG(5, ("set_user_info_7: failed to get new username\n"));
3762                 return NT_STATUS_ACCESS_DENIED;
3763         }
3764
3765         /* check to see if the new username already exists.  Note: we can't
3766            reliably lock all backends, so there is potentially the
3767            possibility that a user can be created in between this check and
3768            the rename.  The rename should fail, but may not get the
3769            exact same failure status code.  I think this is small enough
3770            of a window for this type of operation and the results are
3771            simply that the rename fails with a slightly different status
3772            code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
3773
3774         rc = can_create(mem_ctx, id7->account_name.string);
3775         if (!NT_STATUS_IS_OK(rc)) {
3776                 return rc;
3777         }
3778
3779         rc = pdb_rename_sam_account(pwd, id7->account_name.string);
3780
3781         return rc;
3782 }
3783
3784 /*******************************************************************
3785  set_user_info_16
3786  ********************************************************************/
3787
3788 static bool set_user_info_16(struct samr_UserInfo16 *id16,
3789                              struct samu *pwd)
3790 {
3791         if (id16 == NULL) {
3792                 DEBUG(5, ("set_user_info_16: NULL id16\n"));
3793                 return False;
3794         }
3795
3796         /* FIX ME: check if the value is really changed --metze */
3797         if (!pdb_set_acct_ctrl(pwd, id16->acct_flags, PDB_CHANGED)) {
3798                 return False;
3799         }
3800
3801         if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3802                 return False;
3803         }
3804
3805         return True;
3806 }
3807
3808 /*******************************************************************
3809  set_user_info_18
3810  ********************************************************************/
3811
3812 static bool set_user_info_18(struct samr_UserInfo18 *id18,
3813                              struct samu *pwd)
3814 {
3815         if (id18 == NULL) {
3816                 DEBUG(2, ("set_user_info_18: id18 is NULL\n"));
3817                 return False;
3818         }
3819
3820         if (!pdb_set_lanman_passwd (pwd, id18->lm_pwd.hash, PDB_CHANGED)) {
3821                 return False;
3822         }
3823         if (!pdb_set_nt_passwd     (pwd, id18->nt_pwd.hash, PDB_CHANGED)) {
3824                 return False;
3825         }
3826         if (!pdb_set_pass_last_set_time (pwd, time(NULL), PDB_CHANGED)) {
3827                 return False;
3828         }
3829
3830         if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3831                 return False;
3832         }
3833
3834         return True;
3835 }
3836
3837 /*******************************************************************
3838  set_user_info_20
3839  ********************************************************************/
3840
3841 static bool set_user_info_20(struct samr_UserInfo20 *id20,
3842                              struct samu *pwd)
3843 {
3844         if (id20 == NULL) {
3845                 DEBUG(5, ("set_user_info_20: NULL id20\n"));
3846                 return False;
3847         }
3848
3849         copy_id20_to_sam_passwd(pwd, id20);
3850
3851         /* write the change out */
3852         if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3853                 return False;
3854         }
3855
3856         return True;
3857 }
3858
3859 /*******************************************************************
3860  set_user_info_21
3861  ********************************************************************/
3862
3863 static NTSTATUS set_user_info_21(TALLOC_CTX *mem_ctx,
3864                                  struct samr_UserInfo21 *id21,
3865                                  struct samu *pwd)
3866 {
3867         NTSTATUS status;
3868
3869         if (id21 == NULL) {
3870                 DEBUG(5, ("set_user_info_21: NULL id21\n"));
3871                 return NT_STATUS_INVALID_PARAMETER;
3872         }
3873
3874         if (id21->fields_present == 0) {
3875                 return NT_STATUS_INVALID_PARAMETER;
3876         }
3877
3878         if (id21->fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
3879                 return NT_STATUS_ACCESS_DENIED;
3880         }
3881
3882         /* we need to separately check for an account rename first */
3883
3884         if (id21->account_name.string &&
3885             (!strequal(id21->account_name.string, pdb_get_username(pwd))))
3886         {
3887
3888                 /* check to see if the new username already exists.  Note: we can't
3889                    reliably lock all backends, so there is potentially the
3890                    possibility that a user can be created in between this check and
3891                    the rename.  The rename should fail, but may not get the
3892                    exact same failure status code.  I think this is small enough
3893                    of a window for this type of operation and the results are
3894                    simply that the rename fails with a slightly different status
3895                    code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
3896
3897                 status = can_create(mem_ctx, id21->account_name.string);
3898                 if (!NT_STATUS_IS_OK(status)) {
3899                         return status;
3900                 }
3901
3902                 status = pdb_rename_sam_account(pwd, id21->account_name.string);
3903
3904                 if (!NT_STATUS_IS_OK(status)) {
3905                         DEBUG(0,("set_user_info_21: failed to rename account: %s\n",
3906                                 nt_errstr(status)));
3907                         return status;
3908                 }
3909
3910                 /* set the new username so that later
3911                    functions can work on the new account */
3912                 pdb_set_username(pwd, id21->account_name.string, PDB_SET);
3913         }
3914
3915         copy_id21_to_sam_passwd("INFO_21", pwd, id21);
3916
3917         /*
3918          * The funny part about the previous two calls is
3919          * that pwd still has the password hashes from the
3920          * passdb entry.  These have not been updated from
3921          * id21.  I don't know if they need to be set.    --jerry
3922          */
3923
3924         if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
3925                 status = pdb_set_unix_primary_group(mem_ctx, pwd);
3926                 if ( !NT_STATUS_IS_OK(status) ) {
3927                         return status;
3928                 }
3929         }
3930
3931         /* Don't worry about writing out the user account since the
3932            primary group SID is generated solely from the user's Unix
3933            primary group. */
3934
3935         /* write the change out */
3936         if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
3937                 return status;
3938         }
3939
3940         return NT_STATUS_OK;
3941 }
3942
3943 /*******************************************************************
3944  set_user_info_23
3945  ********************************************************************/
3946
3947 static NTSTATUS set_user_info_23(TALLOC_CTX *mem_ctx,
3948                                  struct samr_UserInfo23 *id23,
3949                                  struct samu *pwd)
3950 {
3951         char *plaintext_buf = NULL;
3952         uint32 len = 0;
3953         uint32_t acct_ctrl;
3954         NTSTATUS status;
3955
3956         if (id23 == NULL) {
3957                 DEBUG(5, ("set_user_info_23: NULL id23\n"));
3958                 return NT_STATUS_INVALID_PARAMETER;
3959         }
3960
3961         if (id23->info.fields_present == 0) {
3962                 return NT_STATUS_INVALID_PARAMETER;
3963         }
3964
3965         if (id23->info.fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
3966                 return NT_STATUS_ACCESS_DENIED;
3967         }
3968
3969         if ((id23->info.fields_present & SAMR_FIELD_PASSWORD) ||
3970             (id23->info.fields_present & SAMR_FIELD_PASSWORD2)) {
3971
3972                 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
3973                           pdb_get_username(pwd)));
3974
3975                 if (!decode_pw_buffer(mem_ctx,
3976                                       id23->password.data,
3977                                       &plaintext_buf,
3978                                       &len,
3979                                       STR_UNICODE)) {
3980                         return NT_STATUS_WRONG_PASSWORD;
3981                 }
3982
3983                 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
3984                         return NT_STATUS_ACCESS_DENIED;
3985                 }
3986         }
3987
3988         copy_id23_to_sam_passwd(pwd, id23);
3989
3990         acct_ctrl = pdb_get_acct_ctrl(pwd);
3991
3992         /* if it's a trust account, don't update /etc/passwd */
3993         if (    ( (acct_ctrl &  ACB_DOMTRUST) == ACB_DOMTRUST ) ||
3994                 ( (acct_ctrl &  ACB_WSTRUST) ==  ACB_WSTRUST) ||
3995                 ( (acct_ctrl &  ACB_SVRTRUST) ==  ACB_SVRTRUST) ) {
3996                 DEBUG(5, ("Changing trust account.  Not updating /etc/passwd\n"));
3997         } else if (plaintext_buf) {
3998                 /* update the UNIX password */
3999                 if (lp_unix_password_sync() ) {
4000                         struct passwd *passwd;
4001                         if (pdb_get_username(pwd) == NULL) {
4002                                 DEBUG(1, ("chgpasswd: User without name???\n"));
4003                                 return NT_STATUS_ACCESS_DENIED;
4004                         }
4005
4006                         passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
4007                         if (passwd == NULL) {
4008                                 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
4009                         }
4010
4011                         if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
4012                                 return NT_STATUS_ACCESS_DENIED;
4013                         }
4014                         TALLOC_FREE(passwd);
4015                 }
4016         }
4017
4018         if (plaintext_buf) {
4019                 memset(plaintext_buf, '\0', strlen(plaintext_buf));
4020         }
4021
4022         if (IS_SAM_CHANGED(pwd, PDB_GROUPSID) &&
4023             (!NT_STATUS_IS_OK(status =  pdb_set_unix_primary_group(mem_ctx,
4024                                                                    pwd)))) {
4025                 return status;
4026         }
4027
4028         if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4029                 return status;
4030         }
4031
4032         return NT_STATUS_OK;
4033 }
4034
4035 /*******************************************************************
4036  set_user_info_pw
4037  ********************************************************************/
4038
4039 static bool set_user_info_pw(uint8 *pass, struct samu *pwd,
4040                              int level)
4041 {
4042         uint32 len = 0;
4043         char *plaintext_buf = NULL;
4044         uint32 acct_ctrl;
4045         time_t last_set_time;
4046         enum pdb_value_state last_set_state;
4047
4048         DEBUG(5, ("Attempting administrator password change for user %s\n",
4049                   pdb_get_username(pwd)));
4050
4051         acct_ctrl = pdb_get_acct_ctrl(pwd);
4052         /* we need to know if it's expired, because this is an admin change, not a
4053            user change, so it's still expired when we're done */
4054         last_set_state = pdb_get_init_flags(pwd, PDB_PASSLASTSET);
4055         last_set_time = pdb_get_pass_last_set_time(pwd);
4056
4057         if (!decode_pw_buffer(talloc_tos(),
4058                                 pass,
4059                                 &plaintext_buf,
4060                                 &len,
4061                                 STR_UNICODE)) {
4062                 return False;
4063         }
4064
4065         if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
4066                 return False;
4067         }
4068
4069         /* if it's a trust account, don't update /etc/passwd */
4070         if ( ( (acct_ctrl &  ACB_DOMTRUST) == ACB_DOMTRUST ) ||
4071                 ( (acct_ctrl &  ACB_WSTRUST) ==  ACB_WSTRUST) ||
4072                 ( (acct_ctrl &  ACB_SVRTRUST) ==  ACB_SVRTRUST) ) {
4073                 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
4074         } else {
4075                 /* update the UNIX password */
4076                 if (lp_unix_password_sync()) {
4077                         struct passwd *passwd;
4078
4079                         if (pdb_get_username(pwd) == NULL) {
4080                                 DEBUG(1, ("chgpasswd: User without name???\n"));
4081                                 return False;
4082                         }
4083
4084                         passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
4085                         if (passwd == NULL) {
4086                                 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
4087                         }
4088
4089                         if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
4090                                 return False;
4091                         }
4092                         TALLOC_FREE(passwd);
4093                 }
4094         }
4095
4096         memset(plaintext_buf, '\0', strlen(plaintext_buf));
4097
4098         /*
4099          * A level 25 change does reset the pwdlastset field, a level 24
4100          * change does not. I know this is probably not the full story, but
4101          * it is needed to make XP join LDAP correctly, without it the later
4102          * auth2 check can fail with PWD_MUST_CHANGE.
4103          */
4104         if (level != 25) {
4105                 /*
4106                  * restore last set time as this is an admin change, not a
4107                  * user pw change
4108                  */
4109                 pdb_set_pass_last_set_time (pwd, last_set_time,
4110                                             last_set_state);
4111         }
4112
4113         DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
4114
4115         /* update the SAMBA password */
4116         if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
4117                 return False;
4118         }
4119
4120         return True;
4121 }
4122
4123 /*******************************************************************
4124  set_user_info_25
4125  ********************************************************************/
4126
4127 static NTSTATUS set_user_info_25(TALLOC_CTX *mem_ctx,
4128                                  struct samr_UserInfo25 *id25,
4129                                  struct samu *pwd)
4130 {
4131         NTSTATUS status;
4132
4133         if (id25 == NULL) {
4134                 DEBUG(5, ("set_user_info_25: NULL id25\n"));
4135                 return NT_STATUS_INVALID_PARAMETER;
4136         }
4137
4138         if (id25->info.fields_present == 0) {
4139                 return NT_STATUS_INVALID_PARAMETER;
4140         }
4141
4142         if (id25->info.fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
4143                 return NT_STATUS_ACCESS_DENIED;
4144         }
4145
4146         copy_id25_to_sam_passwd(pwd, id25);
4147
4148         /* write the change out */
4149         if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4150                 return status;
4151         }
4152
4153         /*
4154          * We need to "pdb_update_sam_account" before the unix primary group
4155          * is set, because the idealx scripts would also change the
4156          * sambaPrimaryGroupSid using the ldap replace method. pdb_ldap uses
4157          * the delete explicit / add explicit, which would then fail to find
4158          * the previous primaryGroupSid value.
4159          */
4160
4161         if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
4162                 status = pdb_set_unix_primary_group(mem_ctx, pwd);
4163                 if ( !NT_STATUS_IS_OK(status) ) {
4164                         return status;
4165                 }
4166         }
4167
4168         return NT_STATUS_OK;
4169 }
4170
4171 /*******************************************************************
4172  samr_SetUserInfo
4173  ********************************************************************/
4174
4175 NTSTATUS _samr_SetUserInfo(pipes_struct *p,
4176                            struct samr_SetUserInfo *r)
4177 {
4178         NTSTATUS status;
4179         struct samu *pwd = NULL;
4180         DOM_SID sid;
4181         POLICY_HND *pol = r->in.user_handle;
4182         union samr_UserInfo *info = r->in.info;
4183         uint16_t switch_value = r->in.level;
4184         uint32_t acc_granted;
4185         uint32_t acc_required;
4186         bool ret;
4187         bool has_enough_rights = False;
4188         uint32_t acb_info;
4189         DISP_INFO *disp_info = NULL;
4190
4191         DEBUG(5,("_samr_SetUserInfo: %d\n", __LINE__));
4192
4193         /* find the policy handle.  open a policy on it. */
4194         if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted, &disp_info)) {
4195                 return NT_STATUS_INVALID_HANDLE;
4196         }
4197
4198         /* This is tricky.  A WinXP domain join sets
4199           (SAMR_USER_ACCESS_SET_PASSWORD|SAMR_USER_ACCESS_SET_ATTRIBUTES|SAMR_USER_ACCESS_GET_ATTRIBUTES)
4200           The MMC lusrmgr plugin includes these perms and more in the SamrOpenUser().  But the
4201           standard Win32 API calls just ask for SAMR_USER_ACCESS_SET_PASSWORD in the SamrOpenUser().
4202           This should be enough for levels 18, 24, 25,& 26.  Info level 23 can set more so
4203           we'll use the set from the WinXP join as the basis. */
4204
4205         switch (switch_value) {
4206         case 18:
4207         case 24:
4208         case 25:
4209         case 26:
4210                 acc_required = SAMR_USER_ACCESS_SET_PASSWORD;
4211                 break;
4212         default:
4213                 acc_required = SAMR_USER_ACCESS_SET_PASSWORD |
4214                                SAMR_USER_ACCESS_SET_ATTRIBUTES |
4215                                SAMR_USER_ACCESS_GET_ATTRIBUTES;
4216                 break;
4217         }
4218
4219         status = access_check_samr_function(acc_granted,
4220                                             acc_required,
4221                                             "_samr_SetUserInfo");
4222         if (!NT_STATUS_IS_OK(status)) {
4223                 return status;
4224         }
4225
4226         DEBUG(5, ("_samr_SetUserInfo: sid:%s, level:%d\n",
4227                   sid_string_dbg(&sid), switch_value));
4228
4229         if (info == NULL) {
4230                 DEBUG(5, ("_samr_SetUserInfo: NULL info level\n"));
4231                 return NT_STATUS_INVALID_INFO_CLASS;
4232         }
4233
4234         if (!(pwd = samu_new(NULL))) {
4235                 return NT_STATUS_NO_MEMORY;
4236         }
4237
4238         become_root();
4239         ret = pdb_getsampwsid(pwd, &sid);
4240         unbecome_root();
4241
4242         if (!ret) {
4243                 TALLOC_FREE(pwd);
4244                 return NT_STATUS_NO_SUCH_USER;
4245         }
4246
4247         /* deal with machine password changes differently from userinfo changes */
4248         /* check to see if we have the sufficient rights */
4249
4250         acb_info = pdb_get_acct_ctrl(pwd);
4251         if (acb_info & ACB_WSTRUST)
4252                 has_enough_rights = user_has_privileges(p->pipe_user.nt_user_token,
4253                                                         &se_machine_account);
4254         else if (acb_info & ACB_NORMAL)
4255                 has_enough_rights = user_has_privileges(p->pipe_user.nt_user_token,
4256                                                         &se_add_users);
4257         else if (acb_info & (ACB_SVRTRUST|ACB_DOMTRUST)) {
4258                 if (lp_enable_privileges()) {
4259                         has_enough_rights = nt_token_check_domain_rid(p->pipe_user.nt_user_token,
4260                                                                       DOMAIN_GROUP_RID_ADMINS);
4261                 }
4262         }
4263
4264         DEBUG(5, ("_samr_SetUserInfo: %s does%s possess sufficient rights\n",
4265                   uidtoname(p->pipe_user.ut.uid),
4266                   has_enough_rights ? "" : " not"));
4267
4268         /* ================ BEGIN SeMachineAccountPrivilege BLOCK ================ */
4269
4270         if (has_enough_rights) {
4271                 become_root();
4272         }
4273
4274         /* ok!  user info levels (lots: see MSDEV help), off we go... */
4275
4276         switch (switch_value) {
4277
4278                 case 7:
4279                         status = set_user_info_7(p->mem_ctx,
4280                                                  &info->info7, pwd);
4281                         break;
4282
4283                 case 16:
4284                         if (!set_user_info_16(&info->info16, pwd)) {
4285                                 status = NT_STATUS_ACCESS_DENIED;
4286                         }
4287                         break;
4288
4289                 case 18:
4290                         /* Used by AS/U JRA. */
4291                         if (!set_user_info_18(&info->info18, pwd)) {
4292                                 status = NT_STATUS_ACCESS_DENIED;
4293                         }
4294                         break;
4295
4296                 case 20:
4297                         if (!set_user_info_20(&info->info20, pwd)) {
4298                                 status = NT_STATUS_ACCESS_DENIED;
4299                         }
4300                         break;
4301
4302                 case 21:
4303                         status = set_user_info_21(p->mem_ctx,
4304                                                   &info->info21, pwd);
4305                         break;
4306
4307                 case 23:
4308                         if (!p->server_info->user_session_key.length) {
4309                                 status = NT_STATUS_NO_USER_SESSION_KEY;
4310                         }
4311                         SamOEMhashBlob(info->info23.password.data, 516,
4312                                        &p->server_info->user_session_key);
4313
4314                         dump_data(100, info->info23.password.data, 516);
4315
4316                         status = set_user_info_23(p->mem_ctx,
4317                                                   &info->info23, pwd);
4318                         break;
4319
4320                 case 24:
4321                         if (!p->server_info->user_session_key.length) {
4322                                 status = NT_STATUS_NO_USER_SESSION_KEY;
4323                         }
4324                         SamOEMhashBlob(info->info24.password.data,
4325                                        516,
4326                                        &p->server_info->user_session_key);
4327
4328                         dump_data(100, info->info24.password.data, 516);
4329
4330                         if (!set_user_info_pw(info->info24.password.data, pwd,
4331                                               switch_value)) {
4332                                 status = NT_STATUS_WRONG_PASSWORD;
4333                         }
4334                         break;
4335
4336                 case 25:
4337                         if (!p->server_info->user_session_key.length) {
4338                                 status = NT_STATUS_NO_USER_SESSION_KEY;
4339                         }
4340                         encode_or_decode_arc4_passwd_buffer(
4341                                 info->info25.password.data,
4342                                 &p->server_info->user_session_key);
4343
4344                         dump_data(100, info->info25.password.data, 532);
4345
4346                         status = set_user_info_25(p->mem_ctx,
4347                                                   &info->info25, pwd);
4348                         if (!NT_STATUS_IS_OK(status)) {
4349                                 goto done;
4350                         }
4351                         if (!set_user_info_pw(info->info25.password.data, pwd,
4352                                               switch_value)) {
4353                                 status = NT_STATUS_WRONG_PASSWORD;
4354                         }
4355                         break;
4356
4357                 case 26:
4358                         if (!p->server_info->user_session_key.length) {
4359                                 status = NT_STATUS_NO_USER_SESSION_KEY;
4360                         }
4361                         encode_or_decode_arc4_passwd_buffer(
4362                                 info->info26.password.data,
4363                                 &p->server_info->user_session_key);
4364
4365                         dump_data(100, info->info26.password.data, 516);
4366
4367                         if (!set_user_info_pw(info->info26.password.data, pwd,
4368                                               switch_value)) {
4369                                 status = NT_STATUS_WRONG_PASSWORD;
4370                         }
4371                         break;
4372
4373                 default:
4374                         status = NT_STATUS_INVALID_INFO_CLASS;
4375         }
4376
4377  done:
4378
4379         TALLOC_FREE(pwd);
4380
4381         if (has_enough_rights) {
4382                 unbecome_root();
4383         }
4384
4385         /* ================ END SeMachineAccountPrivilege BLOCK ================ */
4386
4387         if (NT_STATUS_IS_OK(status)) {
4388                 force_flush_samr_cache(disp_info);
4389         }
4390
4391         return status;
4392 }
4393
4394 /*******************************************************************
4395  _samr_SetUserInfo2
4396  ********************************************************************/
4397
4398 NTSTATUS _samr_SetUserInfo2(pipes_struct *p,
4399                             struct samr_SetUserInfo2 *r)
4400 {
4401         struct samr_SetUserInfo q;
4402
4403         q.in.user_handle        = r->in.user_handle;
4404         q.in.level              = r->in.level;
4405         q.in.info               = r->in.info;
4406
4407         return _samr_SetUserInfo(p, &q);
4408 }
4409
4410 /*********************************************************************
4411  _samr_GetAliasMembership
4412 *********************************************************************/
4413
4414 NTSTATUS _samr_GetAliasMembership(pipes_struct *p,
4415                                   struct samr_GetAliasMembership *r)
4416 {
4417         size_t num_alias_rids;
4418         uint32 *alias_rids;
4419         struct samr_info *info = NULL;
4420         size_t i;
4421
4422         NTSTATUS ntstatus1;
4423         NTSTATUS ntstatus2;
4424
4425         DOM_SID *members;
4426
4427         DEBUG(5,("_samr_GetAliasMembership: %d\n", __LINE__));
4428
4429         /* find the policy handle.  open a policy on it. */
4430         if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
4431                 return NT_STATUS_INVALID_HANDLE;
4432
4433         ntstatus1 = access_check_samr_function(info->acc_granted,
4434                                                SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS,
4435                                                "_samr_GetAliasMembership");
4436         ntstatus2 = access_check_samr_function(info->acc_granted,
4437                                                SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
4438                                                "_samr_GetAliasMembership");
4439
4440         if (!NT_STATUS_IS_OK(ntstatus1) || !NT_STATUS_IS_OK(ntstatus2)) {
4441                 if (!(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus2)) &&
4442                     !(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus1))) {
4443                         return (NT_STATUS_IS_OK(ntstatus1)) ? ntstatus2 : ntstatus1;
4444                 }
4445         }
4446
4447         if (!sid_check_is_domain(&info->sid) &&
4448             !sid_check_is_builtin(&info->sid))
4449                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
4450
4451         if (r->in.sids->num_sids) {
4452                 members = TALLOC_ARRAY(p->mem_ctx, DOM_SID, r->in.sids->num_sids);
4453
4454                 if (members == NULL)
4455                         return NT_STATUS_NO_MEMORY;
4456         } else {
4457                 members = NULL;
4458         }
4459
4460         for (i=0; i<r->in.sids->num_sids; i++)
4461                 sid_copy(&members[i], r->in.sids->sids[i].sid);
4462
4463         alias_rids = NULL;
4464         num_alias_rids = 0;
4465
4466         become_root();
4467         ntstatus1 = pdb_enum_alias_memberships(p->mem_ctx, &info->sid, members,
4468                                                r->in.sids->num_sids,
4469                                                &alias_rids, &num_alias_rids);
4470         unbecome_root();
4471
4472         if (!NT_STATUS_IS_OK(ntstatus1)) {
4473                 return ntstatus1;
4474         }
4475
4476         r->out.rids->count = num_alias_rids;
4477         r->out.rids->ids = alias_rids;
4478
4479         return NT_STATUS_OK;
4480 }
4481
4482 /*********************************************************************
4483  _samr_GetMembersInAlias
4484 *********************************************************************/
4485
4486 NTSTATUS _samr_GetMembersInAlias(pipes_struct *p,
4487                                  struct samr_GetMembersInAlias *r)
4488 {
4489         NTSTATUS status;
4490         size_t i;
4491         size_t num_sids = 0;
4492         struct lsa_SidPtr *sids = NULL;
4493         DOM_SID *pdb_sids = NULL;
4494
4495         DOM_SID alias_sid;
4496
4497         uint32 acc_granted;
4498
4499         /* find the policy handle.  open a policy on it. */
4500         if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, NULL))
4501                 return NT_STATUS_INVALID_HANDLE;
4502
4503         status = access_check_samr_function(acc_granted,
4504                                             SAMR_ALIAS_ACCESS_GET_MEMBERS,
4505                                             "_samr_GetMembersInAlias");
4506         if (!NT_STATUS_IS_OK(status)) {
4507                 return status;
4508         }
4509
4510         DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
4511
4512         become_root();
4513         status = pdb_enum_aliasmem(&alias_sid, &pdb_sids, &num_sids);
4514         unbecome_root();
4515
4516         if (!NT_STATUS_IS_OK(status)) {
4517                 return status;
4518         }
4519
4520         if (num_sids) {
4521                 sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_SidPtr, num_sids);
4522                 if (sids == NULL) {
4523                         TALLOC_FREE(pdb_sids);
4524                         return NT_STATUS_NO_MEMORY;
4525                 }
4526         }
4527
4528         for (i = 0; i < num_sids; i++) {
4529                 sids[i].sid = sid_dup_talloc(p->mem_ctx, &pdb_sids[i]);
4530                 if (!sids[i].sid) {
4531                         TALLOC_FREE(pdb_sids);
4532                         return NT_STATUS_NO_MEMORY;
4533                 }
4534         }
4535
4536         r->out.sids->num_sids = num_sids;
4537         r->out.sids->sids = sids;
4538
4539         TALLOC_FREE(pdb_sids);
4540
4541         return NT_STATUS_OK;
4542 }
4543
4544 /*********************************************************************
4545  _samr_QueryGroupMember
4546 *********************************************************************/
4547
4548 NTSTATUS _samr_QueryGroupMember(pipes_struct *p,
4549                                 struct samr_QueryGroupMember *r)
4550 {
4551         DOM_SID group_sid;
4552         size_t i, num_members;
4553
4554         uint32 *rid=NULL;
4555         uint32 *attr=NULL;
4556
4557         uint32 acc_granted;
4558
4559         NTSTATUS status;
4560         struct samr_RidTypeArray *rids = NULL;
4561
4562         rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidTypeArray);
4563         if (!rids) {
4564                 return NT_STATUS_NO_MEMORY;
4565         }
4566
4567         /* find the policy handle.  open a policy on it. */
4568         if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, NULL))
4569                 return NT_STATUS_INVALID_HANDLE;
4570
4571         status = access_check_samr_function(acc_granted,
4572                                             SAMR_GROUP_ACCESS_GET_MEMBERS,
4573                                             "_samr_QueryGroupMember");
4574         if (!NT_STATUS_IS_OK(status)) {
4575                 return status;
4576         }
4577
4578         DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
4579
4580         if (!sid_check_is_in_our_domain(&group_sid)) {
4581                 DEBUG(3, ("sid %s is not in our domain\n",
4582                           sid_string_dbg(&group_sid)));
4583                 return NT_STATUS_NO_SUCH_GROUP;
4584         }
4585
4586         DEBUG(10, ("lookup on Domain SID\n"));
4587
4588         become_root();
4589         status = pdb_enum_group_members(p->mem_ctx, &group_sid,
4590                                         &rid, &num_members);
4591         unbecome_root();
4592
4593         if (!NT_STATUS_IS_OK(status))
4594                 return status;
4595
4596         if (num_members) {
4597                 attr=TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_members);
4598                 if (attr == NULL) {
4599                         return NT_STATUS_NO_MEMORY;
4600                 }
4601         } else {
4602                 attr = NULL;
4603         }
4604
4605         for (i=0; i<num_members; i++)
4606                 attr[i] = SID_NAME_USER;
4607
4608         rids->count = num_members;
4609         rids->types = attr;
4610         rids->rids = rid;
4611
4612         *r->out.rids = rids;
4613
4614         return NT_STATUS_OK;
4615 }
4616
4617 /*********************************************************************
4618  _samr_AddAliasMember
4619 *********************************************************************/
4620
4621 NTSTATUS _samr_AddAliasMember(pipes_struct *p,
4622                               struct samr_AddAliasMember *r)
4623 {
4624         DOM_SID alias_sid;
4625         uint32 acc_granted;
4626         SE_PRIV se_rights;
4627         bool can_add_accounts;
4628         NTSTATUS status;
4629         DISP_INFO *disp_info = NULL;
4630
4631         /* Find the policy handle. Open a policy on it. */
4632         if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
4633                 return NT_STATUS_INVALID_HANDLE;
4634
4635         status = access_check_samr_function(acc_granted,
4636                                             SAMR_ALIAS_ACCESS_ADD_MEMBER,
4637                                             "_samr_AddAliasMember");
4638         if (!NT_STATUS_IS_OK(status)) {
4639                 return status;
4640         }
4641
4642         DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
4643
4644         se_priv_copy( &se_rights, &se_add_users );
4645         can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4646
4647         /******** BEGIN SeAddUsers BLOCK *********/
4648
4649         if ( can_add_accounts )
4650                 become_root();
4651
4652         status = pdb_add_aliasmem(&alias_sid, r->in.sid);
4653
4654         if ( can_add_accounts )
4655                 unbecome_root();
4656
4657         /******** END SeAddUsers BLOCK *********/
4658
4659         if (NT_STATUS_IS_OK(status)) {
4660                 force_flush_samr_cache(disp_info);
4661         }
4662
4663         return status;
4664 }
4665
4666 /*********************************************************************
4667  _samr_DeleteAliasMember
4668 *********************************************************************/
4669
4670 NTSTATUS _samr_DeleteAliasMember(pipes_struct *p,
4671                                  struct samr_DeleteAliasMember *r)
4672 {
4673         DOM_SID alias_sid;
4674         uint32 acc_granted;
4675         SE_PRIV se_rights;
4676         bool can_add_accounts;
4677         NTSTATUS status;
4678         DISP_INFO *disp_info = NULL;
4679
4680         /* Find the policy handle. Open a policy on it. */
4681         if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
4682                 return NT_STATUS_INVALID_HANDLE;
4683
4684         status = access_check_samr_function(acc_granted,
4685                                             SAMR_ALIAS_ACCESS_REMOVE_MEMBER,
4686                                             "_samr_DeleteAliasMember");
4687         if (!NT_STATUS_IS_OK(status)) {
4688                 return status;
4689         }
4690
4691         DEBUG(10, ("_samr_del_aliasmem:sid is %s\n",
4692                    sid_string_dbg(&alias_sid)));
4693
4694         se_priv_copy( &se_rights, &se_add_users );
4695         can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4696
4697         /******** BEGIN SeAddUsers BLOCK *********/
4698
4699         if ( can_add_accounts )
4700                 become_root();
4701
4702         status = pdb_del_aliasmem(&alias_sid, r->in.sid);
4703
4704         if ( can_add_accounts )
4705                 unbecome_root();
4706
4707         /******** END SeAddUsers BLOCK *********/
4708
4709         if (NT_STATUS_IS_OK(status)) {
4710                 force_flush_samr_cache(disp_info);
4711         }
4712
4713         return status;
4714 }
4715
4716 /*********************************************************************
4717  _samr_AddGroupMember
4718 *********************************************************************/
4719
4720 NTSTATUS _samr_AddGroupMember(pipes_struct *p,
4721                               struct samr_AddGroupMember *r)
4722 {
4723         NTSTATUS status;
4724         DOM_SID group_sid;
4725         uint32 group_rid;
4726         uint32 acc_granted;
4727         SE_PRIV se_rights;
4728         bool can_add_accounts;
4729         DISP_INFO *disp_info = NULL;
4730
4731         /* Find the policy handle. Open a policy on it. */
4732         if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
4733                 return NT_STATUS_INVALID_HANDLE;
4734
4735         status = access_check_samr_function(acc_granted,
4736                                             SAMR_GROUP_ACCESS_ADD_MEMBER,
4737                                             "_samr_AddGroupMember");
4738         if (!NT_STATUS_IS_OK(status)) {
4739                 return status;
4740         }
4741
4742         DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
4743
4744         if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
4745                                 &group_rid)) {
4746                 return NT_STATUS_INVALID_HANDLE;
4747         }
4748
4749         se_priv_copy( &se_rights, &se_add_users );
4750         can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4751
4752         /******** BEGIN SeAddUsers BLOCK *********/
4753
4754         if ( can_add_accounts )
4755                 become_root();
4756
4757         status = pdb_add_groupmem(p->mem_ctx, group_rid, r->in.rid);
4758
4759         if ( can_add_accounts )
4760                 unbecome_root();
4761
4762         /******** END SeAddUsers BLOCK *********/
4763
4764         force_flush_samr_cache(disp_info);
4765
4766         return status;
4767 }
4768
4769 /*********************************************************************
4770  _samr_DeleteGroupMember
4771 *********************************************************************/
4772
4773 NTSTATUS _samr_DeleteGroupMember(pipes_struct *p,
4774                                  struct samr_DeleteGroupMember *r)
4775
4776 {
4777         NTSTATUS status;
4778         DOM_SID group_sid;
4779         uint32 group_rid;
4780         uint32 acc_granted;
4781         SE_PRIV se_rights;
4782         bool can_add_accounts;
4783         DISP_INFO *disp_info = NULL;
4784
4785         /*
4786          * delete the group member named r->in.rid
4787          * who is a member of the sid associated with the handle
4788          * the rid is a user's rid as the group is a domain group.
4789          */
4790
4791         /* Find the policy handle. Open a policy on it. */
4792         if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
4793                 return NT_STATUS_INVALID_HANDLE;
4794
4795         status = access_check_samr_function(acc_granted,
4796                                             SAMR_GROUP_ACCESS_REMOVE_MEMBER,
4797                                             "_samr_DeleteGroupMember");
4798         if (!NT_STATUS_IS_OK(status)) {
4799                 return status;
4800         }
4801
4802         if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
4803                                 &group_rid)) {
4804                 return NT_STATUS_INVALID_HANDLE;
4805         }
4806
4807         se_priv_copy( &se_rights, &se_add_users );
4808         can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4809
4810         /******** BEGIN SeAddUsers BLOCK *********/
4811
4812         if ( can_add_accounts )
4813                 become_root();
4814
4815         status = pdb_del_groupmem(p->mem_ctx, group_rid, r->in.rid);
4816
4817         if ( can_add_accounts )
4818                 unbecome_root();
4819
4820         /******** END SeAddUsers BLOCK *********/
4821
4822         force_flush_samr_cache(disp_info);
4823
4824         return status;
4825 }
4826
4827 /*********************************************************************
4828  _samr_DeleteUser
4829 *********************************************************************/
4830
4831 NTSTATUS _samr_DeleteUser(pipes_struct *p,
4832                           struct samr_DeleteUser *r)
4833 {
4834         NTSTATUS status;
4835         DOM_SID user_sid;
4836         struct samu *sam_pass=NULL;
4837         uint32 acc_granted;
4838         bool can_add_accounts;
4839         uint32 acb_info;
4840         DISP_INFO *disp_info = NULL;
4841         bool ret;
4842
4843         DEBUG(5, ("_samr_DeleteUser: %d\n", __LINE__));
4844
4845         /* Find the policy handle. Open a policy on it. */
4846         if (!get_lsa_policy_samr_sid(p, r->in.user_handle, &user_sid, &acc_granted, &disp_info))
4847                 return NT_STATUS_INVALID_HANDLE;
4848
4849         status = access_check_samr_function(acc_granted,
4850                                             STD_RIGHT_DELETE_ACCESS,
4851                                             "_samr_DeleteUser");
4852         if (!NT_STATUS_IS_OK(status)) {
4853                 return status;
4854         }
4855
4856         if (!sid_check_is_in_our_domain(&user_sid))
4857                 return NT_STATUS_CANNOT_DELETE;
4858
4859         /* check if the user exists before trying to delete */
4860         if ( !(sam_pass = samu_new( NULL )) ) {
4861                 return NT_STATUS_NO_MEMORY;
4862         }
4863
4864         become_root();
4865         ret = pdb_getsampwsid(sam_pass, &user_sid);
4866         unbecome_root();
4867
4868         if( !ret ) {
4869                 DEBUG(5,("_samr_DeleteUser: User %s doesn't exist.\n",
4870                         sid_string_dbg(&user_sid)));
4871                 TALLOC_FREE(sam_pass);
4872                 return NT_STATUS_NO_SUCH_USER;
4873         }
4874
4875         acb_info = pdb_get_acct_ctrl(sam_pass);
4876
4877         /* For machine accounts it's the SeMachineAccountPrivilege that counts. */
4878         if ( acb_info & ACB_WSTRUST ) {
4879                 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_machine_account );
4880         } else {
4881                 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_add_users );
4882         }
4883
4884         /******** BEGIN SeAddUsers BLOCK *********/
4885
4886         if ( can_add_accounts )
4887                 become_root();
4888
4889         status = pdb_delete_user(p->mem_ctx, sam_pass);
4890
4891         if ( can_add_accounts )
4892                 unbecome_root();
4893
4894         /******** END SeAddUsers BLOCK *********/
4895
4896         if ( !NT_STATUS_IS_OK(status) ) {
4897                 DEBUG(5,("_samr_DeleteUser: Failed to delete entry for "
4898                          "user %s: %s.\n", pdb_get_username(sam_pass),
4899                          nt_errstr(status)));
4900                 TALLOC_FREE(sam_pass);
4901                 return status;
4902         }
4903
4904
4905         TALLOC_FREE(sam_pass);
4906
4907         if (!close_policy_hnd(p, r->in.user_handle))
4908                 return NT_STATUS_OBJECT_NAME_INVALID;
4909
4910         ZERO_STRUCTP(r->out.user_handle);
4911
4912         force_flush_samr_cache(disp_info);
4913
4914         return NT_STATUS_OK;
4915 }
4916
4917 /*********************************************************************
4918  _samr_DeleteDomainGroup
4919 *********************************************************************/
4920
4921 NTSTATUS _samr_DeleteDomainGroup(pipes_struct *p,
4922                                  struct samr_DeleteDomainGroup *r)
4923 {
4924         NTSTATUS status;
4925         DOM_SID group_sid;
4926         uint32 group_rid;
4927         uint32 acc_granted;
4928         SE_PRIV se_rights;
4929         bool can_add_accounts;
4930         DISP_INFO *disp_info = NULL;
4931
4932         DEBUG(5, ("samr_DeleteDomainGroup: %d\n", __LINE__));
4933
4934         /* Find the policy handle. Open a policy on it. */
4935         if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
4936                 return NT_STATUS_INVALID_HANDLE;
4937
4938         status = access_check_samr_function(acc_granted,
4939                                             STD_RIGHT_DELETE_ACCESS,
4940                                             "_samr_DeleteDomainGroup");
4941         if (!NT_STATUS_IS_OK(status)) {
4942                 return status;
4943         }
4944
4945         DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
4946
4947         if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
4948                                 &group_rid)) {
4949                 return NT_STATUS_NO_SUCH_GROUP;
4950         }
4951
4952         se_priv_copy( &se_rights, &se_add_users );
4953         can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4954
4955         /******** BEGIN SeAddUsers BLOCK *********/
4956
4957         if ( can_add_accounts )
4958                 become_root();
4959
4960         status = pdb_delete_dom_group(p->mem_ctx, group_rid);
4961
4962         if ( can_add_accounts )
4963                 unbecome_root();
4964
4965         /******** END SeAddUsers BLOCK *********/
4966
4967         if ( !NT_STATUS_IS_OK(status) ) {
4968                 DEBUG(5,("_samr_DeleteDomainGroup: Failed to delete mapping "
4969                          "entry for group %s: %s\n",
4970                          sid_string_dbg(&group_sid),
4971                          nt_errstr(status)));
4972                 return status;
4973         }
4974
4975         if (!close_policy_hnd(p, r->in.group_handle))
4976                 return NT_STATUS_OBJECT_NAME_INVALID;
4977
4978         force_flush_samr_cache(disp_info);
4979
4980         return NT_STATUS_OK;
4981 }
4982
4983 /*********************************************************************
4984  _samr_DeleteDomAlias
4985 *********************************************************************/
4986
4987 NTSTATUS _samr_DeleteDomAlias(pipes_struct *p,
4988                               struct samr_DeleteDomAlias *r)
4989 {
4990         DOM_SID alias_sid;
4991         uint32 acc_granted;
4992         SE_PRIV se_rights;
4993         bool can_add_accounts;
4994         NTSTATUS status;
4995         DISP_INFO *disp_info = NULL;
4996
4997         DEBUG(5, ("_samr_DeleteDomAlias: %d\n", __LINE__));
4998
4999         /* Find the policy handle. Open a policy on it. */
5000         if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
5001                 return NT_STATUS_INVALID_HANDLE;
5002
5003         /* copy the handle to the outgoing reply */
5004
5005         memcpy(r->out.alias_handle, r->in.alias_handle, sizeof(r->out.alias_handle));
5006
5007         status = access_check_samr_function(acc_granted,
5008                                             STD_RIGHT_DELETE_ACCESS,
5009                                             "_samr_DeleteDomAlias");
5010         if (!NT_STATUS_IS_OK(status)) {
5011                 return status;
5012         }
5013
5014         DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
5015
5016         /* Don't let Windows delete builtin groups */
5017
5018         if ( sid_check_is_in_builtin( &alias_sid ) ) {
5019                 return NT_STATUS_SPECIAL_ACCOUNT;
5020         }
5021
5022         if (!sid_check_is_in_our_domain(&alias_sid))
5023                 return NT_STATUS_NO_SUCH_ALIAS;
5024
5025         DEBUG(10, ("lookup on Local SID\n"));
5026
5027         se_priv_copy( &se_rights, &se_add_users );
5028         can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
5029
5030         /******** BEGIN SeAddUsers BLOCK *********/
5031
5032         if ( can_add_accounts )
5033                 become_root();
5034
5035         /* Have passdb delete the alias */
5036         status = pdb_delete_alias(&alias_sid);
5037
5038         if ( can_add_accounts )
5039                 unbecome_root();
5040
5041         /******** END SeAddUsers BLOCK *********/
5042
5043         if ( !NT_STATUS_IS_OK(status))
5044                 return status;
5045
5046         if (!close_policy_hnd(p, r->in.alias_handle))
5047                 return NT_STATUS_OBJECT_NAME_INVALID;
5048
5049         force_flush_samr_cache(disp_info);
5050
5051         return NT_STATUS_OK;
5052 }
5053
5054 /*********************************************************************
5055  _samr_CreateDomainGroup
5056 *********************************************************************/
5057
5058 NTSTATUS _samr_CreateDomainGroup(pipes_struct *p,
5059                                  struct samr_CreateDomainGroup *r)
5060
5061 {
5062         NTSTATUS status;
5063         DOM_SID dom_sid;
5064         DOM_SID info_sid;
5065         const char *name;
5066         struct samr_info *info;
5067         uint32 acc_granted;
5068         SE_PRIV se_rights;
5069         bool can_add_accounts;
5070         DISP_INFO *disp_info = NULL;
5071
5072         /* Find the policy handle. Open a policy on it. */
5073         if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &dom_sid, &acc_granted, &disp_info))
5074                 return NT_STATUS_INVALID_HANDLE;
5075
5076         status = access_check_samr_function(acc_granted,
5077                                             SAMR_DOMAIN_ACCESS_CREATE_GROUP,
5078                                             "_samr_CreateDomainGroup");
5079         if (!NT_STATUS_IS_OK(status)) {
5080                 return status;
5081         }
5082
5083         if (!sid_equal(&dom_sid, get_global_sam_sid()))
5084                 return NT_STATUS_ACCESS_DENIED;
5085
5086         name = r->in.name->string;
5087         if (name == NULL) {
5088                 return NT_STATUS_NO_MEMORY;
5089         }
5090
5091         status = can_create(p->mem_ctx, name);
5092         if (!NT_STATUS_IS_OK(status)) {
5093                 return status;
5094         }
5095
5096         se_priv_copy( &se_rights, &se_add_users );
5097         can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
5098
5099         /******** BEGIN SeAddUsers BLOCK *********/
5100
5101         if ( can_add_accounts )
5102                 become_root();
5103
5104         /* check that we successfully create the UNIX group */
5105
5106         status = pdb_create_dom_group(p->mem_ctx, name, r->out.rid);
5107
5108         if ( can_add_accounts )
5109                 unbecome_root();
5110
5111         /******** END SeAddUsers BLOCK *********/
5112
5113         /* check if we should bail out here */
5114
5115         if ( !NT_STATUS_IS_OK(status) )
5116                 return status;
5117
5118         sid_compose(&info_sid, get_global_sam_sid(), *r->out.rid);
5119
5120         if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
5121                 return NT_STATUS_NO_MEMORY;
5122
5123         /* they created it; let the user do what he wants with it */
5124
5125         info->acc_granted = GENERIC_RIGHTS_GROUP_ALL_ACCESS;
5126
5127         /* get a (unique) handle.  open a policy on it. */
5128         if (!create_policy_hnd(p, r->out.group_handle, free_samr_info, (void *)info))
5129                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5130
5131         force_flush_samr_cache(disp_info);
5132
5133         return NT_STATUS_OK;
5134 }
5135
5136 /*********************************************************************
5137  _samr_CreateDomAlias
5138 *********************************************************************/
5139
5140 NTSTATUS _samr_CreateDomAlias(pipes_struct *p,
5141                               struct samr_CreateDomAlias *r)
5142 {
5143         DOM_SID dom_sid;
5144         DOM_SID info_sid;
5145         const char *name = NULL;
5146         struct samr_info *info;
5147         uint32 acc_granted;
5148         gid_t gid;
5149         NTSTATUS result;
5150         SE_PRIV se_rights;
5151         bool can_add_accounts;
5152         DISP_INFO *disp_info = NULL;
5153
5154         /* Find the policy handle. Open a policy on it. */
5155         if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &dom_sid, &acc_granted, &disp_info))
5156                 return NT_STATUS_INVALID_HANDLE;
5157
5158         result = access_check_samr_function(acc_granted,
5159                                             SAMR_DOMAIN_ACCESS_CREATE_ALIAS,
5160                                             "_samr_CreateDomAlias");
5161         if (!NT_STATUS_IS_OK(result)) {
5162                 return result;
5163         }
5164
5165         if (!sid_equal(&dom_sid, get_global_sam_sid()))
5166                 return NT_STATUS_ACCESS_DENIED;
5167
5168         name = r->in.alias_name->string;
5169
5170         se_priv_copy( &se_rights, &se_add_users );
5171         can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
5172
5173         result = can_create(p->mem_ctx, name);
5174         if (!NT_STATUS_IS_OK(result)) {
5175                 return result;
5176         }
5177
5178         /******** BEGIN SeAddUsers BLOCK *********/
5179
5180         if ( can_add_accounts )
5181                 become_root();
5182
5183         /* Have passdb create the alias */
5184         result = pdb_create_alias(name, r->out.rid);
5185
5186         if ( can_add_accounts )
5187                 unbecome_root();
5188
5189         /******** END SeAddUsers BLOCK *********/
5190
5191         if (!NT_STATUS_IS_OK(result)) {
5192                 DEBUG(10, ("pdb_create_alias failed: %s\n",
5193                            nt_errstr(result)));
5194                 return result;
5195         }
5196
5197         sid_copy(&info_sid, get_global_sam_sid());
5198         sid_append_rid(&info_sid, *r->out.rid);
5199
5200         if (!sid_to_gid(&info_sid, &gid)) {
5201                 DEBUG(10, ("Could not find alias just created\n"));
5202                 return NT_STATUS_ACCESS_DENIED;
5203         }
5204
5205         /* check if the group has been successfully created */
5206         if ( getgrgid(gid) == NULL ) {
5207                 DEBUG(10, ("getgrgid(%d) of just created alias failed\n",
5208                            gid));
5209                 return NT_STATUS_ACCESS_DENIED;
5210         }
5211
5212         if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
5213                 return NT_STATUS_NO_MEMORY;
5214
5215         /* they created it; let the user do what he wants with it */
5216
5217         info->acc_granted = GENERIC_RIGHTS_ALIAS_ALL_ACCESS;
5218
5219         /* get a (unique) handle.  open a policy on it. */
5220         if (!create_policy_hnd(p, r->out.alias_handle, free_samr_info, (void *)info))
5221                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5222
5223         force_flush_samr_cache(disp_info);
5224
5225         return NT_STATUS_OK;
5226 }
5227
5228 /*********************************************************************
5229  _samr_QueryGroupInfo
5230 *********************************************************************/
5231
5232 NTSTATUS _samr_QueryGroupInfo(pipes_struct *p,
5233                               struct samr_QueryGroupInfo *r)
5234 {
5235         NTSTATUS status;
5236         DOM_SID group_sid;
5237         GROUP_MAP map;
5238         union samr_GroupInfo *info = NULL;
5239         uint32 acc_granted;
5240         bool ret;
5241         uint32_t attributes = SE_GROUP_MANDATORY |
5242                               SE_GROUP_ENABLED_BY_DEFAULT |
5243                               SE_GROUP_ENABLED;
5244         const char *group_name = NULL;
5245         const char *group_description = NULL;
5246
5247         if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, NULL))
5248                 return NT_STATUS_INVALID_HANDLE;
5249
5250         status = access_check_samr_function(acc_granted,
5251                                             SAMR_GROUP_ACCESS_LOOKUP_INFO,
5252                                             "_samr_QueryGroupInfo");
5253         if (!NT_STATUS_IS_OK(status)) {
5254                 return status;
5255         }
5256
5257         become_root();
5258         ret = get_domain_group_from_sid(group_sid, &map);
5259         unbecome_root();
5260         if (!ret)
5261                 return NT_STATUS_INVALID_HANDLE;
5262
5263         /* FIXME: map contains fstrings */
5264         group_name = talloc_strdup(r, map.nt_name);
5265         group_description = talloc_strdup(r, map.comment);
5266
5267         info = TALLOC_ZERO_P(p->mem_ctx, union samr_GroupInfo);
5268         if (!info) {
5269                 return NT_STATUS_NO_MEMORY;
5270         }
5271
5272         switch (r->in.level) {
5273                 case 1: {
5274                         uint32 *members;
5275                         size_t num_members;
5276
5277                         become_root();
5278                         status = pdb_enum_group_members(
5279                                 p->mem_ctx, &group_sid, &members, &num_members);
5280                         unbecome_root();
5281
5282                         if (!NT_STATUS_IS_OK(status)) {
5283                                 return status;
5284                         }
5285
5286                         init_samr_group_info1(&info->all,
5287                                               group_name,
5288                                               attributes,
5289                                               num_members,
5290                                               group_description);
5291                         break;
5292                 }
5293                 case 2:
5294                         init_samr_group_info2(&info->name,
5295                                               group_name);
5296                         break;
5297                 case 3:
5298                         init_samr_group_info3(&info->attributes,
5299                                               attributes);
5300                         break;
5301                 case 4:
5302                         init_samr_group_info4(&info->description,
5303                                               group_description);
5304                         break;
5305                 case 5: {
5306                         /*
5307                         uint32 *members;
5308                         size_t num_members;
5309                         */
5310
5311                         /*
5312                         become_root();
5313                         status = pdb_enum_group_members(
5314                                 p->mem_ctx, &group_sid, &members, &num_members);
5315                         unbecome_root();
5316
5317                         if (!NT_STATUS_IS_OK(status)) {
5318                                 return status;
5319                         }
5320                         */
5321                         init_samr_group_info5(&info->all2,
5322                                               group_name,
5323                                               attributes,
5324                                               0, /* num_members - in w2k3 this is always 0 */
5325                                               group_description);
5326
5327                         break;
5328                 }
5329                 default:
5330                         return NT_STATUS_INVALID_INFO_CLASS;
5331         }
5332
5333         *r->out.info = info;
5334
5335         return NT_STATUS_OK;
5336 }
5337
5338 /*********************************************************************
5339  _samr_SetGroupInfo
5340 *********************************************************************/
5341
5342 NTSTATUS _samr_SetGroupInfo(pipes_struct *p,
5343                             struct samr_SetGroupInfo *r)
5344 {
5345         DOM_SID group_sid;
5346         GROUP_MAP map;
5347         uint32 acc_granted;
5348         NTSTATUS status;
5349         bool ret;
5350         bool can_mod_accounts;
5351         DISP_INFO *disp_info = NULL;
5352
5353         if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
5354                 return NT_STATUS_INVALID_HANDLE;
5355
5356         status = access_check_samr_function(acc_granted,
5357                                             SAMR_GROUP_ACCESS_SET_INFO,
5358                                             "_samr_SetGroupInfo");
5359         if (!NT_STATUS_IS_OK(status)) {
5360                 return status;
5361         }
5362
5363         become_root();
5364         ret = get_domain_group_from_sid(group_sid, &map);
5365         unbecome_root();
5366         if (!ret)
5367                 return NT_STATUS_NO_SUCH_GROUP;
5368
5369         switch (r->in.level) {
5370                 case 1:
5371                         fstrcpy(map.comment, r->in.info->all.description.string);
5372                         break;
5373                 case 4:
5374                         fstrcpy(map.comment, r->in.info->description.string);
5375                         break;
5376                 default:
5377                         return NT_STATUS_INVALID_INFO_CLASS;
5378         }
5379
5380         can_mod_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_add_users );
5381
5382         /******** BEGIN SeAddUsers BLOCK *********/
5383
5384         if ( can_mod_accounts )
5385                 become_root();
5386
5387         status = pdb_update_group_mapping_entry(&map);
5388
5389         if ( can_mod_accounts )
5390                 unbecome_root();
5391
5392         /******** End SeAddUsers BLOCK *********/
5393
5394         if (NT_STATUS_IS_OK(status)) {
5395                 force_flush_samr_cache(disp_info);
5396         }
5397
5398         return status;
5399 }
5400
5401 /*********************************************************************
5402  _samr_SetAliasInfo
5403 *********************************************************************/
5404
5405 NTSTATUS _samr_SetAliasInfo(pipes_struct *p,
5406                             struct samr_SetAliasInfo *r)
5407 {
5408         DOM_SID group_sid;
5409         struct acct_info info;
5410         uint32 acc_granted;
5411         bool can_mod_accounts;
5412         NTSTATUS status;
5413         DISP_INFO *disp_info = NULL;
5414
5415         if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &group_sid, &acc_granted, &disp_info))
5416                 return NT_STATUS_INVALID_HANDLE;
5417
5418         status = access_check_samr_function(acc_granted,
5419                                             SAMR_ALIAS_ACCESS_SET_INFO,
5420                                             "_samr_SetAliasInfo");
5421         if (!NT_STATUS_IS_OK(status)) {
5422                 return status;
5423         }
5424
5425         /* get the current group information */
5426
5427         become_root();
5428         status = pdb_get_aliasinfo( &group_sid, &info );
5429         unbecome_root();
5430
5431         if ( !NT_STATUS_IS_OK(status))
5432                 return status;
5433
5434         switch (r->in.level) {
5435                 case ALIASINFONAME:
5436                 {
5437                         fstring group_name;
5438
5439                         /* We currently do not support renaming groups in the
5440                            the BUILTIN domain.  Refer to util_builtin.c to understand
5441                            why.  The eventually needs to be fixed to be like Windows
5442                            where you can rename builtin groups, just not delete them */
5443
5444                         if ( sid_check_is_in_builtin( &group_sid ) ) {
5445                                 return NT_STATUS_SPECIAL_ACCOUNT;
5446                         }
5447
5448                         /* There has to be a valid name (and it has to be different) */
5449
5450                         if ( !r->in.info->name.string )
5451                                 return NT_STATUS_INVALID_PARAMETER;
5452
5453                         /* If the name is the same just reply "ok".  Yes this
5454                            doesn't allow you to change the case of a group name. */
5455
5456                         if ( strequal( r->in.info->name.string, info.acct_name ) )
5457                                 return NT_STATUS_OK;
5458
5459                         fstrcpy( info.acct_name, r->in.info->name.string);
5460
5461                         /* make sure the name doesn't already exist as a user
5462                            or local group */
5463
5464                         fstr_sprintf( group_name, "%s\\%s", global_myname(), info.acct_name );
5465                         status = can_create( p->mem_ctx, group_name );
5466                         if ( !NT_STATUS_IS_OK( status ) )
5467                                 return status;
5468                         break;
5469                 }
5470                 case ALIASINFODESCRIPTION:
5471                         if (r->in.info->description.string) {
5472                                 fstrcpy(info.acct_desc,
5473                                         r->in.info->description.string);
5474                         } else {
5475                                 fstrcpy( info.acct_desc, "" );
5476                         }
5477                         break;
5478                 default:
5479                         return NT_STATUS_INVALID_INFO_CLASS;
5480         }
5481
5482         can_mod_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_add_users );
5483
5484         /******** BEGIN SeAddUsers BLOCK *********/
5485
5486         if ( can_mod_accounts )
5487                 become_root();
5488
5489         status = pdb_set_aliasinfo( &group_sid, &info );
5490
5491         if ( can_mod_accounts )
5492                 unbecome_root();
5493
5494         /******** End SeAddUsers BLOCK *********/
5495
5496         if (NT_STATUS_IS_OK(status))
5497                 force_flush_samr_cache(disp_info);
5498
5499         return status;
5500 }
5501
5502 /****************************************************************
5503  _samr_GetDomPwInfo
5504 ****************************************************************/
5505
5506 NTSTATUS _samr_GetDomPwInfo(pipes_struct *p,
5507                             struct samr_GetDomPwInfo *r)
5508 {
5509         uint32_t min_password_length = 0;
5510         uint32_t password_properties = 0;
5511
5512         /* Perform access check.  Since this rpc does not require a
5513            policy handle it will not be caught by the access checks on
5514            SAMR_CONNECT or SAMR_CONNECT_ANON. */
5515
5516         if (!pipe_access_check(p)) {
5517                 DEBUG(3, ("access denied to _samr_GetDomPwInfo\n"));
5518                 return NT_STATUS_ACCESS_DENIED;
5519         }
5520
5521         become_root();
5522         pdb_get_account_policy(AP_MIN_PASSWORD_LEN,
5523                                &min_password_length);
5524         pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
5525                                &password_properties);
5526         unbecome_root();
5527
5528         if (lp_check_password_script() && *lp_check_password_script()) {
5529                 password_properties |= DOMAIN_PASSWORD_COMPLEX;
5530         }
5531
5532         r->out.info->min_password_length = min_password_length;
5533         r->out.info->password_properties = password_properties;
5534
5535         return NT_STATUS_OK;
5536 }
5537
5538 /*********************************************************************
5539  _samr_OpenGroup
5540 *********************************************************************/
5541
5542 NTSTATUS _samr_OpenGroup(pipes_struct *p,
5543                          struct samr_OpenGroup *r)
5544
5545 {
5546         DOM_SID sid;
5547         DOM_SID info_sid;
5548         GROUP_MAP map;
5549         struct samr_info *info;
5550         SEC_DESC         *psd = NULL;
5551         uint32            acc_granted;
5552         uint32            des_access = r->in.access_mask;
5553         size_t            sd_size;
5554         NTSTATUS          status;
5555         fstring sid_string;
5556         bool ret;
5557         SE_PRIV se_rights;
5558
5559         if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &sid, &acc_granted, NULL))
5560                 return NT_STATUS_INVALID_HANDLE;
5561
5562         status = access_check_samr_function(acc_granted,
5563                                             SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
5564                                             "_samr_OpenGroup");
5565
5566         if ( !NT_STATUS_IS_OK(status) )
5567                 return status;
5568
5569         /*check if access can be granted as requested by client. */
5570         map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
5571
5572         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &grp_generic_mapping, NULL, 0);
5573         se_map_generic(&des_access,&grp_generic_mapping);
5574
5575         se_priv_copy( &se_rights, &se_add_users );
5576
5577         status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
5578                 &se_rights, GENERIC_RIGHTS_GROUP_WRITE, des_access,
5579                 &acc_granted, "_samr_OpenGroup");
5580
5581         if ( !NT_STATUS_IS_OK(status) )
5582                 return status;
5583
5584         /* this should not be hard-coded like this */
5585
5586         if (!sid_equal(&sid, get_global_sam_sid()))
5587                 return NT_STATUS_ACCESS_DENIED;
5588
5589         sid_copy(&info_sid, get_global_sam_sid());
5590         sid_append_rid(&info_sid, r->in.rid);
5591         sid_to_fstring(sid_string, &info_sid);
5592
5593         if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
5594                 return NT_STATUS_NO_MEMORY;
5595
5596         info->acc_granted = acc_granted;
5597
5598         DEBUG(10, ("_samr_OpenGroup:Opening SID: %s\n", sid_string));
5599
5600         /* check if that group really exists */
5601         become_root();
5602         ret = get_domain_group_from_sid(info->sid, &map);
5603         unbecome_root();
5604         if (!ret)
5605                 return NT_STATUS_NO_SUCH_GROUP;
5606
5607         /* get a (unique) handle.  open a policy on it. */
5608         if (!create_policy_hnd(p, r->out.group_handle, free_samr_info, (void *)info))
5609                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5610
5611         return NT_STATUS_OK;
5612 }
5613
5614 /*********************************************************************
5615  _samr_RemoveMemberFromForeignDomain
5616 *********************************************************************/
5617
5618 NTSTATUS _samr_RemoveMemberFromForeignDomain(pipes_struct *p,
5619                                              struct samr_RemoveMemberFromForeignDomain *r)
5620 {
5621         DOM_SID                 delete_sid, domain_sid;
5622         uint32                  acc_granted;
5623         NTSTATUS                result;
5624         DISP_INFO *disp_info = NULL;
5625
5626         sid_copy( &delete_sid, r->in.sid );
5627
5628         DEBUG(5,("_samr_RemoveMemberFromForeignDomain: removing SID [%s]\n",
5629                 sid_string_dbg(&delete_sid)));
5630
5631         /* Find the policy handle. Open a policy on it. */
5632
5633         if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &domain_sid,
5634                                      &acc_granted, &disp_info))
5635                 return NT_STATUS_INVALID_HANDLE;
5636
5637         result = access_check_samr_function(acc_granted,
5638                                             STD_RIGHT_DELETE_ACCESS,
5639                                             "_samr_RemoveMemberFromForeignDomain");
5640
5641         if (!NT_STATUS_IS_OK(result))
5642                 return result;
5643
5644         DEBUG(8, ("_samr_RemoveMemberFromForeignDomain: sid is %s\n",
5645                   sid_string_dbg(&domain_sid)));
5646
5647         /* we can only delete a user from a group since we don't have
5648            nested groups anyways.  So in the latter case, just say OK */
5649
5650         /* TODO: The above comment nowadays is bogus. Since we have nested
5651          * groups now, and aliases members are never reported out of the unix
5652          * group membership, the "just say OK" makes this call a no-op. For
5653          * us. This needs fixing however. */
5654
5655         /* I've only ever seen this in the wild when deleting a user from
5656          * usrmgr.exe. domain_sid is the builtin domain, and the sid to delete
5657          * is the user about to be deleted. I very much suspect this is the
5658          * only application of this call. To verify this, let people report
5659          * other cases. */
5660
5661         if (!sid_check_is_builtin(&domain_sid)) {
5662                 DEBUG(1,("_samr_RemoveMemberFromForeignDomain: domain_sid = %s, "
5663                          "global_sam_sid() = %s\n",
5664                          sid_string_dbg(&domain_sid),
5665                          sid_string_dbg(get_global_sam_sid())));
5666                 DEBUGADD(1,("please report to samba-technical@samba.org!\n"));
5667                 return NT_STATUS_OK;
5668         }
5669
5670         force_flush_samr_cache(disp_info);
5671
5672         result = NT_STATUS_OK;
5673
5674         return result;
5675 }
5676
5677 /*******************************************************************
5678  _samr_QueryDomainInfo2
5679  ********************************************************************/
5680
5681 NTSTATUS _samr_QueryDomainInfo2(pipes_struct *p,
5682                                 struct samr_QueryDomainInfo2 *r)
5683 {
5684         struct samr_QueryDomainInfo q;
5685
5686         q.in.domain_handle      = r->in.domain_handle;
5687         q.in.level              = r->in.level;
5688
5689         q.out.info              = r->out.info;
5690
5691         return _samr_QueryDomainInfo(p, &q);
5692 }
5693
5694 /*******************************************************************
5695  _samr_SetDomainInfo
5696  ********************************************************************/
5697
5698 NTSTATUS _samr_SetDomainInfo(pipes_struct *p,
5699                              struct samr_SetDomainInfo *r)
5700 {
5701         struct samr_info *info = NULL;
5702         time_t u_expire, u_min_age;
5703         time_t u_logout;
5704         time_t u_lock_duration, u_reset_time;
5705         NTSTATUS result;
5706
5707         DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
5708
5709         /* find the policy handle.  open a policy on it. */
5710         if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
5711                 return NT_STATUS_INVALID_HANDLE;
5712
5713         /* We do have different access bits for info
5714          * levels here, but we're really just looking for
5715          * GENERIC_RIGHTS_DOMAIN_WRITE access. Unfortunately
5716          * this maps to different specific bits. So
5717          * assume if we have SAMR_DOMAIN_ACCESS_SET_INFO_1
5718          * set we are ok. */
5719
5720         result = access_check_samr_function(info->acc_granted,
5721                                             SAMR_DOMAIN_ACCESS_SET_INFO_1,
5722                                             "_samr_SetDomainInfo");
5723
5724         if (!NT_STATUS_IS_OK(result))
5725                 return result;
5726
5727         DEBUG(5,("_samr_SetDomainInfo: level: %d\n", r->in.level));
5728
5729         switch (r->in.level) {
5730                 case 0x01:
5731                         u_expire=nt_time_to_unix_abs((NTTIME *)&r->in.info->info1.max_password_age);
5732                         u_min_age=nt_time_to_unix_abs((NTTIME *)&r->in.info->info1.min_password_age);
5733                         pdb_set_account_policy(AP_MIN_PASSWORD_LEN, (uint32)r->in.info->info1.min_password_length);
5734                         pdb_set_account_policy(AP_PASSWORD_HISTORY, (uint32)r->in.info->info1.password_history_length);
5735                         pdb_set_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, (uint32)r->in.info->info1.password_properties);
5736                         pdb_set_account_policy(AP_MAX_PASSWORD_AGE, (int)u_expire);
5737                         pdb_set_account_policy(AP_MIN_PASSWORD_AGE, (int)u_min_age);
5738                         break;
5739                 case 0x02:
5740                         break;
5741                 case 0x03:
5742                         u_logout=nt_time_to_unix_abs((NTTIME *)&r->in.info->info3.force_logoff_time);
5743                         pdb_set_account_policy(AP_TIME_TO_LOGOUT, (int)u_logout);
5744                         break;
5745                 case 0x05:
5746                         break;
5747                 case 0x06:
5748                         break;
5749                 case 0x07:
5750                         break;
5751                 case 0x0c:
5752                         u_lock_duration=nt_time_to_unix_abs((NTTIME *)&r->in.info->info12.lockout_duration);
5753                         if (u_lock_duration != -1)
5754                                 u_lock_duration /= 60;
5755
5756                         u_reset_time=nt_time_to_unix_abs((NTTIME *)&r->in.info->info12.lockout_window)/60;
5757
5758                         pdb_set_account_policy(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
5759                         pdb_set_account_policy(AP_RESET_COUNT_TIME, (int)u_reset_time);
5760                         pdb_set_account_policy(AP_BAD_ATTEMPT_LOCKOUT, (uint32)r->in.info->info12.lockout_threshold);
5761                         break;
5762                 default:
5763                         return NT_STATUS_INVALID_INFO_CLASS;
5764         }
5765
5766         DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
5767
5768         return NT_STATUS_OK;
5769 }
5770
5771 /****************************************************************
5772  _samr_GetDisplayEnumerationIndex
5773 ****************************************************************/
5774
5775 NTSTATUS _samr_GetDisplayEnumerationIndex(pipes_struct *p,
5776                                           struct samr_GetDisplayEnumerationIndex *r)
5777 {
5778         struct samr_info *info = NULL;
5779         uint32_t max_entries = (uint32_t) -1;
5780         uint32_t enum_context = 0;
5781         int i;
5782         uint32_t num_account = 0;
5783         struct samr_displayentry *entries = NULL;
5784         NTSTATUS status;
5785
5786         DEBUG(5,("_samr_GetDisplayEnumerationIndex: %d\n", __LINE__));
5787
5788         /* find the policy handle.  open a policy on it. */
5789         if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info)) {
5790                 return NT_STATUS_INVALID_HANDLE;
5791         }
5792
5793         status = access_check_samr_function(info->acc_granted,
5794                                             SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
5795                                             "_samr_GetDisplayEnumerationIndex");
5796         if (!NT_STATUS_IS_OK(status)) {
5797                 return status;
5798         }
5799
5800         if ((r->in.level < 1) || (r->in.level > 3)) {
5801                 DEBUG(0,("_samr_GetDisplayEnumerationIndex: "
5802                         "Unknown info level (%u)\n",
5803                         r->in.level));
5804                 return NT_STATUS_INVALID_INFO_CLASS;
5805         }
5806
5807         become_root();
5808
5809         /* The following done as ROOT. Don't return without unbecome_root(). */
5810
5811         switch (r->in.level) {
5812         case 1:
5813                 if (info->disp_info->users == NULL) {
5814                         info->disp_info->users = pdb_search_users(ACB_NORMAL);
5815                         if (info->disp_info->users == NULL) {
5816                                 unbecome_root();
5817                                 return NT_STATUS_ACCESS_DENIED;
5818                         }
5819                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5820                                 "starting user enumeration at index %u\n",
5821                                 (unsigned int)enum_context));
5822                 } else {
5823                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5824                                 "using cached user enumeration at index %u\n",
5825                                 (unsigned int)enum_context));
5826                 }
5827                 num_account = pdb_search_entries(info->disp_info->users,
5828                                                  enum_context, max_entries,
5829                                                  &entries);
5830                 break;
5831         case 2:
5832                 if (info->disp_info->machines == NULL) {
5833                         info->disp_info->machines =
5834                                 pdb_search_users(ACB_WSTRUST|ACB_SVRTRUST);
5835                         if (info->disp_info->machines == NULL) {
5836                                 unbecome_root();
5837                                 return NT_STATUS_ACCESS_DENIED;
5838                         }
5839                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5840                                 "starting machine enumeration at index %u\n",
5841                                 (unsigned int)enum_context));
5842                 } else {
5843                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5844                                 "using cached machine enumeration at index %u\n",
5845                                 (unsigned int)enum_context));
5846                 }
5847                 num_account = pdb_search_entries(info->disp_info->machines,
5848                                                  enum_context, max_entries,
5849                                                  &entries);
5850                 break;
5851         case 3:
5852                 if (info->disp_info->groups == NULL) {
5853                         info->disp_info->groups = pdb_search_groups();
5854                         if (info->disp_info->groups == NULL) {
5855                                 unbecome_root();
5856                                 return NT_STATUS_ACCESS_DENIED;
5857                         }
5858                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5859                                 "starting group enumeration at index %u\n",
5860                                 (unsigned int)enum_context));
5861                 } else {
5862                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5863                                 "using cached group enumeration at index %u\n",
5864                                 (unsigned int)enum_context));
5865                 }
5866                 num_account = pdb_search_entries(info->disp_info->groups,
5867                                                  enum_context, max_entries,
5868                                                  &entries);
5869                 break;
5870         default:
5871                 unbecome_root();
5872                 smb_panic("info class changed");
5873                 break;
5874         }
5875
5876         unbecome_root();
5877
5878         /* Ensure we cache this enumeration. */
5879         set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
5880
5881         DEBUG(10,("_samr_GetDisplayEnumerationIndex: looking for :%s\n",
5882                 r->in.name->string));
5883
5884         for (i=0; i<num_account; i++) {
5885                 if (strequal(entries[i].account_name, r->in.name->string)) {
5886                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5887                                 "found %s at idx %d\n",
5888                                 r->in.name->string, i));
5889                         *r->out.idx = i;
5890                         return NT_STATUS_OK;
5891                 }
5892         }
5893
5894         /* assuming account_name lives at the very end */
5895         *r->out.idx = num_account;
5896
5897         return NT_STATUS_NO_MORE_ENTRIES;
5898 }
5899
5900 /****************************************************************
5901  _samr_GetDisplayEnumerationIndex2
5902 ****************************************************************/
5903
5904 NTSTATUS _samr_GetDisplayEnumerationIndex2(pipes_struct *p,
5905                                            struct samr_GetDisplayEnumerationIndex2 *r)
5906 {
5907         struct samr_GetDisplayEnumerationIndex q;
5908
5909         q.in.domain_handle      = r->in.domain_handle;
5910         q.in.level              = r->in.level;
5911         q.in.name               = r->in.name;
5912
5913         q.out.idx               = r->out.idx;
5914
5915         return _samr_GetDisplayEnumerationIndex(p, &q);
5916 }
5917
5918 /****************************************************************
5919 ****************************************************************/
5920
5921 NTSTATUS _samr_Shutdown(pipes_struct *p,
5922                         struct samr_Shutdown *r)
5923 {
5924         p->rng_fault_state = true;
5925         return NT_STATUS_NOT_IMPLEMENTED;
5926 }
5927
5928 /****************************************************************
5929 ****************************************************************/
5930
5931 NTSTATUS _samr_SetMemberAttributesOfGroup(pipes_struct *p,
5932                                           struct samr_SetMemberAttributesOfGroup *r)
5933 {
5934         p->rng_fault_state = true;
5935         return NT_STATUS_NOT_IMPLEMENTED;
5936 }
5937
5938 /****************************************************************
5939 ****************************************************************/
5940
5941 NTSTATUS _samr_ChangePasswordUser(pipes_struct *p,
5942                                   struct samr_ChangePasswordUser *r)
5943 {
5944         p->rng_fault_state = true;
5945         return NT_STATUS_NOT_IMPLEMENTED;
5946 }
5947
5948 /****************************************************************
5949 ****************************************************************/
5950
5951 NTSTATUS _samr_TestPrivateFunctionsDomain(pipes_struct *p,
5952                                           struct samr_TestPrivateFunctionsDomain *r)
5953 {
5954         p->rng_fault_state = true;
5955         return NT_STATUS_NOT_IMPLEMENTED;
5956 }
5957
5958 /****************************************************************
5959 ****************************************************************/
5960
5961 NTSTATUS _samr_TestPrivateFunctionsUser(pipes_struct *p,
5962                                         struct samr_TestPrivateFunctionsUser *r)
5963 {
5964         p->rng_fault_state = true;
5965         return NT_STATUS_NOT_IMPLEMENTED;
5966 }
5967
5968 /****************************************************************
5969 ****************************************************************/
5970
5971 NTSTATUS _samr_AddMultipleMembersToAlias(pipes_struct *p,
5972                                          struct samr_AddMultipleMembersToAlias *r)
5973 {
5974         p->rng_fault_state = true;
5975         return NT_STATUS_NOT_IMPLEMENTED;
5976 }
5977
5978 /****************************************************************
5979 ****************************************************************/
5980
5981 NTSTATUS _samr_RemoveMultipleMembersFromAlias(pipes_struct *p,
5982                                               struct samr_RemoveMultipleMembersFromAlias *r)
5983 {
5984         p->rng_fault_state = true;
5985         return NT_STATUS_NOT_IMPLEMENTED;
5986 }
5987
5988 /****************************************************************
5989 ****************************************************************/
5990
5991 NTSTATUS _samr_OemChangePasswordUser2(pipes_struct *p,
5992                                       struct samr_OemChangePasswordUser2 *r)
5993 {
5994         p->rng_fault_state = true;
5995         return NT_STATUS_NOT_IMPLEMENTED;
5996 }
5997
5998 /****************************************************************
5999 ****************************************************************/
6000
6001 NTSTATUS _samr_SetBootKeyInformation(pipes_struct *p,
6002                                      struct samr_SetBootKeyInformation *r)
6003 {
6004         p->rng_fault_state = true;
6005         return NT_STATUS_NOT_IMPLEMENTED;
6006 }
6007
6008 /****************************************************************
6009 ****************************************************************/
6010
6011 NTSTATUS _samr_GetBootKeyInformation(pipes_struct *p,
6012                                      struct samr_GetBootKeyInformation *r)
6013 {
6014         p->rng_fault_state = true;
6015         return NT_STATUS_NOT_IMPLEMENTED;
6016 }
6017
6018 /****************************************************************
6019 ****************************************************************/
6020
6021 NTSTATUS _samr_Connect3(pipes_struct *p,
6022                         struct samr_Connect3 *r)
6023 {
6024         p->rng_fault_state = true;
6025         return NT_STATUS_NOT_IMPLEMENTED;
6026 }
6027
6028 /****************************************************************
6029 ****************************************************************/
6030
6031 NTSTATUS _samr_RidToSid(pipes_struct *p,
6032                         struct samr_RidToSid *r)
6033 {
6034         p->rng_fault_state = true;
6035         return NT_STATUS_NOT_IMPLEMENTED;
6036 }
6037
6038 /****************************************************************
6039 ****************************************************************/
6040
6041 NTSTATUS _samr_SetDsrmPassword(pipes_struct *p,
6042                                struct samr_SetDsrmPassword *r)
6043 {
6044         p->rng_fault_state = true;
6045         return NT_STATUS_NOT_IMPLEMENTED;
6046 }
6047
6048 /****************************************************************
6049 ****************************************************************/
6050
6051 NTSTATUS _samr_ValidatePassword(pipes_struct *p,
6052                                 struct samr_ValidatePassword *r)
6053 {
6054         p->rng_fault_state = true;
6055         return NT_STATUS_NOT_IMPLEMENTED;
6056 }