/*
- Unix SMB/Netbios implementation.
- Version 2.0
+ Unix SMB/CIFS implementation.
Copyright (C) Luke Kenneth Casson Leighton 1996-2000.
Copyright (C) Tim Potter 2000.
Copyright (C) Re-written by Jeremy Allison 2000.
*/
#include "includes.h"
-#include "nterr.h"
-#include "sids.h"
-extern int DEBUGLEVEL;
+extern DOM_SID global_sid_Builtin;
/**********************************************************************************
Check if this ACE has a SID in common with the token.
**********************************************************************************/
-static BOOL token_sid_in_ace( NT_USER_TOKEN *token, SEC_ACE *ace)
+static BOOL token_sid_in_ace(const NT_USER_TOKEN *token, const SEC_ACE *ace)
{
size_t i;
for (i = 0; i < token->num_sids; i++) {
- if (sid_equal(&ace->sid, &token->user_sids[i]))
+ if (sid_equal(&ace->trustee, &token->user_sids[i]))
return True;
}
bits not yet granted. Zero means permission allowed (no more needed bits).
**********************************************************************************/
-static uint32 check_ace(SEC_ACE *ace, NT_USER_TOKEN *token, uint32 acc_desired,
+static uint32 check_ace(SEC_ACE *ace, const NT_USER_TOKEN *token, uint32 acc_desired,
NTSTATUS *status)
{
uint32 mask = ace->info.mask;
include other bits requested.
**********************************************************************************/
-static BOOL get_max_access( SEC_ACL *the_acl, NT_USER_TOKEN *token, uint32 *granted,
+static BOOL get_max_access( SEC_ACL *the_acl, const NT_USER_TOKEN *token, uint32 *granted,
uint32 desired,
NTSTATUS *status)
{
*/
*granted = acc_granted;
- *status = NT_STATUS_NOPROBLEMO;
+ *status = NT_STATUS_OK;
return True;
}
}
}
+/* Map standard access rights to object specific rights. This technique is
+ used to give meaning to assigning read, write, execute and all access to
+ objects. Each type of object has its own mapping of standard to object
+ specific access rights. */
+
+void se_map_standard(uint32 *access_mask, struct standard_mapping *mapping)
+{
+ uint32 old_mask = *access_mask;
+
+ if (*access_mask & READ_CONTROL_ACCESS) {
+ *access_mask &= ~READ_CONTROL_ACCESS;
+ *access_mask |= mapping->std_read;
+ }
+
+ if (*access_mask & (DELETE_ACCESS|WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS|SYNCHRONIZE_ACCESS)) {
+ *access_mask &= ~(DELETE_ACCESS|WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS|SYNCHRONIZE_ACCESS);
+ *access_mask |= mapping->std_all;
+ }
+
+ if (old_mask != *access_mask) {
+ DEBUG(10, ("se_map_standard(): mapped mask 0x%08x to 0x%08x\n",
+ old_mask, *access_mask));
+ }
+}
+
/*****************************************************************************
Check access rights of a user against a security descriptor. Look at
each ACE in the security descriptor until an access denied ACE denies
"Access-Checking" document in MSDN.
*****************************************************************************/
-BOOL se_access_check(SEC_DESC *sd, struct current_user *user,
+BOOL se_access_check(const SEC_DESC *sd, const NT_USER_TOKEN *token,
uint32 acc_desired, uint32 *acc_granted,
NTSTATUS *status)
{
size_t i;
SEC_ACL *the_acl;
fstring sid_str;
- NT_USER_TOKEN *token = user->nt_user_token ? user->nt_user_token : &anonymous_token;
uint32 tmp_acc_desired = acc_desired;
if (!status || !acc_granted)
return False;
- *status = NT_STATUS_NOPROBLEMO;
+ if (!token)
+ token = &anonymous_token;
+
+ *status = NT_STATUS_OK;
*acc_granted = 0;
- DEBUG(10,("se_access_check: requested access %x, for uid %u\n",
- (unsigned int)acc_desired, (unsigned int)user->uid ));
+ DEBUG(10,("se_access_check: requested access 0x%08x, for NT token with %u entries and first sid %s.\n",
+ (unsigned int)acc_desired, (unsigned int)token->num_sids,
+ sid_to_string(sid_str, &token->user_sids[0])));
/*
* No security descriptor or security descriptor with no DACL
/* ACL must have something in it */
if (!sd || (sd && (!(sd->type & SEC_DESC_DACL_PRESENT) || sd->dacl == NULL))) {
- *status = NT_STATUS_NOPROBLEMO;
+ *status = NT_STATUS_OK;
*acc_granted = acc_desired;
DEBUG(5, ("se_access_check: no sd or blank DACL, access allowed\n"));
return True;
}
/* The user sid is the first in the token */
-
- DEBUG(3, ("se_access_check: user sid is %s\n", sid_to_string(sid_str, &token->user_sids[0]) ));
-
- for (i = 1; i < token->num_sids; i++) {
- DEBUG(3, ("se_access_check: also %s\n",
- sid_to_string(sid_str, &token->user_sids[i])));
+ if (DEBUGLVL(3)) {
+ DEBUG(3, ("se_access_check: user sid is %s\n", sid_to_string(sid_str, &token->user_sids[PRIMARY_USER_SID_INDEX]) ));
+
+ for (i = 1; i < token->num_sids; i++) {
+ DEBUGADD(3, ("se_access_check: also %s\n",
+ sid_to_string(sid_str, &token->user_sids[i])));
+ }
}
/* Is the token the owner of the SID ? */
for ( i = 0 ; i < the_acl->num_aces && tmp_acc_desired != 0; i++) {
SEC_ACE *ace = &the_acl->ace[i];
- DEBUG(10,("se_access_check: ACE %u: type %d, flags = 0x%02x, SID = %s mask = %x, current desired = %x\n",
+ DEBUGADD(10,("se_access_check: ACE %u: type %d, flags = 0x%02x, SID = %s mask = %x, current desired = %x\n",
(unsigned int)i, ace->type, ace->flags,
- sid_to_string(sid_str, &ace->sid),
+ sid_to_string(sid_str, &ace->trustee),
(unsigned int) ace->info.mask,
(unsigned int)tmp_acc_desired ));
tmp_acc_desired = check_ace( ace, token, tmp_acc_desired, status);
if (NT_STATUS_V(*status)) {
*acc_granted = 0;
- DEBUG(5,("se_access_check: ACE %u denied with status %s.\n", (unsigned int)i, get_nt_error_msg(*status)));
+ DEBUG(5,("se_access_check: ACE %u denied with status %s.\n", (unsigned int)i, nt_errstr(*status)));
return False;
}
}
if (tmp_acc_desired == 0) {
*acc_granted = acc_desired;
- *status = NT_STATUS_NOPROBLEMO;
+ *status = NT_STATUS_OK;
DEBUG(5,("se_access_check: access (%x) granted.\n", (unsigned int)acc_desired ));
return True;
}
continue;
init_sec_access(&new_ace->info, ace->info.mask);
- init_sec_ace(new_ace, &ace->sid, ace->type,
+ init_sec_ace(new_ace, &ace->trustee, ace->type,
new_ace->info, new_flags);
- sid_to_string(sid_str, &ace->sid);
+ sid_to_string(sid_str, &ace->trustee);
DEBUG(5, ("se_create_child_secdesc(): %s:%d/0x%02x/0x%08x "
" inherited as %s:%d/0x%02x/0x%08x\n", sid_str,
return sdb;
}
+
+/*******************************************************************
+ samr_make_sam_obj_sd
+ ********************************************************************/
+
+NTSTATUS samr_make_sam_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
+{
+ extern DOM_SID global_sid_World;
+ DOM_SID adm_sid;
+ DOM_SID act_sid;
+
+ SEC_ACE ace[3];
+ SEC_ACCESS mask;
+
+ SEC_ACL *psa = NULL;
+
+ sid_copy(&adm_sid, &global_sid_Builtin);
+ sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
+
+ sid_copy(&act_sid, &global_sid_Builtin);
+ sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
+
+ /*basic access for every one*/
+ init_sec_access(&mask, GENERIC_RIGHTS_SAM_EXECUTE | GENERIC_RIGHTS_SAM_READ);
+ init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
+
+ /*full access for builtin aliases Administrators and Account Operators*/
+ init_sec_access(&mask, GENERIC_RIGHTS_SAM_ALL_ACCESS);
+ init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
+ init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
+
+ if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
+ return NT_STATUS_NO_MEMORY;
+
+ if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, sd_size)) == NULL)
+ return NT_STATUS_NO_MEMORY;
+
+ return NT_STATUS_OK;
+}