summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/include/proto.h4
-rw-r--r--source3/libsmb/cliconnect.c41
-rw-r--r--source3/winbindd/winbindd_cm.c12
3 files changed, 31 insertions, 26 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h
index e30bb327a6..719eacb42e 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -4221,7 +4221,9 @@ NTSTATUS cli_add_event_ctx(struct cli_state *cli,
/* The following definitions come from libsmb/cliconnect.c */
ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user,
- const char *pass, const char *domain);
+ const char *pass, const char *user_domain,
+ const char * dest_realm);
+
NTSTATUS cli_session_setup(struct cli_state *cli,
const char *user,
const char *pass, int passlen,
diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c
index 751f10bc53..134c3c8a1d 100644
--- a/source3/libsmb/cliconnect.c
+++ b/source3/libsmb/cliconnect.c
@@ -785,12 +785,16 @@ static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, const char *use
/****************************************************************************
Do a spnego encrypted session setup.
+
+ user_domain: The shortname of the domain the user/machine is a member of.
+ dest_realm: The realm we're connecting to, if NULL we use our default realm.
****************************************************************************/
ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user,
- const char *pass, const char *domain)
+ const char *pass, const char *user_domain,
+ const char * dest_realm)
{
- char *principal;
+ char *principal = NULL;
char *OIDs[ASN1_MAX_OIDS];
int i;
bool got_kerberos_mechanism = False;
@@ -813,8 +817,10 @@ ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user,
/* there is 16 bytes of GUID before the real spnego packet starts */
blob = data_blob(cli->secblob.data+16, cli->secblob.length-16);
- /* the server sent us the first part of the SPNEGO exchange in the negprot
- reply */
+ /* The server sent us the first part of the SPNEGO exchange in the
+ * negprot reply. It is WRONG to depend on the principal sent in the
+ * negprot reply, but right now we do it. If we don't receive one,
+ * we try to best guess, then fall back to NTLM. */
if (!spnego_parse_negTokenInit(blob, OIDs, &principal)) {
data_blob_free(&blob);
return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER);
@@ -833,18 +839,6 @@ ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user,
DEBUG(3,("got principal=%s\n", principal ? principal : "<null>"));
- if (got_kerberos_mechanism && (principal == NULL)) {
- /*
- * It is WRONG to depend on the principal sent in the negprot
- * reply, but right now we do it. So for safety (don't
- * segfault later) disable Kerberos when no principal was
- * sent. -- VL
- */
- DEBUG(1, ("Kerberos mech was offered, but no principal was "
- "sent, disabling Kerberos\n"));
- cli->use_kerberos = False;
- }
-
fstrcpy(cli->user_name, user);
#ifdef HAVE_KRB5
@@ -897,7 +891,12 @@ ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user,
return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
}
- realm = kerberos_get_default_realm_from_ccache();
+ if (dest_realm) {
+ realm = SMB_STRDUP(dest_realm);
+ strupper_m(realm);
+ } else {
+ realm = kerberos_get_default_realm_from_ccache();
+ }
if (realm && *realm) {
if (asprintf(&principal, "%s$@%s",
machine, realm) < 0) {
@@ -914,7 +913,8 @@ ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user,
}
if (principal) {
- rc = cli_session_setup_kerberos(cli, principal, domain);
+ rc = cli_session_setup_kerberos(cli, principal,
+ dest_realm);
if (ADS_ERR_OK(rc) || !cli->fallback_after_kerberos) {
SAFE_FREE(principal);
return rc;
@@ -939,7 +939,7 @@ ntlmssp:
account[PTR_DIFF(p,user)] = '\0';
}
- return ADS_ERROR_NT(cli_session_setup_ntlmssp(cli, account, pass, domain));
+ return ADS_ERROR_NT(cli_session_setup_ntlmssp(cli, account, pass, user_domain));
}
/****************************************************************************
@@ -1031,7 +1031,8 @@ NTSTATUS cli_session_setup(struct cli_state *cli,
/* if the server supports extended security then use SPNEGO */
if (cli->capabilities & CAP_EXTENDED_SECURITY) {
- ADS_STATUS status = cli_session_setup_spnego(cli, user, pass, workgroup);
+ ADS_STATUS status = cli_session_setup_spnego(cli, user, pass,
+ workgroup, NULL);
if (!ADS_ERR_OK(status)) {
DEBUG(3, ("SPNEGO login failed: %s\n", ads_errstr(status)));
return ads_ntstatus(status);
diff --git a/source3/winbindd/winbindd_cm.c b/source3/winbindd/winbindd_cm.c
index 9bab80377a..2ee0fae6db 100644
--- a/source3/winbindd/winbindd_cm.c
+++ b/source3/winbindd/winbindd_cm.c
@@ -827,14 +827,15 @@ static NTSTATUS cm_prepare_connection(const struct winbindd_domain *domain,
(*cli)->use_kerberos = True;
DEBUG(5, ("connecting to %s from %s with kerberos principal "
- "[%s]\n", controller, global_myname(),
- machine_krb5_principal));
+ "[%s] and realm [%s]\n", controller, global_myname(),
+ machine_krb5_principal, domain->alt_name));
winbindd_set_locator_kdc_envs(domain);
ads_status = cli_session_setup_spnego(*cli,
machine_krb5_principal,
- machine_password,
+ machine_password,
+ lp_workgroup(),
domain->name);
if (!ADS_ERR_OK(ads_status)) {
@@ -855,12 +856,13 @@ static NTSTATUS cm_prepare_connection(const struct winbindd_domain *domain,
DEBUG(5, ("connecting to %s from %s with username "
"[%s]\\[%s]\n", controller, global_myname(),
- domain->name, machine_account));
+ lp_workgroup(), machine_account));
ads_status = cli_session_setup_spnego(*cli,
machine_account,
machine_password,
- domain->name);
+ lp_workgroup(),
+ NULL);
if (!ADS_ERR_OK(ads_status)) {
DEBUG(4, ("authenticated session setup failed with %s\n",
ads_errstr(ads_status)));