View | Details | Raw Unified | Return to bug 54016
Collapse All | Expand All

(-)source3/smbd/open.c.orig (-3 / +49 lines)
 Lines 3857-3862   static NTSTATUS mkdir_internal(connectio Link Here 
3857
	bool posix_open = false;
3857
	bool posix_open = false;
3858
	bool need_re_stat = false;
3858
	bool need_re_stat = false;
3859
	uint32_t access_mask = SEC_DIR_ADD_SUBDIR;
3859
	uint32_t access_mask = SEC_DIR_ADD_SUBDIR;
3860
	bool ok;
3861
	struct smb_filename *oldwd_fname = NULL;
3862
	struct smb_filename *smb_fname_rel = NULL;
3860
3863
3861
	if (!CAN_WRITE(conn) || (access_mask & ~(conn->share_access))) {
3864
	if (!CAN_WRITE(conn) || (access_mask & ~(conn->share_access))) {
3862
		DEBUG(5,("mkdir_internal: failing share access "
3865
		DEBUG(5,("mkdir_internal: failing share access "
 Lines 3864-3871   static NTSTATUS mkdir_internal(connectio Link Here 
3864
		return NT_STATUS_ACCESS_DENIED;
3867
		return NT_STATUS_ACCESS_DENIED;
3865
	}
3868
	}
3866
3869
3870
	ok = parent_smb_fname(talloc_tos(),
3871
			      smb_dname,
3872
			      &parent_dir,
3873
			      &smb_fname_rel);
3874
	if (!ok) {
3875
		return NT_STATUS_NO_MEMORY;
3876
	}
3877
3867
	if (!parent_dirname(talloc_tos(), smb_dname->base_name, &parent_dir,
3878
	if (!parent_dirname(talloc_tos(), smb_dname->base_name, &parent_dir,
3868
			    NULL)) {
3879
			    &smb_fname_rel)) {
3869
		return NT_STATUS_NO_MEMORY;
3880
		return NT_STATUS_NO_MEMORY;
3870
	}
3881
	}
3871
3882
 Lines 3888-3897   static NTSTATUS mkdir_internal(connectio Link Here 
3888
		return status;
3899
		return status;
3889
	}
3900
	}
3890
3901
3891
	if (SMB_VFS_MKDIR(conn, smb_dname, mode) != 0) {
3902
	oldwd_fname = vfs_GetWd(talloc_tos(), conn);
3892
		return map_nt_error_from_unix(errno);
3903
	if (oldwd_fname == NULL) {
3904
		return NT_STATUS_NO_MEMORY;
3893
	}
3905
	}
3894
3906
3907
	/* Pin parent directory in place. */
3908
	if (vfs_ChDir(conn, parent_dir_fname) == -1) {
3909
		status = map_nt_error_from_unix(errno);
3910
		TALLOC_FREE(oldwd_fname);
3911
		return status;
3912
	}
3913
3914
	/* Ensure the relative path is below the share. */
3915
	status = check_reduced_name(conn, parent_dir_fname, smb_fname_rel);
3916
	if (!NT_STATUS_IS_OK(status)) {
3917
		goto need_chdir_err;
3918
	}
3919
3920
	if (SMB_VFS_MKDIR(conn, smb_fname_rel, mode) != 0) {
3921
		status = map_nt_error_from_unix(errno);
3922
		goto need_chdir_err;
3923
	}
3924
3925
	/* Return to share $cwd. */
3926
	ret = vfs_ChDir(conn, oldwd_fname);
3927
	if (ret == -1) {
3928
		smb_panic("unable to get back to old directory\n");
3929
	}
3930
	TALLOC_FREE(oldwd_fname);
3931
3895
	/* Ensure we're checking for a symlink here.... */
3932
	/* Ensure we're checking for a symlink here.... */
3896
	/* We don't want to get caught by a symlink racer. */
3933
	/* We don't want to get caught by a symlink racer. */
3897
3934
 Lines 3957-3962   static NTSTATUS mkdir_internal(connectio Link Here 
3957
		     smb_dname->base_name);
3994
		     smb_dname->base_name);
3958
3995
3959
	return NT_STATUS_OK;
3996
	return NT_STATUS_OK;
3997
3998
  need_chdir_err:
3999
4000
	ret = vfs_ChDir(conn, oldwd_fname);
4001
	if (ret == -1) {
4002
		smb_panic("unable to get back to old directory\n");
4003
	}
4004
	TALLOC_FREE(oldwd_fname);
4005
	return status;
3960
}
4006
}
3961
4007
3962
/****************************************************************************
4008
/****************************************************************************
(-)source3/lib/filename_util.c.orig (+63 lines)
 Lines 239-244   struct smb_filename *cp_smb_filename(TAL Link Here 
239
	return out;
239
	return out;
240
}
240
}
241
241
242
/**
243
 * Return allocated parent directory and basename of path
244
 *
245
 * Note: if requesting name, it is returned as talloc child of the
246
 * parent. Freeing the parent is thus sufficient to free both.
247
 */
248
bool parent_smb_fname(TALLOC_CTX *mem_ctx,
249
		      const struct smb_filename *path,
250
		      struct smb_filename **_parent,
251
		      struct smb_filename  **_name)
252
{
253
	TALLOC_CTX *frame = talloc_stackframe();
254
	struct smb_filename *parent = NULL;
255
	struct smb_filename *name = NULL;
256
	char *p = NULL;
257
258
	parent = cp_smb_filename(frame, path);
259
	if (parent == NULL) {
260
		TALLOC_FREE(frame);
261
		return false;
262
	}
263
	TALLOC_FREE(parent->stream_name);
264
	SET_STAT_INVALID(parent->st);
265
266
	p = strrchr_m(parent->base_name, '/'); /* Find final '/', if any */
267
	if (p == NULL) {
268
		TALLOC_FREE(parent->base_name);
269
		parent->base_name = talloc_strdup(parent, ".");
270
		if (parent->base_name == NULL) {
271
			TALLOC_FREE(frame);
272
			return false;
273
		}
274
		p = path->base_name;
275
	} else {
276
		*p = '\0';
277
		p++;
278
	}
279
280
	if (_name == NULL) {
281
		*_parent = talloc_move(mem_ctx, &parent);
282
		TALLOC_FREE(frame);
283
		return true;
284
	}
285
286
	name = cp_smb_filename(frame, path);
287
	if (name == NULL) {
288
		TALLOC_FREE(frame);
289
		return false;
290
	}
291
	TALLOC_FREE(name->base_name);
292
293
	name->base_name = talloc_strdup(name, p);
294
	if (name == NULL) {
295
		TALLOC_FREE(frame);
296
		return false;
297
	}
298
299
	*_parent = talloc_move(mem_ctx, &parent);
300
	*_name = talloc_move(*_parent, &name);
301
	TALLOC_FREE(frame);
302
	return true;
303
}
304
242
/****************************************************************************
305
/****************************************************************************
243
 Simple check to determine if the filename is a stream.
306
 Simple check to determine if the filename is a stream.
244
 ***************************************************************************/
307
 ***************************************************************************/

Return to bug 54016