View | Details | Raw Unified | Return to bug 277878 | Differences between
and this patch

Collapse All | Expand All

(-)samba-4.18.3/source3/smbd/open.c (-16 / +21 lines)
Lines 1204-1212 Link Here
1204
	int new_fd;
1204
	int new_fd;
1205
	NTSTATUS status;
1205
	NTSTATUS status;
1206
1206
1207
	if (!fsp->fsp_flags.have_proc_fds) {
1208
		return NT_STATUS_MORE_PROCESSING_REQUIRED;
1209
	}
1210
1207
1211
	old_fd = fsp_get_pathref_fd(fsp);
1208
	old_fd = fsp_get_pathref_fd(fsp);
1212
	if (old_fd == -1) {
1209
	if (old_fd == -1) {
Lines 1222-1243 Link Here
1222
		return NT_STATUS_INVALID_HANDLE;
1219
		return NT_STATUS_INVALID_HANDLE;
1223
	}
1220
	}
1224
1221
1225
	p = sys_proc_fd_path(old_fd, buf, sizeof(buf));
1222
	
1226
	if (p == NULL) {
1223
	if (sys_open_real_fd_from_pathref_fd(old_fd, &new_fd, flags) != 0) {
1227
		return NT_STATUS_NO_MEMORY;
1224
		if (!fsp->fsp_flags.have_proc_fds) {
1228
	}
1225
			return NT_STATUS_MORE_PROCESSING_REQUIRED;
1226
		}
1229
1227
1230
	proc_fname = (struct smb_filename) {
1228
		p = sys_proc_fd_path(old_fd, buf, sizeof(buf));
1231
		.base_name = discard_const_p(char, p),
1229
		if (p == NULL) {
1232
	};
1230
			return NT_STATUS_NO_MEMORY;
1231
		}
1233
1232
1234
	fsp->fsp_flags.is_pathref = false;
1233
		proc_fname = (struct smb_filename) {
1234
			.base_name = discard_const_p(char, p),
1235
		};
1235
1236
1236
	new_fd = SMB_VFS_OPENAT(fsp->conn,
1237
		new_fd = SMB_VFS_OPENAT(fsp->conn,
1237
				fsp->conn->cwd_fsp,
1238
					fsp->conn->cwd_fsp,
1238
				&proc_fname,
1239
					&proc_fname,
1239
				fsp,
1240
					fsp,
1240
				&how);
1241
					&how);
1242
	}
1243
1241
	if (new_fd == -1) {
1244
	if (new_fd == -1) {
1242
		status = map_nt_error_from_unix(errno);
1245
		status = map_nt_error_from_unix(errno);
1243
		fd_close(fsp);
1246
		fd_close(fsp);
Lines 1250-1255 Link Here
1250
	}
1260
	}
1251
1261
1252
	fsp_set_fd(fsp, new_fd);
1262
	fsp_set_fd(fsp, new_fd);
1263
	fsp->fsp_flags.is_pathref = false;
1264
	
1253
	return NT_STATUS_OK;
1265
	return NT_STATUS_OK;
1254
}
1266
}
1255
1267
(-)samba-4.18.3/source3/lib/system.c (+25 lines)
Lines 1022-1027 Link Here
1022
} proc_fd_patterns[] = {
1022
} proc_fd_patterns[] = {
1023
	/* Linux */
1023
	/* Linux */
1024
	{ "/proc/self/fd/%d", "/proc/self/fd/0" },
1024
	{ "/proc/self/fd/%d", "/proc/self/fd/0" },
1025
	/* FreeBSD */
1026
	{ "/compat/linux/dev/fd/%d", "/compat/linux/dev/fd/0" },
1025
	{ NULL, NULL },
1027
	{ NULL, NULL },
1026
};
1028
};
1027
1029
Lines 1077-1080 Link Here
1077
	}
1079
	}
1078
1080
1079
	return buf;
1081
	return buf;
1082
}
1083
1084
1085
/* Helper function that opens a usable fd for accessing data
1086
   (metadata & content) from a pathref fd */
1087
int sys_open_real_fd_from_pathref_fd(int fd,
1088
				     int *rfd,
1089
				     int flags) {
1090
	int tfd;
1091
1092
#if defined(HAVE_OPENAT) && defined(O_EMPTY_PATH)
1093
	/* This works for FreeBSD 13+ atleast */
1094
	
1095
	tfd = openat(fd, "", O_EMPTY_PATH|flags);
1096
	if (tfd < 0) {
1097
		return errno;
1098
	}
1099
1100
	*rfd = tfd;
1101
	return 0;
1102
#else
1103
	return ENOSYS;
1104
#endif
1080
}
1105
}
(-)samba-4.18.3/source3/modules/vfs_default.c (-6 / +96 lines)
Lines 2721-2727 Link Here
2721
2721
2722
static int vfswrap_fchmod(vfs_handle_struct *handle, files_struct *fsp, mode_t mode)
2722
static int vfswrap_fchmod(vfs_handle_struct *handle, files_struct *fsp, mode_t mode)
2723
{
2723
{
2724
	int result;
2724
	int result, fd, real_fd;
2725
2725
2726
	START_PROFILE(syscall_fchmod);
2726
	START_PROFILE(syscall_fchmod);
2727
2727
Lines 2731-2738 Link Here
2731
		return result;
2731
		return result;
2732
	}
2732
	}
2733
2733
2734
	fd = fsp_get_pathref_fd(fsp);
2735
2734
	if (fsp->fsp_flags.have_proc_fds) {
2736
	if (fsp->fsp_flags.have_proc_fds) {
2735
		int fd = fsp_get_pathref_fd(fsp);
2736
		const char *p = NULL;
2737
		const char *p = NULL;
2737
		char buf[PATH_MAX];
2738
		char buf[PATH_MAX];
2738
2739
Lines 2746-2751 Link Here
2746
		return result;
2747
		return result;
2747
	}
2748
	}
2748
2749
2750
	if (sys_open_real_fd_from_pathref_fd(fd, &real_fd, O_RDONLY|O_NONBLOCK) == 0) {
2751
		int saved_errno;
2752
	  
2753
		result = fchmod(real_fd, mode);
2754
		saved_errno = errno;
2755
		close(real_fd);
2756
		errno = saved_errno;
2757
		END_PROFILE(syscall_fchmod);
2758
		return result;
2759
	}
2760
2749
	/*
2761
	/*
2750
	 * This is no longer a handle based call.
2762
	 * This is no longer a handle based call.
2751
	 */
2763
	 */
Lines 2758-2764 Link Here
2758
static int vfswrap_fchown(vfs_handle_struct *handle, files_struct *fsp, uid_t uid, gid_t gid)
2770
static int vfswrap_fchown(vfs_handle_struct *handle, files_struct *fsp, uid_t uid, gid_t gid)
2759
{
2771
{
2760
#ifdef HAVE_FCHOWN
2772
#ifdef HAVE_FCHOWN
2761
	int result;
2773
	int result, fd, real_fd;
2762
2774
2763
	START_PROFILE(syscall_fchown);
2775
	START_PROFILE(syscall_fchown);
2764
	if (!fsp->fsp_flags.is_pathref) {
2776
	if (!fsp->fsp_flags.is_pathref) {
Lines 2767-2774 Link Here
2767
		return result;
2779
		return result;
2768
	}
2780
	}
2769
2781
2782
	fd = fsp_get_pathref_fd(fsp);
2783
	
2770
	if (fsp->fsp_flags.have_proc_fds) {
2784
	if (fsp->fsp_flags.have_proc_fds) {
2771
		int fd = fsp_get_pathref_fd(fsp);
2772
		const char *p = NULL;
2785
		const char *p = NULL;
2773
		char buf[PATH_MAX];
2786
		char buf[PATH_MAX];
2774
2787
Lines 2782-2787 Link Here
2782
		return result;
2795
		return result;
2783
	}
2796
	}
2784
2797
2798
	if (sys_open_real_fd_from_pathref_fd(fd, &real_fd, O_RDONLY|O_NONBLOCK) == 0) {
2799
		int saved_errno;
2800
	  
2801
		result = fchown(real_fd, uid, gid);
2802
		saved_errno = errno;
2803
		close(real_fd);
2804
		errno = saved_errno;
2805
		END_PROFILE(syscall_fchown);
2806
		return result;
2807
	}
2808
2785
	/*
2809
	/*
2786
	 * This is no longer a handle based call.
2810
	 * This is no longer a handle based call.
2787
	 */
2811
	 */
Lines 2855-2861 Link Here
2855
			   files_struct *fsp,
2879
			   files_struct *fsp,
2856
			   struct smb_file_time *ft)
2880
			   struct smb_file_time *ft)
2857
{
2881
{
2858
	int result = -1;
2882
	int result = -1, fd, real_fd;
2859
	struct timespec ts[2];
2883
	struct timespec ts[2];
2860
	struct timespec *times = NULL;
2884
	struct timespec *times = NULL;
2861
2885
Lines 2900-2907 Link Here
2900
		goto out;
2924
		goto out;
2901
	}
2925
	}
2902
2926
2927
	fd = fsp_get_pathref_fd(fsp);
2928
	
2903
	if (fsp->fsp_flags.have_proc_fds) {
2929
	if (fsp->fsp_flags.have_proc_fds) {
2904
		int fd = fsp_get_pathref_fd(fsp);
2905
		const char *p = NULL;
2930
		const char *p = NULL;
2906
		char buf[PATH_MAX];
2931
		char buf[PATH_MAX];
2907
2932
Lines 2919-2924 Link Here
2919
		goto out;
2944
		goto out;
2920
	}
2945
	}
2921
2946
2947
	if (sys_open_real_fd_from_pathref_fd(fd, &real_fd, O_RDONLY|O_NONBLOCK) == 0) {
2948
		int saved_errno;
2949
	  
2950
		result = futimens(real_fd, times);
2951
		saved_errno = errno;
2952
		close(real_fd);
2953
		errno = saved_errno;
2954
		goto out;
2955
	}
2956
2922
	/*
2957
	/*
2923
	 * The fd is a pathref (opened with O_PATH) and there isn't fd to
2958
	 * The fd is a pathref (opened with O_PATH) and there isn't fd to
2924
	 * path translation mechanism. Fallback to path based call.
2959
	 * path translation mechanism. Fallback to path based call.
Lines 3322-3327 Link Here
3322
{
3357
{
3323
#ifdef HAVE_FCHFLAGS
3358
#ifdef HAVE_FCHFLAGS
3324
	int fd = fsp_get_pathref_fd(fsp);
3359
	int fd = fsp_get_pathref_fd(fsp);
3360
	int real_fd;
3325
3361
3326
	SMB_ASSERT(!fsp_is_alternate_stream(fsp));
3362
	SMB_ASSERT(!fsp_is_alternate_stream(fsp));
3327
3363
Lines 3341-3346 Link Here
3341
		return chflags(p, flags);
3377
		return chflags(p, flags);
3342
	}
3378
	}
3343
3379
3380
	if (sys_open_real_fd_from_pathref_fd(fd, &real_fd, O_RDONLY|O_NONBLOCK) == 0) {
3381
	  int saved_errno, result;
3382
	  
3383
		result = fchflags(real_fd, flags);
3384
		saved_errno = errno;
3385
		close(real_fd);
3386
		errno = saved_errno;
3387
		return result;
3388
	}
3389
3344
	/*
3390
	/*
3345
	 * This is no longer a handle based call.
3391
	 * This is no longer a handle based call.
3346
	 */
3392
	 */
Lines 3569-3574 Link Here
3569
				 size_t size)
3615
				 size_t size)
3570
{
3616
{
3571
	int fd = fsp_get_pathref_fd(fsp);
3617
	int fd = fsp_get_pathref_fd(fsp);
3618
	int real_fd;
3572
3619
3573
	SMB_ASSERT(!fsp_is_alternate_stream(fsp));
3620
	SMB_ASSERT(!fsp_is_alternate_stream(fsp));
3574
3621
Lines 3588-3593 Link Here
3588
		return getxattr(p, name, value, size);
3635
		return getxattr(p, name, value, size);
3589
	}
3636
	}
3590
3637
3638
	if (sys_open_real_fd_from_pathref_fd(fd, &real_fd, O_RDONLY|O_NONBLOCK) == 0) {
3639
		int saved_errno, result;
3640
	  
3641
		result = fgetxattr(real_fd, name, value, size);
3642
		saved_errno = errno;
3643
		close(real_fd);
3644
		errno = saved_errno;
3645
		return result;
3646
	}
3647
3591
	/*
3648
	/*
3592
	 * This is no longer a handle based call.
3649
	 * This is no longer a handle based call.
3593
	 */
3650
	 */
Lines 3895-3900 Link Here
3895
static ssize_t vfswrap_flistxattr(struct vfs_handle_struct *handle, struct files_struct *fsp, char *list, size_t size)
3952
static ssize_t vfswrap_flistxattr(struct vfs_handle_struct *handle, struct files_struct *fsp, char *list, size_t size)
3896
{
3953
{
3897
	int fd = fsp_get_pathref_fd(fsp);
3954
	int fd = fsp_get_pathref_fd(fsp);
3955
	int real_fd;
3898
3956
3899
	SMB_ASSERT(!fsp_is_alternate_stream(fsp));
3957
	SMB_ASSERT(!fsp_is_alternate_stream(fsp));
3900
3958
Lines 3914-3919 Link Here
3914
		return listxattr(p, list, size);
3972
		return listxattr(p, list, size);
3915
	}
3973
	}
3916
3974
3975
	if (sys_open_real_fd_from_pathref_fd(fd, &real_fd, O_RDONLY|O_NONBLOCK) == 0) {
3976
		int saved_errno, result;
3977
	  
3978
		result = flistxattr(real_fd, list, size);
3979
		saved_errno = errno;
3980
		close(real_fd);
3981
		errno = saved_errno;
3982
		return result;
3983
	}
3984
3917
	/*
3985
	/*
3918
	 * This is no longer a handle based call.
3986
	 * This is no longer a handle based call.
3919
	 */
3987
	 */
Lines 3923-3928 Link Here
3923
static int vfswrap_fremovexattr(struct vfs_handle_struct *handle, struct files_struct *fsp, const char *name)
3991
static int vfswrap_fremovexattr(struct vfs_handle_struct *handle, struct files_struct *fsp, const char *name)
3924
{
3992
{
3925
	int fd = fsp_get_pathref_fd(fsp);
3993
	int fd = fsp_get_pathref_fd(fsp);
3994
	int real_fd;
3926
3995
3927
	SMB_ASSERT(!fsp_is_alternate_stream(fsp));
3996
	SMB_ASSERT(!fsp_is_alternate_stream(fsp));
3928
3997
Lines 3942-3947 Link Here
3942
		return removexattr(p, name);
4011
		return removexattr(p, name);
3943
	}
4012
	}
3944
4013
4014
	if (sys_open_real_fd_from_pathref_fd(fd, &real_fd, O_RDONLY|O_NONBLOCK) == 0) {
4015
		int saved_errno, result;
4016
	  
4017
		result = fremovexattr(real_fd, name);
4018
		saved_errno = errno;
4019
		close(real_fd);
4020
		errno = saved_errno;
4021
		return result;
4022
	}
4023
3945
	/*
4024
	/*
3946
	 * This is no longer a handle based call.
4025
	 * This is no longer a handle based call.
3947
	 */
4026
	 */
Lines 3951-3956 Link Here
3951
static int vfswrap_fsetxattr(struct vfs_handle_struct *handle, struct files_struct *fsp, const char *name, const void *value, size_t size, int flags)
4030
static int vfswrap_fsetxattr(struct vfs_handle_struct *handle, struct files_struct *fsp, const char *name, const void *value, size_t size, int flags)
3952
{
4031
{
3953
	int fd = fsp_get_pathref_fd(fsp);
4032
	int fd = fsp_get_pathref_fd(fsp);
4033
	int real_fd;
3954
4034
3955
	SMB_ASSERT(!fsp_is_alternate_stream(fsp));
4035
	SMB_ASSERT(!fsp_is_alternate_stream(fsp));
3956
4036
Lines 3968-3973 Link Here
3968
		}
4048
		}
3969
4049
3970
		return setxattr(p, name, value, size, flags);
4050
		return setxattr(p, name, value, size, flags);
4051
	}
4052
4053
	if (sys_open_real_fd_from_pathref_fd(fd, &real_fd, O_RDONLY|O_NONBLOCK) == 0) {
4054
		int saved_errno, result;
4055
	  
4056
		result = fsetxattr(real_fd, name, value, size, flags);
4057
		saved_errno = errno;
4058
		close(real_fd);
4059
		errno = saved_errno;
4060
		return result;
3971
	}
4061
	}
3972
4062
3973
	/*
4063
	/*
(-)samba-4.18.3/source3/modules/vfs_zfsacl.c (-13 / +89 lines)
Lines 234-246 Link Here
234
234
235
	SMB_ASSERT(i == naces);
235
	SMB_ASSERT(i == naces);
236
236
237
	/* store acl */
237
	if (!fsp->fsp_flags.is_pathref) {
238
	fd = fsp_get_pathref_fd(fsp);
238
		rv = facl(fsp_get_io_fd(fsp), ACE_SETACL, naces, acebuf);
239
	if (fd == -1) {
239
	} else {
240
		errno = EBADF;
240
		const char *procfd_p = NULL;
241
		return false;
241
		char buf[PATH_MAX];
242
243
		fd = fsp_get_pathref_fd(fsp);
244
		if (fsp->fsp_flags.have_proc_fds && (procfd_p = sys_proc_fd_path(fd, buf, sizeof(buf)))) {
245
			rv = acl(procfd_p, ACE_SETACL, naces, acebuf);
246
		} else {
247
			int real_fd;
248
249
			fd = fsp_get_pathref_fd(fsp);
250
		
251
			/* First try this for versions of FreeBSD 13+ that allows facl() on O_PATH fd's */
252
			rv = facl(fd, ACE_SETACL, naces, acebuf);
253
		
254
			if (rv < 0 && errno == EBADF &&
255
			    sys_open_real_fd_from_pathref_fd(fd, &real_fd, O_RDONLY|O_NONBLOCK) == 0) {
256
				/* Works on FreeBSD 13+ */
257
				int saved_errno;
258
259
				rv = facl(real_fd, ACE_SETACL, naces, acebuf);
260
				saved_errno = errno;
261
				close(real_fd);
262
				errno = saved_errno;
263
			} else {
264
				/* Last ditch fallback */
265
				rv = acl(fsp->fsp_name->base_name, ACE_SETACL, naces, acebuf);
266
			}
267
		}
242
	}
268
	}
243
	rv = facl(fd, ACE_SETACL, naces, acebuf);
269
244
	if (rv != 0) {
270
	if (rv != 0) {
245
		if(errno == ENOSYS) {
271
		if(errno == ENOSYS) {
246
			DEBUG(9, ("acl(ACE_SETACL, %s): Operation is not "
272
			DEBUG(9, ("acl(ACE_SETACL, %s): Operation is not "
Lines 284-297 Link Here
284
{
310
{
285
	int naces, rv;
311
	int naces, rv;
286
	ace_t *acebuf = NULL;
312
	ace_t *acebuf = NULL;
287
	int fd;
313
	int fd = -1;
314
	const char *procfd_p = NULL;
315
	char buf[PATH_MAX];
288
316
289
	fd = fsp_get_pathref_fd(fsp);
317
	if (!fsp->fsp_flags.is_pathref) {
290
	if (fd == -1) {
318
		naces = facl(fsp_get_io_fd(fsp), ACE_GETACLCNT, 0, NULL);
291
		errno = EBADF;
319
	} else {
292
		return -1;
320
	  	fd = fsp_get_pathref_fd(fsp);
321
		
322
		if (fsp->fsp_flags.have_proc_fds && (procfd_p = sys_proc_fd_path(fd, buf, sizeof(buf)))) {
323
			/* If we have procfd support, try this first */
324
			naces = acl(procfd_p, ACE_GETACLCNT, 0, NULL);
325
		} else {
326
			int real_fd;
327
328
			/* First try this for versions of FreeBSD 13+ that allows facl() on O_PATH fd's */
329
			naces = facl(fd, ACE_GETACLCNT, 0, NULL);
330
			if (naces < 0 && errno == EBADF &&
331
			    sys_open_real_fd_from_pathref_fd(fd, &real_fd, O_RDONLY|O_NONBLOCK) == 0) {
332
				/* Works on FreeBSD 13+ */
333
				int saved_errno;
334
335
				naces = facl(real_fd, ACE_GETACLCNT, 0, NULL);
336
				saved_errno = errno;
337
				close(real_fd);
338
				errno = saved_errno;
339
			} else {
340
				/* Last ditch fallback */
341
				naces = acl(fsp->fsp_name->base_name, ACE_GETACLCNT, 0, NULL);
342
			}
343
		}
293
	}
344
	}
294
	naces = facl(fd, ACE_GETACLCNT, 0, NULL);
345
295
	if (naces == -1) {
346
	if (naces == -1) {
296
		int dbg_level = 10;
347
		int dbg_level = 10;
297
348
Lines 309-315 Link Here
309
		return -1;
360
		return -1;
310
	}
361
	}
311
362
312
	rv = facl(fd, ACE_GETACL, naces, acebuf);
363
	if (!fsp->fsp_flags.is_pathref) {
364
		rv = facl(fsp_get_io_fd(fsp), ACE_GETACL, naces, acebuf);
365
	} else {
366
		if (procfd_p) {
367
			rv = acl(procfd_p, ACE_GETACL, naces, acebuf);
368
		} else {
369
			int real_fd;
370
371
			/* First try this for versions of FreeBSD that allows facl() on O_PATH fd's */
372
			rv = facl(fd, ACE_GETACL, naces, acebuf);
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_GETACL, 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_GETACL, naces, acebuf);
385
			}
386
		}
387
	}
388
313
	if (rv == -1) {
389
	if (rv == -1) {
314
		DBG_DEBUG("acl(ACE_GETACL, %s): %s ",
390
		DBG_DEBUG("acl(ACE_GETACL, %s): %s ",
315
			  fsp_str_dbg(fsp), strerror(errno));
391
			  fsp_str_dbg(fsp), strerror(errno));
(-)samba-4.18.3/source3/include/proto.h (+4 lines)
Lines 211-216 Link Here
211
bool sys_have_proc_fds(void);
211
bool sys_have_proc_fds(void);
212
const char *sys_proc_fd_path(int fd, char *buf, size_t bufsize);
212
const char *sys_proc_fd_path(int fd, char *buf, size_t bufsize);
213
213
214
int sys_open_real_fd_from_pathref_fd(int fd,
215
				     int *mfd,
216
				     int flags);
217
214
struct stat;
218
struct stat;
215
void init_stat_ex_from_stat (struct stat_ex *dst,
219
void init_stat_ex_from_stat (struct stat_ex *dst,
216
			    const struct stat *src,
220
			    const struct stat *src,

Return to bug 277878