mirror of
https://github.com/samba-team/samba.git
synced 2025-12-09 00:23:50 +03:00
Unify se_access_check with the S4 code. Will make
calculation of SEC_FLAG_MAXIMUM_ALLOWED much easier for files. Jeremy.
This commit is contained in:
@@ -1417,9 +1417,8 @@ WERROR registry_push_value(TALLOC_CTX *mem_ctx,
|
|||||||
void se_map_generic(uint32 *access_mask, const struct generic_mapping *mapping);
|
void se_map_generic(uint32 *access_mask, const struct generic_mapping *mapping);
|
||||||
void security_acl_map_generic(struct security_acl *sa, const struct generic_mapping *mapping);
|
void security_acl_map_generic(struct security_acl *sa, const struct generic_mapping *mapping);
|
||||||
void se_map_standard(uint32 *access_mask, struct standard_mapping *mapping);
|
void se_map_standard(uint32 *access_mask, struct standard_mapping *mapping);
|
||||||
bool se_access_check(const SEC_DESC *sd, const NT_USER_TOKEN *token,
|
NTSTATUS se_access_check(const SEC_DESC *sd, const NT_USER_TOKEN *token,
|
||||||
uint32 acc_desired, uint32 *acc_granted,
|
uint32 acc_desired, uint32 *acc_granted);
|
||||||
NTSTATUS *status);
|
|
||||||
NTSTATUS samr_make_sam_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size);
|
NTSTATUS samr_make_sam_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size);
|
||||||
|
|
||||||
/* The following definitions come from lib/util_sec.c */
|
/* The following definitions come from lib/util_sec.c */
|
||||||
|
|||||||
@@ -287,11 +287,11 @@ bool share_access_check(const NT_USER_TOKEN *token, const char *sharename,
|
|||||||
return True;
|
return True;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = se_access_check(psd, token, desired_access, &granted, &status);
|
status = se_access_check(psd, token, desired_access, &granted);
|
||||||
|
|
||||||
TALLOC_FREE(psd);
|
TALLOC_FREE(psd);
|
||||||
|
|
||||||
return ret;
|
return NT_STATUS_IS_OK(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
/*
|
/*
|
||||||
Unix SMB/CIFS implementation.
|
Unix SMB/CIFS implementation.
|
||||||
Copyright (C) Luke Kenneth Casson Leighton 1996-2000.
|
|
||||||
Copyright (C) Tim Potter 2000.
|
Copyright (C) Andrew Tridgell 2004
|
||||||
Copyright (C) Re-written by Jeremy Allison 2000.
|
Copyright (C) Gerald Carter 2005
|
||||||
|
Copyright (C) Volker Lendecke 2007
|
||||||
|
Copyright (C) Jeremy Allison 2008
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -22,125 +24,6 @@
|
|||||||
|
|
||||||
extern NT_USER_TOKEN anonymous_token;
|
extern NT_USER_TOKEN anonymous_token;
|
||||||
|
|
||||||
/*********************************************************************************
|
|
||||||
Check an ACE against a SID. We return the remaining needed permission
|
|
||||||
bits not yet granted. Zero means permission allowed (no more needed bits).
|
|
||||||
**********************************************************************************/
|
|
||||||
|
|
||||||
static uint32 check_ace(SEC_ACE *ace, const NT_USER_TOKEN *token, uint32 acc_desired,
|
|
||||||
NTSTATUS *status)
|
|
||||||
{
|
|
||||||
uint32_t mask = ace->access_mask;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Inherit only is ignored.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (ace->flags & SEC_ACE_FLAG_INHERIT_ONLY) {
|
|
||||||
return acc_desired;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If this ACE has no SID in common with the token,
|
|
||||||
* ignore it as it cannot be used to make an access
|
|
||||||
* determination.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!token_sid_in_ace( token, ace))
|
|
||||||
return acc_desired;
|
|
||||||
|
|
||||||
switch (ace->type) {
|
|
||||||
case SEC_ACE_TYPE_ACCESS_ALLOWED:
|
|
||||||
/*
|
|
||||||
* This is explicitly allowed.
|
|
||||||
* Remove the bits from the remaining
|
|
||||||
* access required. Return the remaining
|
|
||||||
* bits needed.
|
|
||||||
*/
|
|
||||||
acc_desired &= ~mask;
|
|
||||||
break;
|
|
||||||
case SEC_ACE_TYPE_ACCESS_DENIED:
|
|
||||||
/*
|
|
||||||
* This is explicitly denied.
|
|
||||||
* If any bits match terminate here,
|
|
||||||
* we are denied.
|
|
||||||
*/
|
|
||||||
if (acc_desired & mask) {
|
|
||||||
*status = NT_STATUS_ACCESS_DENIED;
|
|
||||||
return 0xFFFFFFFF;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case SEC_ACE_TYPE_SYSTEM_ALARM:
|
|
||||||
case SEC_ACE_TYPE_SYSTEM_AUDIT:
|
|
||||||
*status = NT_STATUS_NOT_IMPLEMENTED;
|
|
||||||
return 0xFFFFFFFF;
|
|
||||||
default:
|
|
||||||
*status = NT_STATUS_INVALID_PARAMETER;
|
|
||||||
return 0xFFFFFFFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
return acc_desired;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************************
|
|
||||||
Maximum access was requested. Calculate the max possible. Fail if it doesn't
|
|
||||||
include other bits requested.
|
|
||||||
**********************************************************************************/
|
|
||||||
|
|
||||||
static bool get_max_access( SEC_ACL *the_acl, const NT_USER_TOKEN *token, uint32 *granted,
|
|
||||||
uint32 desired,
|
|
||||||
NTSTATUS *status)
|
|
||||||
{
|
|
||||||
uint32 acc_denied = 0;
|
|
||||||
uint32 acc_granted = 0;
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
for ( i = 0 ; i < the_acl->num_aces; i++) {
|
|
||||||
SEC_ACE *ace = &the_acl->aces[i];
|
|
||||||
uint32 mask = ace->access_mask;
|
|
||||||
|
|
||||||
if (!token_sid_in_ace( token, ace))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
switch (ace->type) {
|
|
||||||
case SEC_ACE_TYPE_ACCESS_ALLOWED:
|
|
||||||
acc_granted |= (mask & ~acc_denied);
|
|
||||||
break;
|
|
||||||
case SEC_ACE_TYPE_ACCESS_DENIED:
|
|
||||||
acc_denied |= (mask & ~acc_granted);
|
|
||||||
break;
|
|
||||||
case SEC_ACE_TYPE_SYSTEM_ALARM:
|
|
||||||
case SEC_ACE_TYPE_SYSTEM_AUDIT:
|
|
||||||
*status = NT_STATUS_NOT_IMPLEMENTED;
|
|
||||||
*granted = 0;
|
|
||||||
return False;
|
|
||||||
default:
|
|
||||||
*status = NT_STATUS_INVALID_PARAMETER;
|
|
||||||
*granted = 0;
|
|
||||||
return False;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If we were granted no access, or we desired bits that we
|
|
||||||
* didn't get, then deny.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if ((acc_granted == 0) || ((acc_granted & desired) != desired)) {
|
|
||||||
*status = NT_STATUS_ACCESS_DENIED;
|
|
||||||
*granted = 0;
|
|
||||||
return False;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Return the access we did get.
|
|
||||||
*/
|
|
||||||
|
|
||||||
*granted = acc_granted;
|
|
||||||
*status = NT_STATUS_OK;
|
|
||||||
return True;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Map generic access rights to object specific rights. This technique is
|
/* Map generic access rights to object specific rights. This technique is
|
||||||
used to give meaning to assigning read, write, execute and all access to
|
used to give meaning to assigning read, write, execute and all access to
|
||||||
objects. Each type of object has its own mapping of generic to object
|
objects. Each type of object has its own mapping of generic to object
|
||||||
@@ -203,13 +86,13 @@ void se_map_standard(uint32 *access_mask, struct standard_mapping *mapping)
|
|||||||
{
|
{
|
||||||
uint32 old_mask = *access_mask;
|
uint32 old_mask = *access_mask;
|
||||||
|
|
||||||
if (*access_mask & READ_CONTROL_ACCESS) {
|
if (*access_mask & SEC_STD_READ_CONTROL) {
|
||||||
*access_mask &= ~READ_CONTROL_ACCESS;
|
*access_mask &= ~SEC_STD_READ_CONTROL;
|
||||||
*access_mask |= mapping->std_read;
|
*access_mask |= mapping->std_read;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*access_mask & (DELETE_ACCESS|WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS|SYNCHRONIZE_ACCESS)) {
|
if (*access_mask & (SEC_STD_DELETE|SEC_STD_WRITE_DAC|SEC_STD_WRITE_OWNER|SEC_STD_SYNCHRONIZE)) {
|
||||||
*access_mask &= ~(DELETE_ACCESS|WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS|SYNCHRONIZE_ACCESS);
|
*access_mask &= ~(SEC_STD_DELETE|SEC_STD_WRITE_DAC|SEC_STD_WRITE_OWNER|SEC_STD_SYNCHRONIZE);
|
||||||
*access_mask |= mapping->std_all;
|
*access_mask |= mapping->std_all;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -219,122 +102,140 @@ void se_map_standard(uint32 *access_mask, struct standard_mapping *mapping)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************
|
/*
|
||||||
Check access rights of a user against a security descriptor. Look at
|
perform a SEC_FLAG_MAXIMUM_ALLOWED access check
|
||||||
each ACE in the security descriptor until an access denied ACE denies
|
*/
|
||||||
any of the desired rights to the user or any of the users groups, or one
|
static uint32_t access_check_max_allowed(const struct security_descriptor *sd,
|
||||||
or more ACEs explicitly grant all requested access rights. See
|
const NT_USER_TOKEN *token)
|
||||||
"Access-Checking" document in MSDN.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
bool se_access_check(const SEC_DESC *sd, const NT_USER_TOKEN *token,
|
|
||||||
uint32 acc_desired, uint32 *acc_granted,
|
|
||||||
NTSTATUS *status)
|
|
||||||
{
|
{
|
||||||
size_t i;
|
uint32_t denied = 0, granted = 0;
|
||||||
SEC_ACL *the_acl;
|
unsigned i;
|
||||||
uint32 tmp_acc_desired = acc_desired;
|
|
||||||
|
if (is_sid_in_token(token, sd->owner_sid)) {
|
||||||
if (!status || !acc_granted)
|
granted |= SEC_STD_WRITE_DAC | SEC_STD_READ_CONTROL | SEC_STD_DELETE;
|
||||||
return False;
|
} else if (user_has_privileges(token, &se_restore)) {
|
||||||
|
granted |= SEC_STD_DELETE;
|
||||||
if (!token)
|
|
||||||
token = &anonymous_token;
|
|
||||||
|
|
||||||
*status = NT_STATUS_OK;
|
|
||||||
*acc_granted = 0;
|
|
||||||
|
|
||||||
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_string_dbg(&token->user_sids[0])));
|
|
||||||
|
|
||||||
/*
|
|
||||||
* No security descriptor or security descriptor with no DACL
|
|
||||||
* present allows all access.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* ACL must have something in it */
|
|
||||||
|
|
||||||
if (!sd || (sd && (!(sd->type & SEC_DESC_DACL_PRESENT) || sd->dacl == NULL))) {
|
|
||||||
*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 */
|
if (sd->dacl == NULL) {
|
||||||
if (DEBUGLVL(3)) {
|
return granted & ~denied;
|
||||||
DEBUG(3, ("se_access_check: user sid is %s\n",
|
}
|
||||||
sid_string_dbg(
|
|
||||||
&token->user_sids[PRIMARY_USER_SID_INDEX])));
|
for (i = 0;i<sd->dacl->num_aces; i++) {
|
||||||
|
struct security_ace *ace = &sd->dacl->aces[i];
|
||||||
for (i = 1; i < token->num_sids; i++) {
|
|
||||||
DEBUGADD(3, ("se_access_check: also %s\n",
|
if (ace->flags & SEC_ACE_FLAG_INHERIT_ONLY) {
|
||||||
sid_string_dbg(&token->user_sids[i])));
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_sid_in_token(token, &ace->trustee)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (ace->type) {
|
||||||
|
case SEC_ACE_TYPE_ACCESS_ALLOWED:
|
||||||
|
granted |= ace->access_mask;
|
||||||
|
break;
|
||||||
|
case SEC_ACE_TYPE_ACCESS_DENIED:
|
||||||
|
case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT:
|
||||||
|
denied |= ace->access_mask;
|
||||||
|
break;
|
||||||
|
default: /* Other ACE types not handled/supported */
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Is the token the owner of the SID ? */
|
return granted & ~denied;
|
||||||
|
|
||||||
if (sd->owner_sid) {
|
|
||||||
for (i = 0; i < token->num_sids; i++) {
|
|
||||||
if (sid_equal(&token->user_sids[i], sd->owner_sid)) {
|
|
||||||
/*
|
|
||||||
* The owner always has SEC_RIGHTS_WRITE_DAC & READ_CONTROL.
|
|
||||||
*/
|
|
||||||
if (tmp_acc_desired & WRITE_DAC_ACCESS)
|
|
||||||
tmp_acc_desired &= ~WRITE_DAC_ACCESS;
|
|
||||||
if (tmp_acc_desired & READ_CONTROL_ACCESS)
|
|
||||||
tmp_acc_desired &= ~READ_CONTROL_ACCESS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
the_acl = sd->dacl;
|
|
||||||
|
|
||||||
if (tmp_acc_desired & MAXIMUM_ALLOWED_ACCESS) {
|
|
||||||
tmp_acc_desired &= ~MAXIMUM_ALLOWED_ACCESS;
|
|
||||||
return get_max_access( the_acl, token, acc_granted, tmp_acc_desired,
|
|
||||||
status);
|
|
||||||
}
|
|
||||||
|
|
||||||
for ( i = 0 ; i < the_acl->num_aces && tmp_acc_desired != 0; i++) {
|
|
||||||
SEC_ACE *ace = &the_acl->aces[i];
|
|
||||||
|
|
||||||
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_string_dbg(&ace->trustee),
|
|
||||||
(unsigned int) ace->access_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, nt_errstr(*status)));
|
|
||||||
return False;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If there are no more desired permissions left then
|
|
||||||
* access was allowed.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (tmp_acc_desired == 0) {
|
|
||||||
*acc_granted = acc_desired;
|
|
||||||
*status = NT_STATUS_OK;
|
|
||||||
DEBUG(5,("se_access_check: access (%x) granted.\n", (unsigned int)acc_desired ));
|
|
||||||
return True;
|
|
||||||
}
|
|
||||||
|
|
||||||
*acc_granted = 0;
|
|
||||||
*status = NT_STATUS_ACCESS_DENIED;
|
|
||||||
DEBUG(5,("se_access_check: access (%x) denied.\n", (unsigned int)acc_desired ));
|
|
||||||
return False;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
the main entry point for access checking.
|
||||||
|
*/
|
||||||
|
NTSTATUS se_access_check(const struct security_descriptor *sd,
|
||||||
|
const NT_USER_TOKEN *token,
|
||||||
|
uint32_t access_desired,
|
||||||
|
uint32_t *access_granted)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
uint32_t bits_remaining;
|
||||||
|
|
||||||
|
*access_granted = access_desired;
|
||||||
|
bits_remaining = access_desired;
|
||||||
|
|
||||||
|
/* handle the maximum allowed flag */
|
||||||
|
if (access_desired & SEC_FLAG_MAXIMUM_ALLOWED) {
|
||||||
|
access_desired |= access_check_max_allowed(sd, token);
|
||||||
|
access_desired &= ~SEC_FLAG_MAXIMUM_ALLOWED;
|
||||||
|
*access_granted = access_desired;
|
||||||
|
bits_remaining = access_desired & ~SEC_STD_DELETE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/* We need to support SeSecurityPrivilege for this. */
|
||||||
|
|
||||||
|
if (access_desired & SEC_FLAG_SYSTEM_SECURITY) {
|
||||||
|
if (user_has_privileges(token, &sec_security)) {
|
||||||
|
bits_remaining &= ~SEC_FLAG_SYSTEM_SECURITY;
|
||||||
|
} else {
|
||||||
|
return NT_STATUS_PRIVILEGE_NOT_HELD;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* a NULL dacl allows access */
|
||||||
|
if ((sd->type & SEC_DESC_DACL_PRESENT) && sd->dacl == NULL) {
|
||||||
|
*access_granted = access_desired;
|
||||||
|
return NT_STATUS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* the owner always gets SEC_STD_WRITE_DAC, SEC_STD_READ_CONTROL and SEC_STD_DELETE */
|
||||||
|
if ((bits_remaining & (SEC_STD_WRITE_DAC|SEC_STD_READ_CONTROL|SEC_STD_DELETE)) &&
|
||||||
|
is_sid_in_token(token, sd->owner_sid)) {
|
||||||
|
bits_remaining &= ~(SEC_STD_WRITE_DAC|SEC_STD_READ_CONTROL|SEC_STD_DELETE);
|
||||||
|
}
|
||||||
|
if ((bits_remaining & SEC_STD_DELETE) &&
|
||||||
|
user_has_privileges(token, &se_restore)) {
|
||||||
|
bits_remaining &= ~SEC_STD_DELETE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sd->dacl == NULL) {
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check each ace in turn. */
|
||||||
|
for (i=0; bits_remaining && i < sd->dacl->num_aces; i++) {
|
||||||
|
struct security_ace *ace = &sd->dacl->aces[i];
|
||||||
|
|
||||||
|
if (ace->flags & SEC_ACE_FLAG_INHERIT_ONLY) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_sid_in_token(token, &ace->trustee)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (ace->type) {
|
||||||
|
case SEC_ACE_TYPE_ACCESS_ALLOWED:
|
||||||
|
bits_remaining &= ~ace->access_mask;
|
||||||
|
break;
|
||||||
|
case SEC_ACE_TYPE_ACCESS_DENIED:
|
||||||
|
case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT:
|
||||||
|
if (bits_remaining & ace->access_mask) {
|
||||||
|
return NT_STATUS_ACCESS_DENIED;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default: /* Other ACE types not handled/supported */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
|
if (bits_remaining != 0) {
|
||||||
|
return NT_STATUS_ACCESS_DENIED;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NT_STATUS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
/*******************************************************************
|
/*******************************************************************
|
||||||
samr_make_sam_obj_sd
|
samr_make_sam_obj_sd
|
||||||
|
|||||||
@@ -376,11 +376,11 @@ static int open_acl_xattr(vfs_handle_struct *handle,
|
|||||||
&pdesc);
|
&pdesc);
|
||||||
if (NT_STATUS_IS_OK(status)) {
|
if (NT_STATUS_IS_OK(status)) {
|
||||||
/* See if we can access it. */
|
/* See if we can access it. */
|
||||||
if (!se_access_check(pdesc,
|
status = se_access_check(pdesc,
|
||||||
handle->conn->server_info->ptok,
|
handle->conn->server_info->ptok,
|
||||||
fsp->access_mask,
|
fsp->access_mask,
|
||||||
&access_granted,
|
&access_granted);
|
||||||
&status)) {
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
errno = map_errno_from_nt_status(status);
|
errno = map_errno_from_nt_status(status);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5825,10 +5825,10 @@ bool print_access_check(struct auth_serversupplied_info *server_info, int snum,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Check access */
|
/* Check access */
|
||||||
result = se_access_check(secdesc->sd, server_info->ptok, access_type,
|
status = se_access_check(secdesc->sd, server_info->ptok, access_type,
|
||||||
&access_granted, &status);
|
&access_granted);
|
||||||
|
|
||||||
DEBUG(4, ("access check was %s\n", result ? "SUCCESS" : "FAILURE"));
|
DEBUG(4, ("access check was %s\n", NT_STATUS_IS_OK(status) ? "SUCCESS" : "FAILURE"));
|
||||||
|
|
||||||
/* see if we need to try the printer admin list */
|
/* see if we need to try the printer admin list */
|
||||||
|
|
||||||
@@ -5842,11 +5842,11 @@ bool print_access_check(struct auth_serversupplied_info *server_info, int snum,
|
|||||||
|
|
||||||
talloc_destroy(mem_ctx);
|
talloc_destroy(mem_ctx);
|
||||||
|
|
||||||
if (!result) {
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
errno = EACCES;
|
errno = EACCES;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return NT_STATUS_IS_OK(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
|||||||
@@ -170,7 +170,8 @@ bool regkey_access_check( REGISTRY_KEY *key, uint32 requested, uint32 *granted,
|
|||||||
|
|
||||||
se_map_generic( &requested, ®_generic_map );
|
se_map_generic( &requested, ®_generic_map );
|
||||||
|
|
||||||
if (!se_access_check(sec_desc, token, requested, granted, &status)) {
|
status =se_access_check(sec_desc, token, requested, granted);
|
||||||
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
TALLOC_FREE(mem_ctx);
|
TALLOC_FREE(mem_ctx);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -71,8 +71,7 @@ static bool elog_check_access( EVENTLOG_INFO *info, NT_USER_TOKEN *token )
|
|||||||
{
|
{
|
||||||
char *tdbname = elog_tdbname(talloc_tos(), info->logname );
|
char *tdbname = elog_tdbname(talloc_tos(), info->logname );
|
||||||
SEC_DESC *sec_desc;
|
SEC_DESC *sec_desc;
|
||||||
bool ret;
|
NTSTATUS status;
|
||||||
NTSTATUS ntstatus;
|
|
||||||
|
|
||||||
if ( !tdbname )
|
if ( !tdbname )
|
||||||
return False;
|
return False;
|
||||||
@@ -97,15 +96,15 @@ static bool elog_check_access( EVENTLOG_INFO *info, NT_USER_TOKEN *token )
|
|||||||
|
|
||||||
/* run the check, try for the max allowed */
|
/* run the check, try for the max allowed */
|
||||||
|
|
||||||
ret = se_access_check( sec_desc, token, MAXIMUM_ALLOWED_ACCESS,
|
status = se_access_check( sec_desc, token, MAXIMUM_ALLOWED_ACCESS,
|
||||||
&info->access_granted, &ntstatus );
|
&info->access_granted);
|
||||||
|
|
||||||
if ( sec_desc )
|
if ( sec_desc )
|
||||||
TALLOC_FREE( sec_desc );
|
TALLOC_FREE( sec_desc );
|
||||||
|
|
||||||
if ( !ret ) {
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
DEBUG(8,("elog_check_access: se_access_check() return %s\n",
|
DEBUG(8,("elog_check_access: se_access_check() return %s\n",
|
||||||
nt_errstr( ntstatus)));
|
nt_errstr(status)));
|
||||||
return False;
|
return False;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -381,7 +381,8 @@ NTSTATUS _lsa_OpenPolicy2(pipes_struct *p,
|
|||||||
/* get the generic lsa policy SD until we store it */
|
/* get the generic lsa policy SD until we store it */
|
||||||
lsa_get_generic_sd(p->mem_ctx, &psd, &sd_size);
|
lsa_get_generic_sd(p->mem_ctx, &psd, &sd_size);
|
||||||
|
|
||||||
if(!se_access_check(psd, p->pipe_user.nt_user_token, des_access, &acc_granted, &status)) {
|
status = se_access_check(psd, p->pipe_user.nt_user_token, des_access, &acc_granted);
|
||||||
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
if (p->pipe_user.ut.uid != sec_initial_uid()) {
|
if (p->pipe_user.ut.uid != sec_initial_uid()) {
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
@@ -431,7 +432,8 @@ NTSTATUS _lsa_OpenPolicy(pipes_struct *p,
|
|||||||
/* get the generic lsa policy SD until we store it */
|
/* get the generic lsa policy SD until we store it */
|
||||||
lsa_get_generic_sd(p->mem_ctx, &psd, &sd_size);
|
lsa_get_generic_sd(p->mem_ctx, &psd, &sd_size);
|
||||||
|
|
||||||
if(!se_access_check(psd, p->pipe_user.nt_user_token, des_access, &acc_granted, &status)) {
|
status = se_access_check(psd, p->pipe_user.nt_user_token, des_access, &acc_granted);
|
||||||
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
if (p->pipe_user.ut.uid != sec_initial_uid()) {
|
if (p->pipe_user.ut.uid != sec_initial_uid()) {
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -186,8 +186,10 @@ static NTSTATUS access_check_samr_object( SEC_DESC *psd, NT_USER_TOKEN *token,
|
|||||||
|
|
||||||
/* check the security descriptor first */
|
/* check the security descriptor first */
|
||||||
|
|
||||||
if ( se_access_check(psd, token, des_access, acc_granted, &status) )
|
status = se_access_check(psd, token, des_access, acc_granted);
|
||||||
|
if (NT_STATUS_IS_OK(status)) {
|
||||||
goto done;
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
/* give root a free pass */
|
/* give root a free pass */
|
||||||
|
|
||||||
|
|||||||
@@ -123,16 +123,12 @@ static struct service_control_op* find_service_by_name( const char *name )
|
|||||||
static NTSTATUS svcctl_access_check( SEC_DESC *sec_desc, NT_USER_TOKEN *token,
|
static NTSTATUS svcctl_access_check( SEC_DESC *sec_desc, NT_USER_TOKEN *token,
|
||||||
uint32 access_desired, uint32 *access_granted )
|
uint32 access_desired, uint32 *access_granted )
|
||||||
{
|
{
|
||||||
NTSTATUS result;
|
|
||||||
|
|
||||||
if ( geteuid() == sec_initial_uid() ) {
|
if ( geteuid() == sec_initial_uid() ) {
|
||||||
DEBUG(5,("svcctl_access_check: using root's token\n"));
|
DEBUG(5,("svcctl_access_check: using root's token\n"));
|
||||||
token = get_root_nt_token();
|
token = get_root_nt_token();
|
||||||
}
|
}
|
||||||
|
|
||||||
se_access_check( sec_desc, token, access_desired, access_granted, &result );
|
return se_access_check( sec_desc, token, access_desired, access_granted);
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************************************************************
|
/********************************************************************
|
||||||
|
|||||||
@@ -30,7 +30,6 @@ bool can_access_file_acl(struct connection_struct *conn,
|
|||||||
const char * fname,
|
const char * fname,
|
||||||
uint32_t access_mask)
|
uint32_t access_mask)
|
||||||
{
|
{
|
||||||
bool result;
|
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
uint32_t access_granted;
|
uint32_t access_granted;
|
||||||
struct security_descriptor *secdesc = NULL;
|
struct security_descriptor *secdesc = NULL;
|
||||||
@@ -45,10 +44,10 @@ bool can_access_file_acl(struct connection_struct *conn,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = se_access_check(secdesc, conn->server_info->ptok,
|
status = se_access_check(secdesc, conn->server_info->ptok,
|
||||||
access_mask, &access_granted, &status);
|
access_mask, &access_granted);
|
||||||
TALLOC_FREE(secdesc);
|
TALLOC_FREE(secdesc);
|
||||||
return result;
|
return NT_STATUS_IS_OK(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
|||||||
@@ -4285,16 +4285,15 @@ static void show_userlist(struct rpc_pipe_client *pipe_hnd,
|
|||||||
uint32 acc_granted;
|
uint32 acc_granted;
|
||||||
|
|
||||||
if (share_sd != NULL) {
|
if (share_sd != NULL) {
|
||||||
if (!se_access_check(share_sd, &tokens[i].token,
|
status = se_access_check(share_sd, &tokens[i].token,
|
||||||
1, &acc_granted, &status)) {
|
1, &acc_granted);
|
||||||
|
|
||||||
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
DEBUG(1, ("Could not check share_sd for "
|
DEBUG(1, ("Could not check share_sd for "
|
||||||
"user %s\n",
|
"user %s\n",
|
||||||
tokens[i].name));
|
tokens[i].name));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!NT_STATUS_IS_OK(status))
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (root_sd == NULL) {
|
if (root_sd == NULL) {
|
||||||
@@ -4302,16 +4301,13 @@ static void show_userlist(struct rpc_pipe_client *pipe_hnd,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!se_access_check(root_sd, &tokens[i].token,
|
status = se_access_check(root_sd, &tokens[i].token,
|
||||||
1, &acc_granted, &status)) {
|
1, &acc_granted);
|
||||||
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
DEBUG(1, ("Could not check root_sd for user %s\n",
|
DEBUG(1, ("Could not check root_sd for user %s\n",
|
||||||
tokens[i].name));
|
tokens[i].name));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!NT_STATUS_IS_OK(status))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
d_printf(" %s\n", tokens[i].name);
|
d_printf(" %s\n", tokens[i].name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user