1
0
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:
Volker Lendecke 2006-12-27 10:57:59 +00:00 committed by Gerald (Jerry) Carter
parent 9f2807fc93
commit 8cd9636458
5 changed files with 80 additions and 56 deletions

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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);
}
/****************************************************************************

View File

@ -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);