Commit 66447e07 authored by Eli Zaretskii's avatar Eli Zaretskii
Browse files

Support Posix ACL APIs on MS-Windows.

 src/w32.c: Include sddl.h and sys/acl.h.
 (SDDL_REVISION_1): Define if not already defined.
 (g_b_init_get_security_descriptor_dacl)
 (g_b_init_convert_sd_to_sddl, g_b_init_convert_sddl_to_sd)
 (g_b_init_is_valid_security_descriptor)
 (g_b_init_set_file_security): New static flags.
 (globals_of_w32): Initialize them to zero.
 (SetFileSecurity_Name): New string constant.
 (SetFileSecurity_Proc, GetSecurityDescriptorDacl_Proc)
 (ConvertStringSecurityDescriptorToSecurityDescriptor_Proc)
 (ConvertSecurityDescriptorToStringSecurityDescriptor_Proc)
 (IsValidSecurityDescriptor_Proc): New typedefs.
 (get_file_security, get_security_descriptor_owner)
 (get_security_descriptor_group): Set errno to ENOTSUP.
 (set_file_security, get_security_descriptor_dacl)
 (is_valid_security_descriptor, convert_sd_to_sddl)
 (convert_sddl_to_sd, acl_valid, acl_to_text, acl_from_text)
 (acl_free, acl_get_file, acl_set_file): New functions.
 src/fileio.c (Fcopy_file) [WINDOWSNT]: Support copying ACLs.

 nt/inc/sys/acl.h: New file.
 nt/inc/ms-w32.h (ENOTSUP): Define if undefined.
 nt/config.nt (HAVE_POSIX_ACL): Define.

 doc/lispref/files.texi (File Attributes, Changing Files): Update to include
 MS-Windows support for ACLs.
parent 207a7ef0
2012-12-17 Eli Zaretskii <eliz@gnu.org>
* files.texi (File Attributes, Changing Files): Update to include
MS-Windows support for ACLs.
2012-12-16 Romain Francoise <romain@orebokech.com>
* files.texi (File Attributes): Document ACL support and new
......
......@@ -1357,13 +1357,14 @@ support, then the return value is @code{(nil nil nil nil)}.
If Emacs has been compiled with @dfn{ACL} (access control list)
support, you can use the function @code{file-acl} to retrieve a file's
ACL entries. The format is platform-specific; on GNU/Linux and BSD,
Emacs uses the POSIX ACL interface. For the function
@code{set-file-acl}, see @ref{Changing Files}.
Emacs uses the POSIX ACL interface, while on MS-Windows Emacs emulates
the POSIX ACL interface with native file security APIs. For the
function @code{set-file-acl}, see @ref{Changing Files}.
@defun file-acl filename
This function returns the ACL entries of the file @var{filename}.
The return value is a string containing the textual representation of
the ACL entries, like the following:
the ACL entries. On Posix hosts, it looks like this:
@example
@group
......@@ -1375,6 +1376,12 @@ other::r--
@end group
@end example
@cindex security descriptor, file
@cindex SDDL, MS-Windows
On MS-Windows, the return value is a textual description of the file's
@dfn{security descriptor} in @acronym{SDDL}, the @dfn{Security
Descriptor Definition Language}.
If the file does not exist or is inaccessible, or if Emacs was unable to
determine the ACL entries, then the return value is @code{nil}. The
latter can happen for local files if Emacs was not compiled with ACL
......@@ -1719,7 +1726,8 @@ SELinux support.
This function sets the ACL entries of the file @var{filename} to
@var{acl-string}. @xref{File Attributes}, for a brief description of
ACLs. The @var{acl-string} argument should be a string containing the
textual representation of the desired ACL entries.
textual representation of the desired ACL entries in the format
appropriate for the ACL interface being used.
@end defun
@node File Names
......
......@@ -44,8 +44,9 @@ simply disabling Transient Mark mode does the same thing.
*** Emacs preserves the ACL entries of files when backing up.
+++
*** New functions `file-acl' and `set-file-acl' get and set the ACL
entries of a file. On GNU/Linux the POSIX ACL interface is used via
libacl.
entries of a file. On GNU/Linux, the POSIX ACL interface is used via
libacl. On MS-Windows, the NT Security APIs are used to emulate the
POSIX ACL interfaces.
* Editing Changes in Emacs 24.4
......
2012-12-17 Eli Zaretskii <eliz@gnu.org>
* inc/sys/acl.h: New file.
* inc/ms-w32.h (ENOTSUP): Define if undefined.
* config.nt (HAVE_POSIX_ACL): Define.
2012-12-15 Eli Zaretskii <eliz@gnu.org>
* inc/ms-w32.h (sys_unlink): Provide prototype.
......
......@@ -725,6 +725,9 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
/* Define to 1 if you have the <png.h> header file. */
#undef HAVE_PNG_H
/* Define to 1 if you have the POSIX ACL support. */
#define HAVE_POSIX_ACL 1
/* Define to 1 if you have the `posix_memalign' function. */
#undef HAVE_POSIX_MEMALIGN
......
......@@ -293,6 +293,10 @@ extern struct tm *localtime_r (time_t const * restrict, struct tm * restrict);
#define NSIG 23
#endif
#ifndef ENOTSUP
#define ENOTSUP ENOSYS
#endif
#ifdef _MSC_VER
typedef int sigset_t;
typedef int ssize_t;
......
/* Emulation of Posix ACLs for Windows. */
#ifndef ACL_H
#define ACL_H
#define NOMINMAX 1 /* don't define min and max */
#include <windows.h>
typedef PSECURITY_DESCRIPTOR acl_t;
typedef unsigned acl_type_t;
/* Values of acl_type_t */
#define ACL_TYPE_ACCESS 0
#define ACL_TYPE_DEFAULT 1
typedef unsigned acl_perm_t;
extern int acl_valid (acl_t);
extern acl_t acl_get_file (const char *, acl_type_t);
extern int acl_set_file (const char *, acl_type_t, acl_t);
extern char * acl_to_text (acl_t, ssize_t *);
extern acl_t acl_from_text (const char *);
extern int acl_free (void *);
#endif /* ACL_H */
2012-12-17 Eli Zaretskii <eliz@gnu.org>
Emulate Posix ACL APIs on MS-Windows.
* w32.c: Include sddl.h and sys/acl.h.
(SDDL_REVISION_1): Define if not already defined.
(g_b_init_get_security_descriptor_dacl)
(g_b_init_convert_sd_to_sddl, g_b_init_convert_sddl_to_sd)
(g_b_init_is_valid_security_descriptor)
(g_b_init_set_file_security): New static flags.
(globals_of_w32): Initialize them to zero.
(SetFileSecurity_Name): New string constant.
(SetFileSecurity_Proc, GetSecurityDescriptorDacl_Proc)
(ConvertStringSecurityDescriptorToSecurityDescriptor_Proc)
(ConvertSecurityDescriptorToStringSecurityDescriptor_Proc)
(IsValidSecurityDescriptor_Proc): New typedefs.
(get_file_security, get_security_descriptor_owner)
(get_security_descriptor_group): Set errno to ENOTSUP.
(set_file_security, get_security_descriptor_dacl)
(is_valid_security_descriptor, convert_sd_to_sddl)
(convert_sddl_to_sd, acl_valid, acl_to_text, acl_from_text)
(acl_free, acl_get_file, acl_set_file): New functions.
* fileio.c (Fcopy_file) [WINDOWSNT]: Support copying ACLs.
2012-12-17 Paul Eggert <eggert@cs.ucla.edu>
Don't reraise SIGCHLD, as that can now lose (Bug#13192).
......
......@@ -1956,6 +1956,14 @@ entries (depending on how Emacs was built). */)
out_st.st_mode = 0;
#ifdef WINDOWSNT
if (!NILP (preserve_extended_attributes))
{
#ifdef HAVE_POSIX_ACL
acl = acl_get_file (SDATA (encoded_file), ACL_TYPE_ACCESS);
if (acl == NULL && errno != ENOTSUP)
report_file_error ("Getting ACL", Fcons (file, Qnil));
#endif
}
if (!CopyFile (SDATA (encoded_file),
SDATA (encoded_newname),
FALSE))
......@@ -1983,6 +1991,17 @@ entries (depending on how Emacs was built). */)
/* Restore original attributes. */
SetFileAttributes (filename, attributes);
}
#ifdef HAVE_POSIX_ACL
if (acl != NULL)
{
bool fail =
acl_set_file (SDATA (encoded_newname), ACL_TYPE_ACCESS, acl) != 0;
if (fail && errno != ENOTSUP)
report_file_error ("Setting ACL", Fcons (newname, Qnil));
acl_free (acl);
}
#endif
#else /* not WINDOWSNT */
immediate_quit = 1;
ifd = emacs_open (SSDATA (encoded_file), O_RDONLY, 0);
......
......@@ -117,6 +117,15 @@ typedef struct _PROCESS_MEMORY_COUNTERS_EX {
#include <winioctl.h>
#include <aclapi.h>
#include <sddl.h>
#include <sys/acl.h>
/* This is not in MinGW's sddl.h (but they are in MSVC headers), so we
define them by hand if not already defined. */
#ifndef SDDL_REVISION_1
#define SDDL_REVISION_1 1
#endif /* SDDL_REVISION_1 */
#ifdef _MSC_VER
/* MSVC doesn't provide the definition of REPARSE_DATA_BUFFER and the
......@@ -257,6 +266,11 @@ static BOOL g_b_init_copy_sid;
static BOOL g_b_init_get_native_system_info;
static BOOL g_b_init_get_system_times;
static BOOL g_b_init_create_symbolic_link;
static BOOL g_b_init_get_security_descriptor_dacl;
static BOOL g_b_init_convert_sd_to_sddl;
static BOOL g_b_init_convert_sddl_to_sd;
static BOOL g_b_init_is_valid_security_descriptor;
static BOOL g_b_init_set_file_security;
/*
BEGIN: Wrapper functions around OpenProcessToken
......@@ -286,9 +300,11 @@ GetProcessTimes_Proc get_process_times_fn = NULL;
#ifdef _UNICODE
const char * const LookupAccountSid_Name = "LookupAccountSidW";
const char * const GetFileSecurity_Name = "GetFileSecurityW";
const char * const SetFileSecurity_Name = "SetFileSecurityW";
#else
const char * const LookupAccountSid_Name = "LookupAccountSidA";
const char * const GetFileSecurity_Name = "GetFileSecurityA";
const char * const SetFileSecurity_Name = "SetFileSecurityA";
#endif
typedef BOOL (WINAPI * LookupAccountSid_Proc) (
LPCTSTR lpSystemName,
......@@ -318,6 +334,10 @@ typedef BOOL (WINAPI * GetFileSecurity_Proc) (
PSECURITY_DESCRIPTOR pSecurityDescriptor,
DWORD nLength,
LPDWORD lpnLengthNeeded);
typedef BOOL (WINAPI *SetFileSecurity_Proc) (
LPCTSTR lpFileName,
SECURITY_INFORMATION SecurityInformation,
PSECURITY_DESCRIPTOR pSecurityDescriptor);
typedef BOOL (WINAPI * GetSecurityDescriptorOwner_Proc) (
PSECURITY_DESCRIPTOR pSecurityDescriptor,
PSID *pOwner,
......@@ -326,6 +346,11 @@ typedef BOOL (WINAPI * GetSecurityDescriptorGroup_Proc) (
PSECURITY_DESCRIPTOR pSecurityDescriptor,
PSID *pGroup,
LPBOOL lpbGroupDefaulted);
typedef BOOL (WINAPI *GetSecurityDescriptorDacl_Proc) (
PSECURITY_DESCRIPTOR pSecurityDescriptor,
LPBOOL lpbDaclPresent,
PACL *pDacl,
LPBOOL lpbDaclDefaulted);
typedef BOOL (WINAPI * IsValidSid_Proc) (
PSID sid);
typedef HANDLE (WINAPI * CreateToolhelp32Snapshot_Proc) (
......@@ -376,6 +401,18 @@ typedef BOOLEAN (WINAPI *CreateSymbolicLink_Proc) (
LPTSTR lpSymlinkFileName,
LPTSTR lpTargetFileName,
DWORD dwFlags);
typedef BOOL (WINAPI *ConvertStringSecurityDescriptorToSecurityDescriptor_Proc) (
LPCTSTR StringSecurityDescriptor,
DWORD StringSDRevision,
PSECURITY_DESCRIPTOR *SecurityDescriptor,
PULONG SecurityDescriptorSize);
typedef BOOL (WINAPI *ConvertSecurityDescriptorToStringSecurityDescriptor_Proc) (
PSECURITY_DESCRIPTOR SecurityDescriptor,
DWORD RequestedStringSDRevision,
SECURITY_INFORMATION SecurityInformation,
LPTSTR *StringSecurityDescriptor,
PULONG StringSecurityDescriptorLen);
typedef BOOL (WINAPI *IsValidSecurityDescriptor_Proc) (PSECURITY_DESCRIPTOR);
/* ** A utility function ** */
static BOOL
......@@ -621,6 +658,7 @@ get_file_security (LPCTSTR lpFileName,
HMODULE hm_advapi32 = NULL;
if (is_windows_9x () == TRUE)
{
errno = ENOTSUP;
return FALSE;
}
if (g_b_init_get_file_security == 0)
......@@ -633,6 +671,7 @@ get_file_security (LPCTSTR lpFileName,
}
if (s_pfn_Get_File_Security == NULL)
{
errno = ENOTSUP;
return FALSE;
}
return (s_pfn_Get_File_Security (lpFileName, RequestedInformation,
......@@ -640,6 +679,35 @@ get_file_security (LPCTSTR lpFileName,
lpnLengthNeeded));
}
static BOOL WINAPI
set_file_security (LPCTSTR lpFileName,
SECURITY_INFORMATION SecurityInformation,
PSECURITY_DESCRIPTOR pSecurityDescriptor)
{
static SetFileSecurity_Proc s_pfn_Set_File_Security = NULL;
HMODULE hm_advapi32 = NULL;
if (is_windows_9x () == TRUE)
{
errno = ENOTSUP;
return FALSE;
}
if (g_b_init_set_file_security == 0)
{
g_b_init_set_file_security = 1;
hm_advapi32 = LoadLibrary ("Advapi32.dll");
s_pfn_Set_File_Security =
(SetFileSecurity_Proc) GetProcAddress (
hm_advapi32, SetFileSecurity_Name);
}
if (s_pfn_Set_File_Security == NULL)
{
errno = ENOTSUP;
return FALSE;
}
return (s_pfn_Set_File_Security (lpFileName, SecurityInformation,
pSecurityDescriptor));
}
static BOOL WINAPI
get_security_descriptor_owner (PSECURITY_DESCRIPTOR pSecurityDescriptor,
PSID *pOwner,
......@@ -649,6 +717,7 @@ get_security_descriptor_owner (PSECURITY_DESCRIPTOR pSecurityDescriptor,
HMODULE hm_advapi32 = NULL;
if (is_windows_9x () == TRUE)
{
errno = ENOTSUP;
return FALSE;
}
if (g_b_init_get_security_descriptor_owner == 0)
......@@ -661,6 +730,7 @@ get_security_descriptor_owner (PSECURITY_DESCRIPTOR pSecurityDescriptor,
}
if (s_pfn_Get_Security_Descriptor_Owner == NULL)
{
errno = ENOTSUP;
return FALSE;
}
return (s_pfn_Get_Security_Descriptor_Owner (pSecurityDescriptor, pOwner,
......@@ -676,6 +746,7 @@ get_security_descriptor_group (PSECURITY_DESCRIPTOR pSecurityDescriptor,
HMODULE hm_advapi32 = NULL;
if (is_windows_9x () == TRUE)
{
errno = ENOTSUP;
return FALSE;
}
if (g_b_init_get_security_descriptor_group == 0)
......@@ -688,12 +759,44 @@ get_security_descriptor_group (PSECURITY_DESCRIPTOR pSecurityDescriptor,
}
if (s_pfn_Get_Security_Descriptor_Group == NULL)
{
errno = ENOTSUP;
return FALSE;
}
return (s_pfn_Get_Security_Descriptor_Group (pSecurityDescriptor, pGroup,
lpbGroupDefaulted));
}
static BOOL WINAPI
get_security_descriptor_dacl (PSECURITY_DESCRIPTOR pSecurityDescriptor,
LPBOOL lpbDaclPresent,
PACL *pDacl,
LPBOOL lpbDaclDefaulted)
{
static GetSecurityDescriptorDacl_Proc s_pfn_Get_Security_Descriptor_Dacl = NULL;
HMODULE hm_advapi32 = NULL;
if (is_windows_9x () == TRUE)
{
errno = ENOTSUP;
return FALSE;
}
if (g_b_init_get_security_descriptor_dacl == 0)
{
g_b_init_get_security_descriptor_dacl = 1;
hm_advapi32 = LoadLibrary ("Advapi32.dll");
s_pfn_Get_Security_Descriptor_Dacl =
(GetSecurityDescriptorDacl_Proc) GetProcAddress (
hm_advapi32, "GetSecurityDescriptorDacl");
}
if (s_pfn_Get_Security_Descriptor_Dacl == NULL)
{
errno = ENOTSUP;
return FALSE;
}
return (s_pfn_Get_Security_Descriptor_Dacl (pSecurityDescriptor,
lpbDaclPresent, pDacl,
lpbDaclDefaulted));
}
static BOOL WINAPI
is_valid_sid (PSID sid)
{
......@@ -888,6 +991,120 @@ create_symbolic_link (LPTSTR lpSymlinkFilename,
}
return retval;
}
static BOOL WINAPI
is_valid_security_descriptor (PSECURITY_DESCRIPTOR pSecurityDescriptor)
{
static IsValidSecurityDescriptor_Proc s_pfn_Is_Valid_Security_Descriptor_Proc = NULL;
if (is_windows_9x () == TRUE)
{
errno = ENOTSUP;
return FALSE;
}
if (g_b_init_is_valid_security_descriptor == 0)
{
g_b_init_is_valid_security_descriptor = 1;
s_pfn_Is_Valid_Security_Descriptor_Proc =
(IsValidSecurityDescriptor_Proc)GetProcAddress (GetModuleHandle ("Advapi32.dll"),
"IsValidSecurityDescriptor");
}
if (s_pfn_Is_Valid_Security_Descriptor_Proc == NULL)
{
errno = ENOTSUP;
return FALSE;
}
return s_pfn_Is_Valid_Security_Descriptor_Proc (pSecurityDescriptor);
}
static BOOL WINAPI
convert_sd_to_sddl (PSECURITY_DESCRIPTOR SecurityDescriptor,
DWORD RequestedStringSDRevision,
SECURITY_INFORMATION SecurityInformation,
LPTSTR *StringSecurityDescriptor,
PULONG StringSecurityDescriptorLen)
{
static ConvertSecurityDescriptorToStringSecurityDescriptor_Proc s_pfn_Convert_SD_To_SDDL = NULL;
BOOL retval;
if (is_windows_9x () == TRUE)
{
errno = ENOTSUP;
return FALSE;
}
if (g_b_init_convert_sd_to_sddl == 0)
{
g_b_init_convert_sd_to_sddl = 1;
#ifdef _UNICODE
s_pfn_Convert_SD_To_SDDL =
(ConvertSecurityDescriptorToStringSecurityDescriptor_Proc)GetProcAddress (GetModuleHandle ("Advapi32.dll"),
"ConvertSecurityDescriptorToStringSecurityDescriptorW");
#else
s_pfn_Convert_SD_To_SDDL =
(ConvertSecurityDescriptorToStringSecurityDescriptor_Proc)GetProcAddress (GetModuleHandle ("Advapi32.dll"),
"ConvertSecurityDescriptorToStringSecurityDescriptorA");
#endif
}
if (s_pfn_Convert_SD_To_SDDL == NULL)
{
errno = ENOTSUP;
return FALSE;
}
retval = s_pfn_Convert_SD_To_SDDL (SecurityDescriptor,
RequestedStringSDRevision,
SecurityInformation,
StringSecurityDescriptor,
StringSecurityDescriptorLen);
return retval;
}
static BOOL WINAPI
convert_sddl_to_sd (LPCTSTR StringSecurityDescriptor,
DWORD StringSDRevision,
PSECURITY_DESCRIPTOR *SecurityDescriptor,
PULONG SecurityDescriptorSize)
{
static ConvertStringSecurityDescriptorToSecurityDescriptor_Proc s_pfn_Convert_SDDL_To_SD = NULL;
BOOL retval;
if (is_windows_9x () == TRUE)
{
errno = ENOTSUP;
return FALSE;
}
if (g_b_init_convert_sddl_to_sd == 0)
{
g_b_init_convert_sddl_to_sd = 1;
#ifdef _UNICODE
s_pfn_Convert_SDDL_To_SD =
(ConvertStringSecurityDescriptorToSecurityDescriptor_Proc)GetProcAddress (GetModuleHandle ("Advapi32.dll"),
"ConvertStringSecurityDescriptorToSecurityDescriptorW");
#else
s_pfn_Convert_SDDL_To_SD =
(ConvertStringSecurityDescriptorToSecurityDescriptor_Proc)GetProcAddress (GetModuleHandle ("Advapi32.dll"),
"ConvertStringSecurityDescriptorToSecurityDescriptorA");
#endif
}
if (s_pfn_Convert_SDDL_To_SD == NULL)
{
errno = ENOTSUP;
return FALSE;
}
retval = s_pfn_Convert_SDDL_To_SD (StringSecurityDescriptor,
StringSDRevision,
SecurityDescriptor,
SecurityDescriptorSize);
return retval;
}
/* Return 1 if P is a valid pointer to an object of size SIZE. Return
......@@ -4477,6 +4694,199 @@ chase_symlinks (const char *file)
return target;
}
/* Posix ACL emulation. */
int
acl_valid (acl_t acl)
{
return is_valid_security_descriptor ((PSECURITY_DESCRIPTOR)acl) ? 0 : -1;
}
char *
acl_to_text (acl_t acl, ssize_t *size)
{
LPTSTR str_acl;
SECURITY_INFORMATION flags =
OWNER_SECURITY_INFORMATION |
GROUP_SECURITY_INFORMATION |
DACL_SECURITY_INFORMATION;
char *retval = NULL;
ssize_t local_size;
int e = errno;
errno = 0;
if (convert_sd_to_sddl ((PSECURITY_DESCRIPTOR)acl, SDDL_REVISION_1, flags, &str_acl, &local_size))
{
errno = e;
/* We don't want to mix heaps, so we duplicate the string in our
heap and free the one allocated by the API. */
retval = xstrdup (str_acl);
if (size)
*size = local_size;
LocalFree (str_acl);
}
else if (errno != ENOTSUP)
errno = EINVAL;
return retval;
}
acl_t
acl_from_text (const char *acl_str)
{
PSECURITY_DESCRIPTOR psd, retval = NULL;
ULONG sd_size;
int e = errno;
errno = 0;
if (convert_sddl_to_sd (acl_str, SDDL_REVISION_1, &psd, &sd_size))
{
errno = e;
retval = xmalloc (sd_size);
memcpy (retval, psd, sd_size);
LocalFree (psd);
}
else if (errno != ENOTSUP)
errno = EINVAL;
return retval;
}
int
acl_free (void *ptr)
{
xfree (ptr);
return 0;
}
acl_t
acl_get_file (const char *fname, acl_type_t type)
{
PSECURITY_DESCRIPTOR psd = NULL;
if (type == ACL_TYPE_ACCESS)
{
DWORD sd_len, err;
SECURITY_INFORMATION si =
OWNER_SECURITY_INFORMATION |
GROUP_SECURITY_INFORMATION |
DACL_SECURITY_INFORMATION ;
int e = errno;
errno = 0;
if (!get_file_security (fname, si, psd, 0, &sd_len)
&& errno != ENOTSUP)
{
err = GetLastError ();
if (err == ERROR_INSUFFICIENT_BUFFER)
{
psd = xmalloc (sd_len);
if (!get_file_security (fname, si, psd, sd_len, &sd_len))
{
xfree (psd);
errno = EIO;
psd = NULL;
}
}
else if (err == ERROR_FILE_NOT_FOUND
|| err == ERROR_PATH_NOT_FOUND)
errno = ENOENT;
else
errno = EIO;
}
else if (!errno)
errno = e;
}
else if (type != ACL_TYPE_DEFAULT)
errno = EINVAL;
return psd;
}
int
acl_set_file (const char *fname, acl_type_t type, acl_t acl)
{
TOKEN_PRIVILEGES old1, old2;
DWORD err;
BOOL res;
int st = 0, retval = -1;
SECURITY_INFORMATION flags = 0;
PSID psid;
PACL pacl;
BOOL dflt;
BOOL dacl_present;
int e;
if (acl_valid (acl) != 0
|| (type != ACL_TYPE_DEFAULT && type != ACL_TYPE_ACCESS))
{
errno = EINVAL;
return -1;
}
if (type == ACL_TYPE_DEFAULT)
{
errno = ENOSYS;
return -1;
}
if (get_security_descriptor_owner ((PSECURITY_DESCRIPTOR)acl, &psid, &dflt)
&& psid)
flags |= OWNER_SECURITY_INFORMATION;
if (get_security_descriptor_group ((PSECURITY_DESCRIPTOR)acl, &psid, &dflt)
&& psid)
flags |= GROUP_SECURITY_INFORMATION;
if (get_security_descriptor_dacl ((PSECURITY_DESCRIPTOR)acl, &dacl_present,
&pacl, &dflt)
&& dacl_present)
flags |= DACL_SECURITY_INFORMATION;
if (!flags)
return 0;
/* According to KB-245153, setting the owner will succeed if either:
(1) the caller is the user who will be the new owner, and has the
SE_TAKE_OWNERSHIP privilege, or
(2) the caller has the SE_RESTORE privilege, in which case she can
set any valid user or group as the owner
We request below both SE_TAKE_OWNERSHIP and SE_RESTORE
privileges, and disregard any failures in obtaining them. If