+4804. [port] win32: access() does not work on directories as
+ required by POSIX. Supply a alternative in
+ isc_file_isdirwritable. [RT #46394]
+
4803. [placeholder]
4802. [test] Refactor mkeys system test to make it quicker and more
#define EXCLBUFFERS 4096
#endif /* TUNE_LARGE */
-#ifdef WIN32
-#define DIR_PERM_OK W_OK
-#else
-#define DIR_PERM_OK W_OK|X_OK
-#endif
-
#define MAX_TCP_TIMEOUT 65535
/*%
goto cleanup;
} else if (directory != NULL) {
- if (access(directory, DIR_PERM_OK) != 0) {
+ if (!isc_file_isdirwritable(directory)) {
isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
NAMED_LOGMODULE_SERVER, ISC_LOG_ERROR,
"managed-keys-directory '%s' "
"option 'directory' contains relative path '%s'",
directory);
- if (access(directory, DIR_PERM_OK) != 0) {
+ if (!isc_file_isdirwritable(directory)) {
isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
NAMED_LOGMODULE_SERVER, ISC_LOG_ERROR,
"directory '%s' is not writable",
dir, isc_result_totext(result));
return (result);
}
- if (access(dir, DIR_PERM_OK) != 0) {
+ if (!isc_file_isdirwritable(dir)) {
isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
NAMED_LOGMODULE_SERVER, ISC_LOG_ERROR,
"new-zones-directory '%s' "
/*
* Check that the working directory is writable.
*/
- if (access(".", DIR_PERM_OK) != 0) {
+ if (!isc_file_isdirwritable(".")) {
isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
NAMED_LOGMODULE_SERVER, ISC_LOG_ERROR,
"the working directory is not writable");
cp ns2/named1.conf ns2/named.conf
mkdir ns2/nope
-chmod 555 ns2/nope
+
+if [ 1 = "${CYGWIN:-0}" ]
+then
+ setfacl -s user::r-x,group::r-x,other::r-x ns2/nope
+else
+ chmod 555 ns2/nope
+fi
* - ISC_R_NOSPACE if the resulting path would be longer than 'length'
*/
+isc_boolean_t
+isc_file_isdirwritable(const char *path);
+/*%<
+ * Return true if the path is a directory and is writable
+ */
+
ISC_LANG_ENDDECLS
#endif /* ISC_FILE_H */
strlcpy(path, buf, length);
return (ISC_R_SUCCESS);
}
+
+isc_boolean_t
+isc_file_isdirwritable(const char *path) {
+ return (ISC_TF(access(path, W_OK|X_OK) == 0));
+}
strlcpy(path, buf, length);
return (ISC_R_SUCCESS);
}
+
+/*
+ * Based on http://blog.aaronballman.com/2011/08/how-to-check-access-rights/
+ */
+isc_boolean_t
+isc_file_isdirwritable(const char *path) {
+ DWORD length = 0;
+ HANDLE hToken = NULL;
+ PSECURITY_DESCRIPTOR security = NULL;
+ isc_boolean_t answer = ISC_FALSE;
+
+ if (isc_file_isdirectory(path) != ISC_R_SUCCESS) {
+ return (answer);
+ }
+
+ /*
+ * Figure out buffer size. GetFileSecurity() should not succeed.
+ */
+ if (GetFileSecurity(path, OWNER_SECURITY_INFORMATION |
+ GROUP_SECURITY_INFORMATION |
+ DACL_SECURITY_INFORMATION,
+ NULL, 0, &length))
+ {
+ return (answer);
+ }
+
+ if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
+ return (answer);
+ }
+
+ security = malloc(length);
+ if (security == NULL) {
+ return (answer);
+ }
+
+ /*
+ * GetFileSecurity() should succeed.
+ */
+ if (!GetFileSecurity(path, OWNER_SECURITY_INFORMATION |
+ GROUP_SECURITY_INFORMATION |
+ DACL_SECURITY_INFORMATION,
+ security, length, &length))
+ {
+ return (answer);
+ }
+
+ if (OpenProcessToken(GetCurrentProcess(), TOKEN_IMPERSONATE |
+ TOKEN_QUERY | TOKEN_DUPLICATE |
+ STANDARD_RIGHTS_READ, &hToken))
+ {
+ HANDLE hImpersonatedToken = NULL;
+
+ if (DuplicateToken(hToken, SecurityImpersonation,
+ &hImpersonatedToken))
+ {
+ GENERIC_MAPPING mapping;
+ PRIVILEGE_SET privileges = { 0 };
+ DWORD grantedAccess = 0;
+ DWORD privilegesLength = sizeof(privileges);
+ BOOL result = FALSE;
+ DWORD genericAccessRights = GENERIC_WRITE;
+
+ mapping.GenericRead = FILE_GENERIC_READ;
+ mapping.GenericWrite = FILE_GENERIC_WRITE;
+ mapping.GenericExecute = FILE_GENERIC_EXECUTE;
+ mapping.GenericAll = FILE_ALL_ACCESS;
+
+ MapGenericMask(&genericAccessRights, &mapping);
+ if (AccessCheck(security, hImpersonatedToken,
+ genericAccessRights, &mapping,
+ &privileges, &privilegesLength,
+ &grantedAccess, &result))
+ {
+ answer = ISC_TF(result);
+ }
+ CloseHandle(hImpersonatedToken);
+ }
+ CloseHandle(hToken);
+ }
+ free(security);
+ return (answer);
+}
isc_file_ischdiridempotent
isc_file_iscurrentdir
isc_file_isdirectory
+isc_file_isdirwritable
isc_file_isplainfile
isc_file_isplainfilefd
isc_file_mktemplate