* security.cc (get_info_from_sd): New function.

(get_nt_attribute): Only call read_sd and get_info_from_sd.
	Return void.
	(get_file_attribute): Move sd error handling to get_info_from_sd.
	and symlink handling to fhandler_disk_file::fstat_helper.
	(get_nt_object_attribute): Only call read_sd and get_info_from_sd.
	Return void.
	(get_object_attribute): Remove symlink handling and simply return -1
	when ntsec is off.
	* fhandler_disk_file.cc (fhandler_disk_file::fstat_helper): For
	symlinks set the attribute, call get_file_attribute to get the ids
	and return.  In the normal case call get_file_attribute with the
	addresses of the buffer ids and do not recheck if the file is a socket.
This commit is contained in:
Corinna Vinschen 2003-04-11 09:38:07 +00:00
parent 4cdc4de239
commit 2e23862a8a
3 changed files with 98 additions and 163 deletions

View File

@ -1,3 +1,19 @@
2003-04-11 Pierre Humblet <pierre.humblet@ieee.org>
* security.cc (get_info_from_sd): New function.
(get_nt_attribute): Only call read_sd and get_info_from_sd.
Return void.
(get_file_attribute): Move sd error handling to get_info_from_sd.
and symlink handling to fhandler_disk_file::fstat_helper.
(get_nt_object_attribute): Only call read_sd and get_info_from_sd.
Return void.
(get_object_attribute): Remove symlink handling and simply return -1
when ntsec is off.
* fhandler_disk_file.cc (fhandler_disk_file::fstat_helper): For
symlinks set the attribute, call get_file_attribute to get the ids
and return. In the normal case call get_file_attribute with the
addresses of the buffer ids and do not recheck if the file is a socket.
2003-04-10 Christopher Faylor <cgf@redhat.com> 2003-04-10 Christopher Faylor <cgf@redhat.com>
* cygthread.cc (cygthread::stub): Initialize stack pointer earlier. * cygthread.cc (cygthread::stub): Initialize stack pointer earlier.

View File

@ -281,14 +281,18 @@ fhandler_disk_file::fstat_helper (struct __stat64 *buf, path_conv *pc,
if (pc->isdir ()) if (pc->isdir ())
buf->st_mode = S_IFDIR; buf->st_mode = S_IFDIR;
else if (pc->issymlink ()) else if (pc->issymlink ())
buf->st_mode = S_IFLNK; {
/* symlinks are everything for everyone! */
buf->st_mode = S_IFLNK | S_IRWXU | S_IRWXG | S_IRWXO;
get_file_attribute (pc->has_acls (), get_win32_name (), NULL,
&buf->st_uid, &buf->st_gid);
goto done;
}
else if (pc->issocket ()) else if (pc->issocket ())
buf->st_mode = S_IFSOCK; buf->st_mode = S_IFSOCK;
__uid32_t uid;
__gid32_t gid;
if (get_file_attribute (pc->has_acls (), get_win32_name (), &buf->st_mode, if (get_file_attribute (pc->has_acls (), get_win32_name (), &buf->st_mode,
&uid, &gid) == 0) &buf->st_uid, &buf->st_gid) == 0)
{ {
/* If read-only attribute is set, modify ntsec return value */ /* If read-only attribute is set, modify ntsec return value */
if (pc->has_attribute (FILE_ATTRIBUTE_READONLY) && !get_symlink_p ()) if (pc->has_attribute (FILE_ATTRIBUTE_READONLY) && !get_symlink_p ())
@ -309,8 +313,6 @@ fhandler_disk_file::fstat_helper (struct __stat64 *buf, path_conv *pc,
buf->st_mode |= S_IFDIR | STD_XBITS; buf->st_mode |= S_IFDIR | STD_XBITS;
else if (buf->st_mode & S_IFMT) else if (buf->st_mode & S_IFMT)
/* nothing */; /* nothing */;
else if (pc->issocket ())
buf->st_mode |= S_IFSOCK;
else else
{ {
buf->st_mode |= S_IFREG; buf->st_mode |= S_IFREG;
@ -344,15 +346,12 @@ fhandler_disk_file::fstat_helper (struct __stat64 *buf, path_conv *pc,
buf->st_mode |= STD_XBITS; buf->st_mode |= STD_XBITS;
} }
buf->st_uid = uid;
buf->st_gid = gid;
/* The number of links to a directory includes the /* The number of links to a directory includes the
number of subdirectories in the directory, since all number of subdirectories in the directory, since all
those subdirectories point to it. those subdirectories point to it.
This is too slow on remote drives, so we do without it and This is too slow on remote drives, so we do without it and
set the number of links to 2. */ set the number of links to 2. */
done:
syscall_printf ("0 = fstat (, %p) st_atime=%x st_size=%D, st_mode=%p, st_ino=%d, sizeof=%d", syscall_printf ("0 = fstat (, %p) st_atime=%x st_size=%D, st_mode=%p, st_ino=%d, sizeof=%d",
buf, buf->st_atime, buf->st_size, buf->st_mode, buf, buf->st_atime, buf->st_size, buf->st_mode,
(int) buf->st_ino, sizeof (*buf)); (int) buf->st_ino, sizeof (*buf));

View File

@ -1318,22 +1318,21 @@ get_attribute_from_acl (mode_t *attribute, PACL acl, PSID owner_sid,
return; return;
} }
static int static void
get_nt_attribute (const char *file, mode_t *attribute, get_info_from_sd (PSECURITY_DESCRIPTOR psd, mode_t *attribute,
__uid32_t *uidret, __gid32_t *gidret) __uid32_t *uidret, __gid32_t *gidret)
{ {
syscall_printf ("file: %s", file); if (!psd)
/* Yeah, sounds too much, but I've seen SDs of 2100 bytes! */
DWORD sd_size = 4096;
char sd_buf[4096];
PSECURITY_DESCRIPTOR psd = (PSECURITY_DESCRIPTOR) sd_buf;
int ret;
if ((ret = read_sd (file, psd, &sd_size)) <= 0)
{ {
debug_printf ("read_sd %E"); /* If reading the security descriptor failed, treat the object
return -1; as unreadable. */
if (attribute)
*attribute &= ~(S_IRWXU | S_IRWXG | S_IRWXO);
if (uidret)
*uidret = ILLEGAL_UID;
if (gidret)
*gidret = ILLEGAL_GID;
return;
} }
cygpsid owner_sid; cygpsid owner_sid;
@ -1345,16 +1344,6 @@ get_nt_attribute (const char *file, mode_t *attribute,
if (!GetSecurityDescriptorGroup (psd, (PSID *) &group_sid, &dummy)) if (!GetSecurityDescriptorGroup (psd, (PSID *) &group_sid, &dummy))
debug_printf ("GetSecurityDescriptorGroup %E"); debug_printf ("GetSecurityDescriptorGroup %E");
PACL acl;
BOOL acl_exists;
if (!GetSecurityDescriptorDacl (psd, &acl_exists, &acl, &dummy))
{
__seterrno ();
debug_printf ("GetSecurityDescriptorDacl %E");
return -1;
}
__uid32_t uid; __uid32_t uid;
__gid32_t gid; __gid32_t gid;
BOOL grp_member = get_sids_info (owner_sid, group_sid, &uid, &gid); BOOL grp_member = get_sids_info (owner_sid, group_sid, &uid, &gid);
@ -1365,21 +1354,46 @@ get_nt_attribute (const char *file, mode_t *attribute,
if (!attribute) if (!attribute)
{ {
syscall_printf ("file: %s uid %d, gid %d", file, uid, gid); syscall_printf ("uid %d, gid %d", uid, gid);
return 0; return;
} }
if (!acl_exists || !acl) PACL acl;
BOOL acl_exists;
if (!GetSecurityDescriptorDacl (psd, &acl_exists, &acl, &dummy))
{ {
*attribute |= S_IRWXU | S_IRWXG | S_IRWXO; __seterrno ();
syscall_printf ("file: %s No ACL = %x, uid %d, gid %d", debug_printf ("GetSecurityDescriptorDacl %E");
file, *attribute, uid, gid); *attribute &= ~(S_IRWXU | S_IRWXG | S_IRWXO);
return 0;
} }
get_attribute_from_acl (attribute, acl, owner_sid, group_sid, grp_member); else if (!acl_exists || !acl)
*attribute |= S_IRWXU | S_IRWXG | S_IRWXO;
else
get_attribute_from_acl (attribute, acl, owner_sid, group_sid, grp_member);
syscall_printf ("file: %s %x, uid %d, gid %d", file, *attribute, uid, gid); syscall_printf ("%sACL = %x, uid %d, gid %d",
return 0; (!acl_exists || !acl)?"NO ":"", *attribute, uid, gid);
return;
}
static void
get_nt_attribute (const char *file, mode_t *attribute,
__uid32_t *uidret, __gid32_t *gidret)
{
/* Yeah, sounds too much, but I've seen SDs of 2100 bytes! */
DWORD sd_size = 4096;
char sd_buf[4096];
PSECURITY_DESCRIPTOR psd = (PSECURITY_DESCRIPTOR) sd_buf;
if (read_sd (file, psd, &sd_size) <= 0)
{
debug_printf ("read_sd %E");
psd = NULL;
}
get_info_from_sd (psd, attribute, uidret, gidret);
return;
} }
int int
@ -1387,22 +1401,11 @@ get_file_attribute (int use_ntsec, const char *file,
mode_t *attribute, __uid32_t *uidret, __gid32_t *gidret) mode_t *attribute, __uid32_t *uidret, __gid32_t *gidret)
{ {
int res; int res;
syscall_printf ("file: %s", file);
if (use_ntsec && allow_ntsec && wincap.has_security ()) if (use_ntsec && allow_ntsec && wincap.has_security ())
{ {
res = get_nt_attribute (file, attribute, uidret, gidret); get_nt_attribute (file, attribute, uidret, gidret);
if (res)
{
/* If reading the security descriptor failed, treat the file
as unreadable. */
*attribute &= ~(S_IRWXU | S_IRWXG | S_IRWXO);
if (uidret)
*uidret = ILLEGAL_UID;
if (gidret)
*gidret = ILLEGAL_GID;
}
else if (attribute && S_ISLNK (*attribute))
*attribute |= S_IRWXU | S_IRWXG | S_IRWXO;
return 0; return 0;
} }
@ -1423,119 +1426,51 @@ get_file_attribute (int use_ntsec, const char *file,
else else
res = 0; res = 0;
/* symlinks are everything for everyone! */
if (S_ISLNK (*attribute))
*attribute |= S_IRWXU | S_IRWXG | S_IRWXO;
return res > 0 ? 0 : -1; return res > 0 ? 0 : -1;
} }
static int static void
get_nt_object_attribute (HANDLE handle, SE_OBJECT_TYPE object_type, get_nt_object_attribute (HANDLE handle, SE_OBJECT_TYPE object_type,
mode_t *attribute, __uid32_t *uidret, __gid32_t *gidret) mode_t *attribute, __uid32_t *uidret, __gid32_t *gidret)
{ {
PSECURITY_DESCRIPTOR psd = NULL; PSECURITY_DESCRIPTOR psd;
cygpsid owner_sid; char sd_buf[4096];
cygpsid group_sid;
PACL acl = NULL;
if (object_type == SE_REGISTRY_KEY) if (object_type == SE_REGISTRY_KEY)
{ {
// use different code for registry handles, for performance reasons /* use different code for registry handles, for performance reasons */
char sd_buf[4096]; psd = (PSECURITY_DESCRIPTOR) & sd_buf[0];
PSECURITY_DESCRIPTOR psd2 = (PSECURITY_DESCRIPTOR) & sd_buf[0];
DWORD len = sizeof (sd_buf); DWORD len = sizeof (sd_buf);
if (ERROR_SUCCESS != RegGetKeySecurity ((HKEY) handle, if (ERROR_SUCCESS != RegGetKeySecurity ((HKEY) handle,
DACL_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION |
GROUP_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION |
OWNER_SECURITY_INFORMATION, OWNER_SECURITY_INFORMATION,
psd2, &len)) psd, &len))
{ {
__seterrno (); __seterrno ();
debug_printf ("RegGetKeySecurity %E"); debug_printf ("RegGetKeySecurity %E");
return -1; psd = NULL;
} }
}
BOOL bDaclPresent;
BOOL bDaclDefaulted;
if (!GetSecurityDescriptorDacl (psd2,
&bDaclPresent, &acl, &bDaclDefaulted))
{
__seterrno ();
debug_printf ("GetSecurityDescriptorDacl %E");
return -1;
}
if (!bDaclPresent)
{
acl = NULL;
}
BOOL bGroupDefaulted;
if (!GetSecurityDescriptorGroup (psd2,
(PSID *) & group_sid,
&bGroupDefaulted))
{
__seterrno ();
debug_printf ("GetSecurityDescriptorGroup %E");
return -1;
}
BOOL bOwnerDefaulted;
if (!GetSecurityDescriptorOwner (psd2,
(PSID *) & owner_sid,
&bOwnerDefaulted))
{
__seterrno ();
debug_printf ("GetSecurityDescriptorOwner %E");
return -1;
}
}
else else
{ {
if (ERROR_SUCCESS != GetSecurityInfo (handle, object_type, if (ERROR_SUCCESS != GetSecurityInfo (handle, object_type,
DACL_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION |
GROUP_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION |
OWNER_SECURITY_INFORMATION, OWNER_SECURITY_INFORMATION,
(PSID *) & owner_sid, NULL, NULL, NULL, NULL, &psd))
(PSID *) & group_sid,
&acl, NULL, &psd))
{ {
__seterrno (); __seterrno ();
debug_printf ("GetSecurityInfo %E"); debug_printf ("GetSecurityInfo %E");
return -1; psd = NULL;
} }
} }
__uid32_t uid; get_info_from_sd (psd, attribute, uidret, gidret);
__gid32_t gid; if (psd != (PSECURITY_DESCRIPTOR) & sd_buf[0])
BOOL grp_member = get_sids_info (owner_sid, group_sid, &uid, &gid); LocalFree (psd);
if (uidret) return;
*uidret = uid;
if (gidret)
*gidret = gid;
if (!attribute)
{
syscall_printf ("uid %d, gid %d", uid, gid);
LocalFree (psd);
return 0;
}
if (!acl)
{
*attribute |= S_IRWXU | S_IRWXG | S_IRWXO;
syscall_printf ("No ACL = %x, uid %d, gid %d", *attribute, uid, gid);
LocalFree (psd);
return 0;
}
get_attribute_from_acl (attribute, acl, owner_sid, group_sid, grp_member);
LocalFree (psd);
syscall_printf ("%x, uid %d, gid %d", *attribute, uid, gid);
return 0;
} }
int int
@ -1544,26 +1479,11 @@ get_object_attribute (HANDLE handle, SE_OBJECT_TYPE object_type,
{ {
if (allow_ntsec && wincap.has_security ()) if (allow_ntsec && wincap.has_security ())
{ {
int res = get_nt_object_attribute (handle, object_type, attribute, get_nt_object_attribute (handle, object_type, attribute, uidret, gidret);
uidret, gidret); return 0;
if (attribute && S_ISLNK (*attribute))
*attribute |= S_IRWXU | S_IRWXG | S_IRWXO;
return res;
} }
/* The entries are already set to default values */
if (uidret) return -1;
*uidret = getuid32 ();
if (gidret)
*gidret = getgid32 ();
if (!attribute)
return 0;
/* symlinks are everything for everyone! */
if (S_ISLNK (*attribute))
*attribute |= S_IRWXU | S_IRWXG | S_IRWXO;
return 0;
} }
BOOL BOOL