svn commit: samba r21097 - in branches: SAMBA_3_0/source/smbd
SAMBA_3_0_24/source/smbd
jra at samba.org
jra at samba.org
Wed Jan 31 19:26:48 GMT 2007
Author: jra
Date: 2007-01-31 19:26:46 +0000 (Wed, 31 Jan 2007)
New Revision: 21097
WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=21097
Log:
Ensure that when manipulating UNIX permissions via
the UNIX extensions we use the correct mask/force mask
settings for new and existing files/directories. Bug
reported by Juran David <ext-david.juran at nokia.com>.
Jeremy.
Modified:
branches/SAMBA_3_0/source/smbd/trans2.c
branches/SAMBA_3_0_24/source/smbd/trans2.c
Changeset:
Modified: branches/SAMBA_3_0/source/smbd/trans2.c
===================================================================
--- branches/SAMBA_3_0/source/smbd/trans2.c 2007-01-31 19:25:08 UTC (rev 21096)
+++ branches/SAMBA_3_0/source/smbd/trans2.c 2007-01-31 19:26:46 UTC (rev 21097)
@@ -1005,12 +1005,24 @@
Map wire perms onto standard UNIX permissions. Obey share restrictions.
****************************************************************************/
-static mode_t unix_perms_from_wire( connection_struct *conn, SMB_STRUCT_STAT *pst, uint32 perms)
+enum perm_type { PERM_NEW_FILE, PERM_NEW_DIR, PERM_EXISTING_FILE, PERM_EXISTING_DIR};
+
+static NTSTATUS unix_perms_from_wire( connection_struct *conn,
+ SMB_STRUCT_STAT *psbuf,
+ uint32 perms,
+ enum perm_type ptype,
+ mode_t *ret_perms)
{
mode_t ret = 0;
- if (perms == SMB_MODE_NO_CHANGE)
- return pst->st_mode;
+ if (perms == SMB_MODE_NO_CHANGE) {
+ if (!VALID_STAT(*psbuf)) {
+ return NT_STATUS_INVALID_PARAMETER;
+ } else {
+ *ret_perms = psbuf->st_mode;
+ return NT_STATUS_OK;
+ }
+ }
ret |= ((perms & UNIX_X_OTH ) ? S_IXOTH : 0);
ret |= ((perms & UNIX_W_OTH ) ? S_IWOTH : 0);
@@ -1031,18 +1043,34 @@
ret |= ((perms & UNIX_SET_UID ) ? S_ISUID : 0);
#endif
- if (VALID_STAT(*pst) && S_ISDIR(pst->st_mode)) {
+ switch (ptype) {
+ case PERM_NEW_FILE:
+ /* Apply mode mask */
+ ret &= lp_create_mask(SNUM(conn));
+ /* Add in force bits */
+ ret |= lp_force_create_mode(SNUM(conn));
+ break;
+ case PERM_NEW_DIR:
ret &= lp_dir_mask(SNUM(conn));
/* Add in force bits */
ret |= lp_force_dir_mode(SNUM(conn));
- } else {
+ break;
+ case PERM_EXISTING_FILE:
/* Apply mode mask */
- ret &= lp_create_mask(SNUM(conn));
+ ret &= lp_security_mask(SNUM(conn));
/* Add in force bits */
- ret |= lp_force_create_mode(SNUM(conn));
+ ret |= lp_force_security_mode(SNUM(conn));
+ break;
+ case PERM_EXISTING_DIR:
+ /* Apply mode mask */
+ ret &= lp_dir_security_mask(SNUM(conn));
+ /* Add in force bits */
+ ret |= lp_force_dir_security_mode(SNUM(conn));
+ break;
}
- return ret;
+ *ret_perms = ret;
+ return NT_STATUS_OK;
}
/****************************************************************************
@@ -4585,18 +4613,18 @@
#endif
SMB_DEV_T dev = (SMB_DEV_T)0;
uint32 raw_unixmode = IVAL(pdata,84);
+ NTSTATUS status;
mode_t unixmode;
if (total_data < 100) {
return NT_STATUS_INVALID_PARAMETER;
}
- if (raw_unixmode == SMB_MODE_NO_CHANGE) {
- return NT_STATUS_INVALID_PARAMETER;
+ status = unix_perms_from_wire(conn, psbuf, raw_unixmode, PERM_NEW_FILE, &unixmode);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
}
- unixmode = unix_perms_from_wire(conn, psbuf, raw_unixmode);
-
#if defined(HAVE_MAKEDEV)
dev = makedev(dev_major, dev_minor);
#endif
@@ -4645,7 +4673,7 @@
}
if (SMB_VFS_STAT(conn, fname, psbuf) != 0) {
- NTSTATUS status = map_nt_error_from_unix(errno);
+ status = map_nt_error_from_unix(errno);
SMB_VFS_UNLINK(conn,fname);
return status;
}
@@ -4671,6 +4699,7 @@
gid_t set_grp = (uid_t)SMB_GID_NO_CHANGE;
NTSTATUS status = NT_STATUS_OK;
BOOL delete_on_fail = False;
+ enum perm_type ptype;
if (total_data < 100) {
return NT_STATUS_INVALID_PARAMETER;
@@ -4694,8 +4723,22 @@
set_owner = (uid_t)IVAL(pdata,40);
set_grp = (gid_t)IVAL(pdata,48);
raw_unixmode = IVAL(pdata,84);
- unixmode = unix_perms_from_wire(conn, psbuf, raw_unixmode);
+ if (VALID_STAT(*psbuf)) {
+ if (S_ISDIR(psbuf->st_mode)) {
+ ptype = PERM_EXISTING_DIR;
+ } else {
+ ptype = PERM_EXISTING_FILE;
+ }
+ } else {
+ ptype = PERM_NEW_FILE;
+ }
+
+ status = unix_perms_from_wire(conn, psbuf, raw_unixmode, ptype, &unixmode);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC: name = %s \
size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
fname, (double)size, (unsigned int)set_owner, (unsigned int)set_grp, (int)raw_unixmode));
Modified: branches/SAMBA_3_0_24/source/smbd/trans2.c
===================================================================
--- branches/SAMBA_3_0_24/source/smbd/trans2.c 2007-01-31 19:25:08 UTC (rev 21096)
+++ branches/SAMBA_3_0_24/source/smbd/trans2.c 2007-01-31 19:26:46 UTC (rev 21097)
@@ -1005,12 +1005,24 @@
Map wire perms onto standard UNIX permissions. Obey share restrictions.
****************************************************************************/
-static mode_t unix_perms_from_wire( connection_struct *conn, SMB_STRUCT_STAT *pst, uint32 perms)
+enum perm_type { PERM_NEW_FILE, PERM_NEW_DIR, PERM_EXISTING_FILE, PERM_EXISTING_DIR};
+
+static NTSTATUS unix_perms_from_wire( connection_struct *conn,
+ SMB_STRUCT_STAT *psbuf,
+ uint32 perms,
+ enum perm_type ptype,
+ mode_t *ret_perms)
{
mode_t ret = 0;
- if (perms == SMB_MODE_NO_CHANGE)
- return pst->st_mode;
+ if (perms == SMB_MODE_NO_CHANGE) {
+ if (!VALID_STAT(*psbuf)) {
+ return NT_STATUS_INVALID_PARAMETER;
+ } else {
+ *ret_perms = psbuf->st_mode;
+ return NT_STATUS_OK;
+ }
+ }
ret |= ((perms & UNIX_X_OTH ) ? S_IXOTH : 0);
ret |= ((perms & UNIX_W_OTH ) ? S_IWOTH : 0);
@@ -1031,18 +1043,34 @@
ret |= ((perms & UNIX_SET_UID ) ? S_ISUID : 0);
#endif
- if (VALID_STAT(*pst) && S_ISDIR(pst->st_mode)) {
+ switch (ptype) {
+ case PERM_NEW_FILE:
+ /* Apply mode mask */
+ ret &= lp_create_mask(SNUM(conn));
+ /* Add in force bits */
+ ret |= lp_force_create_mode(SNUM(conn));
+ break;
+ case PERM_NEW_DIR:
ret &= lp_dir_mask(SNUM(conn));
/* Add in force bits */
ret |= lp_force_dir_mode(SNUM(conn));
- } else {
+ break;
+ case PERM_EXISTING_FILE:
/* Apply mode mask */
- ret &= lp_create_mask(SNUM(conn));
+ ret &= lp_security_mask(SNUM(conn));
/* Add in force bits */
- ret |= lp_force_create_mode(SNUM(conn));
+ ret |= lp_force_security_mode(SNUM(conn));
+ break;
+ case PERM_EXISTING_DIR:
+ /* Apply mode mask */
+ ret &= lp_dir_security_mask(SNUM(conn));
+ /* Add in force bits */
+ ret |= lp_force_dir_security_mode(SNUM(conn));
+ break;
}
- return ret;
+ *ret_perms = ret;
+ return NT_STATUS_OK;
}
/****************************************************************************
@@ -4589,18 +4617,18 @@
#endif
SMB_DEV_T dev = (SMB_DEV_T)0;
uint32 raw_unixmode = IVAL(pdata,84);
+ NTSTATUS status;
mode_t unixmode;
if (total_data < 100) {
return NT_STATUS_INVALID_PARAMETER;
}
- if (raw_unixmode == SMB_MODE_NO_CHANGE) {
- return NT_STATUS_INVALID_PARAMETER;
+ status = unix_perms_from_wire(conn, psbuf, raw_unixmode, PERM_NEW_FILE, &unixmode);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
}
- unixmode = unix_perms_from_wire(conn, psbuf, raw_unixmode);
-
#if defined(HAVE_MAKEDEV)
dev = makedev(dev_major, dev_minor);
#endif
@@ -4649,7 +4677,7 @@
}
if (SMB_VFS_STAT(conn, fname, psbuf) != 0) {
- NTSTATUS status = map_nt_error_from_unix(errno);
+ status = map_nt_error_from_unix(errno);
SMB_VFS_UNLINK(conn,fname);
return status;
}
@@ -4675,6 +4703,7 @@
gid_t set_grp = (uid_t)SMB_GID_NO_CHANGE;
NTSTATUS status = NT_STATUS_OK;
BOOL delete_on_fail = False;
+ enum perm_type ptype;
if (total_data < 100) {
return NT_STATUS_INVALID_PARAMETER;
@@ -4698,8 +4727,22 @@
set_owner = (uid_t)IVAL(pdata,40);
set_grp = (gid_t)IVAL(pdata,48);
raw_unixmode = IVAL(pdata,84);
- unixmode = unix_perms_from_wire(conn, psbuf, raw_unixmode);
+ if (VALID_STAT(*psbuf)) {
+ if (S_ISDIR(psbuf->st_mode)) {
+ ptype = PERM_EXISTING_DIR;
+ } else {
+ ptype = PERM_EXISTING_FILE;
+ }
+ } else {
+ ptype = PERM_NEW_FILE;
+ }
+
+ status = unix_perms_from_wire(conn, psbuf, raw_unixmode, ptype, &unixmode);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC: name = %s \
size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
fname, (double)size, (unsigned int)set_owner, (unsigned int)set_grp, (int)raw_unixmode));
More information about the samba-cvs
mailing list