[PATCH] s3: introduce new share parameter "open special files"

Volker Lendecke Volker.Lendecke at SerNet.DE
Sat May 4 02:19:38 MDT 2013


On Sat, May 04, 2013 at 08:11:59AM +1200, Andrew Bartlett wrote:
> On Fri, 2013-05-03 at 13:31 +0200, Ralph Wuerthner wrote:
> > On Fri, 3 May 2013 13:15:33 +0200
> > Ralph Wuerthner <ralphw at de.ibm.com> wrote:
> > 
> > > Hi list,
> > > 
> > > attached patch introduces a new share parameter "open special files"
> > > to control whether special files such as sockets, devices and fifo's
> > > will be opened by the server or not. If set to "no" open requests to
> > > special files will fail with "access denied". Default value for "open
> > > special files" is "no".
> > > 
> > > Access to special files impose a security risk because it may for
> > > example allow remote clients raw access to local hard drives or
> > > kernel memory.
> > > 
> > > Regards
> > > 
> > > 	Ralph
> > 
> > I found a bug in above patch: the check for special files
> > must be done after checking for directories. Otherwise opening a
> > directory as a file will fail with "access denied" instead of "file is
> > a directory".
> 
> So, does this pass a full 'make test' now?

The attached version passed a manual autobuild.

Volker

-- 
SerNet GmbH, Bahnhofsallee 1b, 37081 Göttingen
phone: +49-551-370000-0, fax: +49-551-370000-9
AG Göttingen, HRB 2816, GF: Dr. Johannes Loxen
http://www.sernet.de, mailto:kontakt at sernet.de
-------------- next part --------------
>From 6902adee84a491e0e616b2207f0a68e317e1f2f7 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Fri, 3 May 2013 15:42:57 +0200
Subject: [PATCH 1/2] smbd: Factor out stat_is_special_file

This will be used for "open special files = yes/no"

Signed-off-by: Volker Lendecke <vl at samba.org>
---
 source3/smbd/dir.c   |   13 +++++++------
 source3/smbd/proto.h |    1 +
 2 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c
index 7dd959f..d783497 100644
--- a/source3/smbd/dir.c
+++ b/source3/smbd/dir.c
@@ -1319,6 +1319,12 @@ static bool user_can_write_file(connection_struct *conn,
   Is a file a "special" type ?
 ********************************************************************/
 
+bool stat_is_special_file(const struct stat_ex *st)
+{
+	mode_t mode = st->st_ex_mode;
+	return !( S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode) );
+}
+
 static bool file_is_special(connection_struct *conn,
 			    const struct smb_filename *smb_fname)
 {
@@ -1334,12 +1340,7 @@ static bool file_is_special(connection_struct *conn,
 
 	SMB_ASSERT(VALID_STAT(smb_fname->st));
 
-	if (S_ISREG(smb_fname->st.st_ex_mode) ||
-	    S_ISDIR(smb_fname->st.st_ex_mode) ||
-	    S_ISLNK(smb_fname->st.st_ex_mode))
-		return False;
-
-	return True;
+	return stat_is_special_file(&smb_fname->st);
 }
 
 /*******************************************************************
diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
index 38707d5..0b86ff1 100644
--- a/source3/smbd/proto.h
+++ b/source3/smbd/proto.h
@@ -229,6 +229,7 @@ bool get_dir_entry(TALLOC_CTX *ctx,
 		struct timespec *date,
 		bool check_descend,
 		bool ask_sharemode);
+bool stat_is_special_file(const struct stat_ex *st);
 bool is_visible_file(connection_struct *conn, const char *dir_path, const char *name, SMB_STRUCT_STAT *pst, bool use_veto);
 struct smb_Dir *OpenDir(TALLOC_CTX *mem_ctx, connection_struct *conn,
 			const char *name, const char *mask, uint32 attr);
-- 
1.7.9.5


>From 917e191c02fbc3b0e8cedf201487754c1ac4a4af Mon Sep 17 00:00:00 2001
From: Ralph Wuerthner <ralph.wuerthner at de.ibm.com>
Date: Thu, 2 May 2013 12:42:09 +0200
Subject: [PATCH 2/2] s3: introduce new share parameter "open special files"

This parameter controls whether special files such as sockets, devices
and fifo's will be opened by the server or not. If set to "no" open
requests to special files will fail with "access denied". Default
value for "open special files" is "no".

Signed-off-by: Ralph Wuerthner <ralph.wuerthner at de.ibm.com>
---
 docs-xml/smbdotconf/filename/openspecialfiles.xml |   19 +++++++++++++++++++
 lib/param/param_functions.c                       |    1 +
 lib/param/param_table.c                           |    9 +++++++++
 source3/include/proto.h                           |    1 +
 source3/param/loadparm.c                          |    1 +
 source3/smbd/open.c                               |   14 ++++++++++++++
 6 files changed, 45 insertions(+)
 create mode 100644 docs-xml/smbdotconf/filename/openspecialfiles.xml

diff --git a/docs-xml/smbdotconf/filename/openspecialfiles.xml b/docs-xml/smbdotconf/filename/openspecialfiles.xml
new file mode 100644
index 0000000..1a98695
--- /dev/null
+++ b/docs-xml/smbdotconf/filename/openspecialfiles.xml
@@ -0,0 +1,19 @@
+<samba:parameter name="open special files"
+                 context="S"
+				 type="boolean"
+                 xmlns:samba="http://www.samba.org/samba/DTD/samba-doc">
+<description>
+
+	<para>
+	This parameter controls whether special files such as sockets, devices
+	and fifo's will be opened by the server or not. If set to "no" open
+	requests to special files will fail with "access denied".
+
+	Access to special files impose a security risk because it may for
+	example allow remote clients raw access to local hard drives or kernel
+	memory.
+	</para>
+
+</description>
+<value type="default">no</value>
+</samba:parameter>
diff --git a/lib/param/param_functions.c b/lib/param/param_functions.c
index 7cb3a69..7ec6dc5 100644
--- a/lib/param/param_functions.c
+++ b/lib/param/param_functions.c
@@ -91,6 +91,7 @@ FN_LOCAL_BOOL(hide_dot_files, bHideDotFiles)
 FN_LOCAL_BOOL(hide_special_files, bHideSpecialFiles)
 FN_LOCAL_BOOL(hideunreadable, bHideUnReadable)
 FN_LOCAL_BOOL(hideunwriteable_files, bHideUnWriteableFiles)
+FN_LOCAL_BOOL(open_special_files, bOpenSpecialFiles)
 FN_LOCAL_BOOL(access_based_share_enum, bAccessBasedShareEnum)
 FN_LOCAL_BOOL(guest_ok, bGuest_ok)
 FN_LOCAL_BOOL(guest_only, bGuest_only)
diff --git a/lib/param/param_table.c b/lib/param/param_table.c
index c65a738..be20a48 100644
--- a/lib/param/param_table.c
+++ b/lib/param/param_table.c
@@ -2462,6 +2462,15 @@ static struct parm_struct parm_table[] = {
 		.flags		= FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
 	},
 	{
+		.label		= "open special files",
+		.type		= P_BOOL,
+		.p_class	= P_LOCAL,
+		.offset		= LOCAL_VAR(bOpenSpecialFiles),
+		.special	= NULL,
+		.enum_list	= NULL,
+		.flags		= FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
+	},
+	{
 		.label		= "delete veto files",
 		.type		= P_BOOL,
 		.p_class	= P_LOCAL,
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 83ab77a..0f3cdf1 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -1275,6 +1275,7 @@ bool lp_hide_dot_files(int );
 bool lp_hide_special_files(int );
 bool lp_hideunreadable(int );
 bool lp_hideunwriteable_files(int );
+bool lp_open_special_files(int);
 bool lp_browseable(int );
 bool lp_access_based_share_enum(int );
 bool lp_readonly(int );
diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
index d1c2a63..a3048aa 100644
--- a/source3/param/loadparm.c
+++ b/source3/param/loadparm.c
@@ -210,6 +210,7 @@ static struct loadparm_service sDefault =
 	.bHideSpecialFiles = false,
 	.bHideUnReadable = false,
 	.bHideUnWriteableFiles = false,
+	.bOpenSpecialFiles = false,
 	.bBrowseable = true,
 	.bAccessBasedShareEnum = false,
 	.bAvailable = true,
diff --git a/source3/smbd/open.c b/source3/smbd/open.c
index 7d02e52..00276d0 100644
--- a/source3/smbd/open.c
+++ b/source3/smbd/open.c
@@ -652,6 +652,11 @@ static NTSTATUS fd_open_atomic(struct connection_struct *conn,
 	return status;
 }
 
+static bool deny_open_special(connection_struct *conn)
+{
+	return !lp_open_special_files(SNUM(conn));
+}
+
 /****************************************************************************
  Open a file.
 ****************************************************************************/
@@ -891,6 +896,15 @@ static NTSTATUS open_file(files_struct *fsp,
 		return NT_STATUS_FILE_IS_A_DIRECTORY;
 	}
 
+	if (stat_is_special_file(&smb_fname->st) && deny_open_special(conn)) {
+		DEBUG(3, ("Denying open of special file %s, mode=%x\n",
+			  smb_fname_str_dbg(smb_fname),
+			  (int)smb_fname->st.st_ex_mode));
+		fd_close(fsp);
+		errno = EACCES;
+		return NT_STATUS_ACCESS_DENIED;
+	}
+
 	fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
 	fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
 	fsp->file_pid = req ? req->smbpid : 0;
-- 
1.7.9.5



More information about the samba-technical mailing list