RFC/WIP: NTLMSSP passthrough + user at realm credentials

Uri Simchoni uri at samba.org
Thu Oct 20 12:07:11 UTC 2016


Hi,

The attached patch seems to fix
https://bugzilla.samba.org/show_bug.cgi?id=12375 - authenticating
clients by a member server using user at realm credentials.

In essence, the client passes an empty domain and upn at realm as user, and
those need to be passed untouched to the netlogon server.

The patch seems to make it work, but I feel I don't have the big
picture, and would like to receive comments on:
- Whether there are any flags to be looked at instead of the heuristic
that the domain is empty and user contains '@'
- If heuristic - do we already have functions to parse and classify a
user name
- Interaction with user mapping
- ... anything else.

I'll also do some more digging into the relevant [MS-xxx] docs.

Thanks,
Uri.
-------------- next part --------------
From 1ba8904d2eadaac9ec98c671800929d986d5f041 Mon Sep 17 00:00:00 2001
From: Uri Simchoni <uri at samba.org>
Date: Thu, 20 Oct 2016 14:54:13 +0300
Subject: [PATCH] s3-winbindd: allow []\[upn at realm] AUTH_CRAP

Signed-off-by: Uri Simchoni <uri at samba.org>
---
 source3/auth/auth_util.c                  | 19 ++++++++++++++-----
 source3/winbindd/winbindd_pam_auth_crap.c | 15 +++++++++------
 2 files changed, 23 insertions(+), 11 deletions(-)

diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c
index 5473fa2..25ceb47 100644
--- a/source3/auth/auth_util.c
+++ b/source3/auth/auth_util.c
@@ -105,10 +105,20 @@ NTSTATUS make_user_info_map(TALLOC_CTX *mem_ctx,
 {
 	const char *domain;
 	NTSTATUS result;
-	bool was_mapped;
+	bool was_mapped = false;
 	char *internal_username = NULL;
+	bool upn_form = false;
 
-	was_mapped = map_username(talloc_tos(), smb_name, &internal_username);
+	if (client_domain[0] == '\0' && strchr(smb_name, '@')) {
+		upn_form = true;
+	}
+
+	if (upn_form) {
+		internal_username = talloc_strdup(talloc_tos(), smb_name);
+	} else {
+		was_mapped =
+		    map_username(talloc_tos(), smb_name, &internal_username);
+	}
 	if (!internal_username) {
 		return NT_STATUS_NO_MEMORY;
 	}
@@ -126,10 +136,9 @@ NTSTATUS make_user_info_map(TALLOC_CTX *mem_ctx,
 	 * non-domain member box will also map to WORKSTATION\user.
 	 * This also deals with the client passing in a "" domain */
 
-	if (!is_trusted_domain(domain) &&
+	if (!upn_form && !is_trusted_domain(domain) &&
 	    !strequal(domain, my_sam_name()) &&
-	    !strequal(domain, get_global_sam_name()))
-	{
+	    !strequal(domain, get_global_sam_name())) {
 		if (lp_map_untrusted_to_domain())
 			domain = my_sam_name();
 		else
diff --git a/source3/winbindd/winbindd_pam_auth_crap.c b/source3/winbindd/winbindd_pam_auth_crap.c
index ffbc322..9bc9424 100644
--- a/source3/winbindd/winbindd_pam_auth_crap.c
+++ b/source3/winbindd/winbindd_pam_auth_crap.c
@@ -37,6 +37,7 @@ struct tevent_req *winbindd_pam_auth_crap_send(
 	struct tevent_req *req, *subreq;
 	struct winbindd_pam_auth_crap_state *state;
 	struct winbindd_domain *domain;
+	const char *auth_domain = NULL;
 
 	req = tevent_req_create(mem_ctx, &state,
 				struct winbindd_pam_auth_crap_state);
@@ -77,14 +78,16 @@ struct tevent_req *winbindd_pam_auth_crap_send(
 		return tevent_req_post(req, ev);
 	}
 
-	if ((request->data.auth_crap.domain[0] == '\0')
-	    && lp_winbind_use_default_domain()) {
-		fstrcpy(request->data.auth_crap.domain,
-			lp_workgroup());
+	auth_domain = request->data.auth_crap.domain;
+	if (auth_domain[0] == '\0') {
+		if (strchr(request->data.auth_crap.user, '@')) {
+			auth_domain = lp_workgroup();
+		} else if (lp_winbind_use_default_domain()) {
+			fstrcpy(request->data.auth_crap.domain, lp_workgroup());
+		}
 	}
 
-	domain = find_auth_domain(
-		request->flags, request->data.auth_crap.domain);
+	domain = find_auth_domain(request->flags, auth_domain);
 	if (domain == NULL) {
 		tevent_req_nterror(req, NT_STATUS_NO_SUCH_USER);
 		return tevent_req_post(req, ev);
-- 
2.9.3



More information about the samba-technical mailing list