[patch] user space access checks on files (outside of a share)

Gerald (Jerry) Carter jerry at samba.org
Thu Oct 13 21:02:42 GMT 2005


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Jeremy,

You are a genius,.  Faking up the connection struct was the
key.  Hole thing is < 150 lines of code.

Summary the list:  We can only open a tdb once in an
smbd process.  But we need to possibly have multiple
open handles to an eventlog tdb.  Therefore we open
the tdb as root and use a reference count strategy to
know when to close.  But this means we can't use an
open() call to see if the user has read permissions
on the tdb to be able to read the log file.

This patch adds an access check to OpenEventlog() based
on the file system perms for the $(lockdir)/eventlog/logname.tdb
file.  I store the access_granted with the open Eventlog
handle so we can just check for SA_FILE_WRITE_DATA for
the ClearEventlog() call later on.

Please take a look and see if I've goofed anything.
Thanks.




cheers, jerry
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.0 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org

iD8DBQFDTstxIR7qMdg1EfYRAoDWAJ9EdPnpLJEPTQHKMeOq4wGk9QbnWACZAWvK
AZj8wPl1FAhD1o53k0cOrC8=
=cNVI
-----END PGP SIGNATURE-----
-------------- next part --------------
Index: smbd/posix_acls.c
===================================================================
--- smbd/posix_acls.c	(revision 10968)
+++ smbd/posix_acls.c	(working copy)
@@ -4182,3 +4182,58 @@
 	/* Finally check other write access. */
 	return (psbuf->st_mode & S_IWOTH) ? True : False;
 }
+
+/********************************************************************
+ Pull the NT ACL from a file on disk or the OpenEventlog() access
+ check.  Caller is responsible for freeing the returned security
+ descriptor via TALLOC_FREE().  This is designed for dealing with 
+ user space access checks in smbd outside of the VFS.  For example,
+ checking access rights in OpenEventlog().
+ 
+ Assume we are dealing with files (for now)
+********************************************************************/
+
+SEC_DESC* get_nt_acl_no_snum( TALLOC_CTX *ctx, const char *fname)
+{
+	SEC_DESC *psd, *ret_sd;
+	size_t sd_size;
+	connection_struct conn;
+	files_struct finfo;
+	struct fd_handle fh;
+	fstring path;
+	pstring filename;
+	
+	ZERO_STRUCT( conn );
+	conn.service = -1;
+	
+	if ( !(conn.mem_ctx = talloc_init( "novfs_get_nt_acl" )) ) {
+		DEBUG(0,("novfs_get_nt_acl: talloc() failed!\n"));
+		return NULL;
+	}
+	
+	fstrcpy( path, "/" );
+	string_set(&conn.connectpath, path);
+	
+	if (!smbd_vfs_init(&conn)) {
+		DEBUG(0,("novfs_get_nt_acl: Unable to create a fake connection struct!\n"));
+		return NULL;
+        }
+	
+	ZERO_STRUCT( finfo );
+	ZERO_STRUCT( fh );
+	
+	finfo.fnum = -1;
+	finfo.conn = &conn;
+	finfo.fh = &fh;
+	finfo.fh->fd = -1;
+	pstrcpy( filename, fname );
+	finfo.fsp_name = filename;
+	
+	sd_size = get_nt_acl( &finfo, DACL_SECURITY_INFORMATION, &psd );
+	
+	ret_sd = dup_sec_desc( ctx, psd );
+	
+	conn_free_internal( &conn );
+	
+	return ret_sd;
+}
Index: rpc_server/srv_eventlog_nt.c
===================================================================
--- rpc_server/srv_eventlog_nt.c	(revision 10968)
+++ rpc_server/srv_eventlog_nt.c	(working copy)
@@ -67,9 +67,44 @@
 /********************************************************************
 ********************************************************************/
 
-static BOOL elog_check_access( EVENTLOG_INFO *info )
+static BOOL elog_check_access( EVENTLOG_INFO *info, NT_USER_TOKEN *token )
 {
-	return True;
+	char *tdbname = elog_tdbname( info->logname );
+	SEC_DESC *sec_desc;
+	BOOL ret;
+	NTSTATUS ntstatus;
+	
+	if ( !tdbname ) 
+		return False;
+	
+	/* get the security descriptor for the file */
+	
+	sec_desc = get_nt_acl_no_snum( info, tdbname );
+	SAFE_FREE( tdbname );
+	
+	if ( !sec_desc ) {
+		DEBUG(5,("elog_check_access: Unable to get NT ACL for %s\n", 
+			tdbname));
+		return False;
+	}
+	
+	/* run the check, try for the max allowed */
+	
+	ret = se_access_check( sec_desc, token, MAXIMUM_ALLOWED_ACCESS,
+		&info->access_granted, &ntstatus );
+		
+	if ( sec_desc )
+		TALLOC_FREE( sec_desc );
+		
+	if ( !ret ) {
+		DEBUG(8,("elog_check_access: se_access_check() return %s\n",
+			nt_errstr( ntstatus)));
+		return False;
+	}
+	
+	/* we have to have READ permission for a successful open */
+	
+	return ( info->access_granted & SA_RIGHT_FILE_READ_DATA );
 }
 
 /********************************************************************
@@ -106,7 +141,7 @@
 	elog->logname = talloc_strdup( elog, logname );
 	
 	/* do the access check */
-	if ( !elog_check_access( elog ) ) {
+	if ( !elog_check_access( elog, p->pipe_user.nt_user_token ) ) {
 		TALLOC_FREE( elog );
 		return WERR_ACCESS_DENIED;
 	}
@@ -130,7 +165,7 @@
 			elog->logname = talloc_strdup( elog, ELOG_APPL );			
 
 			/* do the access check */
-			if ( !elog_check_access( elog ) ) {
+			if ( !elog_check_access( elog, p->pipe_user.nt_user_token ) ) {
 				TALLOC_FREE( elog );
 				return WERR_ACCESS_DENIED;
 			}


More information about the samba-technical mailing list