From b5a05a70392beec96bb2ad0aae695fb20bd92137 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 8 Oct 2009 15:55:35 -0700 Subject: [PATCH] Fix bug 6769 - symlink unlink does nothing. Jeremy. --- source/modules/vfs_default.c | 6 +++- source/smbd/posix_acls.c | 57 +++++++++++++++++++++++++++++++----------- source/smbd/reply.c | 49 ++++++++++++++++++++++++++++-------- 3 files changed, 85 insertions(+), 27 deletions(-) diff --git a/source/modules/vfs_default.c b/source/modules/vfs_default.c index 1e95633..d8ef888 100644 --- a/source/modules/vfs_default.c +++ b/source/modules/vfs_default.c @@ -993,7 +993,11 @@ static NTSTATUS vfswrap_streaminfo(vfs_handle_struct *handle, ret = SMB_VFS_FSTAT(fsp, &sbuf); } else { - ret = SMB_VFS_STAT(handle->conn, fname, &sbuf); + if (lp_posix_pathnames()) { + ret = SMB_VFS_LSTAT(handle->conn, fname, &sbuf); + } else { + ret = SMB_VFS_STAT(handle->conn, fname, &sbuf); + } } if (ret == -1) { diff --git a/source/smbd/posix_acls.c b/source/smbd/posix_acls.c index 1afd48e..c8d9e00 100644 --- a/source/smbd/posix_acls.c +++ b/source/smbd/posix_acls.c @@ -3178,13 +3178,19 @@ NTSTATUS posix_get_nt_acl(struct connection_struct *conn, const char *name, SMB_ACL_T posix_acl = NULL; SMB_ACL_T def_acl = NULL; struct pai_val *pal; + int ret; *ppdesc = NULL; DEBUG(10,("posix_get_nt_acl: called for file %s\n", name )); /* Get the stat struct for the owner info. */ - if(SMB_VFS_STAT(conn, name, &sbuf) != 0) { + if (lp_posix_pathnames()) { + ret = SMB_VFS_LSTAT(conn, name, &sbuf); + } else { + ret = SMB_VFS_STAT(conn, name, &sbuf); + } + if(ret != 0) { return map_nt_error_from_unix(errno); } @@ -3218,6 +3224,7 @@ int try_chown(connection_struct *conn, const char *fname, uid_t uid, gid_t gid) int ret; files_struct *fsp; SMB_STRUCT_STAT st; + bool posix_paths = lp_posix_pathnames(); if(!CAN_WRITE(conn)) { return -1; @@ -3225,7 +3232,11 @@ int try_chown(connection_struct *conn, const char *fname, uid_t uid, gid_t gid) /* Case (1). */ /* try the direct way first */ - ret = SMB_VFS_CHOWN(conn, fname, uid, gid); + if (posix_paths) { + ret = SMB_VFS_LCHOWN(conn, fname, uid, gid); + } else { + ret = SMB_VFS_CHOWN(conn, fname, uid, gid); + } if (ret == 0) return 0; @@ -3265,7 +3276,12 @@ int try_chown(connection_struct *conn, const char *fname, uid_t uid, gid_t gid) return -1; } - if (SMB_VFS_STAT(conn,fname,&st)) { + if (posix_paths) { + ret = SMB_VFS_LSTAT(conn,fname,&st); + } else { + ret = SMB_VFS_STAT(conn,fname,&st); + } + if (ret != 0) { return -1; } @@ -3497,6 +3513,8 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC bool set_acl_as_root = false; bool acl_set_support = false; bool ret = false; + bool posix_paths = lp_posix_pathnames(); + int sret; DEBUG(10,("set_nt_acl: called for file %s\n", fsp->fsp_name )); @@ -3510,8 +3528,14 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC */ if(fsp->is_directory || fsp->fh->fd == -1) { - if(SMB_VFS_STAT(fsp->conn,fsp->fsp_name, &sbuf) != 0) + if (posix_paths) { + sret = SMB_VFS_LSTAT(fsp->conn,fsp->fsp_name, &sbuf); + } else { + sret = SMB_VFS_STAT(fsp->conn,fsp->fsp_name, &sbuf); + } + if (sret != 0) { return map_nt_error_from_unix(errno); + } } else { if(SMB_VFS_FSTAT(fsp, &sbuf) != 0) return map_nt_error_from_unix(errno); @@ -3555,17 +3579,24 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC */ if(fsp->is_directory) { - if(SMB_VFS_STAT(fsp->conn, fsp->fsp_name, &sbuf) != 0) { + if (posix_paths) { + sret = SMB_VFS_LSTAT(fsp->conn, fsp->fsp_name, &sbuf); + } else { + sret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name, &sbuf); + } + if (sret != 0) { return map_nt_error_from_unix(errno); } } else { - - int sret; - - if(fsp->fh->fd == -1) - sret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name, &sbuf); - else + if(fsp->fh->fd == -1) { + if (posix_paths) { + sret = SMB_VFS_LSTAT(fsp->conn, fsp->fsp_name, &sbuf); + } else { + sret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name, &sbuf); + } + } else { sret = SMB_VFS_FSTAT(fsp, &sbuf); + } if(sret != 0) return map_nt_error_from_unix(errno); @@ -3644,8 +3675,6 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC return map_nt_error_from_unix(errno); } } else { - int sret = -1; - /* * No default ACL - delete one if it exists. */ @@ -3705,8 +3734,6 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC } if (orig_mode != posix_perms) { - int sret = -1; - DEBUG(3,("set_nt_acl: chmod %s. perms = 0%o.\n", fsp->fsp_name, (unsigned int)posix_perms )); diff --git a/source/smbd/reply.c b/source/smbd/reply.c index 46653cd..8c20e95 100644 --- a/source/smbd/reply.c +++ b/source/smbd/reply.c @@ -957,10 +957,19 @@ void reply_checkpath(struct smb_request *req) goto path_err; } - if (!VALID_STAT(sbuf) && (SMB_VFS_STAT(conn,name,&sbuf) != 0)) { - DEBUG(3,("reply_checkpath: stat of %s failed (%s)\n",name,strerror(errno))); - status = map_nt_error_from_unix(errno); - goto path_err; + if (!VALID_STAT(sbuf)) { + int ret; + + if (lp_posix_pathnames()) { + ret = SMB_VFS_LSTAT(conn,name,&sbuf); + } else { + ret = SMB_VFS_STAT(conn,name,&sbuf); + } + if (ret != 0) { + DEBUG(3,("reply_checkpath: stat of %s failed (%s)\n",name,strerror(errno))); + status = map_nt_error_from_unix(errno); + goto path_err; + } } if (!S_ISDIR(sbuf.st_mode)) { @@ -1067,11 +1076,20 @@ void reply_getatr(struct smb_request *req) END_PROFILE(SMBgetatr); return; } - if (!VALID_STAT(sbuf) && (SMB_VFS_STAT(conn,fname,&sbuf) != 0)) { - DEBUG(3,("reply_getatr: stat of %s failed (%s)\n",fname,strerror(errno))); - reply_unixerror(req, ERRDOS,ERRbadfile); - END_PROFILE(SMBgetatr); - return; + if (!VALID_STAT(sbuf)) { + int ret; + + if (lp_posix_pathnames()) { + ret = SMB_VFS_LSTAT(conn,fname,&sbuf); + } else { + ret = SMB_VFS_STAT(conn,fname,&sbuf); + } + if (ret != 0) { + DEBUG(3,("reply_getatr: stat of %s failed (%s)\n",fname,strerror(errno))); + reply_unixerror(req, ERRDOS,ERRbadfile); + END_PROFILE(SMBgetatr); + return; + } } mode = dos_mode(conn,fname,&sbuf); @@ -2301,6 +2319,8 @@ static NTSTATUS do_unlink(connection_struct *conn, uint32 fattr; files_struct *fsp; uint32 dirtype_orig = dirtype; + bool posix_paths = lp_posix_pathnames(); + int ret; NTSTATUS status; DEBUG(10,("do_unlink: %s, dirtype = %d\n", fname, dirtype )); @@ -2309,7 +2329,12 @@ static NTSTATUS do_unlink(connection_struct *conn, return NT_STATUS_MEDIA_WRITE_PROTECTED; } - if (SMB_VFS_LSTAT(conn,fname,&sbuf) != 0) { + if (posix_paths) { + ret = SMB_VFS_LSTAT(conn,fname,&sbuf); + } else { + ret = SMB_VFS_STAT(conn,fname,&sbuf); + } + if (ret != 0) { return map_nt_error_from_unix(errno); } @@ -2395,7 +2420,9 @@ static NTSTATUS do_unlink(connection_struct *conn, FILE_SHARE_NONE, /* share_access */ FILE_OPEN, /* create_disposition*/ FILE_NON_DIRECTORY_FILE, /* create_options */ - FILE_ATTRIBUTE_NORMAL, /* file_attributes */ + /* file_attributes */ + posix_paths ? FILE_FLAG_POSIX_SEMANTICS|0777 : + FILE_ATTRIBUTE_NORMAL, 0, /* oplock_request */ 0, /* allocation_size */ NULL, /* sd */ -- 1.5.4.3