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