mirror of
https://github.com/samba-team/samba.git
synced 2025-02-08 05:57:51 +03:00
r25400: Windows 2008 (Longhorn) Interop fixes for AD specific auth2 flags,
and client fixes. Patch from Todd Stetcher <todd.stetcher@isilon.com>. (This used to be commit 8304ccba7346597425307e260e88647e49081f68)
This commit is contained in:
parent
470ebf8a35
commit
3529156971
@ -124,7 +124,7 @@ machine %s. Error was : %s.\n", dc_name, nt_errstr(result)));
|
|||||||
|
|
||||||
if (!lp_client_schannel()) {
|
if (!lp_client_schannel()) {
|
||||||
/* We need to set up a creds chain on an unauthenticated netlogon pipe. */
|
/* 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;
|
uint32 sec_chan_type = 0;
|
||||||
unsigned char machine_pwd[16];
|
unsigned char machine_pwd[16];
|
||||||
|
|
||||||
|
@ -111,6 +111,8 @@ enum RPC_PKT_TYPE {
|
|||||||
/* these are the flags that ADS clients use */
|
/* 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_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 {
|
enum schannel_direction {
|
||||||
SENDER_IS_INITIATOR,
|
SENDER_IS_INITIATOR,
|
||||||
SENDER_IS_ACCEPTOR
|
SENDER_IS_ACCEPTOR
|
||||||
|
@ -747,6 +747,7 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads)
|
|||||||
char *OIDs[ASN1_MAX_OIDS];
|
char *OIDs[ASN1_MAX_OIDS];
|
||||||
#ifdef HAVE_KRB5
|
#ifdef HAVE_KRB5
|
||||||
BOOL got_kerberos_mechanism = False;
|
BOOL got_kerberos_mechanism = False;
|
||||||
|
BOOL try_kerberos = True;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
rc = ldap_sasl_bind_s(ads->ldap.ld, NULL, "GSS-SPNEGO", NULL, NULL, NULL, &scred);
|
rc = ldap_sasl_bind_s(ads->ldap.ld, NULL, "GSS-SPNEGO", NULL, NULL, NULL, &scred);
|
||||||
@ -784,7 +785,8 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads)
|
|||||||
#endif
|
#endif
|
||||||
free(OIDs[i]);
|
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
|
#ifdef HAVE_KRB5
|
||||||
if (!(ads->auth.flags & ADS_AUTH_DISABLE_KERBEROS) &&
|
if (!(ads->auth.flags & ADS_AUTH_DISABLE_KERBEROS) &&
|
||||||
|
@ -55,57 +55,45 @@ failed:
|
|||||||
ADS_STATUS ads_guess_service_principal(ADS_STRUCT *ads,
|
ADS_STATUS ads_guess_service_principal(ADS_STRUCT *ads,
|
||||||
char **returned_principal)
|
char **returned_principal)
|
||||||
{
|
{
|
||||||
|
ADS_STATUS status;
|
||||||
char *princ = NULL;
|
char *princ = NULL;
|
||||||
|
char *server = NULL;
|
||||||
|
char *server_realm = NULL;
|
||||||
|
|
||||||
if (ads->server.realm && ads->server.ldap_server) {
|
if (ads->server.realm && ads->server.ldap_server) {
|
||||||
char *server, *server_realm;
|
|
||||||
|
|
||||||
server = SMB_STRDUP(ads->server.ldap_server);
|
server = SMB_STRDUP(ads->server.ldap_server);
|
||||||
server_realm = SMB_STRDUP(ads->server.realm);
|
server_realm = SMB_STRDUP(ads->server.realm);
|
||||||
|
|
||||||
if (!server || !server_realm) {
|
if (!server || !server_realm) {
|
||||||
return ADS_ERROR(LDAP_NO_MEMORY);
|
status = ADS_ERROR(LDAP_NO_MEMORY);
|
||||||
}
|
goto fail;
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
} else if (ads->config.realm && ads->config.ldap_server_name) {
|
} else if (ads->config.realm && ads->config.ldap_server_name) {
|
||||||
char *server, *server_realm;
|
|
||||||
|
|
||||||
server = SMB_STRDUP(ads->config.ldap_server_name);
|
server = SMB_STRDUP(ads->config.ldap_server_name);
|
||||||
server_realm = SMB_STRDUP(ads->config.realm);
|
server_realm = SMB_STRDUP(ads->config.realm);
|
||||||
|
|
||||||
if (!server || !server_realm) {
|
if (!server || !server_realm) {
|
||||||
return ADS_ERROR(LDAP_NO_MEMORY);
|
status = ADS_ERROR(LDAP_NO_MEMORY);
|
||||||
}
|
goto fail;
|
||||||
|
}
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
strlower_m(server);
|
||||||
|
strupper_m(server_realm);
|
||||||
|
asprintf(&princ, "ldap/%s@%s", server, server_realm);
|
||||||
|
|
||||||
if (!princ) {
|
if (!princ) {
|
||||||
return ADS_ERROR(LDAP_PARAM_ERROR);
|
status = ADS_ERROR(LDAP_PARAM_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
*returned_principal = princ;
|
*returned_principal = princ;
|
||||||
|
status = ADS_SUCCESS;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
SAFE_FREE(server);
|
||||||
|
SAFE_FREE(server_realm);
|
||||||
|
|
||||||
return ADS_SUCCESS;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -822,20 +822,36 @@ ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user,
|
|||||||
free(OIDs[i]);
|
free(OIDs[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG(3,("got principal=%s\n", principal ? principal : "<null>"));
|
|
||||||
|
|
||||||
if (got_kerberos_mechanism && (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
|
* We didn't get a valid principal in the negTokenInit. Fake
|
||||||
* reply, but right now we do it. So for safety (don't
|
* it, or fall back on NTLM. We prefer to fake it, and hit the
|
||||||
* segfault later) disable Kerberos when no principal was
|
* translate_name cache to get a REAL realm name.
|
||||||
* sent. -- VL
|
*/
|
||||||
*/
|
if (!(cli->desthost && translate_name(domain, dns_name,
|
||||||
DEBUG(1, ("Kerberos mech was offered, but no principal was "
|
nb_name) &&
|
||||||
"sent, disabling Kerberos\n"));
|
asprintf(&principal, "host/%s@%s", cli->desthost,
|
||||||
cli->use_kerberos = False;
|
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);
|
fstrcpy(cli->user_name, user);
|
||||||
|
|
||||||
#ifdef HAVE_KRB5
|
#ifdef HAVE_KRB5
|
||||||
@ -872,7 +888,9 @@ ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user,
|
|||||||
|
|
||||||
ntlmssp:
|
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)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
@ -52,7 +52,18 @@ DATA_BLOB spnego_gen_negTokenInit(char guid[16],
|
|||||||
asn1_push_tag(&data, ASN1_CONTEXT(3));
|
asn1_push_tag(&data, ASN1_CONTEXT(3));
|
||||||
asn1_push_tag(&data, ASN1_SEQUENCE(0));
|
asn1_push_tag(&data, ASN1_SEQUENCE(0));
|
||||||
asn1_push_tag(&data, ASN1_CONTEXT(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_write_GeneralString(&data,principal);
|
||||||
|
|
||||||
asn1_pop_tag(&data);
|
asn1_pop_tag(&data);
|
||||||
asn1_pop_tag(&data);
|
asn1_pop_tag(&data);
|
||||||
asn1_pop_tag(&data);
|
asn1_pop_tag(&data);
|
||||||
@ -154,6 +165,14 @@ BOOL spnego_parse_negTokenInit(DATA_BLOB blob,
|
|||||||
asn1_start_tag(&data, ASN1_SEQUENCE(0));
|
asn1_start_tag(&data, ASN1_SEQUENCE(0));
|
||||||
asn1_start_tag(&data, ASN1_CONTEXT(0));
|
asn1_start_tag(&data, ASN1_CONTEXT(0));
|
||||||
asn1_read_GeneralString(&data,principal);
|
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);
|
asn1_end_tag(&data);
|
||||||
asn1_end_tag(&data);
|
asn1_end_tag(&data);
|
||||||
|
@ -1714,3 +1714,32 @@ NTSTATUS get_kdc_list( const char *realm, const char *sitename, struct ip_servic
|
|||||||
|
|
||||||
return NT_STATUS_OK;
|
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;
|
||||||
|
|
||||||
|
}
|
||||||
|
@ -40,7 +40,7 @@ static NTSTATUS just_change_the_password(struct rpc_pipe_client *cli, TALLOC_CTX
|
|||||||
already have valid creds. If not we must set them up. */
|
already have valid creds. If not we must set them up. */
|
||||||
|
|
||||||
if (cli->auth.auth_type != PIPE_AUTH_TYPE_SCHANNEL) {
|
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,
|
result = rpccli_netlogon_setup_creds(cli,
|
||||||
cli->cli->desthost, /* server name */
|
cli->cli->desthost, /* server name */
|
||||||
|
@ -2633,7 +2633,7 @@ struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state
|
|||||||
const char *password,
|
const char *password,
|
||||||
NTSTATUS *perr)
|
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 *netlogon_pipe = NULL;
|
||||||
struct rpc_pipe_client *result = NULL;
|
struct rpc_pipe_client *result = NULL;
|
||||||
|
|
||||||
@ -2667,7 +2667,7 @@ struct rpc_pipe_client *cli_rpc_pipe_open_schannel(struct cli_state *cli,
|
|||||||
const char *domain,
|
const char *domain,
|
||||||
NTSTATUS *perr)
|
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 *netlogon_pipe = NULL;
|
||||||
struct rpc_pipe_client *result = NULL;
|
struct rpc_pipe_client *result = NULL;
|
||||||
|
|
||||||
|
@ -605,7 +605,7 @@ static NTSTATUS do_cmd(struct cli_state *cli,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (cmd_entry->pipe_idx == PI_NETLOGON) {
|
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;
|
uint32 sec_channel_type;
|
||||||
uchar trust_password[16];
|
uchar trust_password[16];
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ NTSTATUS net_rpc_join_ok(const char *domain, const char *server,
|
|||||||
{
|
{
|
||||||
enum security_types sec;
|
enum security_types sec;
|
||||||
unsigned int conn_flags = NET_FLAGS_PDC;
|
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 cli_state *cli = NULL;
|
||||||
struct rpc_pipe_client *pipe_hnd = NULL;
|
struct rpc_pipe_client *pipe_hnd = NULL;
|
||||||
struct rpc_pipe_client *netlogon_pipe = NULL;
|
struct rpc_pipe_client *netlogon_pipe = NULL;
|
||||||
@ -132,7 +132,7 @@ int net_rpc_join_newstyle(int argc, const char **argv)
|
|||||||
struct cli_state *cli;
|
struct cli_state *cli;
|
||||||
TALLOC_CTX *mem_ctx;
|
TALLOC_CTX *mem_ctx;
|
||||||
uint32 acb_info = ACB_WSTRUST;
|
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;
|
uint32 sec_channel_type;
|
||||||
struct rpc_pipe_client *pipe_hnd = NULL;
|
struct rpc_pipe_client *pipe_hnd = NULL;
|
||||||
|
|
||||||
|
@ -237,7 +237,7 @@ NTSTATUS rpc_samdump_internals(const DOM_SID *domain_sid,
|
|||||||
|
|
||||||
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
|
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
|
||||||
uchar trust_password[16];
|
uchar trust_password[16];
|
||||||
uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS;
|
uint32 neg_flags = NETLOGON_NEG_SELECT_AUTH2_FLAGS;
|
||||||
uint32 sec_channel_type = 0;
|
uint32 sec_channel_type = 0;
|
||||||
|
|
||||||
if (!secrets_fetch_trust_account_password(domain_name,
|
if (!secrets_fetch_trust_account_password(domain_name,
|
||||||
|
@ -2141,7 +2141,7 @@ NTSTATUS cm_connect_netlogon(struct winbindd_domain *domain,
|
|||||||
struct winbindd_cm_conn *conn;
|
struct winbindd_cm_conn *conn;
|
||||||
NTSTATUS result;
|
NTSTATUS result;
|
||||||
|
|
||||||
uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS;
|
uint32 neg_flags = NETLOGON_NEG_SELECT_AUTH2_FLAGS;
|
||||||
uint8 mach_pwd[16];
|
uint8 mach_pwd[16];
|
||||||
uint32 sec_chan_type;
|
uint32 sec_chan_type;
|
||||||
const char *account_name;
|
const char *account_name;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user