diff options
| author | Eli Zaretskii | 2012-12-17 21:14:34 +0200 |
|---|---|---|
| committer | Eli Zaretskii | 2012-12-17 21:14:34 +0200 |
| commit | 66447e07c1aa037730127d6fcdd2658f87f13dc0 (patch) | |
| tree | 0547cb5e75ae1ffeb51d7b3f80275e0a65f70720 | |
| parent | 207a7ef0531ca92468e19115a2c2064c9b22bfd4 (diff) | |
| download | emacs-66447e07c1aa037730127d6fcdd2658f87f13dc0.tar.gz emacs-66447e07c1aa037730127d6fcdd2658f87f13dc0.zip | |
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.
| -rw-r--r-- | doc/lispref/ChangeLog | 5 | ||||
| -rw-r--r-- | doc/lispref/files.texi | 16 | ||||
| -rw-r--r-- | etc/NEWS | 5 | ||||
| -rw-r--r-- | nt/ChangeLog | 8 | ||||
| -rw-r--r-- | nt/config.nt | 3 | ||||
| -rw-r--r-- | nt/inc/ms-w32.h | 4 | ||||
| -rw-r--r-- | nt/inc/sys/acl.h | 25 | ||||
| -rw-r--r-- | src/ChangeLog | 24 | ||||
| -rw-r--r-- | src/fileio.c | 19 | ||||
| -rw-r--r-- | src/w32.c | 415 |
10 files changed, 518 insertions, 6 deletions
diff --git a/doc/lispref/ChangeLog b/doc/lispref/ChangeLog index 922147844bd..a0bbafb116f 100644 --- a/doc/lispref/ChangeLog +++ b/doc/lispref/ChangeLog | |||
| @@ -1,3 +1,8 @@ | |||
| 1 | 2012-12-17 Eli Zaretskii <eliz@gnu.org> | ||
| 2 | |||
| 3 | * files.texi (File Attributes, Changing Files): Update to include | ||
| 4 | MS-Windows support for ACLs. | ||
| 5 | |||
| 1 | 2012-12-16 Romain Francoise <romain@orebokech.com> | 6 | 2012-12-16 Romain Francoise <romain@orebokech.com> |
| 2 | 7 | ||
| 3 | * files.texi (File Attributes): Document ACL support and new | 8 | * files.texi (File Attributes): Document ACL support and new |
diff --git a/doc/lispref/files.texi b/doc/lispref/files.texi index 93bee961929..5440388fe70 100644 --- a/doc/lispref/files.texi +++ b/doc/lispref/files.texi | |||
| @@ -1357,13 +1357,14 @@ support, then the return value is @code{(nil nil nil nil)}. | |||
| 1357 | If Emacs has been compiled with @dfn{ACL} (access control list) | 1357 | If Emacs has been compiled with @dfn{ACL} (access control list) |
| 1358 | support, you can use the function @code{file-acl} to retrieve a file's | 1358 | support, you can use the function @code{file-acl} to retrieve a file's |
| 1359 | ACL entries. The format is platform-specific; on GNU/Linux and BSD, | 1359 | ACL entries. The format is platform-specific; on GNU/Linux and BSD, |
| 1360 | Emacs uses the POSIX ACL interface. For the function | 1360 | Emacs uses the POSIX ACL interface, while on MS-Windows Emacs emulates |
| 1361 | @code{set-file-acl}, see @ref{Changing Files}. | 1361 | the POSIX ACL interface with native file security APIs. For the |
| 1362 | function @code{set-file-acl}, see @ref{Changing Files}. | ||
| 1362 | 1363 | ||
| 1363 | @defun file-acl filename | 1364 | @defun file-acl filename |
| 1364 | This function returns the ACL entries of the file @var{filename}. | 1365 | This function returns the ACL entries of the file @var{filename}. |
| 1365 | The return value is a string containing the textual representation of | 1366 | The return value is a string containing the textual representation of |
| 1366 | the ACL entries, like the following: | 1367 | the ACL entries. On Posix hosts, it looks like this: |
| 1367 | 1368 | ||
| 1368 | @example | 1369 | @example |
| 1369 | @group | 1370 | @group |
| @@ -1375,6 +1376,12 @@ other::r-- | |||
| 1375 | @end group | 1376 | @end group |
| 1376 | @end example | 1377 | @end example |
| 1377 | 1378 | ||
| 1379 | @cindex security descriptor, file | ||
| 1380 | @cindex SDDL, MS-Windows | ||
| 1381 | On MS-Windows, the return value is a textual description of the file's | ||
| 1382 | @dfn{security descriptor} in @acronym{SDDL}, the @dfn{Security | ||
| 1383 | Descriptor Definition Language}. | ||
| 1384 | |||
| 1378 | If the file does not exist or is inaccessible, or if Emacs was unable to | 1385 | If the file does not exist or is inaccessible, or if Emacs was unable to |
| 1379 | determine the ACL entries, then the return value is @code{nil}. The | 1386 | determine the ACL entries, then the return value is @code{nil}. The |
| 1380 | latter can happen for local files if Emacs was not compiled with ACL | 1387 | latter can happen for local files if Emacs was not compiled with ACL |
| @@ -1719,7 +1726,8 @@ SELinux support. | |||
| 1719 | This function sets the ACL entries of the file @var{filename} to | 1726 | This function sets the ACL entries of the file @var{filename} to |
| 1720 | @var{acl-string}. @xref{File Attributes}, for a brief description of | 1727 | @var{acl-string}. @xref{File Attributes}, for a brief description of |
| 1721 | ACLs. The @var{acl-string} argument should be a string containing the | 1728 | ACLs. The @var{acl-string} argument should be a string containing the |
| 1722 | textual representation of the desired ACL entries. | 1729 | textual representation of the desired ACL entries in the format |
| 1730 | appropriate for the ACL interface being used. | ||
| 1723 | @end defun | 1731 | @end defun |
| 1724 | 1732 | ||
| 1725 | @node File Names | 1733 | @node File Names |
| @@ -44,8 +44,9 @@ simply disabling Transient Mark mode does the same thing. | |||
| 44 | *** Emacs preserves the ACL entries of files when backing up. | 44 | *** Emacs preserves the ACL entries of files when backing up. |
| 45 | +++ | 45 | +++ |
| 46 | *** New functions `file-acl' and `set-file-acl' get and set the ACL | 46 | *** New functions `file-acl' and `set-file-acl' get and set the ACL |
| 47 | entries of a file. On GNU/Linux the POSIX ACL interface is used via | 47 | entries of a file. On GNU/Linux, the POSIX ACL interface is used via |
| 48 | libacl. | 48 | libacl. On MS-Windows, the NT Security APIs are used to emulate the |
| 49 | POSIX ACL interfaces. | ||
| 49 | 50 | ||
| 50 | * Editing Changes in Emacs 24.4 | 51 | * Editing Changes in Emacs 24.4 |
| 51 | 52 | ||
diff --git a/nt/ChangeLog b/nt/ChangeLog index bcd15422bdf..114fa826b2b 100644 --- a/nt/ChangeLog +++ b/nt/ChangeLog | |||
| @@ -1,3 +1,11 @@ | |||
| 1 | 2012-12-17 Eli Zaretskii <eliz@gnu.org> | ||
| 2 | |||
| 3 | * inc/sys/acl.h: New file. | ||
| 4 | |||
| 5 | * inc/ms-w32.h (ENOTSUP): Define if undefined. | ||
| 6 | |||
| 7 | * config.nt (HAVE_POSIX_ACL): Define. | ||
| 8 | |||
| 1 | 2012-12-15 Eli Zaretskii <eliz@gnu.org> | 9 | 2012-12-15 Eli Zaretskii <eliz@gnu.org> |
| 2 | 10 | ||
| 3 | * inc/ms-w32.h (sys_unlink): Provide prototype. | 11 | * inc/ms-w32.h (sys_unlink): Provide prototype. |
diff --git a/nt/config.nt b/nt/config.nt index db26bf6cbae..aef92a8cccd 100644 --- a/nt/config.nt +++ b/nt/config.nt | |||
| @@ -725,6 +725,9 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 725 | /* Define to 1 if you have the <png.h> header file. */ | 725 | /* Define to 1 if you have the <png.h> header file. */ |
| 726 | #undef HAVE_PNG_H | 726 | #undef HAVE_PNG_H |
| 727 | 727 | ||
| 728 | /* Define to 1 if you have the POSIX ACL support. */ | ||
| 729 | #define HAVE_POSIX_ACL 1 | ||
| 730 | |||
| 728 | /* Define to 1 if you have the `posix_memalign' function. */ | 731 | /* Define to 1 if you have the `posix_memalign' function. */ |
| 729 | #undef HAVE_POSIX_MEMALIGN | 732 | #undef HAVE_POSIX_MEMALIGN |
| 730 | 733 | ||
diff --git a/nt/inc/ms-w32.h b/nt/inc/ms-w32.h index aab30391063..78e1d544cde 100644 --- a/nt/inc/ms-w32.h +++ b/nt/inc/ms-w32.h | |||
| @@ -293,6 +293,10 @@ extern struct tm *localtime_r (time_t const * restrict, struct tm * restrict); | |||
| 293 | #define NSIG 23 | 293 | #define NSIG 23 |
| 294 | #endif | 294 | #endif |
| 295 | 295 | ||
| 296 | #ifndef ENOTSUP | ||
| 297 | #define ENOTSUP ENOSYS | ||
| 298 | #endif | ||
| 299 | |||
| 296 | #ifdef _MSC_VER | 300 | #ifdef _MSC_VER |
| 297 | typedef int sigset_t; | 301 | typedef int sigset_t; |
| 298 | typedef int ssize_t; | 302 | typedef int ssize_t; |
diff --git a/nt/inc/sys/acl.h b/nt/inc/sys/acl.h new file mode 100644 index 00000000000..3133e3bfc09 --- /dev/null +++ b/nt/inc/sys/acl.h | |||
| @@ -0,0 +1,25 @@ | |||
| 1 | /* Emulation of Posix ACLs for Windows. */ | ||
| 2 | |||
| 3 | #ifndef ACL_H | ||
| 4 | #define ACL_H | ||
| 5 | |||
| 6 | #define NOMINMAX 1 /* don't define min and max */ | ||
| 7 | #include <windows.h> | ||
| 8 | |||
| 9 | typedef PSECURITY_DESCRIPTOR acl_t; | ||
| 10 | typedef unsigned acl_type_t; | ||
| 11 | |||
| 12 | /* Values of acl_type_t */ | ||
| 13 | #define ACL_TYPE_ACCESS 0 | ||
| 14 | #define ACL_TYPE_DEFAULT 1 | ||
| 15 | |||
| 16 | typedef unsigned acl_perm_t; | ||
| 17 | |||
| 18 | extern int acl_valid (acl_t); | ||
| 19 | extern acl_t acl_get_file (const char *, acl_type_t); | ||
| 20 | extern int acl_set_file (const char *, acl_type_t, acl_t); | ||
| 21 | extern char * acl_to_text (acl_t, ssize_t *); | ||
| 22 | extern acl_t acl_from_text (const char *); | ||
| 23 | extern int acl_free (void *); | ||
| 24 | |||
| 25 | #endif /* ACL_H */ | ||
diff --git a/src/ChangeLog b/src/ChangeLog index d5071c541b4..acfd5c561b7 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,27 @@ | |||
| 1 | 2012-12-17 Eli Zaretskii <eliz@gnu.org> | ||
| 2 | |||
| 3 | Emulate Posix ACL APIs on MS-Windows. | ||
| 4 | * w32.c: Include sddl.h and sys/acl.h. | ||
| 5 | (SDDL_REVISION_1): Define if not already defined. | ||
| 6 | (g_b_init_get_security_descriptor_dacl) | ||
| 7 | (g_b_init_convert_sd_to_sddl, g_b_init_convert_sddl_to_sd) | ||
| 8 | (g_b_init_is_valid_security_descriptor) | ||
| 9 | (g_b_init_set_file_security): New static flags. | ||
| 10 | (globals_of_w32): Initialize them to zero. | ||
| 11 | (SetFileSecurity_Name): New string constant. | ||
| 12 | (SetFileSecurity_Proc, GetSecurityDescriptorDacl_Proc) | ||
| 13 | (ConvertStringSecurityDescriptorToSecurityDescriptor_Proc) | ||
| 14 | (ConvertSecurityDescriptorToStringSecurityDescriptor_Proc) | ||
| 15 | (IsValidSecurityDescriptor_Proc): New typedefs. | ||
| 16 | (get_file_security, get_security_descriptor_owner) | ||
| 17 | (get_security_descriptor_group): Set errno to ENOTSUP. | ||
| 18 | (set_file_security, get_security_descriptor_dacl) | ||
| 19 | (is_valid_security_descriptor, convert_sd_to_sddl) | ||
| 20 | (convert_sddl_to_sd, acl_valid, acl_to_text, acl_from_text) | ||
| 21 | (acl_free, acl_get_file, acl_set_file): New functions. | ||
| 22 | |||
| 23 | * fileio.c (Fcopy_file) [WINDOWSNT]: Support copying ACLs. | ||
| 24 | |||
| 1 | 2012-12-17 Paul Eggert <eggert@cs.ucla.edu> | 25 | 2012-12-17 Paul Eggert <eggert@cs.ucla.edu> |
| 2 | 26 | ||
| 3 | Don't reraise SIGCHLD, as that can now lose (Bug#13192). | 27 | Don't reraise SIGCHLD, as that can now lose (Bug#13192). |
diff --git a/src/fileio.c b/src/fileio.c index f1cfe0eb625..26150a7e55b 100644 --- a/src/fileio.c +++ b/src/fileio.c | |||
| @@ -1956,6 +1956,14 @@ entries (depending on how Emacs was built). */) | |||
| 1956 | out_st.st_mode = 0; | 1956 | out_st.st_mode = 0; |
| 1957 | 1957 | ||
| 1958 | #ifdef WINDOWSNT | 1958 | #ifdef WINDOWSNT |
| 1959 | if (!NILP (preserve_extended_attributes)) | ||
| 1960 | { | ||
| 1961 | #ifdef HAVE_POSIX_ACL | ||
| 1962 | acl = acl_get_file (SDATA (encoded_file), ACL_TYPE_ACCESS); | ||
| 1963 | if (acl == NULL && errno != ENOTSUP) | ||
| 1964 | report_file_error ("Getting ACL", Fcons (file, Qnil)); | ||
| 1965 | #endif | ||
| 1966 | } | ||
| 1959 | if (!CopyFile (SDATA (encoded_file), | 1967 | if (!CopyFile (SDATA (encoded_file), |
| 1960 | SDATA (encoded_newname), | 1968 | SDATA (encoded_newname), |
| 1961 | FALSE)) | 1969 | FALSE)) |
| @@ -1983,6 +1991,17 @@ entries (depending on how Emacs was built). */) | |||
| 1983 | /* Restore original attributes. */ | 1991 | /* Restore original attributes. */ |
| 1984 | SetFileAttributes (filename, attributes); | 1992 | SetFileAttributes (filename, attributes); |
| 1985 | } | 1993 | } |
| 1994 | #ifdef HAVE_POSIX_ACL | ||
| 1995 | if (acl != NULL) | ||
| 1996 | { | ||
| 1997 | bool fail = | ||
| 1998 | acl_set_file (SDATA (encoded_newname), ACL_TYPE_ACCESS, acl) != 0; | ||
| 1999 | if (fail && errno != ENOTSUP) | ||
| 2000 | report_file_error ("Setting ACL", Fcons (newname, Qnil)); | ||
| 2001 | |||
| 2002 | acl_free (acl); | ||
| 2003 | } | ||
| 2004 | #endif | ||
| 1986 | #else /* not WINDOWSNT */ | 2005 | #else /* not WINDOWSNT */ |
| 1987 | immediate_quit = 1; | 2006 | immediate_quit = 1; |
| 1988 | ifd = emacs_open (SSDATA (encoded_file), O_RDONLY, 0); | 2007 | ifd = emacs_open (SSDATA (encoded_file), O_RDONLY, 0); |
| @@ -117,6 +117,15 @@ typedef struct _PROCESS_MEMORY_COUNTERS_EX { | |||
| 117 | 117 | ||
| 118 | #include <winioctl.h> | 118 | #include <winioctl.h> |
| 119 | #include <aclapi.h> | 119 | #include <aclapi.h> |
| 120 | #include <sddl.h> | ||
| 121 | |||
| 122 | #include <sys/acl.h> | ||
| 123 | |||
| 124 | /* This is not in MinGW's sddl.h (but they are in MSVC headers), so we | ||
| 125 | define them by hand if not already defined. */ | ||
| 126 | #ifndef SDDL_REVISION_1 | ||
| 127 | #define SDDL_REVISION_1 1 | ||
| 128 | #endif /* SDDL_REVISION_1 */ | ||
| 120 | 129 | ||
| 121 | #ifdef _MSC_VER | 130 | #ifdef _MSC_VER |
| 122 | /* MSVC doesn't provide the definition of REPARSE_DATA_BUFFER and the | 131 | /* MSVC doesn't provide the definition of REPARSE_DATA_BUFFER and the |
| @@ -257,6 +266,11 @@ static BOOL g_b_init_copy_sid; | |||
| 257 | static BOOL g_b_init_get_native_system_info; | 266 | static BOOL g_b_init_get_native_system_info; |
| 258 | static BOOL g_b_init_get_system_times; | 267 | static BOOL g_b_init_get_system_times; |
| 259 | static BOOL g_b_init_create_symbolic_link; | 268 | static BOOL g_b_init_create_symbolic_link; |
| 269 | static BOOL g_b_init_get_security_descriptor_dacl; | ||
| 270 | static BOOL g_b_init_convert_sd_to_sddl; | ||
| 271 | static BOOL g_b_init_convert_sddl_to_sd; | ||
| 272 | static BOOL g_b_init_is_valid_security_descriptor; | ||
| 273 | static BOOL g_b_init_set_file_security; | ||
| 260 | 274 | ||
| 261 | /* | 275 | /* |
| 262 | BEGIN: Wrapper functions around OpenProcessToken | 276 | BEGIN: Wrapper functions around OpenProcessToken |
| @@ -286,9 +300,11 @@ GetProcessTimes_Proc get_process_times_fn = NULL; | |||
| 286 | #ifdef _UNICODE | 300 | #ifdef _UNICODE |
| 287 | const char * const LookupAccountSid_Name = "LookupAccountSidW"; | 301 | const char * const LookupAccountSid_Name = "LookupAccountSidW"; |
| 288 | const char * const GetFileSecurity_Name = "GetFileSecurityW"; | 302 | const char * const GetFileSecurity_Name = "GetFileSecurityW"; |
| 303 | const char * const SetFileSecurity_Name = "SetFileSecurityW"; | ||
| 289 | #else | 304 | #else |
| 290 | const char * const LookupAccountSid_Name = "LookupAccountSidA"; | 305 | const char * const LookupAccountSid_Name = "LookupAccountSidA"; |
| 291 | const char * const GetFileSecurity_Name = "GetFileSecurityA"; | 306 | const char * const GetFileSecurity_Name = "GetFileSecurityA"; |
| 307 | const char * const SetFileSecurity_Name = "SetFileSecurityA"; | ||
| 292 | #endif | 308 | #endif |
| 293 | typedef BOOL (WINAPI * LookupAccountSid_Proc) ( | 309 | typedef BOOL (WINAPI * LookupAccountSid_Proc) ( |
| 294 | LPCTSTR lpSystemName, | 310 | LPCTSTR lpSystemName, |
| @@ -318,6 +334,10 @@ typedef BOOL (WINAPI * GetFileSecurity_Proc) ( | |||
| 318 | PSECURITY_DESCRIPTOR pSecurityDescriptor, | 334 | PSECURITY_DESCRIPTOR pSecurityDescriptor, |
| 319 | DWORD nLength, | 335 | DWORD nLength, |
| 320 | LPDWORD lpnLengthNeeded); | 336 | LPDWORD lpnLengthNeeded); |
| 337 | typedef BOOL (WINAPI *SetFileSecurity_Proc) ( | ||
| 338 | LPCTSTR lpFileName, | ||
| 339 | SECURITY_INFORMATION SecurityInformation, | ||
| 340 | PSECURITY_DESCRIPTOR pSecurityDescriptor); | ||
| 321 | typedef BOOL (WINAPI * GetSecurityDescriptorOwner_Proc) ( | 341 | typedef BOOL (WINAPI * GetSecurityDescriptorOwner_Proc) ( |
| 322 | PSECURITY_DESCRIPTOR pSecurityDescriptor, | 342 | PSECURITY_DESCRIPTOR pSecurityDescriptor, |
| 323 | PSID *pOwner, | 343 | PSID *pOwner, |
| @@ -326,6 +346,11 @@ typedef BOOL (WINAPI * GetSecurityDescriptorGroup_Proc) ( | |||
| 326 | PSECURITY_DESCRIPTOR pSecurityDescriptor, | 346 | PSECURITY_DESCRIPTOR pSecurityDescriptor, |
| 327 | PSID *pGroup, | 347 | PSID *pGroup, |
| 328 | LPBOOL lpbGroupDefaulted); | 348 | LPBOOL lpbGroupDefaulted); |
| 349 | typedef BOOL (WINAPI *GetSecurityDescriptorDacl_Proc) ( | ||
| 350 | PSECURITY_DESCRIPTOR pSecurityDescriptor, | ||
| 351 | LPBOOL lpbDaclPresent, | ||
| 352 | PACL *pDacl, | ||
| 353 | LPBOOL lpbDaclDefaulted); | ||
| 329 | typedef BOOL (WINAPI * IsValidSid_Proc) ( | 354 | typedef BOOL (WINAPI * IsValidSid_Proc) ( |
| 330 | PSID sid); | 355 | PSID sid); |
| 331 | typedef HANDLE (WINAPI * CreateToolhelp32Snapshot_Proc) ( | 356 | typedef HANDLE (WINAPI * CreateToolhelp32Snapshot_Proc) ( |
| @@ -376,6 +401,18 @@ typedef BOOLEAN (WINAPI *CreateSymbolicLink_Proc) ( | |||
| 376 | LPTSTR lpSymlinkFileName, | 401 | LPTSTR lpSymlinkFileName, |
| 377 | LPTSTR lpTargetFileName, | 402 | LPTSTR lpTargetFileName, |
| 378 | DWORD dwFlags); | 403 | DWORD dwFlags); |
| 404 | typedef BOOL (WINAPI *ConvertStringSecurityDescriptorToSecurityDescriptor_Proc) ( | ||
| 405 | LPCTSTR StringSecurityDescriptor, | ||
| 406 | DWORD StringSDRevision, | ||
| 407 | PSECURITY_DESCRIPTOR *SecurityDescriptor, | ||
| 408 | PULONG SecurityDescriptorSize); | ||
| 409 | typedef BOOL (WINAPI *ConvertSecurityDescriptorToStringSecurityDescriptor_Proc) ( | ||
| 410 | PSECURITY_DESCRIPTOR SecurityDescriptor, | ||
| 411 | DWORD RequestedStringSDRevision, | ||
| 412 | SECURITY_INFORMATION SecurityInformation, | ||
| 413 | LPTSTR *StringSecurityDescriptor, | ||
| 414 | PULONG StringSecurityDescriptorLen); | ||
| 415 | typedef BOOL (WINAPI *IsValidSecurityDescriptor_Proc) (PSECURITY_DESCRIPTOR); | ||
| 379 | 416 | ||
| 380 | /* ** A utility function ** */ | 417 | /* ** A utility function ** */ |
| 381 | static BOOL | 418 | static BOOL |
| @@ -621,6 +658,7 @@ get_file_security (LPCTSTR lpFileName, | |||
| 621 | HMODULE hm_advapi32 = NULL; | 658 | HMODULE hm_advapi32 = NULL; |
| 622 | if (is_windows_9x () == TRUE) | 659 | if (is_windows_9x () == TRUE) |
| 623 | { | 660 | { |
| 661 | errno = ENOTSUP; | ||
| 624 | return FALSE; | 662 | return FALSE; |
| 625 | } | 663 | } |
| 626 | if (g_b_init_get_file_security == 0) | 664 | if (g_b_init_get_file_security == 0) |
| @@ -633,6 +671,7 @@ get_file_security (LPCTSTR lpFileName, | |||
| 633 | } | 671 | } |
| 634 | if (s_pfn_Get_File_Security == NULL) | 672 | if (s_pfn_Get_File_Security == NULL) |
| 635 | { | 673 | { |
| 674 | errno = ENOTSUP; | ||
| 636 | return FALSE; | 675 | return FALSE; |
| 637 | } | 676 | } |
| 638 | return (s_pfn_Get_File_Security (lpFileName, RequestedInformation, | 677 | return (s_pfn_Get_File_Security (lpFileName, RequestedInformation, |
| @@ -641,6 +680,35 @@ get_file_security (LPCTSTR lpFileName, | |||
| 641 | } | 680 | } |
| 642 | 681 | ||
| 643 | static BOOL WINAPI | 682 | static BOOL WINAPI |
| 683 | set_file_security (LPCTSTR lpFileName, | ||
| 684 | SECURITY_INFORMATION SecurityInformation, | ||
| 685 | PSECURITY_DESCRIPTOR pSecurityDescriptor) | ||
| 686 | { | ||
| 687 | static SetFileSecurity_Proc s_pfn_Set_File_Security = NULL; | ||
| 688 | HMODULE hm_advapi32 = NULL; | ||
| 689 | if (is_windows_9x () == TRUE) | ||
| 690 | { | ||
| 691 | errno = ENOTSUP; | ||
| 692 | return FALSE; | ||
| 693 | } | ||
| 694 | if (g_b_init_set_file_security == 0) | ||
| 695 | { | ||
| 696 | g_b_init_set_file_security = 1; | ||
| 697 | hm_advapi32 = LoadLibrary ("Advapi32.dll"); | ||
| 698 | s_pfn_Set_File_Security = | ||
| 699 | (SetFileSecurity_Proc) GetProcAddress ( | ||
| 700 | hm_advapi32, SetFileSecurity_Name); | ||
| 701 | } | ||
| 702 | if (s_pfn_Set_File_Security == NULL) | ||
| 703 | { | ||
| 704 | errno = ENOTSUP; | ||
| 705 | return FALSE; | ||
| 706 | } | ||
| 707 | return (s_pfn_Set_File_Security (lpFileName, SecurityInformation, | ||
| 708 | pSecurityDescriptor)); | ||
| 709 | } | ||
| 710 | |||
| 711 | static BOOL WINAPI | ||
| 644 | get_security_descriptor_owner (PSECURITY_DESCRIPTOR pSecurityDescriptor, | 712 | get_security_descriptor_owner (PSECURITY_DESCRIPTOR pSecurityDescriptor, |
| 645 | PSID *pOwner, | 713 | PSID *pOwner, |
| 646 | LPBOOL lpbOwnerDefaulted) | 714 | LPBOOL lpbOwnerDefaulted) |
| @@ -649,6 +717,7 @@ get_security_descriptor_owner (PSECURITY_DESCRIPTOR pSecurityDescriptor, | |||
| 649 | HMODULE hm_advapi32 = NULL; | 717 | HMODULE hm_advapi32 = NULL; |
| 650 | if (is_windows_9x () == TRUE) | 718 | if (is_windows_9x () == TRUE) |
| 651 | { | 719 | { |
| 720 | errno = ENOTSUP; | ||
| 652 | return FALSE; | 721 | return FALSE; |
| 653 | } | 722 | } |
| 654 | if (g_b_init_get_security_descriptor_owner == 0) | 723 | if (g_b_init_get_security_descriptor_owner == 0) |
| @@ -661,6 +730,7 @@ get_security_descriptor_owner (PSECURITY_DESCRIPTOR pSecurityDescriptor, | |||
| 661 | } | 730 | } |
| 662 | if (s_pfn_Get_Security_Descriptor_Owner == NULL) | 731 | if (s_pfn_Get_Security_Descriptor_Owner == NULL) |
| 663 | { | 732 | { |
| 733 | errno = ENOTSUP; | ||
| 664 | return FALSE; | 734 | return FALSE; |
| 665 | } | 735 | } |
| 666 | return (s_pfn_Get_Security_Descriptor_Owner (pSecurityDescriptor, pOwner, | 736 | return (s_pfn_Get_Security_Descriptor_Owner (pSecurityDescriptor, pOwner, |
| @@ -676,6 +746,7 @@ get_security_descriptor_group (PSECURITY_DESCRIPTOR pSecurityDescriptor, | |||
| 676 | HMODULE hm_advapi32 = NULL; | 746 | HMODULE hm_advapi32 = NULL; |
| 677 | if (is_windows_9x () == TRUE) | 747 | if (is_windows_9x () == TRUE) |
| 678 | { | 748 | { |
| 749 | errno = ENOTSUP; | ||
| 679 | return FALSE; | 750 | return FALSE; |
| 680 | } | 751 | } |
| 681 | if (g_b_init_get_security_descriptor_group == 0) | 752 | if (g_b_init_get_security_descriptor_group == 0) |
| @@ -688,6 +759,7 @@ get_security_descriptor_group (PSECURITY_DESCRIPTOR pSecurityDescriptor, | |||
| 688 | } | 759 | } |
| 689 | if (s_pfn_Get_Security_Descriptor_Group == NULL) | 760 | if (s_pfn_Get_Security_Descriptor_Group == NULL) |
| 690 | { | 761 | { |
| 762 | errno = ENOTSUP; | ||
| 691 | return FALSE; | 763 | return FALSE; |
| 692 | } | 764 | } |
| 693 | return (s_pfn_Get_Security_Descriptor_Group (pSecurityDescriptor, pGroup, | 765 | return (s_pfn_Get_Security_Descriptor_Group (pSecurityDescriptor, pGroup, |
| @@ -695,6 +767,37 @@ get_security_descriptor_group (PSECURITY_DESCRIPTOR pSecurityDescriptor, | |||
| 695 | } | 767 | } |
| 696 | 768 | ||
| 697 | static BOOL WINAPI | 769 | static BOOL WINAPI |
| 770 | get_security_descriptor_dacl (PSECURITY_DESCRIPTOR pSecurityDescriptor, | ||
| 771 | LPBOOL lpbDaclPresent, | ||
| 772 | PACL *pDacl, | ||
| 773 | LPBOOL lpbDaclDefaulted) | ||
| 774 | { | ||
| 775 | static GetSecurityDescriptorDacl_Proc s_pfn_Get_Security_Descriptor_Dacl = NULL; | ||
| 776 | HMODULE hm_advapi32 = NULL; | ||
| 777 | if (is_windows_9x () == TRUE) | ||
| 778 | { | ||
| 779 | errno = ENOTSUP; | ||
| 780 | return FALSE; | ||
| 781 | } | ||
| 782 | if (g_b_init_get_security_descriptor_dacl == 0) | ||
| 783 | { | ||
| 784 | g_b_init_get_security_descriptor_dacl = 1; | ||
| 785 | hm_advapi32 = LoadLibrary ("Advapi32.dll"); | ||
| 786 | s_pfn_Get_Security_Descriptor_Dacl = | ||
| 787 | (GetSecurityDescriptorDacl_Proc) GetProcAddress ( | ||
| 788 | hm_advapi32, "GetSecurityDescriptorDacl"); | ||
| 789 | } | ||
| 790 | if (s_pfn_Get_Security_Descriptor_Dacl == NULL) | ||
| 791 | { | ||
| 792 | errno = ENOTSUP; | ||
| 793 | return FALSE; | ||
| 794 | } | ||
| 795 | return (s_pfn_Get_Security_Descriptor_Dacl (pSecurityDescriptor, | ||
| 796 | lpbDaclPresent, pDacl, | ||
| 797 | lpbDaclDefaulted)); | ||
| 798 | } | ||
| 799 | |||
| 800 | static BOOL WINAPI | ||
| 698 | is_valid_sid (PSID sid) | 801 | is_valid_sid (PSID sid) |
| 699 | { | 802 | { |
| 700 | static IsValidSid_Proc s_pfn_Is_Valid_Sid = NULL; | 803 | static IsValidSid_Proc s_pfn_Is_Valid_Sid = NULL; |
| @@ -888,6 +991,120 @@ create_symbolic_link (LPTSTR lpSymlinkFilename, | |||
| 888 | } | 991 | } |
| 889 | return retval; | 992 | return retval; |
| 890 | } | 993 | } |
| 994 | |||
| 995 | static BOOL WINAPI | ||
| 996 | is_valid_security_descriptor (PSECURITY_DESCRIPTOR pSecurityDescriptor) | ||
| 997 | { | ||
| 998 | static IsValidSecurityDescriptor_Proc s_pfn_Is_Valid_Security_Descriptor_Proc = NULL; | ||
| 999 | |||
| 1000 | if (is_windows_9x () == TRUE) | ||
| 1001 | { | ||
| 1002 | errno = ENOTSUP; | ||
| 1003 | return FALSE; | ||
| 1004 | } | ||
| 1005 | |||
| 1006 | if (g_b_init_is_valid_security_descriptor == 0) | ||
| 1007 | { | ||
| 1008 | g_b_init_is_valid_security_descriptor = 1; | ||
| 1009 | s_pfn_Is_Valid_Security_Descriptor_Proc = | ||
| 1010 | (IsValidSecurityDescriptor_Proc)GetProcAddress (GetModuleHandle ("Advapi32.dll"), | ||
| 1011 | "IsValidSecurityDescriptor"); | ||
| 1012 | } | ||
| 1013 | if (s_pfn_Is_Valid_Security_Descriptor_Proc == NULL) | ||
| 1014 | { | ||
| 1015 | errno = ENOTSUP; | ||
| 1016 | return FALSE; | ||
| 1017 | } | ||
| 1018 | |||
| 1019 | return s_pfn_Is_Valid_Security_Descriptor_Proc (pSecurityDescriptor); | ||
| 1020 | } | ||
| 1021 | |||
| 1022 | static BOOL WINAPI | ||
| 1023 | convert_sd_to_sddl (PSECURITY_DESCRIPTOR SecurityDescriptor, | ||
| 1024 | DWORD RequestedStringSDRevision, | ||
| 1025 | SECURITY_INFORMATION SecurityInformation, | ||
| 1026 | LPTSTR *StringSecurityDescriptor, | ||
| 1027 | PULONG StringSecurityDescriptorLen) | ||
| 1028 | { | ||
| 1029 | static ConvertSecurityDescriptorToStringSecurityDescriptor_Proc s_pfn_Convert_SD_To_SDDL = NULL; | ||
| 1030 | BOOL retval; | ||
| 1031 | |||
| 1032 | if (is_windows_9x () == TRUE) | ||
| 1033 | { | ||
| 1034 | errno = ENOTSUP; | ||
| 1035 | return FALSE; | ||
| 1036 | } | ||
| 1037 | |||
| 1038 | if (g_b_init_convert_sd_to_sddl == 0) | ||
| 1039 | { | ||
| 1040 | g_b_init_convert_sd_to_sddl = 1; | ||
| 1041 | #ifdef _UNICODE | ||
| 1042 | s_pfn_Convert_SD_To_SDDL = | ||
| 1043 | (ConvertSecurityDescriptorToStringSecurityDescriptor_Proc)GetProcAddress (GetModuleHandle ("Advapi32.dll"), | ||
| 1044 | "ConvertSecurityDescriptorToStringSecurityDescriptorW"); | ||
| 1045 | #else | ||
| 1046 | s_pfn_Convert_SD_To_SDDL = | ||
| 1047 | (ConvertSecurityDescriptorToStringSecurityDescriptor_Proc)GetProcAddress (GetModuleHandle ("Advapi32.dll"), | ||
| 1048 | "ConvertSecurityDescriptorToStringSecurityDescriptorA"); | ||
| 1049 | #endif | ||
| 1050 | } | ||
| 1051 | if (s_pfn_Convert_SD_To_SDDL == NULL) | ||
| 1052 | { | ||
| 1053 | errno = ENOTSUP; | ||
| 1054 | return FALSE; | ||
| 1055 | } | ||
| 1056 | |||
| 1057 | retval = s_pfn_Convert_SD_To_SDDL (SecurityDescriptor, | ||
| 1058 | RequestedStringSDRevision, | ||
| 1059 | SecurityInformation, | ||
| 1060 | StringSecurityDescriptor, | ||
| 1061 | StringSecurityDescriptorLen); | ||
| 1062 | |||
| 1063 | return retval; | ||
| 1064 | } | ||
| 1065 | |||
| 1066 | static BOOL WINAPI | ||
| 1067 | convert_sddl_to_sd (LPCTSTR StringSecurityDescriptor, | ||
| 1068 | DWORD StringSDRevision, | ||
| 1069 | PSECURITY_DESCRIPTOR *SecurityDescriptor, | ||
| 1070 | PULONG SecurityDescriptorSize) | ||
| 1071 | { | ||
| 1072 | static ConvertStringSecurityDescriptorToSecurityDescriptor_Proc s_pfn_Convert_SDDL_To_SD = NULL; | ||
| 1073 | BOOL retval; | ||
| 1074 | |||
| 1075 | if (is_windows_9x () == TRUE) | ||
| 1076 | { | ||
| 1077 | errno = ENOTSUP; | ||
| 1078 | return FALSE; | ||
| 1079 | } | ||
| 1080 | |||
| 1081 | if (g_b_init_convert_sddl_to_sd == 0) | ||
| 1082 | { | ||
| 1083 | g_b_init_convert_sddl_to_sd = 1; | ||
| 1084 | #ifdef _UNICODE | ||
| 1085 | s_pfn_Convert_SDDL_To_SD = | ||
| 1086 | (ConvertStringSecurityDescriptorToSecurityDescriptor_Proc)GetProcAddress (GetModuleHandle ("Advapi32.dll"), | ||
| 1087 | "ConvertStringSecurityDescriptorToSecurityDescriptorW"); | ||
| 1088 | #else | ||
| 1089 | s_pfn_Convert_SDDL_To_SD = | ||
| 1090 | (ConvertStringSecurityDescriptorToSecurityDescriptor_Proc)GetProcAddress (GetModuleHandle ("Advapi32.dll"), | ||
| 1091 | "ConvertStringSecurityDescriptorToSecurityDescriptorA"); | ||
| 1092 | #endif | ||
| 1093 | } | ||
| 1094 | if (s_pfn_Convert_SDDL_To_SD == NULL) | ||
| 1095 | { | ||
| 1096 | errno = ENOTSUP; | ||
| 1097 | return FALSE; | ||
| 1098 | } | ||
| 1099 | |||
| 1100 | retval = s_pfn_Convert_SDDL_To_SD (StringSecurityDescriptor, | ||
| 1101 | StringSDRevision, | ||
| 1102 | SecurityDescriptor, | ||
| 1103 | SecurityDescriptorSize); | ||
| 1104 | |||
| 1105 | return retval; | ||
| 1106 | } | ||
| 1107 | |||
| 891 | 1108 | ||
| 892 | 1109 | ||
| 893 | /* Return 1 if P is a valid pointer to an object of size SIZE. Return | 1110 | /* Return 1 if P is a valid pointer to an object of size SIZE. Return |
| @@ -4477,6 +4694,199 @@ chase_symlinks (const char *file) | |||
| 4477 | return target; | 4694 | return target; |
| 4478 | } | 4695 | } |
| 4479 | 4696 | ||
| 4697 | |||
| 4698 | /* Posix ACL emulation. */ | ||
| 4699 | |||
| 4700 | int | ||
| 4701 | acl_valid (acl_t acl) | ||
| 4702 | { | ||
| 4703 | return is_valid_security_descriptor ((PSECURITY_DESCRIPTOR)acl) ? 0 : -1; | ||
| 4704 | } | ||
| 4705 | |||
| 4706 | char * | ||
| 4707 | acl_to_text (acl_t acl, ssize_t *size) | ||
| 4708 | { | ||
| 4709 | LPTSTR str_acl; | ||
| 4710 | SECURITY_INFORMATION flags = | ||
| 4711 | OWNER_SECURITY_INFORMATION | | ||
| 4712 | GROUP_SECURITY_INFORMATION | | ||
| 4713 | DACL_SECURITY_INFORMATION; | ||
| 4714 | char *retval = NULL; | ||
| 4715 | ssize_t local_size; | ||
| 4716 | int e = errno; | ||
| 4717 | |||
| 4718 | errno = 0; | ||
| 4719 | |||
| 4720 | if (convert_sd_to_sddl ((PSECURITY_DESCRIPTOR)acl, SDDL_REVISION_1, flags, &str_acl, &local_size)) | ||
| 4721 | { | ||
| 4722 | errno = e; | ||
| 4723 | /* We don't want to mix heaps, so we duplicate the string in our | ||
| 4724 | heap and free the one allocated by the API. */ | ||
| 4725 | retval = xstrdup (str_acl); | ||
| 4726 | if (size) | ||
| 4727 | *size = local_size; | ||
| 4728 | LocalFree (str_acl); | ||
| 4729 | } | ||
| 4730 | else if (errno != ENOTSUP) | ||
| 4731 | errno = EINVAL; | ||
| 4732 | |||
| 4733 | return retval; | ||
| 4734 | } | ||
| 4735 | |||
| 4736 | acl_t | ||
| 4737 | acl_from_text (const char *acl_str) | ||
| 4738 | { | ||
| 4739 | PSECURITY_DESCRIPTOR psd, retval = NULL; | ||
| 4740 | ULONG sd_size; | ||
| 4741 | int e = errno; | ||
| 4742 | |||
| 4743 | errno = 0; | ||
| 4744 | |||
| 4745 | if (convert_sddl_to_sd (acl_str, SDDL_REVISION_1, &psd, &sd_size)) | ||
| 4746 | { | ||
| 4747 | errno = e; | ||
| 4748 | retval = xmalloc (sd_size); | ||
| 4749 | memcpy (retval, psd, sd_size); | ||
| 4750 | LocalFree (psd); | ||
| 4751 | } | ||
| 4752 | else if (errno != ENOTSUP) | ||
| 4753 | errno = EINVAL; | ||
| 4754 | |||
| 4755 | return retval; | ||
| 4756 | } | ||
| 4757 | |||
| 4758 | int | ||
| 4759 | acl_free (void *ptr) | ||
| 4760 | { | ||
| 4761 | xfree (ptr); | ||
| 4762 | return 0; | ||
| 4763 | } | ||
| 4764 | |||
| 4765 | acl_t | ||
| 4766 | acl_get_file (const char *fname, acl_type_t type) | ||
| 4767 | { | ||
| 4768 | PSECURITY_DESCRIPTOR psd = NULL; | ||
| 4769 | |||
| 4770 | if (type == ACL_TYPE_ACCESS) | ||
| 4771 | { | ||
| 4772 | DWORD sd_len, err; | ||
| 4773 | SECURITY_INFORMATION si = | ||
| 4774 | OWNER_SECURITY_INFORMATION | | ||
| 4775 | GROUP_SECURITY_INFORMATION | | ||
| 4776 | DACL_SECURITY_INFORMATION ; | ||
| 4777 | int e = errno; | ||
| 4778 | |||
| 4779 | errno = 0; | ||
| 4780 | if (!get_file_security (fname, si, psd, 0, &sd_len) | ||
| 4781 | && errno != ENOTSUP) | ||
| 4782 | { | ||
| 4783 | err = GetLastError (); | ||
| 4784 | if (err == ERROR_INSUFFICIENT_BUFFER) | ||
| 4785 | { | ||
| 4786 | psd = xmalloc (sd_len); | ||
| 4787 | if (!get_file_security (fname, si, psd, sd_len, &sd_len)) | ||
| 4788 | { | ||
| 4789 | xfree (psd); | ||
| 4790 | errno = EIO; | ||
| 4791 | psd = NULL; | ||
| 4792 | } | ||
| 4793 | } | ||
| 4794 | else if (err == ERROR_FILE_NOT_FOUND | ||
| 4795 | || err == ERROR_PATH_NOT_FOUND) | ||
| 4796 | errno = ENOENT; | ||
| 4797 | else | ||
| 4798 | errno = EIO; | ||
| 4799 | } | ||
| 4800 | else if (!errno) | ||
| 4801 | errno = e; | ||
| 4802 | } | ||
| 4803 | else if (type != ACL_TYPE_DEFAULT) | ||
| 4804 | errno = EINVAL; | ||
| 4805 | |||
| 4806 | return psd; | ||
| 4807 | } | ||
| 4808 | |||
| 4809 | int | ||
| 4810 | acl_set_file (const char *fname, acl_type_t type, acl_t acl) | ||
| 4811 | { | ||
| 4812 | TOKEN_PRIVILEGES old1, old2; | ||
| 4813 | DWORD err; | ||
| 4814 | BOOL res; | ||
| 4815 | int st = 0, retval = -1; | ||
| 4816 | SECURITY_INFORMATION flags = 0; | ||
| 4817 | PSID psid; | ||
| 4818 | PACL pacl; | ||
| 4819 | BOOL dflt; | ||
| 4820 | BOOL dacl_present; | ||
| 4821 | int e; | ||
| 4822 | |||
| 4823 | if (acl_valid (acl) != 0 | ||
| 4824 | || (type != ACL_TYPE_DEFAULT && type != ACL_TYPE_ACCESS)) | ||
| 4825 | { | ||
| 4826 | errno = EINVAL; | ||
| 4827 | return -1; | ||
| 4828 | } | ||
| 4829 | |||
| 4830 | if (type == ACL_TYPE_DEFAULT) | ||
| 4831 | { | ||
| 4832 | errno = ENOSYS; | ||
| 4833 | return -1; | ||
| 4834 | } | ||
| 4835 | |||
| 4836 | if (get_security_descriptor_owner ((PSECURITY_DESCRIPTOR)acl, &psid, &dflt) | ||
| 4837 | && psid) | ||
| 4838 | flags |= OWNER_SECURITY_INFORMATION; | ||
| 4839 | if (get_security_descriptor_group ((PSECURITY_DESCRIPTOR)acl, &psid, &dflt) | ||
| 4840 | && psid) | ||
| 4841 | flags |= GROUP_SECURITY_INFORMATION; | ||
| 4842 | if (get_security_descriptor_dacl ((PSECURITY_DESCRIPTOR)acl, &dacl_present, | ||
| 4843 | &pacl, &dflt) | ||
| 4844 | && dacl_present) | ||
| 4845 | flags |= DACL_SECURITY_INFORMATION; | ||
| 4846 | if (!flags) | ||
| 4847 | return 0; | ||
| 4848 | |||
| 4849 | /* According to KB-245153, setting the owner will succeed if either: | ||
| 4850 | (1) the caller is the user who will be the new owner, and has the | ||
| 4851 | SE_TAKE_OWNERSHIP privilege, or | ||
| 4852 | (2) the caller has the SE_RESTORE privilege, in which case she can | ||
| 4853 | set any valid user or group as the owner | ||
| 4854 | |||
| 4855 | We request below both SE_TAKE_OWNERSHIP and SE_RESTORE | ||
| 4856 | privileges, and disregard any failures in obtaining them. If | ||
| 4857 | these privileges cannot be obtained, and do not already exist in | ||
| 4858 | the calling thread's security token, this function could fail | ||
| 4859 | with EPERM. */ | ||
| 4860 | if (enable_privilege (SE_TAKE_OWNERSHIP_NAME, TRUE, &old1)) | ||
| 4861 | st++; | ||
| 4862 | if (enable_privilege (SE_RESTORE_NAME, TRUE, &old2)) | ||
| 4863 | st++; | ||
| 4864 | |||
| 4865 | e = errno; | ||
| 4866 | errno = 0; | ||
| 4867 | set_file_security ((char *)fname, flags, (PSECURITY_DESCRIPTOR)acl); | ||
| 4868 | err = GetLastError (); | ||
| 4869 | if (st >= 2) | ||
| 4870 | restore_privilege (&old2); | ||
| 4871 | if (st >= 1) | ||
| 4872 | restore_privilege (&old1); | ||
| 4873 | |||
| 4874 | if (errno == ENOTSUP) | ||
| 4875 | ; | ||
| 4876 | else if (err == ERROR_SUCCESS) | ||
| 4877 | { | ||
| 4878 | retval = 0; | ||
| 4879 | errno = e; | ||
| 4880 | } | ||
| 4881 | else if (err == ERROR_INVALID_OWNER) | ||
| 4882 | errno = EPERM; | ||
| 4883 | else if (err == ERROR_FILE_NOT_FOUND || err == ERROR_PATH_NOT_FOUND) | ||
| 4884 | errno = ENOENT; | ||
| 4885 | |||
| 4886 | return retval; | ||
| 4887 | } | ||
| 4888 | |||
| 4889 | |||
| 4480 | /* MS-Windows version of careadlinkat (cf. ../lib/careadlinkat.c). We | 4890 | /* MS-Windows version of careadlinkat (cf. ../lib/careadlinkat.c). We |
| 4481 | have a fixed max size for file names, so we don't need the kind of | 4891 | have a fixed max size for file names, so we don't need the kind of |
| 4482 | alloc/malloc/realloc dance the gnulib version does. We also don't | 4892 | alloc/malloc/realloc dance the gnulib version does. We also don't |
| @@ -6848,6 +7258,11 @@ globals_of_w32 (void) | |||
| 6848 | g_b_init_get_native_system_info = 0; | 7258 | g_b_init_get_native_system_info = 0; |
| 6849 | g_b_init_get_system_times = 0; | 7259 | g_b_init_get_system_times = 0; |
| 6850 | g_b_init_create_symbolic_link = 0; | 7260 | g_b_init_create_symbolic_link = 0; |
| 7261 | g_b_init_get_security_descriptor_dacl = 0; | ||
| 7262 | g_b_init_convert_sd_to_sddl = 0; | ||
| 7263 | g_b_init_convert_sddl_to_sd = 0; | ||
| 7264 | g_b_init_is_valid_security_descriptor = 0; | ||
| 7265 | g_b_init_set_file_security = 0; | ||
| 6851 | num_of_processors = 0; | 7266 | num_of_processors = 0; |
| 6852 | /* The following sets a handler for shutdown notifications for | 7267 | /* The following sets a handler for shutdown notifications for |
| 6853 | console apps. This actually applies to Emacs in both console and | 7268 | console apps. This actually applies to Emacs in both console and |