* fhandler.cc (fhandler_base::fhaccess): Call check_registry_access
for registry keys/values if ntsec is on. * security.cc (check_access): New static function derived from check_file_access, but object type agnostic. (check_file_access): Only do file specific stuff. Call check_access. (check_registry_access): New access check function for registry keys/ values. * security.h (check_registry_access): Declare.
This commit is contained in:
parent
9367c0dcff
commit
1b4153db74
|
@ -1,3 +1,14 @@
|
||||||
|
2006-10-21 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
|
* fhandler.cc (fhandler_base::fhaccess): Call check_registry_access
|
||||||
|
for registry keys/values if ntsec is on.
|
||||||
|
* security.cc (check_access): New static function derived from
|
||||||
|
check_file_access, but object type agnostic.
|
||||||
|
(check_file_access): Only do file specific stuff. Call check_access.
|
||||||
|
(check_registry_access): New access check function for registry keys/
|
||||||
|
values.
|
||||||
|
* security.h (check_registry_access): Declare.
|
||||||
|
|
||||||
2006-10-21 Corinna Vinschen <corinna@vinschen.de>
|
2006-10-21 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
* fhandler_registry.cc (fhandler_registry::fstat): Set restrictive
|
* fhandler_registry.cc (fhandler_registry::fstat): Set restrictive
|
||||||
|
|
|
@ -388,6 +388,12 @@ fhandler_base::fhaccess (int flags)
|
||||||
res = check_file_access (get_win32_name (), flags);
|
res = check_file_access (get_win32_name (), flags);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
else if (get_device () == FH_REGISTRY && allow_ntsec && open (O_RDONLY, 0))
|
||||||
|
{
|
||||||
|
res = check_registry_access (get_handle (), flags);
|
||||||
|
close ();
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
struct __stat64 st;
|
struct __stat64 st;
|
||||||
if (fstat (&st))
|
if (fstat (&st))
|
||||||
|
|
|
@ -1944,38 +1944,19 @@ set_file_attribute (bool use_ntsec, HANDLE handle, const char *file,
|
||||||
myself->uid, myself->gid, attribute);
|
myself->uid, myself->gid, attribute);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
static int
|
||||||
check_file_access (const char *fn, int flags)
|
check_access (security_descriptor &sd, GENERIC_MAPPING &mapping,
|
||||||
|
DWORD desired, int flags)
|
||||||
{
|
{
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
|
|
||||||
security_descriptor sd;
|
|
||||||
|
|
||||||
HANDLE hToken;
|
|
||||||
BOOL status;
|
BOOL status;
|
||||||
DWORD desired = 0, granted;
|
DWORD granted;
|
||||||
DWORD plength = sizeof (PRIVILEGE_SET) + 3 * sizeof (LUID_AND_ATTRIBUTES);
|
DWORD plen = sizeof (PRIVILEGE_SET) + 3 * sizeof (LUID_AND_ATTRIBUTES);
|
||||||
PPRIVILEGE_SET pset = (PPRIVILEGE_SET) alloca (plength);
|
PPRIVILEGE_SET pset = (PPRIVILEGE_SET) alloca (plen);
|
||||||
static GENERIC_MAPPING NO_COPY mapping = { FILE_GENERIC_READ,
|
HANDLE tok = cygheap->user.issetuid () ? cygheap->user.token ()
|
||||||
FILE_GENERIC_WRITE,
|
: hProcImpToken;
|
||||||
FILE_GENERIC_EXECUTE,
|
|
||||||
FILE_ALL_ACCESS };
|
|
||||||
if (read_sd (fn, sd) <= 0)
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
if (cygheap->user.issetuid ())
|
if (!AccessCheck (sd, tok, desired, &mapping, pset, &plen, &granted, &status))
|
||||||
hToken = cygheap->user.token ();
|
|
||||||
else
|
|
||||||
hToken = hProcImpToken;
|
|
||||||
|
|
||||||
if (flags & R_OK)
|
|
||||||
desired |= FILE_READ_DATA;
|
|
||||||
if (flags & W_OK)
|
|
||||||
desired |= FILE_WRITE_DATA;
|
|
||||||
if (flags & X_OK)
|
|
||||||
desired |= FILE_EXECUTE;
|
|
||||||
if (!AccessCheck (sd, hToken, desired, &mapping,
|
|
||||||
pset, &plength, &granted, &status))
|
|
||||||
__seterrno ();
|
__seterrno ();
|
||||||
else if (!status)
|
else if (!status)
|
||||||
{
|
{
|
||||||
|
@ -1993,31 +1974,73 @@ check_file_access (const char *fn, int flags)
|
||||||
backup/restore privileges has to be made. Sigh. */
|
backup/restore privileges has to be made. Sigh. */
|
||||||
int granted_flags = 0;
|
int granted_flags = 0;
|
||||||
if (flags & R_OK)
|
if (flags & R_OK)
|
||||||
{
|
{
|
||||||
pset->PrivilegeCount = 1;
|
pset->PrivilegeCount = 1;
|
||||||
pset->Control = 0;
|
pset->Control = 0;
|
||||||
pset->Privilege[0].Luid = *privilege_luid (SE_BACKUP_PRIV);
|
pset->Privilege[0].Luid = *privilege_luid (SE_BACKUP_PRIV);
|
||||||
pset->Privilege[0].Attributes = 0;
|
pset->Privilege[0].Attributes = 0;
|
||||||
if (PrivilegeCheck (hToken, pset, &status) && status)
|
if (PrivilegeCheck (tok, pset, &status) && status)
|
||||||
granted_flags |= R_OK;
|
granted_flags |= R_OK;
|
||||||
}
|
}
|
||||||
if (flags & W_OK)
|
if (flags & W_OK)
|
||||||
{
|
{
|
||||||
pset->PrivilegeCount = 1;
|
pset->PrivilegeCount = 1;
|
||||||
pset->Control = 0;
|
pset->Control = 0;
|
||||||
pset->Privilege[0].Luid = *privilege_luid (SE_RESTORE_PRIV);
|
pset->Privilege[0].Luid = *privilege_luid (SE_RESTORE_PRIV);
|
||||||
pset->Privilege[0].Attributes = 0;
|
pset->Privilege[0].Attributes = 0;
|
||||||
if (PrivilegeCheck (hToken, pset, &status) && status)
|
if (PrivilegeCheck (tok, pset, &status) && status)
|
||||||
granted_flags |= W_OK;
|
granted_flags |= W_OK;
|
||||||
}
|
}
|
||||||
if (granted_flags == flags)
|
if (granted_flags == flags)
|
||||||
ret = 0;
|
ret = 0;
|
||||||
else
|
else
|
||||||
set_errno (EACCES);
|
set_errno (EACCES);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
ret = 0;
|
ret = 0;
|
||||||
done:
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
check_file_access (const char *fn, int flags)
|
||||||
|
{
|
||||||
|
security_descriptor sd;
|
||||||
|
int ret = -1;
|
||||||
|
static GENERIC_MAPPING NO_COPY mapping = { FILE_GENERIC_READ,
|
||||||
|
FILE_GENERIC_WRITE,
|
||||||
|
FILE_GENERIC_EXECUTE,
|
||||||
|
FILE_ALL_ACCESS };
|
||||||
|
DWORD desired = 0;
|
||||||
|
if (flags & R_OK)
|
||||||
|
desired |= FILE_READ_DATA;
|
||||||
|
if (flags & W_OK)
|
||||||
|
desired |= FILE_WRITE_DATA;
|
||||||
|
if (flags & X_OK)
|
||||||
|
desired |= FILE_EXECUTE;
|
||||||
|
if (read_sd (fn, sd) > 0)
|
||||||
|
ret = check_access (sd, mapping, desired, flags);
|
||||||
|
debug_printf ("flags %x, ret %d", flags, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
check_registry_access (HANDLE hdl, int flags)
|
||||||
|
{
|
||||||
|
security_descriptor sd;
|
||||||
|
int ret = -1;
|
||||||
|
static GENERIC_MAPPING NO_COPY mapping = { KEY_READ,
|
||||||
|
KEY_WRITE,
|
||||||
|
KEY_EXECUTE,
|
||||||
|
KEY_ALL_ACCESS };
|
||||||
|
DWORD desired = 0;
|
||||||
|
if (flags & R_OK)
|
||||||
|
desired |= KEY_ENUMERATE_SUB_KEYS;
|
||||||
|
if (flags & W_OK)
|
||||||
|
desired |= KEY_SET_VALUE;
|
||||||
|
if (flags & X_OK)
|
||||||
|
desired |= KEY_QUERY_VALUE;
|
||||||
|
if (!get_reg_security (hdl, sd))
|
||||||
|
ret = check_access (sd, mapping, desired, flags);
|
||||||
debug_printf ("flags %x, ret %d", flags, ret);
|
debug_printf ("flags %x, ret %d", flags, ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -302,6 +302,7 @@ LONG __stdcall write_sd (HANDLE fh, const char *file, security_descriptor &sd);
|
||||||
bool __stdcall add_access_allowed_ace (PACL acl, int offset, DWORD attributes, PSID sid, size_t &len_add, DWORD inherit);
|
bool __stdcall add_access_allowed_ace (PACL acl, int offset, DWORD attributes, PSID sid, size_t &len_add, DWORD inherit);
|
||||||
bool __stdcall add_access_denied_ace (PACL acl, int offset, DWORD attributes, PSID sid, size_t &len_add, DWORD inherit);
|
bool __stdcall add_access_denied_ace (PACL acl, int offset, DWORD attributes, PSID sid, size_t &len_add, DWORD inherit);
|
||||||
int __stdcall check_file_access (const char *, int);
|
int __stdcall check_file_access (const char *, int);
|
||||||
|
int __stdcall check_registry_access (HANDLE, int);
|
||||||
|
|
||||||
void set_security_attribute (int attribute, PSECURITY_ATTRIBUTES psa,
|
void set_security_attribute (int attribute, PSECURITY_ATTRIBUTES psa,
|
||||||
security_descriptor &sd_buf);
|
security_descriptor &sd_buf);
|
||||||
|
|
Loading…
Reference in New Issue