Removed
Link Here
|
1 |
https://bugzilla.samba.org/show_bug.cgi?id=15376 |
2 |
|
3 |
--- source3/smbd/open.c 2023-04-19 12:18:56.254875400 +0200 |
4 |
+++ source3/smbd/open.c 2023-06-20 08:29:06.210298000 +0200 |
5 |
@@ -1204,9 +1204,6 @@ |
6 |
int new_fd; |
7 |
NTSTATUS status; |
8 |
|
9 |
- if (!fsp->fsp_flags.have_proc_fds) { |
10 |
- return NT_STATUS_MORE_PROCESSING_REQUIRED; |
11 |
- } |
12 |
|
13 |
old_fd = fsp_get_pathref_fd(fsp); |
14 |
if (old_fd == -1) { |
15 |
@@ -1222,22 +1219,28 @@ |
16 |
return NT_STATUS_INVALID_HANDLE; |
17 |
} |
18 |
|
19 |
- p = sys_proc_fd_path(old_fd, buf, sizeof(buf)); |
20 |
- if (p == NULL) { |
21 |
- return NT_STATUS_NO_MEMORY; |
22 |
- } |
23 |
+ |
24 |
+ if (sys_open_real_fd_from_pathref_fd(old_fd, &new_fd, flags) != 0) { |
25 |
+ if (!fsp->fsp_flags.have_proc_fds) { |
26 |
+ return NT_STATUS_MORE_PROCESSING_REQUIRED; |
27 |
+ } |
28 |
|
29 |
- proc_fname = (struct smb_filename) { |
30 |
- .base_name = discard_const_p(char, p), |
31 |
- }; |
32 |
+ p = sys_proc_fd_path(old_fd, buf, sizeof(buf)); |
33 |
+ if (p == NULL) { |
34 |
+ return NT_STATUS_NO_MEMORY; |
35 |
+ } |
36 |
|
37 |
- fsp->fsp_flags.is_pathref = false; |
38 |
+ proc_fname = (struct smb_filename) { |
39 |
+ .base_name = discard_const_p(char, p), |
40 |
+ }; |
41 |
|
42 |
- new_fd = SMB_VFS_OPENAT(fsp->conn, |
43 |
- fsp->conn->cwd_fsp, |
44 |
- &proc_fname, |
45 |
- fsp, |
46 |
- &how); |
47 |
+ new_fd = SMB_VFS_OPENAT(fsp->conn, |
48 |
+ fsp->conn->cwd_fsp, |
49 |
+ &proc_fname, |
50 |
+ fsp, |
51 |
+ &how); |
52 |
+ } |
53 |
+ |
54 |
if (new_fd == -1) { |
55 |
status = map_nt_error_from_unix(errno); |
56 |
fd_close(fsp); |
57 |
@@ -1250,6 +1260,8 @@ |
58 |
} |
59 |
|
60 |
fsp_set_fd(fsp, new_fd); |
61 |
+ fsp->fsp_flags.is_pathref = false; |
62 |
+ |
63 |
return NT_STATUS_OK; |
64 |
} |
65 |
|
66 |
--- source3/lib/system.c 2023-01-18 16:32:24.174553200 +0100 |
67 |
+++ source3/lib/system.c 2023-06-19 23:35:30.132465000 +0200 |
68 |
@@ -1022,6 +1022,8 @@ |
69 |
} proc_fd_patterns[] = { |
70 |
/* Linux */ |
71 |
{ "/proc/self/fd/%d", "/proc/self/fd/0" }, |
72 |
+ /* FreeBSD */ |
73 |
+ { "/compat/linux/dev/fd/%d", "/compat/linux/dev/fd/0" }, |
74 |
{ NULL, NULL }, |
75 |
}; |
76 |
|
77 |
@@ -1077,4 +1079,27 @@ |
78 |
} |
79 |
|
80 |
return buf; |
81 |
+} |
82 |
+ |
83 |
+ |
84 |
+/* Helper function that opens a usable fd for accessing data |
85 |
+ (metadata & content) from a pathref fd */ |
86 |
+int sys_open_real_fd_from_pathref_fd(int fd, |
87 |
+ int *rfd, |
88 |
+ int flags) { |
89 |
+ int tfd; |
90 |
+ |
91 |
+#if defined(HAVE_OPENAT) && defined(O_EMPTY_PATH) |
92 |
+ /* This works for FreeBSD 13+ atleast */ |
93 |
+ |
94 |
+ tfd = openat(fd, "", O_EMPTY_PATH|flags); |
95 |
+ if (tfd < 0) { |
96 |
+ return errno; |
97 |
+ } |
98 |
+ |
99 |
+ *rfd = tfd; |
100 |
+ return 0; |
101 |
+#else |
102 |
+ return ENOSYS; |
103 |
+#endif |
104 |
} |
105 |
--- source3/modules/vfs_default.c 2023-05-31 18:06:44.154299500 +0200 |
106 |
+++ source3/modules/vfs_default.c 2023-06-19 23:23:58.116903000 +0200 |
107 |
@@ -2721,7 +2721,7 @@ |
108 |
|
109 |
static int vfswrap_fchmod(vfs_handle_struct *handle, files_struct *fsp, mode_t mode) |
110 |
{ |
111 |
- int result; |
112 |
+ int result, fd, real_fd; |
113 |
|
114 |
START_PROFILE(syscall_fchmod); |
115 |
|
116 |
@@ -2731,8 +2731,9 @@ |
117 |
return result; |
118 |
} |
119 |
|
120 |
+ fd = fsp_get_pathref_fd(fsp); |
121 |
+ |
122 |
if (fsp->fsp_flags.have_proc_fds) { |
123 |
- int fd = fsp_get_pathref_fd(fsp); |
124 |
const char *p = NULL; |
125 |
char buf[PATH_MAX]; |
126 |
|
127 |
@@ -2746,6 +2747,17 @@ |
128 |
return result; |
129 |
} |
130 |
|
131 |
+ if (sys_open_real_fd_from_pathref_fd(fd, &real_fd, O_RDONLY|O_NONBLOCK) == 0) { |
132 |
+ int saved_errno; |
133 |
+ |
134 |
+ result = fchmod(real_fd, mode); |
135 |
+ saved_errno = errno; |
136 |
+ close(real_fd); |
137 |
+ errno = saved_errno; |
138 |
+ END_PROFILE(syscall_fchmod); |
139 |
+ return result; |
140 |
+ } |
141 |
+ |
142 |
/* |
143 |
* This is no longer a handle based call. |
144 |
*/ |
145 |
@@ -2758,7 +2770,7 @@ |
146 |
static int vfswrap_fchown(vfs_handle_struct *handle, files_struct *fsp, uid_t uid, gid_t gid) |
147 |
{ |
148 |
#ifdef HAVE_FCHOWN |
149 |
- int result; |
150 |
+ int result, fd, real_fd; |
151 |
|
152 |
START_PROFILE(syscall_fchown); |
153 |
if (!fsp->fsp_flags.is_pathref) { |
154 |
@@ -2767,8 +2779,9 @@ |
155 |
return result; |
156 |
} |
157 |
|
158 |
+ fd = fsp_get_pathref_fd(fsp); |
159 |
+ |
160 |
if (fsp->fsp_flags.have_proc_fds) { |
161 |
- int fd = fsp_get_pathref_fd(fsp); |
162 |
const char *p = NULL; |
163 |
char buf[PATH_MAX]; |
164 |
|
165 |
@@ -2782,6 +2795,17 @@ |
166 |
return result; |
167 |
} |
168 |
|
169 |
+ if (sys_open_real_fd_from_pathref_fd(fd, &real_fd, O_RDONLY|O_NONBLOCK) == 0) { |
170 |
+ int saved_errno; |
171 |
+ |
172 |
+ result = fchown(real_fd, uid, gid); |
173 |
+ saved_errno = errno; |
174 |
+ close(real_fd); |
175 |
+ errno = saved_errno; |
176 |
+ END_PROFILE(syscall_fchown); |
177 |
+ return result; |
178 |
+ } |
179 |
+ |
180 |
/* |
181 |
* This is no longer a handle based call. |
182 |
*/ |
183 |
@@ -2855,7 +2879,7 @@ |
184 |
files_struct *fsp, |
185 |
struct smb_file_time *ft) |
186 |
{ |
187 |
- int result = -1; |
188 |
+ int result = -1, fd, real_fd; |
189 |
struct timespec ts[2]; |
190 |
struct timespec *times = NULL; |
191 |
|
192 |
@@ -2900,8 +2924,9 @@ |
193 |
goto out; |
194 |
} |
195 |
|
196 |
+ fd = fsp_get_pathref_fd(fsp); |
197 |
+ |
198 |
if (fsp->fsp_flags.have_proc_fds) { |
199 |
- int fd = fsp_get_pathref_fd(fsp); |
200 |
const char *p = NULL; |
201 |
char buf[PATH_MAX]; |
202 |
|
203 |
@@ -2919,6 +2944,16 @@ |
204 |
goto out; |
205 |
} |
206 |
|
207 |
+ if (sys_open_real_fd_from_pathref_fd(fd, &real_fd, O_RDONLY|O_NONBLOCK) == 0) { |
208 |
+ int saved_errno; |
209 |
+ |
210 |
+ result = futimens(real_fd, times); |
211 |
+ saved_errno = errno; |
212 |
+ close(real_fd); |
213 |
+ errno = saved_errno; |
214 |
+ goto out; |
215 |
+ } |
216 |
+ |
217 |
/* |
218 |
* The fd is a pathref (opened with O_PATH) and there isn't fd to |
219 |
* path translation mechanism. Fallback to path based call. |
220 |
@@ -3322,6 +3357,7 @@ |
221 |
{ |
222 |
#ifdef HAVE_FCHFLAGS |
223 |
int fd = fsp_get_pathref_fd(fsp); |
224 |
+ int real_fd; |
225 |
|
226 |
SMB_ASSERT(!fsp_is_alternate_stream(fsp)); |
227 |
|
228 |
@@ -3341,6 +3377,16 @@ |
229 |
return chflags(p, flags); |
230 |
} |
231 |
|
232 |
+ if (sys_open_real_fd_from_pathref_fd(fd, &real_fd, O_RDONLY|O_NONBLOCK) == 0) { |
233 |
+ int saved_errno, result; |
234 |
+ |
235 |
+ result = fchflags(real_fd, flags); |
236 |
+ saved_errno = errno; |
237 |
+ close(real_fd); |
238 |
+ errno = saved_errno; |
239 |
+ return result; |
240 |
+ } |
241 |
+ |
242 |
/* |
243 |
* This is no longer a handle based call. |
244 |
*/ |
245 |
@@ -3569,6 +3615,7 @@ |
246 |
size_t size) |
247 |
{ |
248 |
int fd = fsp_get_pathref_fd(fsp); |
249 |
+ int real_fd; |
250 |
|
251 |
SMB_ASSERT(!fsp_is_alternate_stream(fsp)); |
252 |
|
253 |
@@ -3588,6 +3635,16 @@ |
254 |
return getxattr(p, name, value, size); |
255 |
} |
256 |
|
257 |
+ if (sys_open_real_fd_from_pathref_fd(fd, &real_fd, O_RDONLY|O_NONBLOCK) == 0) { |
258 |
+ int saved_errno, result; |
259 |
+ |
260 |
+ result = fgetxattr(real_fd, name, value, size); |
261 |
+ saved_errno = errno; |
262 |
+ close(real_fd); |
263 |
+ errno = saved_errno; |
264 |
+ return result; |
265 |
+ } |
266 |
+ |
267 |
/* |
268 |
* This is no longer a handle based call. |
269 |
*/ |
270 |
@@ -3895,6 +3952,7 @@ |
271 |
static ssize_t vfswrap_flistxattr(struct vfs_handle_struct *handle, struct files_struct *fsp, char *list, size_t size) |
272 |
{ |
273 |
int fd = fsp_get_pathref_fd(fsp); |
274 |
+ int real_fd; |
275 |
|
276 |
SMB_ASSERT(!fsp_is_alternate_stream(fsp)); |
277 |
|
278 |
@@ -3914,6 +3972,16 @@ |
279 |
return listxattr(p, list, size); |
280 |
} |
281 |
|
282 |
+ if (sys_open_real_fd_from_pathref_fd(fd, &real_fd, O_RDONLY|O_NONBLOCK) == 0) { |
283 |
+ int saved_errno, result; |
284 |
+ |
285 |
+ result = flistxattr(real_fd, list, size); |
286 |
+ saved_errno = errno; |
287 |
+ close(real_fd); |
288 |
+ errno = saved_errno; |
289 |
+ return result; |
290 |
+ } |
291 |
+ |
292 |
/* |
293 |
* This is no longer a handle based call. |
294 |
*/ |
295 |
@@ -3923,6 +3991,7 @@ |
296 |
static int vfswrap_fremovexattr(struct vfs_handle_struct *handle, struct files_struct *fsp, const char *name) |
297 |
{ |
298 |
int fd = fsp_get_pathref_fd(fsp); |
299 |
+ int real_fd; |
300 |
|
301 |
SMB_ASSERT(!fsp_is_alternate_stream(fsp)); |
302 |
|
303 |
@@ -3942,6 +4011,16 @@ |
304 |
return removexattr(p, name); |
305 |
} |
306 |
|
307 |
+ if (sys_open_real_fd_from_pathref_fd(fd, &real_fd, O_RDONLY|O_NONBLOCK) == 0) { |
308 |
+ int saved_errno, result; |
309 |
+ |
310 |
+ result = fremovexattr(real_fd, name); |
311 |
+ saved_errno = errno; |
312 |
+ close(real_fd); |
313 |
+ errno = saved_errno; |
314 |
+ return result; |
315 |
+ } |
316 |
+ |
317 |
/* |
318 |
* This is no longer a handle based call. |
319 |
*/ |
320 |
@@ -3951,6 +4030,7 @@ |
321 |
static int vfswrap_fsetxattr(struct vfs_handle_struct *handle, struct files_struct *fsp, const char *name, const void *value, size_t size, int flags) |
322 |
{ |
323 |
int fd = fsp_get_pathref_fd(fsp); |
324 |
+ int real_fd; |
325 |
|
326 |
SMB_ASSERT(!fsp_is_alternate_stream(fsp)); |
327 |
|
328 |
@@ -3968,6 +4048,16 @@ |
329 |
} |
330 |
|
331 |
return setxattr(p, name, value, size, flags); |
332 |
+ } |
333 |
+ |
334 |
+ if (sys_open_real_fd_from_pathref_fd(fd, &real_fd, O_RDONLY|O_NONBLOCK) == 0) { |
335 |
+ int saved_errno, result; |
336 |
+ |
337 |
+ result = fsetxattr(real_fd, name, value, size, flags); |
338 |
+ saved_errno = errno; |
339 |
+ close(real_fd); |
340 |
+ errno = saved_errno; |
341 |
+ return result; |
342 |
} |
343 |
|
344 |
/* |
345 |
--- source3/modules/vfs_zfsacl.c 2023-01-18 16:32:24.210553400 +0100 |
346 |
+++ source3/modules/vfs_zfsacl.c 2023-06-20 08:51:53.077953000 +0200 |
347 |
@@ -234,13 +234,39 @@ |
348 |
|
349 |
SMB_ASSERT(i == naces); |
350 |
|
351 |
- /* store acl */ |
352 |
- fd = fsp_get_pathref_fd(fsp); |
353 |
- if (fd == -1) { |
354 |
- errno = EBADF; |
355 |
- return false; |
356 |
+ if (!fsp->fsp_flags.is_pathref) { |
357 |
+ rv = facl(fsp_get_io_fd(fsp), ACE_SETACL, naces, acebuf); |
358 |
+ } else { |
359 |
+ const char *procfd_p = NULL; |
360 |
+ char buf[PATH_MAX]; |
361 |
+ |
362 |
+ fd = fsp_get_pathref_fd(fsp); |
363 |
+ if (fsp->fsp_flags.have_proc_fds && (procfd_p = sys_proc_fd_path(fd, buf, sizeof(buf)))) { |
364 |
+ rv = acl(procfd_p, ACE_SETACL, naces, acebuf); |
365 |
+ } else { |
366 |
+ int real_fd; |
367 |
+ |
368 |
+ fd = fsp_get_pathref_fd(fsp); |
369 |
+ |
370 |
+ /* First try this for versions of FreeBSD 13+ that allows facl() on O_PATH fd's */ |
371 |
+ rv = facl(fd, ACE_SETACL, naces, acebuf); |
372 |
+ |
373 |
+ if (rv < 0 && errno == EBADF && |
374 |
+ sys_open_real_fd_from_pathref_fd(fd, &real_fd, O_RDONLY|O_NONBLOCK) == 0) { |
375 |
+ /* Works on FreeBSD 13+ */ |
376 |
+ int saved_errno; |
377 |
+ |
378 |
+ rv = facl(real_fd, ACE_SETACL, naces, acebuf); |
379 |
+ saved_errno = errno; |
380 |
+ close(real_fd); |
381 |
+ errno = saved_errno; |
382 |
+ } else { |
383 |
+ /* Last ditch fallback */ |
384 |
+ rv = acl(fsp->fsp_name->base_name, ACE_SETACL, naces, acebuf); |
385 |
+ } |
386 |
+ } |
387 |
} |
388 |
- rv = facl(fd, ACE_SETACL, naces, acebuf); |
389 |
+ |
390 |
if (rv != 0) { |
391 |
if(errno == ENOSYS) { |
392 |
DEBUG(9, ("acl(ACE_SETACL, %s): Operation is not " |
393 |
@@ -284,14 +310,39 @@ |
394 |
{ |
395 |
int naces, rv; |
396 |
ace_t *acebuf = NULL; |
397 |
- int fd; |
398 |
+ int fd = -1; |
399 |
+ const char *procfd_p = NULL; |
400 |
+ char buf[PATH_MAX]; |
401 |
|
402 |
- fd = fsp_get_pathref_fd(fsp); |
403 |
- if (fd == -1) { |
404 |
- errno = EBADF; |
405 |
- return -1; |
406 |
+ if (!fsp->fsp_flags.is_pathref) { |
407 |
+ naces = facl(fsp_get_io_fd(fsp), ACE_GETACLCNT, 0, NULL); |
408 |
+ } else { |
409 |
+ fd = fsp_get_pathref_fd(fsp); |
410 |
+ |
411 |
+ if (fsp->fsp_flags.have_proc_fds && (procfd_p = sys_proc_fd_path(fd, buf, sizeof(buf)))) { |
412 |
+ /* If we have procfd support, try this first */ |
413 |
+ naces = acl(procfd_p, ACE_GETACLCNT, 0, NULL); |
414 |
+ } else { |
415 |
+ int real_fd; |
416 |
+ |
417 |
+ /* First try this for versions of FreeBSD 13+ that allows facl() on O_PATH fd's */ |
418 |
+ naces = facl(fd, ACE_GETACLCNT, 0, NULL); |
419 |
+ if (naces < 0 && errno == EBADF && |
420 |
+ sys_open_real_fd_from_pathref_fd(fd, &real_fd, O_RDONLY|O_NONBLOCK) == 0) { |
421 |
+ /* Works on FreeBSD 13+ */ |
422 |
+ int saved_errno; |
423 |
+ |
424 |
+ naces = facl(real_fd, ACE_GETACLCNT, 0, NULL); |
425 |
+ saved_errno = errno; |
426 |
+ close(real_fd); |
427 |
+ errno = saved_errno; |
428 |
+ } else { |
429 |
+ /* Last ditch fallback */ |
430 |
+ naces = acl(fsp->fsp_name->base_name, ACE_GETACLCNT, 0, NULL); |
431 |
+ } |
432 |
+ } |
433 |
} |
434 |
- naces = facl(fd, ACE_GETACLCNT, 0, NULL); |
435 |
+ |
436 |
if (naces == -1) { |
437 |
int dbg_level = 10; |
438 |
|
439 |
@@ -309,7 +360,32 @@ |
440 |
return -1; |
441 |
} |
442 |
|
443 |
- rv = facl(fd, ACE_GETACL, naces, acebuf); |
444 |
+ if (!fsp->fsp_flags.is_pathref) { |
445 |
+ rv = facl(fsp_get_io_fd(fsp), ACE_GETACL, naces, acebuf); |
446 |
+ } else { |
447 |
+ if (procfd_p) { |
448 |
+ rv = acl(procfd_p, ACE_GETACL, naces, acebuf); |
449 |
+ } else { |
450 |
+ int real_fd; |
451 |
+ |
452 |
+ /* First try this for versions of FreeBSD that allows facl() on O_PATH fd's */ |
453 |
+ rv = facl(fd, ACE_GETACL, naces, acebuf); |
454 |
+ if (rv < 0 && errno == EBADF && |
455 |
+ sys_open_real_fd_from_pathref_fd(fd, &real_fd, O_RDONLY|O_NONBLOCK) == 0) { |
456 |
+ /* Works on FreeBSD 13+ */ |
457 |
+ int saved_errno; |
458 |
+ |
459 |
+ rv = facl(real_fd, ACE_GETACL, naces, acebuf); |
460 |
+ saved_errno = errno; |
461 |
+ close(real_fd); |
462 |
+ errno = saved_errno; |
463 |
+ } else { |
464 |
+ /* Last ditch fallback */ |
465 |
+ rv = acl(fsp->fsp_name->base_name, ACE_GETACL, naces, acebuf); |
466 |
+ } |
467 |
+ } |
468 |
+ } |
469 |
+ |
470 |
if (rv == -1) { |
471 |
DBG_DEBUG("acl(ACE_GETACL, %s): %s ", |
472 |
fsp_str_dbg(fsp), strerror(errno)); |
473 |
--- source3/include/proto.h 2023-05-31 18:06:44.142299400 +0200 |
474 |
+++ source3/include/proto.h 2023-06-19 23:23:58.115127000 +0200 |
475 |
@@ -211,6 +211,10 @@ |
476 |
bool sys_have_proc_fds(void); |
477 |
const char *sys_proc_fd_path(int fd, char *buf, size_t bufsize); |
478 |
|
479 |
+int sys_open_real_fd_from_pathref_fd(int fd, |
480 |
+ int *mfd, |
481 |
+ int flags); |
482 |
+ |
483 |
struct stat; |
484 |
void init_stat_ex_from_stat (struct stat_ex *dst, |
485 |
const struct stat *src, |
486 |
- |