a42499
From a803d2524b8c06e2c360db0c686a212ac49f7321 Mon Sep 17 00:00:00 2001
a42499
From: Jeremy Allison <jra@samba.org>
a42499
Date: Thu, 21 Mar 2019 14:51:30 -0700
a42499
Subject: [PATCH] CVE-2019-3880 s3: rpc: winreg: Remove implementations of
a42499
 SaveKey/RestoreKey.
a42499
a42499
The were not using VFS backend calls and could only work
a42499
locally, and were unsafe against symlink races and other
a42499
security issues.
a42499
a42499
If the incoming handle is valid, return WERR_BAD_PATHNAME.
a42499
a42499
[MS-RRP] states "The format of the file name is implementation-specific"
a42499
so ensure we don't allow this.
a42499
a42499
As reported by Michael Hanselmann.
a42499
a42499
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13851
a42499
a42499
Signed-off-by: Jeremy Allison <jra@samba.org>
a42499
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
a42499
---
a42499
 source3/rpc_server/winreg/srv_winreg_nt.c | 92 ++-----------------------------
a42499
 1 file changed, 4 insertions(+), 88 deletions(-)
a42499
a42499
diff --git a/source3/rpc_server/winreg/srv_winreg_nt.c b/source3/rpc_server/winreg/srv_winreg_nt.c
a42499
index d9ee8d0602d..816c6bb2a12 100644
a42499
--- a/source3/rpc_server/winreg/srv_winreg_nt.c
a42499
+++ b/source3/rpc_server/winreg/srv_winreg_nt.c
a42499
@@ -640,46 +640,6 @@ WERROR _winreg_AbortSystemShutdown(struct pipes_struct *p,
a42499
 }
a42499
 
a42499
 /*******************************************************************
a42499
- ********************************************************************/
a42499
-
a42499
-static int validate_reg_filename(TALLOC_CTX *ctx, char **pp_fname )
a42499
-{
a42499
-	char *p = NULL;
a42499
-	int num_services = lp_numservices();
a42499
-	int snum = -1;
a42499
-	const char *share_path = NULL;
a42499
-	char *fname = *pp_fname;
a42499
-
a42499
-	/* convert to a unix path, stripping the C:\ along the way */
a42499
-
a42499
-	if (!(p = valid_share_pathname(ctx, fname))) {
a42499
-		return -1;
a42499
-	}
a42499
-
a42499
-	/* has to exist within a valid file share */
a42499
-
a42499
-	for (snum=0; snum
a42499
-		if (!lp_snum_ok(snum) || lp_printable(snum)) {
a42499
-			continue;
a42499
-		}
a42499
-
a42499
-		share_path = lp_path(talloc_tos(), snum);
a42499
-
a42499
-		/* make sure we have a path (e.g. [homes] ) */
a42499
-		if (strlen(share_path) == 0) {
a42499
-			continue;
a42499
-		}
a42499
-
a42499
-		if (strncmp(share_path, p, strlen(share_path)) == 0) {
a42499
-			break;
a42499
-		}
a42499
-	}
a42499
-
a42499
-	*pp_fname = p;
a42499
-	return (snum < num_services) ? snum : -1;
a42499
-}
a42499
-
a42499
-/*******************************************************************
a42499
  _winreg_RestoreKey
a42499
  ********************************************************************/
a42499
 
a42499
@@ -687,36 +647,11 @@ WERROR _winreg_RestoreKey(struct pipes_struct *p,
a42499
 			  struct winreg_RestoreKey *r)
a42499
 {
a42499
 	struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
a42499
-	char *fname = NULL;
a42499
-	int snum = -1;
a42499
 
a42499
-	if ( !regkey )
a42499
+	if ( !regkey ) {
a42499
 		return WERR_INVALID_HANDLE;
a42499
-
a42499
-	if ( !r->in.filename || !r->in.filename->name )
a42499
-		return WERR_INVALID_PARAMETER;
a42499
-
a42499
-	fname = talloc_strdup(p->mem_ctx, r->in.filename->name);
a42499
-	if (!fname) {
a42499
-		return WERR_NOT_ENOUGH_MEMORY;
a42499
 	}
a42499
-
a42499
-	DEBUG(8,("_winreg_RestoreKey: verifying restore of key [%s] from "
a42499
-		 "\"%s\"\n", regkey->key->name, fname));
a42499
-
a42499
-	if ((snum = validate_reg_filename(p->mem_ctx, &fname)) == -1)
a42499
-		return WERR_BAD_PATHNAME;
a42499
-
a42499
-	/* user must posses SeRestorePrivilege for this this proceed */
a42499
-
a42499
-	if ( !security_token_has_privilege(p->session_info->security_token, SEC_PRIV_RESTORE)) {
a42499
-		return WERR_ACCESS_DENIED;
a42499
-	}
a42499
-
a42499
-	DEBUG(2,("_winreg_RestoreKey: Restoring [%s] from %s in share %s\n",
a42499
-		 regkey->key->name, fname, lp_servicename(talloc_tos(), snum) ));
a42499
-
a42499
-	return reg_restorekey(regkey, fname);
a42499
+	return WERR_BAD_PATHNAME;
a42499
 }
a42499
 
a42499
 /*******************************************************************
a42499
@@ -727,30 +662,11 @@ WERROR _winreg_SaveKey(struct pipes_struct *p,
a42499
 		       struct winreg_SaveKey *r)
a42499
 {
a42499
 	struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
a42499
-	char *fname = NULL;
a42499
-	int snum = -1;
a42499
 
a42499
-	if ( !regkey )
a42499
+	if ( !regkey ) {
a42499
 		return WERR_INVALID_HANDLE;
a42499
-
a42499
-	if ( !r->in.filename || !r->in.filename->name )
a42499
-		return WERR_INVALID_PARAMETER;
a42499
-
a42499
-	fname = talloc_strdup(p->mem_ctx, r->in.filename->name);
a42499
-	if (!fname) {
a42499
-		return WERR_NOT_ENOUGH_MEMORY;
a42499
 	}
a42499
-
a42499
-	DEBUG(8,("_winreg_SaveKey: verifying backup of key [%s] to \"%s\"\n",
a42499
-		 regkey->key->name, fname));
a42499
-
a42499
-	if ((snum = validate_reg_filename(p->mem_ctx, &fname)) == -1 )
a42499
-		return WERR_BAD_PATHNAME;
a42499
-
a42499
-	DEBUG(2,("_winreg_SaveKey: Saving [%s] to %s in share %s\n",
a42499
-		 regkey->key->name, fname, lp_servicename(talloc_tos(), snum) ));
a42499
-
a42499
-	return reg_savekey(regkey, fname);
a42499
+	return WERR_BAD_PATHNAME;
a42499
 }
a42499
 
a42499
 /*******************************************************************
a42499
-- 
a42499
2.11.0
a42499