if (!lp_client_schannel()) {
/* We need to set up a creds chain on an unauthenticated netlogon pipe. */
- uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS;
+ uint32 neg_flags = NETLOGON_NEG_SELECT_AUTH2_FLAGS;
uint32 sec_chan_type = 0;
unsigned char machine_pwd[16];
/* these are the flags that ADS clients use */
#define NETLOGON_NEG_AUTH2_ADS_FLAGS (0x200fbffb | NETLOGON_NEG_ARCFOUR | NETLOGON_NEG_128BIT | NETLOGON_NEG_SCHANNEL)
+#define NETLOGON_NEG_SELECT_AUTH2_FLAGS ((lp_security() == SEC_ADS) ? NETLOGON_NEG_AUTH2_ADS_FLAGS : NETLOGON_NEG_AUTH2_FLAGS)
+
enum schannel_direction {
SENDER_IS_INITIATOR,
SENDER_IS_ACCEPTOR
char *OIDs[ASN1_MAX_OIDS];
#ifdef HAVE_KRB5
BOOL got_kerberos_mechanism = False;
+ BOOL try_kerberos = True;
#endif
rc = ldap_sasl_bind_s(ads->ldap.ld, NULL, "GSS-SPNEGO", NULL, NULL, NULL, &scred);
#endif
free(OIDs[i]);
}
- DEBUG(3,("ads_sasl_spnego_bind: got server principal name = %s\n", given_principal));
+ DEBUG(3,("ads_sasl_spnego_bind: got server principal name = %s\n",
+ (given_principal ? given_principal : NULL)));
#ifdef HAVE_KRB5
if (!(ads->auth.flags & ADS_AUTH_DISABLE_KERBEROS) &&
ADS_STATUS ads_guess_service_principal(ADS_STRUCT *ads,
char **returned_principal)
{
+ ADS_STATUS status;
char *princ = NULL;
+ char *server = NULL;
+ char *server_realm = NULL;
if (ads->server.realm && ads->server.ldap_server) {
- char *server, *server_realm;
-
server = SMB_STRDUP(ads->server.ldap_server);
server_realm = SMB_STRDUP(ads->server.realm);
- if (!server || !server_realm) {
- return ADS_ERROR(LDAP_NO_MEMORY);
- }
-
- strlower_m(server);
- strupper_m(server_realm);
- asprintf(&princ, "ldap/%s@%s", server, server_realm);
-
- SAFE_FREE(server);
- SAFE_FREE(server_realm);
-
- if (!princ) {
- return ADS_ERROR(LDAP_NO_MEMORY);
+ if (!server || !server_realm) {
+ status = ADS_ERROR(LDAP_NO_MEMORY);
+ goto fail;
}
} else if (ads->config.realm && ads->config.ldap_server_name) {
- char *server, *server_realm;
-
server = SMB_STRDUP(ads->config.ldap_server_name);
server_realm = SMB_STRDUP(ads->config.realm);
- if (!server || !server_realm) {
- return ADS_ERROR(LDAP_NO_MEMORY);
- }
-
- strlower_m(server);
- strupper_m(server_realm);
- asprintf(&princ, "ldap/%s@%s", server, server_realm);
-
- SAFE_FREE(server);
- SAFE_FREE(server_realm);
-
- if (!princ) {
- return ADS_ERROR(LDAP_NO_MEMORY);
- }
+ if (!server || !server_realm) {
+ status = ADS_ERROR(LDAP_NO_MEMORY);
+ goto fail;
+ }
}
+ strlower_m(server);
+ strupper_m(server_realm);
+ asprintf(&princ, "ldap/%s@%s", server, server_realm);
+
if (!princ) {
- return ADS_ERROR(LDAP_PARAM_ERROR);
+ status = ADS_ERROR(LDAP_PARAM_ERROR);
}
*returned_principal = princ;
+ status = ADS_SUCCESS;
+
+fail:
+ SAFE_FREE(server);
+ SAFE_FREE(server_realm);
- return ADS_SUCCESS;
+ return status;
}
#endif
free(OIDs[i]);
}
- DEBUG(3,("got principal=%s\n", principal ? principal : "<null>"));
if (got_kerberos_mechanism && (principal == NULL)) {
+ fstring dns_name;
+ fstring nb_name;
+
/*
- * 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;
+ * We didn't get a valid principal in the negTokenInit. Fake
+ * it, or fall back on NTLM. We prefer to fake it, and hit the
+ * translate_name cache to get a REAL realm name.
+ */
+ if (!(cli->desthost && translate_name(domain, dns_name,
+ nb_name) &&
+ asprintf(&principal, "host/%s@%s", cli->desthost,
+ dns_name))) {
+
+ /*
+ * 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;
+ }
+
}
+ DEBUG(3,("got principal=%s\n", principal ? principal : "<null>"));
+
fstrcpy(cli->user_name, user);
#ifdef HAVE_KRB5
ntlmssp:
- return ADS_ERROR_NT(cli_session_setup_ntlmssp(cli, user, pass, domain));
+ /* NTLM is sensitive to adding a domain with a UPN */
+ return ADS_ERROR_NT(cli_session_setup_ntlmssp(cli, user, pass,
+ (strchr(user, '@') ? NULL : domain)));
}
/****************************************************************************
asn1_push_tag(&data, ASN1_CONTEXT(3));
asn1_push_tag(&data, ASN1_SEQUENCE(0));
asn1_push_tag(&data, ASN1_CONTEXT(0));
+
+ /*
+ * @todo
+ * Windows 2008 sends a bogus principal, since this
+ * is not truly supported in the SPNEGO protocol.
+ *
+ * We should do the same, but I'm worried this will break things,
+ * such as DFS.
+ * todd.stecher@isilon.com
+ */
asn1_write_GeneralString(&data,principal);
+
asn1_pop_tag(&data);
asn1_pop_tag(&data);
asn1_pop_tag(&data);
asn1_start_tag(&data, ASN1_SEQUENCE(0));
asn1_start_tag(&data, ASN1_CONTEXT(0));
asn1_read_GeneralString(&data,principal);
+ /*
+ * Windows 2008 sends a bogus principal, since this
+ * is not truly supported in the SPNEGO protocol.
+ * todd.stecher@isilon.com
+ */
+ if (strcmp(ADS_IGNORE_PRINCIPAL, *principal) == 0)
+ SAFE_FREE(*principal);
+
asn1_end_tag(&data);
asn1_end_tag(&data);
asn1_end_tag(&data);
return NT_STATUS_OK;
}
+
+
+BOOL translate_name(const char *realm, fstring dns_domain_name,
+ fstring nb_domain_name)
+{
+ struct winbindd_request request;
+ struct winbindd_response response;
+ NSS_STATUS wb_result;
+
+ /* Call winbindd */
+
+ ZERO_STRUCT(request);
+ ZERO_STRUCT(response);
+
+ fstrcpy(request.domain_name, realm);
+ wb_result = winbindd_request_response(WINBINDD_DOMAIN_INFO,
+ &request, &response);
+
+ if (wb_result != NSS_STATUS_SUCCESS) {
+ DEBUG(0, ("Failed to translate %s\n", realm));
+ return False;
+ }
+
+ fstrcpy(dns_domain_name, response.data.domain_info.alt_name);
+ fstrcpy(nb_domain_name, response.data.domain_info.name);
+
+ return True;
+
+}
already have valid creds. If not we must set them up. */
if (cli->auth.auth_type != PIPE_AUTH_TYPE_SCHANNEL) {
- uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS;
+ uint32 neg_flags = NETLOGON_NEG_SELECT_AUTH2_FLAGS;
result = rpccli_netlogon_setup_creds(cli,
cli->cli->desthost, /* server name */
const char *password,
NTSTATUS *perr)
{
- uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS|NETLOGON_NEG_SCHANNEL;
+ uint32 neg_flags = NETLOGON_NEG_SELECT_AUTH2_FLAGS|NETLOGON_NEG_SCHANNEL;
struct rpc_pipe_client *netlogon_pipe = NULL;
struct rpc_pipe_client *result = NULL;
const char *domain,
NTSTATUS *perr)
{
- uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS|NETLOGON_NEG_SCHANNEL;
+ uint32 neg_flags = NETLOGON_NEG_SELECT_AUTH2_FLAGS|NETLOGON_NEG_SCHANNEL;
struct rpc_pipe_client *netlogon_pipe = NULL;
struct rpc_pipe_client *result = NULL;
}
if (cmd_entry->pipe_idx == PI_NETLOGON) {
- uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS;
+ uint32 neg_flags = NETLOGON_NEG_SELECT_AUTH2_FLAGS;
uint32 sec_channel_type;
uchar trust_password[16];
{
enum security_types sec;
unsigned int conn_flags = NET_FLAGS_PDC;
- uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS|NETLOGON_NEG_SCHANNEL;
+ uint32 neg_flags = NETLOGON_NEG_SELECT_AUTH2_FLAGS|NETLOGON_NEG_SCHANNEL;
struct cli_state *cli = NULL;
struct rpc_pipe_client *pipe_hnd = NULL;
struct rpc_pipe_client *netlogon_pipe = NULL;
struct cli_state *cli;
TALLOC_CTX *mem_ctx;
uint32 acb_info = ACB_WSTRUST;
- uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS|(lp_client_schannel() ? NETLOGON_NEG_SCHANNEL : 0);
+ uint32 neg_flags = NETLOGON_NEG_SELECT_AUTH2_FLAGS|(lp_client_schannel() ? NETLOGON_NEG_SCHANNEL : 0);
uint32 sec_channel_type;
struct rpc_pipe_client *pipe_hnd = NULL;
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
uchar trust_password[16];
- uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS;
+ uint32 neg_flags = NETLOGON_NEG_SELECT_AUTH2_FLAGS;
uint32 sec_channel_type = 0;
if (!secrets_fetch_trust_account_password(domain_name,
struct winbindd_cm_conn *conn;
NTSTATUS result;
- uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS;
+ uint32 neg_flags = NETLOGON_NEG_SELECT_AUTH2_FLAGS;
uint8 mach_pwd[16];
uint32 sec_chan_type;
const char *account_name;