forked from wine-compholio/wine-staging
/
0005-server-Store-file-security-attributes-with-extended-.patch
118 lines (111 loc) · 3.85 KB
/
0005-server-Store-file-security-attributes-with-extended-.patch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
From 8f38d8b6dd8bdb5ab7f7ebe9c619566cc0430065 Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
Date: Mon, 30 Mar 2015 13:04:23 +0200
Subject: [PATCH] server: Store file security attributes with extended file
attributes. (v8)
---
server/file.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 66 insertions(+)
diff --git a/server/file.c b/server/file.c
index 74199126f59..ba27eab5957 100644
--- a/server/file.c
+++ b/server/file.c
@@ -32,6 +32,7 @@
#include <sys/time.h>
#include <sys/types.h>
#include <time.h>
+#include <limits.h>
#include <unistd.h>
#ifdef HAVE_UTIME_H
#include <utime.h>
@@ -39,6 +40,15 @@
#ifdef HAVE_POLL_H
#include <poll.h>
#endif
+#ifdef HAVE_ATTR_XATTR_H
+#undef XATTR_ADDITIONAL_OPTIONS
+#include <attr/xattr.h>
+#elif defined(HAVE_SYS_XATTR_H)
+#include <sys/xattr.h>
+#endif
+#ifdef HAVE_SYS_EXTATTR_H
+#include <sys/extattr.h>
+#endif
#include "ntstatus.h"
#define WIN32_NO_STATUS
@@ -52,6 +62,21 @@
#include "process.h"
#include "security.h"
+#ifndef XATTR_USER_PREFIX
+#define XATTR_USER_PREFIX "user."
+#endif
+#ifndef XATTR_SIZE_MAX
+#define XATTR_SIZE_MAX 65536
+#endif
+
+/* We intentionally do not match the Samba 4 extended attribute for NT security descriptors (SDs):
+ * 1) Samba stores this information using an internal data structure (we use a flat NT SD).
+ * 2) Samba uses the attribute "security.NTACL". This attribute is within a namespace that only
+ * the administrator has write access to, which prohibits the user from copying the attributes
+ * when copying a file and would require Wine to run with adminstrative privileges.
+ */
+#define WINE_XATTR_SD XATTR_USER_PREFIX "wine.sd"
+
struct file
{
struct object obj; /* object header */
@@ -204,6 +229,44 @@ int is_file_executable( const char *name )
return len >= 4 && (!strcasecmp( name + len - 4, ".exe") || !strcasecmp( name + len - 4, ".com" ));
}
+static int xattr_fset( int filedes, const char *name, void *value, size_t size )
+{
+#if defined(XATTR_ADDITIONAL_OPTIONS)
+ return fsetxattr( filedes, name, value, size, 0, 0 );
+#elif defined(HAVE_SYS_XATTR_H) || defined(HAVE_ATTR_XATTR_H)
+ return fsetxattr( filedes, name, value, size, 0 );
+#elif defined(HAVE_SYS_EXTATTR_H)
+ if (!xattr_valid_namespace( name )) return -1;
+ return extattr_set_fd( filedes, EXTATTR_NAMESPACE_USER, &name[XATTR_USER_PREFIX_LEN],
+ value, size );
+#else
+ errno = ENOSYS;
+ return -1;
+#endif
+}
+
+static void set_xattr_sd( int fd, const struct security_descriptor *sd )
+{
+ char buffer[XATTR_SIZE_MAX];
+ int present, len;
+ const ACL *dacl;
+
+ /* there's no point in storing the security descriptor if there's no DACL */
+ if (!sd) return;
+ dacl = sd_get_dacl( sd, &present );
+ if (!present || !dacl) return;
+
+ len = 2 + sizeof(struct security_descriptor) + sd->owner_len +
+ sd->group_len + sd->sacl_len + sd->dacl_len;
+ if (len > XATTR_SIZE_MAX) return;
+
+ /* include the descriptor revision and resource manager control bits */
+ buffer[0] = SECURITY_DESCRIPTOR_REVISION;
+ buffer[1] = 0;
+ memcpy( &buffer[2], sd, len - 2 );
+ xattr_fset( fd, WINE_XATTR_SD, buffer, len );
+}
+
static struct object *create_file( struct fd *root, const char *nameptr, data_size_t len,
unsigned int access, unsigned int sharing, int create,
unsigned int options, unsigned int attrs,
@@ -623,6 +686,9 @@ int set_file_sd( struct object *obj, struct fd *fd, mode_t *mode, uid_t *uid,
*mode = (*mode & S_IFMT) | new_mode;
}
+ /* extended attributes are set after the file mode, to ensure it stays in sync */
+ set_xattr_sd( unix_fd, new_sd );
+
free( obj->sd );
obj->sd = new_sd;
return 1;
--
2.28.0