summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRalph Boehme <slow@samba.org>2021-10-08 12:33:16 +0200
committerJule Anger <janger@samba.org>2021-11-08 10:46:43 +0100
commit6280d99de7d0f761842a5ab37a6253aefa237344 (patch)
tree223e5ac3aadff2367db7b63a88a47c4d47a83c6e
parentc3c49ceeb7991f9851e616a901e2f601ff796c3e (diff)
downloadsamba-6280d99de7d0f761842a5ab37a6253aefa237344.tar.gz
CVE-2020-25717: s3:auth: remove fallbacks in smb_getpwnam()
So far we tried getpwnam("DOMAIN\account") first and always did a fallback to getpwnam("account") completely ignoring the domain part, this just causes problems as we mix "DOMAIN1\account", "DOMAIN2\account", and "account"! As we require a running winbindd for domain member setups we should no longer do a fallback to just "account" for users served by winbindd! For users of the local SAM don't use this code path, as check_sam_security() doesn't call check_account(). The only case where smb_getpwnam("account") happens is when map_username() via ("username map [script]") mapped "DOMAIN\account" to something without '\', but that is explicitly desired by the admin. Note: use 'git show -w' BUG: https://bugzilla.samba.org/show_bug.cgi?id=14801 BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556 Pair-Programmed-With: Stefan Metzmacher <metze@samba.org> Signed-off-by: Ralph Boehme <slow@samba.org> Signed-off-by: Stefan Metzmacher <metze@samba.org> Reviewed-by: Andrew Bartlett <abartlet@samba.org>
-rw-r--r--selftest/knownfail.d/ktest26
-rw-r--r--source3/auth/auth_util.c77
2 files changed, 68 insertions, 35 deletions
diff --git a/selftest/knownfail.d/ktest b/selftest/knownfail.d/ktest
new file mode 100644
index 00000000000..809612ba0b9
--- /dev/null
+++ b/selftest/knownfail.d/ktest
@@ -0,0 +1,26 @@
+^samba3.rpc.lsa.lookupsids.krb5.with.old.ccache.ncacn_np.with..smb2...lsa.LookupSidsReply.ktest
+^samba3.rpc.lsa.lookupsids.krb5.ncacn_np.with..smb2...lsa.LookupSidsReply.ktest
+^samba3.blackbox.rpcclient.krb5.ncacn_np.with..krb5...rpcclient.ktest:local
+^samba3.blackbox.rpcclient.krb5.ncacn_np.with..spnego,krb5...rpcclient.ktest:local
+^samba3.rpc.lsa.lookupsids.krb5.with.old.ccache.ncacn_np.with..smb2,connect...lsa.LookupSidsReply.ktest
+^samba3.rpc.lsa.lookupsids.krb5.ncacn_np.with..smb2,connect...lsa.LookupSidsReply.ktest
+^samba3.rpc.lsa.lookupsids.krb5.with.old.ccache.ncacn_np.with..smb2,packet...lsa.LookupSidsReply.ktest
+^samba3.rpc.lsa.lookupsids.krb5.ncacn_np.with..smb2,packet...lsa.LookupSidsReply.ktest
+^samba3.blackbox.rpcclient.krb5.ncacn_np.with..krb5,packet...rpcclient.ktest:local
+^samba3.blackbox.rpcclient.krb5.ncacn_np.with..spnego,krb5,packet...rpcclient.ktest:local
+^samba3.rpc.lsa.lookupsids.krb5.with.old.ccache.ncacn_np.with..smb2,sign...lsa.LookupSidsReply.ktest
+^samba3.rpc.lsa.lookupsids.krb5.ncacn_np.with..smb2,sign...lsa.LookupSidsReply.ktest
+^samba3.blackbox.rpcclient.krb5.ncacn_np.with..krb5,sign...rpcclient.ktest:local
+^samba3.blackbox.rpcclient.krb5.ncacn_np.with..spnego,krb5,sign...rpcclient.ktest:local
+^samba3.rpc.lsa.lookupsids.krb5.with.old.ccache.ncacn_np.with..smb2,seal...lsa.LookupSidsReply.ktest
+^samba3.rpc.lsa.lookupsids.krb5.ncacn_np.with..smb2,seal...lsa.LookupSidsReply.ktest
+^samba3.blackbox.rpcclient.krb5.ncacn_np.with..krb5,seal...rpcclient.ktest:local
+^samba3.blackbox.rpcclient.krb5.ncacn_np.with..spnego,krb5,seal...rpcclient.ktest:local
+^samba3.blackbox.smbclient_krb5.old.ccache..smbclient.ktest:local
+^samba3.blackbox.smbclient_krb5.new.ccache..smbclient.ktest:local
+^samba3.blackbox.smbclient_large_file..krb5.smbclient.large.posix.write.read.ktest:local
+^samba3.blackbox.smbclient_large_file..krb5.cmp.of.read.and.written.files.ktest:local
+^samba3.blackbox.smbclient_krb5.old.ccache.--client-protection=encrypt.smbclient.ktest:local
+^samba3.blackbox.smbclient_krb5.new.ccache.--client-protection=encrypt.smbclient.ktest:local
+^samba3.blackbox.smbclient_large_file.--client-protection=encrypt.krb5.smbclient.large.posix.write.read.ktest:local
+^samba3.blackbox.smbclient_large_file.--client-protection=encrypt.krb5.cmp.of.read.and.written.files.ktest:local
diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c
index 99b85d47a5f..d81313a0495 100644
--- a/source3/auth/auth_util.c
+++ b/source3/auth/auth_util.c
@@ -1933,7 +1933,7 @@ struct passwd *smb_getpwnam( TALLOC_CTX *mem_ctx, const char *domuser,
{
struct passwd *pw = NULL;
char *p = NULL;
- char *username = NULL;
+ const char *username = NULL;
/* we only save a copy of the username it has been mangled
by winbindd use default domain */
@@ -1952,48 +1952,55 @@ struct passwd *smb_getpwnam( TALLOC_CTX *mem_ctx, const char *domuser,
/* code for a DOMAIN\user string */
if ( p ) {
- pw = Get_Pwnam_alloc( mem_ctx, domuser );
- if ( pw ) {
- /* make sure we get the case of the username correct */
- /* work around 'winbind use default domain = yes' */
-
- if ( lp_winbind_use_default_domain() &&
- !strchr_m( pw->pw_name, *lp_winbind_separator() ) ) {
- char *domain;
-
- /* split the domain and username into 2 strings */
- *p = '\0';
- domain = username;
-
- *p_save_username = talloc_asprintf(mem_ctx,
- "%s%c%s",
- domain,
- *lp_winbind_separator(),
- pw->pw_name);
- if (!*p_save_username) {
- TALLOC_FREE(pw);
- return NULL;
- }
- } else {
- *p_save_username = talloc_strdup(mem_ctx, pw->pw_name);
- }
+ const char *domain = NULL;
- /* whew -- done! */
- return pw;
+ /* split the domain and username into 2 strings */
+ *p = '\0';
+ domain = username;
+ p++;
+ username = p;
+
+ if (strequal(domain, get_global_sam_name())) {
+ /*
+ * This typically don't happen
+ * as check_sam_Security()
+ * don't call make_server_info_info3()
+ * and thus check_account().
+ *
+ * But we better keep this.
+ */
+ goto username_only;
}
- /* setup for lookup of just the username */
- /* remember that p and username are overlapping memory */
-
- p++;
- username = talloc_strdup(mem_ctx, p);
- if (!username) {
+ pw = Get_Pwnam_alloc( mem_ctx, domuser );
+ if (pw == NULL) {
return NULL;
}
+ /* make sure we get the case of the username correct */
+ /* work around 'winbind use default domain = yes' */
+
+ if ( lp_winbind_use_default_domain() &&
+ !strchr_m( pw->pw_name, *lp_winbind_separator() ) ) {
+ *p_save_username = talloc_asprintf(mem_ctx,
+ "%s%c%s",
+ domain,
+ *lp_winbind_separator(),
+ pw->pw_name);
+ if (!*p_save_username) {
+ TALLOC_FREE(pw);
+ return NULL;
+ }
+ } else {
+ *p_save_username = talloc_strdup(mem_ctx, pw->pw_name);
+ }
+
+ /* whew -- done! */
+ return pw;
+
}
/* just lookup a plain username */
-
+username_only:
pw = Get_Pwnam_alloc(mem_ctx, username);
/* Create local user if requested but only if winbindd