From: Tim Prouty Date: Fri, 26 Jun 2009 01:19:09 +0000 (-0700) Subject: s3 file_access: Convert some more functions over to use smb_filneame X-Git-Tag: tevent-0.9.8~928 X-Git-Url: http://git.samba.org/samba.git/?p=ira%2Fwip.git;a=commitdiff_plain;h=eb8c658fcdda5d1337605ed5e2e8da15bc51ba20;ds=sidebyside s3 file_access: Convert some more functions over to use smb_filneame --- diff --git a/source3/include/proto.h b/source3/include/proto.h index f685152de86..731934d7149 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -6268,7 +6268,8 @@ bool can_delete_file_in_directory(connection_struct *conn, bool can_access_file_data(connection_struct *conn, const struct smb_filename *smb_fname, uint32 access_mask); -bool can_write_to_file(connection_struct *conn, const char *fname, const SMB_STRUCT_STAT *psbuf); +bool can_write_to_file(connection_struct *conn, + const struct smb_filename *smb_fname); bool directory_has_default_acl(connection_struct *conn, const char *fname); /* The following definitions come from smbd/fileio.c */ diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index aff30a6967c..723fb6fd6f2 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -1007,7 +1007,8 @@ static bool user_can_read_file(connection_struct *conn, use it for anything security sensitive. ********************************************************************/ -static bool user_can_write_file(connection_struct *conn, char *name, SMB_STRUCT_STAT *pst) +static bool user_can_write_file(connection_struct *conn, + const struct smb_filename *smb_fname) { /* * If user is a member of the Admin group @@ -1018,22 +1019,23 @@ static bool user_can_write_file(connection_struct *conn, char *name, SMB_STRUCT_ return True; } - SMB_ASSERT(VALID_STAT(*pst)); + SMB_ASSERT(VALID_STAT(smb_fname->st)); /* Pseudo-open the file */ - if(S_ISDIR(pst->st_ex_mode)) { + if(S_ISDIR(smb_fname->st.st_ex_mode)) { return True; } - return can_write_to_file(conn, name, pst); + return can_write_to_file(conn, smb_fname); } /******************************************************************* Is a file a "special" type ? ********************************************************************/ -static bool file_is_special(connection_struct *conn, char *name, SMB_STRUCT_STAT *pst) +static bool file_is_special(connection_struct *conn, + const struct smb_filename *smb_fname) { /* * If user is a member of the Admin group @@ -1043,9 +1045,11 @@ static bool file_is_special(connection_struct *conn, char *name, SMB_STRUCT_STAT if (conn->admin_user) return False; - SMB_ASSERT(VALID_STAT(*pst)); + SMB_ASSERT(VALID_STAT(smb_fname->st)); - if (S_ISREG(pst->st_ex_mode) || S_ISDIR(pst->st_ex_mode) || S_ISLNK(pst->st_ex_mode)) + if (S_ISREG(smb_fname->st.st_ex_mode) || + S_ISDIR(smb_fname->st.st_ex_mode) || + S_ISLNK(smb_fname->st.st_ex_mode)) return False; return True; @@ -1094,7 +1098,7 @@ bool is_visible_file(connection_struct *conn, const char *dir_path, /* Create an smb_filename with stream_name == NULL. */ status = create_synthetic_smb_fname(talloc_tos(), entry, NULL, - NULL, &smb_fname_base); + pst, &smb_fname_base); if (!NT_STATUS_IS_OK(status)) { ret = false; goto out; @@ -1104,15 +1108,15 @@ bool is_visible_file(connection_struct *conn, const char *dir_path, * the configuration options. We succeed, on the basis that the * checks *might* have passed if the file was present. */ - if (!VALID_STAT(*pst) && - (SMB_VFS_STAT(conn, smb_fname_base) != 0)) - { - ret = true; - goto out; + if (!VALID_STAT(*pst)) { + if (SMB_VFS_STAT(conn, smb_fname_base) != 0) { + ret = true; + goto out; + } else { + *pst = smb_fname_base->st; + } } - *pst = smb_fname_base->st; - /* Honour _hide unreadable_ option */ if (hide_unreadable && !user_can_read_file(conn, smb_fname_base)) { @@ -1122,14 +1126,15 @@ bool is_visible_file(connection_struct *conn, const char *dir_path, goto out; } /* Honour _hide unwriteable_ option */ - if (hide_unwriteable && !user_can_write_file(conn, entry, pst)) { + if (hide_unwriteable && !user_can_write_file(conn, + smb_fname_base)) { DEBUG(10,("is_visible_file: file %s is unwritable.\n", entry )); ret = false; goto out; } /* Honour _hide_special_ option */ - if (hide_special && file_is_special(conn, entry, pst)) { + if (hide_special && file_is_special(conn, smb_fname_base)) { DEBUG(10,("is_visible_file: file %s is special.\n", entry )); ret = false; diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index afebb9efd0e..26d3320a4c5 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -151,10 +151,18 @@ static uint32 dos_mode_from_sbuf(connection_struct *conn, const char *path, cons result |= aRONLY; } } else if (ro_opts == MAP_READONLY_PERMISSIONS) { - /* Check actual permissions for read-only. */ - if (!can_write_to_file(conn, path, sbuf)) { - result |= aRONLY; + struct smb_filename *smb_fname = NULL; + NTSTATUS status; + + status = create_synthetic_smb_fname_split(talloc_tos(), path, + sbuf, &smb_fname); + if (NT_STATUS_IS_OK(status)) { + /* Check actual permissions for read-only. */ + if (!can_write_to_file(conn, smb_fname)) { + result |= aRONLY; + } } + TALLOC_FREE(smb_fname); } /* Else never set the readonly bit. */ if (MAP_ARCHIVE(conn) && ((sbuf->st_ex_mode & S_IXUSR) != 0)) @@ -712,11 +720,11 @@ int file_set_dosmode(connection_struct *conn, const char *fname, int file_ntimes(connection_struct *conn, const char *fname, struct smb_file_time *ft) { - SMB_STRUCT_STAT sbuf; + struct smb_filename *smb_fname = NULL; + NTSTATUS status; int ret = -1; errno = 0; - ZERO_STRUCT(sbuf); DEBUG(6, ("file_ntime: actime: %s", time_to_asc(convert_timespec_to_time_t(ft->atime)))); @@ -754,13 +762,21 @@ int file_ntimes(connection_struct *conn, const char *fname, (as DOS does). */ + status = create_synthetic_smb_fname_split(talloc_tos(), fname, NULL, + &smb_fname); + + if (!NT_STATUS_IS_OK(status)) { + return -1; + } + /* Check if we have write access. */ - if (can_write_to_file(conn, fname, &sbuf)) { + if (can_write_to_file(conn, smb_fname)) { /* We are allowed to become root and change the filetime. */ become_root(); ret = SMB_VFS_NTIMES(conn, fname, ft); unbecome_root(); } + TALLOC_FREE(smb_fname); return ret; } diff --git a/source3/smbd/file_access.c b/source3/smbd/file_access.c index 87d45c5e7f6..d8fee1db06f 100644 --- a/source3/smbd/file_access.c +++ b/source3/smbd/file_access.c @@ -232,23 +232,10 @@ bool can_access_file_data(connection_struct *conn, Note this doesn't take into account share write permissions. ****************************************************************************/ -bool can_write_to_file(connection_struct *conn, const char *fname, const SMB_STRUCT_STAT *psbuf) +bool can_write_to_file(connection_struct *conn, + const struct smb_filename *smb_fname) { - struct smb_filename *smb_fname; - NTSTATUS status; - bool ret; - - status = create_synthetic_smb_fname_split(talloc_tos(), fname, psbuf, - &smb_fname); - if (!NT_STATUS_IS_OK(status)) { - return false; - } - - ret = can_access_file_data(conn, smb_fname, FILE_WRITE_DATA); - - TALLOC_FREE(smb_fname); - - return ret; + return can_access_file_data(conn, smb_fname, FILE_WRITE_DATA); } /**************************************************************************** diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c index 560b844a56c..04767bf5590 100644 --- a/source3/smbd/nttrans.c +++ b/source3/smbd/nttrans.c @@ -673,7 +673,7 @@ void reply_ntcreate_and_X(struct smb_request *req) uint32 perms = 0; p += 25; if (fsp->is_directory || - can_write_to_file(conn, fsp->fsp_name, &smb_fname->st)) { + can_write_to_file(conn, smb_fname)) { perms = FILE_GENERIC_ALL; } else { perms = FILE_GENERIC_READ|FILE_EXECUTE; @@ -1155,7 +1155,7 @@ static void call_nt_transact_create(connection_struct *conn, uint32 perms = 0; p += 25; if (fsp->is_directory || - can_write_to_file(conn, fsp->fsp_name, &smb_fname->st)) { + can_write_to_file(conn, smb_fname)) { perms = FILE_GENERIC_ALL; } else { perms = FILE_GENERIC_READ|FILE_EXECUTE; diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c index 437112c751d..627ca2e171f 100644 --- a/source3/smbd/posix_acls.c +++ b/source3/smbd/posix_acls.c @@ -2550,6 +2550,9 @@ static bool acl_group_override(connection_struct *conn, const SMB_STRUCT_STAT *psbuf, const char *fname) { + struct smb_filename *smb_fname = NULL; + NTSTATUS status; + if ((errno != EPERM) && (errno != EACCES)) { return false; } @@ -2560,11 +2563,20 @@ static bool acl_group_override(connection_struct *conn, return true; } + status = create_synthetic_smb_fname_split(talloc_tos(), fname, psbuf, + &smb_fname); + + if (!NT_STATUS_IS_OK(status)) { + return false; + } + /* user has writeable permission */ if (lp_dos_filemode(SNUM(conn)) && - can_write_to_file(conn, fname, psbuf)) { + can_write_to_file(conn, smb_fname)) { + TALLOC_FREE(smb_fname); return true; } + TALLOC_FREE(smb_fname); return false; }