summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2002-04-20 07:28:46 +0000
committerAndrew Tridgell <tridge@samba.org>2002-04-20 07:28:46 +0000
commit86cf3b9f11a7ca756079ed2f9248415e13adb7f7 (patch)
tree66d593395a7cf464c883c9242bd1569af07aa415
parent5c261ce93d369d8c3901117777c3bb421178a186 (diff)
downloadsamba-86cf3b9f11a7ca756079ed2f9248415e13adb7f7.tar.gz
samba-86cf3b9f11a7ca756079ed2f9248415e13adb7f7.tar.bz2
samba-86cf3b9f11a7ca756079ed2f9248415e13adb7f7.zip
try to cope better with the take ownership operation for foreign SIDs
what we do is map to the authenticated user when the sid is unmappable and dos filemodes are enabled (This used to be commit b6c2ef4f54e7b42125f8c89ee5a62b0ba6b52f59)
-rw-r--r--source3/smbd/open.c6
-rw-r--r--source3/smbd/posix_acls.c60
2 files changed, 63 insertions, 3 deletions
diff --git a/source3/smbd/open.c b/source3/smbd/open.c
index 29a854a397..f8ba1ca8d8 100644
--- a/source3/smbd/open.c
+++ b/source3/smbd/open.c
@@ -1046,7 +1046,7 @@ flags=0x%X flags2=0x%X mode=0%o returned %d\n",
Open a file for for write to ensure that we can fchmod it.
****************************************************************************/
-files_struct *open_file_fchmod(connection_struct *conn, char *fname, SMB_STRUCT_STAT *psbuf)
+files_struct *open_file_fchmod(connection_struct *conn, const char *fname, SMB_STRUCT_STAT *psbuf)
{
files_struct *fsp = NULL;
BOOL fsp_open;
@@ -1058,7 +1058,9 @@ files_struct *open_file_fchmod(connection_struct *conn, char *fname, SMB_STRUCT_
if(!fsp)
return NULL;
- fsp_open = open_file(fsp,conn,fname,psbuf,O_WRONLY,0,0);
+ /* 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. */
+ fsp_open = open_file(fsp,conn,fname,psbuf,O_WRONLY,0,FILE_WRITE_DATA);
/*
* This is not a user visible file open.
diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c
index 9c8835214f..713210f693 100644
--- a/source3/smbd/posix_acls.c
+++ b/source3/smbd/posix_acls.c
@@ -439,9 +439,15 @@ static BOOL unpack_nt_owners(SMB_STRUCT_STAT *psbuf, uid_t *puser, gid_t *pgrp,
if (security_info_sent & OWNER_SECURITY_INFORMATION) {
sid_copy(&owner_sid, psd->owner_sid);
if (!sid_to_uid( &owner_sid, puser, &sid_type)) {
+#if ACL_FORCE_UNMAPPABLE
+ /* this allows take ownership to work reasonably */
+ extern struct current_user current_user;
+ *puser = current_user.uid;
+#else
DEBUG(3,("unpack_nt_owners: unable to validate owner sid for %s\n",
sid_string_static(&owner_sid)));
return False;
+#endif
}
}
@@ -453,8 +459,14 @@ static BOOL unpack_nt_owners(SMB_STRUCT_STAT *psbuf, uid_t *puser, gid_t *pgrp,
if (security_info_sent & GROUP_SECURITY_INFORMATION) {
sid_copy(&grp_sid, psd->grp_sid);
if (!sid_to_gid( &grp_sid, pgrp, &sid_type)) {
+#if ACL_FORCE_UNMAPPABLE
+ /* this allows take group ownership to work reasonably */
+ extern struct current_user current_user;
+ *pgrp = current_user.gid;
+#else
DEBUG(3,("unpack_nt_owners: unable to validate group sid.\n"));
return False;
+#endif
}
}
@@ -1996,6 +2008,52 @@ size_t get_nt_acl(files_struct *fsp, SEC_DESC **ppdesc)
return sd_size;
}
+/*
+ try to chown a file. We will be able to chown it under the following conditions
+
+ 1) if we have root privileges, then it will just work
+ 2) if we have write permission to the file and dos_filemodes is set
+ then allow chown to the currently authenticated user.
+
+ */
+static int try_chown(connection_struct *conn, const char *fname, uid_t uid, gid_t gid)
+{
+ int ret;
+ extern struct current_user current_user;
+ files_struct *fsp;
+ SMB_STRUCT_STAT st;
+
+ /* try the direct way first */
+ ret = vfs_chown(conn, fname, uid, gid);
+ if (ret == 0) return 0;
+
+ if(!CAN_WRITE(conn) || !lp_dos_filemode(SNUM(conn)))
+ return -1;
+
+ if (vfs_stat(conn,fname,&st)) {
+ return -1;
+ }
+
+ fsp = open_file_fchmod(conn,fname,&st);
+ if (!fsp) {
+ return -1;
+ }
+
+ /* only allow chown to the current user. This is more secure,
+ and also copes with the case where the SID in a take ownership ACL is
+ a local SID on the users workstation
+ */
+ uid = current_user.uid;
+
+ become_root();
+ ret = vfswrap_fchown(fsp, fsp->fd, uid, gid);
+ unbecome_root();
+
+ close_file_fchmod(fsp);
+
+ return ret;
+}
+
/****************************************************************************
Reply to set a security descriptor on an fsp. security_info_sent is the
description of the following NT ACL.
@@ -2052,7 +2110,7 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd)
DEBUG(3,("set_nt_acl: chown %s. uid = %u, gid = %u.\n",
fsp->fsp_name, (unsigned int)user, (unsigned int)grp ));
- if(vfs_chown( fsp->conn, fsp->fsp_name, user, grp) == -1) {
+ if(try_chown( fsp->conn, fsp->fsp_name, user, grp) == -1) {
DEBUG(3,("set_nt_acl: chown %s, %u, %u failed. Error = %s.\n",
fsp->fsp_name, (unsigned int)user, (unsigned int)grp, strerror(errno) ));
return False;