mirror of
https://github.com/samba-team/samba.git
synced 2025-08-03 04:22:09 +03:00
added trusted realm support to ADS authentication
the method used for checking if a domain is a trusted domain is very crude, we should really call a backend fn of some sort. For now I'm using winbindd to do the dirty work.
This commit is contained in:
@ -29,19 +29,21 @@
|
||||
|
||||
static BOOL check_domain_match(char *user, char *domain)
|
||||
{
|
||||
/*
|
||||
* If we aren't serving to trusted domains, we must make sure that
|
||||
* the validation request comes from an account in the same domain
|
||||
* as the Samba server
|
||||
*/
|
||||
/*
|
||||
* If we aren't serving to trusted domains, we must make sure that
|
||||
* the validation request comes from an account in the same domain
|
||||
* as the Samba server
|
||||
*/
|
||||
|
||||
if (!lp_allow_trusted_domains() &&
|
||||
!(strequal("", domain) || strequal(lp_workgroup(), domain) || is_netbios_alias_or_name(domain))) {
|
||||
DEBUG(1, ("check_domain_match: Attempt to connect as user %s from domain %s denied.\n", user, domain));
|
||||
return False;
|
||||
} else {
|
||||
return True;
|
||||
}
|
||||
if (!lp_allow_trusted_domains() &&
|
||||
!(strequal("", domain) ||
|
||||
strequal(lp_workgroup(), domain) ||
|
||||
is_netbios_alias_or_name(domain))) {
|
||||
DEBUG(1, ("check_domain_match: Attempt to connect as user %s from domain %s denied.\n", user, domain));
|
||||
return False;
|
||||
} else {
|
||||
return True;
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -215,7 +215,26 @@ BOOL make_user_info_map(auth_usersupplied_info **user_info,
|
||||
map_username(internal_username);
|
||||
|
||||
if (lp_allow_trusted_domains()) {
|
||||
domain = client_domain;
|
||||
char *user;
|
||||
/* the client could have given us a workstation name
|
||||
or other crap for the workgroup - we really need a
|
||||
way of telling if this domain name is one of our
|
||||
trusted domain names
|
||||
|
||||
The way I do it here is by checking if the fully
|
||||
qualified username exists. This is rather reliant
|
||||
on winbind, but until we have a better method this
|
||||
will have to do
|
||||
*/
|
||||
asprintf(&user, "%s%s%s",
|
||||
client_domain, lp_winbind_separator(),
|
||||
smb_name);
|
||||
if (Get_Pwnam(user) != NULL) {
|
||||
domain = client_domain;
|
||||
} else {
|
||||
domain = lp_workgroup();
|
||||
}
|
||||
free(user);
|
||||
} else {
|
||||
domain = lp_workgroup();
|
||||
}
|
||||
|
@ -60,8 +60,8 @@ static krb5_error_code krb5_mk_req2(krb5_context context,
|
||||
|
||||
if ((retval = krb5_get_credentials(context, 0,
|
||||
ccache, &creds, &credsp))) {
|
||||
DEBUG(1,("krb5_get_credentials failed (%s)\n",
|
||||
error_message(retval)));
|
||||
DEBUG(1,("krb5_get_credentials failed for %s (%s)\n",
|
||||
principal, error_message(retval)));
|
||||
goto cleanup_creds;
|
||||
}
|
||||
|
||||
|
@ -153,6 +153,7 @@ struct winbindd_methods {
|
||||
/* Structures to hold per domain information */
|
||||
struct winbindd_domain {
|
||||
fstring name; /* Domain name */
|
||||
fstring full_name; /* full Domain name (realm) */
|
||||
DOM_SID sid; /* SID for this domain */
|
||||
struct winbindd_methods *methods; /* lookup methods for
|
||||
this domain (LDAP or
|
||||
|
@ -147,6 +147,8 @@ static ADS_STRUCT *ads_cached_connection(struct winbindd_domain *domain)
|
||||
primary_realm = strdup(ads->realm);
|
||||
}
|
||||
|
||||
fstrcpy(domain->full_name, ads->server_realm);
|
||||
|
||||
domain->private = (void *)ads;
|
||||
return ads;
|
||||
}
|
||||
|
@ -55,7 +55,8 @@ struct winbindd_domain *find_domain_from_name(char *domain_name)
|
||||
/* Search through list */
|
||||
|
||||
for (tmp = domain_list; tmp != NULL; tmp = tmp->next) {
|
||||
if (strcasecmp(domain_name, tmp->name) == 0)
|
||||
if (strcasecmp(domain_name, tmp->name) == 0 ||
|
||||
strcasecmp(domain_name, tmp->full_name) == 0)
|
||||
return tmp;
|
||||
}
|
||||
|
||||
@ -164,6 +165,9 @@ BOOL get_domain_info(void)
|
||||
DEBUG(1,("Added domain %s (%s)\n",
|
||||
domain->name,
|
||||
sid_string_static(&domain->sid)));
|
||||
|
||||
/* this primes the connection */
|
||||
cache_methods.domain_sid(domain, &domain->sid);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -107,14 +107,18 @@ static int reply_spnego_kerberos(connection_struct *conn,
|
||||
|
||||
*p = 0;
|
||||
if (strcasecmp(p+1, ads->realm) != 0) {
|
||||
DEBUG(3,("Ticket for incorrect realm %s\n", p+1));
|
||||
ads_destroy(&ads);
|
||||
return ERROR_NT(NT_STATUS_LOGON_FAILURE);
|
||||
DEBUG(3,("Ticket for foreign realm %s@%s\n", client, p+1));
|
||||
if (!lp_allow_trusted_domains()) {
|
||||
return ERROR_NT(NT_STATUS_LOGON_FAILURE);
|
||||
}
|
||||
/* this gives a fully qualified user name (ie. with full realm).
|
||||
that leads to very long usernames, but what else can we do? */
|
||||
asprintf(&user, "%s%s%s", p+1, lp_winbind_separator(), client);
|
||||
} else {
|
||||
user = strdup(client);
|
||||
}
|
||||
ads_destroy(&ads);
|
||||
|
||||
user = client;
|
||||
|
||||
/* the password is good - let them in */
|
||||
pw = smb_getpwnam(user,False);
|
||||
if (!pw) {
|
||||
@ -129,6 +133,7 @@ static int reply_spnego_kerberos(connection_struct *conn,
|
||||
|
||||
sess_vuid = register_vuid(server_info, user);
|
||||
|
||||
free(user);
|
||||
free_server_info(&server_info);
|
||||
|
||||
if (sess_vuid == -1) {
|
||||
|
Reference in New Issue
Block a user