mirror of
https://github.com/samba-team/samba.git
synced 2025-03-26 18:50:30 +03:00
r20356: Consolidate the calls to parent_dirname() per open to one.
This involved passing the dirname as argument to a few routines instead of calling parent_dirname() deep down. Volker (This used to be commit 7977fd78652897bb7d4db1c21c5749043428f911)
This commit is contained in:
parent
9f2807fc93
commit
8cd9636458
@ -59,7 +59,7 @@ static uint32 set_offline_flag(connection_struct *conn, const char *const path)
|
||||
/****************************************************************************
|
||||
Change a dos mode to a unix mode.
|
||||
Base permission for files:
|
||||
if creating file and inheriting
|
||||
if creating file and inheriting (i.e. parent_dir != NULL)
|
||||
apply read/write bits from parent directory.
|
||||
else
|
||||
everybody gets read bit set
|
||||
@ -79,23 +79,26 @@ static uint32 set_offline_flag(connection_struct *conn, const char *const path)
|
||||
}
|
||||
****************************************************************************/
|
||||
|
||||
mode_t unix_mode(connection_struct *conn, int dosmode, const char *fname, BOOL creating_file)
|
||||
mode_t unix_mode(connection_struct *conn, int dosmode, const char *fname,
|
||||
const char *inherit_from_dir)
|
||||
{
|
||||
mode_t result = (S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR | S_IWGRP | S_IWOTH);
|
||||
mode_t dir_mode = 0; /* Mode of the parent directory if inheriting. */
|
||||
mode_t dir_mode = 0; /* Mode of the inherit_from directory if
|
||||
* inheriting. */
|
||||
|
||||
if (!lp_store_dos_attributes(SNUM(conn)) && IS_DOS_READONLY(dosmode)) {
|
||||
result &= ~(S_IWUSR | S_IWGRP | S_IWOTH);
|
||||
}
|
||||
|
||||
if (fname && creating_file && lp_inherit_perms(SNUM(conn))) {
|
||||
char *dname;
|
||||
if (fname && (inherit_from_dir != NULL)
|
||||
&& lp_inherit_perms(SNUM(conn))) {
|
||||
SMB_STRUCT_STAT sbuf;
|
||||
|
||||
dname = parent_dirname(fname);
|
||||
DEBUG(2,("unix_mode(%s) inheriting from %s\n",fname,dname));
|
||||
if (SMB_VFS_STAT(conn,dname,&sbuf) != 0) {
|
||||
DEBUG(4,("unix_mode(%s) failed, [dir %s]: %s\n",fname,dname,strerror(errno)));
|
||||
DEBUG(2, ("unix_mode(%s) inheriting from %s\n", fname,
|
||||
inherit_from_dir));
|
||||
if (SMB_VFS_STAT(conn, inherit_from_dir, &sbuf) != 0) {
|
||||
DEBUG(4,("unix_mode(%s) failed, [dir %s]: %s\n", fname,
|
||||
inherit_from_dir, strerror(errno)));
|
||||
return(0); /* *** shouldn't happen! *** */
|
||||
}
|
||||
|
||||
@ -429,7 +432,9 @@ uint32 dos_mode(connection_struct *conn, const char *path,SMB_STRUCT_STAT *sbuf)
|
||||
chmod a file - but preserve some bits.
|
||||
********************************************************************/
|
||||
|
||||
int file_set_dosmode(connection_struct *conn, const char *fname, uint32 dosmode, SMB_STRUCT_STAT *st, BOOL creating_file)
|
||||
int file_set_dosmode(connection_struct *conn, const char *fname,
|
||||
uint32 dosmode, SMB_STRUCT_STAT *st,
|
||||
const char *parent_dir)
|
||||
{
|
||||
SMB_STRUCT_STAT st1;
|
||||
int mask=0;
|
||||
@ -462,7 +467,7 @@ int file_set_dosmode(connection_struct *conn, const char *fname, uint32 dosmode,
|
||||
return 0;
|
||||
}
|
||||
|
||||
unixmode = unix_mode(conn,dosmode,fname, creating_file);
|
||||
unixmode = unix_mode(conn,dosmode,fname, parent_dir);
|
||||
|
||||
/* preserve the s bits */
|
||||
mask |= (S_ISUID | S_ISGID);
|
||||
|
@ -1697,7 +1697,8 @@ static NTSTATUS copy_internals(connection_struct *conn, char *oldname, char *new
|
||||
/* Grrr. We have to do this as open_file_ntcreate adds aARCH when it
|
||||
creates the file. This isn't the correct thing to do in the copy
|
||||
case. JRA */
|
||||
file_set_dosmode(conn, newname, fattr, &sbuf2, True);
|
||||
file_set_dosmode(conn, newname, fattr, &sbuf2,
|
||||
parent_dirname(newname));
|
||||
|
||||
if (ret < (SMB_OFF_T)sbuf1.st_size) {
|
||||
return NT_STATUS_DISK_FULL;
|
||||
|
@ -84,18 +84,18 @@ int fd_close(struct connection_struct *conn,
|
||||
Do this by fd if possible.
|
||||
****************************************************************************/
|
||||
|
||||
static void change_fd_owner_to_parent(connection_struct *conn,
|
||||
files_struct *fsp)
|
||||
static void change_file_owner_to_parent(connection_struct *conn,
|
||||
const char *inherit_from_dir,
|
||||
files_struct *fsp)
|
||||
{
|
||||
const char *parent_path = parent_dirname(fsp->fsp_name);
|
||||
SMB_STRUCT_STAT parent_st;
|
||||
int ret;
|
||||
|
||||
ret = SMB_VFS_STAT(conn, parent_path, &parent_st);
|
||||
ret = SMB_VFS_STAT(conn, inherit_from_dir, &parent_st);
|
||||
if (ret == -1) {
|
||||
DEBUG(0,("change_fd_owner_to_parent: failed to stat parent "
|
||||
DEBUG(0,("change_file_owner_to_parent: failed to stat parent "
|
||||
"directory %s. Error was %s\n",
|
||||
parent_path, strerror(errno) ));
|
||||
inherit_from_dir, strerror(errno) ));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -103,33 +103,33 @@ static void change_fd_owner_to_parent(connection_struct *conn,
|
||||
ret = SMB_VFS_FCHOWN(fsp, fsp->fh->fd, parent_st.st_uid, (gid_t)-1);
|
||||
unbecome_root();
|
||||
if (ret == -1) {
|
||||
DEBUG(0,("change_fd_owner_to_parent: failed to fchown "
|
||||
DEBUG(0,("change_file_owner_to_parent: failed to fchown "
|
||||
"file %s to parent directory uid %u. Error "
|
||||
"was %s\n", fsp->fsp_name,
|
||||
(unsigned int)parent_st.st_uid,
|
||||
strerror(errno) ));
|
||||
}
|
||||
|
||||
DEBUG(10,("change_fd_owner_to_parent: changed new file %s to "
|
||||
DEBUG(10,("change_file_owner_to_parent: changed new file %s to "
|
||||
"parent directory uid %u.\n", fsp->fsp_name,
|
||||
(unsigned int)parent_st.st_uid ));
|
||||
}
|
||||
|
||||
static void change_owner_to_parent(connection_struct *conn,
|
||||
const char *fname,
|
||||
SMB_STRUCT_STAT *psbuf)
|
||||
static void change_dir_owner_to_parent(connection_struct *conn,
|
||||
const char *inherit_from_dir,
|
||||
const char *fname,
|
||||
SMB_STRUCT_STAT *psbuf)
|
||||
{
|
||||
pstring saved_dir;
|
||||
SMB_STRUCT_STAT sbuf;
|
||||
const char *parent_path = parent_dirname(fname);
|
||||
SMB_STRUCT_STAT parent_st;
|
||||
int ret;
|
||||
|
||||
ret = SMB_VFS_STAT(conn, parent_path, &parent_st);
|
||||
ret = SMB_VFS_STAT(conn, inherit_from_dir, &parent_st);
|
||||
if (ret == -1) {
|
||||
DEBUG(0,("change_owner_to_parent: failed to stat parent "
|
||||
DEBUG(0,("change_dir_owner_to_parent: failed to stat parent "
|
||||
"directory %s. Error was %s\n",
|
||||
parent_path, strerror(errno) ));
|
||||
inherit_from_dir, strerror(errno) ));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -141,21 +141,21 @@ static void change_owner_to_parent(connection_struct *conn,
|
||||
*/
|
||||
|
||||
if (!vfs_GetWd(conn,saved_dir)) {
|
||||
DEBUG(0,("change_owner_to_parent: failed to get "
|
||||
DEBUG(0,("change_dir_owner_to_parent: failed to get "
|
||||
"current working directory\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
/* Chdir into the new path. */
|
||||
if (vfs_ChDir(conn, fname) == -1) {
|
||||
DEBUG(0,("change_owner_to_parent: failed to change "
|
||||
DEBUG(0,("change_dir_owner_to_parent: failed to change "
|
||||
"current working directory to %s. Error "
|
||||
"was %s\n", fname, strerror(errno) ));
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (SMB_VFS_STAT(conn,".",&sbuf) == -1) {
|
||||
DEBUG(0,("change_owner_to_parent: failed to stat "
|
||||
DEBUG(0,("change_dir_owner_to_parent: failed to stat "
|
||||
"directory '.' (%s) Error was %s\n",
|
||||
fname, strerror(errno)));
|
||||
goto out;
|
||||
@ -165,7 +165,7 @@ static void change_owner_to_parent(connection_struct *conn,
|
||||
if (sbuf.st_dev != psbuf->st_dev ||
|
||||
sbuf.st_ino != psbuf->st_ino ||
|
||||
sbuf.st_mode != psbuf->st_mode ) {
|
||||
DEBUG(0,("change_owner_to_parent: "
|
||||
DEBUG(0,("change_dir_owner_to_parent: "
|
||||
"device/inode/mode on directory %s changed. "
|
||||
"Refusing to chown !\n", fname ));
|
||||
goto out;
|
||||
@ -175,14 +175,14 @@ static void change_owner_to_parent(connection_struct *conn,
|
||||
ret = SMB_VFS_CHOWN(conn, ".", parent_st.st_uid, (gid_t)-1);
|
||||
unbecome_root();
|
||||
if (ret == -1) {
|
||||
DEBUG(10,("change_owner_to_parent: failed to chown "
|
||||
DEBUG(10,("change_dir_owner_to_parent: failed to chown "
|
||||
"directory %s to parent directory uid %u. "
|
||||
"Error was %s\n", fname,
|
||||
(unsigned int)parent_st.st_uid, strerror(errno) ));
|
||||
goto out;
|
||||
}
|
||||
|
||||
DEBUG(10,("change_owner_to_parent: changed ownership of new "
|
||||
DEBUG(10,("change_dir_owner_to_parent: changed ownership of new "
|
||||
"directory %s to parent directory uid %u.\n",
|
||||
fname, (unsigned int)parent_st.st_uid ));
|
||||
|
||||
@ -197,6 +197,7 @@ static void change_owner_to_parent(connection_struct *conn,
|
||||
|
||||
static NTSTATUS open_file(files_struct *fsp,
|
||||
connection_struct *conn,
|
||||
const char *parent_dir,
|
||||
const char *fname,
|
||||
SMB_STRUCT_STAT *psbuf,
|
||||
int flags,
|
||||
@ -297,12 +298,14 @@ static NTSTATUS open_file(files_struct *fsp,
|
||||
|
||||
/* Inherit the ACL if required */
|
||||
if (lp_inherit_perms(SNUM(conn))) {
|
||||
inherit_access_acl(conn, fname, unx_mode);
|
||||
inherit_access_acl(conn, parent_dir, fname,
|
||||
unx_mode);
|
||||
}
|
||||
|
||||
/* Change the owner if required. */
|
||||
if (lp_inherit_owner(SNUM(conn))) {
|
||||
change_fd_owner_to_parent(conn, fsp);
|
||||
change_file_owner_to_parent(conn, parent_dir,
|
||||
fsp);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1124,6 +1127,7 @@ NTSTATUS open_file_ntcreate(connection_struct *conn,
|
||||
uint32 open_access_mask = access_mask;
|
||||
NTSTATUS status;
|
||||
int ret_flock;
|
||||
const char *parent_dir;
|
||||
|
||||
if (conn->printer) {
|
||||
/*
|
||||
@ -1140,9 +1144,15 @@ NTSTATUS open_file_ntcreate(connection_struct *conn,
|
||||
return print_fsp_open(conn, fname, result);
|
||||
}
|
||||
|
||||
if (!(parent_dir = talloc_strdup(tmp_talloc_ctx(),
|
||||
parent_dirname(fname)))) {
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
/* We add aARCH to this as this mode is only used if the file is
|
||||
* created new. */
|
||||
unx_mode = unix_mode(conn, new_dos_attributes | aARCH,fname, True);
|
||||
unx_mode = unix_mode(conn, new_dos_attributes | aARCH, fname,
|
||||
parent_dir);
|
||||
|
||||
DEBUG(10, ("open_file_ntcreate: fname=%s, dos_attrs=0x%x "
|
||||
"access_mask=0x%x share_access=0x%x "
|
||||
@ -1194,7 +1204,7 @@ NTSTATUS open_file_ntcreate(connection_struct *conn,
|
||||
/* this is for OS/2 long file names - say we don't support them */
|
||||
if (!lp_posix_pathnames() && strstr(fname,".+,;=[].")) {
|
||||
/* OS/2 Workplace shell fix may be main code stream in a later
|
||||
* release. */
|
||||
* release. */
|
||||
DEBUG(5,("open_file_ntcreate: OS/2 long filenames are not "
|
||||
"supported.\n"));
|
||||
if (use_nt_status()) {
|
||||
@ -1554,8 +1564,7 @@ NTSTATUS open_file_ntcreate(connection_struct *conn,
|
||||
*/
|
||||
|
||||
if ((flags2 & O_CREAT) && lp_inherit_acls(SNUM(conn)) &&
|
||||
(def_acl = directory_has_default_acl(conn,
|
||||
parent_dirname(fname)))) {
|
||||
(def_acl = directory_has_default_acl(conn, parent_dir))) {
|
||||
unx_mode = 0777;
|
||||
}
|
||||
|
||||
@ -1569,8 +1578,8 @@ NTSTATUS open_file_ntcreate(connection_struct *conn,
|
||||
* open_file strips any O_TRUNC flags itself.
|
||||
*/
|
||||
|
||||
fsp_open = open_file(fsp,conn,fname,psbuf,flags|flags2,unx_mode,
|
||||
access_mask, open_access_mask);
|
||||
fsp_open = open_file(fsp, conn, parent_dir, fname, psbuf, flags|flags2,
|
||||
unx_mode, access_mask, open_access_mask);
|
||||
|
||||
if (!NT_STATUS_IS_OK(fsp_open)) {
|
||||
if (lck != NULL) {
|
||||
@ -1658,7 +1667,7 @@ NTSTATUS open_file_ntcreate(connection_struct *conn,
|
||||
ret_flock = SMB_VFS_KERNEL_FLOCK(fsp, fsp->fh->fd, share_access);
|
||||
if(ret_flock == -1 ){
|
||||
|
||||
talloc_free(lck);
|
||||
TALLOC_FREE(lck);
|
||||
fd_close(conn, fsp);
|
||||
file_free(fsp);
|
||||
|
||||
@ -1755,7 +1764,7 @@ NTSTATUS open_file_ntcreate(connection_struct *conn,
|
||||
lp_store_dos_attributes(SNUM(conn))) {
|
||||
file_set_dosmode(conn, fname,
|
||||
new_dos_attributes | aARCH, NULL,
|
||||
True);
|
||||
parent_dir);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1835,7 +1844,8 @@ NTSTATUS open_file_fchmod(connection_struct *conn, const char *fname,
|
||||
|
||||
/* note! we must use a non-zero desired access or we don't get
|
||||
a real file descriptor. Oh what a twisted web we weave. */
|
||||
status = open_file(fsp,conn,fname,psbuf,O_WRONLY,0,FILE_WRITE_DATA,FILE_WRITE_DATA);
|
||||
status = open_file(fsp, conn, NULL, fname, psbuf, O_WRONLY, 0,
|
||||
FILE_WRITE_DATA, FILE_WRITE_DATA);
|
||||
|
||||
/*
|
||||
* This is not a user visible file open.
|
||||
@ -1868,6 +1878,7 @@ static NTSTATUS mkdir_internal(connection_struct *conn, const char *name,
|
||||
{
|
||||
int ret= -1;
|
||||
mode_t mode;
|
||||
const char *parent_dir;
|
||||
|
||||
if(!CAN_WRITE(conn)) {
|
||||
DEBUG(5,("mkdir_internal: failing create on read-only share "
|
||||
@ -1879,7 +1890,12 @@ static NTSTATUS mkdir_internal(connection_struct *conn, const char *name,
|
||||
return map_nt_error_from_unix(errno);
|
||||
}
|
||||
|
||||
mode = unix_mode(conn, aDIR, name, True);
|
||||
if (!(parent_dir = talloc_strdup(tmp_talloc_ctx(),
|
||||
parent_dirname(name)))) {
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
mode = unix_mode(conn, aDIR, name, parent_dir);
|
||||
|
||||
if ((ret=SMB_VFS_MKDIR(conn, name, mode)) != 0) {
|
||||
return map_nt_error_from_unix(errno);
|
||||
@ -1901,7 +1917,7 @@ static NTSTATUS mkdir_internal(connection_struct *conn, const char *name,
|
||||
}
|
||||
|
||||
if (lp_inherit_perms(SNUM(conn))) {
|
||||
inherit_access_acl(conn, name, mode);
|
||||
inherit_access_acl(conn, parent_dir, name, mode);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1917,7 +1933,7 @@ static NTSTATUS mkdir_internal(connection_struct *conn, const char *name,
|
||||
|
||||
/* Change the owner if required. */
|
||||
if (lp_inherit_owner(SNUM(conn))) {
|
||||
change_owner_to_parent(conn, name, psbuf);
|
||||
change_dir_owner_to_parent(conn, parent_dir, name, psbuf);
|
||||
}
|
||||
|
||||
return NT_STATUS_OK;
|
||||
|
@ -1878,7 +1878,10 @@ static mode_t create_default_mode(files_struct *fsp, BOOL interitable_mode)
|
||||
int snum = SNUM(fsp->conn);
|
||||
mode_t and_bits = (mode_t)0;
|
||||
mode_t or_bits = (mode_t)0;
|
||||
mode_t mode = interitable_mode ? unix_mode( fsp->conn, FILE_ATTRIBUTE_ARCHIVE, fsp->fsp_name, False) : S_IRUSR;
|
||||
mode_t mode = interitable_mode
|
||||
? unix_mode( fsp->conn, FILE_ATTRIBUTE_ARCHIVE, fsp->fsp_name,
|
||||
NULL )
|
||||
: S_IRUSR;
|
||||
|
||||
if (fsp->is_directory)
|
||||
mode |= (S_IWUSR|S_IXUSR);
|
||||
@ -3461,15 +3464,13 @@ int chmod_acl(connection_struct *conn, const char *name, mode_t mode)
|
||||
inherit this Access ACL to file name.
|
||||
****************************************************************************/
|
||||
|
||||
int inherit_access_acl(connection_struct *conn, const char *name, mode_t mode)
|
||||
int inherit_access_acl(connection_struct *conn, const char *inherit_from_dir,
|
||||
const char *name, mode_t mode)
|
||||
{
|
||||
pstring dirname;
|
||||
pstrcpy(dirname, parent_dirname(name));
|
||||
|
||||
if (directory_has_default_acl(conn, dirname))
|
||||
if (directory_has_default_acl(conn, inherit_from_dir))
|
||||
return 0;
|
||||
|
||||
return copy_access_acl(conn, dirname, name, mode);
|
||||
return copy_access_acl(conn, inherit_from_dir, name, mode);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -4300,8 +4300,9 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
|
||||
return(UNIXERROR(ERRDOS,ERRnoaccess));
|
||||
|
||||
if (lp_inherit_perms(SNUM(conn))) {
|
||||
inherit_access_acl(conn, fname,
|
||||
unixmode);
|
||||
inherit_access_acl(
|
||||
conn, parent_dirname(fname),
|
||||
fname, unixmode);
|
||||
}
|
||||
|
||||
SSVAL(params,0,0);
|
||||
|
Loading…
x
Reference in New Issue
Block a user