Change ldap search filter. This function is also used to search machine accounts...
[Samba/gebeck_regimport.git] / source3 / rpc_server / srv_samr_nt.c
blobdf7bb9b206ca49d934ef6898a5ee95f6710482cd
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-2005,
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.
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 3 of the License, or
18 * (at your option) any later version.
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, see <http://www.gnu.org/licenses/>.
30 * This is the implementation of the SAMR code.
33 #include "includes.h"
35 #undef DBGC_CLASS
36 #define DBGC_CLASS DBGC_RPC_SRV
38 #define SAMR_USR_RIGHTS_WRITE_PW \
39 ( READ_CONTROL_ACCESS | \
40 SA_RIGHT_USER_CHANGE_PASSWORD | \
41 SA_RIGHT_USER_SET_LOC_COM )
42 #define SAMR_USR_RIGHTS_CANT_WRITE_PW \
43 ( READ_CONTROL_ACCESS | SA_RIGHT_USER_SET_LOC_COM )
45 #define DISP_INFO_CACHE_TIMEOUT 10
47 typedef struct disp_info {
48 DOM_SID sid; /* identify which domain this is. */
49 bool builtin_domain; /* Quick flag to check if this is the builtin domain. */
50 struct pdb_search *users; /* querydispinfo 1 and 4 */
51 struct pdb_search *machines; /* querydispinfo 2 */
52 struct pdb_search *groups; /* querydispinfo 3 and 5, enumgroups */
53 struct pdb_search *aliases; /* enumaliases */
55 uint16 enum_acb_mask;
56 struct pdb_search *enum_users; /* enumusers with a mask */
58 struct timed_event *cache_timeout_event; /* cache idle timeout
59 * handler. */
60 } DISP_INFO;
62 /* We keep a static list of these by SID as modern clients close down
63 all resources between each request in a complete enumeration. */
65 struct samr_info {
66 /* for use by the \PIPE\samr policy */
67 DOM_SID sid;
68 bool builtin_domain; /* Quick flag to check if this is the builtin domain. */
69 uint32 status; /* some sort of flag. best to record it. comes from opnum 0x39 */
70 uint32 acc_granted;
71 DISP_INFO *disp_info;
72 TALLOC_CTX *mem_ctx;
75 static const struct generic_mapping sam_generic_mapping = {
76 GENERIC_RIGHTS_SAM_READ,
77 GENERIC_RIGHTS_SAM_WRITE,
78 GENERIC_RIGHTS_SAM_EXECUTE,
79 GENERIC_RIGHTS_SAM_ALL_ACCESS};
80 static const struct generic_mapping dom_generic_mapping = {
81 GENERIC_RIGHTS_DOMAIN_READ,
82 GENERIC_RIGHTS_DOMAIN_WRITE,
83 GENERIC_RIGHTS_DOMAIN_EXECUTE,
84 GENERIC_RIGHTS_DOMAIN_ALL_ACCESS};
85 static const struct generic_mapping usr_generic_mapping = {
86 GENERIC_RIGHTS_USER_READ,
87 GENERIC_RIGHTS_USER_WRITE,
88 GENERIC_RIGHTS_USER_EXECUTE,
89 GENERIC_RIGHTS_USER_ALL_ACCESS};
90 static const struct generic_mapping usr_nopwchange_generic_mapping = {
91 GENERIC_RIGHTS_USER_READ,
92 GENERIC_RIGHTS_USER_WRITE,
93 GENERIC_RIGHTS_USER_EXECUTE & ~SA_RIGHT_USER_CHANGE_PASSWORD,
94 GENERIC_RIGHTS_USER_ALL_ACCESS};
95 static const struct generic_mapping grp_generic_mapping = {
96 GENERIC_RIGHTS_GROUP_READ,
97 GENERIC_RIGHTS_GROUP_WRITE,
98 GENERIC_RIGHTS_GROUP_EXECUTE,
99 GENERIC_RIGHTS_GROUP_ALL_ACCESS};
100 static const struct generic_mapping ali_generic_mapping = {
101 GENERIC_RIGHTS_ALIAS_READ,
102 GENERIC_RIGHTS_ALIAS_WRITE,
103 GENERIC_RIGHTS_ALIAS_EXECUTE,
104 GENERIC_RIGHTS_ALIAS_ALL_ACCESS};
106 /*******************************************************************
107 *******************************************************************/
109 static NTSTATUS make_samr_object_sd( TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size,
110 const struct generic_mapping *map,
111 DOM_SID *sid, uint32 sid_access )
113 DOM_SID domadmin_sid;
114 SEC_ACE ace[5]; /* at most 5 entries */
115 SEC_ACCESS mask;
116 size_t i = 0;
118 SEC_ACL *psa = NULL;
120 /* basic access for Everyone */
122 init_sec_access(&mask, map->generic_execute | map->generic_read );
123 init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
125 /* add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
127 init_sec_access(&mask, map->generic_all);
129 init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
130 init_sec_ace(&ace[i++], &global_sid_Builtin_Account_Operators, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
132 /* Add Full Access for Domain Admins if we are a DC */
134 if ( IS_DC ) {
135 sid_copy( &domadmin_sid, get_global_sam_sid() );
136 sid_append_rid( &domadmin_sid, DOMAIN_GROUP_RID_ADMINS );
137 init_sec_ace(&ace[i++], &domadmin_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
140 /* if we have a sid, give it some special access */
142 if ( sid ) {
143 init_sec_access( &mask, sid_access );
144 init_sec_ace(&ace[i++], sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
147 /* create the security descriptor */
149 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) == NULL)
150 return NT_STATUS_NO_MEMORY;
152 if ((*psd = make_sec_desc(ctx, SECURITY_DESCRIPTOR_REVISION_1,
153 SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL,
154 psa, sd_size)) == NULL)
155 return NT_STATUS_NO_MEMORY;
157 return NT_STATUS_OK;
160 /*******************************************************************
161 Checks if access to an object should be granted, and returns that
162 level of access for further checks.
163 ********************************************************************/
165 static NTSTATUS access_check_samr_object( SEC_DESC *psd, NT_USER_TOKEN *token,
166 SE_PRIV *rights, uint32 rights_mask,
167 uint32 des_access, uint32 *acc_granted,
168 const char *debug )
170 NTSTATUS status = NT_STATUS_ACCESS_DENIED;
171 uint32 saved_mask = 0;
173 /* check privileges; certain SAM access bits should be overridden
174 by privileges (mostly having to do with creating/modifying/deleting
175 users and groups) */
177 if ( rights && user_has_any_privilege( token, rights ) ) {
179 saved_mask = (des_access & rights_mask);
180 des_access &= ~saved_mask;
182 DEBUG(4,("access_check_samr_object: user rights access mask [0x%x]\n",
183 rights_mask));
187 /* check the security descriptor first */
189 if ( se_access_check(psd, token, des_access, acc_granted, &status) )
190 goto done;
192 /* give root a free pass */
194 if ( geteuid() == sec_initial_uid() ) {
196 DEBUG(4,("%s: ACCESS should be DENIED (requested: %#010x)\n", debug, des_access));
197 DEBUGADD(4,("but overritten by euid == sec_initial_uid()\n"));
199 *acc_granted = des_access;
201 status = NT_STATUS_OK;
202 goto done;
206 done:
207 /* add in any bits saved during the privilege check (only
208 matters is status is ok) */
210 *acc_granted |= rights_mask;
212 DEBUG(4,("%s: access %s (requested: 0x%08x, granted: 0x%08x)\n",
213 debug, NT_STATUS_IS_OK(status) ? "GRANTED" : "DENIED",
214 des_access, *acc_granted));
216 return status;
219 /*******************************************************************
220 Checks if access to a function can be granted
221 ********************************************************************/
223 static NTSTATUS access_check_samr_function(uint32 acc_granted, uint32 acc_required, const char *debug)
225 DEBUG(5,("%s: access check ((granted: %#010x; required: %#010x)\n",
226 debug, acc_granted, acc_required));
228 /* check the security descriptor first */
230 if ( (acc_granted&acc_required) == acc_required )
231 return NT_STATUS_OK;
233 /* give root a free pass */
235 if (geteuid() == sec_initial_uid()) {
237 DEBUG(4,("%s: ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
238 debug, acc_granted, acc_required));
239 DEBUGADD(4,("but overwritten by euid == 0\n"));
241 return NT_STATUS_OK;
244 DEBUG(2,("%s: ACCESS DENIED (granted: %#010x; required: %#010x)\n",
245 debug, acc_granted, acc_required));
247 return NT_STATUS_ACCESS_DENIED;
250 /*******************************************************************
251 Fetch or create a dispinfo struct.
252 ********************************************************************/
254 static DISP_INFO *get_samr_dispinfo_by_sid(DOM_SID *psid)
257 * We do a static cache for DISP_INFO's here. Explanation can be found
258 * in Jeremy's checkin message to r11793:
260 * Fix the SAMR cache so it works across completely insane
261 * client behaviour (ie.:
262 * open pipe/open SAMR handle/enumerate 0 - 1024
263 * close SAMR handle, close pipe.
264 * open pipe/open SAMR handle/enumerate 1024 - 2048...
265 * close SAMR handle, close pipe.
266 * And on ad-nausium. Amazing.... probably object-oriented
267 * client side programming in action yet again.
268 * This change should *massively* improve performance when
269 * enumerating users from an LDAP database.
270 * Jeremy.
272 * "Our" and the builtin domain are the only ones where we ever
273 * enumerate stuff, so just cache 2 entries.
276 static struct disp_info builtin_dispinfo;
277 static struct disp_info domain_dispinfo;
279 /* There are two cases to consider here:
280 1) The SID is a domain SID and we look for an equality match, or
281 2) This is an account SID and so we return the DISP_INFO* for our
282 domain */
284 if (psid == NULL) {
285 return NULL;
288 if (sid_check_is_builtin(psid) || sid_check_is_in_builtin(psid)) {
290 * Necessary only once, but it does not really hurt.
292 sid_copy(&builtin_dispinfo.sid, &global_sid_Builtin);
294 return &builtin_dispinfo;
297 if (sid_check_is_domain(psid) || sid_check_is_in_our_domain(psid)) {
299 * Necessary only once, but it does not really hurt.
301 sid_copy(&domain_dispinfo.sid, get_global_sam_sid());
303 return &domain_dispinfo;
306 return NULL;
309 /*******************************************************************
310 Create a samr_info struct.
311 ********************************************************************/
313 static struct samr_info *get_samr_info_by_sid(DOM_SID *psid)
315 struct samr_info *info;
316 fstring sid_str;
317 TALLOC_CTX *mem_ctx;
319 if (psid) {
320 sid_to_fstring(sid_str, psid);
321 } else {
322 fstrcpy(sid_str,"(NULL)");
325 mem_ctx = talloc_init("samr_info for domain sid %s", sid_str);
327 if ((info = TALLOC_ZERO_P(mem_ctx, struct samr_info)) == NULL)
328 return NULL;
330 DEBUG(10,("get_samr_info_by_sid: created new info for sid %s\n", sid_str));
331 if (psid) {
332 sid_copy( &info->sid, psid);
333 info->builtin_domain = sid_check_is_builtin(psid);
334 } else {
335 DEBUG(10,("get_samr_info_by_sid: created new info for NULL sid.\n"));
336 info->builtin_domain = False;
338 info->mem_ctx = mem_ctx;
340 info->disp_info = get_samr_dispinfo_by_sid(psid);
342 return info;
345 /*******************************************************************
346 Function to free the per SID data.
347 ********************************************************************/
349 static void free_samr_cache(DISP_INFO *disp_info)
351 DEBUG(10, ("free_samr_cache: deleting cache for SID %s\n",
352 sid_string_dbg(&disp_info->sid)));
354 /* We need to become root here because the paged search might have to
355 * tell the LDAP server we're not interested in the rest anymore. */
357 become_root();
359 if (disp_info->users) {
360 DEBUG(10,("free_samr_cache: deleting users cache\n"));
361 pdb_search_destroy(disp_info->users);
362 disp_info->users = NULL;
364 if (disp_info->machines) {
365 DEBUG(10,("free_samr_cache: deleting machines cache\n"));
366 pdb_search_destroy(disp_info->machines);
367 disp_info->machines = NULL;
369 if (disp_info->groups) {
370 DEBUG(10,("free_samr_cache: deleting groups cache\n"));
371 pdb_search_destroy(disp_info->groups);
372 disp_info->groups = NULL;
374 if (disp_info->aliases) {
375 DEBUG(10,("free_samr_cache: deleting aliases cache\n"));
376 pdb_search_destroy(disp_info->aliases);
377 disp_info->aliases = NULL;
379 if (disp_info->enum_users) {
380 DEBUG(10,("free_samr_cache: deleting enum_users cache\n"));
381 pdb_search_destroy(disp_info->enum_users);
382 disp_info->enum_users = NULL;
384 disp_info->enum_acb_mask = 0;
386 unbecome_root();
389 /*******************************************************************
390 Function to free the per handle data.
391 ********************************************************************/
393 static void free_samr_info(void *ptr)
395 struct samr_info *info=(struct samr_info *) ptr;
397 /* Only free the dispinfo cache if no one bothered to set up
398 a timeout. */
400 if (info->disp_info && info->disp_info->cache_timeout_event == NULL) {
401 free_samr_cache(info->disp_info);
404 talloc_destroy(info->mem_ctx);
407 /*******************************************************************
408 Idle event handler. Throw away the disp info cache.
409 ********************************************************************/
411 static void disp_info_cache_idle_timeout_handler(struct event_context *ev_ctx,
412 struct timed_event *te,
413 const struct timeval *now,
414 void *private_data)
416 DISP_INFO *disp_info = (DISP_INFO *)private_data;
418 TALLOC_FREE(disp_info->cache_timeout_event);
420 DEBUG(10, ("disp_info_cache_idle_timeout_handler: caching timed "
421 "out\n"));
422 free_samr_cache(disp_info);
425 /*******************************************************************
426 Setup cache removal idle event handler.
427 ********************************************************************/
429 static void set_disp_info_cache_timeout(DISP_INFO *disp_info, time_t secs_fromnow)
431 /* Remove any pending timeout and update. */
433 TALLOC_FREE(disp_info->cache_timeout_event);
435 DEBUG(10,("set_disp_info_cache_timeout: caching enumeration for "
436 "SID %s for %u seconds\n", sid_string_dbg(&disp_info->sid),
437 (unsigned int)secs_fromnow ));
439 disp_info->cache_timeout_event = event_add_timed(
440 smbd_event_context(), NULL,
441 timeval_current_ofs(secs_fromnow, 0),
442 "disp_info_cache_idle_timeout_handler",
443 disp_info_cache_idle_timeout_handler, (void *)disp_info);
446 /*******************************************************************
447 Force flush any cache. We do this on any samr_set_xxx call.
448 We must also remove the timeout handler.
449 ********************************************************************/
451 static void force_flush_samr_cache(DISP_INFO *disp_info)
453 if ((disp_info == NULL) || (disp_info->cache_timeout_event == NULL)) {
454 return;
457 DEBUG(10,("force_flush_samr_cache: clearing idle event\n"));
458 TALLOC_FREE(disp_info->cache_timeout_event);
459 free_samr_cache(disp_info);
462 /*******************************************************************
463 Ensure password info is never given out. Paranioa... JRA.
464 ********************************************************************/
466 static void samr_clear_sam_passwd(struct samu *sam_pass)
469 if (!sam_pass)
470 return;
472 /* These now zero out the old password */
474 pdb_set_lanman_passwd(sam_pass, NULL, PDB_DEFAULT);
475 pdb_set_nt_passwd(sam_pass, NULL, PDB_DEFAULT);
478 static uint32 count_sam_users(struct disp_info *info, uint32 acct_flags)
480 struct samr_displayentry *entry;
482 if (info->builtin_domain) {
483 /* No users in builtin. */
484 return 0;
487 if (info->users == NULL) {
488 info->users = pdb_search_users(acct_flags);
489 if (info->users == NULL) {
490 return 0;
493 /* Fetch the last possible entry, thus trigger an enumeration */
494 pdb_search_entries(info->users, 0xffffffff, 1, &entry);
496 /* Ensure we cache this enumeration. */
497 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
499 return info->users->num_entries;
502 static uint32 count_sam_groups(struct disp_info *info)
504 struct samr_displayentry *entry;
506 if (info->builtin_domain) {
507 /* No groups in builtin. */
508 return 0;
511 if (info->groups == NULL) {
512 info->groups = pdb_search_groups();
513 if (info->groups == NULL) {
514 return 0;
517 /* Fetch the last possible entry, thus trigger an enumeration */
518 pdb_search_entries(info->groups, 0xffffffff, 1, &entry);
520 /* Ensure we cache this enumeration. */
521 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
523 return info->groups->num_entries;
526 static uint32 count_sam_aliases(struct disp_info *info)
528 struct samr_displayentry *entry;
530 if (info->aliases == NULL) {
531 info->aliases = pdb_search_aliases(&info->sid);
532 if (info->aliases == NULL) {
533 return 0;
536 /* Fetch the last possible entry, thus trigger an enumeration */
537 pdb_search_entries(info->aliases, 0xffffffff, 1, &entry);
539 /* Ensure we cache this enumeration. */
540 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
542 return info->aliases->num_entries;
545 /*******************************************************************
546 _samr_Close
547 ********************************************************************/
549 NTSTATUS _samr_Close(pipes_struct *p, struct samr_Close *r)
551 if (!close_policy_hnd(p, r->in.handle)) {
552 return NT_STATUS_INVALID_HANDLE;
555 ZERO_STRUCTP(r->out.handle);
557 return NT_STATUS_OK;
560 /*******************************************************************
561 _samr_OpenDomain
562 ********************************************************************/
564 NTSTATUS _samr_OpenDomain(pipes_struct *p,
565 struct samr_OpenDomain *r)
567 struct samr_info *info;
568 SEC_DESC *psd = NULL;
569 uint32 acc_granted;
570 uint32 des_access = r->in.access_mask;
571 NTSTATUS status;
572 size_t sd_size;
573 SE_PRIV se_rights;
575 /* find the connection policy handle. */
577 if ( !find_policy_by_hnd(p, r->in.connect_handle, (void**)(void *)&info) )
578 return NT_STATUS_INVALID_HANDLE;
580 status = access_check_samr_function(info->acc_granted,
581 SA_RIGHT_SAM_OPEN_DOMAIN,
582 "_samr_OpenDomain" );
584 if ( !NT_STATUS_IS_OK(status) )
585 return status;
587 /*check if access can be granted as requested by client. */
589 make_samr_object_sd( p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0 );
590 se_map_generic( &des_access, &dom_generic_mapping );
592 se_priv_copy( &se_rights, &se_machine_account );
593 se_priv_add( &se_rights, &se_add_users );
595 status = access_check_samr_object( psd, p->pipe_user.nt_user_token,
596 &se_rights, GENERIC_RIGHTS_DOMAIN_WRITE, des_access,
597 &acc_granted, "_samr_OpenDomain" );
599 if ( !NT_STATUS_IS_OK(status) )
600 return status;
602 if (!sid_check_is_domain(r->in.sid) &&
603 !sid_check_is_builtin(r->in.sid)) {
604 return NT_STATUS_NO_SUCH_DOMAIN;
607 /* associate the domain SID with the (unique) handle. */
608 if ((info = get_samr_info_by_sid(r->in.sid))==NULL)
609 return NT_STATUS_NO_MEMORY;
610 info->acc_granted = acc_granted;
612 /* get a (unique) handle. open a policy on it. */
613 if (!create_policy_hnd(p, r->out.domain_handle, free_samr_info, (void *)info))
614 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
616 DEBUG(5,("_samr_OpenDomain: %d\n", __LINE__));
618 return NT_STATUS_OK;
621 /*******************************************************************
622 _samr_GetUserPwInfo
623 ********************************************************************/
625 NTSTATUS _samr_GetUserPwInfo(pipes_struct *p,
626 struct samr_GetUserPwInfo *r)
628 struct samr_info *info = NULL;
630 /* find the policy handle. open a policy on it. */
631 if (!find_policy_by_hnd(p, r->in.user_handle, (void **)(void *)&info))
632 return NT_STATUS_INVALID_HANDLE;
634 if (!sid_check_is_in_our_domain(&info->sid))
635 return NT_STATUS_OBJECT_TYPE_MISMATCH;
637 ZERO_STRUCTP(r->out.info);
639 DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__));
642 * NT sometimes return NT_STATUS_ACCESS_DENIED
643 * I don't know yet why.
646 return NT_STATUS_OK;
649 /*******************************************************************
650 ********************************************************************/
652 static bool get_lsa_policy_samr_sid( pipes_struct *p, POLICY_HND *pol,
653 DOM_SID *sid, uint32 *acc_granted,
654 DISP_INFO **ppdisp_info)
656 struct samr_info *info = NULL;
658 /* find the policy handle. open a policy on it. */
659 if (!find_policy_by_hnd(p, pol, (void **)(void *)&info))
660 return False;
662 if (!info)
663 return False;
665 *sid = info->sid;
666 *acc_granted = info->acc_granted;
667 if (ppdisp_info) {
668 *ppdisp_info = info->disp_info;
671 return True;
674 /*******************************************************************
675 _samr_SetSecurity
676 ********************************************************************/
678 NTSTATUS _samr_SetSecurity(pipes_struct *p,
679 struct samr_SetSecurity *r)
681 DOM_SID pol_sid;
682 uint32 acc_granted, i;
683 SEC_ACL *dacl;
684 bool ret;
685 struct samu *sampass=NULL;
686 NTSTATUS status;
688 if (!get_lsa_policy_samr_sid(p, r->in.handle, &pol_sid, &acc_granted, NULL))
689 return NT_STATUS_INVALID_HANDLE;
691 if (!(sampass = samu_new( p->mem_ctx))) {
692 DEBUG(0,("No memory!\n"));
693 return NT_STATUS_NO_MEMORY;
696 /* get the user record */
697 become_root();
698 ret = pdb_getsampwsid(sampass, &pol_sid);
699 unbecome_root();
701 if (!ret) {
702 DEBUG(4, ("User %s not found\n", sid_string_dbg(&pol_sid)));
703 TALLOC_FREE(sampass);
704 return NT_STATUS_INVALID_HANDLE;
707 dacl = r->in.sdbuf->sd->dacl;
708 for (i=0; i < dacl->num_aces; i++) {
709 if (sid_equal(&pol_sid, &dacl->aces[i].trustee)) {
710 ret = pdb_set_pass_can_change(sampass,
711 (dacl->aces[i].access_mask &
712 SA_RIGHT_USER_CHANGE_PASSWORD) ?
713 True: False);
714 break;
718 if (!ret) {
719 TALLOC_FREE(sampass);
720 return NT_STATUS_ACCESS_DENIED;
723 status = access_check_samr_function(acc_granted,
724 SA_RIGHT_USER_SET_ATTRIBUTES,
725 "_samr_SetSecurity");
726 if (NT_STATUS_IS_OK(status)) {
727 become_root();
728 status = pdb_update_sam_account(sampass);
729 unbecome_root();
732 TALLOC_FREE(sampass);
734 return status;
737 /*******************************************************************
738 build correct perms based on policies and password times for _samr_query_sec_obj
739 *******************************************************************/
740 static bool check_change_pw_access(TALLOC_CTX *mem_ctx, DOM_SID *user_sid)
742 struct samu *sampass=NULL;
743 bool ret;
745 if ( !(sampass = samu_new( mem_ctx )) ) {
746 DEBUG(0,("No memory!\n"));
747 return False;
750 become_root();
751 ret = pdb_getsampwsid(sampass, user_sid);
752 unbecome_root();
754 if (ret == False) {
755 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
756 TALLOC_FREE(sampass);
757 return False;
760 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
762 if (pdb_get_pass_can_change(sampass)) {
763 TALLOC_FREE(sampass);
764 return True;
766 TALLOC_FREE(sampass);
767 return False;
771 /*******************************************************************
772 _samr_QuerySecurity
773 ********************************************************************/
775 NTSTATUS _samr_QuerySecurity(pipes_struct *p,
776 struct samr_QuerySecurity *r)
778 NTSTATUS status;
779 DOM_SID pol_sid;
780 SEC_DESC * psd = NULL;
781 uint32 acc_granted;
782 size_t sd_size;
784 /* Get the SID. */
785 if (!get_lsa_policy_samr_sid(p, r->in.handle, &pol_sid, &acc_granted, NULL))
786 return NT_STATUS_INVALID_HANDLE;
788 DEBUG(10,("_samr_QuerySecurity: querying security on SID: %s\n",
789 sid_string_dbg(&pol_sid)));
791 /* Check what typ of SID is beeing queried (e.g Domain SID, User SID, Group SID) */
793 /* To query the security of the SAM it self an invalid SID with S-0-0 is passed to this function */
794 if (pol_sid.sid_rev_num == 0) {
795 DEBUG(5,("_samr_QuerySecurity: querying security on SAM\n"));
796 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
797 } else if (sid_equal(&pol_sid,get_global_sam_sid())) {
798 /* check if it is our domain SID */
799 DEBUG(5,("_samr_QuerySecurity: querying security on Domain "
800 "with SID: %s\n", sid_string_dbg(&pol_sid)));
801 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0);
802 } else if (sid_equal(&pol_sid,&global_sid_Builtin)) {
803 /* check if it is the Builtin Domain */
804 /* TODO: Builtin probably needs a different SD with restricted write access*/
805 DEBUG(5,("_samr_QuerySecurity: querying security on Builtin "
806 "Domain with SID: %s\n", sid_string_dbg(&pol_sid)));
807 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0);
808 } else if (sid_check_is_in_our_domain(&pol_sid) ||
809 sid_check_is_in_builtin(&pol_sid)) {
810 /* TODO: different SDs have to be generated for aliases groups and users.
811 Currently all three get a default user SD */
812 DEBUG(10,("_samr_QuerySecurity: querying security on Object "
813 "with SID: %s\n", sid_string_dbg(&pol_sid)));
814 if (check_change_pw_access(p->mem_ctx, &pol_sid)) {
815 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping,
816 &pol_sid, SAMR_USR_RIGHTS_WRITE_PW);
817 } else {
818 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_nopwchange_generic_mapping,
819 &pol_sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
821 } else {
822 return NT_STATUS_OBJECT_TYPE_MISMATCH;
825 if ((*r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
826 return NT_STATUS_NO_MEMORY;
828 return status;
831 /*******************************************************************
832 makes a SAM_ENTRY / UNISTR2* structure from a user list.
833 ********************************************************************/
835 static NTSTATUS make_user_sam_entry_list(TALLOC_CTX *ctx,
836 struct samr_SamEntry **sam_pp,
837 uint32_t num_entries,
838 uint32_t start_idx,
839 struct samr_displayentry *entries)
841 uint32_t i;
842 struct samr_SamEntry *sam;
844 *sam_pp = NULL;
846 if (num_entries == 0) {
847 return NT_STATUS_OK;
850 sam = TALLOC_ZERO_ARRAY(ctx, struct samr_SamEntry, num_entries);
851 if (sam == NULL) {
852 DEBUG(0, ("make_user_sam_entry_list: TALLOC_ZERO failed!\n"));
853 return NT_STATUS_NO_MEMORY;
856 for (i = 0; i < num_entries; i++) {
857 #if 0
859 * usrmgr expects a non-NULL terminated string with
860 * trust relationships
862 if (entries[i].acct_flags & ACB_DOMTRUST) {
863 init_unistr2(&uni_temp_name, entries[i].account_name,
864 UNI_FLAGS_NONE);
865 } else {
866 init_unistr2(&uni_temp_name, entries[i].account_name,
867 UNI_STR_TERMINATE);
869 #endif
870 init_lsa_String(&sam[i].name, entries[i].account_name);
871 sam[i].idx = entries[i].rid;
874 *sam_pp = sam;
876 return NT_STATUS_OK;
879 /*******************************************************************
880 _samr_EnumDomainUsers
881 ********************************************************************/
883 NTSTATUS _samr_EnumDomainUsers(pipes_struct *p,
884 struct samr_EnumDomainUsers *r)
886 NTSTATUS status;
887 struct samr_info *info = NULL;
888 int num_account;
889 uint32 enum_context = *r->in.resume_handle;
890 enum remote_arch_types ra_type = get_remote_arch();
891 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
892 uint32 max_entries = max_sam_entries;
893 struct samr_displayentry *entries = NULL;
894 struct samr_SamArray *samr_array = NULL;
895 struct samr_SamEntry *samr_entries = NULL;
897 /* find the policy handle. open a policy on it. */
898 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
899 return NT_STATUS_INVALID_HANDLE;
901 status = access_check_samr_function(info->acc_granted,
902 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
903 "_samr_EnumDomainUsers");
904 if (!NT_STATUS_IS_OK(status)) {
905 return status;
908 DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
910 if (info->builtin_domain) {
911 /* No users in builtin. */
912 *r->out.resume_handle = *r->in.resume_handle;
913 DEBUG(5,("_samr_EnumDomainUsers: No users in BUILTIN\n"));
914 return status;
917 samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
918 if (!samr_array) {
919 return NT_STATUS_NO_MEMORY;
922 become_root();
924 /* AS ROOT !!!! */
926 if ((info->disp_info->enum_users != NULL) &&
927 (info->disp_info->enum_acb_mask != r->in.acct_flags)) {
928 pdb_search_destroy(info->disp_info->enum_users);
929 info->disp_info->enum_users = NULL;
932 if (info->disp_info->enum_users == NULL) {
933 info->disp_info->enum_users = pdb_search_users(r->in.acct_flags);
934 info->disp_info->enum_acb_mask = r->in.acct_flags;
937 if (info->disp_info->enum_users == NULL) {
938 /* END AS ROOT !!!! */
939 unbecome_root();
940 return NT_STATUS_ACCESS_DENIED;
943 num_account = pdb_search_entries(info->disp_info->enum_users,
944 enum_context, max_entries,
945 &entries);
947 /* END AS ROOT !!!! */
949 unbecome_root();
951 if (num_account == 0) {
952 DEBUG(5, ("_samr_EnumDomainUsers: enumeration handle over "
953 "total entries\n"));
954 *r->out.resume_handle = *r->in.resume_handle;
955 return NT_STATUS_OK;
958 status = make_user_sam_entry_list(p->mem_ctx, &samr_entries,
959 num_account, enum_context,
960 entries);
961 if (!NT_STATUS_IS_OK(status)) {
962 return status;
965 if (max_entries <= num_account) {
966 status = STATUS_MORE_ENTRIES;
967 } else {
968 status = NT_STATUS_OK;
971 /* Ensure we cache this enumeration. */
972 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
974 DEBUG(5, ("_samr_EnumDomainUsers: %d\n", __LINE__));
976 samr_array->count = num_account;
977 samr_array->entries = samr_entries;
979 *r->out.resume_handle = *r->in.resume_handle + num_account;
980 *r->out.sam = samr_array;
981 *r->out.num_entries = num_account;
983 DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
985 return status;
988 /*******************************************************************
989 makes a SAM_ENTRY / UNISTR2* structure from a group list.
990 ********************************************************************/
992 static void make_group_sam_entry_list(TALLOC_CTX *ctx,
993 struct samr_SamEntry **sam_pp,
994 uint32_t num_sam_entries,
995 struct samr_displayentry *entries)
997 struct samr_SamEntry *sam;
998 uint32_t i;
1000 *sam_pp = NULL;
1002 if (num_sam_entries == 0) {
1003 return;
1006 sam = TALLOC_ZERO_ARRAY(ctx, struct samr_SamEntry, num_sam_entries);
1007 if (sam == NULL) {
1008 return;
1011 for (i = 0; i < num_sam_entries; i++) {
1013 * JRA. I think this should include the null. TNG does not.
1015 init_lsa_String(&sam[i].name, entries[i].account_name);
1016 sam[i].idx = entries[i].rid;
1019 *sam_pp = sam;
1022 /*******************************************************************
1023 _samr_EnumDomainGroups
1024 ********************************************************************/
1026 NTSTATUS _samr_EnumDomainGroups(pipes_struct *p,
1027 struct samr_EnumDomainGroups *r)
1029 NTSTATUS status;
1030 struct samr_info *info = NULL;
1031 struct samr_displayentry *groups;
1032 uint32 num_groups;
1033 struct samr_SamArray *samr_array = NULL;
1034 struct samr_SamEntry *samr_entries = NULL;
1036 /* find the policy handle. open a policy on it. */
1037 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
1038 return NT_STATUS_INVALID_HANDLE;
1040 status = access_check_samr_function(info->acc_granted,
1041 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
1042 "_samr_EnumDomainGroups");
1043 if (!NT_STATUS_IS_OK(status)) {
1044 return status;
1047 DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
1049 if (info->builtin_domain) {
1050 /* No groups in builtin. */
1051 *r->out.resume_handle = *r->in.resume_handle;
1052 DEBUG(5,("_samr_EnumDomainGroups: No groups in BUILTIN\n"));
1053 return status;
1056 samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
1057 if (!samr_array) {
1058 return NT_STATUS_NO_MEMORY;
1061 /* the domain group array is being allocated in the function below */
1063 become_root();
1065 if (info->disp_info->groups == NULL) {
1066 info->disp_info->groups = pdb_search_groups();
1068 if (info->disp_info->groups == NULL) {
1069 unbecome_root();
1070 return NT_STATUS_ACCESS_DENIED;
1074 num_groups = pdb_search_entries(info->disp_info->groups,
1075 *r->in.resume_handle,
1076 MAX_SAM_ENTRIES, &groups);
1077 unbecome_root();
1079 /* Ensure we cache this enumeration. */
1080 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1082 make_group_sam_entry_list(p->mem_ctx, &samr_entries,
1083 num_groups, groups);
1085 samr_array->count = num_groups;
1086 samr_array->entries = samr_entries;
1088 *r->out.sam = samr_array;
1089 *r->out.num_entries = num_groups;
1090 /* this was missing, IMHO:
1091 *r->out.resume_handle = num_groups + *r->in.resume_handle;
1094 DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
1096 return status;
1099 /*******************************************************************
1100 _samr_EnumDomainAliases
1101 ********************************************************************/
1103 NTSTATUS _samr_EnumDomainAliases(pipes_struct *p,
1104 struct samr_EnumDomainAliases *r)
1106 NTSTATUS status;
1107 struct samr_info *info;
1108 struct samr_displayentry *aliases;
1109 uint32 num_aliases = 0;
1110 struct samr_SamArray *samr_array = NULL;
1111 struct samr_SamEntry *samr_entries = NULL;
1113 /* find the policy handle. open a policy on it. */
1114 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
1115 return NT_STATUS_INVALID_HANDLE;
1117 status = access_check_samr_function(info->acc_granted,
1118 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
1119 "_samr_EnumDomainAliases");
1120 if (!NT_STATUS_IS_OK(status)) {
1121 return status;
1124 DEBUG(5,("_samr_EnumDomainAliases: sid %s\n",
1125 sid_string_dbg(&info->sid)));
1127 samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
1128 if (!samr_array) {
1129 return NT_STATUS_NO_MEMORY;
1132 become_root();
1134 if (info->disp_info->aliases == NULL) {
1135 info->disp_info->aliases = pdb_search_aliases(&info->sid);
1136 if (info->disp_info->aliases == NULL) {
1137 unbecome_root();
1138 return NT_STATUS_ACCESS_DENIED;
1142 num_aliases = pdb_search_entries(info->disp_info->aliases,
1143 *r->in.resume_handle,
1144 MAX_SAM_ENTRIES, &aliases);
1145 unbecome_root();
1147 /* Ensure we cache this enumeration. */
1148 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1150 make_group_sam_entry_list(p->mem_ctx, &samr_entries,
1151 num_aliases, aliases);
1153 DEBUG(5,("_samr_EnumDomainAliases: %d\n", __LINE__));
1155 samr_array->count = num_aliases;
1156 samr_array->entries = samr_entries;
1158 *r->out.sam = samr_array;
1159 *r->out.num_entries = num_aliases;
1160 *r->out.resume_handle = num_aliases + *r->in.resume_handle;
1162 return status;
1165 /*******************************************************************
1166 inits a samr_DispInfoGeneral structure.
1167 ********************************************************************/
1169 static NTSTATUS init_samr_dispinfo_1(TALLOC_CTX *ctx,
1170 struct samr_DispInfoGeneral *r,
1171 uint32_t num_entries,
1172 uint32_t start_idx,
1173 struct samr_displayentry *entries)
1175 uint32 i;
1177 DEBUG(10, ("init_samr_dispinfo_1: num_entries: %d\n", num_entries));
1179 if (num_entries == 0) {
1180 return NT_STATUS_OK;
1183 r->count = num_entries;
1185 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryGeneral, num_entries);
1186 if (!r->entries) {
1187 return NT_STATUS_NO_MEMORY;
1190 for (i = 0; i < num_entries ; i++) {
1192 init_lsa_String(&r->entries[i].account_name,
1193 entries[i].account_name);
1195 init_lsa_String(&r->entries[i].description,
1196 entries[i].description);
1198 init_lsa_String(&r->entries[i].full_name,
1199 entries[i].fullname);
1201 r->entries[i].rid = entries[i].rid;
1202 r->entries[i].acct_flags = entries[i].acct_flags;
1203 r->entries[i].idx = start_idx+i+1;
1206 return NT_STATUS_OK;
1209 /*******************************************************************
1210 inits a samr_DispInfoFull structure.
1211 ********************************************************************/
1213 static NTSTATUS init_samr_dispinfo_2(TALLOC_CTX *ctx,
1214 struct samr_DispInfoFull *r,
1215 uint32_t num_entries,
1216 uint32_t start_idx,
1217 struct samr_displayentry *entries)
1219 uint32_t i;
1221 DEBUG(10, ("init_samr_dispinfo_2: num_entries: %d\n", num_entries));
1223 if (num_entries == 0) {
1224 return NT_STATUS_OK;
1227 r->count = num_entries;
1229 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryFull, num_entries);
1230 if (!r->entries) {
1231 return NT_STATUS_NO_MEMORY;
1234 for (i = 0; i < num_entries ; i++) {
1236 init_lsa_String(&r->entries[i].account_name,
1237 entries[i].account_name);
1239 init_lsa_String(&r->entries[i].description,
1240 entries[i].description);
1242 r->entries[i].rid = entries[i].rid;
1243 r->entries[i].acct_flags = entries[i].acct_flags;
1244 r->entries[i].idx = start_idx+i+1;
1247 return NT_STATUS_OK;
1250 /*******************************************************************
1251 inits a samr_DispInfoFullGroups structure.
1252 ********************************************************************/
1254 static NTSTATUS init_samr_dispinfo_3(TALLOC_CTX *ctx,
1255 struct samr_DispInfoFullGroups *r,
1256 uint32_t num_entries,
1257 uint32_t start_idx,
1258 struct samr_displayentry *entries)
1260 uint32_t i;
1262 DEBUG(5, ("init_samr_dispinfo_3: num_entries: %d\n", num_entries));
1264 if (num_entries == 0) {
1265 return NT_STATUS_OK;
1268 r->count = num_entries;
1270 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryFullGroup, num_entries);
1271 if (!r->entries) {
1272 return NT_STATUS_NO_MEMORY;
1275 for (i = 0; i < num_entries ; i++) {
1277 init_lsa_String(&r->entries[i].account_name,
1278 entries[i].account_name);
1280 init_lsa_String(&r->entries[i].description,
1281 entries[i].description);
1283 r->entries[i].rid = entries[i].rid;
1284 r->entries[i].acct_flags = entries[i].acct_flags;
1285 r->entries[i].idx = start_idx+i+1;
1288 return NT_STATUS_OK;
1291 /*******************************************************************
1292 inits a samr_DispInfoAscii structure.
1293 ********************************************************************/
1295 static NTSTATUS init_samr_dispinfo_4(TALLOC_CTX *ctx,
1296 struct samr_DispInfoAscii *r,
1297 uint32_t num_entries,
1298 uint32_t start_idx,
1299 struct samr_displayentry *entries)
1301 uint32_t i;
1303 DEBUG(5, ("init_samr_dispinfo_4: num_entries: %d\n", num_entries));
1305 if (num_entries == 0) {
1306 return NT_STATUS_OK;
1309 r->count = num_entries;
1311 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryAscii, num_entries);
1312 if (!r->entries) {
1313 return NT_STATUS_NO_MEMORY;
1316 for (i = 0; i < num_entries ; i++) {
1318 init_lsa_AsciiString(&r->entries[i].account_name,
1319 entries[i].account_name);
1321 r->entries[i].idx = start_idx+i+1;
1324 return NT_STATUS_OK;
1327 /*******************************************************************
1328 inits a samr_DispInfoAscii structure.
1329 ********************************************************************/
1331 static NTSTATUS init_samr_dispinfo_5(TALLOC_CTX *ctx,
1332 struct samr_DispInfoAscii *r,
1333 uint32_t num_entries,
1334 uint32_t start_idx,
1335 struct samr_displayentry *entries)
1337 uint32_t i;
1339 DEBUG(5, ("init_samr_dispinfo_5: num_entries: %d\n", num_entries));
1341 if (num_entries == 0) {
1342 return NT_STATUS_OK;
1345 r->count = num_entries;
1347 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryAscii, num_entries);
1348 if (!r->entries) {
1349 return NT_STATUS_NO_MEMORY;
1352 for (i = 0; i < num_entries ; i++) {
1354 init_lsa_AsciiString(&r->entries[i].account_name,
1355 entries[i].account_name);
1357 r->entries[i].idx = start_idx+i+1;
1360 return NT_STATUS_OK;
1363 /*******************************************************************
1364 _samr_QueryDisplayInfo
1365 ********************************************************************/
1367 NTSTATUS _samr_QueryDisplayInfo(pipes_struct *p,
1368 struct samr_QueryDisplayInfo *r)
1370 NTSTATUS status;
1371 struct samr_info *info = NULL;
1372 uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
1374 uint32 max_entries = r->in.max_entries;
1375 uint32 enum_context = r->in.start_idx;
1376 uint32 max_size = r->in.buf_size;
1378 union samr_DispInfo *disp_info = r->out.info;
1380 uint32 temp_size=0, total_data_size=0;
1381 NTSTATUS disp_ret = NT_STATUS_UNSUCCESSFUL;
1382 uint32 num_account = 0;
1383 enum remote_arch_types ra_type = get_remote_arch();
1384 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
1385 struct samr_displayentry *entries = NULL;
1387 DEBUG(5,("_samr_QueryDisplayInfo: %d\n", __LINE__));
1389 /* find the policy handle. open a policy on it. */
1390 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
1391 return NT_STATUS_INVALID_HANDLE;
1394 * calculate how many entries we will return.
1395 * based on
1396 * - the number of entries the client asked
1397 * - our limit on that
1398 * - the starting point (enumeration context)
1399 * - the buffer size the client will accept
1403 * We are a lot more like W2K. Instead of reading the SAM
1404 * each time to find the records we need to send back,
1405 * we read it once and link that copy to the sam handle.
1406 * For large user list (over the MAX_SAM_ENTRIES)
1407 * it's a definitive win.
1408 * second point to notice: between enumerations
1409 * our sam is now the same as it's a snapshoot.
1410 * third point: got rid of the static SAM_USER_21 struct
1411 * no more intermediate.
1412 * con: it uses much more memory, as a full copy is stored
1413 * in memory.
1415 * If you want to change it, think twice and think
1416 * of the second point , that's really important.
1418 * JFM, 12/20/2001
1421 if ((r->in.level < 1) || (r->in.level > 5)) {
1422 DEBUG(0,("_samr_QueryDisplayInfo: Unknown info level (%u)\n",
1423 (unsigned int)r->in.level ));
1424 return NT_STATUS_INVALID_INFO_CLASS;
1427 /* first limit the number of entries we will return */
1428 if(max_entries > max_sam_entries) {
1429 DEBUG(5, ("_samr_QueryDisplayInfo: client requested %d "
1430 "entries, limiting to %d\n", max_entries,
1431 max_sam_entries));
1432 max_entries = max_sam_entries;
1435 /* calculate the size and limit on the number of entries we will
1436 * return */
1438 temp_size=max_entries*struct_size;
1440 if (temp_size>max_size) {
1441 max_entries=MIN((max_size/struct_size),max_entries);;
1442 DEBUG(5, ("_samr_QueryDisplayInfo: buffer size limits to "
1443 "only %d entries\n", max_entries));
1446 become_root();
1448 /* THe following done as ROOT. Don't return without unbecome_root(). */
1450 switch (r->in.level) {
1451 case 0x1:
1452 case 0x4:
1453 if (info->disp_info->users == NULL) {
1454 info->disp_info->users = pdb_search_users(ACB_NORMAL);
1455 if (info->disp_info->users == NULL) {
1456 unbecome_root();
1457 return NT_STATUS_ACCESS_DENIED;
1459 DEBUG(10,("_samr_QueryDisplayInfo: starting user enumeration at index %u\n",
1460 (unsigned int)enum_context ));
1461 } else {
1462 DEBUG(10,("_samr_QueryDisplayInfo: using cached user enumeration at index %u\n",
1463 (unsigned int)enum_context ));
1466 num_account = pdb_search_entries(info->disp_info->users,
1467 enum_context, max_entries,
1468 &entries);
1469 break;
1470 case 0x2:
1471 if (info->disp_info->machines == NULL) {
1472 info->disp_info->machines =
1473 pdb_search_users(ACB_WSTRUST|ACB_SVRTRUST);
1474 if (info->disp_info->machines == NULL) {
1475 unbecome_root();
1476 return NT_STATUS_ACCESS_DENIED;
1478 DEBUG(10,("_samr_QueryDisplayInfo: starting machine enumeration at index %u\n",
1479 (unsigned int)enum_context ));
1480 } else {
1481 DEBUG(10,("_samr_QueryDisplayInfo: using cached machine enumeration at index %u\n",
1482 (unsigned int)enum_context ));
1485 num_account = pdb_search_entries(info->disp_info->machines,
1486 enum_context, max_entries,
1487 &entries);
1488 break;
1489 case 0x3:
1490 case 0x5:
1491 if (info->disp_info->groups == NULL) {
1492 info->disp_info->groups = pdb_search_groups();
1493 if (info->disp_info->groups == NULL) {
1494 unbecome_root();
1495 return NT_STATUS_ACCESS_DENIED;
1497 DEBUG(10,("_samr_QueryDisplayInfo: starting group enumeration at index %u\n",
1498 (unsigned int)enum_context ));
1499 } else {
1500 DEBUG(10,("_samr_QueryDisplayInfo: using cached group enumeration at index %u\n",
1501 (unsigned int)enum_context ));
1504 num_account = pdb_search_entries(info->disp_info->groups,
1505 enum_context, max_entries,
1506 &entries);
1507 break;
1508 default:
1509 unbecome_root();
1510 smb_panic("info class changed");
1511 break;
1513 unbecome_root();
1516 /* Now create reply structure */
1517 switch (r->in.level) {
1518 case 0x1:
1519 disp_ret = init_samr_dispinfo_1(p->mem_ctx, &disp_info->info1,
1520 num_account, enum_context,
1521 entries);
1522 break;
1523 case 0x2:
1524 disp_ret = init_samr_dispinfo_2(p->mem_ctx, &disp_info->info2,
1525 num_account, enum_context,
1526 entries);
1527 break;
1528 case 0x3:
1529 disp_ret = init_samr_dispinfo_3(p->mem_ctx, &disp_info->info3,
1530 num_account, enum_context,
1531 entries);
1532 break;
1533 case 0x4:
1534 disp_ret = init_samr_dispinfo_4(p->mem_ctx, &disp_info->info4,
1535 num_account, enum_context,
1536 entries);
1537 break;
1538 case 0x5:
1539 disp_ret = init_samr_dispinfo_5(p->mem_ctx, &disp_info->info5,
1540 num_account, enum_context,
1541 entries);
1542 break;
1543 default:
1544 smb_panic("info class changed");
1545 break;
1548 if (!NT_STATUS_IS_OK(disp_ret))
1549 return disp_ret;
1551 /* calculate the total size */
1552 total_data_size=num_account*struct_size;
1554 if (num_account) {
1555 status = STATUS_MORE_ENTRIES;
1556 } else {
1557 status = NT_STATUS_OK;
1560 /* Ensure we cache this enumeration. */
1561 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1563 DEBUG(5, ("_samr_QueryDisplayInfo: %d\n", __LINE__));
1565 *r->out.total_size = total_data_size;
1566 *r->out.returned_size = temp_size;
1568 return status;
1571 /****************************************************************
1572 _samr_QueryDisplayInfo2
1573 ****************************************************************/
1575 NTSTATUS _samr_QueryDisplayInfo2(pipes_struct *p,
1576 struct samr_QueryDisplayInfo2 *r)
1578 struct samr_QueryDisplayInfo q;
1580 q.in.domain_handle = r->in.domain_handle;
1581 q.in.level = r->in.level;
1582 q.in.start_idx = r->in.start_idx;
1583 q.in.max_entries = r->in.max_entries;
1584 q.in.buf_size = r->in.buf_size;
1586 q.out.total_size = r->out.total_size;
1587 q.out.returned_size = r->out.returned_size;
1588 q.out.info = r->out.info;
1590 return _samr_QueryDisplayInfo(p, &q);
1593 /****************************************************************
1594 _samr_QueryDisplayInfo3
1595 ****************************************************************/
1597 NTSTATUS _samr_QueryDisplayInfo3(pipes_struct *p,
1598 struct samr_QueryDisplayInfo3 *r)
1600 struct samr_QueryDisplayInfo q;
1602 q.in.domain_handle = r->in.domain_handle;
1603 q.in.level = r->in.level;
1604 q.in.start_idx = r->in.start_idx;
1605 q.in.max_entries = r->in.max_entries;
1606 q.in.buf_size = r->in.buf_size;
1608 q.out.total_size = r->out.total_size;
1609 q.out.returned_size = r->out.returned_size;
1610 q.out.info = r->out.info;
1612 return _samr_QueryDisplayInfo(p, &q);
1615 /*******************************************************************
1616 _samr_QueryAliasInfo
1617 ********************************************************************/
1619 NTSTATUS _samr_QueryAliasInfo(pipes_struct *p,
1620 struct samr_QueryAliasInfo *r)
1622 DOM_SID sid;
1623 struct acct_info info;
1624 uint32 acc_granted;
1625 NTSTATUS status;
1626 union samr_AliasInfo *alias_info = NULL;
1627 const char *alias_name = NULL;
1628 const char *alias_description = NULL;
1630 DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1632 alias_info = TALLOC_ZERO_P(p->mem_ctx, union samr_AliasInfo);
1633 if (!alias_info) {
1634 return NT_STATUS_NO_MEMORY;
1637 /* find the policy handle. open a policy on it. */
1638 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &sid, &acc_granted, NULL))
1639 return NT_STATUS_INVALID_HANDLE;
1641 status = access_check_samr_function(acc_granted,
1642 SA_RIGHT_ALIAS_LOOKUP_INFO,
1643 "_samr_QueryAliasInfo");
1644 if (!NT_STATUS_IS_OK(status)) {
1645 return status;
1648 become_root();
1649 status = pdb_get_aliasinfo(&sid, &info);
1650 unbecome_root();
1652 if ( !NT_STATUS_IS_OK(status))
1653 return status;
1655 /* FIXME: info contains fstrings */
1656 alias_name = talloc_strdup(r, info.acct_name);
1657 alias_description = talloc_strdup(r, info.acct_desc);
1659 switch (r->in.level) {
1660 case ALIASINFOALL:
1661 init_samr_alias_info1(&alias_info->all,
1662 alias_name,
1664 alias_description);
1665 break;
1666 case ALIASINFODESCRIPTION:
1667 init_samr_alias_info3(&alias_info->description,
1668 alias_description);
1669 break;
1670 default:
1671 return NT_STATUS_INVALID_INFO_CLASS;
1674 *r->out.info = alias_info;
1676 DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1678 return NT_STATUS_OK;
1681 #if 0
1682 /*******************************************************************
1683 samr_reply_lookup_ids
1684 ********************************************************************/
1686 uint32 _samr_lookup_ids(pipes_struct *p, SAMR_Q_LOOKUP_IDS *q_u, SAMR_R_LOOKUP_IDS *r_u)
1688 uint32 rid[MAX_SAM_ENTRIES];
1689 int num_rids = q_u->num_sids1;
1691 r_u->status = NT_STATUS_OK;
1693 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1695 if (num_rids > MAX_SAM_ENTRIES) {
1696 num_rids = MAX_SAM_ENTRIES;
1697 DEBUG(5,("_samr_lookup_ids: truncating entries to %d\n", num_rids));
1700 #if 0
1701 int i;
1702 SMB_ASSERT_ARRAY(q_u->uni_user_name, num_rids);
1704 for (i = 0; i < num_rids && status == 0; i++)
1706 struct sam_passwd *sam_pass;
1707 fstring user_name;
1710 fstrcpy(user_name, unistrn2(q_u->uni_user_name[i].buffer,
1711 q_u->uni_user_name[i].uni_str_len));
1713 /* find the user account */
1714 become_root();
1715 sam_pass = get_smb21pwd_entry(user_name, 0);
1716 unbecome_root();
1718 if (sam_pass == NULL)
1720 status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1721 rid[i] = 0;
1723 else
1725 rid[i] = sam_pass->user_rid;
1728 #endif
1730 num_rids = 1;
1731 rid[0] = BUILTIN_ALIAS_RID_USERS;
1733 init_samr_r_lookup_ids(&r_u, num_rids, rid, NT_STATUS_OK);
1735 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1737 return r_u->status;
1739 #endif
1741 /*******************************************************************
1742 _samr_LookupNames
1743 ********************************************************************/
1745 NTSTATUS _samr_LookupNames(pipes_struct *p,
1746 struct samr_LookupNames *r)
1748 NTSTATUS status;
1749 uint32 rid[MAX_SAM_ENTRIES];
1750 enum lsa_SidType type[MAX_SAM_ENTRIES];
1751 int i;
1752 int num_rids = r->in.num_names;
1753 DOM_SID pol_sid;
1754 uint32 acc_granted;
1755 struct samr_Ids rids, types;
1757 DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1759 ZERO_ARRAY(rid);
1760 ZERO_ARRAY(type);
1762 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &pol_sid, &acc_granted, NULL)) {
1763 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1766 status = access_check_samr_function(acc_granted,
1767 0, /* Don't know the acc_bits yet */
1768 "_samr_LookupNames");
1769 if (!NT_STATUS_IS_OK(status)) {
1770 return status;
1773 if (num_rids > MAX_SAM_ENTRIES) {
1774 num_rids = MAX_SAM_ENTRIES;
1775 DEBUG(5,("_samr_LookupNames: truncating entries to %d\n", num_rids));
1778 DEBUG(5,("_samr_LookupNames: looking name on SID %s\n",
1779 sid_string_dbg(&pol_sid)));
1781 for (i = 0; i < num_rids; i++) {
1783 status = NT_STATUS_NONE_MAPPED;
1784 type[i] = SID_NAME_UNKNOWN;
1786 rid[i] = 0xffffffff;
1788 if (sid_check_is_builtin(&pol_sid)) {
1789 if (lookup_builtin_name(r->in.names[i].string,
1790 &rid[i]))
1792 type[i] = SID_NAME_ALIAS;
1794 } else {
1795 lookup_global_sam_name(r->in.names[i].string, 0,
1796 &rid[i], &type[i]);
1799 if (type[i] != SID_NAME_UNKNOWN) {
1800 status = NT_STATUS_OK;
1804 rids.count = num_rids;
1805 rids.ids = rid;
1807 types.count = num_rids;
1808 types.ids = type;
1810 *r->out.rids = rids;
1811 *r->out.types = types;
1813 DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1815 return status;
1818 /*******************************************************************
1819 _samr_ChangePasswordUser2
1820 ********************************************************************/
1822 NTSTATUS _samr_ChangePasswordUser2(pipes_struct *p,
1823 struct samr_ChangePasswordUser2 *r)
1825 NTSTATUS status;
1826 fstring user_name;
1827 fstring wks;
1829 DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1831 fstrcpy(user_name, r->in.account->string);
1832 fstrcpy(wks, r->in.server->string);
1834 DEBUG(5,("_samr_ChangePasswordUser2: user: %s wks: %s\n", user_name, wks));
1837 * Pass the user through the NT -> unix user mapping
1838 * function.
1841 (void)map_username(user_name);
1844 * UNIX username case mangling not required, pass_oem_change
1845 * is case insensitive.
1848 status = pass_oem_change(user_name,
1849 r->in.lm_password->data,
1850 r->in.lm_verifier->hash,
1851 r->in.nt_password->data,
1852 r->in.nt_verifier->hash,
1853 NULL);
1855 DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1857 return status;
1860 /*******************************************************************
1861 _samr_ChangePasswordUser3
1862 ********************************************************************/
1864 NTSTATUS _samr_ChangePasswordUser3(pipes_struct *p,
1865 struct samr_ChangePasswordUser3 *r)
1867 NTSTATUS status;
1868 fstring user_name;
1869 const char *wks = NULL;
1870 uint32 reject_reason;
1871 struct samr_DomInfo1 *dominfo = NULL;
1872 struct samr_ChangeReject *reject = NULL;
1874 DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
1876 fstrcpy(user_name, r->in.account->string);
1877 if (r->in.server && r->in.server->string) {
1878 wks = r->in.server->string;
1881 DEBUG(5,("_samr_ChangePasswordUser3: user: %s wks: %s\n", user_name, wks));
1884 * Pass the user through the NT -> unix user mapping
1885 * function.
1888 (void)map_username(user_name);
1891 * UNIX username case mangling not required, pass_oem_change
1892 * is case insensitive.
1895 status = pass_oem_change(user_name,
1896 r->in.lm_password->data,
1897 r->in.lm_verifier->hash,
1898 r->in.nt_password->data,
1899 r->in.nt_verifier->hash,
1900 &reject_reason);
1902 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) ||
1903 NT_STATUS_EQUAL(status, NT_STATUS_ACCOUNT_RESTRICTION)) {
1905 uint32 min_pass_len,pass_hist,password_properties;
1906 time_t u_expire, u_min_age;
1907 NTTIME nt_expire, nt_min_age;
1908 uint32 account_policy_temp;
1910 dominfo = TALLOC_ZERO_P(p->mem_ctx, struct samr_DomInfo1);
1911 if (!dominfo) {
1912 return NT_STATUS_NO_MEMORY;
1915 reject = TALLOC_ZERO_P(p->mem_ctx, struct samr_ChangeReject);
1916 if (!reject) {
1917 return NT_STATUS_NO_MEMORY;
1920 become_root();
1922 /* AS ROOT !!! */
1924 pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &account_policy_temp);
1925 min_pass_len = account_policy_temp;
1927 pdb_get_account_policy(AP_PASSWORD_HISTORY, &account_policy_temp);
1928 pass_hist = account_policy_temp;
1930 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
1931 password_properties = account_policy_temp;
1933 pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
1934 u_expire = account_policy_temp;
1936 pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
1937 u_min_age = account_policy_temp;
1939 /* !AS ROOT */
1941 unbecome_root();
1943 unix_to_nt_time_abs(&nt_expire, u_expire);
1944 unix_to_nt_time_abs(&nt_min_age, u_min_age);
1946 if (lp_check_password_script() && *lp_check_password_script()) {
1947 password_properties |= DOMAIN_PASSWORD_COMPLEX;
1950 init_samr_DomInfo1(dominfo,
1951 min_pass_len,
1952 pass_hist,
1953 password_properties,
1954 u_expire,
1955 u_min_age);
1957 reject->reason = reject_reason;
1959 *r->out.dominfo = dominfo;
1960 *r->out.reject = reject;
1963 DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
1965 return status;
1968 /*******************************************************************
1969 makes a SAMR_R_LOOKUP_RIDS structure.
1970 ********************************************************************/
1972 static bool make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names,
1973 const char **names,
1974 struct lsa_String **lsa_name_array_p)
1976 struct lsa_String *lsa_name_array = NULL;
1977 uint32_t i;
1979 *lsa_name_array_p = NULL;
1981 if (num_names != 0) {
1982 lsa_name_array = TALLOC_ZERO_ARRAY(ctx, struct lsa_String, num_names);
1983 if (!lsa_name_array) {
1984 return false;
1988 for (i = 0; i < num_names; i++) {
1989 DEBUG(10, ("names[%d]:%s\n", i, names[i] && *names[i] ? names[i] : ""));
1990 init_lsa_String(&lsa_name_array[i], names[i]);
1993 *lsa_name_array_p = lsa_name_array;
1995 return true;
1998 /*******************************************************************
1999 _samr_LookupRids
2000 ********************************************************************/
2002 NTSTATUS _samr_LookupRids(pipes_struct *p,
2003 struct samr_LookupRids *r)
2005 NTSTATUS status;
2006 const char **names;
2007 enum lsa_SidType *attrs = NULL;
2008 uint32 *wire_attrs = NULL;
2009 DOM_SID pol_sid;
2010 int num_rids = (int)r->in.num_rids;
2011 uint32 acc_granted;
2012 int i;
2013 struct lsa_Strings names_array;
2014 struct samr_Ids types_array;
2015 struct lsa_String *lsa_names = NULL;
2017 DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2019 /* find the policy handle. open a policy on it. */
2020 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &pol_sid, &acc_granted, NULL))
2021 return NT_STATUS_INVALID_HANDLE;
2023 if (num_rids > 1000) {
2024 DEBUG(0, ("Got asked for %d rids (more than 1000) -- according "
2025 "to samba4 idl this is not possible\n", num_rids));
2026 return NT_STATUS_UNSUCCESSFUL;
2029 if (num_rids) {
2030 names = TALLOC_ZERO_ARRAY(p->mem_ctx, const char *, num_rids);
2031 attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, enum lsa_SidType, num_rids);
2032 wire_attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_rids);
2034 if ((names == NULL) || (attrs == NULL) || (wire_attrs==NULL))
2035 return NT_STATUS_NO_MEMORY;
2036 } else {
2037 names = NULL;
2038 attrs = NULL;
2039 wire_attrs = NULL;
2042 become_root(); /* lookup_sid can require root privs */
2043 status = pdb_lookup_rids(&pol_sid, num_rids, r->in.rids,
2044 names, attrs);
2045 unbecome_root();
2047 if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED) && (num_rids == 0)) {
2048 status = NT_STATUS_OK;
2051 if (!make_samr_lookup_rids(p->mem_ctx, num_rids, names,
2052 &lsa_names)) {
2053 return NT_STATUS_NO_MEMORY;
2056 /* Convert from enum lsa_SidType to uint32 for wire format. */
2057 for (i = 0; i < num_rids; i++) {
2058 wire_attrs[i] = (uint32)attrs[i];
2061 names_array.count = num_rids;
2062 names_array.names = lsa_names;
2064 types_array.count = num_rids;
2065 types_array.ids = wire_attrs;
2067 *r->out.names = names_array;
2068 *r->out.types = types_array;
2070 DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2072 return status;
2075 /*******************************************************************
2076 _samr_OpenUser
2077 ********************************************************************/
2079 NTSTATUS _samr_OpenUser(pipes_struct *p,
2080 struct samr_OpenUser *r)
2082 struct samu *sampass=NULL;
2083 DOM_SID sid;
2084 POLICY_HND domain_pol = *r->in.domain_handle;
2085 POLICY_HND *user_pol = r->out.user_handle;
2086 struct samr_info *info = NULL;
2087 SEC_DESC *psd = NULL;
2088 uint32 acc_granted;
2089 uint32 des_access = r->in.access_mask;
2090 size_t sd_size;
2091 bool ret;
2092 NTSTATUS nt_status;
2093 SE_PRIV se_rights;
2095 /* find the domain policy handle and get domain SID / access bits in the domain policy. */
2097 if ( !get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted, NULL) )
2098 return NT_STATUS_INVALID_HANDLE;
2100 nt_status = access_check_samr_function(acc_granted,
2101 SA_RIGHT_DOMAIN_OPEN_ACCOUNT,
2102 "_samr_OpenUser" );
2104 if ( !NT_STATUS_IS_OK(nt_status) )
2105 return nt_status;
2107 if ( !(sampass = samu_new( p->mem_ctx )) ) {
2108 return NT_STATUS_NO_MEMORY;
2111 /* append the user's RID to it */
2113 if (!sid_append_rid(&sid, r->in.rid))
2114 return NT_STATUS_NO_SUCH_USER;
2116 /* check if access can be granted as requested by client. */
2118 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &sid, SAMR_USR_RIGHTS_WRITE_PW);
2119 se_map_generic(&des_access, &usr_generic_mapping);
2121 se_priv_copy( &se_rights, &se_machine_account );
2122 se_priv_add( &se_rights, &se_add_users );
2124 nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
2125 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
2126 &acc_granted, "_samr_OpenUser");
2128 if ( !NT_STATUS_IS_OK(nt_status) )
2129 return nt_status;
2131 become_root();
2132 ret=pdb_getsampwsid(sampass, &sid);
2133 unbecome_root();
2135 /* check that the SID exists in our domain. */
2136 if (ret == False) {
2137 return NT_STATUS_NO_SUCH_USER;
2140 TALLOC_FREE(sampass);
2142 /* associate the user's SID and access bits with the new handle. */
2143 if ((info = get_samr_info_by_sid(&sid)) == NULL)
2144 return NT_STATUS_NO_MEMORY;
2145 info->acc_granted = acc_granted;
2147 /* get a (unique) handle. open a policy on it. */
2148 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info))
2149 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2151 return NT_STATUS_OK;
2154 /*************************************************************************
2155 get_user_info_7. Safe. Only gives out account_name.
2156 *************************************************************************/
2158 static NTSTATUS get_user_info_7(TALLOC_CTX *mem_ctx,
2159 struct samr_UserInfo7 *r,
2160 DOM_SID *user_sid)
2162 struct samu *smbpass=NULL;
2163 bool ret;
2164 const char *account_name = NULL;
2166 ZERO_STRUCTP(r);
2168 if ( !(smbpass = samu_new( mem_ctx )) ) {
2169 return NT_STATUS_NO_MEMORY;
2172 become_root();
2173 ret = pdb_getsampwsid(smbpass, user_sid);
2174 unbecome_root();
2176 if ( !ret ) {
2177 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
2178 return NT_STATUS_NO_SUCH_USER;
2181 account_name = talloc_strdup(mem_ctx, pdb_get_username(smbpass));
2182 if (!account_name) {
2183 TALLOC_FREE(smbpass);
2184 return NT_STATUS_NO_MEMORY;
2186 TALLOC_FREE(smbpass);
2188 DEBUG(3,("User:[%s]\n", account_name));
2190 init_samr_user_info7(r, account_name);
2192 return NT_STATUS_OK;
2195 /*************************************************************************
2196 get_user_info_9. Only gives out primary group SID.
2197 *************************************************************************/
2199 static NTSTATUS get_user_info_9(TALLOC_CTX *mem_ctx,
2200 struct samr_UserInfo9 *r,
2201 DOM_SID *user_sid)
2203 struct samu *smbpass=NULL;
2204 bool ret;
2206 ZERO_STRUCTP(r);
2208 if ( !(smbpass = samu_new( mem_ctx )) ) {
2209 return NT_STATUS_NO_MEMORY;
2212 become_root();
2213 ret = pdb_getsampwsid(smbpass, user_sid);
2214 unbecome_root();
2216 if (ret==False) {
2217 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
2218 TALLOC_FREE(smbpass);
2219 return NT_STATUS_NO_SUCH_USER;
2222 DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
2224 init_samr_user_info9(r, pdb_get_group_rid(smbpass));
2226 TALLOC_FREE(smbpass);
2228 return NT_STATUS_OK;
2231 /*************************************************************************
2232 get_user_info_16. Safe. Only gives out acb bits.
2233 *************************************************************************/
2235 static NTSTATUS get_user_info_16(TALLOC_CTX *mem_ctx,
2236 struct samr_UserInfo16 *r,
2237 DOM_SID *user_sid)
2239 struct samu *smbpass=NULL;
2240 bool ret;
2242 ZERO_STRUCTP(r);
2244 if ( !(smbpass = samu_new( mem_ctx )) ) {
2245 return NT_STATUS_NO_MEMORY;
2248 become_root();
2249 ret = pdb_getsampwsid(smbpass, user_sid);
2250 unbecome_root();
2252 if (ret==False) {
2253 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
2254 TALLOC_FREE(smbpass);
2255 return NT_STATUS_NO_SUCH_USER;
2258 DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
2260 init_samr_user_info16(r, pdb_get_acct_ctrl(smbpass));
2262 TALLOC_FREE(smbpass);
2264 return NT_STATUS_OK;
2267 /*************************************************************************
2268 get_user_info_18. OK - this is the killer as it gives out password info.
2269 Ensure that this is only allowed on an encrypted connection with a root
2270 user. JRA.
2271 *************************************************************************/
2273 static NTSTATUS get_user_info_18(pipes_struct *p,
2274 TALLOC_CTX *mem_ctx,
2275 struct samr_UserInfo18 *r,
2276 DOM_SID *user_sid)
2278 struct samu *smbpass=NULL;
2279 bool ret;
2281 ZERO_STRUCTP(r);
2283 if (p->auth.auth_type != PIPE_AUTH_TYPE_NTLMSSP || p->auth.auth_type != PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) {
2284 return NT_STATUS_ACCESS_DENIED;
2287 if (p->auth.auth_level != PIPE_AUTH_LEVEL_PRIVACY) {
2288 return NT_STATUS_ACCESS_DENIED;
2292 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
2295 if ( !(smbpass = samu_new( mem_ctx )) ) {
2296 return NT_STATUS_NO_MEMORY;
2299 ret = pdb_getsampwsid(smbpass, user_sid);
2301 if (ret == False) {
2302 DEBUG(4, ("User %s not found\n", sid_string_dbg(user_sid)));
2303 TALLOC_FREE(smbpass);
2304 return (geteuid() == (uid_t)0) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
2307 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
2309 if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
2310 TALLOC_FREE(smbpass);
2311 return NT_STATUS_ACCOUNT_DISABLED;
2314 init_samr_user_info18(r, pdb_get_lanman_passwd(smbpass),
2315 pdb_get_nt_passwd(smbpass));
2317 TALLOC_FREE(smbpass);
2319 return NT_STATUS_OK;
2322 /*************************************************************************
2323 get_user_info_20
2324 *************************************************************************/
2326 static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx,
2327 struct samr_UserInfo20 *r,
2328 DOM_SID *user_sid)
2330 struct samu *sampass=NULL;
2331 bool ret;
2332 const char *munged_dial = NULL;
2333 const char *munged_dial_decoded = NULL;
2334 DATA_BLOB blob;
2336 ZERO_STRUCTP(r);
2338 if ( !(sampass = samu_new( mem_ctx )) ) {
2339 return NT_STATUS_NO_MEMORY;
2342 become_root();
2343 ret = pdb_getsampwsid(sampass, user_sid);
2344 unbecome_root();
2346 if (ret == False) {
2347 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
2348 TALLOC_FREE(sampass);
2349 return NT_STATUS_NO_SUCH_USER;
2352 munged_dial = pdb_get_munged_dial(sampass);
2354 samr_clear_sam_passwd(sampass);
2356 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
2358 if (munged_dial) {
2359 blob = base64_decode_data_blob(munged_dial);
2360 munged_dial_decoded = talloc_strndup(mem_ctx,
2361 (const char *)blob.data,
2362 blob.length);
2363 data_blob_free(&blob);
2364 if (!munged_dial_decoded) {
2365 TALLOC_FREE(sampass);
2366 return NT_STATUS_NO_MEMORY;
2370 #if 0
2371 init_unistr2_from_datablob(&usr->uni_munged_dial, &blob);
2372 init_uni_hdr(&usr->hdr_munged_dial, &usr->uni_munged_dial);
2373 data_blob_free(&blob);
2374 #endif
2375 init_samr_user_info20(r, munged_dial_decoded);
2377 TALLOC_FREE(sampass);
2379 return NT_STATUS_OK;
2383 /*************************************************************************
2384 get_user_info_21
2385 *************************************************************************/
2387 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx,
2388 struct samr_UserInfo21 *r,
2389 DOM_SID *user_sid,
2390 DOM_SID *domain_sid)
2392 struct samu *pw = NULL;
2393 bool ret;
2394 const DOM_SID *sid_user, *sid_group;
2395 uint32_t rid, primary_gid;
2396 NTTIME last_logon, last_logoff, last_password_change,
2397 acct_expiry, allow_password_change, force_password_change;
2398 time_t must_change_time;
2399 uint8_t password_expired;
2400 const char *account_name, *full_name, *home_directory, *home_drive,
2401 *logon_script, *profile_path, *description,
2402 *workstations, *comment, *parameters;
2403 struct samr_LogonHours logon_hours;
2404 const char *munged_dial = NULL;
2405 DATA_BLOB blob;
2407 ZERO_STRUCTP(r);
2409 if (!(pw = samu_new(mem_ctx))) {
2410 return NT_STATUS_NO_MEMORY;
2413 become_root();
2414 ret = pdb_getsampwsid(pw, user_sid);
2415 unbecome_root();
2417 if (ret == False) {
2418 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
2419 TALLOC_FREE(pw);
2420 return NT_STATUS_NO_SUCH_USER;
2423 samr_clear_sam_passwd(pw);
2425 DEBUG(3,("User:[%s]\n", pdb_get_username(pw)));
2427 sid_user = pdb_get_user_sid(pw);
2429 if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2430 DEBUG(0, ("get_user_info_21: User %s has SID %s, \nwhich conflicts with "
2431 "the domain sid %s. Failing operation.\n",
2432 pdb_get_username(pw), sid_string_dbg(sid_user),
2433 sid_string_dbg(domain_sid)));
2434 TALLOC_FREE(pw);
2435 return NT_STATUS_UNSUCCESSFUL;
2438 become_root();
2439 sid_group = pdb_get_group_sid(pw);
2440 unbecome_root();
2442 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2443 DEBUG(0, ("get_user_info_21: User %s has Primary Group SID %s, \n"
2444 "which conflicts with the domain sid %s. Failing operation.\n",
2445 pdb_get_username(pw), sid_string_dbg(sid_group),
2446 sid_string_dbg(domain_sid)));
2447 TALLOC_FREE(pw);
2448 return NT_STATUS_UNSUCCESSFUL;
2451 unix_to_nt_time(&last_logon, pdb_get_logon_time(pw));
2452 unix_to_nt_time(&last_logoff, pdb_get_logoff_time(pw));
2453 unix_to_nt_time(&acct_expiry, pdb_get_kickoff_time(pw));
2454 unix_to_nt_time(&last_password_change, pdb_get_pass_last_set_time(pw));
2455 unix_to_nt_time(&allow_password_change, pdb_get_pass_can_change_time(pw));
2457 must_change_time = pdb_get_pass_must_change_time(pw);
2458 if (must_change_time == get_time_t_max()) {
2459 unix_to_nt_time_abs(&force_password_change, must_change_time);
2460 } else {
2461 unix_to_nt_time(&force_password_change, must_change_time);
2464 if (pdb_get_pass_must_change_time(pw) == 0) {
2465 password_expired = PASS_MUST_CHANGE_AT_NEXT_LOGON;
2466 } else {
2467 password_expired = 0;
2470 munged_dial = pdb_get_munged_dial(pw);
2471 if (munged_dial) {
2472 blob = base64_decode_data_blob(munged_dial);
2473 parameters = talloc_strndup(mem_ctx, (const char *)blob.data, blob.length);
2474 data_blob_free(&blob);
2475 if (!parameters) {
2476 TALLOC_FREE(pw);
2477 return NT_STATUS_NO_MEMORY;
2479 } else {
2480 parameters = NULL;
2484 account_name = talloc_strdup(mem_ctx, pdb_get_username(pw));
2485 full_name = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2486 home_directory = talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2487 home_drive = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2488 logon_script = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2489 profile_path = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2490 description = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2491 workstations = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2492 comment = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2494 logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2495 #if 0
2498 Look at a user on a real NT4 PDC with usrmgr, press
2499 'ok'. Then you will see that fields_present is set to
2500 0x08f827fa. Look at the user immediately after that again,
2501 and you will see that 0x00fffff is returned. This solves
2502 the problem that you get access denied after having looked
2503 at the user.
2504 -- Volker
2507 #if 0
2508 init_unistr2_from_datablob(&usr->uni_munged_dial, &munged_dial_blob);
2509 init_uni_hdr(&usr->hdr_munged_dial, &usr->uni_munged_dial);
2510 data_blob_free(&munged_dial_blob);
2511 #endif
2512 #endif
2514 init_samr_user_info21(r,
2515 last_logon,
2516 last_logoff,
2517 last_password_change,
2518 acct_expiry,
2519 allow_password_change,
2520 force_password_change,
2521 account_name,
2522 full_name,
2523 home_directory,
2524 home_drive,
2525 logon_script,
2526 profile_path,
2527 description,
2528 workstations,
2529 comment,
2530 parameters,
2531 rid,
2532 primary_gid,
2533 pdb_get_acct_ctrl(pw),
2534 pdb_build_fields_present(pw),
2535 logon_hours,
2536 pdb_get_bad_password_count(pw),
2537 pdb_get_logon_count(pw),
2538 0, /* country_code */
2539 0, /* code_page */
2540 0, /* nt_password_set */
2541 0, /* lm_password_set */
2542 password_expired);
2543 TALLOC_FREE(pw);
2545 return NT_STATUS_OK;
2548 /*******************************************************************
2549 _samr_QueryUserInfo
2550 ********************************************************************/
2552 NTSTATUS _samr_QueryUserInfo(pipes_struct *p,
2553 struct samr_QueryUserInfo *r)
2555 NTSTATUS status;
2556 union samr_UserInfo *user_info = NULL;
2557 struct samr_info *info = NULL;
2558 DOM_SID domain_sid;
2559 uint32 rid;
2561 /* search for the handle */
2562 if (!find_policy_by_hnd(p, r->in.user_handle, (void **)(void *)&info))
2563 return NT_STATUS_INVALID_HANDLE;
2565 domain_sid = info->sid;
2567 sid_split_rid(&domain_sid, &rid);
2569 if (!sid_check_is_in_our_domain(&info->sid))
2570 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2572 DEBUG(5,("_samr_QueryUserInfo: sid:%s\n",
2573 sid_string_dbg(&info->sid)));
2575 user_info = TALLOC_ZERO_P(p->mem_ctx, union samr_UserInfo);
2576 if (!user_info) {
2577 return NT_STATUS_NO_MEMORY;
2580 DEBUG(5,("_samr_QueryUserInfo: user info level: %d\n", r->in.level));
2582 switch (r->in.level) {
2583 case 7:
2584 status = get_user_info_7(p->mem_ctx, &user_info->info7, &info->sid);
2585 if (!NT_STATUS_IS_OK(status)) {
2586 return status;
2588 break;
2589 case 9:
2590 status = get_user_info_9(p->mem_ctx, &user_info->info9, &info->sid);
2591 if (!NT_STATUS_IS_OK(status)) {
2592 return status;
2594 break;
2595 case 16:
2596 status = get_user_info_16(p->mem_ctx, &user_info->info16, &info->sid);
2597 if (!NT_STATUS_IS_OK(status)) {
2598 return status;
2600 break;
2602 case 18:
2603 status = get_user_info_18(p, p->mem_ctx, &user_info->info18, &info->sid);
2604 if (!NT_STATUS_IS_OK(status)) {
2605 return status;
2607 break;
2609 case 20:
2610 status = get_user_info_20(p->mem_ctx, &user_info->info20, &info->sid);
2611 if (!NT_STATUS_IS_OK(status)) {
2612 return status;
2614 break;
2616 case 21:
2617 status = get_user_info_21(p->mem_ctx, &user_info->info21,
2618 &info->sid, &domain_sid);
2619 if (!NT_STATUS_IS_OK(status)) {
2620 return status;
2622 break;
2624 default:
2625 return NT_STATUS_INVALID_INFO_CLASS;
2628 *r->out.info = user_info;
2630 DEBUG(5,("_samr_QueryUserInfo: %d\n", __LINE__));
2632 return status;
2635 /*******************************************************************
2636 _samr_GetGroupsForUser
2637 ********************************************************************/
2639 NTSTATUS _samr_GetGroupsForUser(pipes_struct *p,
2640 struct samr_GetGroupsForUser *r)
2642 struct samu *sam_pass=NULL;
2643 DOM_SID sid;
2644 DOM_SID *sids;
2645 struct samr_RidWithAttribute dom_gid;
2646 struct samr_RidWithAttribute *gids = NULL;
2647 uint32 primary_group_rid;
2648 size_t num_groups = 0;
2649 gid_t *unix_gids;
2650 size_t i, num_gids;
2651 uint32 acc_granted;
2652 bool ret;
2653 NTSTATUS result;
2654 bool success = False;
2656 struct samr_RidWithAttributeArray *rids = NULL;
2659 * from the SID in the request:
2660 * we should send back the list of DOMAIN GROUPS
2661 * the user is a member of
2663 * and only the DOMAIN GROUPS
2664 * no ALIASES !!! neither aliases of the domain
2665 * nor aliases of the builtin SID
2667 * JFM, 12/2/2001
2670 DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
2672 rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidWithAttributeArray);
2673 if (!rids) {
2674 return NT_STATUS_NO_MEMORY;
2677 /* find the policy handle. open a policy on it. */
2678 if (!get_lsa_policy_samr_sid(p, r->in.user_handle, &sid, &acc_granted, NULL))
2679 return NT_STATUS_INVALID_HANDLE;
2681 result = access_check_samr_function(acc_granted,
2682 SA_RIGHT_USER_GET_GROUPS,
2683 "_samr_GetGroupsForUser");
2684 if (!NT_STATUS_IS_OK(result)) {
2685 return result;
2688 if (!sid_check_is_in_our_domain(&sid))
2689 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2691 if ( !(sam_pass = samu_new( p->mem_ctx )) ) {
2692 return NT_STATUS_NO_MEMORY;
2695 become_root();
2696 ret = pdb_getsampwsid(sam_pass, &sid);
2697 unbecome_root();
2699 if (!ret) {
2700 DEBUG(10, ("pdb_getsampwsid failed for %s\n",
2701 sid_string_dbg(&sid)));
2702 return NT_STATUS_NO_SUCH_USER;
2705 sids = NULL;
2707 /* make both calls inside the root block */
2708 become_root();
2709 result = pdb_enum_group_memberships(p->mem_ctx, sam_pass,
2710 &sids, &unix_gids, &num_groups);
2711 if ( NT_STATUS_IS_OK(result) ) {
2712 success = sid_peek_check_rid(get_global_sam_sid(),
2713 pdb_get_group_sid(sam_pass),
2714 &primary_group_rid);
2716 unbecome_root();
2718 if (!NT_STATUS_IS_OK(result)) {
2719 DEBUG(10, ("pdb_enum_group_memberships failed for %s\n",
2720 sid_string_dbg(&sid)));
2721 return result;
2724 if ( !success ) {
2725 DEBUG(5, ("Group sid %s for user %s not in our domain\n",
2726 sid_string_dbg(pdb_get_group_sid(sam_pass)),
2727 pdb_get_username(sam_pass)));
2728 TALLOC_FREE(sam_pass);
2729 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2732 gids = NULL;
2733 num_gids = 0;
2735 dom_gid.attributes = (SE_GROUP_MANDATORY|SE_GROUP_ENABLED_BY_DEFAULT|
2736 SE_GROUP_ENABLED);
2737 dom_gid.rid = primary_group_rid;
2738 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
2740 for (i=0; i<num_groups; i++) {
2742 if (!sid_peek_check_rid(get_global_sam_sid(),
2743 &(sids[i]), &dom_gid.rid)) {
2744 DEBUG(10, ("Found sid %s not in our domain\n",
2745 sid_string_dbg(&sids[i])));
2746 continue;
2749 if (dom_gid.rid == primary_group_rid) {
2750 /* We added the primary group directly from the
2751 * sam_account. The other SIDs are unique from
2752 * enum_group_memberships */
2753 continue;
2756 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
2759 rids->count = num_gids;
2760 rids->rids = gids;
2762 *r->out.rids = rids;
2764 DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
2766 return result;
2769 /*******************************************************************
2770 samr_QueryDomainInfo_internal
2771 ********************************************************************/
2773 static NTSTATUS samr_QueryDomainInfo_internal(const char *fn_name,
2774 pipes_struct *p,
2775 struct policy_handle *handle,
2776 uint32_t level,
2777 union samr_DomainInfo **dom_info_ptr)
2779 NTSTATUS status = NT_STATUS_OK;
2780 struct samr_info *info = NULL;
2781 union samr_DomainInfo *dom_info;
2782 uint32 min_pass_len,pass_hist,password_properties;
2783 time_t u_expire, u_min_age;
2784 NTTIME nt_expire, nt_min_age;
2786 time_t u_lock_duration, u_reset_time;
2787 NTTIME nt_lock_duration, nt_reset_time;
2788 uint32 lockout;
2789 time_t u_logout;
2790 NTTIME nt_logout;
2792 uint32 account_policy_temp;
2794 time_t seq_num;
2795 uint32 server_role;
2797 uint32 num_users=0, num_groups=0, num_aliases=0;
2799 DEBUG(5,("%s: %d\n", fn_name, __LINE__));
2801 dom_info = TALLOC_ZERO_P(p->mem_ctx, union samr_DomainInfo);
2802 if (!dom_info) {
2803 return NT_STATUS_NO_MEMORY;
2806 *dom_info_ptr = dom_info;
2808 /* find the policy handle. open a policy on it. */
2809 if (!find_policy_by_hnd(p, handle, (void **)(void *)&info)) {
2810 return NT_STATUS_INVALID_HANDLE;
2813 switch (level) {
2814 case 0x01:
2816 become_root();
2818 /* AS ROOT !!! */
2820 pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &account_policy_temp);
2821 min_pass_len = account_policy_temp;
2823 pdb_get_account_policy(AP_PASSWORD_HISTORY, &account_policy_temp);
2824 pass_hist = account_policy_temp;
2826 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
2827 password_properties = account_policy_temp;
2829 pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
2830 u_expire = account_policy_temp;
2832 pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
2833 u_min_age = account_policy_temp;
2835 /* !AS ROOT */
2837 unbecome_root();
2839 unix_to_nt_time_abs(&nt_expire, u_expire);
2840 unix_to_nt_time_abs(&nt_min_age, u_min_age);
2842 init_samr_DomInfo1(&dom_info->info1,
2843 (uint16)min_pass_len,
2844 (uint16)pass_hist,
2845 password_properties,
2846 nt_expire,
2847 nt_min_age);
2848 break;
2849 case 0x02:
2851 become_root();
2853 /* AS ROOT !!! */
2855 num_users = count_sam_users(info->disp_info, ACB_NORMAL);
2856 num_groups = count_sam_groups(info->disp_info);
2857 num_aliases = count_sam_aliases(info->disp_info);
2859 pdb_get_account_policy(AP_TIME_TO_LOGOUT, &account_policy_temp);
2860 u_logout = account_policy_temp;
2862 unix_to_nt_time_abs(&nt_logout, u_logout);
2864 if (!pdb_get_seq_num(&seq_num))
2865 seq_num = time(NULL);
2867 /* !AS ROOT */
2869 unbecome_root();
2871 server_role = ROLE_DOMAIN_PDC;
2872 if (lp_server_role() == ROLE_DOMAIN_BDC)
2873 server_role = ROLE_DOMAIN_BDC;
2875 init_samr_DomInfo2(&dom_info->info2,
2876 nt_logout,
2877 lp_serverstring(),
2878 lp_workgroup(),
2879 global_myname(),
2880 seq_num,
2882 server_role,
2884 num_users,
2885 num_groups,
2886 num_aliases);
2887 break;
2888 case 0x03:
2890 become_root();
2892 /* AS ROOT !!! */
2895 uint32 ul;
2896 pdb_get_account_policy(AP_TIME_TO_LOGOUT, &ul);
2897 u_logout = (time_t)ul;
2900 /* !AS ROOT */
2902 unbecome_root();
2904 unix_to_nt_time_abs(&nt_logout, u_logout);
2906 init_samr_DomInfo3(&dom_info->info3,
2907 nt_logout);
2909 break;
2910 case 0x04:
2911 init_samr_DomInfo4(&dom_info->info4,
2912 lp_serverstring());
2913 break;
2914 case 0x05:
2915 init_samr_DomInfo5(&dom_info->info5,
2916 get_global_sam_name());
2917 break;
2918 case 0x06:
2919 /* NT returns its own name when a PDC. win2k and later
2920 * only the name of the PDC if itself is a BDC (samba4
2921 * idl) */
2922 init_samr_DomInfo6(&dom_info->info6,
2923 global_myname());
2924 break;
2925 case 0x07:
2926 server_role = ROLE_DOMAIN_PDC;
2927 if (lp_server_role() == ROLE_DOMAIN_BDC)
2928 server_role = ROLE_DOMAIN_BDC;
2930 init_samr_DomInfo7(&dom_info->info7,
2931 server_role);
2932 break;
2933 case 0x08:
2935 become_root();
2937 /* AS ROOT !!! */
2939 if (!pdb_get_seq_num(&seq_num)) {
2940 seq_num = time(NULL);
2943 /* !AS ROOT */
2945 unbecome_root();
2947 init_samr_DomInfo8(&dom_info->info8,
2948 seq_num,
2950 break;
2951 case 0x0c:
2953 become_root();
2955 /* AS ROOT !!! */
2957 pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
2958 u_lock_duration = account_policy_temp;
2959 if (u_lock_duration != -1) {
2960 u_lock_duration *= 60;
2963 pdb_get_account_policy(AP_RESET_COUNT_TIME, &account_policy_temp);
2964 u_reset_time = account_policy_temp * 60;
2966 pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
2967 lockout = account_policy_temp;
2969 /* !AS ROOT */
2971 unbecome_root();
2973 unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
2974 unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
2976 init_samr_DomInfo12(&dom_info->info12,
2977 nt_lock_duration,
2978 nt_reset_time,
2979 (uint16)lockout);
2980 break;
2981 default:
2982 return NT_STATUS_INVALID_INFO_CLASS;
2985 DEBUG(5,("%s: %d\n", fn_name, __LINE__));
2987 return status;
2990 /*******************************************************************
2991 _samr_QueryDomainInfo
2992 ********************************************************************/
2994 NTSTATUS _samr_QueryDomainInfo(pipes_struct *p,
2995 struct samr_QueryDomainInfo *r)
2997 return samr_QueryDomainInfo_internal("_samr_QueryDomainInfo",
2999 r->in.domain_handle,
3000 r->in.level,
3001 r->out.info);
3004 /* W2k3 seems to use the same check for all 3 objects that can be created via
3005 * SAMR, if you try to create for example "Dialup" as an alias it says
3006 * "NT_STATUS_USER_EXISTS". This is racy, but we can't really lock the user
3007 * database. */
3009 static NTSTATUS can_create(TALLOC_CTX *mem_ctx, const char *new_name)
3011 enum lsa_SidType type;
3012 bool result;
3014 DEBUG(10, ("Checking whether [%s] can be created\n", new_name));
3016 become_root();
3017 /* Lookup in our local databases (LOOKUP_NAME_REMOTE not set)
3018 * whether the name already exists */
3019 result = lookup_name(mem_ctx, new_name, LOOKUP_NAME_LOCAL,
3020 NULL, NULL, NULL, &type);
3021 unbecome_root();
3023 if (!result) {
3024 DEBUG(10, ("%s does not exist, can create it\n", new_name));
3025 return NT_STATUS_OK;
3028 DEBUG(5, ("trying to create %s, exists as %s\n",
3029 new_name, sid_type_lookup(type)));
3031 if (type == SID_NAME_DOM_GRP) {
3032 return NT_STATUS_GROUP_EXISTS;
3034 if (type == SID_NAME_ALIAS) {
3035 return NT_STATUS_ALIAS_EXISTS;
3038 /* Yes, the default is NT_STATUS_USER_EXISTS */
3039 return NT_STATUS_USER_EXISTS;
3042 /*******************************************************************
3043 _samr_CreateUser2
3044 ********************************************************************/
3046 NTSTATUS _samr_CreateUser2(pipes_struct *p,
3047 struct samr_CreateUser2 *r)
3049 const char *account = NULL;
3050 DOM_SID sid;
3051 POLICY_HND dom_pol = *r->in.domain_handle;
3052 uint32_t acb_info = r->in.acct_flags;
3053 POLICY_HND *user_pol = r->out.user_handle;
3054 struct samr_info *info = NULL;
3055 NTSTATUS nt_status;
3056 uint32 acc_granted;
3057 SEC_DESC *psd;
3058 size_t sd_size;
3059 /* check this, when giving away 'add computer to domain' privs */
3060 uint32 des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
3061 bool can_add_account = False;
3062 SE_PRIV se_rights;
3063 DISP_INFO *disp_info = NULL;
3065 /* Get the domain SID stored in the domain policy */
3066 if (!get_lsa_policy_samr_sid(p, &dom_pol, &sid, &acc_granted,
3067 &disp_info))
3068 return NT_STATUS_INVALID_HANDLE;
3070 nt_status = access_check_samr_function(acc_granted,
3071 SA_RIGHT_DOMAIN_CREATE_USER,
3072 "_samr_CreateUser2");
3073 if (!NT_STATUS_IS_OK(nt_status)) {
3074 return nt_status;
3077 if (!(acb_info == ACB_NORMAL || acb_info == ACB_DOMTRUST ||
3078 acb_info == ACB_WSTRUST || acb_info == ACB_SVRTRUST)) {
3079 /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if
3080 this parameter is not an account type */
3081 return NT_STATUS_INVALID_PARAMETER;
3084 account = r->in.account_name->string;
3085 if (account == NULL) {
3086 return NT_STATUS_NO_MEMORY;
3089 nt_status = can_create(p->mem_ctx, account);
3090 if (!NT_STATUS_IS_OK(nt_status)) {
3091 return nt_status;
3094 /* determine which user right we need to check based on the acb_info */
3096 if ( acb_info & ACB_WSTRUST )
3098 se_priv_copy( &se_rights, &se_machine_account );
3099 can_add_account = user_has_privileges(
3100 p->pipe_user.nt_user_token, &se_rights );
3102 /* usrmgr.exe (and net rpc trustdom grant) creates a normal user
3103 account for domain trusts and changes the ACB flags later */
3104 else if ( acb_info & ACB_NORMAL &&
3105 (account[strlen(account)-1] != '$') )
3107 se_priv_copy( &se_rights, &se_add_users );
3108 can_add_account = user_has_privileges(
3109 p->pipe_user.nt_user_token, &se_rights );
3111 else /* implicit assumption of a BDC or domain trust account here
3112 * (we already check the flags earlier) */
3114 if ( lp_enable_privileges() ) {
3115 /* only Domain Admins can add a BDC or domain trust */
3116 se_priv_copy( &se_rights, &se_priv_none );
3117 can_add_account = nt_token_check_domain_rid(
3118 p->pipe_user.nt_user_token,
3119 DOMAIN_GROUP_RID_ADMINS );
3123 DEBUG(5, ("_samr_CreateUser2: %s can add this account : %s\n",
3124 uidtoname(p->pipe_user.ut.uid),
3125 can_add_account ? "True":"False" ));
3127 /********** BEGIN Admin BLOCK **********/
3129 if ( can_add_account )
3130 become_root();
3132 nt_status = pdb_create_user(p->mem_ctx, account, acb_info,
3133 r->out.rid);
3135 if ( can_add_account )
3136 unbecome_root();
3138 /********** END Admin BLOCK **********/
3140 /* now check for failure */
3142 if ( !NT_STATUS_IS_OK(nt_status) )
3143 return nt_status;
3145 /* Get the user's SID */
3147 sid_compose(&sid, get_global_sam_sid(), *r->out.rid);
3149 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping,
3150 &sid, SAMR_USR_RIGHTS_WRITE_PW);
3151 se_map_generic(&des_access, &usr_generic_mapping);
3153 nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3154 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
3155 &acc_granted, "_samr_CreateUser2");
3157 if ( !NT_STATUS_IS_OK(nt_status) ) {
3158 return nt_status;
3161 /* associate the user's SID with the new handle. */
3162 if ((info = get_samr_info_by_sid(&sid)) == NULL) {
3163 return NT_STATUS_NO_MEMORY;
3166 ZERO_STRUCTP(info);
3167 info->sid = sid;
3168 info->acc_granted = acc_granted;
3170 /* get a (unique) handle. open a policy on it. */
3171 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info)) {
3172 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3175 /* After a "set" ensure we have no cached display info. */
3176 force_flush_samr_cache(info->disp_info);
3178 *r->out.access_granted = acc_granted;
3180 return NT_STATUS_OK;
3183 /*******************************************************************
3184 _samr_Connect
3185 ********************************************************************/
3187 NTSTATUS _samr_Connect(pipes_struct *p,
3188 struct samr_Connect *r)
3190 struct samr_info *info = NULL;
3191 uint32 des_access = r->in.access_mask;
3193 /* Access check */
3195 if (!pipe_access_check(p)) {
3196 DEBUG(3, ("access denied to _samr_Connect\n"));
3197 return NT_STATUS_ACCESS_DENIED;
3200 /* set up the SAMR connect_anon response */
3202 /* associate the user's SID with the new handle. */
3203 if ((info = get_samr_info_by_sid(NULL)) == NULL)
3204 return NT_STATUS_NO_MEMORY;
3206 /* don't give away the farm but this is probably ok. The SA_RIGHT_SAM_ENUM_DOMAINS
3207 was observed from a win98 client trying to enumerate users (when configured
3208 user level access control on shares) --jerry */
3210 if (des_access == MAXIMUM_ALLOWED_ACCESS) {
3211 /* Map to max possible knowing we're filtered below. */
3212 des_access = GENERIC_ALL_ACCESS;
3215 se_map_generic( &des_access, &sam_generic_mapping );
3216 info->acc_granted = des_access & (SA_RIGHT_SAM_ENUM_DOMAINS|SA_RIGHT_SAM_OPEN_DOMAIN);
3218 /* get a (unique) handle. open a policy on it. */
3219 if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info))
3220 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3222 return NT_STATUS_OK;
3225 /*******************************************************************
3226 _samr_Connect2
3227 ********************************************************************/
3229 NTSTATUS _samr_Connect2(pipes_struct *p,
3230 struct samr_Connect2 *r)
3232 struct samr_info *info = NULL;
3233 SEC_DESC *psd = NULL;
3234 uint32 acc_granted;
3235 uint32 des_access = r->in.access_mask;
3236 NTSTATUS nt_status;
3237 size_t sd_size;
3240 DEBUG(5,("_samr_Connect2: %d\n", __LINE__));
3242 /* Access check */
3244 if (!pipe_access_check(p)) {
3245 DEBUG(3, ("access denied to _samr_Connect2\n"));
3246 return NT_STATUS_ACCESS_DENIED;
3249 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
3250 se_map_generic(&des_access, &sam_generic_mapping);
3252 nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3253 NULL, 0, des_access, &acc_granted, "_samr_Connect2");
3255 if ( !NT_STATUS_IS_OK(nt_status) )
3256 return nt_status;
3258 /* associate the user's SID and access granted with the new handle. */
3259 if ((info = get_samr_info_by_sid(NULL)) == NULL)
3260 return NT_STATUS_NO_MEMORY;
3262 info->acc_granted = acc_granted;
3263 info->status = r->in.access_mask; /* this looks so wrong... - gd */
3265 /* get a (unique) handle. open a policy on it. */
3266 if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info))
3267 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3269 DEBUG(5,("_samr_Connect2: %d\n", __LINE__));
3271 return nt_status;
3274 /*******************************************************************
3275 _samr_Connect4
3276 ********************************************************************/
3278 NTSTATUS _samr_Connect4(pipes_struct *p,
3279 struct samr_Connect4 *r)
3281 struct samr_info *info = NULL;
3282 SEC_DESC *psd = NULL;
3283 uint32 acc_granted;
3284 uint32 des_access = r->in.access_mask;
3285 NTSTATUS nt_status;
3286 size_t sd_size;
3289 DEBUG(5,("_samr_Connect4: %d\n", __LINE__));
3291 /* Access check */
3293 if (!pipe_access_check(p)) {
3294 DEBUG(3, ("access denied to samr_Connect4\n"));
3295 return NT_STATUS_ACCESS_DENIED;
3298 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
3299 se_map_generic(&des_access, &sam_generic_mapping);
3301 nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3302 NULL, 0, des_access, &acc_granted, "_samr_Connect4");
3304 if ( !NT_STATUS_IS_OK(nt_status) )
3305 return nt_status;
3307 /* associate the user's SID and access granted with the new handle. */
3308 if ((info = get_samr_info_by_sid(NULL)) == NULL)
3309 return NT_STATUS_NO_MEMORY;
3311 info->acc_granted = acc_granted;
3312 info->status = r->in.access_mask; /* ??? */
3314 /* get a (unique) handle. open a policy on it. */
3315 if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info))
3316 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3318 DEBUG(5,("_samr_Connect4: %d\n", __LINE__));
3320 return NT_STATUS_OK;
3323 /*******************************************************************
3324 _samr_Connect5
3325 ********************************************************************/
3327 NTSTATUS _samr_Connect5(pipes_struct *p,
3328 struct samr_Connect5 *r)
3330 struct samr_info *info = NULL;
3331 SEC_DESC *psd = NULL;
3332 uint32 acc_granted;
3333 uint32 des_access = r->in.access_mask;
3334 NTSTATUS nt_status;
3335 size_t sd_size;
3336 struct samr_ConnectInfo1 info1;
3338 DEBUG(5,("_samr_Connect5: %d\n", __LINE__));
3340 /* Access check */
3342 if (!pipe_access_check(p)) {
3343 DEBUG(3, ("access denied to samr_Connect5\n"));
3344 return NT_STATUS_ACCESS_DENIED;
3347 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
3348 se_map_generic(&des_access, &sam_generic_mapping);
3350 nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3351 NULL, 0, des_access, &acc_granted, "_samr_Connect5");
3353 if ( !NT_STATUS_IS_OK(nt_status) )
3354 return nt_status;
3356 /* associate the user's SID and access granted with the new handle. */
3357 if ((info = get_samr_info_by_sid(NULL)) == NULL)
3358 return NT_STATUS_NO_MEMORY;
3360 info->acc_granted = acc_granted;
3361 info->status = r->in.access_mask; /* ??? */
3363 /* get a (unique) handle. open a policy on it. */
3364 if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info))
3365 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3367 DEBUG(5,("_samr_Connect5: %d\n", __LINE__));
3369 info1.client_version = SAMR_CONNECT_AFTER_W2K;
3370 info1.unknown2 = 0;
3372 *r->out.level_out = 1;
3373 r->out.info_out->info1 = info1;
3375 return NT_STATUS_OK;
3378 /**********************************************************************
3379 _samr_LookupDomain
3380 **********************************************************************/
3382 NTSTATUS _samr_LookupDomain(pipes_struct *p,
3383 struct samr_LookupDomain *r)
3385 NTSTATUS status = NT_STATUS_OK;
3386 struct samr_info *info;
3387 const char *domain_name;
3388 DOM_SID *sid = NULL;
3390 if (!find_policy_by_hnd(p, r->in.connect_handle, (void**)(void *)&info))
3391 return NT_STATUS_INVALID_HANDLE;
3393 /* win9x user manager likes to use SA_RIGHT_SAM_ENUM_DOMAINS here.
3394 Reverted that change so we will work with RAS servers again */
3396 status = access_check_samr_function(info->acc_granted,
3397 SA_RIGHT_SAM_OPEN_DOMAIN,
3398 "_samr_LookupDomain");
3399 if (!NT_STATUS_IS_OK(status)) {
3400 return status;
3403 domain_name = r->in.domain_name->string;
3405 sid = TALLOC_ZERO_P(p->mem_ctx, struct dom_sid2);
3406 if (!sid) {
3407 return NT_STATUS_NO_MEMORY;
3410 if (strequal(domain_name, builtin_domain_name())) {
3411 sid_copy(sid, &global_sid_Builtin);
3412 } else {
3413 if (!secrets_fetch_domain_sid(domain_name, sid)) {
3414 status = NT_STATUS_NO_SUCH_DOMAIN;
3418 DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name,
3419 sid_string_dbg(sid)));
3421 *r->out.sid = sid;
3423 return status;
3426 /**********************************************************************
3427 _samr_EnumDomains
3428 **********************************************************************/
3430 NTSTATUS _samr_EnumDomains(pipes_struct *p,
3431 struct samr_EnumDomains *r)
3433 NTSTATUS status;
3434 struct samr_info *info;
3435 uint32_t num_entries = 2;
3436 struct samr_SamEntry *entry_array = NULL;
3437 struct samr_SamArray *sam;
3439 if (!find_policy_by_hnd(p, r->in.connect_handle, (void**)(void *)&info))
3440 return NT_STATUS_INVALID_HANDLE;
3442 status = access_check_samr_function(info->acc_granted,
3443 SA_RIGHT_SAM_ENUM_DOMAINS,
3444 "_samr_EnumDomains");
3445 if (!NT_STATUS_IS_OK(status)) {
3446 return status;
3449 sam = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
3450 if (!sam) {
3451 return NT_STATUS_NO_MEMORY;
3454 entry_array = TALLOC_ZERO_ARRAY(p->mem_ctx,
3455 struct samr_SamEntry,
3456 num_entries);
3457 if (!entry_array) {
3458 return NT_STATUS_NO_MEMORY;
3461 entry_array[0].idx = 0;
3462 init_lsa_String(&entry_array[0].name, get_global_sam_name());
3464 entry_array[1].idx = 1;
3465 init_lsa_String(&entry_array[1].name, "Builtin");
3467 sam->count = num_entries;
3468 sam->entries = entry_array;
3470 *r->out.sam = sam;
3471 *r->out.num_entries = num_entries;
3473 return status;
3476 /*******************************************************************
3477 _samr_OpenAlias
3478 ********************************************************************/
3480 NTSTATUS _samr_OpenAlias(pipes_struct *p,
3481 struct samr_OpenAlias *r)
3483 DOM_SID sid;
3484 POLICY_HND domain_pol = *r->in.domain_handle;
3485 uint32 alias_rid = r->in.rid;
3486 POLICY_HND *alias_pol = r->out.alias_handle;
3487 struct samr_info *info = NULL;
3488 SEC_DESC *psd = NULL;
3489 uint32 acc_granted;
3490 uint32 des_access = r->in.access_mask;
3491 size_t sd_size;
3492 NTSTATUS status;
3493 SE_PRIV se_rights;
3495 /* find the domain policy and get the SID / access bits stored in the domain policy */
3497 if ( !get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted, NULL) )
3498 return NT_STATUS_INVALID_HANDLE;
3500 status = access_check_samr_function(acc_granted,
3501 SA_RIGHT_DOMAIN_OPEN_ACCOUNT,
3502 "_samr_OpenAlias");
3504 if ( !NT_STATUS_IS_OK(status) )
3505 return status;
3507 /* append the alias' RID to it */
3509 if (!sid_append_rid(&sid, alias_rid))
3510 return NT_STATUS_NO_SUCH_ALIAS;
3512 /*check if access can be granted as requested by client. */
3514 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &ali_generic_mapping, NULL, 0);
3515 se_map_generic(&des_access,&ali_generic_mapping);
3517 se_priv_copy( &se_rights, &se_add_users );
3520 status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3521 &se_rights, GENERIC_RIGHTS_ALIAS_WRITE, des_access,
3522 &acc_granted, "_samr_OpenAlias");
3524 if ( !NT_STATUS_IS_OK(status) )
3525 return status;
3528 /* Check we actually have the requested alias */
3529 enum lsa_SidType type;
3530 bool result;
3531 gid_t gid;
3533 become_root();
3534 result = lookup_sid(NULL, &sid, NULL, NULL, &type);
3535 unbecome_root();
3537 if (!result || (type != SID_NAME_ALIAS)) {
3538 return NT_STATUS_NO_SUCH_ALIAS;
3541 /* make sure there is a mapping */
3543 if ( !sid_to_gid( &sid, &gid ) ) {
3544 return NT_STATUS_NO_SUCH_ALIAS;
3549 /* associate the alias SID with the new handle. */
3550 if ((info = get_samr_info_by_sid(&sid)) == NULL)
3551 return NT_STATUS_NO_MEMORY;
3553 info->acc_granted = acc_granted;
3555 /* get a (unique) handle. open a policy on it. */
3556 if (!create_policy_hnd(p, alias_pol, free_samr_info, (void *)info))
3557 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3559 return NT_STATUS_OK;
3562 /*******************************************************************
3563 set_user_info_7
3564 ********************************************************************/
3566 static NTSTATUS set_user_info_7(TALLOC_CTX *mem_ctx,
3567 struct samr_UserInfo7 *id7,
3568 struct samu *pwd)
3570 NTSTATUS rc;
3572 if (id7 == NULL) {
3573 DEBUG(5, ("set_user_info_7: NULL id7\n"));
3574 TALLOC_FREE(pwd);
3575 return NT_STATUS_ACCESS_DENIED;
3578 if (!id7->account_name.string) {
3579 DEBUG(5, ("set_user_info_7: failed to get new username\n"));
3580 TALLOC_FREE(pwd);
3581 return NT_STATUS_ACCESS_DENIED;
3584 /* check to see if the new username already exists. Note: we can't
3585 reliably lock all backends, so there is potentially the
3586 possibility that a user can be created in between this check and
3587 the rename. The rename should fail, but may not get the
3588 exact same failure status code. I think this is small enough
3589 of a window for this type of operation and the results are
3590 simply that the rename fails with a slightly different status
3591 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
3593 rc = can_create(mem_ctx, id7->account_name.string);
3594 if (!NT_STATUS_IS_OK(rc)) {
3595 return rc;
3598 rc = pdb_rename_sam_account(pwd, id7->account_name.string);
3600 TALLOC_FREE(pwd);
3601 return rc;
3604 /*******************************************************************
3605 set_user_info_16
3606 ********************************************************************/
3608 static bool set_user_info_16(struct samr_UserInfo16 *id16,
3609 struct samu *pwd)
3611 if (id16 == NULL) {
3612 DEBUG(5, ("set_user_info_16: NULL id16\n"));
3613 TALLOC_FREE(pwd);
3614 return False;
3617 /* FIX ME: check if the value is really changed --metze */
3618 if (!pdb_set_acct_ctrl(pwd, id16->acct_flags, PDB_CHANGED)) {
3619 TALLOC_FREE(pwd);
3620 return False;
3623 if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3624 TALLOC_FREE(pwd);
3625 return False;
3628 TALLOC_FREE(pwd);
3630 return True;
3633 /*******************************************************************
3634 set_user_info_18
3635 ********************************************************************/
3637 static bool set_user_info_18(struct samr_UserInfo18 *id18,
3638 struct samu *pwd)
3640 if (id18 == NULL) {
3641 DEBUG(2, ("set_user_info_18: id18 is NULL\n"));
3642 TALLOC_FREE(pwd);
3643 return False;
3646 if (!pdb_set_lanman_passwd (pwd, id18->lm_pwd.hash, PDB_CHANGED)) {
3647 TALLOC_FREE(pwd);
3648 return False;
3650 if (!pdb_set_nt_passwd (pwd, id18->nt_pwd.hash, PDB_CHANGED)) {
3651 TALLOC_FREE(pwd);
3652 return False;
3654 if (!pdb_set_pass_last_set_time (pwd, time(NULL), PDB_CHANGED)) {
3655 TALLOC_FREE(pwd);
3656 return False;
3659 if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3660 TALLOC_FREE(pwd);
3661 return False;
3664 TALLOC_FREE(pwd);
3665 return True;
3668 /*******************************************************************
3669 set_user_info_20
3670 ********************************************************************/
3672 static bool set_user_info_20(struct samr_UserInfo20 *id20,
3673 struct samu *pwd)
3675 if (id20 == NULL) {
3676 DEBUG(5, ("set_user_info_20: NULL id20\n"));
3677 return False;
3680 copy_id20_to_sam_passwd(pwd, id20);
3682 /* write the change out */
3683 if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3684 TALLOC_FREE(pwd);
3685 return False;
3688 TALLOC_FREE(pwd);
3690 return True;
3693 /*******************************************************************
3694 set_user_info_21
3695 ********************************************************************/
3697 static NTSTATUS set_user_info_21(TALLOC_CTX *mem_ctx,
3698 struct samr_UserInfo21 *id21,
3699 struct samu *pwd)
3701 NTSTATUS status;
3703 if (id21 == NULL) {
3704 DEBUG(5, ("set_user_info_21: NULL id21\n"));
3705 return NT_STATUS_INVALID_PARAMETER;
3708 /* we need to separately check for an account rename first */
3710 if (id21->account_name.string &&
3711 (!strequal(id21->account_name.string, pdb_get_username(pwd))))
3714 /* check to see if the new username already exists. Note: we can't
3715 reliably lock all backends, so there is potentially the
3716 possibility that a user can be created in between this check and
3717 the rename. The rename should fail, but may not get the
3718 exact same failure status code. I think this is small enough
3719 of a window for this type of operation and the results are
3720 simply that the rename fails with a slightly different status
3721 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
3723 status = can_create(mem_ctx, id21->account_name.string);
3724 if (!NT_STATUS_IS_OK(status)) {
3725 return status;
3728 status = pdb_rename_sam_account(pwd, id21->account_name.string);
3730 if (!NT_STATUS_IS_OK(status)) {
3731 DEBUG(0,("set_user_info_21: failed to rename account: %s\n",
3732 nt_errstr(status)));
3733 TALLOC_FREE(pwd);
3734 return status;
3737 /* set the new username so that later
3738 functions can work on the new account */
3739 pdb_set_username(pwd, id21->account_name.string, PDB_SET);
3742 copy_id21_to_sam_passwd("INFO_21", pwd, id21);
3745 * The funny part about the previous two calls is
3746 * that pwd still has the password hashes from the
3747 * passdb entry. These have not been updated from
3748 * id21. I don't know if they need to be set. --jerry
3751 if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
3752 status = pdb_set_unix_primary_group(mem_ctx, pwd);
3753 if ( !NT_STATUS_IS_OK(status) ) {
3754 return status;
3758 /* Don't worry about writing out the user account since the
3759 primary group SID is generated solely from the user's Unix
3760 primary group. */
3762 /* write the change out */
3763 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
3764 TALLOC_FREE(pwd);
3765 return status;
3768 TALLOC_FREE(pwd);
3770 return NT_STATUS_OK;
3773 /*******************************************************************
3774 set_user_info_23
3775 ********************************************************************/
3777 static NTSTATUS set_user_info_23(TALLOC_CTX *mem_ctx,
3778 struct samr_UserInfo23 *id23,
3779 struct samu *pwd)
3781 char *plaintext_buf = NULL;
3782 uint32 len = 0;
3783 uint16 acct_ctrl;
3784 NTSTATUS status;
3786 if (id23 == NULL) {
3787 DEBUG(5, ("set_user_info_23: NULL id23\n"));
3788 return NT_STATUS_INVALID_PARAMETER;
3791 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
3792 pdb_get_username(pwd)));
3794 acct_ctrl = pdb_get_acct_ctrl(pwd);
3796 if (!decode_pw_buffer(mem_ctx,
3797 id23->password.data,
3798 &plaintext_buf,
3799 &len,
3800 STR_UNICODE)) {
3801 TALLOC_FREE(pwd);
3802 return NT_STATUS_INVALID_PARAMETER;
3805 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
3806 TALLOC_FREE(pwd);
3807 return NT_STATUS_ACCESS_DENIED;
3810 copy_id23_to_sam_passwd(pwd, id23);
3812 /* if it's a trust account, don't update /etc/passwd */
3813 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
3814 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
3815 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
3816 DEBUG(5, ("Changing trust account. Not updating /etc/passwd\n"));
3817 } else {
3818 /* update the UNIX password */
3819 if (lp_unix_password_sync() ) {
3820 struct passwd *passwd;
3821 if (pdb_get_username(pwd) == NULL) {
3822 DEBUG(1, ("chgpasswd: User without name???\n"));
3823 TALLOC_FREE(pwd);
3824 return NT_STATUS_ACCESS_DENIED;
3827 passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
3828 if (passwd == NULL) {
3829 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
3832 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
3833 TALLOC_FREE(pwd);
3834 return NT_STATUS_ACCESS_DENIED;
3836 TALLOC_FREE(passwd);
3840 memset(plaintext_buf, '\0', strlen(plaintext_buf));
3842 if (IS_SAM_CHANGED(pwd, PDB_GROUPSID) &&
3843 (!NT_STATUS_IS_OK(status = pdb_set_unix_primary_group(mem_ctx,
3844 pwd)))) {
3845 TALLOC_FREE(pwd);
3846 return status;
3849 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
3850 TALLOC_FREE(pwd);
3851 return status;
3854 TALLOC_FREE(pwd);
3856 return NT_STATUS_OK;
3859 /*******************************************************************
3860 set_user_info_pw
3861 ********************************************************************/
3863 static bool set_user_info_pw(uint8 *pass, struct samu *pwd)
3865 uint32 len = 0;
3866 char *plaintext_buf = NULL;
3867 uint32 acct_ctrl;
3868 time_t last_set_time;
3869 enum pdb_value_state last_set_state;
3871 DEBUG(5, ("Attempting administrator password change for user %s\n",
3872 pdb_get_username(pwd)));
3874 acct_ctrl = pdb_get_acct_ctrl(pwd);
3875 /* we need to know if it's expired, because this is an admin change, not a
3876 user change, so it's still expired when we're done */
3877 last_set_state = pdb_get_init_flags(pwd, PDB_PASSLASTSET);
3878 last_set_time = pdb_get_pass_last_set_time(pwd);
3880 if (!decode_pw_buffer(talloc_tos(),
3881 pass,
3882 &plaintext_buf,
3883 &len,
3884 STR_UNICODE)) {
3885 TALLOC_FREE(pwd);
3886 return False;
3889 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
3890 TALLOC_FREE(pwd);
3891 return False;
3894 /* if it's a trust account, don't update /etc/passwd */
3895 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
3896 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
3897 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
3898 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
3899 } else {
3900 /* update the UNIX password */
3901 if (lp_unix_password_sync()) {
3902 struct passwd *passwd;
3904 if (pdb_get_username(pwd) == NULL) {
3905 DEBUG(1, ("chgpasswd: User without name???\n"));
3906 TALLOC_FREE(pwd);
3907 return False;
3910 passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
3911 if (passwd == NULL) {
3912 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
3915 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
3916 TALLOC_FREE(pwd);
3917 return False;
3919 TALLOC_FREE(passwd);
3923 memset(plaintext_buf, '\0', strlen(plaintext_buf));
3925 /* restore last set time as this is an admin change, not a user pw change */
3926 pdb_set_pass_last_set_time (pwd, last_set_time, last_set_state);
3928 DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
3930 /* update the SAMBA password */
3931 if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3932 TALLOC_FREE(pwd);
3933 return False;
3936 TALLOC_FREE(pwd);
3938 return True;
3941 /*******************************************************************
3942 set_user_info_25
3943 ********************************************************************/
3945 static NTSTATUS set_user_info_25(TALLOC_CTX *mem_ctx,
3946 struct samr_UserInfo25 *id25,
3947 struct samu *pwd)
3949 NTSTATUS status;
3951 if (id25 == NULL) {
3952 DEBUG(5, ("set_user_info_25: NULL id25\n"));
3953 return NT_STATUS_INVALID_PARAMETER;
3956 copy_id25_to_sam_passwd(pwd, id25);
3958 /* write the change out */
3959 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
3960 TALLOC_FREE(pwd);
3961 return status;
3965 * We need to "pdb_update_sam_account" before the unix primary group
3966 * is set, because the idealx scripts would also change the
3967 * sambaPrimaryGroupSid using the ldap replace method. pdb_ldap uses
3968 * the delete explicit / add explicit, which would then fail to find
3969 * the previous primaryGroupSid value.
3972 if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
3973 status = pdb_set_unix_primary_group(mem_ctx, pwd);
3974 if ( !NT_STATUS_IS_OK(status) ) {
3975 return status;
3979 /* WARNING: No TALLOC_FREE(pwd), we are about to set the password
3980 * hereafter! */
3982 return NT_STATUS_OK;
3985 /*******************************************************************
3986 samr_SetUserInfo_internal
3987 ********************************************************************/
3989 static NTSTATUS samr_SetUserInfo_internal(const char *fn_name,
3990 pipes_struct *p,
3991 struct policy_handle *user_handle,
3992 uint16_t level,
3993 union samr_UserInfo *info)
3995 NTSTATUS status;
3996 struct samu *pwd = NULL;
3997 DOM_SID sid;
3998 POLICY_HND *pol = user_handle;
3999 uint16_t switch_value = level;
4000 uint32_t acc_granted;
4001 uint32_t acc_required;
4002 bool ret;
4003 bool has_enough_rights = False;
4004 uint32_t acb_info;
4005 DISP_INFO *disp_info = NULL;
4007 DEBUG(5,("%s: %d\n", fn_name, __LINE__));
4009 /* find the policy handle. open a policy on it. */
4010 if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted, &disp_info)) {
4011 return NT_STATUS_INVALID_HANDLE;
4014 /* This is tricky. A WinXP domain join sets
4015 (SA_RIGHT_USER_SET_PASSWORD|SA_RIGHT_USER_SET_ATTRIBUTES|SA_RIGHT_USER_ACCT_FLAGS_EXPIRY)
4016 The MMC lusrmgr plugin includes these perms and more in the SamrOpenUser(). But the
4017 standard Win32 API calls just ask for SA_RIGHT_USER_SET_PASSWORD in the SamrOpenUser().
4018 This should be enough for levels 18, 24, 25,& 26. Info level 23 can set more so
4019 we'll use the set from the WinXP join as the basis. */
4021 switch (switch_value) {
4022 case 18:
4023 case 24:
4024 case 25:
4025 case 26:
4026 acc_required = SA_RIGHT_USER_SET_PASSWORD;
4027 break;
4028 default:
4029 acc_required = SA_RIGHT_USER_SET_PASSWORD |
4030 SA_RIGHT_USER_SET_ATTRIBUTES |
4031 SA_RIGHT_USER_ACCT_FLAGS_EXPIRY;
4032 break;
4035 status = access_check_samr_function(acc_granted,
4036 acc_required,
4037 fn_name);
4038 if (!NT_STATUS_IS_OK(status)) {
4039 return status;
4042 DEBUG(5, ("%s: sid:%s, level:%d\n",
4043 fn_name, sid_string_dbg(&sid), switch_value));
4045 if (info == NULL) {
4046 DEBUG(5, ("%s: NULL info level\n", fn_name));
4047 return NT_STATUS_INVALID_INFO_CLASS;
4050 if (!(pwd = samu_new(NULL))) {
4051 return NT_STATUS_NO_MEMORY;
4054 become_root();
4055 ret = pdb_getsampwsid(pwd, &sid);
4056 unbecome_root();
4058 if (!ret) {
4059 TALLOC_FREE(pwd);
4060 return NT_STATUS_NO_SUCH_USER;
4063 /* deal with machine password changes differently from userinfo changes */
4064 /* check to see if we have the sufficient rights */
4066 acb_info = pdb_get_acct_ctrl(pwd);
4067 if (acb_info & ACB_WSTRUST)
4068 has_enough_rights = user_has_privileges(p->pipe_user.nt_user_token,
4069 &se_machine_account);
4070 else if (acb_info & ACB_NORMAL)
4071 has_enough_rights = user_has_privileges(p->pipe_user.nt_user_token,
4072 &se_add_users);
4073 else if (acb_info & (ACB_SVRTRUST|ACB_DOMTRUST)) {
4074 if (lp_enable_privileges()) {
4075 has_enough_rights = nt_token_check_domain_rid(p->pipe_user.nt_user_token,
4076 DOMAIN_GROUP_RID_ADMINS);
4080 DEBUG(5, ("%s: %s does%s possess sufficient rights\n",
4081 fn_name,
4082 uidtoname(p->pipe_user.ut.uid),
4083 has_enough_rights ? "" : " not"));
4085 /* ================ BEGIN SeMachineAccountPrivilege BLOCK ================ */
4087 if (has_enough_rights) {
4088 become_root();
4091 /* ok! user info levels (lots: see MSDEV help), off we go... */
4093 switch (switch_value) {
4095 case 7:
4096 status = set_user_info_7(p->mem_ctx,
4097 &info->info7, pwd);
4098 break;
4100 case 16:
4101 if (!set_user_info_16(&info->info16, pwd)) {
4102 status = NT_STATUS_ACCESS_DENIED;
4104 break;
4106 case 18:
4107 /* Used by AS/U JRA. */
4108 if (!set_user_info_18(&info->info18, pwd)) {
4109 status = NT_STATUS_ACCESS_DENIED;
4111 break;
4113 case 20:
4114 if (!set_user_info_20(&info->info20, pwd)) {
4115 status = NT_STATUS_ACCESS_DENIED;
4117 break;
4119 case 21:
4120 status = set_user_info_21(p->mem_ctx,
4121 &info->info21, pwd);
4122 break;
4124 case 23:
4125 if (!p->session_key.length) {
4126 status = NT_STATUS_NO_USER_SESSION_KEY;
4128 SamOEMhashBlob(info->info23.password.data, 516,
4129 &p->session_key);
4131 dump_data(100, info->info23.password.data, 516);
4133 status = set_user_info_23(p->mem_ctx,
4134 &info->info23, pwd);
4135 break;
4137 case 24:
4138 if (!p->session_key.length) {
4139 status = NT_STATUS_NO_USER_SESSION_KEY;
4141 SamOEMhashBlob(info->info24.password.data,
4142 516,
4143 &p->session_key);
4145 dump_data(100, info->info24.password.data, 516);
4147 if (!set_user_info_pw(info->info24.password.data, pwd)) {
4148 status = NT_STATUS_ACCESS_DENIED;
4150 break;
4152 case 25:
4153 if (!p->session_key.length) {
4154 status = NT_STATUS_NO_USER_SESSION_KEY;
4156 encode_or_decode_arc4_passwd_buffer(info->info25.password.data,
4157 &p->session_key);
4159 dump_data(100, info->info25.password.data, 532);
4161 status = set_user_info_25(p->mem_ctx,
4162 &info->info25, pwd);
4163 if (!NT_STATUS_IS_OK(status)) {
4164 goto done;
4166 if (!set_user_info_pw(info->info25.password.data, pwd)) {
4167 status = NT_STATUS_ACCESS_DENIED;
4169 break;
4171 case 26:
4172 if (!p->session_key.length) {
4173 status = NT_STATUS_NO_USER_SESSION_KEY;
4175 encode_or_decode_arc4_passwd_buffer(info->info26.password.data,
4176 &p->session_key);
4178 dump_data(100, info->info26.password.data, 516);
4180 if (!set_user_info_pw(info->info26.password.data, pwd)) {
4181 status = NT_STATUS_ACCESS_DENIED;
4183 break;
4185 default:
4186 status = NT_STATUS_INVALID_INFO_CLASS;
4189 done:
4191 if (has_enough_rights) {
4192 unbecome_root();
4195 /* ================ END SeMachineAccountPrivilege BLOCK ================ */
4197 if (NT_STATUS_IS_OK(status)) {
4198 force_flush_samr_cache(disp_info);
4201 return status;
4204 /*******************************************************************
4205 _samr_SetUserInfo
4206 ********************************************************************/
4208 NTSTATUS _samr_SetUserInfo(pipes_struct *p,
4209 struct samr_SetUserInfo *r)
4211 return samr_SetUserInfo_internal("_samr_SetUserInfo",
4213 r->in.user_handle,
4214 r->in.level,
4215 r->in.info);
4218 /*******************************************************************
4219 _samr_SetUserInfo2
4220 ********************************************************************/
4222 NTSTATUS _samr_SetUserInfo2(pipes_struct *p,
4223 struct samr_SetUserInfo2 *r)
4225 return samr_SetUserInfo_internal("_samr_SetUserInfo2",
4227 r->in.user_handle,
4228 r->in.level,
4229 r->in.info);
4232 /*********************************************************************
4233 _samr_GetAliasMembership
4234 *********************************************************************/
4236 NTSTATUS _samr_GetAliasMembership(pipes_struct *p,
4237 struct samr_GetAliasMembership *r)
4239 size_t num_alias_rids;
4240 uint32 *alias_rids;
4241 struct samr_info *info = NULL;
4242 size_t i;
4244 NTSTATUS ntstatus1;
4245 NTSTATUS ntstatus2;
4247 DOM_SID *members;
4249 DEBUG(5,("_samr_GetAliasMembership: %d\n", __LINE__));
4251 /* find the policy handle. open a policy on it. */
4252 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
4253 return NT_STATUS_INVALID_HANDLE;
4255 ntstatus1 = access_check_samr_function(info->acc_granted,
4256 SA_RIGHT_DOMAIN_LOOKUP_ALIAS_BY_MEM,
4257 "_samr_GetAliasMembership");
4258 ntstatus2 = access_check_samr_function(info->acc_granted,
4259 SA_RIGHT_DOMAIN_OPEN_ACCOUNT,
4260 "_samr_GetAliasMembership");
4262 if (!NT_STATUS_IS_OK(ntstatus1) || !NT_STATUS_IS_OK(ntstatus2)) {
4263 if (!(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus2)) &&
4264 !(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus1))) {
4265 return (NT_STATUS_IS_OK(ntstatus1)) ? ntstatus2 : ntstatus1;
4269 if (!sid_check_is_domain(&info->sid) &&
4270 !sid_check_is_builtin(&info->sid))
4271 return NT_STATUS_OBJECT_TYPE_MISMATCH;
4273 if (r->in.sids->num_sids) {
4274 members = TALLOC_ARRAY(p->mem_ctx, DOM_SID, r->in.sids->num_sids);
4276 if (members == NULL)
4277 return NT_STATUS_NO_MEMORY;
4278 } else {
4279 members = NULL;
4282 for (i=0; i<r->in.sids->num_sids; i++)
4283 sid_copy(&members[i], r->in.sids->sids[i].sid);
4285 alias_rids = NULL;
4286 num_alias_rids = 0;
4288 become_root();
4289 ntstatus1 = pdb_enum_alias_memberships(p->mem_ctx, &info->sid, members,
4290 r->in.sids->num_sids,
4291 &alias_rids, &num_alias_rids);
4292 unbecome_root();
4294 if (!NT_STATUS_IS_OK(ntstatus1)) {
4295 return ntstatus1;
4298 r->out.rids->count = num_alias_rids;
4299 r->out.rids->ids = alias_rids;
4301 return NT_STATUS_OK;
4304 /*********************************************************************
4305 _samr_GetMembersInAlias
4306 *********************************************************************/
4308 NTSTATUS _samr_GetMembersInAlias(pipes_struct *p,
4309 struct samr_GetMembersInAlias *r)
4311 NTSTATUS status;
4312 size_t i;
4313 size_t num_sids = 0;
4314 struct lsa_SidPtr *sids = NULL;
4315 DOM_SID *pdb_sids = NULL;
4317 DOM_SID alias_sid;
4319 uint32 acc_granted;
4321 /* find the policy handle. open a policy on it. */
4322 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, NULL))
4323 return NT_STATUS_INVALID_HANDLE;
4325 status = access_check_samr_function(acc_granted,
4326 SA_RIGHT_ALIAS_GET_MEMBERS,
4327 "_samr_GetMembersInAlias");
4328 if (!NT_STATUS_IS_OK(status)) {
4329 return status;
4332 DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
4334 become_root();
4335 status = pdb_enum_aliasmem(&alias_sid, &pdb_sids, &num_sids);
4336 unbecome_root();
4338 if (!NT_STATUS_IS_OK(status)) {
4339 return status;
4342 if (num_sids) {
4343 sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_SidPtr, num_sids);
4344 if (sids == NULL) {
4345 TALLOC_FREE(pdb_sids);
4346 return NT_STATUS_NO_MEMORY;
4350 for (i = 0; i < num_sids; i++) {
4351 sids[i].sid = sid_dup_talloc(p->mem_ctx, &pdb_sids[i]);
4352 if (!sids[i].sid) {
4353 TALLOC_FREE(pdb_sids);
4354 return NT_STATUS_NO_MEMORY;
4358 r->out.sids->num_sids = num_sids;
4359 r->out.sids->sids = sids;
4361 TALLOC_FREE(pdb_sids);
4363 return NT_STATUS_OK;
4366 /*********************************************************************
4367 _samr_QueryGroupMember
4368 *********************************************************************/
4370 NTSTATUS _samr_QueryGroupMember(pipes_struct *p,
4371 struct samr_QueryGroupMember *r)
4373 DOM_SID group_sid;
4374 size_t i, num_members;
4376 uint32 *rid=NULL;
4377 uint32 *attr=NULL;
4379 uint32 acc_granted;
4381 NTSTATUS status;
4382 struct samr_RidTypeArray *rids = NULL;
4384 rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidTypeArray);
4385 if (!rids) {
4386 return NT_STATUS_NO_MEMORY;
4389 /* find the policy handle. open a policy on it. */
4390 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, NULL))
4391 return NT_STATUS_INVALID_HANDLE;
4393 status = access_check_samr_function(acc_granted,
4394 SA_RIGHT_GROUP_GET_MEMBERS,
4395 "_samr_QueryGroupMember");
4396 if (!NT_STATUS_IS_OK(status)) {
4397 return status;
4400 DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
4402 if (!sid_check_is_in_our_domain(&group_sid)) {
4403 DEBUG(3, ("sid %s is not in our domain\n",
4404 sid_string_dbg(&group_sid)));
4405 return NT_STATUS_NO_SUCH_GROUP;
4408 DEBUG(10, ("lookup on Domain SID\n"));
4410 become_root();
4411 status = pdb_enum_group_members(p->mem_ctx, &group_sid,
4412 &rid, &num_members);
4413 unbecome_root();
4415 if (!NT_STATUS_IS_OK(status))
4416 return status;
4418 if (num_members) {
4419 attr=TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_members);
4420 if (attr == NULL) {
4421 return NT_STATUS_NO_MEMORY;
4423 } else {
4424 attr = NULL;
4427 for (i=0; i<num_members; i++)
4428 attr[i] = SID_NAME_USER;
4430 rids->count = num_members;
4431 rids->types = attr;
4432 rids->rids = rid;
4434 *r->out.rids = rids;
4436 return NT_STATUS_OK;
4439 /*********************************************************************
4440 _samr_AddAliasMember
4441 *********************************************************************/
4443 NTSTATUS _samr_AddAliasMember(pipes_struct *p,
4444 struct samr_AddAliasMember *r)
4446 DOM_SID alias_sid;
4447 uint32 acc_granted;
4448 SE_PRIV se_rights;
4449 bool can_add_accounts;
4450 NTSTATUS status;
4451 DISP_INFO *disp_info = NULL;
4453 /* Find the policy handle. Open a policy on it. */
4454 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
4455 return NT_STATUS_INVALID_HANDLE;
4457 status = access_check_samr_function(acc_granted,
4458 SA_RIGHT_ALIAS_ADD_MEMBER,
4459 "_samr_AddAliasMember");
4460 if (!NT_STATUS_IS_OK(status)) {
4461 return status;
4464 DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
4466 se_priv_copy( &se_rights, &se_add_users );
4467 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4469 /******** BEGIN SeAddUsers BLOCK *********/
4471 if ( can_add_accounts )
4472 become_root();
4474 status = pdb_add_aliasmem(&alias_sid, r->in.sid);
4476 if ( can_add_accounts )
4477 unbecome_root();
4479 /******** END SeAddUsers BLOCK *********/
4481 if (NT_STATUS_IS_OK(status)) {
4482 force_flush_samr_cache(disp_info);
4485 return status;
4488 /*********************************************************************
4489 _samr_DeleteAliasMember
4490 *********************************************************************/
4492 NTSTATUS _samr_DeleteAliasMember(pipes_struct *p,
4493 struct samr_DeleteAliasMember *r)
4495 DOM_SID alias_sid;
4496 uint32 acc_granted;
4497 SE_PRIV se_rights;
4498 bool can_add_accounts;
4499 NTSTATUS status;
4500 DISP_INFO *disp_info = NULL;
4502 /* Find the policy handle. Open a policy on it. */
4503 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
4504 return NT_STATUS_INVALID_HANDLE;
4506 status = access_check_samr_function(acc_granted,
4507 SA_RIGHT_ALIAS_REMOVE_MEMBER,
4508 "_samr_DeleteAliasMember");
4509 if (!NT_STATUS_IS_OK(status)) {
4510 return status;
4513 DEBUG(10, ("_samr_del_aliasmem:sid is %s\n",
4514 sid_string_dbg(&alias_sid)));
4516 se_priv_copy( &se_rights, &se_add_users );
4517 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4519 /******** BEGIN SeAddUsers BLOCK *********/
4521 if ( can_add_accounts )
4522 become_root();
4524 status = pdb_del_aliasmem(&alias_sid, r->in.sid);
4526 if ( can_add_accounts )
4527 unbecome_root();
4529 /******** END SeAddUsers BLOCK *********/
4531 if (NT_STATUS_IS_OK(status)) {
4532 force_flush_samr_cache(disp_info);
4535 return status;
4538 /*********************************************************************
4539 _samr_AddGroupMember
4540 *********************************************************************/
4542 NTSTATUS _samr_AddGroupMember(pipes_struct *p,
4543 struct samr_AddGroupMember *r)
4545 NTSTATUS status;
4546 DOM_SID group_sid;
4547 uint32 group_rid;
4548 uint32 acc_granted;
4549 SE_PRIV se_rights;
4550 bool can_add_accounts;
4551 DISP_INFO *disp_info = NULL;
4553 /* Find the policy handle. Open a policy on it. */
4554 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
4555 return NT_STATUS_INVALID_HANDLE;
4557 status = access_check_samr_function(acc_granted,
4558 SA_RIGHT_GROUP_ADD_MEMBER,
4559 "_samr_AddGroupMember");
4560 if (!NT_STATUS_IS_OK(status)) {
4561 return status;
4564 DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
4566 if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
4567 &group_rid)) {
4568 return NT_STATUS_INVALID_HANDLE;
4571 se_priv_copy( &se_rights, &se_add_users );
4572 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4574 /******** BEGIN SeAddUsers BLOCK *********/
4576 if ( can_add_accounts )
4577 become_root();
4579 status = pdb_add_groupmem(p->mem_ctx, group_rid, r->in.rid);
4581 if ( can_add_accounts )
4582 unbecome_root();
4584 /******** END SeAddUsers BLOCK *********/
4586 force_flush_samr_cache(disp_info);
4588 return status;
4591 /*********************************************************************
4592 _samr_DeleteGroupMember
4593 *********************************************************************/
4595 NTSTATUS _samr_DeleteGroupMember(pipes_struct *p,
4596 struct samr_DeleteGroupMember *r)
4599 NTSTATUS status;
4600 DOM_SID group_sid;
4601 uint32 group_rid;
4602 uint32 acc_granted;
4603 SE_PRIV se_rights;
4604 bool can_add_accounts;
4605 DISP_INFO *disp_info = NULL;
4608 * delete the group member named r->in.rid
4609 * who is a member of the sid associated with the handle
4610 * the rid is a user's rid as the group is a domain group.
4613 /* Find the policy handle. Open a policy on it. */
4614 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
4615 return NT_STATUS_INVALID_HANDLE;
4617 status = access_check_samr_function(acc_granted,
4618 SA_RIGHT_GROUP_REMOVE_MEMBER,
4619 "_samr_DeleteGroupMember");
4620 if (!NT_STATUS_IS_OK(status)) {
4621 return status;
4624 if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
4625 &group_rid)) {
4626 return NT_STATUS_INVALID_HANDLE;
4629 se_priv_copy( &se_rights, &se_add_users );
4630 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4632 /******** BEGIN SeAddUsers BLOCK *********/
4634 if ( can_add_accounts )
4635 become_root();
4637 status = pdb_del_groupmem(p->mem_ctx, group_rid, r->in.rid);
4639 if ( can_add_accounts )
4640 unbecome_root();
4642 /******** END SeAddUsers BLOCK *********/
4644 force_flush_samr_cache(disp_info);
4646 return status;
4649 /*********************************************************************
4650 _samr_DeleteUser
4651 *********************************************************************/
4653 NTSTATUS _samr_DeleteUser(pipes_struct *p,
4654 struct samr_DeleteUser *r)
4656 NTSTATUS status;
4657 DOM_SID user_sid;
4658 struct samu *sam_pass=NULL;
4659 uint32 acc_granted;
4660 bool can_add_accounts;
4661 uint32 acb_info;
4662 DISP_INFO *disp_info = NULL;
4663 bool ret;
4665 DEBUG(5, ("_samr_DeleteUser: %d\n", __LINE__));
4667 /* Find the policy handle. Open a policy on it. */
4668 if (!get_lsa_policy_samr_sid(p, r->in.user_handle, &user_sid, &acc_granted, &disp_info))
4669 return NT_STATUS_INVALID_HANDLE;
4671 status = access_check_samr_function(acc_granted,
4672 STD_RIGHT_DELETE_ACCESS,
4673 "_samr_DeleteUser");
4674 if (!NT_STATUS_IS_OK(status)) {
4675 return status;
4678 if (!sid_check_is_in_our_domain(&user_sid))
4679 return NT_STATUS_CANNOT_DELETE;
4681 /* check if the user exists before trying to delete */
4682 if ( !(sam_pass = samu_new( NULL )) ) {
4683 return NT_STATUS_NO_MEMORY;
4686 become_root();
4687 ret = pdb_getsampwsid(sam_pass, &user_sid);
4688 unbecome_root();
4690 if( !ret ) {
4691 DEBUG(5,("_samr_DeleteUser: User %s doesn't exist.\n",
4692 sid_string_dbg(&user_sid)));
4693 TALLOC_FREE(sam_pass);
4694 return NT_STATUS_NO_SUCH_USER;
4697 acb_info = pdb_get_acct_ctrl(sam_pass);
4699 /* For machine accounts it's the SeMachineAccountPrivilege that counts. */
4700 if ( acb_info & ACB_WSTRUST ) {
4701 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_machine_account );
4702 } else {
4703 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_add_users );
4706 /******** BEGIN SeAddUsers BLOCK *********/
4708 if ( can_add_accounts )
4709 become_root();
4711 status = pdb_delete_user(p->mem_ctx, sam_pass);
4713 if ( can_add_accounts )
4714 unbecome_root();
4716 /******** END SeAddUsers BLOCK *********/
4718 if ( !NT_STATUS_IS_OK(status) ) {
4719 DEBUG(5,("_samr_DeleteUser: Failed to delete entry for "
4720 "user %s: %s.\n", pdb_get_username(sam_pass),
4721 nt_errstr(status)));
4722 TALLOC_FREE(sam_pass);
4723 return status;
4727 TALLOC_FREE(sam_pass);
4729 if (!close_policy_hnd(p, r->in.user_handle))
4730 return NT_STATUS_OBJECT_NAME_INVALID;
4732 force_flush_samr_cache(disp_info);
4734 return NT_STATUS_OK;
4737 /*********************************************************************
4738 _samr_DeleteDomainGroup
4739 *********************************************************************/
4741 NTSTATUS _samr_DeleteDomainGroup(pipes_struct *p,
4742 struct samr_DeleteDomainGroup *r)
4744 NTSTATUS status;
4745 DOM_SID group_sid;
4746 uint32 group_rid;
4747 uint32 acc_granted;
4748 SE_PRIV se_rights;
4749 bool can_add_accounts;
4750 DISP_INFO *disp_info = NULL;
4752 DEBUG(5, ("samr_DeleteDomainGroup: %d\n", __LINE__));
4754 /* Find the policy handle. Open a policy on it. */
4755 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
4756 return NT_STATUS_INVALID_HANDLE;
4758 status = access_check_samr_function(acc_granted,
4759 STD_RIGHT_DELETE_ACCESS,
4760 "_samr_DeleteDomainGroup");
4761 if (!NT_STATUS_IS_OK(status)) {
4762 return status;
4765 DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
4767 if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
4768 &group_rid)) {
4769 return NT_STATUS_NO_SUCH_GROUP;
4772 se_priv_copy( &se_rights, &se_add_users );
4773 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4775 /******** BEGIN SeAddUsers BLOCK *********/
4777 if ( can_add_accounts )
4778 become_root();
4780 status = pdb_delete_dom_group(p->mem_ctx, group_rid);
4782 if ( can_add_accounts )
4783 unbecome_root();
4785 /******** END SeAddUsers BLOCK *********/
4787 if ( !NT_STATUS_IS_OK(status) ) {
4788 DEBUG(5,("_samr_DeleteDomainGroup: Failed to delete mapping "
4789 "entry for group %s: %s\n",
4790 sid_string_dbg(&group_sid),
4791 nt_errstr(status)));
4792 return status;
4795 if (!close_policy_hnd(p, r->in.group_handle))
4796 return NT_STATUS_OBJECT_NAME_INVALID;
4798 force_flush_samr_cache(disp_info);
4800 return NT_STATUS_OK;
4803 /*********************************************************************
4804 _samr_DeleteDomAlias
4805 *********************************************************************/
4807 NTSTATUS _samr_DeleteDomAlias(pipes_struct *p,
4808 struct samr_DeleteDomAlias *r)
4810 DOM_SID alias_sid;
4811 uint32 acc_granted;
4812 SE_PRIV se_rights;
4813 bool can_add_accounts;
4814 NTSTATUS status;
4815 DISP_INFO *disp_info = NULL;
4817 DEBUG(5, ("_samr_DeleteDomAlias: %d\n", __LINE__));
4819 /* Find the policy handle. Open a policy on it. */
4820 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
4821 return NT_STATUS_INVALID_HANDLE;
4823 /* copy the handle to the outgoing reply */
4825 memcpy(r->out.alias_handle, r->in.alias_handle, sizeof(r->out.alias_handle));
4827 status = access_check_samr_function(acc_granted,
4828 STD_RIGHT_DELETE_ACCESS,
4829 "_samr_DeleteDomAlias");
4830 if (!NT_STATUS_IS_OK(status)) {
4831 return status;
4834 DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
4836 /* Don't let Windows delete builtin groups */
4838 if ( sid_check_is_in_builtin( &alias_sid ) ) {
4839 return NT_STATUS_SPECIAL_ACCOUNT;
4842 if (!sid_check_is_in_our_domain(&alias_sid))
4843 return NT_STATUS_NO_SUCH_ALIAS;
4845 DEBUG(10, ("lookup on Local SID\n"));
4847 se_priv_copy( &se_rights, &se_add_users );
4848 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4850 /******** BEGIN SeAddUsers BLOCK *********/
4852 if ( can_add_accounts )
4853 become_root();
4855 /* Have passdb delete the alias */
4856 status = pdb_delete_alias(&alias_sid);
4858 if ( can_add_accounts )
4859 unbecome_root();
4861 /******** END SeAddUsers BLOCK *********/
4863 if ( !NT_STATUS_IS_OK(status))
4864 return status;
4866 if (!close_policy_hnd(p, r->in.alias_handle))
4867 return NT_STATUS_OBJECT_NAME_INVALID;
4869 force_flush_samr_cache(disp_info);
4871 return NT_STATUS_OK;
4874 /*********************************************************************
4875 _samr_CreateDomainGroup
4876 *********************************************************************/
4878 NTSTATUS _samr_CreateDomainGroup(pipes_struct *p,
4879 struct samr_CreateDomainGroup *r)
4882 NTSTATUS status;
4883 DOM_SID dom_sid;
4884 DOM_SID info_sid;
4885 const char *name;
4886 struct samr_info *info;
4887 uint32 acc_granted;
4888 SE_PRIV se_rights;
4889 bool can_add_accounts;
4890 DISP_INFO *disp_info = NULL;
4892 /* Find the policy handle. Open a policy on it. */
4893 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &dom_sid, &acc_granted, &disp_info))
4894 return NT_STATUS_INVALID_HANDLE;
4896 status = access_check_samr_function(acc_granted,
4897 SA_RIGHT_DOMAIN_CREATE_GROUP,
4898 "_samr_CreateDomainGroup");
4899 if (!NT_STATUS_IS_OK(status)) {
4900 return status;
4903 if (!sid_equal(&dom_sid, get_global_sam_sid()))
4904 return NT_STATUS_ACCESS_DENIED;
4906 name = r->in.name->string;
4907 if (name == NULL) {
4908 return NT_STATUS_NO_MEMORY;
4911 status = can_create(p->mem_ctx, name);
4912 if (!NT_STATUS_IS_OK(status)) {
4913 return status;
4916 se_priv_copy( &se_rights, &se_add_users );
4917 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4919 /******** BEGIN SeAddUsers BLOCK *********/
4921 if ( can_add_accounts )
4922 become_root();
4924 /* check that we successfully create the UNIX group */
4926 status = pdb_create_dom_group(p->mem_ctx, name, r->out.rid);
4928 if ( can_add_accounts )
4929 unbecome_root();
4931 /******** END SeAddUsers BLOCK *********/
4933 /* check if we should bail out here */
4935 if ( !NT_STATUS_IS_OK(status) )
4936 return status;
4938 sid_compose(&info_sid, get_global_sam_sid(), *r->out.rid);
4940 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4941 return NT_STATUS_NO_MEMORY;
4943 /* they created it; let the user do what he wants with it */
4945 info->acc_granted = GENERIC_RIGHTS_GROUP_ALL_ACCESS;
4947 /* get a (unique) handle. open a policy on it. */
4948 if (!create_policy_hnd(p, r->out.group_handle, free_samr_info, (void *)info))
4949 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4951 force_flush_samr_cache(disp_info);
4953 return NT_STATUS_OK;
4956 /*********************************************************************
4957 _samr_CreateDomAlias
4958 *********************************************************************/
4960 NTSTATUS _samr_CreateDomAlias(pipes_struct *p,
4961 struct samr_CreateDomAlias *r)
4963 DOM_SID dom_sid;
4964 DOM_SID info_sid;
4965 const char *name = NULL;
4966 struct samr_info *info;
4967 uint32 acc_granted;
4968 gid_t gid;
4969 NTSTATUS result;
4970 SE_PRIV se_rights;
4971 bool can_add_accounts;
4972 DISP_INFO *disp_info = NULL;
4974 /* Find the policy handle. Open a policy on it. */
4975 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &dom_sid, &acc_granted, &disp_info))
4976 return NT_STATUS_INVALID_HANDLE;
4978 result = access_check_samr_function(acc_granted,
4979 SA_RIGHT_DOMAIN_CREATE_ALIAS,
4980 "_samr_CreateDomAlias");
4981 if (!NT_STATUS_IS_OK(result)) {
4982 return result;
4985 if (!sid_equal(&dom_sid, get_global_sam_sid()))
4986 return NT_STATUS_ACCESS_DENIED;
4988 name = r->in.alias_name->string;
4990 se_priv_copy( &se_rights, &se_add_users );
4991 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4993 result = can_create(p->mem_ctx, name);
4994 if (!NT_STATUS_IS_OK(result)) {
4995 return result;
4998 /******** BEGIN SeAddUsers BLOCK *********/
5000 if ( can_add_accounts )
5001 become_root();
5003 /* Have passdb create the alias */
5004 result = pdb_create_alias(name, r->out.rid);
5006 if ( can_add_accounts )
5007 unbecome_root();
5009 /******** END SeAddUsers BLOCK *********/
5011 if (!NT_STATUS_IS_OK(result)) {
5012 DEBUG(10, ("pdb_create_alias failed: %s\n",
5013 nt_errstr(result)));
5014 return result;
5017 sid_copy(&info_sid, get_global_sam_sid());
5018 sid_append_rid(&info_sid, *r->out.rid);
5020 if (!sid_to_gid(&info_sid, &gid)) {
5021 DEBUG(10, ("Could not find alias just created\n"));
5022 return NT_STATUS_ACCESS_DENIED;
5025 /* check if the group has been successfully created */
5026 if ( getgrgid(gid) == NULL ) {
5027 DEBUG(10, ("getgrgid(%d) of just created alias failed\n",
5028 gid));
5029 return NT_STATUS_ACCESS_DENIED;
5032 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
5033 return NT_STATUS_NO_MEMORY;
5035 /* they created it; let the user do what he wants with it */
5037 info->acc_granted = GENERIC_RIGHTS_ALIAS_ALL_ACCESS;
5039 /* get a (unique) handle. open a policy on it. */
5040 if (!create_policy_hnd(p, r->out.alias_handle, free_samr_info, (void *)info))
5041 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5043 force_flush_samr_cache(disp_info);
5045 return NT_STATUS_OK;
5048 /*********************************************************************
5049 _samr_QueryGroupInfo
5050 *********************************************************************/
5052 NTSTATUS _samr_QueryGroupInfo(pipes_struct *p,
5053 struct samr_QueryGroupInfo *r)
5055 NTSTATUS status;
5056 DOM_SID group_sid;
5057 GROUP_MAP map;
5058 union samr_GroupInfo *info = NULL;
5059 uint32 acc_granted;
5060 bool ret;
5061 uint32_t attributes = SE_GROUP_MANDATORY |
5062 SE_GROUP_ENABLED_BY_DEFAULT |
5063 SE_GROUP_ENABLED;
5064 const char *group_name = NULL;
5065 const char *group_description = NULL;
5067 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, NULL))
5068 return NT_STATUS_INVALID_HANDLE;
5070 status = access_check_samr_function(acc_granted,
5071 SA_RIGHT_GROUP_LOOKUP_INFO,
5072 "_samr_QueryGroupInfo");
5073 if (!NT_STATUS_IS_OK(status)) {
5074 return status;
5077 become_root();
5078 ret = get_domain_group_from_sid(group_sid, &map);
5079 unbecome_root();
5080 if (!ret)
5081 return NT_STATUS_INVALID_HANDLE;
5083 /* FIXME: map contains fstrings */
5084 group_name = talloc_strdup(r, map.nt_name);
5085 group_description = talloc_strdup(r, map.comment);
5087 info = TALLOC_ZERO_P(p->mem_ctx, union samr_GroupInfo);
5088 if (!info) {
5089 return NT_STATUS_NO_MEMORY;
5092 switch (r->in.level) {
5093 case 1: {
5094 uint32 *members;
5095 size_t num_members;
5097 become_root();
5098 status = pdb_enum_group_members(
5099 p->mem_ctx, &group_sid, &members, &num_members);
5100 unbecome_root();
5102 if (!NT_STATUS_IS_OK(status)) {
5103 return status;
5106 init_samr_group_info1(&info->all,
5107 group_name,
5108 attributes,
5109 num_members,
5110 group_description);
5111 break;
5113 case 2:
5114 init_samr_group_info2(&info->name,
5115 group_name);
5116 break;
5117 case 3:
5118 init_samr_group_info3(&info->attributes,
5119 attributes);
5120 break;
5121 case 4:
5122 init_samr_group_info4(&info->description,
5123 group_description);
5124 break;
5125 case 5: {
5127 uint32 *members;
5128 size_t num_members;
5132 become_root();
5133 status = pdb_enum_group_members(
5134 p->mem_ctx, &group_sid, &members, &num_members);
5135 unbecome_root();
5137 if (!NT_STATUS_IS_OK(status)) {
5138 return status;
5141 init_samr_group_info5(&info->all2,
5142 group_name,
5143 attributes,
5144 0, /* num_members - in w2k3 this is always 0 */
5145 group_description);
5147 break;
5149 default:
5150 return NT_STATUS_INVALID_INFO_CLASS;
5153 *r->out.info = info;
5155 return NT_STATUS_OK;
5158 /*********************************************************************
5159 _samr_SetGroupInfo
5160 *********************************************************************/
5162 NTSTATUS _samr_SetGroupInfo(pipes_struct *p,
5163 struct samr_SetGroupInfo *r)
5165 DOM_SID group_sid;
5166 GROUP_MAP map;
5167 uint32 acc_granted;
5168 NTSTATUS status;
5169 bool ret;
5170 bool can_mod_accounts;
5171 DISP_INFO *disp_info = NULL;
5173 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
5174 return NT_STATUS_INVALID_HANDLE;
5176 status = access_check_samr_function(acc_granted,
5177 SA_RIGHT_GROUP_SET_INFO,
5178 "_samr_SetGroupInfo");
5179 if (!NT_STATUS_IS_OK(status)) {
5180 return status;
5183 become_root();
5184 ret = get_domain_group_from_sid(group_sid, &map);
5185 unbecome_root();
5186 if (!ret)
5187 return NT_STATUS_NO_SUCH_GROUP;
5189 switch (r->in.level) {
5190 case 1:
5191 fstrcpy(map.comment, r->in.info->all.description.string);
5192 break;
5193 case 4:
5194 fstrcpy(map.comment, r->in.info->description.string);
5195 break;
5196 default:
5197 return NT_STATUS_INVALID_INFO_CLASS;
5200 can_mod_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_add_users );
5202 /******** BEGIN SeAddUsers BLOCK *********/
5204 if ( can_mod_accounts )
5205 become_root();
5207 status = pdb_update_group_mapping_entry(&map);
5209 if ( can_mod_accounts )
5210 unbecome_root();
5212 /******** End SeAddUsers BLOCK *********/
5214 if (NT_STATUS_IS_OK(status)) {
5215 force_flush_samr_cache(disp_info);
5218 return status;
5221 /*********************************************************************
5222 _samr_SetAliasInfo
5223 *********************************************************************/
5225 NTSTATUS _samr_SetAliasInfo(pipes_struct *p,
5226 struct samr_SetAliasInfo *r)
5228 DOM_SID group_sid;
5229 struct acct_info info;
5230 uint32 acc_granted;
5231 bool can_mod_accounts;
5232 NTSTATUS status;
5233 DISP_INFO *disp_info = NULL;
5235 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &group_sid, &acc_granted, &disp_info))
5236 return NT_STATUS_INVALID_HANDLE;
5238 status = access_check_samr_function(acc_granted,
5239 SA_RIGHT_ALIAS_SET_INFO,
5240 "_samr_SetAliasInfo");
5241 if (!NT_STATUS_IS_OK(status)) {
5242 return status;
5245 /* get the current group information */
5247 become_root();
5248 status = pdb_get_aliasinfo( &group_sid, &info );
5249 unbecome_root();
5251 if ( !NT_STATUS_IS_OK(status))
5252 return status;
5254 switch (r->in.level) {
5255 case ALIASINFONAME:
5257 fstring group_name;
5259 /* We currently do not support renaming groups in the
5260 the BUILTIN domain. Refer to util_builtin.c to understand
5261 why. The eventually needs to be fixed to be like Windows
5262 where you can rename builtin groups, just not delete them */
5264 if ( sid_check_is_in_builtin( &group_sid ) ) {
5265 return NT_STATUS_SPECIAL_ACCOUNT;
5268 /* There has to be a valid name (and it has to be different) */
5270 if ( !r->in.info->name.string )
5271 return NT_STATUS_INVALID_PARAMETER;
5273 /* If the name is the same just reply "ok". Yes this
5274 doesn't allow you to change the case of a group name. */
5276 if ( strequal( r->in.info->name.string, info.acct_name ) )
5277 return NT_STATUS_OK;
5279 fstrcpy( info.acct_name, r->in.info->name.string);
5281 /* make sure the name doesn't already exist as a user
5282 or local group */
5284 fstr_sprintf( group_name, "%s\\%s", global_myname(), info.acct_name );
5285 status = can_create( p->mem_ctx, group_name );
5286 if ( !NT_STATUS_IS_OK( status ) )
5287 return status;
5288 break;
5290 case ALIASINFODESCRIPTION:
5291 if (r->in.info->description.string) {
5292 fstrcpy(info.acct_desc,
5293 r->in.info->description.string);
5294 } else {
5295 fstrcpy( info.acct_desc, "" );
5297 break;
5298 default:
5299 return NT_STATUS_INVALID_INFO_CLASS;
5302 can_mod_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_add_users );
5304 /******** BEGIN SeAddUsers BLOCK *********/
5306 if ( can_mod_accounts )
5307 become_root();
5309 status = pdb_set_aliasinfo( &group_sid, &info );
5311 if ( can_mod_accounts )
5312 unbecome_root();
5314 /******** End SeAddUsers BLOCK *********/
5316 if (NT_STATUS_IS_OK(status))
5317 force_flush_samr_cache(disp_info);
5319 return status;
5322 /****************************************************************
5323 _samr_GetDomPwInfo
5324 ****************************************************************/
5326 NTSTATUS _samr_GetDomPwInfo(pipes_struct *p,
5327 struct samr_GetDomPwInfo *r)
5329 /* Perform access check. Since this rpc does not require a
5330 policy handle it will not be caught by the access checks on
5331 SAMR_CONNECT or SAMR_CONNECT_ANON. */
5333 if (!pipe_access_check(p)) {
5334 DEBUG(3, ("access denied to _samr_GetDomPwInfo\n"));
5335 return NT_STATUS_ACCESS_DENIED;
5338 /* Actually, returning zeros here works quite well :-). */
5339 ZERO_STRUCTP(r->out.info);
5341 return NT_STATUS_OK;
5344 /*********************************************************************
5345 _samr_OpenGroup
5346 *********************************************************************/
5348 NTSTATUS _samr_OpenGroup(pipes_struct *p,
5349 struct samr_OpenGroup *r)
5352 DOM_SID sid;
5353 DOM_SID info_sid;
5354 GROUP_MAP map;
5355 struct samr_info *info;
5356 SEC_DESC *psd = NULL;
5357 uint32 acc_granted;
5358 uint32 des_access = r->in.access_mask;
5359 size_t sd_size;
5360 NTSTATUS status;
5361 fstring sid_string;
5362 bool ret;
5363 SE_PRIV se_rights;
5365 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &sid, &acc_granted, NULL))
5366 return NT_STATUS_INVALID_HANDLE;
5368 status = access_check_samr_function(acc_granted,
5369 SA_RIGHT_DOMAIN_OPEN_ACCOUNT,
5370 "_samr_OpenGroup");
5372 if ( !NT_STATUS_IS_OK(status) )
5373 return status;
5375 /*check if access can be granted as requested by client. */
5376 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &grp_generic_mapping, NULL, 0);
5377 se_map_generic(&des_access,&grp_generic_mapping);
5379 se_priv_copy( &se_rights, &se_add_users );
5381 status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
5382 &se_rights, GENERIC_RIGHTS_GROUP_WRITE, des_access,
5383 &acc_granted, "_samr_OpenGroup");
5385 if ( !NT_STATUS_IS_OK(status) )
5386 return status;
5388 /* this should not be hard-coded like this */
5390 if (!sid_equal(&sid, get_global_sam_sid()))
5391 return NT_STATUS_ACCESS_DENIED;
5393 sid_copy(&info_sid, get_global_sam_sid());
5394 sid_append_rid(&info_sid, r->in.rid);
5395 sid_to_fstring(sid_string, &info_sid);
5397 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
5398 return NT_STATUS_NO_MEMORY;
5400 info->acc_granted = acc_granted;
5402 DEBUG(10, ("_samr_OpenGroup:Opening SID: %s\n", sid_string));
5404 /* check if that group really exists */
5405 become_root();
5406 ret = get_domain_group_from_sid(info->sid, &map);
5407 unbecome_root();
5408 if (!ret)
5409 return NT_STATUS_NO_SUCH_GROUP;
5411 /* get a (unique) handle. open a policy on it. */
5412 if (!create_policy_hnd(p, r->out.group_handle, free_samr_info, (void *)info))
5413 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5415 return NT_STATUS_OK;
5418 /*********************************************************************
5419 _samr_RemoveMemberFromForeignDomain
5420 *********************************************************************/
5422 NTSTATUS _samr_RemoveMemberFromForeignDomain(pipes_struct *p,
5423 struct samr_RemoveMemberFromForeignDomain *r)
5425 DOM_SID delete_sid, domain_sid;
5426 uint32 acc_granted;
5427 NTSTATUS result;
5428 DISP_INFO *disp_info = NULL;
5430 sid_copy( &delete_sid, r->in.sid );
5432 DEBUG(5,("_samr_RemoveMemberFromForeignDomain: removing SID [%s]\n",
5433 sid_string_dbg(&delete_sid)));
5435 /* Find the policy handle. Open a policy on it. */
5437 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &domain_sid,
5438 &acc_granted, &disp_info))
5439 return NT_STATUS_INVALID_HANDLE;
5441 result = access_check_samr_function(acc_granted,
5442 STD_RIGHT_DELETE_ACCESS,
5443 "_samr_RemoveMemberFromForeignDomain");
5445 if (!NT_STATUS_IS_OK(result))
5446 return result;
5448 DEBUG(8, ("_samr_RemoveMemberFromForeignDomain: sid is %s\n",
5449 sid_string_dbg(&domain_sid)));
5451 /* we can only delete a user from a group since we don't have
5452 nested groups anyways. So in the latter case, just say OK */
5454 /* TODO: The above comment nowadays is bogus. Since we have nested
5455 * groups now, and aliases members are never reported out of the unix
5456 * group membership, the "just say OK" makes this call a no-op. For
5457 * us. This needs fixing however. */
5459 /* I've only ever seen this in the wild when deleting a user from
5460 * usrmgr.exe. domain_sid is the builtin domain, and the sid to delete
5461 * is the user about to be deleted. I very much suspect this is the
5462 * only application of this call. To verify this, let people report
5463 * other cases. */
5465 if (!sid_check_is_builtin(&domain_sid)) {
5466 DEBUG(1,("_samr_RemoveMemberFromForeignDomain: domain_sid = %s, "
5467 "global_sam_sid() = %s\n",
5468 sid_string_dbg(&domain_sid),
5469 sid_string_dbg(get_global_sam_sid())));
5470 DEBUGADD(1,("please report to samba-technical@samba.org!\n"));
5471 return NT_STATUS_OK;
5474 force_flush_samr_cache(disp_info);
5476 result = NT_STATUS_OK;
5478 return result;
5481 /*******************************************************************
5482 _samr_QueryDomainInfo2
5483 ********************************************************************/
5485 NTSTATUS _samr_QueryDomainInfo2(pipes_struct *p,
5486 struct samr_QueryDomainInfo2 *r)
5488 return samr_QueryDomainInfo_internal("_samr_QueryDomainInfo2",
5490 r->in.domain_handle,
5491 r->in.level,
5492 r->out.info);
5495 /*******************************************************************
5496 _samr_SetDomainInfo
5497 ********************************************************************/
5499 NTSTATUS _samr_SetDomainInfo(pipes_struct *p,
5500 struct samr_SetDomainInfo *r)
5502 time_t u_expire, u_min_age;
5503 time_t u_logout;
5504 time_t u_lock_duration, u_reset_time;
5506 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
5508 /* find the policy handle. open a policy on it. */
5509 if (!find_policy_by_hnd(p, r->in.domain_handle, NULL))
5510 return NT_STATUS_INVALID_HANDLE;
5512 DEBUG(5,("_samr_SetDomainInfo: level: %d\n", r->in.level));
5514 switch (r->in.level) {
5515 case 0x01:
5516 u_expire=nt_time_to_unix_abs((NTTIME *)&r->in.info->info1.max_password_age);
5517 u_min_age=nt_time_to_unix_abs((NTTIME *)&r->in.info->info1.min_password_age);
5518 pdb_set_account_policy(AP_MIN_PASSWORD_LEN, (uint32)r->in.info->info1.min_password_length);
5519 pdb_set_account_policy(AP_PASSWORD_HISTORY, (uint32)r->in.info->info1.password_history_length);
5520 pdb_set_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, (uint32)r->in.info->info1.password_properties);
5521 pdb_set_account_policy(AP_MAX_PASSWORD_AGE, (int)u_expire);
5522 pdb_set_account_policy(AP_MIN_PASSWORD_AGE, (int)u_min_age);
5523 break;
5524 case 0x02:
5525 break;
5526 case 0x03:
5527 u_logout=nt_time_to_unix_abs((NTTIME *)&r->in.info->info3.force_logoff_time);
5528 pdb_set_account_policy(AP_TIME_TO_LOGOUT, (int)u_logout);
5529 break;
5530 case 0x05:
5531 break;
5532 case 0x06:
5533 break;
5534 case 0x07:
5535 break;
5536 case 0x0c:
5537 u_lock_duration=nt_time_to_unix_abs((NTTIME *)&r->in.info->info12.lockout_duration);
5538 if (u_lock_duration != -1)
5539 u_lock_duration /= 60;
5541 u_reset_time=nt_time_to_unix_abs((NTTIME *)&r->in.info->info12.lockout_window)/60;
5543 pdb_set_account_policy(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
5544 pdb_set_account_policy(AP_RESET_COUNT_TIME, (int)u_reset_time);
5545 pdb_set_account_policy(AP_BAD_ATTEMPT_LOCKOUT, (uint32)r->in.info->info12.lockout_threshold);
5546 break;
5547 default:
5548 return NT_STATUS_INVALID_INFO_CLASS;
5551 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
5553 return NT_STATUS_OK;
5556 /****************************************************************
5557 ****************************************************************/
5559 NTSTATUS _samr_Shutdown(pipes_struct *p,
5560 struct samr_Shutdown *r)
5562 p->rng_fault_state = true;
5563 return NT_STATUS_NOT_IMPLEMENTED;
5566 /****************************************************************
5567 ****************************************************************/
5569 NTSTATUS _samr_CreateUser(pipes_struct *p,
5570 struct samr_CreateUser *r)
5572 p->rng_fault_state = true;
5573 return NT_STATUS_NOT_IMPLEMENTED;
5576 /****************************************************************
5577 ****************************************************************/
5579 NTSTATUS _samr_SetMemberAttributesOfGroup(pipes_struct *p,
5580 struct samr_SetMemberAttributesOfGroup *r)
5582 p->rng_fault_state = true;
5583 return NT_STATUS_NOT_IMPLEMENTED;
5586 /****************************************************************
5587 ****************************************************************/
5589 NTSTATUS _samr_ChangePasswordUser(pipes_struct *p,
5590 struct samr_ChangePasswordUser *r)
5592 p->rng_fault_state = true;
5593 return NT_STATUS_NOT_IMPLEMENTED;
5596 /****************************************************************
5597 ****************************************************************/
5599 NTSTATUS _samr_GetDisplayEnumerationIndex(pipes_struct *p,
5600 struct samr_GetDisplayEnumerationIndex *r)
5602 p->rng_fault_state = true;
5603 return NT_STATUS_NOT_IMPLEMENTED;
5606 /****************************************************************
5607 ****************************************************************/
5609 NTSTATUS _samr_TestPrivateFunctionsDomain(pipes_struct *p,
5610 struct samr_TestPrivateFunctionsDomain *r)
5612 p->rng_fault_state = true;
5613 return NT_STATUS_NOT_IMPLEMENTED;
5616 /****************************************************************
5617 ****************************************************************/
5619 NTSTATUS _samr_TestPrivateFunctionsUser(pipes_struct *p,
5620 struct samr_TestPrivateFunctionsUser *r)
5622 p->rng_fault_state = true;
5623 return NT_STATUS_NOT_IMPLEMENTED;
5626 /****************************************************************
5627 ****************************************************************/
5629 NTSTATUS _samr_QueryUserInfo2(pipes_struct *p,
5630 struct samr_QueryUserInfo2 *r)
5632 p->rng_fault_state = true;
5633 return NT_STATUS_NOT_IMPLEMENTED;
5636 /****************************************************************
5637 ****************************************************************/
5639 NTSTATUS _samr_GetDisplayEnumerationIndex2(pipes_struct *p,
5640 struct samr_GetDisplayEnumerationIndex2 *r)
5642 p->rng_fault_state = true;
5643 return NT_STATUS_NOT_IMPLEMENTED;
5646 /****************************************************************
5647 ****************************************************************/
5649 NTSTATUS _samr_AddMultipleMembersToAlias(pipes_struct *p,
5650 struct samr_AddMultipleMembersToAlias *r)
5652 p->rng_fault_state = true;
5653 return NT_STATUS_NOT_IMPLEMENTED;
5656 /****************************************************************
5657 ****************************************************************/
5659 NTSTATUS _samr_RemoveMultipleMembersFromAlias(pipes_struct *p,
5660 struct samr_RemoveMultipleMembersFromAlias *r)
5662 p->rng_fault_state = true;
5663 return NT_STATUS_NOT_IMPLEMENTED;
5666 /****************************************************************
5667 ****************************************************************/
5669 NTSTATUS _samr_OemChangePasswordUser2(pipes_struct *p,
5670 struct samr_OemChangePasswordUser2 *r)
5672 p->rng_fault_state = true;
5673 return NT_STATUS_NOT_IMPLEMENTED;
5676 /****************************************************************
5677 ****************************************************************/
5679 NTSTATUS _samr_SetBootKeyInformation(pipes_struct *p,
5680 struct samr_SetBootKeyInformation *r)
5682 p->rng_fault_state = true;
5683 return NT_STATUS_NOT_IMPLEMENTED;
5686 /****************************************************************
5687 ****************************************************************/
5689 NTSTATUS _samr_GetBootKeyInformation(pipes_struct *p,
5690 struct samr_GetBootKeyInformation *r)
5692 p->rng_fault_state = true;
5693 return NT_STATUS_NOT_IMPLEMENTED;
5696 /****************************************************************
5697 ****************************************************************/
5699 NTSTATUS _samr_Connect3(pipes_struct *p,
5700 struct samr_Connect3 *r)
5702 p->rng_fault_state = true;
5703 return NT_STATUS_NOT_IMPLEMENTED;
5706 /****************************************************************
5707 ****************************************************************/
5709 NTSTATUS _samr_RidToSid(pipes_struct *p,
5710 struct samr_RidToSid *r)
5712 p->rng_fault_state = true;
5713 return NT_STATUS_NOT_IMPLEMENTED;
5716 /****************************************************************
5717 ****************************************************************/
5719 NTSTATUS _samr_SetDsrmPassword(pipes_struct *p,
5720 struct samr_SetDsrmPassword *r)
5722 p->rng_fault_state = true;
5723 return NT_STATUS_NOT_IMPLEMENTED;
5726 /****************************************************************
5727 ****************************************************************/
5729 NTSTATUS _samr_ValidatePassword(pipes_struct *p,
5730 struct samr_ValidatePassword *r)
5732 p->rng_fault_state = true;
5733 return NT_STATUS_NOT_IMPLEMENTED;