Preserve DACL when creating tempfile on Win32.
diff --git a/lib/zip_source_win32a.c b/lib/zip_source_win32a.c
index 03534a0..bb3ebaa 100644
--- a/lib/zip_source_win32a.c
+++ b/lib/zip_source_win32a.c
@@ -40,7 +40,7 @@
static void * _win32_strdup_a(const void *str);
static HANDLE _win32_open_a(_zip_source_win32_read_file_t *ctx);
-static HANDLE _win32_create_temp_a(_zip_source_win32_read_file_t *ctx, void **temp, zip_uint32_t value);
+static HANDLE _win32_create_temp_a(_zip_source_win32_read_file_t *ctx, void **temp, zip_uint32_t value, PSECURITY_ATTRIBUTES sa);
static int _win32_rename_temp_a(_zip_source_win32_read_file_t *ctx);
static int _win32_remove_a(const void *fname);
@@ -89,7 +89,7 @@
static HANDLE
-_win32_create_temp_a(_zip_source_win32_read_file_t *ctx, void **temp, zip_uint32_t value)
+_win32_create_temp_a(_zip_source_win32_read_file_t *ctx, void **temp, zip_uint32_t value, PSECURITY_ATTRIBUTES sa)
{
int len;
@@ -104,7 +104,7 @@
return INVALID_HANDLE_VALUE;
}
- return CreateFileA((const char *)*temp, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_TEMPORARY, NULL);
+ return CreateFileA((const char *)*temp, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, sa, CREATE_NEW, FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_TEMPORARY, NULL);
}
diff --git a/lib/zip_source_win32file.c b/lib/zip_source_win32file.c
index ee8319e..b392ab8 100644
--- a/lib/zip_source_win32file.c
+++ b/lib/zip_source_win32file.c
@@ -417,20 +417,52 @@
int i;
HANDLE th = INVALID_HANDLE_VALUE;
void *temp = NULL;
+ SECURITY_INFORMATION si;
+ SECURITY_ATTRIBUTES sa;
+ PSECURITY_DESCRIPTOR psd = NULL;
+ PSECURITY_ATTRIBUTES psa = NULL;
+ DWORD len;
+ BOOL success;
+
+ /*
+ Read the DACL from the original file, so we can copy it to the temp file.
+ If there is no original file, or if we can't read the DACL, we'll use the
+ default security descriptor.
+ */
+ if (ctx->h != INVALID_HANDLE_VALUE && GetFileType(ctx->h) == FILE_TYPE_DISK) {
+ si = DACL_SECURITY_INFORMATION | UNPROTECTED_DACL_SECURITY_INFORMATION;
+ len = 0;
+ success = GetUserObjectSecurity(ctx->h, &si, NULL, len, &len);
+ if (!success && GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
+ if ((psd = (PSECURITY_DESCRIPTOR)malloc(len)) == NULL) {
+ zip_error_set(&ctx->error, ZIP_ER_MEMORY, 0);
+ return -1;
+ }
+ success = GetUserObjectSecurity(ctx->h, &si, psd, len, &len);
+ }
+ if (success) {
+ sa.nLength = sizeof(SECURITY_ATTRIBUTES);
+ sa.bInheritHandle = FALSE;
+ sa.lpSecurityDescriptor = psd;
+ psa = &sa;
+ }
+ }
zip_uint32_t value = GetTickCount();
for (i = 0; i < 1024 && th == INVALID_HANDLE_VALUE; i++) {
- th = ctx->ops->op_create_temp(ctx, &temp, value + i);
+ th = ctx->ops->op_create_temp(ctx, &temp, value + i, psa);
if (th == INVALID_HANDLE_VALUE && GetLastError() != ERROR_FILE_EXISTS)
break;
}
if (th == INVALID_HANDLE_VALUE) {
free(temp);
+ free(psd);
zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, _zip_win32_error_to_errno(GetLastError()));
return -1;
}
+ free(psd);
ctx->hout = th;
ctx->tmpname = temp;
diff --git a/lib/zip_source_win32w.c b/lib/zip_source_win32w.c
index e58d2a3..d18b432 100644
--- a/lib/zip_source_win32w.c
+++ b/lib/zip_source_win32w.c
@@ -40,7 +40,7 @@
static void * _win32_strdup_w(const void *str);
static HANDLE _win32_open_w(_zip_source_win32_read_file_t *ctx);
-static HANDLE _win32_create_temp_w(_zip_source_win32_read_file_t *ctx, void **temp, zip_uint32_t value);
+static HANDLE _win32_create_temp_w(_zip_source_win32_read_file_t *ctx, void **temp, zip_uint32_t value, PSECURITY_ATTRIBUTES sa);
static int _win32_rename_temp_w(_zip_source_win32_read_file_t *ctx);
static int _win32_remove_w(const void *fname);
@@ -89,7 +89,7 @@
static HANDLE
-_win32_create_temp_w(_zip_source_win32_read_file_t *ctx, void **temp, zip_uint32_t value)
+_win32_create_temp_w(_zip_source_win32_read_file_t *ctx, void **temp, zip_uint32_t value, PSECURITY_ATTRIBUTES sa)
{
int len;
@@ -104,7 +104,7 @@
return INVALID_HANDLE_VALUE;
}
- return CreateFileW((const wchar_t *)*temp, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_TEMPORARY, NULL);
+ return CreateFileW((const wchar_t *)*temp, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, sa, CREATE_NEW, FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_TEMPORARY, NULL);
}
diff --git a/lib/zipwin32.h b/lib/zipwin32.h
index 3adfdc3..7416bd2 100644
--- a/lib/zipwin32.h
+++ b/lib/zipwin32.h
@@ -68,7 +68,7 @@
struct _zip_source_win32_file_ops {
void *(*op_strdup)(const void *);
void *(*op_open)(_zip_source_win32_read_file_t *);
- void *(*op_create_temp)(_zip_source_win32_read_file_t *, void **, zip_uint32_t);
+ void *(*op_create_temp)(_zip_source_win32_read_file_t *, void **, zip_uint32_t, PSECURITY_ATTRIBUTES);
int (*op_rename_temp)(_zip_source_win32_read_file_t *);
int (*op_remove)(const void *);
};