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 2 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, write to the Free Software
27 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
31 * This is the implementation of the SAMR code.
37 #define DBGC_CLASS DBGC_RPC_SRV
39 #define SAMR_USR_RIGHTS_WRITE_PW \
40 ( READ_CONTROL_ACCESS | \
41 SA_RIGHT_USER_CHANGE_PASSWORD | \
42 SA_RIGHT_USER_SET_LOC_COM )
44 #define DISP_INFO_CACHE_TIMEOUT 10
46 typedef struct disp_info
{
47 struct disp_info
*next
, *prev
;
49 DOM_SID sid
; /* identify which domain this is. */
50 BOOL builtin_domain
; /* Quick flag to check if this is the builtin domain. */
51 struct pdb_search
*users
; /* querydispinfo 1 and 4 */
52 struct pdb_search
*machines
; /* querydispinfo 2 */
53 struct pdb_search
*groups
; /* querydispinfo 3 and 5, enumgroups */
54 struct pdb_search
*aliases
; /* enumaliases */
57 struct pdb_search
*enum_users
; /* enumusers with a mask */
60 smb_event_id_t di_cache_timeout_event
; /* cache idle timeout handler. */
63 /* We keep a static list of these by SID as modern clients close down
64 all resources between each request in a complete enumeration. */
66 static DISP_INFO
*disp_info_list
;
69 /* for use by the \PIPE\samr policy */
71 BOOL builtin_domain
; /* Quick flag to check if this is the builtin domain. */
72 uint32 status
; /* some sort of flag. best to record it. comes from opnum 0x39 */
78 static struct generic_mapping sam_generic_mapping
= {
79 GENERIC_RIGHTS_SAM_READ
,
80 GENERIC_RIGHTS_SAM_WRITE
,
81 GENERIC_RIGHTS_SAM_EXECUTE
,
82 GENERIC_RIGHTS_SAM_ALL_ACCESS
};
83 static struct generic_mapping dom_generic_mapping
= {
84 GENERIC_RIGHTS_DOMAIN_READ
,
85 GENERIC_RIGHTS_DOMAIN_WRITE
,
86 GENERIC_RIGHTS_DOMAIN_EXECUTE
,
87 GENERIC_RIGHTS_DOMAIN_ALL_ACCESS
};
88 static struct generic_mapping usr_generic_mapping
= {
89 GENERIC_RIGHTS_USER_READ
,
90 GENERIC_RIGHTS_USER_WRITE
,
91 GENERIC_RIGHTS_USER_EXECUTE
,
92 GENERIC_RIGHTS_USER_ALL_ACCESS
};
93 static struct generic_mapping grp_generic_mapping
= {
94 GENERIC_RIGHTS_GROUP_READ
,
95 GENERIC_RIGHTS_GROUP_WRITE
,
96 GENERIC_RIGHTS_GROUP_EXECUTE
,
97 GENERIC_RIGHTS_GROUP_ALL_ACCESS
};
98 static struct generic_mapping ali_generic_mapping
= {
99 GENERIC_RIGHTS_ALIAS_READ
,
100 GENERIC_RIGHTS_ALIAS_WRITE
,
101 GENERIC_RIGHTS_ALIAS_EXECUTE
,
102 GENERIC_RIGHTS_ALIAS_ALL_ACCESS
};
104 /*******************************************************************
105 *******************************************************************/
107 static NTSTATUS
make_samr_object_sd( TALLOC_CTX
*ctx
, SEC_DESC
**psd
, size_t *sd_size
,
108 struct generic_mapping
*map
,
109 DOM_SID
*sid
, uint32 sid_access
)
111 DOM_SID domadmin_sid
;
112 SEC_ACE ace
[5]; /* at most 5 entries */
118 /* basic access for Everyone */
120 init_sec_access(&mask
, map
->generic_execute
| map
->generic_read
);
121 init_sec_ace(&ace
[i
++], &global_sid_World
, SEC_ACE_TYPE_ACCESS_ALLOWED
, mask
, 0);
123 /* add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
125 init_sec_access(&mask
, map
->generic_all
);
127 init_sec_ace(&ace
[i
++], &global_sid_Builtin_Administrators
, SEC_ACE_TYPE_ACCESS_ALLOWED
, mask
, 0);
128 init_sec_ace(&ace
[i
++], &global_sid_Builtin_Account_Operators
, SEC_ACE_TYPE_ACCESS_ALLOWED
, mask
, 0);
130 /* Add Full Access for Domain Admins if we are a DC */
133 sid_copy( &domadmin_sid
, get_global_sam_sid() );
134 sid_append_rid( &domadmin_sid
, DOMAIN_GROUP_RID_ADMINS
);
135 init_sec_ace(&ace
[i
++], &domadmin_sid
, SEC_ACE_TYPE_ACCESS_ALLOWED
, mask
, 0);
138 /* if we have a sid, give it some special access */
141 init_sec_access( &mask
, sid_access
);
142 init_sec_ace(&ace
[i
++], sid
, SEC_ACE_TYPE_ACCESS_ALLOWED
, mask
, 0);
145 /* create the security descriptor */
147 if ((psa
= make_sec_acl(ctx
, NT4_ACL_REVISION
, i
, ace
)) == NULL
)
148 return NT_STATUS_NO_MEMORY
;
150 if ((*psd
= make_sec_desc(ctx
, SEC_DESC_REVISION
, SEC_DESC_SELF_RELATIVE
, NULL
, NULL
, NULL
, psa
, sd_size
)) == NULL
)
151 return NT_STATUS_NO_MEMORY
;
156 /*******************************************************************
157 Checks if access to an object should be granted, and returns that
158 level of access for further checks.
159 ********************************************************************/
161 static NTSTATUS
access_check_samr_object( SEC_DESC
*psd
, NT_USER_TOKEN
*token
,
162 SE_PRIV
*rights
, uint32 rights_mask
,
163 uint32 des_access
, uint32
*acc_granted
,
166 NTSTATUS status
= NT_STATUS_ACCESS_DENIED
;
167 uint32 saved_mask
= 0;
169 /* check privileges; certain SAM access bits should be overridden
170 by privileges (mostly having to do with creating/modifying/deleting
173 if ( rights
&& user_has_any_privilege( token
, rights
) ) {
175 saved_mask
= (des_access
& rights_mask
);
176 des_access
&= ~saved_mask
;
178 DEBUG(4,("access_check_samr_object: user rights access mask [0x%x]\n",
183 /* check the security descriptor first */
185 if ( se_access_check(psd
, token
, des_access
, acc_granted
, &status
) )
188 /* give root a free pass */
190 if ( geteuid() == sec_initial_uid() ) {
192 DEBUG(4,("%s: ACCESS should be DENIED (requested: %#010x)\n", debug
, des_access
));
193 DEBUGADD(4,("but overritten by euid == sec_initial_uid()\n"));
195 *acc_granted
= des_access
;
197 status
= NT_STATUS_OK
;
203 /* add in any bits saved during the privilege check (only
204 matters is status is ok) */
206 *acc_granted
|= rights_mask
;
208 DEBUG(4,("%s: access %s (requested: 0x%08x, granted: 0x%08x)\n",
209 debug
, NT_STATUS_IS_OK(status
) ? "GRANTED" : "DENIED",
210 des_access
, *acc_granted
));
215 /*******************************************************************
216 Checks if access to a function can be granted
217 ********************************************************************/
219 static NTSTATUS
access_check_samr_function(uint32 acc_granted
, uint32 acc_required
, const char *debug
)
221 DEBUG(5,("%s: access check ((granted: %#010x; required: %#010x)\n",
222 debug
, acc_granted
, acc_required
));
224 /* check the security descriptor first */
226 if ( (acc_granted
&acc_required
) == acc_required
)
229 /* give root a free pass */
231 if (geteuid() == sec_initial_uid()) {
233 DEBUG(4,("%s: ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
234 debug
, acc_granted
, acc_required
));
235 DEBUGADD(4,("but overwritten by euid == 0\n"));
240 DEBUG(2,("%s: ACCESS DENIED (granted: %#010x; required: %#010x)\n",
241 debug
, acc_granted
, acc_required
));
243 return NT_STATUS_ACCESS_DENIED
;
246 /*******************************************************************
247 Fetch or create a dispinfo struct.
248 ********************************************************************/
250 static DISP_INFO
*get_samr_dispinfo_by_sid(DOM_SID
*psid
, const char *sid_str
)
255 for (dpi
= disp_info_list
; dpi
; dpi
= dpi
->next
) {
256 if (sid_equal(psid
, &dpi
->sid
)) {
261 /* This struct is never free'd - I'm using talloc so we
262 can get a list out of smbd using smbcontrol. There will
263 be one of these per SID we're authorative for. JRA. */
265 mem_ctx
= talloc_init("DISP_INFO for domain sid %s", sid_str
);
267 if ((dpi
= TALLOC_ZERO_P(mem_ctx
, DISP_INFO
)) == NULL
)
270 dpi
->mem_ctx
= mem_ctx
;
273 sid_copy( &dpi
->sid
, psid
);
274 dpi
->builtin_domain
= sid_check_is_builtin(psid
);
276 dpi
->builtin_domain
= False
;
279 DLIST_ADD(disp_info_list
, dpi
);
284 /*******************************************************************
285 Create a samr_info struct.
286 ********************************************************************/
288 static struct samr_info
*get_samr_info_by_sid(DOM_SID
*psid
)
290 struct samr_info
*info
;
295 sid_to_string(sid_str
, psid
);
297 fstrcpy(sid_str
,"(NULL)");
300 mem_ctx
= talloc_init("samr_info for domain sid %s", sid_str
);
302 if ((info
= TALLOC_ZERO_P(mem_ctx
, struct samr_info
)) == NULL
)
305 DEBUG(10,("get_samr_info_by_sid: created new info for sid %s\n", sid_str
));
307 sid_copy( &info
->sid
, psid
);
308 info
->builtin_domain
= sid_check_is_builtin(psid
);
310 DEBUG(10,("get_samr_info_by_sid: created new info for NULL sid.\n"));
311 info
->builtin_domain
= False
;
313 info
->mem_ctx
= mem_ctx
;
315 info
->disp_info
= get_samr_dispinfo_by_sid(psid
, sid_str
);
317 if (!info
->disp_info
) {
318 talloc_destroy(mem_ctx
);
325 /*******************************************************************
326 Function to free the per SID data.
327 ********************************************************************/
329 static void free_samr_cache(DISP_INFO
*disp_info
, const char *sid_str
)
331 DEBUG(10,("free_samr_cache: deleting cache for SID %s\n", sid_str
));
333 /* We need to become root here because the paged search might have to
334 * tell the LDAP server we're not interested in the rest anymore. */
338 if (disp_info
->users
) {
339 DEBUG(10,("free_samr_cache: deleting users cache\n"));
340 pdb_search_destroy(disp_info
->users
);
341 disp_info
->users
= NULL
;
343 if (disp_info
->machines
) {
344 DEBUG(10,("free_samr_cache: deleting machines cache\n"));
345 pdb_search_destroy(disp_info
->machines
);
346 disp_info
->machines
= NULL
;
348 if (disp_info
->groups
) {
349 DEBUG(10,("free_samr_cache: deleting groups cache\n"));
350 pdb_search_destroy(disp_info
->groups
);
351 disp_info
->groups
= NULL
;
353 if (disp_info
->aliases
) {
354 DEBUG(10,("free_samr_cache: deleting aliases cache\n"));
355 pdb_search_destroy(disp_info
->aliases
);
356 disp_info
->aliases
= NULL
;
358 if (disp_info
->enum_users
) {
359 DEBUG(10,("free_samr_cache: deleting enum_users cache\n"));
360 pdb_search_destroy(disp_info
->enum_users
);
361 disp_info
->enum_users
= NULL
;
363 disp_info
->enum_acb_mask
= 0;
368 /*******************************************************************
369 Function to free the per handle data.
370 ********************************************************************/
372 static void free_samr_info(void *ptr
)
374 struct samr_info
*info
=(struct samr_info
*) ptr
;
376 /* Only free the dispinfo cache if no one bothered to set up
379 if (info
->disp_info
&& info
->disp_info
->di_cache_timeout_event
== (smb_event_id_t
)0) {
381 sid_to_string(sid_str
, &info
->disp_info
->sid
);
382 free_samr_cache(info
->disp_info
, sid_str
);
385 talloc_destroy(info
->mem_ctx
);
388 /*******************************************************************
389 Idle event handler. Throw away the disp info cache.
390 ********************************************************************/
392 static void disp_info_cache_idle_timeout_handler(void **private_data
,
397 DISP_INFO
*disp_info
= (DISP_INFO
*)(*private_data
);
399 sid_to_string(sid_str
, &disp_info
->sid
);
401 free_samr_cache(disp_info
, sid_str
);
403 /* Remove the event. */
404 smb_unregister_idle_event(disp_info
->di_cache_timeout_event
);
405 disp_info
->di_cache_timeout_event
= (smb_event_id_t
)0;
407 DEBUG(10,("disp_info_cache_idle_timeout_handler: caching timed out for SID %s at %u\n",
408 sid_str
, (unsigned int)ev_now
));
411 /*******************************************************************
412 Setup cache removal idle event handler.
413 ********************************************************************/
415 static void set_disp_info_cache_timeout(DISP_INFO
*disp_info
, time_t secs_fromnow
)
419 sid_to_string(sid_str
, &disp_info
->sid
);
421 /* Remove any pending timeout and update. */
423 if (disp_info
->di_cache_timeout_event
) {
424 smb_unregister_idle_event(disp_info
->di_cache_timeout_event
);
425 disp_info
->di_cache_timeout_event
= (smb_event_id_t
)0;
428 DEBUG(10,("set_disp_info_cache_timeout: caching enumeration for SID %s for %u seconds\n",
429 sid_str
, (unsigned int)secs_fromnow
));
431 disp_info
->di_cache_timeout_event
=
432 smb_register_idle_event(disp_info_cache_idle_timeout_handler
,
437 /*******************************************************************
438 Force flush any cache. We do this on any samr_set_xxx call.
439 We must also remove the timeout handler.
440 ********************************************************************/
442 static void force_flush_samr_cache(DISP_INFO
*disp_info
)
447 sid_to_string(sid_str
, &disp_info
->sid
);
448 if (disp_info
->di_cache_timeout_event
) {
449 smb_unregister_idle_event(disp_info
->di_cache_timeout_event
);
450 disp_info
->di_cache_timeout_event
= (smb_event_id_t
)0;
451 DEBUG(10,("force_flush_samr_cache: clearing idle event for SID %s\n",
454 free_samr_cache(disp_info
, sid_str
);
458 /*******************************************************************
459 Ensure password info is never given out. Paranioa... JRA.
460 ********************************************************************/
462 static void samr_clear_sam_passwd(SAM_ACCOUNT
*sam_pass
)
468 /* These now zero out the old password */
470 pdb_set_lanman_passwd(sam_pass
, NULL
, PDB_DEFAULT
);
471 pdb_set_nt_passwd(sam_pass
, NULL
, PDB_DEFAULT
);
474 static uint32
count_sam_users(struct disp_info
*info
, uint16 acct_flags
)
476 struct samr_displayentry
*entry
;
478 if (info
->builtin_domain
) {
479 /* No users in builtin. */
483 if (info
->users
== NULL
) {
484 info
->users
= pdb_search_users(acct_flags
);
485 if (info
->users
== NULL
) {
489 /* Fetch the last possible entry, thus trigger an enumeration */
490 pdb_search_entries(info
->users
, 0xffffffff, 1, &entry
);
492 /* Ensure we cache this enumeration. */
493 set_disp_info_cache_timeout(info
, DISP_INFO_CACHE_TIMEOUT
);
495 return info
->users
->num_entries
;
498 static uint32
count_sam_groups(struct disp_info
*info
)
500 struct samr_displayentry
*entry
;
502 if (info
->builtin_domain
) {
503 /* No groups in builtin. */
507 if (info
->groups
== NULL
) {
508 info
->groups
= pdb_search_groups();
509 if (info
->groups
== NULL
) {
513 /* Fetch the last possible entry, thus trigger an enumeration */
514 pdb_search_entries(info
->groups
, 0xffffffff, 1, &entry
);
516 /* Ensure we cache this enumeration. */
517 set_disp_info_cache_timeout(info
, DISP_INFO_CACHE_TIMEOUT
);
519 return info
->groups
->num_entries
;
522 static uint32
count_sam_aliases(struct disp_info
*info
)
524 struct samr_displayentry
*entry
;
526 if (info
->aliases
== NULL
) {
527 info
->aliases
= pdb_search_aliases(&info
->sid
);
528 if (info
->aliases
== NULL
) {
532 /* Fetch the last possible entry, thus trigger an enumeration */
533 pdb_search_entries(info
->aliases
, 0xffffffff, 1, &entry
);
535 /* Ensure we cache this enumeration. */
536 set_disp_info_cache_timeout(info
, DISP_INFO_CACHE_TIMEOUT
);
538 return info
->aliases
->num_entries
;
541 /*******************************************************************
543 ********************************************************************/
545 NTSTATUS
_samr_close_hnd(pipes_struct
*p
, SAMR_Q_CLOSE_HND
*q_u
, SAMR_R_CLOSE_HND
*r_u
)
547 r_u
->status
= NT_STATUS_OK
;
549 /* close the policy handle */
550 if (!close_policy_hnd(p
, &q_u
->pol
))
551 return NT_STATUS_OBJECT_NAME_INVALID
;
553 DEBUG(5,("samr_reply_close_hnd: %d\n", __LINE__
));
558 /*******************************************************************
559 samr_reply_open_domain
560 ********************************************************************/
562 NTSTATUS
_samr_open_domain(pipes_struct
*p
, SAMR_Q_OPEN_DOMAIN
*q_u
, SAMR_R_OPEN_DOMAIN
*r_u
)
564 struct samr_info
*info
;
565 SEC_DESC
*psd
= NULL
;
567 uint32 des_access
= q_u
->flags
;
572 r_u
->status
= NT_STATUS_OK
;
574 /* find the connection policy handle. */
576 if ( !find_policy_by_hnd(p
, &q_u
->pol
, (void**)(void *)&info
) )
577 return NT_STATUS_INVALID_HANDLE
;
579 status
= access_check_samr_function( info
->acc_granted
,
580 SA_RIGHT_SAM_OPEN_DOMAIN
, "_samr_open_domain" );
582 if ( !NT_STATUS_IS_OK(status
) )
585 /*check if access can be granted as requested by client. */
587 make_samr_object_sd( p
->mem_ctx
, &psd
, &sd_size
, &dom_generic_mapping
, NULL
, 0 );
588 se_map_generic( &des_access
, &dom_generic_mapping
);
590 se_priv_copy( &se_rights
, &se_machine_account
);
591 se_priv_add( &se_rights
, &se_add_users
);
593 status
= access_check_samr_object( psd
, p
->pipe_user
.nt_user_token
,
594 &se_rights
, GENERIC_RIGHTS_DOMAIN_WRITE
, des_access
,
595 &acc_granted
, "_samr_open_domain" );
597 if ( !NT_STATUS_IS_OK(status
) )
600 if (!sid_check_is_domain(&q_u
->dom_sid
.sid
) &&
601 !sid_check_is_builtin(&q_u
->dom_sid
.sid
)) {
602 return NT_STATUS_NO_SUCH_DOMAIN
;
605 /* associate the domain SID with the (unique) handle. */
606 if ((info
= get_samr_info_by_sid(&q_u
->dom_sid
.sid
))==NULL
)
607 return NT_STATUS_NO_MEMORY
;
608 info
->acc_granted
= acc_granted
;
610 /* get a (unique) handle. open a policy on it. */
611 if (!create_policy_hnd(p
, &r_u
->domain_pol
, free_samr_info
, (void *)info
))
612 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
614 DEBUG(5,("samr_open_domain: %d\n", __LINE__
));
619 /*******************************************************************
620 _samr_get_usrdom_pwinfo
621 ********************************************************************/
623 NTSTATUS
_samr_get_usrdom_pwinfo(pipes_struct
*p
, SAMR_Q_GET_USRDOM_PWINFO
*q_u
, SAMR_R_GET_USRDOM_PWINFO
*r_u
)
625 struct samr_info
*info
= NULL
;
627 r_u
->status
= NT_STATUS_OK
;
629 /* find the policy handle. open a policy on it. */
630 if (!find_policy_by_hnd(p
, &q_u
->user_pol
, (void **)(void *)&info
))
631 return NT_STATUS_INVALID_HANDLE
;
633 if (!sid_check_is_in_our_domain(&info
->sid
))
634 return NT_STATUS_OBJECT_TYPE_MISMATCH
;
636 init_samr_r_get_usrdom_pwinfo(r_u
, NT_STATUS_OK
);
638 DEBUG(5,("_samr_get_usrdom_pwinfo: %d\n", __LINE__
));
641 * NT sometimes return NT_STATUS_ACCESS_DENIED
642 * I don't know yet why.
648 /*******************************************************************
650 ********************************************************************/
652 NTSTATUS
_samr_set_sec_obj(pipes_struct
*p
, SAMR_Q_SET_SEC_OBJ
*q_u
, SAMR_R_SET_SEC_OBJ
*r_u
)
654 DEBUG(0,("_samr_set_sec_obj: Not yet implemented!\n"));
655 return NT_STATUS_NOT_IMPLEMENTED
;
658 /*******************************************************************
659 ********************************************************************/
661 static BOOL
get_lsa_policy_samr_sid( pipes_struct
*p
, POLICY_HND
*pol
,
662 DOM_SID
*sid
, uint32
*acc_granted
,
663 DISP_INFO
**ppdisp_info
)
665 struct samr_info
*info
= NULL
;
667 /* find the policy handle. open a policy on it. */
668 if (!find_policy_by_hnd(p
, pol
, (void **)(void *)&info
))
675 *acc_granted
= info
->acc_granted
;
677 *ppdisp_info
= info
->disp_info
;
683 /*******************************************************************
685 ********************************************************************/
687 NTSTATUS
_samr_query_sec_obj(pipes_struct
*p
, SAMR_Q_QUERY_SEC_OBJ
*q_u
, SAMR_R_QUERY_SEC_OBJ
*r_u
)
691 SEC_DESC
* psd
= NULL
;
695 r_u
->status
= NT_STATUS_OK
;
698 if (!get_lsa_policy_samr_sid(p
, &q_u
->user_pol
, &pol_sid
, &acc_granted
, NULL
))
699 return NT_STATUS_INVALID_HANDLE
;
701 DEBUG(10,("_samr_query_sec_obj: querying security on SID: %s\n", sid_to_string(str_sid
, &pol_sid
)));
703 /* Check what typ of SID is beeing queried (e.g Domain SID, User SID, Group SID) */
705 /* To query the security of the SAM it self an invalid SID with S-0-0 is passed to this function */
706 if (pol_sid
.sid_rev_num
== 0) {
707 DEBUG(5,("_samr_query_sec_obj: querying security on SAM\n"));
708 r_u
->status
= make_samr_object_sd(p
->mem_ctx
, &psd
, &sd_size
, &sam_generic_mapping
, NULL
, 0);
709 } else if (sid_equal(&pol_sid
,get_global_sam_sid())) {
710 /* check if it is our domain SID */
711 DEBUG(5,("_samr_query_sec_obj: querying security on Domain with SID: %s\n", sid_to_string(str_sid
, &pol_sid
)));
712 r_u
->status
= make_samr_object_sd(p
->mem_ctx
, &psd
, &sd_size
, &dom_generic_mapping
, NULL
, 0);
713 } else if (sid_equal(&pol_sid
,&global_sid_Builtin
)) {
714 /* check if it is the Builtin Domain */
715 /* TODO: Builtin probably needs a different SD with restricted write access*/
716 DEBUG(5,("_samr_query_sec_obj: querying security on Builtin Domain with SID: %s\n", sid_to_string(str_sid
, &pol_sid
)));
717 r_u
->status
= make_samr_object_sd(p
->mem_ctx
, &psd
, &sd_size
, &dom_generic_mapping
, NULL
, 0);
718 } else if (sid_check_is_in_our_domain(&pol_sid
) ||
719 sid_check_is_in_builtin(&pol_sid
)) {
720 /* TODO: different SDs have to be generated for aliases groups and users.
721 Currently all three get a default user SD */
722 DEBUG(10,("_samr_query_sec_obj: querying security on Object with SID: %s\n", sid_to_string(str_sid
, &pol_sid
)));
723 r_u
->status
= make_samr_object_sd(p
->mem_ctx
, &psd
, &sd_size
, &usr_generic_mapping
, &pol_sid
, SAMR_USR_RIGHTS_WRITE_PW
);
725 return NT_STATUS_OBJECT_TYPE_MISMATCH
;
728 if ((r_u
->buf
= make_sec_desc_buf(p
->mem_ctx
, sd_size
, psd
)) == NULL
)
729 return NT_STATUS_NO_MEMORY
;
731 if (NT_STATUS_IS_OK(r_u
->status
))
737 /*******************************************************************
738 makes a SAM_ENTRY / UNISTR2* structure from a user list.
739 ********************************************************************/
741 static NTSTATUS
make_user_sam_entry_list(TALLOC_CTX
*ctx
, SAM_ENTRY
**sam_pp
,
742 UNISTR2
**uni_name_pp
,
743 uint32 num_entries
, uint32 start_idx
,
744 struct samr_displayentry
*entries
)
753 if (num_entries
== 0)
756 sam
= TALLOC_ZERO_ARRAY(ctx
, SAM_ENTRY
, num_entries
);
758 uni_name
= TALLOC_ZERO_ARRAY(ctx
, UNISTR2
, num_entries
);
760 if (sam
== NULL
|| uni_name
== NULL
) {
761 DEBUG(0, ("make_user_sam_entry_list: talloc_zero failed!\n"));
762 return NT_STATUS_NO_MEMORY
;
765 for (i
= 0; i
< num_entries
; i
++) {
766 UNISTR2 uni_temp_name
;
768 * usrmgr expects a non-NULL terminated string with
769 * trust relationships
771 if (entries
[i
].acct_flags
& ACB_DOMTRUST
) {
772 init_unistr2(&uni_temp_name
, entries
[i
].account_name
,
775 init_unistr2(&uni_temp_name
, entries
[i
].account_name
,
779 init_sam_entry(&sam
[i
], &uni_temp_name
, entries
[i
].rid
);
780 copy_unistr2(&uni_name
[i
], &uni_temp_name
);
784 *uni_name_pp
= uni_name
;
788 /*******************************************************************
789 samr_reply_enum_dom_users
790 ********************************************************************/
792 NTSTATUS
_samr_enum_dom_users(pipes_struct
*p
, SAMR_Q_ENUM_DOM_USERS
*q_u
,
793 SAMR_R_ENUM_DOM_USERS
*r_u
)
795 struct samr_info
*info
= NULL
;
797 uint32 enum_context
=q_u
->start_idx
;
798 enum remote_arch_types ra_type
= get_remote_arch();
799 int max_sam_entries
= (ra_type
== RA_WIN95
) ? MAX_SAM_ENTRIES_W95
: MAX_SAM_ENTRIES_W2K
;
800 uint32 max_entries
= max_sam_entries
;
801 struct samr_displayentry
*entries
= NULL
;
803 r_u
->status
= NT_STATUS_OK
;
805 /* find the policy handle. open a policy on it. */
806 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)(void *)&info
))
807 return NT_STATUS_INVALID_HANDLE
;
809 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(info
->acc_granted
,
810 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS
,
811 "_samr_enum_dom_users"))) {
815 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__
));
817 if (info
->builtin_domain
) {
818 /* No users in builtin. */
819 init_samr_r_enum_dom_users(r_u
, q_u
->start_idx
, 0);
820 DEBUG(5,("_samr_enum_dom_users: No users in BUILTIN\n"));
828 if ((info
->disp_info
->enum_users
!= NULL
) &&
829 (info
->disp_info
->enum_acb_mask
!= q_u
->acb_mask
)) {
830 pdb_search_destroy(info
->disp_info
->enum_users
);
831 info
->disp_info
->enum_users
= NULL
;
834 if (info
->disp_info
->enum_users
== NULL
) {
835 info
->disp_info
->enum_users
= pdb_search_users(q_u
->acb_mask
);
836 info
->disp_info
->enum_acb_mask
= q_u
->acb_mask
;
839 if (info
->disp_info
->enum_users
== NULL
) {
840 /* END AS ROOT !!!! */
842 return NT_STATUS_ACCESS_DENIED
;
845 num_account
= pdb_search_entries(info
->disp_info
->enum_users
,
846 enum_context
, max_entries
,
849 /* END AS ROOT !!!! */
853 if (num_account
== 0) {
854 DEBUG(5, ("_samr_enum_dom_users: enumeration handle over "
859 r_u
->status
= make_user_sam_entry_list(p
->mem_ctx
, &r_u
->sam
,
861 num_account
, enum_context
,
864 if (!NT_STATUS_IS_OK(r_u
->status
))
867 if (max_entries
<= num_account
) {
868 r_u
->status
= STATUS_MORE_ENTRIES
;
870 r_u
->status
= NT_STATUS_OK
;
873 /* Ensure we cache this enumeration. */
874 set_disp_info_cache_timeout(info
->disp_info
, DISP_INFO_CACHE_TIMEOUT
);
876 DEBUG(5, ("_samr_enum_dom_users: %d\n", __LINE__
));
878 init_samr_r_enum_dom_users(r_u
, q_u
->start_idx
+ num_account
,
881 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__
));
886 /*******************************************************************
887 makes a SAM_ENTRY / UNISTR2* structure from a group list.
888 ********************************************************************/
890 static void make_group_sam_entry_list(TALLOC_CTX
*ctx
, SAM_ENTRY
**sam_pp
,
891 UNISTR2
**uni_name_pp
,
892 uint32 num_sam_entries
,
893 struct samr_displayentry
*entries
)
902 if (num_sam_entries
== 0)
905 sam
= TALLOC_ZERO_ARRAY(ctx
, SAM_ENTRY
, num_sam_entries
);
906 uni_name
= TALLOC_ZERO_ARRAY(ctx
, UNISTR2
, num_sam_entries
);
908 if (sam
== NULL
|| uni_name
== NULL
) {
909 DEBUG(0, ("NULL pointers in SAMR_R_QUERY_DISPINFO\n"));
913 for (i
= 0; i
< num_sam_entries
; i
++) {
915 * JRA. I think this should include the null. TNG does not.
917 init_unistr2(&uni_name
[i
], entries
[i
].account_name
,
919 init_sam_entry(&sam
[i
], &uni_name
[i
], entries
[i
].rid
);
923 *uni_name_pp
= uni_name
;
926 /*******************************************************************
927 samr_reply_enum_dom_groups
928 ********************************************************************/
930 NTSTATUS
_samr_enum_dom_groups(pipes_struct
*p
, SAMR_Q_ENUM_DOM_GROUPS
*q_u
, SAMR_R_ENUM_DOM_GROUPS
*r_u
)
932 struct samr_info
*info
= NULL
;
933 struct samr_displayentry
*groups
;
936 r_u
->status
= NT_STATUS_OK
;
938 /* find the policy handle. open a policy on it. */
939 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)(void *)&info
))
940 return NT_STATUS_INVALID_HANDLE
;
942 r_u
->status
= access_check_samr_function(info
->acc_granted
,
943 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS
,
944 "_samr_enum_dom_groups");
945 if (!NT_STATUS_IS_OK(r_u
->status
))
948 DEBUG(5,("samr_reply_enum_dom_groups: %d\n", __LINE__
));
950 if (info
->builtin_domain
) {
951 /* No groups in builtin. */
952 init_samr_r_enum_dom_groups(r_u
, q_u
->start_idx
, 0);
953 DEBUG(5,("_samr_enum_dom_users: No groups in BUILTIN\n"));
957 /* the domain group array is being allocated in the function below */
961 if (info
->disp_info
->groups
== NULL
) {
962 info
->disp_info
->groups
= pdb_search_groups();
964 if (info
->disp_info
->groups
== NULL
) {
966 return NT_STATUS_ACCESS_DENIED
;
970 num_groups
= pdb_search_entries(info
->disp_info
->groups
, q_u
->start_idx
,
971 MAX_SAM_ENTRIES
, &groups
);
974 /* Ensure we cache this enumeration. */
975 set_disp_info_cache_timeout(info
->disp_info
, DISP_INFO_CACHE_TIMEOUT
);
977 make_group_sam_entry_list(p
->mem_ctx
, &r_u
->sam
, &r_u
->uni_grp_name
,
980 init_samr_r_enum_dom_groups(r_u
, q_u
->start_idx
, num_groups
);
982 DEBUG(5,("samr_enum_dom_groups: %d\n", __LINE__
));
987 /*******************************************************************
988 samr_reply_enum_dom_aliases
989 ********************************************************************/
991 NTSTATUS
_samr_enum_dom_aliases(pipes_struct
*p
, SAMR_Q_ENUM_DOM_ALIASES
*q_u
, SAMR_R_ENUM_DOM_ALIASES
*r_u
)
993 struct samr_info
*info
;
994 struct samr_displayentry
*aliases
;
995 uint32 num_aliases
= 0;
997 /* find the policy handle. open a policy on it. */
998 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)(void *)&info
))
999 return NT_STATUS_INVALID_HANDLE
;
1001 r_u
->status
= access_check_samr_function(info
->acc_granted
,
1002 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS
,
1003 "_samr_enum_dom_aliases");
1004 if (!NT_STATUS_IS_OK(r_u
->status
))
1007 DEBUG(5,("samr_reply_enum_dom_aliases: sid %s\n",
1008 sid_string_static(&info
->sid
)));
1012 if (info
->disp_info
->aliases
== NULL
) {
1013 info
->disp_info
->aliases
= pdb_search_aliases(&info
->sid
);
1014 if (info
->disp_info
->aliases
== NULL
) {
1016 return NT_STATUS_ACCESS_DENIED
;
1020 num_aliases
= pdb_search_entries(info
->disp_info
->aliases
, q_u
->start_idx
,
1021 MAX_SAM_ENTRIES
, &aliases
);
1024 /* Ensure we cache this enumeration. */
1025 set_disp_info_cache_timeout(info
->disp_info
, DISP_INFO_CACHE_TIMEOUT
);
1027 make_group_sam_entry_list(p
->mem_ctx
, &r_u
->sam
, &r_u
->uni_grp_name
,
1028 num_aliases
, aliases
);
1030 init_samr_r_enum_dom_aliases(r_u
, q_u
->start_idx
+ num_aliases
,
1033 DEBUG(5,("samr_enum_dom_aliases: %d\n", __LINE__
));
1038 /*******************************************************************
1039 samr_reply_query_dispinfo
1040 ********************************************************************/
1042 NTSTATUS
_samr_query_dispinfo(pipes_struct
*p
, SAMR_Q_QUERY_DISPINFO
*q_u
,
1043 SAMR_R_QUERY_DISPINFO
*r_u
)
1045 struct samr_info
*info
= NULL
;
1046 uint32 struct_size
=0x20; /* W2K always reply that, client doesn't care */
1048 uint32 max_entries
=q_u
->max_entries
;
1049 uint32 enum_context
=q_u
->start_idx
;
1050 uint32 max_size
=q_u
->max_size
;
1052 SAM_DISPINFO_CTR
*ctr
;
1053 uint32 temp_size
=0, total_data_size
=0;
1054 NTSTATUS disp_ret
= NT_STATUS_UNSUCCESSFUL
;
1055 uint32 num_account
= 0;
1056 enum remote_arch_types ra_type
= get_remote_arch();
1057 int max_sam_entries
= (ra_type
== RA_WIN95
) ? MAX_SAM_ENTRIES_W95
: MAX_SAM_ENTRIES_W2K
;
1058 struct samr_displayentry
*entries
= NULL
;
1060 DEBUG(5, ("samr_reply_query_dispinfo: %d\n", __LINE__
));
1061 r_u
->status
= NT_STATUS_UNSUCCESSFUL
;
1063 /* find the policy handle. open a policy on it. */
1064 if (!find_policy_by_hnd(p
, &q_u
->domain_pol
, (void **)(void *)&info
))
1065 return NT_STATUS_INVALID_HANDLE
;
1068 * calculate how many entries we will return.
1070 * - the number of entries the client asked
1071 * - our limit on that
1072 * - the starting point (enumeration context)
1073 * - the buffer size the client will accept
1077 * We are a lot more like W2K. Instead of reading the SAM
1078 * each time to find the records we need to send back,
1079 * we read it once and link that copy to the sam handle.
1080 * For large user list (over the MAX_SAM_ENTRIES)
1081 * it's a definitive win.
1082 * second point to notice: between enumerations
1083 * our sam is now the same as it's a snapshoot.
1084 * third point: got rid of the static SAM_USER_21 struct
1085 * no more intermediate.
1086 * con: it uses much more memory, as a full copy is stored
1089 * If you want to change it, think twice and think
1090 * of the second point , that's really important.
1095 if ((q_u
->switch_level
< 1) || (q_u
->switch_level
> 5)) {
1096 DEBUG(0,("_samr_query_dispinfo: Unknown info level (%u)\n",
1097 (unsigned int)q_u
->switch_level
));
1098 return NT_STATUS_INVALID_INFO_CLASS
;
1101 /* first limit the number of entries we will return */
1102 if(max_entries
> max_sam_entries
) {
1103 DEBUG(5, ("samr_reply_query_dispinfo: client requested %d "
1104 "entries, limiting to %d\n", max_entries
,
1106 max_entries
= max_sam_entries
;
1109 /* calculate the size and limit on the number of entries we will
1112 temp_size
=max_entries
*struct_size
;
1114 if (temp_size
>max_size
) {
1115 max_entries
=MIN((max_size
/struct_size
),max_entries
);;
1116 DEBUG(5, ("samr_reply_query_dispinfo: buffer size limits to "
1117 "only %d entries\n", max_entries
));
1120 if (!(ctr
= TALLOC_ZERO_P(p
->mem_ctx
,SAM_DISPINFO_CTR
)))
1121 return NT_STATUS_NO_MEMORY
;
1127 /* THe following done as ROOT. Don't return without unbecome_root(). */
1129 switch (q_u
->switch_level
) {
1132 if (info
->disp_info
->users
== NULL
) {
1133 info
->disp_info
->users
= pdb_search_users(ACB_NORMAL
);
1134 if (info
->disp_info
->users
== NULL
) {
1136 return NT_STATUS_ACCESS_DENIED
;
1138 DEBUG(10,("samr_reply_query_dispinfo: starting user enumeration at index %u\n",
1139 (unsigned int)enum_context
));
1141 DEBUG(10,("samr_reply_query_dispinfo: using cached user enumeration at index %u\n",
1142 (unsigned int)enum_context
));
1145 num_account
= pdb_search_entries(info
->disp_info
->users
,
1146 enum_context
, max_entries
,
1150 if (info
->disp_info
->machines
== NULL
) {
1151 info
->disp_info
->machines
=
1152 pdb_search_users(ACB_WSTRUST
|ACB_SVRTRUST
);
1153 if (info
->disp_info
->machines
== NULL
) {
1155 return NT_STATUS_ACCESS_DENIED
;
1157 DEBUG(10,("samr_reply_query_dispinfo: starting machine enumeration at index %u\n",
1158 (unsigned int)enum_context
));
1160 DEBUG(10,("samr_reply_query_dispinfo: using cached machine enumeration at index %u\n",
1161 (unsigned int)enum_context
));
1164 num_account
= pdb_search_entries(info
->disp_info
->machines
,
1165 enum_context
, max_entries
,
1170 if (info
->disp_info
->groups
== NULL
) {
1171 info
->disp_info
->groups
= pdb_search_groups();
1172 if (info
->disp_info
->groups
== NULL
) {
1174 return NT_STATUS_ACCESS_DENIED
;
1176 DEBUG(10,("samr_reply_query_dispinfo: starting group enumeration at index %u\n",
1177 (unsigned int)enum_context
));
1179 DEBUG(10,("samr_reply_query_dispinfo: using cached group enumeration at index %u\n",
1180 (unsigned int)enum_context
));
1183 num_account
= pdb_search_entries(info
->disp_info
->groups
,
1184 enum_context
, max_entries
,
1189 smb_panic("info class changed");
1194 /* Now create reply structure */
1195 switch (q_u
->switch_level
) {
1197 disp_ret
= init_sam_dispinfo_1(p
->mem_ctx
, &ctr
->sam
.info1
,
1198 num_account
, enum_context
,
1202 disp_ret
= init_sam_dispinfo_2(p
->mem_ctx
, &ctr
->sam
.info2
,
1203 num_account
, enum_context
,
1207 disp_ret
= init_sam_dispinfo_3(p
->mem_ctx
, &ctr
->sam
.info3
,
1208 num_account
, enum_context
,
1212 disp_ret
= init_sam_dispinfo_4(p
->mem_ctx
, &ctr
->sam
.info4
,
1213 num_account
, enum_context
,
1217 disp_ret
= init_sam_dispinfo_5(p
->mem_ctx
, &ctr
->sam
.info5
,
1218 num_account
, enum_context
,
1222 smb_panic("info class changed");
1226 if (!NT_STATUS_IS_OK(disp_ret
))
1229 /* calculate the total size */
1230 total_data_size
=num_account
*struct_size
;
1233 r_u
->status
= STATUS_MORE_ENTRIES
;
1235 r_u
->status
= NT_STATUS_OK
;
1238 /* Ensure we cache this enumeration. */
1239 set_disp_info_cache_timeout(info
->disp_info
, DISP_INFO_CACHE_TIMEOUT
);
1241 DEBUG(5, ("_samr_query_dispinfo: %d\n", __LINE__
));
1243 init_samr_r_query_dispinfo(r_u
, num_account
, total_data_size
,
1244 temp_size
, q_u
->switch_level
, ctr
,
1251 /*******************************************************************
1252 samr_reply_query_aliasinfo
1253 ********************************************************************/
1255 NTSTATUS
_samr_query_aliasinfo(pipes_struct
*p
, SAMR_Q_QUERY_ALIASINFO
*q_u
, SAMR_R_QUERY_ALIASINFO
*r_u
)
1258 struct acct_info info
;
1262 r_u
->status
= NT_STATUS_OK
;
1264 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__
));
1266 /* find the policy handle. open a policy on it. */
1267 if (!get_lsa_policy_samr_sid(p
, &q_u
->pol
, &sid
, &acc_granted
, NULL
))
1268 return NT_STATUS_INVALID_HANDLE
;
1269 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, SA_RIGHT_ALIAS_LOOKUP_INFO
, "_samr_query_aliasinfo"))) {
1274 ret
= pdb_get_aliasinfo(&sid
, &info
);
1278 return NT_STATUS_NO_SUCH_ALIAS
;
1280 if ( !(r_u
->ctr
= TALLOC_ZERO_P( p
->mem_ctx
, ALIAS_INFO_CTR
)) )
1281 return NT_STATUS_NO_MEMORY
;
1284 switch (q_u
->level
) {
1286 r_u
->ctr
->level
= 1;
1287 init_samr_alias_info1(&r_u
->ctr
->alias
.info1
, info
.acct_name
, 1, info
.acct_desc
);
1290 r_u
->ctr
->level
= 3;
1291 init_samr_alias_info3(&r_u
->ctr
->alias
.info3
, info
.acct_desc
);
1294 return NT_STATUS_INVALID_INFO_CLASS
;
1297 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__
));
1303 /*******************************************************************
1304 samr_reply_lookup_ids
1305 ********************************************************************/
1307 uint32
_samr_lookup_ids(pipes_struct
*p
, SAMR_Q_LOOKUP_IDS
*q_u
, SAMR_R_LOOKUP_IDS
*r_u
)
1309 uint32 rid
[MAX_SAM_ENTRIES
];
1310 int num_rids
= q_u
->num_sids1
;
1312 r_u
->status
= NT_STATUS_OK
;
1314 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__
));
1316 if (num_rids
> MAX_SAM_ENTRIES
) {
1317 num_rids
= MAX_SAM_ENTRIES
;
1318 DEBUG(5,("_samr_lookup_ids: truncating entries to %d\n", num_rids
));
1323 SMB_ASSERT_ARRAY(q_u
->uni_user_name
, num_rids
);
1325 for (i
= 0; i
< num_rids
&& status
== 0; i
++)
1327 struct sam_passwd
*sam_pass
;
1331 fstrcpy(user_name
, unistrn2(q_u
->uni_user_name
[i
].buffer
,
1332 q_u
->uni_user_name
[i
].uni_str_len
));
1334 /* find the user account */
1336 sam_pass
= get_smb21pwd_entry(user_name
, 0);
1339 if (sam_pass
== NULL
)
1341 status
= 0xC0000000 | NT_STATUS_NO_SUCH_USER
;
1346 rid
[i
] = sam_pass
->user_rid
;
1352 rid
[0] = BUILTIN_ALIAS_RID_USERS
;
1354 init_samr_r_lookup_ids(&r_u
, num_rids
, rid
, NT_STATUS_OK
);
1356 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__
));
1362 /*******************************************************************
1364 ********************************************************************/
1366 NTSTATUS
_samr_lookup_names(pipes_struct
*p
, SAMR_Q_LOOKUP_NAMES
*q_u
, SAMR_R_LOOKUP_NAMES
*r_u
)
1368 uint32 rid
[MAX_SAM_ENTRIES
];
1369 enum SID_NAME_USE type
[MAX_SAM_ENTRIES
];
1371 int num_rids
= q_u
->num_names2
;
1376 r_u
->status
= NT_STATUS_OK
;
1378 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__
));
1383 if (!get_lsa_policy_samr_sid(p
, &q_u
->pol
, &pol_sid
, &acc_granted
, NULL
)) {
1384 init_samr_r_lookup_names(p
->mem_ctx
, r_u
, 0, NULL
, NULL
, NT_STATUS_OBJECT_TYPE_MISMATCH
);
1388 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, 0, "_samr_lookup_names"))) { /* Don't know the acc_bits yet */
1392 if (num_rids
> MAX_SAM_ENTRIES
) {
1393 num_rids
= MAX_SAM_ENTRIES
;
1394 DEBUG(5,("_samr_lookup_names: truncating entries to %d\n", num_rids
));
1397 DEBUG(5,("_samr_lookup_names: looking name on SID %s\n", sid_to_string(sid_str
, &pol_sid
)));
1399 for (i
= 0; i
< num_rids
; i
++) {
1403 r_u
->status
= NT_STATUS_NONE_MAPPED
;
1404 type
[i
] = SID_NAME_UNKNOWN
;
1406 rid
[i
] = 0xffffffff;
1408 ret
= rpcstr_pull(name
, q_u
->uni_name
[i
].buffer
, sizeof(name
), q_u
->uni_name
[i
].uni_str_len
*2, 0);
1414 if (sid_check_is_builtin(&pol_sid
)) {
1415 if (lookup_builtin_name(name
, &rid
[i
])) {
1416 type
[i
] = SID_NAME_ALIAS
;
1419 lookup_global_sam_name(name
, 0, &rid
[i
], &type
[i
]);
1422 if (type
[i
] != SID_NAME_UNKNOWN
) {
1423 r_u
->status
= NT_STATUS_OK
;
1427 init_samr_r_lookup_names(p
->mem_ctx
, r_u
, num_rids
, rid
, (uint32
*)type
, r_u
->status
);
1429 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__
));
1434 /*******************************************************************
1435 _samr_chgpasswd_user
1436 ********************************************************************/
1438 NTSTATUS
_samr_chgpasswd_user(pipes_struct
*p
, SAMR_Q_CHGPASSWD_USER
*q_u
, SAMR_R_CHGPASSWD_USER
*r_u
)
1443 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__
));
1445 r_u
->status
= NT_STATUS_OK
;
1447 rpcstr_pull(user_name
, q_u
->uni_user_name
.buffer
, sizeof(user_name
), q_u
->uni_user_name
.uni_str_len
*2, 0);
1448 rpcstr_pull(wks
, q_u
->uni_dest_host
.buffer
, sizeof(wks
), q_u
->uni_dest_host
.uni_str_len
*2,0);
1450 DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name
, wks
));
1453 * Pass the user through the NT -> unix user mapping
1457 (void)map_username(user_name
);
1460 * UNIX username case mangling not required, pass_oem_change
1461 * is case insensitive.
1464 r_u
->status
= pass_oem_change(user_name
, q_u
->lm_newpass
.pass
, q_u
->lm_oldhash
.hash
,
1465 q_u
->nt_newpass
.pass
, q_u
->nt_oldhash
.hash
, NULL
);
1467 init_samr_r_chgpasswd_user(r_u
, r_u
->status
);
1469 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__
));
1474 /*******************************************************************
1475 _samr_chgpasswd_user3
1476 ********************************************************************/
1478 NTSTATUS
_samr_chgpasswd_user3(pipes_struct
*p
, SAMR_Q_CHGPASSWD_USER3
*q_u
, SAMR_R_CHGPASSWD_USER3
*r_u
)
1482 uint32 reject_reason
;
1483 SAM_UNK_INFO_1
*info
= NULL
;
1484 SAMR_CHANGE_REJECT
*reject
= NULL
;
1486 DEBUG(5,("_samr_chgpasswd_user3: %d\n", __LINE__
));
1488 rpcstr_pull(user_name
, q_u
->uni_user_name
.buffer
, sizeof(user_name
), q_u
->uni_user_name
.uni_str_len
*2, 0);
1489 rpcstr_pull(wks
, q_u
->uni_dest_host
.buffer
, sizeof(wks
), q_u
->uni_dest_host
.uni_str_len
*2,0);
1491 DEBUG(5,("_samr_chgpasswd_user3: user: %s wks: %s\n", user_name
, wks
));
1494 * Pass the user through the NT -> unix user mapping
1498 (void)map_username(user_name
);
1501 * UNIX username case mangling not required, pass_oem_change
1502 * is case insensitive.
1505 r_u
->status
= pass_oem_change(user_name
, q_u
->lm_newpass
.pass
, q_u
->lm_oldhash
.hash
,
1506 q_u
->nt_newpass
.pass
, q_u
->nt_oldhash
.hash
, &reject_reason
);
1508 if (NT_STATUS_EQUAL(r_u
->status
, NT_STATUS_PASSWORD_RESTRICTION
) ||
1509 NT_STATUS_EQUAL(r_u
->status
, NT_STATUS_ACCOUNT_RESTRICTION
)) {
1511 uint32 min_pass_len
,pass_hist
,password_properties
;
1512 time_t u_expire
, u_min_age
;
1513 NTTIME nt_expire
, nt_min_age
;
1514 uint32 account_policy_temp
;
1516 if ((info
= TALLOC_ZERO_P(p
->mem_ctx
, SAM_UNK_INFO_1
)) == NULL
) {
1517 return NT_STATUS_NO_MEMORY
;
1520 if ((reject
= TALLOC_ZERO_P(p
->mem_ctx
, SAMR_CHANGE_REJECT
)) == NULL
) {
1521 return NT_STATUS_NO_MEMORY
;
1525 ZERO_STRUCTP(reject
);
1531 pdb_get_account_policy(AP_MIN_PASSWORD_LEN
, &account_policy_temp
);
1532 min_pass_len
= account_policy_temp
;
1534 pdb_get_account_policy(AP_PASSWORD_HISTORY
, &account_policy_temp
);
1535 pass_hist
= account_policy_temp
;
1537 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS
, &account_policy_temp
);
1538 password_properties
= account_policy_temp
;
1540 pdb_get_account_policy(AP_MAX_PASSWORD_AGE
, &account_policy_temp
);
1541 u_expire
= account_policy_temp
;
1543 pdb_get_account_policy(AP_MIN_PASSWORD_AGE
, &account_policy_temp
);
1544 u_min_age
= account_policy_temp
;
1550 unix_to_nt_time_abs(&nt_expire
, u_expire
);
1551 unix_to_nt_time_abs(&nt_min_age
, u_min_age
);
1553 init_unk_info1(info
, (uint16
)min_pass_len
, (uint16
)pass_hist
,
1554 password_properties
, nt_expire
, nt_min_age
);
1556 reject
->reject_reason
= reject_reason
;
1559 init_samr_r_chgpasswd_user3(r_u
, r_u
->status
, reject
, info
);
1561 DEBUG(5,("_samr_chgpasswd_user3: %d\n", __LINE__
));
1566 /*******************************************************************
1567 makes a SAMR_R_LOOKUP_RIDS structure.
1568 ********************************************************************/
1570 static BOOL
make_samr_lookup_rids(TALLOC_CTX
*ctx
, uint32 num_names
,
1571 const char **names
, UNIHDR
**pp_hdr_name
,
1572 UNISTR2
**pp_uni_name
)
1575 UNIHDR
*hdr_name
=NULL
;
1576 UNISTR2
*uni_name
=NULL
;
1578 *pp_uni_name
= NULL
;
1579 *pp_hdr_name
= NULL
;
1581 if (num_names
!= 0) {
1582 hdr_name
= TALLOC_ZERO_ARRAY(ctx
, UNIHDR
, num_names
);
1583 if (hdr_name
== NULL
)
1586 uni_name
= TALLOC_ZERO_ARRAY(ctx
,UNISTR2
, num_names
);
1587 if (uni_name
== NULL
)
1591 for (i
= 0; i
< num_names
; i
++) {
1592 DEBUG(10, ("names[%d]:%s\n", i
, names
[i
] && *names
[i
] ? names
[i
] : ""));
1593 init_unistr2(&uni_name
[i
], names
[i
], UNI_FLAGS_NONE
);
1594 init_uni_hdr(&hdr_name
[i
], &uni_name
[i
]);
1597 *pp_uni_name
= uni_name
;
1598 *pp_hdr_name
= hdr_name
;
1603 /*******************************************************************
1605 ********************************************************************/
1607 NTSTATUS
_samr_lookup_rids(pipes_struct
*p
, SAMR_Q_LOOKUP_RIDS
*q_u
, SAMR_R_LOOKUP_RIDS
*r_u
)
1610 uint32
*attrs
= NULL
;
1611 UNIHDR
*hdr_name
= NULL
;
1612 UNISTR2
*uni_name
= NULL
;
1614 int num_rids
= q_u
->num_rids1
;
1617 r_u
->status
= NT_STATUS_OK
;
1619 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__
));
1621 /* find the policy handle. open a policy on it. */
1622 if (!get_lsa_policy_samr_sid(p
, &q_u
->pol
, &pol_sid
, &acc_granted
, NULL
))
1623 return NT_STATUS_INVALID_HANDLE
;
1625 if (num_rids
> 1000) {
1626 DEBUG(0, ("Got asked for %d rids (more than 1000) -- according "
1627 "to samba4 idl this is not possible\n", num_rids
));
1628 return NT_STATUS_UNSUCCESSFUL
;
1631 names
= TALLOC_ZERO_ARRAY(p
->mem_ctx
, const char *, num_rids
);
1632 attrs
= TALLOC_ZERO_ARRAY(p
->mem_ctx
, uint32
, num_rids
);
1634 if ((num_rids
!= 0) && ((names
== NULL
) || (attrs
== NULL
)))
1635 return NT_STATUS_NO_MEMORY
;
1637 become_root(); /* lookup_sid can require root privs */
1638 r_u
->status
= pdb_lookup_rids(&pol_sid
, num_rids
, q_u
->rid
,
1642 if(!make_samr_lookup_rids(p
->mem_ctx
, num_rids
, names
,
1643 &hdr_name
, &uni_name
))
1644 return NT_STATUS_NO_MEMORY
;
1646 init_samr_r_lookup_rids(r_u
, num_rids
, hdr_name
, uni_name
, attrs
);
1648 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__
));
1653 /*******************************************************************
1654 _samr_open_user. Safe - gives out no passwd info.
1655 ********************************************************************/
1657 NTSTATUS
_samr_open_user(pipes_struct
*p
, SAMR_Q_OPEN_USER
*q_u
, SAMR_R_OPEN_USER
*r_u
)
1659 SAM_ACCOUNT
*sampass
=NULL
;
1661 POLICY_HND domain_pol
= q_u
->domain_pol
;
1662 POLICY_HND
*user_pol
= &r_u
->user_pol
;
1663 struct samr_info
*info
= NULL
;
1664 SEC_DESC
*psd
= NULL
;
1666 uint32 des_access
= q_u
->access_mask
;
1672 r_u
->status
= NT_STATUS_OK
;
1674 /* find the domain policy handle and get domain SID / access bits in the domain policy. */
1676 if ( !get_lsa_policy_samr_sid(p
, &domain_pol
, &sid
, &acc_granted
, NULL
) )
1677 return NT_STATUS_INVALID_HANDLE
;
1679 nt_status
= access_check_samr_function( acc_granted
,
1680 SA_RIGHT_DOMAIN_OPEN_ACCOUNT
, "_samr_open_user" );
1682 if ( !NT_STATUS_IS_OK(nt_status
) )
1685 nt_status
= pdb_init_sam_talloc(p
->mem_ctx
, &sampass
);
1687 if (!NT_STATUS_IS_OK(nt_status
))
1690 /* append the user's RID to it */
1692 if (!sid_append_rid(&sid
, q_u
->user_rid
))
1693 return NT_STATUS_NO_SUCH_USER
;
1695 /* check if access can be granted as requested by client. */
1697 make_samr_object_sd(p
->mem_ctx
, &psd
, &sd_size
, &usr_generic_mapping
, &sid
, SAMR_USR_RIGHTS_WRITE_PW
);
1698 se_map_generic(&des_access
, &usr_generic_mapping
);
1700 se_priv_copy( &se_rights
, &se_machine_account
);
1701 se_priv_add( &se_rights
, &se_add_users
);
1703 nt_status
= access_check_samr_object(psd
, p
->pipe_user
.nt_user_token
,
1704 &se_rights
, GENERIC_RIGHTS_USER_WRITE
, des_access
,
1705 &acc_granted
, "_samr_open_user");
1707 if ( !NT_STATUS_IS_OK(nt_status
) )
1711 ret
=pdb_getsampwsid(sampass
, &sid
);
1714 /* check that the SID exists in our domain. */
1716 return NT_STATUS_NO_SUCH_USER
;
1719 pdb_free_sam(&sampass
);
1721 /* associate the user's SID and access bits with the new handle. */
1722 if ((info
= get_samr_info_by_sid(&sid
)) == NULL
)
1723 return NT_STATUS_NO_MEMORY
;
1724 info
->acc_granted
= acc_granted
;
1726 /* get a (unique) handle. open a policy on it. */
1727 if (!create_policy_hnd(p
, user_pol
, free_samr_info
, (void *)info
))
1728 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
1733 /*************************************************************************
1734 get_user_info_7. Safe. Only gives out account_name.
1735 *************************************************************************/
1737 static NTSTATUS
get_user_info_7(TALLOC_CTX
*mem_ctx
, SAM_USER_INFO_7
*id7
, DOM_SID
*user_sid
)
1739 SAM_ACCOUNT
*smbpass
=NULL
;
1743 nt_status
= pdb_init_sam_talloc(mem_ctx
, &smbpass
);
1745 if (!NT_STATUS_IS_OK(nt_status
)) {
1750 ret
= pdb_getsampwsid(smbpass
, user_sid
);
1754 DEBUG(4,("User %s not found\n", sid_string_static(user_sid
)));
1755 return NT_STATUS_NO_SUCH_USER
;
1758 DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass
) ));
1761 init_sam_user_info7(id7
, pdb_get_username(smbpass
) );
1763 pdb_free_sam(&smbpass
);
1765 return NT_STATUS_OK
;
1768 /*************************************************************************
1769 get_user_info_9. Only gives out primary group SID.
1770 *************************************************************************/
1771 static NTSTATUS
get_user_info_9(TALLOC_CTX
*mem_ctx
, SAM_USER_INFO_9
* id9
, DOM_SID
*user_sid
)
1773 SAM_ACCOUNT
*smbpass
=NULL
;
1777 nt_status
= pdb_init_sam_talloc(mem_ctx
, &smbpass
);
1779 if (!NT_STATUS_IS_OK(nt_status
)) {
1784 ret
= pdb_getsampwsid(smbpass
, user_sid
);
1788 DEBUG(4,("User %s not found\n", sid_string_static(user_sid
)));
1789 return NT_STATUS_NO_SUCH_USER
;
1792 DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass
) ));
1795 init_sam_user_info9(id9
, pdb_get_group_rid(smbpass
) );
1797 pdb_free_sam(&smbpass
);
1799 return NT_STATUS_OK
;
1802 /*************************************************************************
1803 get_user_info_16. Safe. Only gives out acb bits.
1804 *************************************************************************/
1806 static NTSTATUS
get_user_info_16(TALLOC_CTX
*mem_ctx
, SAM_USER_INFO_16
*id16
, DOM_SID
*user_sid
)
1808 SAM_ACCOUNT
*smbpass
=NULL
;
1812 nt_status
= pdb_init_sam_talloc(mem_ctx
, &smbpass
);
1814 if (!NT_STATUS_IS_OK(nt_status
)) {
1819 ret
= pdb_getsampwsid(smbpass
, user_sid
);
1823 DEBUG(4,("User %s not found\n", sid_string_static(user_sid
)));
1824 return NT_STATUS_NO_SUCH_USER
;
1827 DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass
) ));
1830 init_sam_user_info16(id16
, pdb_get_acct_ctrl(smbpass
) );
1832 pdb_free_sam(&smbpass
);
1834 return NT_STATUS_OK
;
1837 /*************************************************************************
1838 get_user_info_18. OK - this is the killer as it gives out password info.
1839 Ensure that this is only allowed on an encrypted connection with a root
1841 *************************************************************************/
1843 static NTSTATUS
get_user_info_18(pipes_struct
*p
, TALLOC_CTX
*mem_ctx
, SAM_USER_INFO_18
* id18
, DOM_SID
*user_sid
)
1845 SAM_ACCOUNT
*smbpass
=NULL
;
1849 if (p
->auth
.auth_type
!= PIPE_AUTH_TYPE_NTLMSSP
|| p
->auth
.auth_type
!= PIPE_AUTH_TYPE_SPNEGO_NTLMSSP
) {
1850 return NT_STATUS_ACCESS_DENIED
;
1853 if (p
->auth
.auth_level
!= PIPE_AUTH_LEVEL_PRIVACY
) {
1854 return NT_STATUS_ACCESS_DENIED
;
1858 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
1861 nt_status
= pdb_init_sam_talloc(mem_ctx
, &smbpass
);
1863 if (!NT_STATUS_IS_OK(nt_status
)) {
1867 ret
= pdb_getsampwsid(smbpass
, user_sid
);
1870 DEBUG(4, ("User %s not found\n", sid_string_static(user_sid
)));
1871 pdb_free_sam(&smbpass
);
1872 return (geteuid() == (uid_t
)0) ? NT_STATUS_NO_SUCH_USER
: NT_STATUS_ACCESS_DENIED
;
1875 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass
), pdb_get_acct_ctrl(smbpass
) ));
1877 if ( pdb_get_acct_ctrl(smbpass
) & ACB_DISABLED
) {
1878 pdb_free_sam(&smbpass
);
1879 return NT_STATUS_ACCOUNT_DISABLED
;
1883 init_sam_user_info18(id18
, pdb_get_lanman_passwd(smbpass
), pdb_get_nt_passwd(smbpass
));
1885 pdb_free_sam(&smbpass
);
1887 return NT_STATUS_OK
;
1890 /*************************************************************************
1892 *************************************************************************/
1894 static NTSTATUS
get_user_info_20(TALLOC_CTX
*mem_ctx
, SAM_USER_INFO_20
*id20
, DOM_SID
*user_sid
)
1896 SAM_ACCOUNT
*sampass
=NULL
;
1899 pdb_init_sam_talloc(mem_ctx
, &sampass
);
1902 ret
= pdb_getsampwsid(sampass
, user_sid
);
1906 DEBUG(4,("User %s not found\n", sid_string_static(user_sid
)));
1907 return NT_STATUS_NO_SUCH_USER
;
1910 samr_clear_sam_passwd(sampass
);
1912 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass
) ));
1915 init_sam_user_info20A(id20
, sampass
);
1917 pdb_free_sam(&sampass
);
1919 return NT_STATUS_OK
;
1922 /*************************************************************************
1924 *************************************************************************/
1926 static NTSTATUS
get_user_info_21(TALLOC_CTX
*mem_ctx
, SAM_USER_INFO_21
*id21
,
1927 DOM_SID
*user_sid
, DOM_SID
*domain_sid
)
1929 SAM_ACCOUNT
*sampass
=NULL
;
1933 nt_status
= pdb_init_sam_talloc(mem_ctx
, &sampass
);
1934 if (!NT_STATUS_IS_OK(nt_status
)) {
1939 ret
= pdb_getsampwsid(sampass
, user_sid
);
1943 DEBUG(4,("User %s not found\n", sid_string_static(user_sid
)));
1944 return NT_STATUS_NO_SUCH_USER
;
1947 samr_clear_sam_passwd(sampass
);
1949 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass
) ));
1952 nt_status
= init_sam_user_info21A(id21
, sampass
, domain_sid
);
1954 pdb_free_sam(&sampass
);
1956 return NT_STATUS_OK
;
1959 /*******************************************************************
1960 _samr_query_userinfo
1961 ********************************************************************/
1963 NTSTATUS
_samr_query_userinfo(pipes_struct
*p
, SAMR_Q_QUERY_USERINFO
*q_u
, SAMR_R_QUERY_USERINFO
*r_u
)
1965 SAM_USERINFO_CTR
*ctr
;
1966 struct samr_info
*info
= NULL
;
1970 r_u
->status
=NT_STATUS_OK
;
1972 /* search for the handle */
1973 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)(void *)&info
))
1974 return NT_STATUS_INVALID_HANDLE
;
1976 domain_sid
= info
->sid
;
1978 sid_split_rid(&domain_sid
, &rid
);
1980 if (!sid_check_is_in_our_domain(&info
->sid
))
1981 return NT_STATUS_OBJECT_TYPE_MISMATCH
;
1983 DEBUG(5,("_samr_query_userinfo: sid:%s\n", sid_string_static(&info
->sid
)));
1985 ctr
= TALLOC_ZERO_P(p
->mem_ctx
, SAM_USERINFO_CTR
);
1987 return NT_STATUS_NO_MEMORY
;
1991 /* ok! user info levels (lots: see MSDEV help), off we go... */
1992 ctr
->switch_value
= q_u
->switch_value
;
1994 DEBUG(5,("_samr_query_userinfo: user info level: %d\n", q_u
->switch_value
));
1996 switch (q_u
->switch_value
) {
1998 ctr
->info
.id7
= TALLOC_ZERO_P(p
->mem_ctx
, SAM_USER_INFO_7
);
1999 if (ctr
->info
.id7
== NULL
)
2000 return NT_STATUS_NO_MEMORY
;
2002 if (!NT_STATUS_IS_OK(r_u
->status
= get_user_info_7(p
->mem_ctx
, ctr
->info
.id7
, &info
->sid
)))
2006 ctr
->info
.id9
= TALLOC_ZERO_P(p
->mem_ctx
, SAM_USER_INFO_9
);
2007 if (ctr
->info
.id9
== NULL
)
2008 return NT_STATUS_NO_MEMORY
;
2010 if (!NT_STATUS_IS_OK(r_u
->status
= get_user_info_9(p
->mem_ctx
, ctr
->info
.id9
, &info
->sid
)))
2014 ctr
->info
.id16
= TALLOC_ZERO_P(p
->mem_ctx
, SAM_USER_INFO_16
);
2015 if (ctr
->info
.id16
== NULL
)
2016 return NT_STATUS_NO_MEMORY
;
2018 if (!NT_STATUS_IS_OK(r_u
->status
= get_user_info_16(p
->mem_ctx
, ctr
->info
.id16
, &info
->sid
)))
2023 ctr
->info
.id18
= TALLOC_ZERO_P(p
->mem_ctx
, SAM_USER_INFO_18
);
2024 if (ctr
->info
.id18
== NULL
)
2025 return NT_STATUS_NO_MEMORY
;
2027 if (!NT_STATUS_IS_OK(r_u
->status
= get_user_info_18(p
, p
->mem_ctx
, ctr
->info
.id18
, &info
->sid
)))
2032 ctr
->info
.id20
= TALLOC_ZERO_P(p
->mem_ctx
,SAM_USER_INFO_20
);
2033 if (ctr
->info
.id20
== NULL
)
2034 return NT_STATUS_NO_MEMORY
;
2035 if (!NT_STATUS_IS_OK(r_u
->status
= get_user_info_20(p
->mem_ctx
, ctr
->info
.id20
, &info
->sid
)))
2040 ctr
->info
.id21
= TALLOC_ZERO_P(p
->mem_ctx
,SAM_USER_INFO_21
);
2041 if (ctr
->info
.id21
== NULL
)
2042 return NT_STATUS_NO_MEMORY
;
2043 if (!NT_STATUS_IS_OK(r_u
->status
= get_user_info_21(p
->mem_ctx
, ctr
->info
.id21
,
2044 &info
->sid
, &domain_sid
)))
2049 return NT_STATUS_INVALID_INFO_CLASS
;
2052 init_samr_r_query_userinfo(r_u
, ctr
, r_u
->status
);
2054 DEBUG(5,("_samr_query_userinfo: %d\n", __LINE__
));
2059 /*******************************************************************
2060 samr_reply_query_usergroups
2061 ********************************************************************/
2063 NTSTATUS
_samr_query_usergroups(pipes_struct
*p
, SAMR_Q_QUERY_USERGROUPS
*q_u
, SAMR_R_QUERY_USERGROUPS
*r_u
)
2065 SAM_ACCOUNT
*sam_pass
=NULL
;
2069 DOM_GID
*gids
= NULL
;
2070 uint32 primary_group_rid
;
2071 size_t num_groups
= 0;
2079 * from the SID in the request:
2080 * we should send back the list of DOMAIN GROUPS
2081 * the user is a member of
2083 * and only the DOMAIN GROUPS
2084 * no ALIASES !!! neither aliases of the domain
2085 * nor aliases of the builtin SID
2090 r_u
->status
= NT_STATUS_OK
;
2092 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__
));
2094 /* find the policy handle. open a policy on it. */
2095 if (!get_lsa_policy_samr_sid(p
, &q_u
->pol
, &sid
, &acc_granted
, NULL
))
2096 return NT_STATUS_INVALID_HANDLE
;
2098 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, SA_RIGHT_USER_GET_GROUPS
, "_samr_query_usergroups"))) {
2102 if (!sid_check_is_in_our_domain(&sid
))
2103 return NT_STATUS_OBJECT_TYPE_MISMATCH
;
2105 pdb_init_sam_talloc(p
->mem_ctx
, &sam_pass
);
2108 ret
= pdb_getsampwsid(sam_pass
, &sid
);
2112 DEBUG(10, ("pdb_getsampwsid failed for %s\n",
2113 sid_string_static(&sid
)));
2114 return NT_STATUS_NO_SUCH_USER
;
2120 result
= pdb_enum_group_memberships(p
->mem_ctx
, sam_pass
,
2121 &sids
, &unix_gids
, &num_groups
);
2124 if (!NT_STATUS_IS_OK(result
)) {
2125 DEBUG(10, ("pdb_enum_group_memberships failed for %s\n",
2126 sid_string_static(&sid
)));
2133 dom_gid
.attr
= (SE_GROUP_MANDATORY
|SE_GROUP_ENABLED_BY_DEFAULT
|
2136 if (!sid_peek_check_rid(get_global_sam_sid(),
2137 pdb_get_group_sid(sam_pass
),
2138 &primary_group_rid
)) {
2139 DEBUG(5, ("Group sid %s for user %s not in our domain\n",
2140 sid_string_static(pdb_get_group_sid(sam_pass
)),
2141 pdb_get_username(sam_pass
)));
2142 pdb_free_sam(&sam_pass
);
2143 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
2146 dom_gid
.g_rid
= primary_group_rid
;
2148 ADD_TO_ARRAY(p
->mem_ctx
, DOM_GID
, dom_gid
, &gids
, &num_gids
);
2150 for (i
=0; i
<num_groups
; i
++) {
2152 if (!sid_peek_check_rid(get_global_sam_sid(),
2153 &(sids
[i
]), &dom_gid
.g_rid
)) {
2154 DEBUG(10, ("Found sid %s not in our domain\n",
2155 sid_string_static(&sids
[i
])));
2159 if (dom_gid
.g_rid
== primary_group_rid
) {
2160 /* We added the primary group directly from the
2161 * sam_account. The other SIDs are unique from
2162 * enum_group_memberships */
2166 ADD_TO_ARRAY(p
->mem_ctx
, DOM_GID
, dom_gid
, &gids
, &num_gids
);
2169 /* construct the response. lkclXXXX: gids are not copied! */
2170 init_samr_r_query_usergroups(r_u
, num_gids
, gids
, r_u
->status
);
2172 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__
));
2177 /*******************************************************************
2178 _samr_query_dom_info
2179 ********************************************************************/
2181 NTSTATUS
_samr_query_dom_info(pipes_struct
*p
, SAMR_Q_QUERY_DOMAIN_INFO
*q_u
, SAMR_R_QUERY_DOMAIN_INFO
*r_u
)
2183 struct samr_info
*info
= NULL
;
2185 uint32 min_pass_len
,pass_hist
,password_properties
;
2186 time_t u_expire
, u_min_age
;
2187 NTTIME nt_expire
, nt_min_age
;
2189 time_t u_lock_duration
, u_reset_time
;
2190 NTTIME nt_lock_duration
, nt_reset_time
;
2195 uint32 account_policy_temp
;
2200 uint32 num_users
=0, num_groups
=0, num_aliases
=0;
2202 if ((ctr
= TALLOC_ZERO_P(p
->mem_ctx
, SAM_UNK_CTR
)) == NULL
) {
2203 return NT_STATUS_NO_MEMORY
;
2208 r_u
->status
= NT_STATUS_OK
;
2210 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__
));
2212 /* find the policy handle. open a policy on it. */
2213 if (!find_policy_by_hnd(p
, &q_u
->domain_pol
, (void **)(void *)&info
)) {
2214 return NT_STATUS_INVALID_HANDLE
;
2217 switch (q_u
->switch_value
) {
2224 pdb_get_account_policy(AP_MIN_PASSWORD_LEN
, &account_policy_temp
);
2225 min_pass_len
= account_policy_temp
;
2227 pdb_get_account_policy(AP_PASSWORD_HISTORY
, &account_policy_temp
);
2228 pass_hist
= account_policy_temp
;
2230 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS
, &account_policy_temp
);
2231 password_properties
= account_policy_temp
;
2233 pdb_get_account_policy(AP_MAX_PASSWORD_AGE
, &account_policy_temp
);
2234 u_expire
= account_policy_temp
;
2236 pdb_get_account_policy(AP_MIN_PASSWORD_AGE
, &account_policy_temp
);
2237 u_min_age
= account_policy_temp
;
2243 unix_to_nt_time_abs(&nt_expire
, u_expire
);
2244 unix_to_nt_time_abs(&nt_min_age
, u_min_age
);
2246 init_unk_info1(&ctr
->info
.inf1
, (uint16
)min_pass_len
, (uint16
)pass_hist
,
2247 password_properties
, nt_expire
, nt_min_age
);
2255 num_users
= count_sam_users(info
->disp_info
, ACB_NORMAL
);
2256 num_groups
= count_sam_groups(info
->disp_info
);
2257 num_aliases
= count_sam_aliases(info
->disp_info
);
2259 pdb_get_account_policy(AP_TIME_TO_LOGOUT
, &account_policy_temp
);
2260 u_logout
= account_policy_temp
;
2262 unix_to_nt_time_abs(&nt_logout
, u_logout
);
2264 if (!pdb_get_seq_num(&seq_num
))
2265 seq_num
= time(NULL
);
2271 server_role
= ROLE_DOMAIN_PDC
;
2272 if (lp_server_role() == ROLE_DOMAIN_BDC
)
2273 server_role
= ROLE_DOMAIN_BDC
;
2275 init_unk_info2(&ctr
->info
.inf2
, lp_serverstring(), lp_workgroup(), global_myname(), seq_num
,
2276 num_users
, num_groups
, num_aliases
, nt_logout
, server_role
);
2286 pdb_get_account_policy(AP_TIME_TO_LOGOUT
, &ul
);
2287 u_logout
= (time_t)ul
;
2294 unix_to_nt_time_abs(&nt_logout
, u_logout
);
2296 init_unk_info3(&ctr
->info
.inf3
, nt_logout
);
2299 init_unk_info5(&ctr
->info
.inf5
, global_myname());
2302 init_unk_info6(&ctr
->info
.inf6
);
2305 server_role
= ROLE_DOMAIN_PDC
;
2306 if (lp_server_role() == ROLE_DOMAIN_BDC
)
2307 server_role
= ROLE_DOMAIN_BDC
;
2309 init_unk_info7(&ctr
->info
.inf7
, server_role
);
2317 if (!pdb_get_seq_num(&seq_num
)) {
2318 seq_num
= time(NULL
);
2325 init_unk_info8(&ctr
->info
.inf8
, (uint32
) seq_num
);
2333 pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION
, &account_policy_temp
);
2334 u_lock_duration
= account_policy_temp
;
2335 if (u_lock_duration
!= -1) {
2336 u_lock_duration
*= 60;
2339 pdb_get_account_policy(AP_RESET_COUNT_TIME
, &account_policy_temp
);
2340 u_reset_time
= account_policy_temp
* 60;
2342 pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT
, &account_policy_temp
);
2343 lockout
= account_policy_temp
;
2349 unix_to_nt_time_abs(&nt_lock_duration
, u_lock_duration
);
2350 unix_to_nt_time_abs(&nt_reset_time
, u_reset_time
);
2352 init_unk_info12(&ctr
->info
.inf12
, nt_lock_duration
, nt_reset_time
, (uint16
)lockout
);
2355 return NT_STATUS_INVALID_INFO_CLASS
;
2359 init_samr_r_query_dom_info(r_u
, q_u
->switch_value
, ctr
, NT_STATUS_OK
);
2361 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__
));
2366 /* W2k3 seems to use the same check for all 3 objects that can be created via
2367 * SAMR, if you try to create for example "Dialup" as an alias it says
2368 * "NT_STATUS_USER_EXISTS". This is racy, but we can't really lock the user
2371 static NTSTATUS
can_create(TALLOC_CTX
*mem_ctx
, const char *new_name
)
2373 enum SID_NAME_USE type
;
2376 DEBUG(10, ("Checking whether [%s] can be created\n", new_name
));
2379 /* Lookup in our local databases (only LOOKUP_NAME_ISOLATED set)
2380 * whether the name already exists */
2381 result
= lookup_name(mem_ctx
, new_name
, LOOKUP_NAME_ISOLATED
,
2382 NULL
, NULL
, NULL
, &type
);
2386 DEBUG(10, ("%s does not exist, can create it\n", new_name
));
2387 return NT_STATUS_OK
;
2390 DEBUG(5, ("trying to create %s, exists as %s\n",
2391 new_name
, sid_type_lookup(type
)));
2393 if (type
== SID_NAME_DOM_GRP
) {
2394 return NT_STATUS_GROUP_EXISTS
;
2396 if (type
== SID_NAME_ALIAS
) {
2397 return NT_STATUS_ALIAS_EXISTS
;
2400 /* Yes, the default is NT_STATUS_USER_EXISTS */
2401 return NT_STATUS_USER_EXISTS
;
2404 /*******************************************************************
2406 Create an account, can be either a normal user or a machine.
2407 This funcion will need to be updated for bdc/domain trusts.
2408 ********************************************************************/
2410 NTSTATUS
_samr_create_user(pipes_struct
*p
, SAMR_Q_CREATE_USER
*q_u
,
2411 SAMR_R_CREATE_USER
*r_u
)
2413 SAM_ACCOUNT
*sam_pass
=NULL
;
2417 POLICY_HND dom_pol
= q_u
->domain_pol
;
2418 UNISTR2 user_account
= q_u
->uni_name
;
2419 uint16 acb_info
= q_u
->acb_info
;
2420 POLICY_HND
*user_pol
= &r_u
->user_pol
;
2421 struct samr_info
*info
= NULL
;
2428 /* check this, when giving away 'add computer to domain' privs */
2429 uint32 des_access
= GENERIC_RIGHTS_USER_ALL_ACCESS
;
2430 BOOL can_add_account
= False
;
2432 DISP_INFO
*disp_info
= NULL
;
2434 /* Get the domain SID stored in the domain policy */
2435 if (!get_lsa_policy_samr_sid(p
, &dom_pol
, &sid
, &acc_granted
,
2437 return NT_STATUS_INVALID_HANDLE
;
2439 nt_status
= access_check_samr_function(acc_granted
,
2440 SA_RIGHT_DOMAIN_CREATE_USER
,
2441 "_samr_create_user");
2442 if (!NT_STATUS_IS_OK(nt_status
)) {
2446 if (!(acb_info
== ACB_NORMAL
|| acb_info
== ACB_DOMTRUST
||
2447 acb_info
== ACB_WSTRUST
|| acb_info
== ACB_SVRTRUST
)) {
2448 /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if
2449 this parameter is not an account type */
2450 return NT_STATUS_INVALID_PARAMETER
;
2453 rpcstr_pull(account
, user_account
.buffer
, sizeof(account
),
2454 user_account
.uni_str_len
*2, 0);
2455 strlower_m(account
);
2457 nt_status
= can_create(p
->mem_ctx
, account
);
2458 if (!NT_STATUS_IS_OK(nt_status
)) {
2462 /*********************************************************************
2463 * HEADS UP! If we have to create a new user account, we have to get
2464 * a new RID from somewhere. This used to be done by the passdb
2465 * backend. It has been moved into idmap now. Since idmap is now
2466 * wrapped up behind winbind, this means you have to run winbindd if
2467 * you want new accounts to get a new RID when "enable rid algorithm =
2468 * no". Tough. We now have a uniform way of allocating RIDs
2469 * regardless of what ever passdb backend people may use. --jerry
2471 *********************************************************************/
2473 pw
= Get_Pwnam(account
);
2475 /* determine which user right we need to check based on the acb_info */
2477 if ( acb_info
& ACB_WSTRUST
)
2479 pstrcpy(add_script
, lp_addmachine_script());
2480 se_priv_copy( &se_rights
, &se_machine_account
);
2481 can_add_account
= user_has_privileges(
2482 p
->pipe_user
.nt_user_token
, &se_rights
);
2484 /* usrmgr.exe (and net rpc trustdom grant) creates a normal user
2485 account for domain trusts and changes the ACB flags later */
2486 else if ( acb_info
& ACB_NORMAL
&&
2487 (account
[strlen(account
)-1] != '$') )
2489 pstrcpy(add_script
, lp_adduser_script());
2490 se_priv_copy( &se_rights
, &se_add_users
);
2491 can_add_account
= user_has_privileges(
2492 p
->pipe_user
.nt_user_token
, &se_rights
);
2494 else /* implicit assumption of a BDC or domain trust account here
2495 * (we already check the flags earlier) */
2497 pstrcpy(add_script
, lp_addmachine_script());
2498 if ( lp_enable_privileges() ) {
2499 /* only Domain Admins can add a BDC or domain trust */
2500 se_priv_copy( &se_rights
, &se_priv_none
);
2501 can_add_account
= nt_token_check_domain_rid(
2502 p
->pipe_user
.nt_user_token
,
2503 DOMAIN_GROUP_RID_ADMINS
);
2507 DEBUG(5, ("_samr_create_user: %s can add this account : %s\n",
2508 p
->pipe_user_name
, can_add_account
? "True":"False" ));
2510 /********** BEGIN Admin BLOCK **********/
2512 if ( can_add_account
)
2519 all_string_sub(add_script
, "%u", account
,
2520 sizeof(add_script
));
2521 add_ret
= smbrun(add_script
,NULL
);
2522 DEBUG(add_ret
? 0 : 3,("_samr_create_user: Running "
2523 "the command `%s' gave %d\n",
2524 add_script
, add_ret
));
2528 /* implicit call to getpwnam() next. we have a valid SID coming out
2531 flush_pwnam_cache();
2532 nt_status
= pdb_init_sam_new(&sam_pass
, account
);
2534 /* this code is order such that we have no unnecessary retuns
2535 out of the admin block of code */
2537 if ( NT_STATUS_IS_OK(nt_status
) ) {
2538 pdb_set_acct_ctrl(sam_pass
, acb_info
, PDB_CHANGED
);
2540 if ( !(ret
= pdb_add_sam_account(sam_pass
)) ) {
2541 pdb_free_sam(&sam_pass
);
2542 DEBUG(0, ("could not add user/computer %s to passdb. "
2543 "Check permissions?\n",
2545 nt_status
= NT_STATUS_ACCESS_DENIED
;
2549 if ( can_add_account
)
2552 /********** END Admin BLOCK **********/
2554 /* now check for failure */
2556 if ( !NT_STATUS_IS_OK(nt_status
) )
2559 /* Get the user's SID */
2561 sid_copy(&sid
, pdb_get_user_sid(sam_pass
));
2563 make_samr_object_sd(p
->mem_ctx
, &psd
, &sd_size
, &usr_generic_mapping
,
2564 &sid
, SAMR_USR_RIGHTS_WRITE_PW
);
2565 se_map_generic(&des_access
, &usr_generic_mapping
);
2567 nt_status
= access_check_samr_object(psd
, p
->pipe_user
.nt_user_token
,
2568 &se_rights
, GENERIC_RIGHTS_USER_WRITE
, des_access
,
2569 &acc_granted
, "_samr_create_user");
2571 if ( !NT_STATUS_IS_OK(nt_status
) ) {
2575 /* associate the user's SID with the new handle. */
2576 if ((info
= get_samr_info_by_sid(&sid
)) == NULL
) {
2577 pdb_free_sam(&sam_pass
);
2578 return NT_STATUS_NO_MEMORY
;
2583 info
->acc_granted
= acc_granted
;
2585 /* get a (unique) handle. open a policy on it. */
2586 if (!create_policy_hnd(p
, user_pol
, free_samr_info
, (void *)info
)) {
2587 pdb_free_sam(&sam_pass
);
2588 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
2591 /* After a "set" ensure we have no cached display info. */
2592 force_flush_samr_cache(info
->disp_info
);
2594 r_u
->user_rid
=pdb_get_user_rid(sam_pass
);
2596 r_u
->access_granted
= acc_granted
;
2598 pdb_free_sam(&sam_pass
);
2600 return NT_STATUS_OK
;
2603 /*******************************************************************
2604 samr_reply_connect_anon
2605 ********************************************************************/
2607 NTSTATUS
_samr_connect_anon(pipes_struct
*p
, SAMR_Q_CONNECT_ANON
*q_u
, SAMR_R_CONNECT_ANON
*r_u
)
2609 struct samr_info
*info
= NULL
;
2610 uint32 des_access
= q_u
->access_mask
;
2614 if (!pipe_access_check(p
)) {
2615 DEBUG(3, ("access denied to samr_connect_anon\n"));
2616 r_u
->status
= NT_STATUS_ACCESS_DENIED
;
2620 /* set up the SAMR connect_anon response */
2622 r_u
->status
= NT_STATUS_OK
;
2624 /* associate the user's SID with the new handle. */
2625 if ((info
= get_samr_info_by_sid(NULL
)) == NULL
)
2626 return NT_STATUS_NO_MEMORY
;
2628 /* don't give away the farm but this is probably ok. The SA_RIGHT_SAM_ENUM_DOMAINS
2629 was observed from a win98 client trying to enumerate users (when configured
2630 user level access control on shares) --jerry */
2632 if (des_access
== MAXIMUM_ALLOWED_ACCESS
) {
2633 /* Map to max possible knowing we're filtered below. */
2634 des_access
= GENERIC_ALL_ACCESS
;
2637 se_map_generic( &des_access
, &sam_generic_mapping
);
2638 info
->acc_granted
= des_access
& (SA_RIGHT_SAM_ENUM_DOMAINS
|SA_RIGHT_SAM_OPEN_DOMAIN
);
2640 info
->status
= q_u
->unknown_0
;
2642 /* get a (unique) handle. open a policy on it. */
2643 if (!create_policy_hnd(p
, &r_u
->connect_pol
, free_samr_info
, (void *)info
))
2644 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
2649 /*******************************************************************
2651 ********************************************************************/
2653 NTSTATUS
_samr_connect(pipes_struct
*p
, SAMR_Q_CONNECT
*q_u
, SAMR_R_CONNECT
*r_u
)
2655 struct samr_info
*info
= NULL
;
2656 SEC_DESC
*psd
= NULL
;
2658 uint32 des_access
= q_u
->access_mask
;
2663 DEBUG(5,("_samr_connect: %d\n", __LINE__
));
2667 if (!pipe_access_check(p
)) {
2668 DEBUG(3, ("access denied to samr_connect\n"));
2669 r_u
->status
= NT_STATUS_ACCESS_DENIED
;
2673 make_samr_object_sd(p
->mem_ctx
, &psd
, &sd_size
, &sam_generic_mapping
, NULL
, 0);
2674 se_map_generic(&des_access
, &sam_generic_mapping
);
2676 nt_status
= access_check_samr_object(psd
, p
->pipe_user
.nt_user_token
,
2677 NULL
, 0, des_access
, &acc_granted
, "_samr_connect");
2679 if ( !NT_STATUS_IS_OK(nt_status
) )
2682 r_u
->status
= NT_STATUS_OK
;
2684 /* associate the user's SID and access granted with the new handle. */
2685 if ((info
= get_samr_info_by_sid(NULL
)) == NULL
)
2686 return NT_STATUS_NO_MEMORY
;
2688 info
->acc_granted
= acc_granted
;
2689 info
->status
= q_u
->access_mask
;
2691 /* get a (unique) handle. open a policy on it. */
2692 if (!create_policy_hnd(p
, &r_u
->connect_pol
, free_samr_info
, (void *)info
))
2693 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
2695 DEBUG(5,("_samr_connect: %d\n", __LINE__
));
2700 /*******************************************************************
2702 ********************************************************************/
2704 NTSTATUS
_samr_connect4(pipes_struct
*p
, SAMR_Q_CONNECT4
*q_u
, SAMR_R_CONNECT4
*r_u
)
2706 struct samr_info
*info
= NULL
;
2707 SEC_DESC
*psd
= NULL
;
2709 uint32 des_access
= q_u
->access_mask
;
2714 DEBUG(5,("_samr_connect4: %d\n", __LINE__
));
2718 if (!pipe_access_check(p
)) {
2719 DEBUG(3, ("access denied to samr_connect4\n"));
2720 r_u
->status
= NT_STATUS_ACCESS_DENIED
;
2724 make_samr_object_sd(p
->mem_ctx
, &psd
, &sd_size
, &sam_generic_mapping
, NULL
, 0);
2725 se_map_generic(&des_access
, &sam_generic_mapping
);
2727 nt_status
= access_check_samr_object(psd
, p
->pipe_user
.nt_user_token
,
2728 NULL
, 0, des_access
, &acc_granted
, "_samr_connect4");
2730 if ( !NT_STATUS_IS_OK(nt_status
) )
2733 r_u
->status
= NT_STATUS_OK
;
2735 /* associate the user's SID and access granted with the new handle. */
2736 if ((info
= get_samr_info_by_sid(NULL
)) == NULL
)
2737 return NT_STATUS_NO_MEMORY
;
2739 info
->acc_granted
= acc_granted
;
2740 info
->status
= q_u
->access_mask
;
2742 /* get a (unique) handle. open a policy on it. */
2743 if (!create_policy_hnd(p
, &r_u
->connect_pol
, free_samr_info
, (void *)info
))
2744 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
2746 DEBUG(5,("_samr_connect: %d\n", __LINE__
));
2751 /*******************************************************************
2753 ********************************************************************/
2755 NTSTATUS
_samr_connect5(pipes_struct
*p
, SAMR_Q_CONNECT5
*q_u
, SAMR_R_CONNECT5
*r_u
)
2757 struct samr_info
*info
= NULL
;
2758 SEC_DESC
*psd
= NULL
;
2760 uint32 des_access
= q_u
->access_mask
;
2766 DEBUG(5,("_samr_connect5: %d\n", __LINE__
));
2772 if (!pipe_access_check(p
)) {
2773 DEBUG(3, ("access denied to samr_connect5\n"));
2774 r_u
->status
= NT_STATUS_ACCESS_DENIED
;
2778 make_samr_object_sd(p
->mem_ctx
, &psd
, &sd_size
, &sam_generic_mapping
, NULL
, 0);
2779 se_map_generic(&des_access
, &sam_generic_mapping
);
2781 nt_status
= access_check_samr_object(psd
, p
->pipe_user
.nt_user_token
,
2782 NULL
, 0, des_access
, &acc_granted
, "_samr_connect5");
2784 if ( !NT_STATUS_IS_OK(nt_status
) )
2787 /* associate the user's SID and access granted with the new handle. */
2788 if ((info
= get_samr_info_by_sid(NULL
)) == NULL
)
2789 return NT_STATUS_NO_MEMORY
;
2791 info
->acc_granted
= acc_granted
;
2792 info
->status
= q_u
->access_mask
;
2794 /* get a (unique) handle. open a policy on it. */
2795 if (!create_policy_hnd(p
, &pol
, free_samr_info
, (void *)info
))
2796 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
2798 DEBUG(5,("_samr_connect: %d\n", __LINE__
));
2800 init_samr_r_connect5(r_u
, &pol
, NT_STATUS_OK
);
2805 /**********************************************************************
2806 api_samr_lookup_domain
2807 **********************************************************************/
2809 NTSTATUS
_samr_lookup_domain(pipes_struct
*p
, SAMR_Q_LOOKUP_DOMAIN
*q_u
, SAMR_R_LOOKUP_DOMAIN
*r_u
)
2811 struct samr_info
*info
;
2812 fstring domain_name
;
2815 r_u
->status
= NT_STATUS_OK
;
2817 if (!find_policy_by_hnd(p
, &q_u
->connect_pol
, (void**)(void *)&info
))
2818 return NT_STATUS_INVALID_HANDLE
;
2820 /* win9x user manager likes to use SA_RIGHT_SAM_ENUM_DOMAINS here.
2821 Reverted that change so we will work with RAS servers again */
2823 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(info
->acc_granted
,
2824 SA_RIGHT_SAM_OPEN_DOMAIN
, "_samr_lookup_domain")))
2829 rpcstr_pull(domain_name
, q_u
->uni_domain
.buffer
, sizeof(domain_name
), q_u
->uni_domain
.uni_str_len
*2, 0);
2833 if (strequal(domain_name
, builtin_domain_name())) {
2834 sid_copy(&sid
, &global_sid_Builtin
);
2836 if (!secrets_fetch_domain_sid(domain_name
, &sid
)) {
2837 r_u
->status
= NT_STATUS_NO_SUCH_DOMAIN
;
2841 DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name
, sid_string_static(&sid
)));
2843 init_samr_r_lookup_domain(r_u
, &sid
, r_u
->status
);
2848 /******************************************************************
2849 makes a SAMR_R_ENUM_DOMAINS structure.
2850 ********************************************************************/
2852 static BOOL
make_enum_domains(TALLOC_CTX
*ctx
, SAM_ENTRY
**pp_sam
,
2853 UNISTR2
**pp_uni_name
, uint32 num_sam_entries
, fstring doms
[])
2859 DEBUG(5, ("make_enum_domains\n"));
2862 *pp_uni_name
= NULL
;
2864 if (num_sam_entries
== 0)
2867 sam
= TALLOC_ZERO_ARRAY(ctx
, SAM_ENTRY
, num_sam_entries
);
2868 uni_name
= TALLOC_ZERO_ARRAY(ctx
, UNISTR2
, num_sam_entries
);
2870 if (sam
== NULL
|| uni_name
== NULL
)
2873 for (i
= 0; i
< num_sam_entries
; i
++) {
2874 init_unistr2(&uni_name
[i
], doms
[i
], UNI_FLAGS_NONE
);
2875 init_sam_entry(&sam
[i
], &uni_name
[i
], 0);
2879 *pp_uni_name
= uni_name
;
2884 /**********************************************************************
2885 api_samr_enum_domains
2886 **********************************************************************/
2888 NTSTATUS
_samr_enum_domains(pipes_struct
*p
, SAMR_Q_ENUM_DOMAINS
*q_u
, SAMR_R_ENUM_DOMAINS
*r_u
)
2890 struct samr_info
*info
;
2891 uint32 num_entries
= 2;
2895 r_u
->status
= NT_STATUS_OK
;
2897 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void**)(void *)&info
))
2898 return NT_STATUS_INVALID_HANDLE
;
2900 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(info
->acc_granted
, SA_RIGHT_SAM_ENUM_DOMAINS
, "_samr_enum_domains"))) {
2904 name
= get_global_sam_name();
2906 fstrcpy(dom
[0],name
);
2908 fstrcpy(dom
[1],"Builtin");
2910 if (!make_enum_domains(p
->mem_ctx
, &r_u
->sam
, &r_u
->uni_dom_name
, num_entries
, dom
))
2911 return NT_STATUS_NO_MEMORY
;
2913 init_samr_r_enum_domains(r_u
, q_u
->start_idx
+ num_entries
, num_entries
);
2918 /*******************************************************************
2920 ********************************************************************/
2922 NTSTATUS
_samr_open_alias(pipes_struct
*p
, SAMR_Q_OPEN_ALIAS
*q_u
, SAMR_R_OPEN_ALIAS
*r_u
)
2925 POLICY_HND domain_pol
= q_u
->dom_pol
;
2926 uint32 alias_rid
= q_u
->rid_alias
;
2927 POLICY_HND
*alias_pol
= &r_u
->pol
;
2928 struct samr_info
*info
= NULL
;
2929 SEC_DESC
*psd
= NULL
;
2931 uint32 des_access
= q_u
->access_mask
;
2936 r_u
->status
= NT_STATUS_OK
;
2938 /* find the domain policy and get the SID / access bits stored in the domain policy */
2940 if ( !get_lsa_policy_samr_sid(p
, &domain_pol
, &sid
, &acc_granted
, NULL
) )
2941 return NT_STATUS_INVALID_HANDLE
;
2943 status
= access_check_samr_function(acc_granted
,
2944 SA_RIGHT_DOMAIN_OPEN_ACCOUNT
, "_samr_open_alias");
2946 if ( !NT_STATUS_IS_OK(status
) )
2949 /* append the alias' RID to it */
2951 if (!sid_append_rid(&sid
, alias_rid
))
2952 return NT_STATUS_NO_SUCH_ALIAS
;
2954 /*check if access can be granted as requested by client. */
2956 make_samr_object_sd(p
->mem_ctx
, &psd
, &sd_size
, &ali_generic_mapping
, NULL
, 0);
2957 se_map_generic(&des_access
,&ali_generic_mapping
);
2959 se_priv_copy( &se_rights
, &se_add_users
);
2962 status
= access_check_samr_object(psd
, p
->pipe_user
.nt_user_token
,
2963 &se_rights
, GENERIC_RIGHTS_ALIAS_WRITE
, des_access
,
2964 &acc_granted
, "_samr_open_alias");
2966 if ( !NT_STATUS_IS_OK(status
) )
2970 /* Check we actually have the requested alias */
2971 enum SID_NAME_USE type
;
2975 result
= lookup_sid(NULL
, &sid
, NULL
, NULL
, &type
);
2978 if (!result
|| (type
!= SID_NAME_ALIAS
)) {
2979 return NT_STATUS_NO_SUCH_ALIAS
;
2983 /* associate the alias SID with the new handle. */
2984 if ((info
= get_samr_info_by_sid(&sid
)) == NULL
)
2985 return NT_STATUS_NO_MEMORY
;
2987 info
->acc_granted
= acc_granted
;
2989 /* get a (unique) handle. open a policy on it. */
2990 if (!create_policy_hnd(p
, alias_pol
, free_samr_info
, (void *)info
))
2991 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
2996 /*******************************************************************
2998 ********************************************************************/
2999 static NTSTATUS
set_user_info_7(TALLOC_CTX
*mem_ctx
,
3000 const SAM_USER_INFO_7
*id7
, SAM_ACCOUNT
*pwd
)
3006 DEBUG(5, ("set_user_info_7: NULL id7\n"));
3008 return NT_STATUS_ACCESS_DENIED
;
3011 if(!rpcstr_pull(new_name
, id7
->uni_name
.buffer
, sizeof(new_name
), id7
->uni_name
.uni_str_len
*2, 0)) {
3012 DEBUG(5, ("set_user_info_7: failed to get new username\n"));
3014 return NT_STATUS_ACCESS_DENIED
;
3017 /* check to see if the new username already exists. Note: we can't
3018 reliably lock all backends, so there is potentially the
3019 possibility that a user can be created in between this check and
3020 the rename. The rename should fail, but may not get the
3021 exact same failure status code. I think this is small enough
3022 of a window for this type of operation and the results are
3023 simply that the rename fails with a slightly different status
3024 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
3026 rc
= can_create(mem_ctx
, new_name
);
3027 if (!NT_STATUS_IS_OK(rc
)) {
3031 rc
= pdb_rename_sam_account(pwd
, new_name
);
3037 /*******************************************************************
3039 ********************************************************************/
3041 static BOOL
set_user_info_16(const SAM_USER_INFO_16
*id16
, SAM_ACCOUNT
*pwd
)
3044 DEBUG(5, ("set_user_info_16: NULL id16\n"));
3049 /* FIX ME: check if the value is really changed --metze */
3050 if (!pdb_set_acct_ctrl(pwd
, id16
->acb_info
, PDB_CHANGED
)) {
3055 if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd
))) {
3065 /*******************************************************************
3067 ********************************************************************/
3069 static BOOL
set_user_info_18(SAM_USER_INFO_18
*id18
, SAM_ACCOUNT
*pwd
)
3073 DEBUG(2, ("set_user_info_18: id18 is NULL\n"));
3078 if (!pdb_set_lanman_passwd (pwd
, id18
->lm_pwd
, PDB_CHANGED
)) {
3082 if (!pdb_set_nt_passwd (pwd
, id18
->nt_pwd
, PDB_CHANGED
)) {
3086 if (!pdb_set_pass_changed_now (pwd
)) {
3091 if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd
))) {
3100 /*******************************************************************
3101 The GROUPSID field in the SAM_ACCOUNT changed. Try to tell unix.
3102 ********************************************************************/
3103 static BOOL
set_unix_primary_group(SAM_ACCOUNT
*sampass
)
3108 if (!sid_to_gid(pdb_get_group_sid(sampass
), &gid
)) {
3109 DEBUG(2,("Could not get gid for primary group of "
3110 "user %s\n", pdb_get_username(sampass
)));
3114 grp
= getgrgid(gid
);
3117 DEBUG(2,("Could not find primary group %lu for "
3118 "user %s\n", (unsigned long)gid
,
3119 pdb_get_username(sampass
)));
3123 if (smb_set_primary_group(grp
->gr_name
,
3124 pdb_get_username(sampass
)) != 0) {
3125 DEBUG(2,("Could not set primary group for user %s to "
3127 pdb_get_username(sampass
), grp
->gr_name
));
3135 /*******************************************************************
3137 ********************************************************************/
3139 static BOOL
set_user_info_20(SAM_USER_INFO_20
*id20
, SAM_ACCOUNT
*pwd
)
3142 DEBUG(5, ("set_user_info_20: NULL id20\n"));
3146 copy_id20_to_sam_passwd(pwd
, id20
);
3148 /* write the change out */
3149 if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd
))) {
3158 /*******************************************************************
3160 ********************************************************************/
3162 static BOOL
set_user_info_21(SAM_USER_INFO_21
*id21
, SAM_ACCOUNT
*pwd
)
3166 DEBUG(5, ("set_user_info_21: NULL id21\n"));
3170 copy_id21_to_sam_passwd(pwd
, id21
);
3173 * The funny part about the previous two calls is
3174 * that pwd still has the password hashes from the
3175 * passdb entry. These have not been updated from
3176 * id21. I don't know if they need to be set. --jerry
3179 if (IS_SAM_CHANGED(pwd
, PDB_GROUPSID
))
3180 set_unix_primary_group(pwd
);
3182 /* write the change out */
3183 if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd
))) {
3193 /*******************************************************************
3195 ********************************************************************/
3197 static BOOL
set_user_info_23(SAM_USER_INFO_23
*id23
, SAM_ACCOUNT
*pwd
)
3199 pstring plaintext_buf
;
3204 DEBUG(5, ("set_user_info_23: NULL id23\n"));
3208 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
3209 pdb_get_username(pwd
)));
3211 acct_ctrl
= pdb_get_acct_ctrl(pwd
);
3213 if (!decode_pw_buffer(id23
->pass
, plaintext_buf
, 256, &len
, STR_UNICODE
)) {
3218 if (!pdb_set_plaintext_passwd (pwd
, plaintext_buf
)) {
3223 copy_id23_to_sam_passwd(pwd
, id23
);
3225 /* if it's a trust account, don't update /etc/passwd */
3226 if ( ( (acct_ctrl
& ACB_DOMTRUST
) == ACB_DOMTRUST
) ||
3227 ( (acct_ctrl
& ACB_WSTRUST
) == ACB_WSTRUST
) ||
3228 ( (acct_ctrl
& ACB_SVRTRUST
) == ACB_SVRTRUST
) ) {
3229 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
3231 /* update the UNIX password */
3232 if (lp_unix_password_sync() ) {
3233 struct passwd
*passwd
= Get_Pwnam(pdb_get_username(pwd
));
3235 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
3238 if(!chgpasswd(pdb_get_username(pwd
), passwd
, "", plaintext_buf
, True
)) {
3245 ZERO_STRUCT(plaintext_buf
);
3247 if (IS_SAM_CHANGED(pwd
, PDB_GROUPSID
))
3248 set_unix_primary_group(pwd
);
3250 if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd
))) {
3260 /*******************************************************************
3262 ********************************************************************/
3264 static BOOL
set_user_info_pw(uint8
*pass
, SAM_ACCOUNT
*pwd
)
3267 pstring plaintext_buf
;
3270 DEBUG(5, ("Attempting administrator password change for user %s\n",
3271 pdb_get_username(pwd
)));
3273 acct_ctrl
= pdb_get_acct_ctrl(pwd
);
3275 ZERO_STRUCT(plaintext_buf
);
3277 if (!decode_pw_buffer(pass
, plaintext_buf
, 256, &len
, STR_UNICODE
)) {
3282 if (!pdb_set_plaintext_passwd (pwd
, plaintext_buf
)) {
3287 /* if it's a trust account, don't update /etc/passwd */
3288 if ( ( (acct_ctrl
& ACB_DOMTRUST
) == ACB_DOMTRUST
) ||
3289 ( (acct_ctrl
& ACB_WSTRUST
) == ACB_WSTRUST
) ||
3290 ( (acct_ctrl
& ACB_SVRTRUST
) == ACB_SVRTRUST
) ) {
3291 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
3293 /* update the UNIX password */
3294 if (lp_unix_password_sync()) {
3295 struct passwd
*passwd
= Get_Pwnam(pdb_get_username(pwd
));
3297 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
3300 if(!chgpasswd(pdb_get_username(pwd
), passwd
, "", plaintext_buf
, True
)) {
3307 ZERO_STRUCT(plaintext_buf
);
3309 DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
3311 /* update the SAMBA password */
3312 if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd
))) {
3322 /*******************************************************************
3323 samr_reply_set_userinfo
3324 ********************************************************************/
3326 NTSTATUS
_samr_set_userinfo(pipes_struct
*p
, SAMR_Q_SET_USERINFO
*q_u
, SAMR_R_SET_USERINFO
*r_u
)
3328 SAM_ACCOUNT
*pwd
= NULL
;
3330 POLICY_HND
*pol
= &q_u
->pol
;
3331 uint16 switch_value
= q_u
->switch_value
;
3332 SAM_USERINFO_CTR
*ctr
= q_u
->ctr
;
3334 uint32 acc_required
;
3336 BOOL has_enough_rights
= False
;
3338 DISP_INFO
*disp_info
= NULL
;
3340 DEBUG(5, ("_samr_set_userinfo: %d\n", __LINE__
));
3342 r_u
->status
= NT_STATUS_OK
;
3344 /* find the policy handle. open a policy on it. */
3345 if (!get_lsa_policy_samr_sid(p
, pol
, &sid
, &acc_granted
, &disp_info
))
3346 return NT_STATUS_INVALID_HANDLE
;
3348 /* observed when joining an XP client to a Samba domain */
3350 acc_required
= SA_RIGHT_USER_SET_PASSWORD
| SA_RIGHT_USER_SET_ATTRIBUTES
| SA_RIGHT_USER_ACCT_FLAGS_EXPIRY
;
3352 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, acc_required
, "_samr_set_userinfo"))) {
3356 DEBUG(5, ("_samr_set_userinfo: sid:%s, level:%d\n", sid_string_static(&sid
), switch_value
));
3359 DEBUG(5, ("_samr_set_userinfo: NULL info level\n"));
3360 return NT_STATUS_INVALID_INFO_CLASS
;
3366 ret
= pdb_getsampwsid(pwd
, &sid
);
3371 return NT_STATUS_NO_SUCH_USER
;
3374 /* deal with machine password changes differently from userinfo changes */
3375 /* check to see if we have the sufficient rights */
3377 acb_info
= pdb_get_acct_ctrl(pwd
);
3378 if ( acb_info
& ACB_WSTRUST
)
3379 has_enough_rights
= user_has_privileges( p
->pipe_user
.nt_user_token
, &se_machine_account
);
3380 else if ( acb_info
& ACB_NORMAL
)
3381 has_enough_rights
= user_has_privileges( p
->pipe_user
.nt_user_token
, &se_add_users
);
3382 else if ( acb_info
& (ACB_SVRTRUST
|ACB_DOMTRUST
) ) {
3383 if ( lp_enable_privileges() )
3384 has_enough_rights
= nt_token_check_domain_rid( p
->pipe_user
.nt_user_token
, DOMAIN_GROUP_RID_ADMINS
);
3387 DEBUG(5, ("_samr_set_userinfo: %s does%s possess sufficient rights\n",
3388 p
->pipe_user_name
, has_enough_rights
? "" : " not"));
3390 /* ================ BEGIN SeMachineAccountPrivilege BLOCK ================ */
3392 if ( has_enough_rights
)
3395 /* ok! user info levels (lots: see MSDEV help), off we go... */
3397 switch (switch_value
) {
3399 if (!set_user_info_18(ctr
->info
.id18
, pwd
))
3400 r_u
->status
= NT_STATUS_ACCESS_DENIED
;
3404 if (!p
->session_key
.length
) {
3405 r_u
->status
= NT_STATUS_NO_USER_SESSION_KEY
;
3407 SamOEMhashBlob(ctr
->info
.id24
->pass
, 516, &p
->session_key
);
3409 dump_data(100, (char *)ctr
->info
.id24
->pass
, 516);
3411 if (!set_user_info_pw(ctr
->info
.id24
->pass
, pwd
))
3412 r_u
->status
= NT_STATUS_ACCESS_DENIED
;
3416 if (!p
->session_key
.length
) {
3417 r_u
->status
= NT_STATUS_NO_USER_SESSION_KEY
;
3419 encode_or_decode_arc4_passwd_buffer(ctr
->info
.id25
->pass
, &p
->session_key
);
3421 dump_data(100, (char *)ctr
->info
.id25
->pass
, 532);
3423 if (!set_user_info_pw(ctr
->info
.id25
->pass
, pwd
))
3424 r_u
->status
= NT_STATUS_ACCESS_DENIED
;
3428 if (!p
->session_key
.length
) {
3429 r_u
->status
= NT_STATUS_NO_USER_SESSION_KEY
;
3431 encode_or_decode_arc4_passwd_buffer(ctr
->info
.id26
->pass
, &p
->session_key
);
3433 dump_data(100, (char *)ctr
->info
.id26
->pass
, 516);
3435 if (!set_user_info_pw(ctr
->info
.id26
->pass
, pwd
))
3436 r_u
->status
= NT_STATUS_ACCESS_DENIED
;
3440 if (!p
->session_key
.length
) {
3441 r_u
->status
= NT_STATUS_NO_USER_SESSION_KEY
;
3443 SamOEMhashBlob(ctr
->info
.id23
->pass
, 516, &p
->session_key
);
3445 dump_data(100, (char *)ctr
->info
.id23
->pass
, 516);
3447 if (!set_user_info_23(ctr
->info
.id23
, pwd
))
3448 r_u
->status
= NT_STATUS_ACCESS_DENIED
;
3452 r_u
->status
= NT_STATUS_INVALID_INFO_CLASS
;
3456 if ( has_enough_rights
)
3459 /* ================ END SeMachineAccountPrivilege BLOCK ================ */
3461 if (NT_STATUS_IS_OK(r_u
->status
)) {
3462 force_flush_samr_cache(disp_info
);
3468 /*******************************************************************
3469 samr_reply_set_userinfo2
3470 ********************************************************************/
3472 NTSTATUS
_samr_set_userinfo2(pipes_struct
*p
, SAMR_Q_SET_USERINFO2
*q_u
, SAMR_R_SET_USERINFO2
*r_u
)
3474 SAM_ACCOUNT
*pwd
= NULL
;
3476 SAM_USERINFO_CTR
*ctr
= q_u
->ctr
;
3477 POLICY_HND
*pol
= &q_u
->pol
;
3478 uint16 switch_value
= q_u
->switch_value
;
3480 uint32 acc_required
;
3482 BOOL has_enough_rights
= False
;
3484 DISP_INFO
*disp_info
= NULL
;
3486 DEBUG(5, ("samr_reply_set_userinfo2: %d\n", __LINE__
));
3488 r_u
->status
= NT_STATUS_OK
;
3490 /* find the policy handle. open a policy on it. */
3491 if (!get_lsa_policy_samr_sid(p
, pol
, &sid
, &acc_granted
, &disp_info
))
3492 return NT_STATUS_INVALID_HANDLE
;
3494 /* observed when joining XP client to Samba domain */
3496 acc_required
= SA_RIGHT_USER_SET_PASSWORD
| SA_RIGHT_USER_SET_ATTRIBUTES
| SA_RIGHT_USER_ACCT_FLAGS_EXPIRY
;
3498 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, acc_required
, "_samr_set_userinfo2"))) {
3502 DEBUG(5, ("samr_reply_set_userinfo2: sid:%s\n", sid_string_static(&sid
)));
3505 DEBUG(5, ("samr_reply_set_userinfo2: NULL info level\n"));
3506 return NT_STATUS_INVALID_INFO_CLASS
;
3509 switch_value
=ctr
->switch_value
;
3514 ret
= pdb_getsampwsid(pwd
, &sid
);
3519 return NT_STATUS_NO_SUCH_USER
;
3522 acb_info
= pdb_get_acct_ctrl(pwd
);
3523 if ( acb_info
& ACB_WSTRUST
)
3524 has_enough_rights
= user_has_privileges( p
->pipe_user
.nt_user_token
, &se_machine_account
);
3525 else if ( acb_info
& ACB_NORMAL
)
3526 has_enough_rights
= user_has_privileges( p
->pipe_user
.nt_user_token
, &se_add_users
);
3527 else if ( acb_info
& (ACB_SVRTRUST
|ACB_DOMTRUST
) ) {
3528 if ( lp_enable_privileges() )
3529 has_enough_rights
= nt_token_check_domain_rid( p
->pipe_user
.nt_user_token
, DOMAIN_GROUP_RID_ADMINS
);
3532 DEBUG(5, ("_samr_set_userinfo2: %s does%s possess sufficient rights\n",
3533 p
->pipe_user_name
, has_enough_rights
? "" : " not"));
3535 /* ================ BEGIN SeMachineAccountPrivilege BLOCK ================ */
3537 if ( has_enough_rights
)
3540 /* ok! user info levels (lots: see MSDEV help), off we go... */
3542 switch (switch_value
) {
3544 r_u
->status
= set_user_info_7(p
->mem_ctx
,
3545 ctr
->info
.id7
, pwd
);
3548 if (!set_user_info_16(ctr
->info
.id16
, pwd
))
3549 r_u
->status
= NT_STATUS_ACCESS_DENIED
;
3552 /* Used by AS/U JRA. */
3553 if (!set_user_info_18(ctr
->info
.id18
, pwd
))
3554 r_u
->status
= NT_STATUS_ACCESS_DENIED
;
3557 if (!set_user_info_20(ctr
->info
.id20
, pwd
))
3558 r_u
->status
= NT_STATUS_ACCESS_DENIED
;
3561 if (!set_user_info_21(ctr
->info
.id21
, pwd
))
3562 return NT_STATUS_ACCESS_DENIED
;
3565 if (!p
->session_key
.length
) {
3566 r_u
->status
= NT_STATUS_NO_USER_SESSION_KEY
;
3568 SamOEMhashBlob(ctr
->info
.id23
->pass
, 516, &p
->session_key
);
3570 dump_data(100, (char *)ctr
->info
.id23
->pass
, 516);
3572 if (!set_user_info_23(ctr
->info
.id23
, pwd
))
3573 r_u
->status
= NT_STATUS_ACCESS_DENIED
;
3576 if (!p
->session_key
.length
) {
3577 r_u
->status
= NT_STATUS_NO_USER_SESSION_KEY
;
3579 encode_or_decode_arc4_passwd_buffer(ctr
->info
.id26
->pass
, &p
->session_key
);
3581 dump_data(100, (char *)ctr
->info
.id26
->pass
, 516);
3583 if (!set_user_info_pw(ctr
->info
.id26
->pass
, pwd
))
3584 r_u
->status
= NT_STATUS_ACCESS_DENIED
;
3587 r_u
->status
= NT_STATUS_INVALID_INFO_CLASS
;
3590 if ( has_enough_rights
)
3593 /* ================ END SeMachineAccountPrivilege BLOCK ================ */
3595 if (NT_STATUS_IS_OK(r_u
->status
)) {
3596 force_flush_samr_cache(disp_info
);
3602 /*********************************************************************
3603 _samr_query_aliasmem
3604 *********************************************************************/
3606 NTSTATUS
_samr_query_useraliases(pipes_struct
*p
, SAMR_Q_QUERY_USERALIASES
*q_u
, SAMR_R_QUERY_USERALIASES
*r_u
)
3608 size_t num_alias_rids
;
3610 struct samr_info
*info
= NULL
;
3618 r_u
->status
= NT_STATUS_OK
;
3620 DEBUG(5,("_samr_query_useraliases: %d\n", __LINE__
));
3622 /* find the policy handle. open a policy on it. */
3623 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)(void *)&info
))
3624 return NT_STATUS_INVALID_HANDLE
;
3626 ntstatus1
= access_check_samr_function(info
->acc_granted
, SA_RIGHT_DOMAIN_LOOKUP_ALIAS_BY_MEM
, "_samr_query_useraliases");
3627 ntstatus2
= access_check_samr_function(info
->acc_granted
, SA_RIGHT_DOMAIN_OPEN_ACCOUNT
, "_samr_query_useraliases");
3629 if (!NT_STATUS_IS_OK(ntstatus1
) || !NT_STATUS_IS_OK(ntstatus2
)) {
3630 if (!(NT_STATUS_EQUAL(ntstatus1
,NT_STATUS_ACCESS_DENIED
) && NT_STATUS_IS_OK(ntstatus2
)) &&
3631 !(NT_STATUS_EQUAL(ntstatus1
,NT_STATUS_ACCESS_DENIED
) && NT_STATUS_IS_OK(ntstatus1
))) {
3632 return (NT_STATUS_IS_OK(ntstatus1
)) ? ntstatus2
: ntstatus1
;
3636 if (!sid_check_is_domain(&info
->sid
) &&
3637 !sid_check_is_builtin(&info
->sid
))
3638 return NT_STATUS_OBJECT_TYPE_MISMATCH
;
3640 members
= TALLOC_ARRAY(p
->mem_ctx
, DOM_SID
, q_u
->num_sids1
);
3642 if (members
== NULL
)
3643 return NT_STATUS_NO_MEMORY
;
3645 for (i
=0; i
<q_u
->num_sids1
; i
++)
3646 sid_copy(&members
[i
], &q_u
->sid
[i
].sid
);
3652 ntstatus1
= pdb_enum_alias_memberships(p
->mem_ctx
, &info
->sid
, members
,
3654 &alias_rids
, &num_alias_rids
);
3657 if (!NT_STATUS_IS_OK(ntstatus1
)) {
3661 init_samr_r_query_useraliases(r_u
, num_alias_rids
, alias_rids
,
3663 return NT_STATUS_OK
;
3666 /*********************************************************************
3667 _samr_query_aliasmem
3668 *********************************************************************/
3670 NTSTATUS
_samr_query_aliasmem(pipes_struct
*p
, SAMR_Q_QUERY_ALIASMEM
*q_u
, SAMR_R_QUERY_ALIASMEM
*r_u
)
3674 size_t num_sids
= 0;
3682 /* find the policy handle. open a policy on it. */
3683 if (!get_lsa_policy_samr_sid(p
, &q_u
->alias_pol
, &alias_sid
, &acc_granted
, NULL
))
3684 return NT_STATUS_INVALID_HANDLE
;
3686 if (!NT_STATUS_IS_OK(r_u
->status
=
3687 access_check_samr_function(acc_granted
, SA_RIGHT_ALIAS_GET_MEMBERS
, "_samr_query_aliasmem"))) {
3691 DEBUG(10, ("sid is %s\n", sid_string_static(&alias_sid
)));
3693 status
= pdb_enum_aliasmem(&alias_sid
, &sids
, &num_sids
);
3695 if (!NT_STATUS_IS_OK(status
)) {
3699 sid
= TALLOC_ZERO_ARRAY(p
->mem_ctx
, DOM_SID2
, num_sids
);
3700 if (num_sids
!=0 && sid
== NULL
) {
3702 return NT_STATUS_NO_MEMORY
;
3705 for (i
= 0; i
< num_sids
; i
++) {
3706 init_dom_sid2(&sid
[i
], &sids
[i
]);
3709 init_samr_r_query_aliasmem(r_u
, num_sids
, sid
, NT_STATUS_OK
);
3713 return NT_STATUS_OK
;
3716 static void add_uid_to_array_unique(uid_t uid
, uid_t
**uids
, int *num
)
3720 for (i
=0; i
<*num
; i
++) {
3721 if ((*uids
)[i
] == uid
)
3725 *uids
= SMB_REALLOC_ARRAY(*uids
, uid_t
, *num
+1);
3730 (*uids
)[*num
] = uid
;
3735 static BOOL
get_memberuids(gid_t gid
, uid_t
**uids
, int *num
)
3739 struct sys_pwent
*userlist
, *user
;
3744 /* We only look at our own sam, so don't care about imported stuff */
3748 if ((grp
= getgrgid(gid
)) == NULL
) {
3753 /* Primary group members */
3755 userlist
= getpwent_list();
3757 for (user
= userlist
; user
!= NULL
; user
= user
->next
) {
3758 if (user
->pw_gid
!= gid
)
3760 add_uid_to_array_unique(user
->pw_uid
, uids
, num
);
3763 pwent_free(userlist
);
3765 /* Secondary group members */
3767 for (gr
= grp
->gr_mem
; (*gr
!= NULL
) && ((*gr
)[0] != '\0'); gr
+= 1) {
3768 struct passwd
*pw
= getpwnam(*gr
);
3772 add_uid_to_array_unique(pw
->pw_uid
, uids
, num
);
3780 /*********************************************************************
3781 _samr_query_groupmem
3782 *********************************************************************/
3784 NTSTATUS
_samr_query_groupmem(pipes_struct
*p
, SAMR_Q_QUERY_GROUPMEM
*q_u
, SAMR_R_QUERY_GROUPMEM
*r_u
)
3787 fstring group_sid_str
;
3788 size_t i
, num_members
;
3797 /* find the policy handle. open a policy on it. */
3798 if (!get_lsa_policy_samr_sid(p
, &q_u
->group_pol
, &group_sid
, &acc_granted
, NULL
))
3799 return NT_STATUS_INVALID_HANDLE
;
3801 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, SA_RIGHT_GROUP_GET_MEMBERS
, "_samr_query_groupmem"))) {
3805 sid_to_string(group_sid_str
, &group_sid
);
3806 DEBUG(10, ("sid is %s\n", group_sid_str
));
3808 if (!sid_check_is_in_our_domain(&group_sid
)) {
3809 DEBUG(3, ("sid %s is not in our domain\n", group_sid_str
));
3810 return NT_STATUS_NO_SUCH_GROUP
;
3813 DEBUG(10, ("lookup on Domain SID\n"));
3816 result
= pdb_enum_group_members(p
->mem_ctx
, &group_sid
,
3817 &rid
, &num_members
);
3820 if (!NT_STATUS_IS_OK(result
))
3823 attr
=TALLOC_ZERO_ARRAY(p
->mem_ctx
, uint32
, num_members
);
3825 if ((num_members
!=0) && (rid
==NULL
))
3826 return NT_STATUS_NO_MEMORY
;
3828 for (i
=0; i
<num_members
; i
++)
3829 attr
[i
] = SID_NAME_USER
;
3831 init_samr_r_query_groupmem(r_u
, num_members
, rid
, attr
, NT_STATUS_OK
);
3833 return NT_STATUS_OK
;
3836 /*********************************************************************
3838 *********************************************************************/
3840 NTSTATUS
_samr_add_aliasmem(pipes_struct
*p
, SAMR_Q_ADD_ALIASMEM
*q_u
, SAMR_R_ADD_ALIASMEM
*r_u
)
3845 BOOL can_add_accounts
;
3847 DISP_INFO
*disp_info
= NULL
;
3849 /* Find the policy handle. Open a policy on it. */
3850 if (!get_lsa_policy_samr_sid(p
, &q_u
->alias_pol
, &alias_sid
, &acc_granted
, &disp_info
))
3851 return NT_STATUS_INVALID_HANDLE
;
3853 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, SA_RIGHT_ALIAS_ADD_MEMBER
, "_samr_add_aliasmem"))) {
3857 DEBUG(10, ("sid is %s\n", sid_string_static(&alias_sid
)));
3859 se_priv_copy( &se_rights
, &se_add_users
);
3860 can_add_accounts
= user_has_privileges( p
->pipe_user
.nt_user_token
, &se_rights
);
3862 /******** BEGIN SeAddUsers BLOCK *********/
3864 if ( can_add_accounts
)
3867 ret
= pdb_add_aliasmem(&alias_sid
, &q_u
->sid
.sid
);
3869 if ( can_add_accounts
)
3872 /******** END SeAddUsers BLOCK *********/
3874 if (NT_STATUS_IS_OK(ret
)) {
3875 force_flush_samr_cache(disp_info
);
3881 /*********************************************************************
3883 *********************************************************************/
3885 NTSTATUS
_samr_del_aliasmem(pipes_struct
*p
, SAMR_Q_DEL_ALIASMEM
*q_u
, SAMR_R_DEL_ALIASMEM
*r_u
)
3890 BOOL can_add_accounts
;
3892 DISP_INFO
*disp_info
= NULL
;
3894 /* Find the policy handle. Open a policy on it. */
3895 if (!get_lsa_policy_samr_sid(p
, &q_u
->alias_pol
, &alias_sid
, &acc_granted
, &disp_info
))
3896 return NT_STATUS_INVALID_HANDLE
;
3898 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, SA_RIGHT_ALIAS_REMOVE_MEMBER
, "_samr_del_aliasmem"))) {
3902 DEBUG(10, ("_samr_del_aliasmem:sid is %s\n",
3903 sid_string_static(&alias_sid
)));
3905 se_priv_copy( &se_rights
, &se_add_users
);
3906 can_add_accounts
= user_has_privileges( p
->pipe_user
.nt_user_token
, &se_rights
);
3908 /******** BEGIN SeAddUsers BLOCK *********/
3910 if ( can_add_accounts
)
3913 ret
= pdb_del_aliasmem(&alias_sid
, &q_u
->sid
.sid
);
3915 if ( can_add_accounts
)
3918 /******** END SeAddUsers BLOCK *********/
3920 if (NT_STATUS_IS_OK(ret
)) {
3921 force_flush_samr_cache(disp_info
);
3927 /*********************************************************************
3929 *********************************************************************/
3931 NTSTATUS
_samr_add_groupmem(pipes_struct
*p
, SAMR_Q_ADD_GROUPMEM
*q_u
, SAMR_R_ADD_GROUPMEM
*r_u
)
3935 fstring group_sid_str
;
3942 SAM_ACCOUNT
*sam_user
=NULL
;
3946 BOOL can_add_accounts
;
3947 DISP_INFO
*disp_info
= NULL
;
3949 /* Find the policy handle. Open a policy on it. */
3950 if (!get_lsa_policy_samr_sid(p
, &q_u
->pol
, &group_sid
, &acc_granted
, &disp_info
))
3951 return NT_STATUS_INVALID_HANDLE
;
3953 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, SA_RIGHT_GROUP_ADD_MEMBER
, "_samr_add_groupmem"))) {
3957 sid_to_string(group_sid_str
, &group_sid
);
3958 DEBUG(10, ("sid is %s\n", group_sid_str
));
3960 if (sid_compare(&group_sid
, get_global_sam_sid())<=0)
3961 return NT_STATUS_NO_SUCH_GROUP
;
3963 DEBUG(10, ("lookup on Domain SID\n"));
3965 if(!get_domain_group_from_sid(group_sid
, &map
))
3966 return NT_STATUS_NO_SUCH_GROUP
;
3968 sid_copy(&user_sid
, get_global_sam_sid());
3969 sid_append_rid(&user_sid
, q_u
->rid
);
3971 ret
= pdb_init_sam(&sam_user
);
3972 if (!NT_STATUS_IS_OK(ret
))
3975 check
= pdb_getsampwsid(sam_user
, &user_sid
);
3977 if (check
!= True
) {
3978 pdb_free_sam(&sam_user
);
3979 return NT_STATUS_NO_SUCH_USER
;
3982 /* check a real user exist before we run the script to add a user to a group */
3983 if (!sid_to_uid(pdb_get_user_sid(sam_user
), &uid
)) {
3984 pdb_free_sam(&sam_user
);
3985 return NT_STATUS_NO_SUCH_USER
;
3988 pdb_free_sam(&sam_user
);
3990 if ((pwd
=getpwuid_alloc(p
->mem_ctx
, uid
)) == NULL
) {
3991 return NT_STATUS_NO_SUCH_USER
;
3994 if ((grp
=getgrgid(map
.gid
)) == NULL
) {
3995 return NT_STATUS_NO_SUCH_GROUP
;
3998 /* we need to copy the name otherwise it's overloaded in user_in_unix_group_list */
3999 fstrcpy(grp_name
, grp
->gr_name
);
4001 /* if the user is already in the group */
4002 if(user_in_unix_group(pwd
->pw_name
, grp_name
)) {
4003 return NT_STATUS_MEMBER_IN_GROUP
;
4006 se_priv_copy( &se_rights
, &se_add_users
);
4007 can_add_accounts
= user_has_privileges( p
->pipe_user
.nt_user_token
, &se_rights
);
4009 /******** BEGIN SeAddUsers BLOCK *********/
4011 if ( can_add_accounts
)
4015 * ok, the group exist, the user exist, the user is not in the group,
4017 * we can (finally) add it to the group !
4020 smb_add_user_group(grp_name
, pwd
->pw_name
);
4022 if ( can_add_accounts
)
4025 /******** END SeAddUsers BLOCK *********/
4027 /* check if the user has been added then ... */
4028 if(!user_in_unix_group(pwd
->pw_name
, grp_name
)) {
4029 return NT_STATUS_MEMBER_NOT_IN_GROUP
; /* don't know what to reply else */
4032 force_flush_samr_cache(disp_info
);
4034 return NT_STATUS_OK
;
4037 /*********************************************************************
4039 *********************************************************************/
4041 NTSTATUS
_samr_del_groupmem(pipes_struct
*p
, SAMR_Q_DEL_GROUPMEM
*q_u
, SAMR_R_DEL_GROUPMEM
*r_u
)
4045 SAM_ACCOUNT
*sam_pass
=NULL
;
4051 BOOL can_add_accounts
;
4052 DISP_INFO
*disp_info
= NULL
;
4055 * delete the group member named q_u->rid
4056 * who is a member of the sid associated with the handle
4057 * the rid is a user's rid as the group is a domain group.
4060 /* Find the policy handle. Open a policy on it. */
4061 if (!get_lsa_policy_samr_sid(p
, &q_u
->pol
, &group_sid
, &acc_granted
, &disp_info
))
4062 return NT_STATUS_INVALID_HANDLE
;
4064 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, SA_RIGHT_GROUP_REMOVE_MEMBER
, "_samr_del_groupmem"))) {
4068 if (!sid_check_is_in_our_domain(&group_sid
))
4069 return NT_STATUS_NO_SUCH_GROUP
;
4071 sid_copy(&user_sid
, get_global_sam_sid());
4072 sid_append_rid(&user_sid
, q_u
->rid
);
4074 if (!get_domain_group_from_sid(group_sid
, &map
))
4075 return NT_STATUS_NO_SUCH_GROUP
;
4077 if ((grp
=getgrgid(map
.gid
)) == NULL
)
4078 return NT_STATUS_NO_SUCH_GROUP
;
4080 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
4081 fstrcpy(grp_name
, grp
->gr_name
);
4083 /* check if the user exists before trying to remove it from the group */
4084 pdb_init_sam(&sam_pass
);
4085 if (!pdb_getsampwsid(sam_pass
, &user_sid
)) {
4086 DEBUG(5,("User %s doesn't exist.\n", pdb_get_username(sam_pass
)));
4087 pdb_free_sam(&sam_pass
);
4088 return NT_STATUS_NO_SUCH_USER
;
4091 /* if the user is not in the group */
4092 if (!user_in_unix_group(pdb_get_username(sam_pass
), grp_name
)) {
4093 pdb_free_sam(&sam_pass
);
4094 return NT_STATUS_MEMBER_NOT_IN_GROUP
;
4098 se_priv_copy( &se_rights
, &se_add_users
);
4099 can_add_accounts
= user_has_privileges( p
->pipe_user
.nt_user_token
, &se_rights
);
4101 /******** BEGIN SeAddUsers BLOCK *********/
4103 if ( can_add_accounts
)
4106 smb_delete_user_group(grp_name
, pdb_get_username(sam_pass
));
4108 if ( can_add_accounts
)
4111 /******** END SeAddUsers BLOCK *********/
4113 /* check if the user has been removed then ... */
4114 if (user_in_unix_group(pdb_get_username(sam_pass
), grp_name
)) {
4115 pdb_free_sam(&sam_pass
);
4116 return NT_STATUS_ACCESS_DENIED
; /* don't know what to reply else */
4119 pdb_free_sam(&sam_pass
);
4121 force_flush_samr_cache(disp_info
);
4123 return NT_STATUS_OK
;
4127 /****************************************************************************
4128 Delete a UNIX user on demand.
4129 ****************************************************************************/
4131 static int smb_delete_user(const char *unix_user
)
4136 pstrcpy(del_script
, lp_deluser_script());
4139 all_string_sub(del_script
, "%u", unix_user
, sizeof(del_script
));
4140 ret
= smbrun(del_script
,NULL
);
4141 flush_pwnam_cache();
4142 DEBUG(ret
? 0 : 3,("smb_delete_user: Running the command `%s' gave %d\n",del_script
,ret
));
4147 /*********************************************************************
4148 _samr_delete_dom_user
4149 *********************************************************************/
4151 NTSTATUS
_samr_delete_dom_user(pipes_struct
*p
, SAMR_Q_DELETE_DOM_USER
*q_u
, SAMR_R_DELETE_DOM_USER
*r_u
)
4154 SAM_ACCOUNT
*sam_pass
=NULL
;
4156 BOOL can_add_accounts
;
4158 DISP_INFO
*disp_info
= NULL
;
4160 DEBUG(5, ("_samr_delete_dom_user: %d\n", __LINE__
));
4162 /* Find the policy handle. Open a policy on it. */
4163 if (!get_lsa_policy_samr_sid(p
, &q_u
->user_pol
, &user_sid
, &acc_granted
, &disp_info
))
4164 return NT_STATUS_INVALID_HANDLE
;
4166 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, STD_RIGHT_DELETE_ACCESS
, "_samr_delete_dom_user"))) {
4170 if (!sid_check_is_in_our_domain(&user_sid
))
4171 return NT_STATUS_CANNOT_DELETE
;
4173 /* check if the user exists before trying to delete */
4174 pdb_init_sam(&sam_pass
);
4175 if(!pdb_getsampwsid(sam_pass
, &user_sid
)) {
4176 DEBUG(5,("_samr_delete_dom_user:User %s doesn't exist.\n",
4177 sid_string_static(&user_sid
)));
4178 pdb_free_sam(&sam_pass
);
4179 return NT_STATUS_NO_SUCH_USER
;
4182 can_add_accounts
= user_has_privileges( p
->pipe_user
.nt_user_token
, &se_add_users
);
4184 /******** BEGIN SeAddUsers BLOCK *********/
4186 if ( can_add_accounts
)
4189 /* First delete the samba side....
4190 code is order to prevent unnecessary returns out of the admin
4193 if ( (ret
= pdb_delete_sam_account(sam_pass
)) == True
) {
4195 * Now delete the unix side ....
4196 * note: we don't check if the delete really happened
4197 * as the script is not necessary present
4198 * and maybe the sysadmin doesn't want to delete the unix side
4200 smb_delete_user( pdb_get_username(sam_pass
) );
4203 if ( can_add_accounts
)
4206 /******** END SeAddUsers BLOCK *********/
4209 DEBUG(5,("_samr_delete_dom_user:Failed to delete entry for user %s.\n", pdb_get_username(sam_pass
)));
4210 pdb_free_sam(&sam_pass
);
4211 return NT_STATUS_CANNOT_DELETE
;
4215 pdb_free_sam(&sam_pass
);
4217 if (!close_policy_hnd(p
, &q_u
->user_pol
))
4218 return NT_STATUS_OBJECT_NAME_INVALID
;
4220 force_flush_samr_cache(disp_info
);
4222 return NT_STATUS_OK
;
4225 /*********************************************************************
4226 _samr_delete_dom_group
4227 *********************************************************************/
4229 NTSTATUS
_samr_delete_dom_group(pipes_struct
*p
, SAMR_Q_DELETE_DOM_GROUP
*q_u
, SAMR_R_DELETE_DOM_GROUP
*r_u
)
4234 fstring group_sid_str
;
4240 BOOL can_add_accounts
;
4242 DISP_INFO
*disp_info
= NULL
;
4244 DEBUG(5, ("samr_delete_dom_group: %d\n", __LINE__
));
4246 /* Find the policy handle. Open a policy on it. */
4247 if (!get_lsa_policy_samr_sid(p
, &q_u
->group_pol
, &group_sid
, &acc_granted
, &disp_info
))
4248 return NT_STATUS_INVALID_HANDLE
;
4250 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, STD_RIGHT_DELETE_ACCESS
, "_samr_delete_dom_group"))) {
4254 sid_copy(&dom_sid
, &group_sid
);
4255 sid_to_string(group_sid_str
, &dom_sid
);
4256 sid_split_rid(&dom_sid
, &group_rid
);
4258 DEBUG(10, ("sid is %s\n", group_sid_str
));
4260 /* we check if it's our SID before deleting */
4261 if (!sid_equal(&dom_sid
, get_global_sam_sid()))
4262 return NT_STATUS_NO_SUCH_GROUP
;
4264 DEBUG(10, ("lookup on Domain SID\n"));
4266 if(!get_domain_group_from_sid(group_sid
, &map
))
4267 return NT_STATUS_NO_SUCH_GROUP
;
4271 /* check if group really exists */
4272 if ( (grp
=getgrgid(gid
)) == NULL
)
4273 return NT_STATUS_NO_SUCH_GROUP
;
4275 se_priv_copy( &se_rights
, &se_add_users
);
4276 can_add_accounts
= user_has_privileges( p
->pipe_user
.nt_user_token
, &se_rights
);
4278 /******** BEGIN SeAddUsers BLOCK *********/
4280 if ( can_add_accounts
)
4283 /* delete mapping first */
4285 if ( (ret
= pdb_delete_group_mapping_entry(group_sid
)) == True
) {
4286 smb_delete_group( grp
->gr_name
);
4289 if ( can_add_accounts
)
4292 /******** END SeAddUsers BLOCK *********/
4295 DEBUG(5,("_samr_delete_dom_group: Failed to delete mapping entry for group %s.\n",
4297 return NT_STATUS_ACCESS_DENIED
;
4300 /* don't check that the unix group has been deleted. Work like
4301 _samr_delet_dom_user() */
4303 if (!close_policy_hnd(p
, &q_u
->group_pol
))
4304 return NT_STATUS_OBJECT_NAME_INVALID
;
4306 force_flush_samr_cache(disp_info
);
4308 return NT_STATUS_OK
;
4311 /*********************************************************************
4312 _samr_delete_dom_alias
4313 *********************************************************************/
4315 NTSTATUS
_samr_delete_dom_alias(pipes_struct
*p
, SAMR_Q_DELETE_DOM_ALIAS
*q_u
, SAMR_R_DELETE_DOM_ALIAS
*r_u
)
4320 BOOL can_add_accounts
;
4322 DISP_INFO
*disp_info
= NULL
;
4324 DEBUG(5, ("_samr_delete_dom_alias: %d\n", __LINE__
));
4326 /* Find the policy handle. Open a policy on it. */
4327 if (!get_lsa_policy_samr_sid(p
, &q_u
->alias_pol
, &alias_sid
, &acc_granted
, &disp_info
))
4328 return NT_STATUS_INVALID_HANDLE
;
4330 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, STD_RIGHT_DELETE_ACCESS
, "_samr_delete_dom_alias"))) {
4334 DEBUG(10, ("sid is %s\n", sid_string_static(&alias_sid
)));
4336 if (!sid_check_is_in_our_domain(&alias_sid
))
4337 return NT_STATUS_NO_SUCH_ALIAS
;
4339 DEBUG(10, ("lookup on Local SID\n"));
4341 se_priv_copy( &se_rights
, &se_add_users
);
4342 can_add_accounts
= user_has_privileges( p
->pipe_user
.nt_user_token
, &se_rights
);
4344 /******** BEGIN SeAddUsers BLOCK *********/
4346 if ( can_add_accounts
)
4349 /* Have passdb delete the alias */
4350 ret
= pdb_delete_alias(&alias_sid
);
4352 if ( can_add_accounts
)
4355 /******** END SeAddUsers BLOCK *********/
4358 return NT_STATUS_ACCESS_DENIED
;
4360 if (!close_policy_hnd(p
, &q_u
->alias_pol
))
4361 return NT_STATUS_OBJECT_NAME_INVALID
;
4363 force_flush_samr_cache(disp_info
);
4365 return NT_STATUS_OK
;
4368 /*********************************************************************
4369 _samr_create_dom_group
4370 *********************************************************************/
4372 NTSTATUS
_samr_create_dom_group(pipes_struct
*p
, SAMR_Q_CREATE_DOM_GROUP
*q_u
, SAMR_R_CREATE_DOM_GROUP
*r_u
)
4379 struct samr_info
*info
;
4383 BOOL can_add_accounts
;
4385 DISP_INFO
*disp_info
= NULL
;
4387 /* Find the policy handle. Open a policy on it. */
4388 if (!get_lsa_policy_samr_sid(p
, &q_u
->pol
, &dom_sid
, &acc_granted
, &disp_info
))
4389 return NT_STATUS_INVALID_HANDLE
;
4391 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, SA_RIGHT_DOMAIN_CREATE_GROUP
, "_samr_create_dom_group"))) {
4395 if (!sid_equal(&dom_sid
, get_global_sam_sid()))
4396 return NT_STATUS_ACCESS_DENIED
;
4398 unistr2_to_ascii(name
, &q_u
->uni_acct_desc
, sizeof(name
)-1);
4400 r_u
->status
= can_create(p
->mem_ctx
, name
);
4401 if (!NT_STATUS_IS_OK(r_u
->status
)) {
4405 se_priv_copy( &se_rights
, &se_add_users
);
4406 can_add_accounts
= user_has_privileges( p
->pipe_user
.nt_user_token
, &se_rights
);
4408 /******** BEGIN SeAddUsers BLOCK *********/
4410 if ( can_add_accounts
)
4413 /* check that we successfully create the UNIX group */
4415 result
= NT_STATUS_ACCESS_DENIED
;
4416 if ( (smb_create_group(name
, &gid
) == 0) && ((grp
=getgrgid(gid
)) != NULL
) ) {
4418 /* so far, so good */
4420 result
= NT_STATUS_OK
;
4422 if (pdb_rid_algorithm()) {
4423 r_u
->rid
= pdb_gid_to_group_rid( grp
->gr_gid
);
4425 if (!pdb_new_rid(&r_u
->rid
)) {
4426 result
= NT_STATUS_ACCESS_DENIED
;
4430 if (NT_STATUS_IS_OK(result
)) {
4432 /* add the group to the mapping table */
4434 sid_copy( &info_sid
, get_global_sam_sid() );
4435 sid_append_rid( &info_sid
, r_u
->rid
);
4436 sid_to_string( sid_string
, &info_sid
);
4438 /* reset the error code if we fail to add the mapping entry */
4440 if ( !add_initial_entry(grp
->gr_gid
, sid_string
, SID_NAME_DOM_GRP
, name
, NULL
) )
4441 result
= NT_STATUS_ACCESS_DENIED
;
4445 if ( can_add_accounts
)
4448 /******** END SeAddUsers BLOCK *********/
4450 /* check if we should bail out here */
4452 if ( !NT_STATUS_IS_OK(result
) )
4455 if ((info
= get_samr_info_by_sid(&info_sid
)) == NULL
)
4456 return NT_STATUS_NO_MEMORY
;
4459 /* they created it; let the user do what he wants with it */
4461 info
->acc_granted
= GENERIC_RIGHTS_GROUP_ALL_ACCESS
;
4463 /* get a (unique) handle. open a policy on it. */
4464 if (!create_policy_hnd(p
, &r_u
->pol
, free_samr_info
, (void *)info
))
4465 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
4467 force_flush_samr_cache(disp_info
);
4469 return NT_STATUS_OK
;
4472 /*********************************************************************
4473 _samr_create_dom_alias
4474 *********************************************************************/
4476 NTSTATUS
_samr_create_dom_alias(pipes_struct
*p
, SAMR_Q_CREATE_DOM_ALIAS
*q_u
, SAMR_R_CREATE_DOM_ALIAS
*r_u
)
4481 struct samr_info
*info
;
4486 BOOL can_add_accounts
;
4487 DISP_INFO
*disp_info
= NULL
;
4489 /* Find the policy handle. Open a policy on it. */
4490 if (!get_lsa_policy_samr_sid(p
, &q_u
->dom_pol
, &dom_sid
, &acc_granted
, &disp_info
))
4491 return NT_STATUS_INVALID_HANDLE
;
4493 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, SA_RIGHT_DOMAIN_CREATE_ALIAS
, "_samr_create_alias"))) {
4497 if (!sid_equal(&dom_sid
, get_global_sam_sid()))
4498 return NT_STATUS_ACCESS_DENIED
;
4500 unistr2_to_ascii(name
, &q_u
->uni_acct_desc
, sizeof(name
)-1);
4502 se_priv_copy( &se_rights
, &se_add_users
);
4503 can_add_accounts
= user_has_privileges( p
->pipe_user
.nt_user_token
, &se_rights
);
4505 result
= can_create(p
->mem_ctx
, name
);
4506 if (!NT_STATUS_IS_OK(result
)) {
4510 /******** BEGIN SeAddUsers BLOCK *********/
4512 if ( can_add_accounts
)
4515 /* Have passdb create the alias */
4516 result
= pdb_create_alias(name
, &r_u
->rid
);
4518 if ( can_add_accounts
)
4521 /******** END SeAddUsers BLOCK *********/
4523 if (!NT_STATUS_IS_OK(result
)) {
4524 DEBUG(10, ("pdb_create_alias failed: %s\n",
4525 nt_errstr(result
)));
4529 sid_copy(&info_sid
, get_global_sam_sid());
4530 sid_append_rid(&info_sid
, r_u
->rid
);
4532 if (!sid_to_gid(&info_sid
, &gid
)) {
4533 DEBUG(10, ("Could not find alias just created\n"));
4534 return NT_STATUS_ACCESS_DENIED
;
4537 /* check if the group has been successfully created */
4538 if ( getgrgid(gid
) == NULL
) {
4539 DEBUG(10, ("getgrgid(%d) of just created alias failed\n",
4541 return NT_STATUS_ACCESS_DENIED
;
4544 if ((info
= get_samr_info_by_sid(&info_sid
)) == NULL
)
4545 return NT_STATUS_NO_MEMORY
;
4547 /* they created it; let the user do what he wants with it */
4549 info
->acc_granted
= GENERIC_RIGHTS_ALIAS_ALL_ACCESS
;
4551 /* get a (unique) handle. open a policy on it. */
4552 if (!create_policy_hnd(p
, &r_u
->alias_pol
, free_samr_info
, (void *)info
))
4553 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
4555 force_flush_samr_cache(disp_info
);
4557 return NT_STATUS_OK
;
4560 /*********************************************************************
4561 _samr_query_groupinfo
4563 sends the name/comment pair of a domain group
4564 level 1 send also the number of users of that group
4565 *********************************************************************/
4567 NTSTATUS
_samr_query_groupinfo(pipes_struct
*p
, SAMR_Q_QUERY_GROUPINFO
*q_u
, SAMR_R_QUERY_GROUPINFO
*r_u
)
4574 GROUP_INFO_CTR
*ctr
;
4578 if (!get_lsa_policy_samr_sid(p
, &q_u
->pol
, &group_sid
, &acc_granted
, NULL
))
4579 return NT_STATUS_INVALID_HANDLE
;
4581 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, SA_RIGHT_GROUP_LOOKUP_INFO
, "_samr_query_groupinfo"))) {
4586 ret
= get_domain_group_from_sid(group_sid
, &map
);
4589 return NT_STATUS_INVALID_HANDLE
;
4591 ctr
=TALLOC_ZERO_P(p
->mem_ctx
, GROUP_INFO_CTR
);
4593 return NT_STATUS_NO_MEMORY
;
4595 switch (q_u
->switch_level
) {
4597 ctr
->switch_value1
= 1;
4598 if(!get_memberuids(map
.gid
, &uids
, &num
))
4599 return NT_STATUS_NO_SUCH_GROUP
;
4601 init_samr_group_info1(&ctr
->group
.info1
, map
.nt_name
, map
.comment
, num
);
4605 ctr
->switch_value1
= 3;
4606 init_samr_group_info3(&ctr
->group
.info3
);
4609 ctr
->switch_value1
= 4;
4610 init_samr_group_info4(&ctr
->group
.info4
, map
.comment
);
4613 return NT_STATUS_INVALID_INFO_CLASS
;
4616 init_samr_r_query_groupinfo(r_u
, ctr
, NT_STATUS_OK
);
4618 return NT_STATUS_OK
;
4621 /*********************************************************************
4624 update a domain group's comment.
4625 *********************************************************************/
4627 NTSTATUS
_samr_set_groupinfo(pipes_struct
*p
, SAMR_Q_SET_GROUPINFO
*q_u
, SAMR_R_SET_GROUPINFO
*r_u
)
4631 GROUP_INFO_CTR
*ctr
;
4635 BOOL can_mod_accounts
;
4636 DISP_INFO
*disp_info
= NULL
;
4638 if (!get_lsa_policy_samr_sid(p
, &q_u
->pol
, &group_sid
, &acc_granted
, &disp_info
))
4639 return NT_STATUS_INVALID_HANDLE
;
4641 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, SA_RIGHT_GROUP_SET_INFO
, "_samr_set_groupinfo"))) {
4646 result
= get_domain_group_from_sid(group_sid
, &map
);
4649 return NT_STATUS_NO_SUCH_GROUP
;
4653 switch (ctr
->switch_value1
) {
4655 unistr2_to_ascii(map
.comment
, &(ctr
->group
.info1
.uni_acct_desc
), sizeof(map
.comment
)-1);
4658 unistr2_to_ascii(map
.comment
, &(ctr
->group
.info4
.uni_acct_desc
), sizeof(map
.comment
)-1);
4661 return NT_STATUS_INVALID_INFO_CLASS
;
4664 can_mod_accounts
= user_has_privileges( p
->pipe_user
.nt_user_token
, &se_add_users
);
4666 /******** BEGIN SeAddUsers BLOCK *********/
4668 if ( can_mod_accounts
)
4671 ret
= pdb_update_group_mapping_entry(&map
);
4673 if ( can_mod_accounts
)
4676 /******** End SeAddUsers BLOCK *********/
4678 if (NT_STATUS_IS_OK(ret
)) {
4679 force_flush_samr_cache(disp_info
);
4685 /*********************************************************************
4688 update an alias's comment.
4689 *********************************************************************/
4691 NTSTATUS
_samr_set_aliasinfo(pipes_struct
*p
, SAMR_Q_SET_ALIASINFO
*q_u
, SAMR_R_SET_ALIASINFO
*r_u
)
4694 struct acct_info info
;
4695 ALIAS_INFO_CTR
*ctr
;
4698 BOOL can_mod_accounts
;
4699 DISP_INFO
*disp_info
= NULL
;
4701 if (!get_lsa_policy_samr_sid(p
, &q_u
->alias_pol
, &group_sid
, &acc_granted
, &disp_info
))
4702 return NT_STATUS_INVALID_HANDLE
;
4704 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, SA_RIGHT_ALIAS_SET_INFO
, "_samr_set_aliasinfo"))) {
4710 switch (ctr
->level
) {
4712 if ( ctr
->alias
.info3
.description
.string
) {
4713 unistr2_to_ascii( info
.acct_desc
,
4714 ctr
->alias
.info3
.description
.string
,
4715 sizeof(info
.acct_desc
)-1 );
4718 fstrcpy( info
.acct_desc
, "" );
4721 return NT_STATUS_INVALID_INFO_CLASS
;
4724 can_mod_accounts
= user_has_privileges( p
->pipe_user
.nt_user_token
, &se_add_users
);
4726 /******** BEGIN SeAddUsers BLOCK *********/
4728 if ( can_mod_accounts
)
4731 ret
= pdb_set_aliasinfo( &group_sid
, &info
);
4733 if ( can_mod_accounts
)
4736 /******** End SeAddUsers BLOCK *********/
4739 force_flush_samr_cache(disp_info
);
4742 return ret
? NT_STATUS_OK
: NT_STATUS_ACCESS_DENIED
;
4745 /*********************************************************************
4746 _samr_get_dom_pwinfo
4747 *********************************************************************/
4749 NTSTATUS
_samr_get_dom_pwinfo(pipes_struct
*p
, SAMR_Q_GET_DOM_PWINFO
*q_u
, SAMR_R_GET_DOM_PWINFO
*r_u
)
4751 /* Perform access check. Since this rpc does not require a
4752 policy handle it will not be caught by the access checks on
4753 SAMR_CONNECT or SAMR_CONNECT_ANON. */
4755 if (!pipe_access_check(p
)) {
4756 DEBUG(3, ("access denied to samr_get_dom_pwinfo\n"));
4757 r_u
->status
= NT_STATUS_ACCESS_DENIED
;
4761 /* Actually, returning zeros here works quite well :-). */
4763 return NT_STATUS_OK
;
4766 /*********************************************************************
4768 *********************************************************************/
4770 NTSTATUS
_samr_open_group(pipes_struct
*p
, SAMR_Q_OPEN_GROUP
*q_u
, SAMR_R_OPEN_GROUP
*r_u
)
4775 struct samr_info
*info
;
4776 SEC_DESC
*psd
= NULL
;
4778 uint32 des_access
= q_u
->access_mask
;
4785 if (!get_lsa_policy_samr_sid(p
, &q_u
->domain_pol
, &sid
, &acc_granted
, NULL
))
4786 return NT_STATUS_INVALID_HANDLE
;
4788 status
= access_check_samr_function(acc_granted
,
4789 SA_RIGHT_DOMAIN_OPEN_ACCOUNT
, "_samr_open_group");
4791 if ( !NT_STATUS_IS_OK(status
) )
4794 /*check if access can be granted as requested by client. */
4795 make_samr_object_sd(p
->mem_ctx
, &psd
, &sd_size
, &grp_generic_mapping
, NULL
, 0);
4796 se_map_generic(&des_access
,&grp_generic_mapping
);
4798 se_priv_copy( &se_rights
, &se_add_users
);
4800 status
= access_check_samr_object(psd
, p
->pipe_user
.nt_user_token
,
4801 &se_rights
, GENERIC_RIGHTS_GROUP_WRITE
, des_access
,
4802 &acc_granted
, "_samr_open_group");
4804 if ( !NT_STATUS_IS_OK(status
) )
4807 /* this should not be hard-coded like this */
4809 if (!sid_equal(&sid
, get_global_sam_sid()))
4810 return NT_STATUS_ACCESS_DENIED
;
4812 sid_copy(&info_sid
, get_global_sam_sid());
4813 sid_append_rid(&info_sid
, q_u
->rid_group
);
4814 sid_to_string(sid_string
, &info_sid
);
4816 if ((info
= get_samr_info_by_sid(&info_sid
)) == NULL
)
4817 return NT_STATUS_NO_MEMORY
;
4819 info
->acc_granted
= acc_granted
;
4821 DEBUG(10, ("_samr_open_group:Opening SID: %s\n", sid_string
));
4823 /* check if that group really exists */
4825 ret
= get_domain_group_from_sid(info
->sid
, &map
);
4828 return NT_STATUS_NO_SUCH_GROUP
;
4830 /* get a (unique) handle. open a policy on it. */
4831 if (!create_policy_hnd(p
, &r_u
->pol
, free_samr_info
, (void *)info
))
4832 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
4834 return NT_STATUS_OK
;
4837 /*********************************************************************
4838 _samr_remove_sid_foreign_domain
4839 *********************************************************************/
4841 NTSTATUS
_samr_remove_sid_foreign_domain(pipes_struct
*p
,
4842 SAMR_Q_REMOVE_SID_FOREIGN_DOMAIN
*q_u
,
4843 SAMR_R_REMOVE_SID_FOREIGN_DOMAIN
*r_u
)
4845 DOM_SID delete_sid
, domain_sid
;
4848 DISP_INFO
*disp_info
= NULL
;
4850 sid_copy( &delete_sid
, &q_u
->sid
.sid
);
4852 DEBUG(5,("_samr_remove_sid_foreign_domain: removing SID [%s]\n",
4853 sid_string_static(&delete_sid
)));
4855 /* Find the policy handle. Open a policy on it. */
4857 if (!get_lsa_policy_samr_sid(p
, &q_u
->dom_pol
, &domain_sid
,
4858 &acc_granted
, &disp_info
))
4859 return NT_STATUS_INVALID_HANDLE
;
4861 result
= access_check_samr_function(acc_granted
, STD_RIGHT_DELETE_ACCESS
,
4862 "_samr_remove_sid_foreign_domain");
4864 if (!NT_STATUS_IS_OK(result
))
4867 DEBUG(8, ("_samr_remove_sid_foreign_domain:sid is %s\n",
4868 sid_string_static(&domain_sid
)));
4870 /* we can only delete a user from a group since we don't have
4871 nested groups anyways. So in the latter case, just say OK */
4873 /* TODO: The above comment nowadays is bogus. Since we have nested
4874 * groups now, and aliases members are never reported out of the unix
4875 * group membership, the "just say OK" makes this call a no-op. For
4876 * us. This needs fixing however. */
4878 /* I've only ever seen this in the wild when deleting a user from
4879 * usrmgr.exe. domain_sid is the builtin domain, and the sid to delete
4880 * is the user about to be deleted. I very much suspect this is the
4881 * only application of this call. To verify this, let people report
4884 if (!sid_check_is_builtin(&domain_sid
)) {
4885 DEBUG(1,("_samr_remove_sid_foreign_domain: domain_sid = %s, "
4886 "global_sam_sid() = %s\n",
4887 sid_string_static(&domain_sid
),
4888 sid_string_static(get_global_sam_sid())));
4889 DEBUGADD(1,("please report to samba-technical@samba.org!\n"));
4890 return NT_STATUS_OK
;
4893 force_flush_samr_cache(disp_info
);
4895 result
= NT_STATUS_OK
;
4900 /*******************************************************************
4901 _samr_query_domain_info2
4902 ********************************************************************/
4904 NTSTATUS
_samr_query_domain_info2(pipes_struct
*p
,
4905 SAMR_Q_QUERY_DOMAIN_INFO2
*q_u
,
4906 SAMR_R_QUERY_DOMAIN_INFO2
*r_u
)
4908 struct samr_info
*info
= NULL
;
4910 uint32 min_pass_len
,pass_hist
,password_properties
;
4911 time_t u_expire
, u_min_age
;
4912 NTTIME nt_expire
, nt_min_age
;
4914 time_t u_lock_duration
, u_reset_time
;
4915 NTTIME nt_lock_duration
, nt_reset_time
;
4921 uint32 num_users
=0, num_groups
=0, num_aliases
=0;
4923 uint32 account_policy_temp
;
4928 if ((ctr
= TALLOC_ZERO_P(p
->mem_ctx
, SAM_UNK_CTR
)) == NULL
)
4929 return NT_STATUS_NO_MEMORY
;
4933 r_u
->status
= NT_STATUS_OK
;
4935 DEBUG(5,("_samr_query_domain_info2: %d\n", __LINE__
));
4937 /* find the policy handle. open a policy on it. */
4938 if (!find_policy_by_hnd(p
, &q_u
->domain_pol
, (void **)(void *)&info
))
4939 return NT_STATUS_INVALID_HANDLE
;
4941 switch (q_u
->switch_value
) {
4943 pdb_get_account_policy(AP_MIN_PASSWORD_LEN
, &account_policy_temp
);
4944 min_pass_len
= account_policy_temp
;
4946 pdb_get_account_policy(AP_PASSWORD_HISTORY
, &account_policy_temp
);
4947 pass_hist
= account_policy_temp
;
4949 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS
, &account_policy_temp
);
4950 password_properties
= account_policy_temp
;
4952 pdb_get_account_policy(AP_MAX_PASSWORD_AGE
, &account_policy_temp
);
4953 u_expire
= account_policy_temp
;
4955 pdb_get_account_policy(AP_MIN_PASSWORD_AGE
, &account_policy_temp
);
4956 u_min_age
= account_policy_temp
;
4958 unix_to_nt_time_abs(&nt_expire
, u_expire
);
4959 unix_to_nt_time_abs(&nt_min_age
, u_min_age
);
4961 init_unk_info1(&ctr
->info
.inf1
, (uint16
)min_pass_len
, (uint16
)pass_hist
,
4962 password_properties
, nt_expire
, nt_min_age
);
4966 num_users
= count_sam_users(info
->disp_info
, ACB_NORMAL
);
4967 num_groups
= count_sam_groups(info
->disp_info
);
4968 num_aliases
= count_sam_aliases(info
->disp_info
);
4971 pdb_get_account_policy(AP_TIME_TO_LOGOUT
, &account_policy_temp
);
4972 u_logout
= account_policy_temp
;
4974 unix_to_nt_time_abs(&nt_logout
, u_logout
);
4976 if (!pdb_get_seq_num(&seq_num
))
4977 seq_num
= time(NULL
);
4979 server_role
= ROLE_DOMAIN_PDC
;
4980 if (lp_server_role() == ROLE_DOMAIN_BDC
)
4981 server_role
= ROLE_DOMAIN_BDC
;
4983 init_unk_info2(&ctr
->info
.inf2
, lp_serverstring(), lp_workgroup(), global_myname(), seq_num
,
4984 num_users
, num_groups
, num_aliases
, nt_logout
, server_role
);
4987 pdb_get_account_policy(AP_TIME_TO_LOGOUT
, &account_policy_temp
);
4988 u_logout
= account_policy_temp
;
4990 unix_to_nt_time_abs(&nt_logout
, u_logout
);
4992 init_unk_info3(&ctr
->info
.inf3
, nt_logout
);
4995 init_unk_info5(&ctr
->info
.inf5
, global_myname());
4998 init_unk_info6(&ctr
->info
.inf6
);
5001 server_role
= ROLE_DOMAIN_PDC
;
5002 if (lp_server_role() == ROLE_DOMAIN_BDC
)
5003 server_role
= ROLE_DOMAIN_BDC
;
5005 init_unk_info7(&ctr
->info
.inf7
, server_role
);
5008 if (!pdb_get_seq_num(&seq_num
))
5009 seq_num
= time(NULL
);
5011 init_unk_info8(&ctr
->info
.inf8
, (uint32
) seq_num
);
5014 pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION
, &account_policy_temp
);
5015 u_lock_duration
= account_policy_temp
;
5016 if (u_lock_duration
!= -1)
5017 u_lock_duration
*= 60;
5019 pdb_get_account_policy(AP_RESET_COUNT_TIME
, &account_policy_temp
);
5020 u_reset_time
= account_policy_temp
* 60;
5022 pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT
, &account_policy_temp
);
5023 lockout
= account_policy_temp
;
5025 unix_to_nt_time_abs(&nt_lock_duration
, u_lock_duration
);
5026 unix_to_nt_time_abs(&nt_reset_time
, u_reset_time
);
5028 init_unk_info12(&ctr
->info
.inf12
, nt_lock_duration
, nt_reset_time
, (uint16
)lockout
);
5031 return NT_STATUS_INVALID_INFO_CLASS
;
5034 init_samr_r_samr_query_domain_info2(r_u
, q_u
->switch_value
, ctr
, NT_STATUS_OK
);
5036 DEBUG(5,("_samr_query_domain_info2: %d\n", __LINE__
));
5041 /*******************************************************************
5043 ********************************************************************/
5045 NTSTATUS
_samr_set_dom_info(pipes_struct
*p
, SAMR_Q_SET_DOMAIN_INFO
*q_u
, SAMR_R_SET_DOMAIN_INFO
*r_u
)
5047 time_t u_expire
, u_min_age
;
5049 time_t u_lock_duration
, u_reset_time
;
5051 r_u
->status
= NT_STATUS_OK
;
5053 DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__
));
5055 /* find the policy handle. open a policy on it. */
5056 if (!find_policy_by_hnd(p
, &q_u
->domain_pol
, NULL
))
5057 return NT_STATUS_INVALID_HANDLE
;
5059 DEBUG(5,("_samr_set_dom_info: switch_value: %d\n", q_u
->switch_value
));
5061 switch (q_u
->switch_value
) {
5063 u_expire
=nt_time_to_unix_abs(&q_u
->ctr
->info
.inf1
.expire
);
5064 u_min_age
=nt_time_to_unix_abs(&q_u
->ctr
->info
.inf1
.min_passwordage
);
5066 pdb_set_account_policy(AP_MIN_PASSWORD_LEN
, (uint32
)q_u
->ctr
->info
.inf1
.min_length_password
);
5067 pdb_set_account_policy(AP_PASSWORD_HISTORY
, (uint32
)q_u
->ctr
->info
.inf1
.password_history
);
5068 pdb_set_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS
, (uint32
)q_u
->ctr
->info
.inf1
.password_properties
);
5069 pdb_set_account_policy(AP_MAX_PASSWORD_AGE
, (int)u_expire
);
5070 pdb_set_account_policy(AP_MIN_PASSWORD_AGE
, (int)u_min_age
);
5075 u_logout
=nt_time_to_unix_abs(&q_u
->ctr
->info
.inf3
.logout
);
5076 pdb_set_account_policy(AP_TIME_TO_LOGOUT
, (int)u_logout
);
5085 u_lock_duration
=nt_time_to_unix_abs(&q_u
->ctr
->info
.inf12
.duration
);
5086 if (u_lock_duration
!= -1)
5087 u_lock_duration
/= 60;
5089 u_reset_time
=nt_time_to_unix_abs(&q_u
->ctr
->info
.inf12
.reset_count
)/60;
5091 pdb_set_account_policy(AP_LOCK_ACCOUNT_DURATION
, (int)u_lock_duration
);
5092 pdb_set_account_policy(AP_RESET_COUNT_TIME
, (int)u_reset_time
);
5093 pdb_set_account_policy(AP_BAD_ATTEMPT_LOCKOUT
, (uint32
)q_u
->ctr
->info
.inf12
.bad_attempt_lockout
);
5096 return NT_STATUS_INVALID_INFO_CLASS
;
5099 init_samr_r_set_domain_info(r_u
, NT_STATUS_OK
);
5101 DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__
));