samba/samba-gc-lookup_unix_user_name-allow-lookup-for-own-realm.patch
DistroBaker 580979ffc9 Merged update from upstream sources
This is an automated DistroBaker update from upstream sources.
If you do not know what this is about or would like to opt out,
contact the OSCI team.

Source: https://src.fedoraproject.org/rpms/samba.git#efa876d95a02913a341dfc94008f28127956e205
2020-10-27 18:49:30 +01:00

211 lines
7.6 KiB
Diff

From 81d6949acdad70ecfb130d3286eeab1b3a51937f Mon Sep 17 00:00:00 2001
From: Alexander Bokovoy <ab@samba.org>
Date: Wed, 7 Oct 2020 19:25:24 +0300
Subject: [PATCH 1/2] cli_credentials_parse_string: fix parsing of principals
When parsing a principal-like name, user name was left with full
principal instead of taking only the left part before '@' sign.
>>> from samba import credentials
>>> t = credentials.Credentials()
>>> t.parse_string('admin@realm.test', credentials.SPECIFIED)
>>> t.get_username()
'admin@realm.test'
The issue is that cli_credentials_set_username() does a talloc_strdup()
of the argument, so we need to change order of assignment to allow
talloc_strdup() to copy the right part of the string.
Signed-off-by: Alexander Bokovoy <ab@samba.org>
---
auth/credentials/credentials.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/auth/credentials/credentials.c b/auth/credentials/credentials.c
index 77c35dd104b..06ac79058f9 100644
--- a/auth/credentials/credentials.c
+++ b/auth/credentials/credentials.c
@@ -840,11 +840,10 @@ _PUBLIC_ void cli_credentials_parse_string(struct cli_credentials *credentials,
* in order to undo the effect of
* cli_credentials_guess().
*/
- cli_credentials_set_username(credentials, uname, obtained);
- cli_credentials_set_domain(credentials, "", obtained);
-
cli_credentials_set_principal(credentials, uname, obtained);
*p = 0;
+ cli_credentials_set_username(credentials, uname, obtained);
+ cli_credentials_set_domain(credentials, "", obtained);
cli_credentials_set_realm(credentials, p+1, obtained);
return;
} else if ((p = strchr_m(uname,'\\'))
--
2.28.0
From fa38bebb993011428612d51819530218d8358f5e Mon Sep 17 00:00:00 2001
From: Alexander Bokovoy <ab@samba.org>
Date: Mon, 13 Jan 2020 16:04:20 +0200
Subject: [PATCH 2/2] lookup_name: allow lookup for own realm
When using security tab in Windows Explorer, a lookup over a trusted
forest might come as realm\name instead of NetBIOS domain name:
--------------------------------------------------------------------
[2020/01/13 11:12:39.859134, 1, pid=33253, effective(1732401004, 1732401004), real(1732401004, 0), class=rpc_parse] ../../librpc/ndr/ndr.c:471(ndr_print_function_debug)
lsa_LookupNames3: struct lsa_LookupNames3
in: struct lsa_LookupNames3
handle : *
handle: struct policy_handle
handle_type : 0x00000000 (0)
uuid : 0000000e-0000-0000-1c5e-a750e5810000
num_names : 0x00000001 (1)
names: ARRAY(1)
names: struct lsa_String
length : 0x001e (30)
size : 0x0020 (32)
string : *
string : 'ipa.test\admins'
sids : *
sids: struct lsa_TransSidArray3
count : 0x00000000 (0)
sids : NULL
level : LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY2 (6)
count : *
count : 0x00000000 (0)
lookup_options : LSA_LOOKUP_OPTION_SEARCH_ISOLATED_NAMES (0)
client_revision : LSA_CLIENT_REVISION_2 (2)
--------------------------------------------------------------------
Allow this lookup using realm to be done against primary domain.
Refactor user name parsing code to reuse cli_credentials_* API to be
consistent with other places. cli_credentials_parse_string() handles
both domain and realm-based user name variants.
Signed-off-by: Alexander Bokovoy <ab@samba.org>
---
source3/passdb/lookup_sid.c | 75 ++++++++++++++++++++++++++-----------
1 file changed, 53 insertions(+), 22 deletions(-)
diff --git a/source3/passdb/lookup_sid.c b/source3/passdb/lookup_sid.c
index 82c47b3145b..39d599fed27 100644
--- a/source3/passdb/lookup_sid.c
+++ b/source3/passdb/lookup_sid.c
@@ -29,6 +29,7 @@
#include "../libcli/security/security.h"
#include "lib/winbind_util.h"
#include "../librpc/gen_ndr/idmap.h"
+#include "auth/credentials/credentials.h"
static bool lookup_unix_user_name(const char *name, struct dom_sid *sid)
{
@@ -78,52 +79,82 @@ bool lookup_name(TALLOC_CTX *mem_ctx,
const char **ret_domain, const char **ret_name,
struct dom_sid *ret_sid, enum lsa_SidType *ret_type)
{
- char *p;
const char *tmp;
const char *domain = NULL;
const char *name = NULL;
+ const char *realm = NULL;
uint32_t rid;
struct dom_sid sid;
enum lsa_SidType type;
TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
+ struct cli_credentials *creds = NULL;
if (tmp_ctx == NULL) {
DEBUG(0, ("talloc_new failed\n"));
return false;
}
- p = strchr_m(full_name, '\\');
-
- if (p != NULL) {
- domain = talloc_strndup(tmp_ctx, full_name,
- PTR_DIFF(p, full_name));
- name = talloc_strdup(tmp_ctx, p+1);
- } else {
- domain = talloc_strdup(tmp_ctx, "");
- name = talloc_strdup(tmp_ctx, full_name);
+ creds = cli_credentials_init(tmp_ctx);
+ if (creds == NULL) {
+ DEBUG(0, ("cli_credentials_init failed\n"));
+ return false;
}
- if ((domain == NULL) || (name == NULL)) {
- DEBUG(0, ("talloc failed\n"));
- TALLOC_FREE(tmp_ctx);
+ cli_credentials_parse_string(creds, full_name, CRED_SPECIFIED);
+ name = cli_credentials_get_username(creds);
+ domain = cli_credentials_get_domain(creds);
+ realm = cli_credentials_get_realm(creds);
+
+ /* At this point we have:
+ * - name -- normal name or empty string
+ * - domain -- either NULL or domain name
+ * - realm -- either NULL or realm name
+ *
+ * domain and realm are exclusive to each other
+ * the code below in lookup_name assumes domain
+ * to be at least empty string, not NULL
+ */
+
+ if ((name == NULL) || (name[0] == '\0')) {
+ DEBUG(0, ("lookup_name with empty name, exit\n"));
return false;
}
+ if ((domain == NULL) && (realm == NULL)) {
+ domain = talloc_strdup(creds, "");
+ }
+
DEBUG(10,("lookup_name: %s => domain=[%s], name=[%s]\n",
full_name, domain, name));
DEBUG(10, ("lookup_name: flags = 0x0%x\n", flags));
- if (((flags & LOOKUP_NAME_DOMAIN) || (flags == 0)) &&
- strequal(domain, get_global_sam_name()))
- {
+ /* Windows clients may send a LookupNames request with both NetBIOS
+ * domain name- and realm-qualified user names. Thus, we need to check
+ * both against both of the SAM domain name and realm, if set. Since
+ * domain name and realm in the request are exclusive, test the one
+ * that is specified. cli_credentials_parse_string() will either set
+ * realm or wouldn't so we can use it to detect if realm was specified.
+ */
+ if ((flags & LOOKUP_NAME_DOMAIN) || (flags == 0)) {
+ const char *domain_name = realm ? realm : domain;
+ bool check_global_sam = false;
+
+ if (domain_name[0] != '\0') {
+ check_global_sam = strequal(domain_name, get_global_sam_name());
+ if (!check_global_sam && lp_realm() != NULL) {
+ check_global_sam = strequal(domain_name, lp_realm());
+ }
+ }
- /* It's our own domain, lookup the name in passdb */
- if (lookup_global_sam_name(name, flags, &rid, &type)) {
- sid_compose(&sid, get_global_sam_sid(), rid);
- goto ok;
+ if (check_global_sam) {
+ /* It's our own domain, lookup the name in passdb */
+ if (lookup_global_sam_name(name, flags, &rid, &type)) {
+ sid_compose(&sid, get_global_sam_sid(), rid);
+ goto ok;
+ }
+ TALLOC_FREE(tmp_ctx);
+ return false;
}
- TALLOC_FREE(tmp_ctx);
- return false;
}
if ((flags & LOOKUP_NAME_BUILTIN) &&
--
2.28.0