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