summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVolker Lendecke <vlendec@samba.org>2006-12-27 10:57:59 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 12:16:43 -0500
commit8cd9636458e175d2e1b63a5211423cec04a6ce91 (patch)
tree47ab7db144234fa02a3484cc21c7ccdd44f5f5a6
parent9f2807fc93bf25bbc06ddedebd0a1d17993444ec (diff)
downloadsamba-8cd9636458e175d2e1b63a5211423cec04a6ce91.tar.gz
samba-8cd9636458e175d2e1b63a5211423cec04a6ce91.tar.bz2
samba-8cd9636458e175d2e1b63a5211423cec04a6ce91.zip
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)
-rw-r--r--source3/smbd/dosmode.c27
-rw-r--r--source3/smbd/nttrans.c3
-rw-r--r--source3/smbd/open.c86
-rw-r--r--source3/smbd/posix_acls.c15
-rw-r--r--source3/smbd/trans2.c5
5 files changed, 80 insertions, 56 deletions
diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c
index 260a8dadbd..1172fe3e6b 100644
--- a/source3/smbd/dosmode.c
+++ b/source3/smbd/dosmode.c
@@ -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);
diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c
index 260a640dae..377ddbeec3 100644
--- a/source3/smbd/nttrans.c
+++ b/source3/smbd/nttrans.c
@@ -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;
diff --git a/source3/smbd/open.c b/source3/smbd/open.c
index 59cd8030af..28170e9cd8 100644
--- a/source3/smbd/open.c
+++ b/source3/smbd/open.c
@@ -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;
diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c
index 75605ace8a..c5da33c9df 100644
--- a/source3/smbd/posix_acls.c
+++ b/source3/smbd/posix_acls.c
@@ -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);
}
/****************************************************************************
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index e91cc7be06..9f22f65e34 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -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);