From 5d378a280f74405fccbadbfb28e1066613c76fd8 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 8 Dec 2001 11:18:56 +0000 Subject: added internal sasl/gssapi code. This means we are no longer dependent on cyrus-sasl which makes the code much less fragile. Also added code to auto-determine the server name or realm (This used to be commit 435fdf276a79c2a517adcd7726933aeef3fa924b) --- source3/libads/sasl.c | 186 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 186 insertions(+) create mode 100644 source3/libads/sasl.c (limited to 'source3/libads/sasl.c') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c new file mode 100644 index 0000000000..dd948b5d4d --- /dev/null +++ b/source3/libads/sasl.c @@ -0,0 +1,186 @@ +/* + Unix SMB/Netbios implementation. + Version 3.0 + ads sasl code + Copyright (C) Andrew Tridgell 2001 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +#ifdef HAVE_ADS + +#if USE_CYRUS_SASL +/* + this is a minimal interact function, just enough for SASL to talk + GSSAPI/kerberos to W2K + Error handling is a bit of a problem. I can't see how to get Cyrus-sasl + to give sensible errors +*/ +static int sasl_interact(LDAP *ld,unsigned flags,void *defaults,void *in) +{ + sasl_interact_t *interact = in; + + while (interact->id != SASL_CB_LIST_END) { + interact->result = strdup(""); + interact->len = strlen(interact->result); + interact++; + } + + return LDAP_SUCCESS; +} +#endif + + +#define MAX_GSS_PASSES 3 + +/* this performs a SASL/gssapi bind + we avoid using cyrus-sasl to make Samba more robust. cyrus-sasl + is very dependent on correctly configured DNS whereas + this routine is much less fragile + see RFC2078 for details +*/ +int ads_sasl_gssapi_bind(ADS_STRUCT *ads) +{ + int rc, minor_status; + gss_name_t serv_name; + gss_buffer_desc input_name; + gss_ctx_id_t context_handle; + gss_OID mech_type = GSS_C_NULL_OID; + gss_buffer_desc output_token, input_token; + OM_uint32 ret_flags, conf_state; + struct berval cred; + struct berval *scred; + int i=0; + int gss_rc; + uint8 *p; + uint32 max_msg_size; + char *sname; + + asprintf(&sname, "ldap@%s.%s", ads->ldap_server_name, ads->realm); + + input_name.value = sname; + input_name.length = strlen(input_name.value); + + rc = gss_import_name(&minor_status,&input_name,gss_nt_service_name, &serv_name); + + free(sname); + + context_handle = GSS_C_NO_CONTEXT; + + input_token.value = NULL; + input_token.length = 0; + + for (i=0; i < MAX_GSS_PASSES; i++) { + gss_rc = gss_init_sec_context(&minor_status, + GSS_C_NO_CREDENTIAL, + &context_handle, + serv_name, + mech_type, + GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG, + 0, + NULL, + &input_token, + NULL, + &output_token, + &ret_flags, + NULL); + + if (input_token.value) { + gss_release_buffer(&minor_status, &input_token); + } + + if (gss_rc && gss_rc != GSS_S_CONTINUE_NEEDED) goto failed; + + cred.bv_val = output_token.value; + cred.bv_len = output_token.length; + + rc = ldap_sasl_bind_s(ads->ld, NULL, "GSSAPI", &cred, NULL, NULL, + &scred); + + if (output_token.value) { + gss_release_buffer(&minor_status, &output_token); + } + + if (scred) { + input_token.value = scred->bv_val; + input_token.length = scred->bv_len; + } else { + input_token.value = NULL; + input_token.length = 0; + } + + if (gss_rc != GSS_S_CONTINUE_NEEDED) break; + } + + gss_release_name(&minor_status, &serv_name); + + gss_rc = gss_unwrap(&minor_status,context_handle,&input_token,&output_token, + &conf_state,NULL); + + gss_release_buffer(&minor_status, &input_token); + + p = (uint8 *)output_token.value; + + max_msg_size = (p[1]<<16) | (p[2]<<8) | p[3]; + + gss_release_buffer(&minor_status, &output_token); + + output_token.value = malloc(strlen(ads->bind_path) + 8); + p = output_token.value; + + *p++ = 1; /* no sign or seal */ + /* choose the same size as the server gave us */ + *p++ = max_msg_size>>16; + *p++ = max_msg_size>>8; + *p++ = max_msg_size; + snprintf(p, strlen(ads->bind_path)+1, "dn:%s", ads->bind_path); + p += strlen(ads->bind_path); + + output_token.length = strlen(ads->bind_path) + 8; + + gss_rc = gss_wrap(&minor_status, context_handle,0,GSS_C_QOP_DEFAULT, + &output_token, &conf_state, + &input_token); + + free(output_token.value); + + cred.bv_val = input_token.value; + cred.bv_len = input_token.length; + + rc = ldap_sasl_bind_s(ads->ld, NULL, "GSSAPI", &cred, NULL, NULL, + &scred); + + gss_release_buffer(&minor_status, &input_token); + return rc; + +failed: + return gss_rc; +} + +int ads_sasl_bind(ADS_STRUCT *ads) +{ +#if USE_CYRUS_SASL + return ldap_sasl_interactive_bind_s(ads->ld, NULL, NULL, NULL, NULL, + LDAP_SASL_QUIET, + sasl_interact, NULL); +#else + return ads_sasl_gssapi_bind(ads); +#endif +} + +#endif + -- cgit From a062e58d9e47f95ac7c66668b3cfe1f72386f6e0 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 19 Dec 2001 08:44:23 +0000 Subject: - added initial support for trusted domains in winbindd_ads - gss error code patch from a.bokovoy@sam-solutions.net - better sid dumping in ads_dump - fixed help in wbinfo (This used to be commit ee1c3e1f044b4ef62169ad74c5cac40eef81bfda) --- source3/libads/sasl.c | 53 ++++++++++++++++++++++++++++++++++----------------- 1 file changed, 36 insertions(+), 17 deletions(-) (limited to 'source3/libads/sasl.c') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index dd948b5d4d..b3610b8fdb 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -53,9 +53,9 @@ static int sasl_interact(LDAP *ld,unsigned flags,void *defaults,void *in) this routine is much less fragile see RFC2078 for details */ -int ads_sasl_gssapi_bind(ADS_STRUCT *ads) +ADS_RETURN_CODE ads_sasl_gssapi_bind(ADS_STRUCT *ads) { - int rc, minor_status; + int minor_status; gss_name_t serv_name; gss_buffer_desc input_name; gss_ctx_id_t context_handle; @@ -69,15 +69,27 @@ int ads_sasl_gssapi_bind(ADS_STRUCT *ads) uint8 *p; uint32 max_msg_size; char *sname; + ADS_RETURN_CODE rc; + krb5_principal principal; + krb5_context ctx; + krb5_enctype enc_types[] = {ENCTYPE_DES_CBC_MD5, ENCTYPE_NULL}; + gss_OID_desc nt_principal = + {10, "\052\206\110\206\367\022\001\002\002\002"}; + + /* we need to fetch a service ticket as the ldap user in the + servers realm, regardless of our realm */ + asprintf(&sname, "ldap/%s@%s", ads->ldap_server_name, ads->server_realm); + krb5_init_context(&ctx); + krb5_set_default_tgs_ktypes(ctx, enc_types); + krb5_parse_name(ctx, sname, &principal); + free(sname); + krb5_free_context(ctx); - asprintf(&sname, "ldap@%s.%s", ads->ldap_server_name, ads->realm); - - input_name.value = sname; - input_name.length = strlen(input_name.value); - - rc = gss_import_name(&minor_status,&input_name,gss_nt_service_name, &serv_name); + input_name.value = &principal; + input_name.length = sizeof(principal); - free(sname); + rc.rc = gss_import_name(&minor_status,&input_name,&nt_principal, &serv_name); + rc.error_type = False; context_handle = GSS_C_NO_CONTEXT; @@ -103,12 +115,17 @@ int ads_sasl_gssapi_bind(ADS_STRUCT *ads) gss_release_buffer(&minor_status, &input_token); } - if (gss_rc && gss_rc != GSS_S_CONTINUE_NEEDED) goto failed; + if (gss_rc && gss_rc != GSS_S_CONTINUE_NEEDED) { + rc.minor_status = minor_status; + rc.rc = gss_rc; + rc.error_type = True; + goto failed; + } cred.bv_val = output_token.value; cred.bv_len = output_token.length; - rc = ldap_sasl_bind_s(ads->ld, NULL, "GSSAPI", &cred, NULL, NULL, + rc.rc = ldap_sasl_bind_s(ads->ld, NULL, "GSSAPI", &cred, NULL, NULL, &scred); if (output_token.value) { @@ -152,7 +169,7 @@ int ads_sasl_gssapi_bind(ADS_STRUCT *ads) output_token.length = strlen(ads->bind_path) + 8; - gss_rc = gss_wrap(&minor_status, context_handle,0,GSS_C_QOP_DEFAULT, + rc.rc = gss_wrap(&minor_status, context_handle,0,GSS_C_QOP_DEFAULT, &output_token, &conf_state, &input_token); @@ -161,22 +178,24 @@ int ads_sasl_gssapi_bind(ADS_STRUCT *ads) cred.bv_val = input_token.value; cred.bv_len = input_token.length; - rc = ldap_sasl_bind_s(ads->ld, NULL, "GSSAPI", &cred, NULL, NULL, + rc.rc = ldap_sasl_bind_s(ads->ld, NULL, "GSSAPI", &cred, NULL, NULL, &scred); gss_release_buffer(&minor_status, &input_token); - return rc; failed: - return gss_rc; + return rc; } -int ads_sasl_bind(ADS_STRUCT *ads) +ADS_RETURN_CODE ads_sasl_bind(ADS_STRUCT *ads) { #if USE_CYRUS_SASL - return ldap_sasl_interactive_bind_s(ads->ld, NULL, NULL, NULL, NULL, + ADS_RETURN_CODE rc; + rc.error_type = False; + rc.rc = ldap_sasl_interactive_bind_s(ads->ld, NULL, NULL, NULL, NULL, LDAP_SASL_QUIET, sasl_interact, NULL); + return rc; #else return ads_sasl_gssapi_bind(ads); #endif -- cgit From 1f31ace6cb771d7bf0b64091fba1d24c466ad4e5 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 19 Dec 2001 12:21:12 +0000 Subject: much better ADS error handling system (This used to be commit 05a90a28843e0d69183a49a76617c5f32817df16) --- source3/libads/sasl.c | 54 +++++++++++++++++++++++++++++++-------------------- 1 file changed, 33 insertions(+), 21 deletions(-) (limited to 'source3/libads/sasl.c') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index b3610b8fdb..48873252f0 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -53,7 +53,7 @@ static int sasl_interact(LDAP *ld,unsigned flags,void *defaults,void *in) this routine is much less fragile see RFC2078 for details */ -ADS_RETURN_CODE ads_sasl_gssapi_bind(ADS_STRUCT *ads) +ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) { int minor_status; gss_name_t serv_name; @@ -65,11 +65,11 @@ ADS_RETURN_CODE ads_sasl_gssapi_bind(ADS_STRUCT *ads) struct berval cred; struct berval *scred; int i=0; - int gss_rc; + int gss_rc, rc; uint8 *p; uint32 max_msg_size; char *sname; - ADS_RETURN_CODE rc; + ADS_STATUS status; krb5_principal principal; krb5_context ctx; krb5_enctype enc_types[] = {ENCTYPE_DES_CBC_MD5, ENCTYPE_NULL}; @@ -88,8 +88,10 @@ ADS_RETURN_CODE ads_sasl_gssapi_bind(ADS_STRUCT *ads) input_name.value = &principal; input_name.length = sizeof(principal); - rc.rc = gss_import_name(&minor_status,&input_name,&nt_principal, &serv_name); - rc.error_type = False; + gss_rc = gss_import_name(&minor_status,&input_name,&nt_principal, &serv_name); + if (gss_rc) { + return ADS_ERROR_GSS(gss_rc, minor_status); + } context_handle = GSS_C_NO_CONTEXT; @@ -116,17 +118,19 @@ ADS_RETURN_CODE ads_sasl_gssapi_bind(ADS_STRUCT *ads) } if (gss_rc && gss_rc != GSS_S_CONTINUE_NEEDED) { - rc.minor_status = minor_status; - rc.rc = gss_rc; - rc.error_type = True; - goto failed; + status = ADS_ERROR_GSS(gss_rc, minor_status); + goto failed; } cred.bv_val = output_token.value; cred.bv_len = output_token.length; - rc.rc = ldap_sasl_bind_s(ads->ld, NULL, "GSSAPI", &cred, NULL, NULL, + rc = ldap_sasl_bind_s(ads->ld, NULL, "GSSAPI", &cred, NULL, NULL, &scred); + if (rc != LDAP_SASL_BIND_IN_PROGRESS) { + status = ADS_ERROR(rc); + goto failed; + } if (output_token.value) { gss_release_buffer(&minor_status, &output_token); @@ -140,13 +144,17 @@ ADS_RETURN_CODE ads_sasl_gssapi_bind(ADS_STRUCT *ads) input_token.length = 0; } - if (gss_rc != GSS_S_CONTINUE_NEEDED) break; + if (gss_rc == 0) break; } gss_release_name(&minor_status, &serv_name); gss_rc = gss_unwrap(&minor_status,context_handle,&input_token,&output_token, &conf_state,NULL); + if (gss_rc) { + status = ADS_ERROR_GSS(gss_rc, minor_status); + goto failed; + } gss_release_buffer(&minor_status, &input_token); @@ -169,33 +177,37 @@ ADS_RETURN_CODE ads_sasl_gssapi_bind(ADS_STRUCT *ads) output_token.length = strlen(ads->bind_path) + 8; - rc.rc = gss_wrap(&minor_status, context_handle,0,GSS_C_QOP_DEFAULT, + gss_rc = gss_wrap(&minor_status, context_handle,0,GSS_C_QOP_DEFAULT, &output_token, &conf_state, &input_token); + if (gss_rc) { + status = ADS_ERROR_GSS(gss_rc, minor_status); + goto failed; + } free(output_token.value); cred.bv_val = input_token.value; cred.bv_len = input_token.length; - rc.rc = ldap_sasl_bind_s(ads->ld, NULL, "GSSAPI", &cred, NULL, NULL, + rc = ldap_sasl_bind_s(ads->ld, NULL, "GSSAPI", &cred, NULL, NULL, &scred); + status = ADS_ERROR(rc); gss_release_buffer(&minor_status, &input_token); failed: - return rc; + return status; } -ADS_RETURN_CODE ads_sasl_bind(ADS_STRUCT *ads) +ADS_STATUS ads_sasl_bind(ADS_STRUCT *ads) { #if USE_CYRUS_SASL - ADS_RETURN_CODE rc; - rc.error_type = False; - rc.rc = ldap_sasl_interactive_bind_s(ads->ld, NULL, NULL, NULL, NULL, - LDAP_SASL_QUIET, - sasl_interact, NULL); - return rc; + int rc; + rc = ldap_sasl_interactive_bind_s(ads->ld, NULL, NULL, NULL, NULL, + LDAP_SASL_QUIET, + sasl_interact, NULL); + return ADS_ERROR(rc); #else return ads_sasl_gssapi_bind(ads); #endif -- cgit From cd68afe31256ad60748b34f7318a180cfc2127cc Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 30 Jan 2002 06:08:46 +0000 Subject: Removed version number from file header. Changed "SMB/Netbios" to "SMB/CIFS" in file header. (This used to be commit 6a58c9bd06d0d7502a24bf5ce5a2faf0a146edfa) --- source3/libads/sasl.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/libads/sasl.c') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 48873252f0..eb29c71fce 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -1,6 +1,5 @@ /* - Unix SMB/Netbios implementation. - Version 3.0 + Unix SMB/CIFS implementation. ads sasl code Copyright (C) Andrew Tridgell 2001 -- cgit From e90b65284812aaa5ff9e9935ce9bbad7791cbbcd Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 15 Jul 2002 10:35:28 +0000 Subject: updated the 3.0 branch from the head branch - ready for alpha18 (This used to be commit 03ac082dcb375b6f3ca3d810a6a6367542bc23ce) --- source3/libads/sasl.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/libads/sasl.c') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index eb29c71fce..1b55453cac 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -171,8 +171,7 @@ ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) *p++ = max_msg_size>>16; *p++ = max_msg_size>>8; *p++ = max_msg_size; - snprintf(p, strlen(ads->bind_path)+1, "dn:%s", ads->bind_path); - p += strlen(ads->bind_path); + snprintf(p, strlen(ads->bind_path)+4, "dn:%s", ads->bind_path); output_token.length = strlen(ads->bind_path) + 8; -- cgit From b2edf254eda92f775e7d3d9b6793b4d77f9000b6 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 17 Aug 2002 17:00:51 +0000 Subject: sync 3.0 branch with head (This used to be commit 3928578b52cfc949be5e0ef444fce1558d75f290) --- source3/libads/sasl.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'source3/libads/sasl.c') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 1b55453cac..81dedb0a81 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -77,7 +77,7 @@ ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) /* we need to fetch a service ticket as the ldap user in the servers realm, regardless of our realm */ - asprintf(&sname, "ldap/%s@%s", ads->ldap_server_name, ads->server_realm); + asprintf(&sname, "ldap/%s@%s", ads->config.ldap_server_name, ads->config.realm); krb5_init_context(&ctx); krb5_set_default_tgs_ktypes(ctx, enc_types); krb5_parse_name(ctx, sname, &principal); @@ -163,7 +163,7 @@ ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) gss_release_buffer(&minor_status, &output_token); - output_token.value = malloc(strlen(ads->bind_path) + 8); + output_token.value = malloc(strlen(ads->config.bind_path) + 8); p = output_token.value; *p++ = 1; /* no sign or seal */ @@ -171,9 +171,10 @@ ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) *p++ = max_msg_size>>16; *p++ = max_msg_size>>8; *p++ = max_msg_size; - snprintf(p, strlen(ads->bind_path)+4, "dn:%s", ads->bind_path); + snprintf(p, strlen(ads->config.bind_path)+4, "dn:%s", ads->config.bind_path); + p += strlen(ads->config.bind_path); - output_token.length = strlen(ads->bind_path) + 8; + output_token.length = strlen(ads->config.bind_path) + 8; gss_rc = gss_wrap(&minor_status, context_handle,0,GSS_C_QOP_DEFAULT, &output_token, &conf_state, -- cgit From a834a73e341059be154426390304a42e4a011f72 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 25 Sep 2002 15:19:00 +0000 Subject: sync'ing up for 3.0alpha20 release (This used to be commit 65e7b5273bb58802bf0c389b77f7fcae0a1f6139) --- source3/libads/sasl.c | 254 ++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 226 insertions(+), 28 deletions(-) (limited to 'source3/libads/sasl.c') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 81dedb0a81..f7dd01084a 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -22,37 +22,198 @@ #ifdef HAVE_ADS -#if USE_CYRUS_SASL -/* - this is a minimal interact function, just enough for SASL to talk - GSSAPI/kerberos to W2K - Error handling is a bit of a problem. I can't see how to get Cyrus-sasl - to give sensible errors +/* + perform a LDAP/SASL/SPNEGO/NTLMSSP bind (just how many layers can + we fit on one socket??) */ -static int sasl_interact(LDAP *ld,unsigned flags,void *defaults,void *in) +static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) { - sasl_interact_t *interact = in; + const char *mechs[] = {OID_NTLMSSP, NULL}; + DATA_BLOB msg1; + DATA_BLOB blob, chal1, chal2, auth; + uint8 challenge[8]; + uint8 nthash[24], lmhash[24], sess_key[16]; + uint32 neg_flags; + struct berval cred, *scred; + ADS_STATUS status; + extern pstring global_myname; + int rc; - while (interact->id != SASL_CB_LIST_END) { - interact->result = strdup(""); - interact->len = strlen(interact->result); - interact++; + if (!ads->auth.password) { + /* No password, don't segfault below... */ + return ADS_ERROR_NT(NT_STATUS_LOGON_FAILURE); } - - return LDAP_SUCCESS; + + neg_flags = NTLMSSP_NEGOTIATE_UNICODE | + NTLMSSP_NEGOTIATE_128 | + NTLMSSP_NEGOTIATE_NTLM; + + memset(sess_key, 0, 16); + + /* generate the ntlmssp negotiate packet */ + msrpc_gen(&blob, "CddB", + "NTLMSSP", + NTLMSSP_NEGOTIATE, + neg_flags, + sess_key, 16); + + /* and wrap it in a SPNEGO wrapper */ + msg1 = gen_negTokenTarg(mechs, blob); + data_blob_free(&blob); + + cred.bv_val = msg1.data; + cred.bv_len = msg1.length; + + rc = ldap_sasl_bind_s(ads->ld, NULL, "GSS-SPNEGO", &cred, NULL, NULL, &scred); + if (rc != LDAP_SASL_BIND_IN_PROGRESS) { + status = ADS_ERROR(rc); + goto failed; + } + + blob = data_blob(scred->bv_val, scred->bv_len); + + /* the server gives us back two challenges */ + if (!spnego_parse_challenge(blob, &chal1, &chal2)) { + DEBUG(3,("Failed to parse challenges\n")); + status = ADS_ERROR(LDAP_OPERATIONS_ERROR); + goto failed; + } + + data_blob_free(&blob); + + /* encrypt the password with the challenge */ + memcpy(challenge, chal1.data + 24, 8); + SMBencrypt(ads->auth.password, challenge,lmhash); + SMBNTencrypt(ads->auth.password, challenge,nthash); + + data_blob_free(&chal1); + data_blob_free(&chal2); + + /* this generates the actual auth packet */ + msrpc_gen(&blob, "CdBBUUUBd", + "NTLMSSP", + NTLMSSP_AUTH, + lmhash, 24, + nthash, 24, + lp_workgroup(), + ads->auth.user_name, + global_myname, + sess_key, 16, + neg_flags); + + /* wrap it in SPNEGO */ + auth = spnego_gen_auth(blob); + + data_blob_free(&blob); + + /* now send the auth packet and we should be done */ + cred.bv_val = auth.data; + cred.bv_len = auth.length; + + rc = ldap_sasl_bind_s(ads->ld, NULL, "GSS-SPNEGO", &cred, NULL, NULL, &scred); + + return ADS_ERROR(rc); + +failed: + return status; } + +/* + perform a LDAP/SASL/SPNEGO/KRB5 bind +*/ +static ADS_STATUS ads_sasl_spnego_krb5_bind(ADS_STRUCT *ads, const char *principal) +{ + DATA_BLOB blob; + struct berval cred, *scred; + int rc; + + blob = spnego_gen_negTokenTarg(principal, ads->auth.time_offset); + + if (!blob.data) { + return ADS_ERROR(LDAP_OPERATIONS_ERROR); + } + + /* now send the auth packet and we should be done */ + cred.bv_val = blob.data; + cred.bv_len = blob.length; + + rc = ldap_sasl_bind_s(ads->ld, NULL, "GSS-SPNEGO", &cred, NULL, NULL, &scred); + + data_blob_free(&blob); + + return ADS_ERROR(rc); +} + +/* + this performs a SASL/SPNEGO bind +*/ +static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) +{ + struct berval *scred=NULL; + int rc, i; + ADS_STATUS status; + DATA_BLOB blob; + char *principal; + char *OIDs[ASN1_MAX_OIDS]; + BOOL got_kerberos_mechanism = False; + + rc = ldap_sasl_bind_s(ads->ld, NULL, "GSS-SPNEGO", NULL, NULL, NULL, &scred); + + if (rc != LDAP_SASL_BIND_IN_PROGRESS) { + status = ADS_ERROR(rc); + goto failed; + } + + blob = data_blob(scred->bv_val, scred->bv_len); + +#if 0 + file_save("sasl_spnego.dat", blob.data, blob.length); #endif + /* the server sent us the first part of the SPNEGO exchange in the negprot + reply */ + if (!spnego_parse_negTokenInit(blob, OIDs, &principal)) { + data_blob_free(&blob); + status = ADS_ERROR(LDAP_OPERATIONS_ERROR); + goto failed; + } + data_blob_free(&blob); + + /* make sure the server understands kerberos */ + for (i=0;OIDs[i];i++) { + DEBUG(3,("got OID=%s\n", OIDs[i])); + if (strcmp(OIDs[i], OID_KERBEROS5_OLD) == 0 || + strcmp(OIDs[i], OID_KERBEROS5) == 0) { + got_kerberos_mechanism = True; + } + free(OIDs[i]); + } + DEBUG(3,("got principal=%s\n", principal)); + if (!(ads->auth.flags & ADS_AUTH_DISABLE_KERBEROS) && + got_kerberos_mechanism && ads_kinit_password(ads) == 0) { + return ads_sasl_spnego_krb5_bind(ads, principal); + } + + /* lets do NTLMSSP ... this has the big advantage that we don't need + to sync clocks, and we don't rely on special versions of the krb5 + library for HMAC_MD4 encryption */ + return ads_sasl_spnego_ntlmssp_bind(ads); + +failed: + return status; +} + +#ifdef HAVE_GSSAPI #define MAX_GSS_PASSES 3 /* this performs a SASL/gssapi bind we avoid using cyrus-sasl to make Samba more robust. cyrus-sasl is very dependent on correctly configured DNS whereas this routine is much less fragile - see RFC2078 for details + see RFC2078 and RFC2222 for details */ -ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) +static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) { int minor_status; gss_name_t serv_name; @@ -68,6 +229,7 @@ ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) uint8 *p; uint32 max_msg_size; char *sname; + unsigned sec_layer; ADS_STATUS status; krb5_principal principal; krb5_context ctx; @@ -159,22 +321,25 @@ ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) p = (uint8 *)output_token.value; + file_save("sasl_gssapi.dat", output_token.value, output_token.length); + max_msg_size = (p[1]<<16) | (p[2]<<8) | p[3]; + sec_layer = *p; gss_release_buffer(&minor_status, &output_token); output_token.value = malloc(strlen(ads->config.bind_path) + 8); p = output_token.value; - *p++ = 1; /* no sign or seal */ + *p++ = 1; /* no sign & seal selection */ /* choose the same size as the server gave us */ *p++ = max_msg_size>>16; *p++ = max_msg_size>>8; *p++ = max_msg_size; snprintf(p, strlen(ads->config.bind_path)+4, "dn:%s", ads->config.bind_path); - p += strlen(ads->config.bind_path); + p += strlen(p); - output_token.length = strlen(ads->config.bind_path) + 8; + output_token.length = PTR_DIFF(p, output_token.value); gss_rc = gss_wrap(&minor_status, context_handle,0,GSS_C_QOP_DEFAULT, &output_token, &conf_state, @@ -198,18 +363,51 @@ ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) failed: return status; } +#endif + +/* mapping between SASL mechanisms and functions */ +static struct { + const char *name; + ADS_STATUS (*fn)(ADS_STRUCT *); +} sasl_mechanisms[] = { + {"GSS-SPNEGO", ads_sasl_spnego_bind}, +#ifdef HAVE_GSSAPI + {"GSSAPI", ads_sasl_gssapi_bind}, /* doesn't work with .NET RC1. No idea why */ +#endif + {NULL, NULL} +}; ADS_STATUS ads_sasl_bind(ADS_STRUCT *ads) { -#if USE_CYRUS_SASL - int rc; - rc = ldap_sasl_interactive_bind_s(ads->ld, NULL, NULL, NULL, NULL, - LDAP_SASL_QUIET, - sasl_interact, NULL); - return ADS_ERROR(rc); -#else - return ads_sasl_gssapi_bind(ads); -#endif + const char *attrs[] = {"supportedSASLMechanisms", NULL}; + char **values; + ADS_STATUS status; + int i, j; + void *res; + + /* get a list of supported SASL mechanisms */ + status = ads_do_search(ads, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res); + if (!ADS_ERR_OK(status)) return status; + + values = ldap_get_values(ads->ld, res, "supportedSASLMechanisms"); + + /* try our supported mechanisms in order */ + for (i=0;sasl_mechanisms[i].name;i++) { + /* see if the server supports it */ + for (j=0;values && values[j];j++) { + if (strcmp(values[j], sasl_mechanisms[i].name) == 0) { + DEBUG(4,("Found SASL mechanism %s\n", values[j])); + status = sasl_mechanisms[i].fn(ads); + ldap_value_free(values); + ldap_msgfree(res); + return status; + } + } + } + + ldap_value_free(values); + ldap_msgfree(res); + return ADS_ERROR(LDAP_AUTH_METHOD_NOT_SUPPORTED); } #endif -- cgit From f2d1f19a66ebaf9b88d23c0faa2412536cc74cda Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 1 Oct 2002 18:26:00 +0000 Subject: syncing up with HEAD. Seems to be a lot of differences creeping in (i ignored the new SAMBA stuff, but the rest of this looks like it should have been merged already). (This used to be commit 3de09e5cf1f667e410ee8b9516a956860ce7290f) --- source3/libads/sasl.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source3/libads/sasl.c') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index f7dd01084a..aa7d99a5f7 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -20,7 +20,7 @@ #include "includes.h" -#ifdef HAVE_ADS +#ifdef HAVE_LDAP /* perform a LDAP/SASL/SPNEGO/NTLMSSP bind (just how many layers can @@ -190,10 +190,12 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) } DEBUG(3,("got principal=%s\n", principal)); +#ifdef HAVE_KRB5 if (!(ads->auth.flags & ADS_AUTH_DISABLE_KERBEROS) && got_kerberos_mechanism && ads_kinit_password(ads) == 0) { return ads_sasl_spnego_krb5_bind(ads, principal); } +#endif /* lets do NTLMSSP ... this has the big advantage that we don't need to sync clocks, and we don't rely on special versions of the krb5 -- cgit From f48a8615d67c2ccba3a0b65877402b24493da58e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sun, 10 Nov 2002 03:07:19 +0000 Subject: After the lord mayors parade...... Janitor for tridge :-). Jeremy. (This used to be commit 76cdfbd5107fff0c38f5fc339f1c27b33fec3a91) --- source3/libads/sasl.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'source3/libads/sasl.c') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index aa7d99a5f7..16ad397d0e 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -192,8 +192,15 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) #ifdef HAVE_KRB5 if (!(ads->auth.flags & ADS_AUTH_DISABLE_KERBEROS) && - got_kerberos_mechanism && ads_kinit_password(ads) == 0) { - return ads_sasl_spnego_krb5_bind(ads, principal); + got_kerberos_mechanism) { + status = ads_sasl_spnego_krb5_bind(ads, principal); + if (ADS_ERR_OK(status)) + return status; + if (ads_kinit_password(ads) == 0) { + status = ads_sasl_spnego_krb5_bind(ads, principal); + } + if (ADS_ERR_OK(status)) + return status; } #endif -- cgit From 2f194322d419350f35a48dff750066894d68eccf Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 12 Nov 2002 23:20:50 +0000 Subject: Removed global_myworkgroup, global_myname, global_myscope. Added liberal dashes of const. This is a rather large check-in, some things may break. It does compile though :-). Jeremy. (This used to be commit f755711df8f74f9b8e8c1a2b0d07d02a931eeb89) --- source3/libads/sasl.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/libads/sasl.c') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 16ad397d0e..7aa77bf2a2 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -36,7 +36,6 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) uint32 neg_flags; struct berval cred, *scred; ADS_STATUS status; - extern pstring global_myname; int rc; if (!ads->auth.password) { @@ -97,7 +96,7 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) nthash, 24, lp_workgroup(), ads->auth.user_name, - global_myname, + global_myname(), sess_key, 16, neg_flags); -- cgit From d1221c9b6c369113a531063737890b58d89bf6fe Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 24 Feb 2003 02:55:00 +0000 Subject: Merge from HEAD client-side authentication changes: - new kerberos code, allowing the account to change it's own password without special SD settings required - NTLMSSP client code, now seperated from cliconnect.c - NTLMv2 client code - SMB signing fixes Andrew Bartlett (This used to be commit 837680ca517982f2e5944730581a83012d4181ae) --- source3/libads/sasl.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'source3/libads/sasl.c') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 7aa77bf2a2..29d4533a54 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -241,7 +241,12 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) ADS_STATUS status; krb5_principal principal; krb5_context ctx; - krb5_enctype enc_types[] = {ENCTYPE_DES_CBC_MD5, ENCTYPE_NULL}; + krb5_enctype enc_types[] = { +#ifdef ENCTYPE_ARCFOUR_HMAC + ENCTYPE_ARCFOUR_HMAC, +#endif + ENCTYPE_DES_CBC_MD5, + ENCTYPE_NULL}; gss_OID_desc nt_principal = {10, "\052\206\110\206\367\022\001\002\002\002"}; -- cgit From 77ced5915d0b6bc07d0518ca8bd4412f3ae0e30b Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 24 Apr 2003 14:02:02 +0000 Subject: Use the kerberos error from ads_kinit_password() in the return value from our SASL code - help in printing a useful error message. Andrew Bartlett (This used to be commit 984321bfab79a1ff20b504e115e94bd6270f0196) --- source3/libads/sasl.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'source3/libads/sasl.c') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 29d4533a54..078ff826e3 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -192,14 +192,19 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) #ifdef HAVE_KRB5 if (!(ads->auth.flags & ADS_AUTH_DISABLE_KERBEROS) && got_kerberos_mechanism) { + int krb_error; status = ads_sasl_spnego_krb5_bind(ads, principal); if (ADS_ERR_OK(status)) return status; - if (ads_kinit_password(ads) == 0) { + + krb_error = ads_kinit_password(ads); + if (krb_error) { + return ADS_ERROR_KRB5(krb_error); + } else { status = ads_sasl_spnego_krb5_bind(ads, principal); - } - if (ADS_ERR_OK(status)) - return status; + if (ADS_ERR_OK(status)) + return status; + } } #endif -- cgit From 7041e295eb1167ea4d6fe8d947efb20e1e74d15d Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 24 Apr 2003 14:07:13 +0000 Subject: Revert patch - we need to try the NTLMSSP code below... Andrew Bartlett (This used to be commit 317158972ec944742ba47b213999def9abbf7452) --- source3/libads/sasl.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) (limited to 'source3/libads/sasl.c') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 078ff826e3..29d4533a54 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -192,19 +192,14 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) #ifdef HAVE_KRB5 if (!(ads->auth.flags & ADS_AUTH_DISABLE_KERBEROS) && got_kerberos_mechanism) { - int krb_error; status = ads_sasl_spnego_krb5_bind(ads, principal); if (ADS_ERR_OK(status)) return status; - - krb_error = ads_kinit_password(ads); - if (krb_error) { - return ADS_ERROR_KRB5(krb_error); - } else { + if (ads_kinit_password(ads) == 0) { status = ads_sasl_spnego_krb5_bind(ads, principal); - if (ADS_ERR_OK(status)) - return status; - } + } + if (ADS_ERR_OK(status)) + return status; } #endif -- cgit From 2cfc19f89939353e81bc0c00c3fe084a68bba20f Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 10 Jun 2003 03:47:42 +0000 Subject: added an auth flag that indicates if we should be allowed to fallback to NTLMSSP for SASL if krb5 fails. This is important as otherwise the admin may think that a join has succeeeded when kerberos is actually broken. (This used to be commit 23a6ea385c4aea208adf36f039244bee14f56a33) --- source3/libads/sasl.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'source3/libads/sasl.c') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 29d4533a54..598208b17f 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -198,8 +198,11 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) if (ads_kinit_password(ads) == 0) { status = ads_sasl_spnego_krb5_bind(ads, principal); } - if (ADS_ERR_OK(status)) + /* only fallback to NTLMSSP if allowed */ + if (ADS_ERR_OK(status) || + !(ads->auth.flags & ADS_AUTH_ALLOW_NTLMSSP)) { return status; + } } #endif -- cgit From 4632786cfb193dd80ce04206912297186e871814 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 25 Jul 2003 23:15:30 +0000 Subject: W00t! Client smb signing is now working correctly with krb5 and w2k server. Server code *should* also work (I'll check shortly). May be the odd memory leak. Problem was we (a) weren't setting signing on in the client krb5 sessionsetup code (b) we need to ask for a subkey... (c). The client and server need to ask for local and remote subkeys respectively. Thanks to Paul Nelson @ Thursby for some sage advice on this :-). Jeremy. (This used to be commit 3f9e3b60709df5ab755045a093e642510d4cde00) --- source3/libads/sasl.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libads/sasl.c') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 598208b17f..910ff3f4dc 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -124,9 +124,10 @@ static ADS_STATUS ads_sasl_spnego_krb5_bind(ADS_STRUCT *ads, const char *princip { DATA_BLOB blob; struct berval cred, *scred; + unsigned char sk[16]; int rc; - blob = spnego_gen_negTokenTarg(principal, ads->auth.time_offset); + blob = spnego_gen_negTokenTarg(principal, ads->auth.time_offset, sk); if (!blob.data) { return ADS_ERROR(LDAP_OPERATIONS_ERROR); -- cgit From aa39cc37dab9c4f8c3295d872bb8cc143890b378 Mon Sep 17 00:00:00 2001 From: Herb Lewis Date: Fri, 15 Aug 2003 04:42:05 +0000 Subject: get rid of more compiler warnings (This used to be commit 398bd14fc6e2f8ab2f34211270e179b8928a6669) --- source3/libads/sasl.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'source3/libads/sasl.c') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 910ff3f4dc..0320bb0cfc 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -60,7 +60,7 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) msg1 = gen_negTokenTarg(mechs, blob); data_blob_free(&blob); - cred.bv_val = msg1.data; + cred.bv_val = (char *)msg1.data; cred.bv_len = msg1.length; rc = ldap_sasl_bind_s(ads->ld, NULL, "GSS-SPNEGO", &cred, NULL, NULL, &scred); @@ -106,7 +106,7 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) data_blob_free(&blob); /* now send the auth packet and we should be done */ - cred.bv_val = auth.data; + cred.bv_val = (char *)auth.data; cred.bv_len = auth.length; rc = ldap_sasl_bind_s(ads->ld, NULL, "GSS-SPNEGO", &cred, NULL, NULL, &scred); @@ -134,7 +134,7 @@ static ADS_STATUS ads_sasl_spnego_krb5_bind(ADS_STRUCT *ads, const char *princip } /* now send the auth packet and we should be done */ - cred.bv_val = blob.data; + cred.bv_val = (char *)blob.data; cred.bv_len = blob.length; rc = ldap_sasl_bind_s(ads->ld, NULL, "GSS-SPNEGO", &cred, NULL, NULL, &scred); @@ -227,7 +227,7 @@ failed: */ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) { - int minor_status; + OM_uint32 minor_status; gss_name_t serv_name; gss_buffer_desc input_name; gss_ctx_id_t context_handle; @@ -328,7 +328,7 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) gss_release_name(&minor_status, &serv_name); gss_rc = gss_unwrap(&minor_status,context_handle,&input_token,&output_token, - &conf_state,NULL); + (int *)&conf_state,NULL); if (gss_rc) { status = ADS_ERROR_GSS(gss_rc, minor_status); goto failed; @@ -353,13 +353,13 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) *p++ = max_msg_size>>16; *p++ = max_msg_size>>8; *p++ = max_msg_size; - snprintf(p, strlen(ads->config.bind_path)+4, "dn:%s", ads->config.bind_path); - p += strlen(p); + snprintf((char *)p, strlen(ads->config.bind_path)+4, "dn:%s", ads->config.bind_path); + p += strlen((const char *)p); output_token.length = PTR_DIFF(p, output_token.value); gss_rc = gss_wrap(&minor_status, context_handle,0,GSS_C_QOP_DEFAULT, - &output_token, &conf_state, + &output_token, (int *)&conf_state, &input_token); if (gss_rc) { status = ADS_ERROR_GSS(gss_rc, minor_status); -- cgit From c904740e95ce416c6ee16171dd8d94cfce43b7d6 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 15 Aug 2003 21:19:34 +0000 Subject: s/OM_uint32//uint32/g (This used to be commit f8a092e7b42cd157cf86240984be40badd0afd87) --- source3/libads/sasl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libads/sasl.c') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 0320bb0cfc..5122803597 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -227,13 +227,13 @@ failed: */ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) { - OM_uint32 minor_status; + uint32 minor_status; gss_name_t serv_name; gss_buffer_desc input_name; gss_ctx_id_t context_handle; gss_OID mech_type = GSS_C_NULL_OID; gss_buffer_desc output_token, input_token; - OM_uint32 ret_flags, conf_state; + uint32 ret_flags, conf_state; struct berval cred; struct berval *scred; int i=0; -- cgit From 7d068355aae99060acac03c6633509545aa782a4 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 8 Jan 2004 08:19:18 +0000 Subject: This merges in my 'always use ADS' patch. Tested on a mix of NT and ADS domains, this patch ensures that we always use the ADS backend when security=ADS, and the remote server is capable. The routines used for this behaviour have been upgraded to modern Samba codeing standards. This is a change in behaviour for mixed mode domains, and if the trusted domain cannot be reached with our current krb5.conf file, we will show that domain as disconnected. This is in line with existing behaviour for native mode domains, and for our primary domain. As a consequence of testing this patch, I found that our kerberos error handling was well below par - we would often throw away useful error values. These changes move more routines to ADS_STATUS to return kerberos errors. Also found when valgrinding the setup, fix a few memory leaks. While sniffing the resultant connections, I noticed we would query our list of trusted domains twice - so I have reworked some of the code to avoid that. Andrew Bartlett (This used to be commit 7c34de8096b86d2869e7177420fe129bd0c7541d) --- source3/libads/sasl.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'source3/libads/sasl.c') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 5122803597..1ab71c6ee5 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -124,13 +124,13 @@ static ADS_STATUS ads_sasl_spnego_krb5_bind(ADS_STRUCT *ads, const char *princip { DATA_BLOB blob; struct berval cred, *scred; - unsigned char sk[16]; + DATA_BLOB session_key; int rc; - blob = spnego_gen_negTokenTarg(principal, ads->auth.time_offset, sk); + rc = spnego_gen_negTokenTarg(principal, ads->auth.time_offset, &blob, &session_key); - if (!blob.data) { - return ADS_ERROR(LDAP_OPERATIONS_ERROR); + if (rc) { + return ADS_ERROR_KRB5(rc); } /* now send the auth packet and we should be done */ @@ -140,6 +140,7 @@ static ADS_STATUS ads_sasl_spnego_krb5_bind(ADS_STRUCT *ads, const char *princip rc = ldap_sasl_bind_s(ads->ld, NULL, "GSS-SPNEGO", &cred, NULL, NULL, &scred); data_blob_free(&blob); + data_blob_free(&session_key); return ADS_ERROR(rc); } @@ -166,6 +167,8 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) blob = data_blob(scred->bv_val, scred->bv_len); + ber_bvfree(scred); + #if 0 file_save("sasl_spnego.dat", blob.data, blob.length); #endif @@ -196,9 +199,13 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) status = ads_sasl_spnego_krb5_bind(ads, principal); if (ADS_ERR_OK(status)) return status; - if (ads_kinit_password(ads) == 0) { + + status = ADS_ERROR_KRB5(ads_kinit_password(ads)); + + if (ADS_ERR_OK(status)) { status = ads_sasl_spnego_krb5_bind(ads, principal); } + /* only fallback to NTLMSSP if allowed */ if (ADS_ERR_OK(status) || !(ads->auth.flags & ADS_AUTH_ALLOW_NTLMSSP)) { -- cgit From 13aa693f35336db17df1d7cb55ab86efbcc230ee Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 6 May 2004 23:08:56 +0000 Subject: r533: More memory leak fixes from kawasa_r@itg.hitachi.co.jp. I need to valgrind winbindd with these in.... Jeremy. (This used to be commit fa4774b73d338a0c0df09f23cd738279bf4e71a2) --- source3/libads/sasl.c | 40 ++++++++++++++++++++++++++++++++-------- 1 file changed, 32 insertions(+), 8 deletions(-) (limited to 'source3/libads/sasl.c') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 1ab71c6ee5..971156ae61 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -29,12 +29,12 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) { const char *mechs[] = {OID_NTLMSSP, NULL}; - DATA_BLOB msg1; + DATA_BLOB msg1 = data_blob(NULL, 0); DATA_BLOB blob, chal1, chal2, auth; uint8 challenge[8]; uint8 nthash[24], lmhash[24], sess_key[16]; uint32 neg_flags; - struct berval cred, *scred; + struct berval cred, *scred = NULL; ADS_STATUS status; int rc; @@ -70,6 +70,7 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) } blob = data_blob(scred->bv_val, scred->bv_len); + ber_bvfree(scred); /* the server gives us back two challenges */ if (!spnego_parse_challenge(blob, &chal1, &chal2)) { @@ -105,15 +106,29 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) data_blob_free(&blob); + /* Remember to free the msg1 blob. The contents of this + have been copied into cred and need freeing before reassignment. */ + data_blob_free(&msg1); + /* now send the auth packet and we should be done */ cred.bv_val = (char *)auth.data; cred.bv_len = auth.length; rc = ldap_sasl_bind_s(ads->ld, NULL, "GSS-SPNEGO", &cred, NULL, NULL, &scred); + ber_bvfree(scred); + data_blob_free(&auth); + return ADS_ERROR(rc); failed: + + /* Remember to free the msg1 blob. The contents of this + have been copied into cred and need freeing. */ + data_blob_free(&msg1); + + if(scred) + ber_bvfree(scred); return status; } @@ -122,9 +137,9 @@ failed: */ static ADS_STATUS ads_sasl_spnego_krb5_bind(ADS_STRUCT *ads, const char *principal) { - DATA_BLOB blob; - struct berval cred, *scred; - DATA_BLOB session_key; + DATA_BLOB blob = data_blob(NULL, 0); + struct berval cred, *scred = NULL; + DATA_BLOB session_key = data_blob(NULL, 0); int rc; rc = spnego_gen_negTokenTarg(principal, ads->auth.time_offset, &blob, &session_key); @@ -141,6 +156,8 @@ static ADS_STATUS ads_sasl_spnego_krb5_bind(ADS_STRUCT *ads, const char *princip data_blob_free(&blob); data_blob_free(&session_key); + if(scred) + ber_bvfree(scred); return ADS_ERROR(rc); } @@ -154,7 +171,7 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) int rc, i; ADS_STATUS status; DATA_BLOB blob; - char *principal; + char *principal = NULL; char *OIDs[ASN1_MAX_OIDS]; BOOL got_kerberos_mechanism = False; @@ -197,8 +214,10 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) if (!(ads->auth.flags & ADS_AUTH_DISABLE_KERBEROS) && got_kerberos_mechanism) { status = ads_sasl_spnego_krb5_bind(ads, principal); - if (ADS_ERR_OK(status)) + if (ADS_ERR_OK(status)) { + SAFE_FREE(principal); return status; + } status = ADS_ERROR_KRB5(ads_kinit_password(ads)); @@ -209,11 +228,14 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) /* only fallback to NTLMSSP if allowed */ if (ADS_ERR_OK(status) || !(ads->auth.flags & ADS_AUTH_ALLOW_NTLMSSP)) { + SAFE_FREE(principal); return status; } } #endif + SAFE_FREE(principal); + /* lets do NTLMSSP ... this has the big advantage that we don't need to sync clocks, and we don't rely on special versions of the krb5 library for HMAC_MD4 encryption */ @@ -242,7 +264,7 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) gss_buffer_desc output_token, input_token; uint32 ret_flags, conf_state; struct berval cred; - struct berval *scred; + struct berval *scred = NULL; int i=0; int gss_rc, rc; uint8 *p; @@ -385,6 +407,8 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) gss_release_buffer(&minor_status, &input_token); failed: + if(scred) + ber_bvfree(scred); return status; } #endif -- cgit From 63378d6f0efa4612da1aecb5dee14992ac069d0f Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 7 May 2004 02:48:03 +0000 Subject: r541: fixing segfault in winbindd caused -r527 -- looks like a bug in heimdal; also initialize some pointers (This used to be commit be74e88d9a4b74fcaf25b0816e3fa8a487c91ab5) --- source3/libads/sasl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads/sasl.c') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 971156ae61..18cbb46588 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -273,7 +273,7 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) unsigned sec_layer; ADS_STATUS status; krb5_principal principal; - krb5_context ctx; + krb5_context ctx = NULL; krb5_enctype enc_types[] = { #ifdef ENCTYPE_ARCFOUR_HMAC ENCTYPE_ARCFOUR_HMAC, -- cgit From bd1fbdbd8a9d5a0cfd9789852caa7eef335767ed Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 7 Jul 2004 18:12:09 +0000 Subject: r1378: Better debugging so I don't get confused what principal we mean. Jeremy. (This used to be commit de80e8b1698d34637cf9c105a8fe02f435d83b02) --- source3/libads/sasl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libads/sasl.c') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 18cbb46588..8eb2c86bed 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -201,14 +201,14 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) /* make sure the server understands kerberos */ for (i=0;OIDs[i];i++) { - DEBUG(3,("got OID=%s\n", OIDs[i])); + DEBUG(3,("ads_sasl_spnego_bind: got OID=%s\n", OIDs[i])); if (strcmp(OIDs[i], OID_KERBEROS5_OLD) == 0 || strcmp(OIDs[i], OID_KERBEROS5) == 0) { got_kerberos_mechanism = True; } free(OIDs[i]); } - DEBUG(3,("got principal=%s\n", principal)); + DEBUG(3,("ads_sasl_spnego_bind: got server principal name =%s\n", principal)); #ifdef HAVE_KRB5 if (!(ads->auth.flags & ADS_AUTH_DISABLE_KERBEROS) && -- cgit From acf9d61421faa6c0055d57fdee7db300dc5431aa Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 7 Dec 2004 18:25:53 +0000 Subject: r4088: Get medieval on our ass about malloc.... :-). Take control of all our allocation functions so we can funnel through some well known functions. Should help greatly with malloc checking. HEAD patch to follow. Jeremy. (This used to be commit 620f2e608f70ba92f032720c031283d295c5c06a) --- source3/libads/sasl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads/sasl.c') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 8eb2c86bed..97ba9c9286 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -374,7 +374,7 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) gss_release_buffer(&minor_status, &output_token); - output_token.value = malloc(strlen(ads->config.bind_path) + 8); + output_token.value = SMB_MALLOC(strlen(ads->config.bind_path) + 8); p = output_token.value; *p++ = 1; /* no sign & seal selection */ -- cgit From 4b831f8e16d305666b0f2b018c35f5427efc21cc Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 22 Mar 2005 15:12:50 +0000 Subject: r5952: BUG 2469: patch from Jason Mader to cleanup compiler warning when not using krb5 (This used to be commit 19a639ac468237b22f16d917c0150fbf10c9623e) --- source3/libads/sasl.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source3/libads/sasl.c') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 97ba9c9286..0164b0c740 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -173,7 +173,9 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) DATA_BLOB blob; char *principal = NULL; char *OIDs[ASN1_MAX_OIDS]; +#ifdef HAVE_KRB5 BOOL got_kerberos_mechanism = False; +#endif rc = ldap_sasl_bind_s(ads->ld, NULL, "GSS-SPNEGO", NULL, NULL, NULL, &scred); @@ -202,10 +204,12 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) /* make sure the server understands kerberos */ for (i=0;OIDs[i];i++) { DEBUG(3,("ads_sasl_spnego_bind: got OID=%s\n", OIDs[i])); +#ifdef HAVE_KRB5 if (strcmp(OIDs[i], OID_KERBEROS5_OLD) == 0 || strcmp(OIDs[i], OID_KERBEROS5) == 0) { got_kerberos_mechanism = True; } +#endif free(OIDs[i]); } DEBUG(3,("ads_sasl_spnego_bind: got server principal name =%s\n", principal)); -- cgit From 9840db418bad5a39edc4a32a1786f5e2d2c9dff8 Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Thu, 31 Mar 2005 05:06:04 +0000 Subject: r6149: Fixes bugs #2498 and 2484. 1. using smbc_getxattr() et al, one may now request all access control entities in the ACL without getting all other NT attributes. 2. added the ability to exclude specified attributes from the result set provided by smbc_getxattr() et al, when requesting all attributes, all NT attributes, or all DOS attributes. 3. eliminated all compiler warnings, including when --enable-developer compiler flags are in use. removed -Wcast-qual flag from list, as that is specifically to force warnings in the case of casting away qualifiers. Note: In the process of eliminating compiler warnings, a few nasties were discovered. In the file libads/sasl.c, PRIVATE kerberos interfaces are being used; and in libsmb/clikrb5.c, both PRIAVE and DEPRECATED kerberos interfaces are being used. Someone who knows kerberos should look at these and determine if there is an alternate method of accomplishing the task. (This used to be commit 994694f7f26da5099f071e1381271a70407f33bb) --- source3/libads/sasl.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'source3/libads/sasl.c') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 0164b0c740..e657f2114e 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -18,6 +18,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#define KRB5_PRIVATE 1 /* this file uses PRIVATE interfaces! */ + #include "includes.h" #ifdef HAVE_LDAP @@ -285,7 +287,8 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) ENCTYPE_DES_CBC_MD5, ENCTYPE_NULL}; gss_OID_desc nt_principal = - {10, "\052\206\110\206\367\022\001\002\002\002"}; + {10, CONST_DISCARD(char *, + "\052\206\110\206\367\022\001\002\002\002")}; /* we need to fetch a service ticket as the ldap user in the servers realm, regardless of our realm */ -- cgit From f24d88cf9da46680d52b42b92bd484e7b09ce99b Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 31 May 2005 13:46:45 +0000 Subject: r7139: trying to reduce the number of diffs between trunk and 3.0; changing version to 3.0.20pre1 (This used to be commit 9727d05241574042dd3aa8844ae5c701d22e2da1) --- source3/libads/sasl.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'source3/libads/sasl.c') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index e657f2114e..0164b0c740 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -18,8 +18,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#define KRB5_PRIVATE 1 /* this file uses PRIVATE interfaces! */ - #include "includes.h" #ifdef HAVE_LDAP @@ -287,8 +285,7 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) ENCTYPE_DES_CBC_MD5, ENCTYPE_NULL}; gss_OID_desc nt_principal = - {10, CONST_DISCARD(char *, - "\052\206\110\206\367\022\001\002\002\002")}; + {10, "\052\206\110\206\367\022\001\002\002\002"}; /* we need to fetch a service ticket as the ldap user in the servers realm, regardless of our realm */ -- cgit From 4dec112b8a99183e1dc01fd8cacad3ece85d21da Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 3 Aug 2005 05:46:06 +0000 Subject: r8989: Fix a warning (This used to be commit 3d491ebf9ca8edae938aee08abb924905fd83deb) --- source3/libads/sasl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads/sasl.c') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 0164b0c740..8fa62a5ade 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -285,7 +285,7 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) ENCTYPE_DES_CBC_MD5, ENCTYPE_NULL}; gss_OID_desc nt_principal = - {10, "\052\206\110\206\367\022\001\002\002\002"}; + {10, CONST_DISCARD(char *, "\052\206\110\206\367\022\001\002\002\002")}; /* we need to fetch a service ticket as the ldap user in the servers realm, regardless of our realm */ -- cgit From 54abd2aa66069e6baf7769c496f46d9dba18db39 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 30 Sep 2005 17:13:37 +0000 Subject: r10656: BIG merge from trunk. Features not copied over * \PIPE\unixinfo * winbindd's {group,alias}membership new functions * winbindd's lookupsids() functionality * swat (trunk changes to be reverted as per discussion with Deryck) (This used to be commit 939c3cb5d78e3a2236209b296aa8aba8bdce32d3) --- source3/libads/sasl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads/sasl.c') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 8fa62a5ade..72cbf7264e 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -142,7 +142,7 @@ static ADS_STATUS ads_sasl_spnego_krb5_bind(ADS_STRUCT *ads, const char *princip DATA_BLOB session_key = data_blob(NULL, 0); int rc; - rc = spnego_gen_negTokenTarg(principal, ads->auth.time_offset, &blob, &session_key); + rc = spnego_gen_negTokenTarg(principal, ads->auth.time_offset, &blob, &session_key, 0); if (rc) { return ADS_ERROR_KRB5(rc); -- cgit From 97ecce03de5d4e9e9e3f9bab55af0fe171045085 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 4 Nov 2005 17:39:42 +0000 Subject: r11504: Added Andrew Bartletts removal of another NTLMSSP implementation patch. Jeremy. (This used to be commit 4591984176fd32ba25155fbc6889a1c637019a08) --- source3/libads/sasl.c | 174 ++++++++++++++++++++++++++------------------------ 1 file changed, 89 insertions(+), 85 deletions(-) (limited to 'source3/libads/sasl.c') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 72cbf7264e..44a95f5990 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -28,108 +28,112 @@ */ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) { - const char *mechs[] = {OID_NTLMSSP, NULL}; DATA_BLOB msg1 = data_blob(NULL, 0); - DATA_BLOB blob, chal1, chal2, auth; - uint8 challenge[8]; - uint8 nthash[24], lmhash[24], sess_key[16]; - uint32 neg_flags; + DATA_BLOB blob = data_blob(NULL, 0); + DATA_BLOB blob_in = data_blob(NULL, 0); + DATA_BLOB blob_out = data_blob(NULL, 0); struct berval cred, *scred = NULL; - ADS_STATUS status; int rc; + NTSTATUS nt_status; + int turn = 1; - if (!ads->auth.password) { - /* No password, don't segfault below... */ - return ADS_ERROR_NT(NT_STATUS_LOGON_FAILURE); - } - - neg_flags = NTLMSSP_NEGOTIATE_UNICODE | - NTLMSSP_NEGOTIATE_128 | - NTLMSSP_NEGOTIATE_NTLM; - - memset(sess_key, 0, 16); - - /* generate the ntlmssp negotiate packet */ - msrpc_gen(&blob, "CddB", - "NTLMSSP", - NTLMSSP_NEGOTIATE, - neg_flags, - sess_key, 16); + struct ntlmssp_state *ntlmssp_state; - /* and wrap it in a SPNEGO wrapper */ - msg1 = gen_negTokenTarg(mechs, blob); - data_blob_free(&blob); - - cred.bv_val = (char *)msg1.data; - cred.bv_len = msg1.length; - - rc = ldap_sasl_bind_s(ads->ld, NULL, "GSS-SPNEGO", &cred, NULL, NULL, &scred); - if (rc != LDAP_SASL_BIND_IN_PROGRESS) { - status = ADS_ERROR(rc); - goto failed; + if (!NT_STATUS_IS_OK(nt_status = ntlmssp_client_start(&ntlmssp_state))) { + return ADS_ERROR_NT(nt_status); } + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_SIGN; - blob = data_blob(scred->bv_val, scred->bv_len); - ber_bvfree(scred); - - /* the server gives us back two challenges */ - if (!spnego_parse_challenge(blob, &chal1, &chal2)) { - DEBUG(3,("Failed to parse challenges\n")); - status = ADS_ERROR(LDAP_OPERATIONS_ERROR); - goto failed; + if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_username(ntlmssp_state, ads->auth.user_name))) { + return ADS_ERROR_NT(nt_status); + } + if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_domain(ntlmssp_state, ads->auth.realm))) { + return ADS_ERROR_NT(nt_status); + } + if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_password(ntlmssp_state, ads->auth.password))) { + return ADS_ERROR_NT(nt_status); } - data_blob_free(&blob); - - /* encrypt the password with the challenge */ - memcpy(challenge, chal1.data + 24, 8); - SMBencrypt(ads->auth.password, challenge,lmhash); - SMBNTencrypt(ads->auth.password, challenge,nthash); - - data_blob_free(&chal1); - data_blob_free(&chal2); - - /* this generates the actual auth packet */ - msrpc_gen(&blob, "CdBBUUUBd", - "NTLMSSP", - NTLMSSP_AUTH, - lmhash, 24, - nthash, 24, - lp_workgroup(), - ads->auth.user_name, - global_myname(), - sess_key, 16, - neg_flags); - - /* wrap it in SPNEGO */ - auth = spnego_gen_auth(blob); + blob_in = data_blob(NULL, 0); + + do { + nt_status = ntlmssp_update(ntlmssp_state, + blob_in, &blob_out); + data_blob_free(&blob_in); + if ((NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED) + || NT_STATUS_IS_OK(nt_status)) + && blob_out.length) { + if (turn == 1) { + /* and wrap it in a SPNEGO wrapper */ + msg1 = gen_negTokenInit(OID_NTLMSSP, blob_out); + } else { + /* wrap it in SPNEGO */ + msg1 = spnego_gen_auth(blob_out); + } - data_blob_free(&blob); + data_blob_free(&blob_out); - /* Remember to free the msg1 blob. The contents of this - have been copied into cred and need freeing before reassignment. */ - data_blob_free(&msg1); + cred.bv_val = (char *)msg1.data; + cred.bv_len = msg1.length; + scred = NULL; + rc = ldap_sasl_bind_s(ads->ld, NULL, "GSS-SPNEGO", &cred, NULL, NULL, &scred); + data_blob_free(&msg1); + if ((rc != LDAP_SASL_BIND_IN_PROGRESS) && (rc != 0)) { + if (scred) { + ber_bvfree(scred); + } - /* now send the auth packet and we should be done */ - cred.bv_val = (char *)auth.data; - cred.bv_len = auth.length; + ntlmssp_end(&ntlmssp_state); + return ADS_ERROR(rc); + } + if (scred) { + blob = data_blob(scred->bv_val, scred->bv_len); + ber_bvfree(scred); + } else { + blob = data_blob(NULL, 0); + } - rc = ldap_sasl_bind_s(ads->ld, NULL, "GSS-SPNEGO", &cred, NULL, NULL, &scred); + } else { - ber_bvfree(scred); - data_blob_free(&auth); + ntlmssp_end(&ntlmssp_state); + data_blob_free(&blob_out); + return ADS_ERROR_NT(nt_status); + } + + if ((turn == 1) && + (rc == LDAP_SASL_BIND_IN_PROGRESS)) { + DATA_BLOB tmp_blob = data_blob(NULL, 0); + /* the server might give us back two challenges */ + if (!spnego_parse_challenge(blob, &blob_in, + &tmp_blob)) { + + ntlmssp_end(&ntlmssp_state); + data_blob_free(&blob); + DEBUG(3,("Failed to parse challenges\n")); + return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER); + } + data_blob_free(&tmp_blob); + } else if (rc == LDAP_SASL_BIND_IN_PROGRESS) { + if (!spnego_parse_auth_response(blob, nt_status, + &blob_in)) { + + ntlmssp_end(&ntlmssp_state); + data_blob_free(&blob); + DEBUG(3,("Failed to parse auth response\n")); + return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER); + } + } + data_blob_free(&blob); + data_blob_free(&blob_out); + turn++; + } while (rc == LDAP_SASL_BIND_IN_PROGRESS && !NT_STATUS_IS_OK(nt_status)); - return ADS_ERROR(rc); - -failed: + /* we have a reference conter on ntlmssp_state, if we are signing + then the state will be kept by the signing engine */ - /* Remember to free the msg1 blob. The contents of this - have been copied into cred and need freeing. */ - data_blob_free(&msg1); + ntlmssp_end(&ntlmssp_state); - if(scred) - ber_bvfree(scred); - return status; + return ADS_ERROR(rc); } /* -- cgit From 14b16baf69aff50dbeb537a7d09236ca66a6568d Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Wed, 25 Jan 2006 21:25:25 +0000 Subject: r13137: make cleare where long ifdefs ends (This used to be commit 58e48fef450f71ac15219f73897801c5a66a2c44) --- source3/libads/sasl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libads/sasl.c') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 44a95f5990..f6adfb5108 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -419,7 +419,7 @@ failed: ber_bvfree(scred); return status; } -#endif +#endif /* HAVE_GGSAPI */ /* mapping between SASL mechanisms and functions */ static struct { @@ -466,5 +466,5 @@ ADS_STATUS ads_sasl_bind(ADS_STRUCT *ads) return ADS_ERROR(LDAP_AUTH_METHOD_NOT_SUPPORTED); } -#endif +#endif /* HAVE_LDAP */ -- cgit From 0af1500fc0bafe61019f1b2ab1d9e1d369221240 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 3 Feb 2006 22:19:41 +0000 Subject: r13316: Let the carnage begin.... Sync with trunk as off r13315 (This used to be commit 17e63ac4ed8325c0d44fe62b2442449f3298559f) --- source3/libads/sasl.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) (limited to 'source3/libads/sasl.c') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index f6adfb5108..d8d33a924f 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -294,16 +294,28 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) /* we need to fetch a service ticket as the ldap user in the servers realm, regardless of our realm */ asprintf(&sname, "ldap/%s@%s", ads->config.ldap_server_name, ads->config.realm); - krb5_init_context(&ctx); - krb5_set_default_tgs_ktypes(ctx, enc_types); - krb5_parse_name(ctx, sname, &principal); + + initialize_krb5_error_table(); + status = ADS_ERROR_KRB5(krb5_init_context(&ctx)); + if (!ADS_ERR_OK(status)) { + return status; + } + status = ADS_ERROR_KRB5(krb5_set_default_tgs_ktypes(ctx, enc_types)); + if (!ADS_ERR_OK(status)) { + return status; + } + status = ADS_ERROR_KRB5(krb5_parse_name(ctx, sname, &principal)); + if (!ADS_ERR_OK(status)) { + return status; + } + free(sname); krb5_free_context(ctx); input_name.value = &principal; input_name.length = sizeof(principal); - gss_rc = gss_import_name(&minor_status,&input_name,&nt_principal, &serv_name); + gss_rc = gss_import_name(&minor_status, &input_name, &nt_principal, &serv_name); if (gss_rc) { return ADS_ERROR_GSS(gss_rc, minor_status); } @@ -375,8 +387,9 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) p = (uint8 *)output_token.value; +#if 0 file_save("sasl_gssapi.dat", output_token.value, output_token.length); - +#endif max_msg_size = (p[1]<<16) | (p[2]<<8) | p[3]; sec_layer = *p; -- cgit From b68b05854ff5a7e75953462eba74f97753428ef1 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 24 Apr 2006 15:57:54 +0000 Subject: r15210: Add wrapper functions smb_krb5_parse_name, smb_krb5_unparse_name, smb_krb5_parse_name_norealm_conv that pull/push from unix charset to utf8 (which krb5 uses on the wire). This should fix issues when the unix charset is not compatible with or set to utf8. Jeremy. (This used to be commit 37ab42afbc9a79cf5b04ce6a1bf4060e9c961199) --- source3/libads/sasl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads/sasl.c') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index d8d33a924f..a12af43eb3 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -304,7 +304,7 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) if (!ADS_ERR_OK(status)) { return status; } - status = ADS_ERROR_KRB5(krb5_parse_name(ctx, sname, &principal)); + status = ADS_ERROR_KRB5(smb_krb5_parse_name(ctx, sname, &principal)); if (!ADS_ERR_OK(status)) { return status; } -- cgit From fbdcf2663b56007a438ac4f0d8d82436b1bfe688 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 11 Jul 2006 18:01:26 +0000 Subject: r16945: Sync trunk -> 3.0 for 3.0.24 code. Still need to do the upper layer directories but this is what everyone is waiting for.... Jeremy. (This used to be commit 9dafb7f48ca3e7af956b0a7d1720c2546fc4cfb8) --- source3/libads/sasl.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'source3/libads/sasl.c') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index a12af43eb3..3c0bea93d6 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -278,7 +278,6 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) uint8 *p; uint32 max_msg_size; char *sname; - unsigned sec_layer; ADS_STATUS status; krb5_principal principal; krb5_context ctx = NULL; @@ -391,7 +390,6 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) file_save("sasl_gssapi.dat", output_token.value, output_token.length); #endif max_msg_size = (p[1]<<16) | (p[2]<<8) | p[3]; - sec_layer = *p; gss_release_buffer(&minor_status, &output_token); -- cgit From 0362fde476733bacfd7aa2d5eba24597a7f4fd56 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 29 Aug 2006 00:53:28 +0000 Subject: r17899: Fix Stanford checker bug - possible null deref. Jeremy. (This used to be commit e77949175144cbe4cfa58788d13acc704eebc251) --- source3/libads/sasl.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'source3/libads/sasl.c') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 3c0bea93d6..b2613071b7 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -276,7 +276,7 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) int i=0; int gss_rc, rc; uint8 *p; - uint32 max_msg_size; + uint32 max_msg_size = 0; char *sname; ADS_STATUS status; krb5_principal principal; @@ -389,7 +389,10 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) #if 0 file_save("sasl_gssapi.dat", output_token.value, output_token.length); #endif - max_msg_size = (p[1]<<16) | (p[2]<<8) | p[3]; + + if (p) { + max_msg_size = (p[1]<<16) | (p[2]<<8) | p[3]; + } gss_release_buffer(&minor_status, &output_token); -- cgit From ee0e397d6f003c583768803aa27716b2b7a23981 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 3 Sep 2006 21:07:16 +0000 Subject: r18019: Fix a C++ warnings: Don't use void * in libads/ for LDAPMessage anymore. Compiled it on systems with and without LDAP, I hope it does not break the build farm too badly. If it does, I'll fix it tomorrow. Volker (This used to be commit b2ff9680ebe0979fbeef7f2dabc2e3f27c959d11) --- source3/libads/sasl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads/sasl.c') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index b2613071b7..fe31ef94bb 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -453,7 +453,7 @@ ADS_STATUS ads_sasl_bind(ADS_STRUCT *ads) char **values; ADS_STATUS status; int i, j; - void *res; + LDAPMessage *res; /* get a list of supported SASL mechanisms */ status = ads_do_search(ads, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res); -- cgit From f8a17bd8bdbb52b200671e7ed52ffd982419f3f6 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 4 Sep 2006 19:47:48 +0000 Subject: r18047: More C++ stuff (This used to be commit 86f4ca84f2df2aa8977eb24828e3aa840dda7201) --- source3/libads/sasl.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libads/sasl.c') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index fe31ef94bb..c3f496938a 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -348,7 +348,7 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) goto failed; } - cred.bv_val = output_token.value; + cred.bv_val = (char *)output_token.value; cred.bv_len = output_token.length; rc = ldap_sasl_bind_s(ads->ld, NULL, "GSSAPI", &cred, NULL, NULL, @@ -397,7 +397,7 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) gss_release_buffer(&minor_status, &output_token); output_token.value = SMB_MALLOC(strlen(ads->config.bind_path) + 8); - p = output_token.value; + p = (uint8 *)output_token.value; *p++ = 1; /* no sign & seal selection */ /* choose the same size as the server gave us */ @@ -419,7 +419,7 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) free(output_token.value); - cred.bv_val = input_token.value; + cred.bv_val = (char *)input_token.value; cred.bv_len = input_token.length; rc = ldap_sasl_bind_s(ads->ld, NULL, "GSSAPI", &cred, NULL, NULL, -- cgit From dc06fda6c7b87a3e2a8521269f4fca3f70969281 Mon Sep 17 00:00:00 2001 From: Herb Lewis Date: Tue, 12 Dec 2006 20:27:01 +0000 Subject: r20132: get rid of defined but not used warning - static function only used inside the #ifdef HAVE_KRB5 (This used to be commit c6cdf76c5809b4a4b145acb7dd4a695aaf7fcd28) --- source3/libads/sasl.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/libads/sasl.c') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index c3f496938a..7d1fd0d1a8 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -136,6 +136,7 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) return ADS_ERROR(rc); } +#ifdef HAVE_KRB5 /* perform a LDAP/SASL/SPNEGO/KRB5 bind */ @@ -165,6 +166,7 @@ static ADS_STATUS ads_sasl_spnego_krb5_bind(ADS_STRUCT *ads, const char *princip return ADS_ERROR(rc); } +#endif /* this performs a SASL/SPNEGO bind -- cgit From 76cdf68ee9f4982f1b847023818641cf4603dfd1 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 29 Dec 2006 09:18:06 +0000 Subject: r20403: Cleaning out my Samba 3.0 tree: As discussed with jerry at the CIFS conf: overriding the administrator's wishes from the krb5.conf has only every given me segfaults. We suggest leaving this up to the defaults from the libraries anyway. Andrew Bartlett (This used to be commit 0b72c04906b1c25e80b217a8f34fd3a8e756b9ca) --- source3/libads/sasl.c | 11 ----------- 1 file changed, 11 deletions(-) (limited to 'source3/libads/sasl.c') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 7d1fd0d1a8..d1699dbab7 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -42,7 +42,6 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) if (!NT_STATUS_IS_OK(nt_status = ntlmssp_client_start(&ntlmssp_state))) { return ADS_ERROR_NT(nt_status); } - ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_SIGN; if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_username(ntlmssp_state, ads->auth.user_name))) { return ADS_ERROR_NT(nt_status); @@ -283,12 +282,6 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) ADS_STATUS status; krb5_principal principal; krb5_context ctx = NULL; - krb5_enctype enc_types[] = { -#ifdef ENCTYPE_ARCFOUR_HMAC - ENCTYPE_ARCFOUR_HMAC, -#endif - ENCTYPE_DES_CBC_MD5, - ENCTYPE_NULL}; gss_OID_desc nt_principal = {10, CONST_DISCARD(char *, "\052\206\110\206\367\022\001\002\002\002")}; @@ -301,10 +294,6 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) if (!ADS_ERR_OK(status)) { return status; } - status = ADS_ERROR_KRB5(krb5_set_default_tgs_ktypes(ctx, enc_types)); - if (!ADS_ERR_OK(status)) { - return status; - } status = ADS_ERROR_KRB5(smb_krb5_parse_name(ctx, sname, &principal)); if (!ADS_ERR_OK(status)) { return status; -- cgit From 594ab518a581f3728c82bdb9cf563e5fa449c0e1 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Mon, 29 Jan 2007 21:15:25 +0000 Subject: r21046: Backing out svn r20403 (Andrew's krb5 ticket cleanup as this is causing the WRONG_PASSWORD error in the SetUserInfo() call during net ads join). We are now back to always list RC4-HMAC first if supported by the krb5 libraries. (This used to be commit 4fb57bce87588ac4898588ea4988eadff3a7f435) --- source3/libads/sasl.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'source3/libads/sasl.c') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index d1699dbab7..7d1fd0d1a8 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -42,6 +42,7 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) if (!NT_STATUS_IS_OK(nt_status = ntlmssp_client_start(&ntlmssp_state))) { return ADS_ERROR_NT(nt_status); } + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_SIGN; if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_username(ntlmssp_state, ads->auth.user_name))) { return ADS_ERROR_NT(nt_status); @@ -282,6 +283,12 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) ADS_STATUS status; krb5_principal principal; krb5_context ctx = NULL; + krb5_enctype enc_types[] = { +#ifdef ENCTYPE_ARCFOUR_HMAC + ENCTYPE_ARCFOUR_HMAC, +#endif + ENCTYPE_DES_CBC_MD5, + ENCTYPE_NULL}; gss_OID_desc nt_principal = {10, CONST_DISCARD(char *, "\052\206\110\206\367\022\001\002\002\002")}; @@ -294,6 +301,10 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) if (!ADS_ERR_OK(status)) { return status; } + status = ADS_ERROR_KRB5(krb5_set_default_tgs_ktypes(ctx, enc_types)); + if (!ADS_ERR_OK(status)) { + return status; + } status = ADS_ERROR_KRB5(smb_krb5_parse_name(ctx, sname, &principal)); if (!ADS_ERR_OK(status)) { return status; -- cgit From 69cee2a3ec4f39aab83a8cbf55307df182bf3065 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 8 Feb 2007 17:02:39 +0000 Subject: r21240: Fix longstanding Bug #4009. For the winbind cached ADS LDAP connection handling (ads_cached_connection()) we were (incorrectly) assuming that the service ticket lifetime equaled the tgt lifetime. For setups where the service ticket just lives 10 minutes, we were leaving hundreds of LDAP connections in CLOSE_WAIT state, until we fail to service entirely with "Too many open files". Also sequence_number() in winbindd_ads.c needs to delete the cached LDAP connection after the ads_do_search_retry() has failed to submit the search request (although the bind succeeded (returning an expired service ticket that we cannot delete from the memory cred cache - this will get fixed later)). Guenther (This used to be commit 7e1a84b7226fb8dcd5d34c64a3478a6d886a9a91) --- source3/libads/sasl.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'source3/libads/sasl.c') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 7d1fd0d1a8..61fd54da1d 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -147,7 +147,8 @@ static ADS_STATUS ads_sasl_spnego_krb5_bind(ADS_STRUCT *ads, const char *princip DATA_BLOB session_key = data_blob(NULL, 0); int rc; - rc = spnego_gen_negTokenTarg(principal, ads->auth.time_offset, &blob, &session_key, 0); + rc = spnego_gen_negTokenTarg(principal, ads->auth.time_offset, &blob, &session_key, 0, + &ads->auth.tgs_expire); if (rc) { return ADS_ERROR_KRB5(rc); @@ -218,7 +219,7 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) #endif free(OIDs[i]); } - DEBUG(3,("ads_sasl_spnego_bind: got server principal name =%s\n", principal)); + DEBUG(3,("ads_sasl_spnego_bind: got server principal name = %s\n", principal)); #ifdef HAVE_KRB5 if (!(ads->auth.flags & ADS_AUTH_DISABLE_KERBEROS) && @@ -229,6 +230,9 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) return status; } + DEBUG(10,("ads_sasl_spnego_krb5_bind failed with: %s, " + "calling kinit\n", ads_errstr(status))); + status = ADS_ERROR_KRB5(ads_kinit_password(ads)); if (ADS_ERR_OK(status)) { -- cgit From 763a553046bfb6e28998adfb671c473485e9f5dc Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Sat, 10 Feb 2007 20:29:09 +0000 Subject: r21273: * Protect the sasl bind against a NULL principal string in the SPNEGO negTokenInit (This used to be commit fe70c224964bf15d626bfd4e0cc6d060e45bba87) --- source3/libads/sasl.c | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) (limited to 'source3/libads/sasl.c') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 61fd54da1d..812f3961f1 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -223,7 +223,35 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) #ifdef HAVE_KRB5 if (!(ads->auth.flags & ADS_AUTH_DISABLE_KERBEROS) && - got_kerberos_mechanism) { + got_kerberos_mechanism) + { + /* I've seen a child Windows 2000 domain not send + the principal name back in the first round of + the SASL bind reply. So we guess based on server + name and realm. --jerry */ + if ( !principal ) { + 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( &principal, "ldap/%s@%s", server, server_realm ); + + SAFE_FREE( server ); + SAFE_FREE( server_realm ); + + if ( !principal ) + return ADS_ERROR(LDAP_NO_MEMORY); + } + + } + status = ads_sasl_spnego_krb5_bind(ads, principal); if (ADS_ERR_OK(status)) { SAFE_FREE(principal); -- cgit From 7d77dd9db600a4b2ee11913bf8169224c2d9424a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 15 Mar 2007 21:53:53 +0000 Subject: r21847: Fix memory leaks in error paths (and in main code path in one case...) in sasl bind. Wonder why coverity didn't find these ? Jeremy. (This used to be commit 89bdd30e4b2bb9dbc2ab57c54be8c6d01cae5a26) --- source3/libads/sasl.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) (limited to 'source3/libads/sasl.c') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 812f3961f1..bdc4f2e276 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -311,9 +311,9 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) int gss_rc, rc; uint8 *p; uint32 max_msg_size = 0; - char *sname; + char *sname = NULL; ADS_STATUS status; - krb5_principal principal; + krb5_principal principal = NULL; krb5_context ctx = NULL; krb5_enctype enc_types[] = { #ifdef ENCTYPE_ARCFOUR_HMAC @@ -331,24 +331,32 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) initialize_krb5_error_table(); status = ADS_ERROR_KRB5(krb5_init_context(&ctx)); if (!ADS_ERR_OK(status)) { + SAFE_FREE(sname); return status; } status = ADS_ERROR_KRB5(krb5_set_default_tgs_ktypes(ctx, enc_types)); if (!ADS_ERR_OK(status)) { + SAFE_FREE(sname); + krb5_free_context(ctx); return status; } status = ADS_ERROR_KRB5(smb_krb5_parse_name(ctx, sname, &principal)); if (!ADS_ERR_OK(status)) { + SAFE_FREE(sname); + krb5_free_context(ctx); return status; } - free(sname); - krb5_free_context(ctx); - input_name.value = &principal; input_name.length = sizeof(principal); gss_rc = gss_import_name(&minor_status, &input_name, &nt_principal, &serv_name); + + /* We've finished with principal and sname now. */ + SAFE_FREE(sname); + krb5_free_principal(ctx, principal); + krb5_free_context(ctx); + if (gss_rc) { return ADS_ERROR_GSS(gss_rc, minor_status); } -- cgit From b74cb6740f78b9b2c02eb3bc0afb1b7378ac0bc2 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 15 Mar 2007 22:11:13 +0000 Subject: r21850: After Jerry explained to me the HORRIBLE way in which the MIT gss libraries *SUCK*, move the frees to the end of the function so MIT doesn't segfault..... Add a comment so that another engineer knows why I did this. Jeremy. (This used to be commit 1a2be06d4a1131952a97f94b05ae69b1dce4c300) --- source3/libads/sasl.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) (limited to 'source3/libads/sasl.c') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index bdc4f2e276..013985a121 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -352,12 +352,19 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) gss_rc = gss_import_name(&minor_status, &input_name, &nt_principal, &serv_name); - /* We've finished with principal and sname now. */ + /* + * The MIT libraries have a *HORRIBLE* bug - input_value.value needs + * to point to the *address* of the krb5_principal, and the gss libraries + * to a shallow copy of the krb5_principal pointer - so we need to keep + * the krb5_principal around until we do the gss_release_name. MIT *SUCKS* ! + * Just one more way in which MIT engineers screwed me over.... JRA. + */ + SAFE_FREE(sname); - krb5_free_principal(ctx, principal); - krb5_free_context(ctx); if (gss_rc) { + krb5_free_principal(ctx, principal); + krb5_free_context(ctx); return ADS_ERROR_GSS(gss_rc, minor_status); } @@ -415,8 +422,6 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) if (gss_rc == 0) break; } - gss_release_name(&minor_status, &serv_name); - gss_rc = gss_unwrap(&minor_status,context_handle,&input_token,&output_token, (int *)&conf_state,NULL); if (gss_rc) { @@ -471,6 +476,11 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) gss_release_buffer(&minor_status, &input_token); failed: + + gss_release_name(&minor_status, &serv_name); + krb5_free_principal(ctx, principal); + krb5_free_context(ctx); + if(scred) ber_bvfree(scred); return status; -- cgit From 98c300ab90cc7775818c333931f1f923f9eb7763 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 4 Apr 2007 14:50:39 +0000 Subject: r22078: fix memory leak in not often used code, we only use it if the server doesn't support GSS-SPNEGO in SASL can someone please review this, maybe it's also for 3.0.25 metze (This used to be commit 8c6930b7013b185af0530b04a7d5a49bc2ce7831) --- source3/libads/sasl.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libads/sasl.c') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 013985a121..ce000a1306 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -301,7 +301,7 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) uint32 minor_status; gss_name_t serv_name; gss_buffer_desc input_name; - gss_ctx_id_t context_handle; + gss_ctx_id_t context_handle = GSS_C_NO_CONTEXT; gss_OID mech_type = GSS_C_NULL_OID; gss_buffer_desc output_token, input_token; uint32 ret_flags, conf_state; @@ -368,8 +368,6 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) return ADS_ERROR_GSS(gss_rc, minor_status); } - context_handle = GSS_C_NO_CONTEXT; - input_token.value = NULL; input_token.length = 0; @@ -478,6 +476,8 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) failed: gss_release_name(&minor_status, &serv_name); + if (context_handle != GSS_C_NO_CONTEXT) + gss_delete_sec_context(&min_status, &context_handle, GSS_C_NO_BUFFER); krb5_free_principal(ctx, principal); krb5_free_context(ctx); -- cgit From 4899c6b8069885df517de00b9608adb70c4a58be Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 4 Apr 2007 17:38:12 +0000 Subject: r22079: Tsk, tsk, Metze didn't compile before check-in :-). Merge the memory leak fix (with fix :-) to 3.0.25. Jeremy. (This used to be commit ab3150fe4ed2a629eb371db5f43ae09b9c583a64) --- source3/libads/sasl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads/sasl.c') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index ce000a1306..0067a19d3b 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -477,7 +477,7 @@ failed: gss_release_name(&minor_status, &serv_name); if (context_handle != GSS_C_NO_CONTEXT) - gss_delete_sec_context(&min_status, &context_handle, GSS_C_NO_BUFFER); + gss_delete_sec_context(&minor_status, &context_handle, GSS_C_NO_BUFFER); krb5_free_principal(ctx, principal); krb5_free_context(ctx); -- cgit From eceb926df94063e91c5abc96f52a1bc7b45ce290 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 5 Apr 2007 12:30:23 +0000 Subject: r22092: - make spnego_parse_auth_response() more generic and not specific for NTLMSSP - it's possible that the server sends a mechOID and authdata if negResult != SPNEGO_NEG_RESULT_INCOMPLETE, but we still force the mechOID to be present if negResult == SPNEGO_NEG_RESULT_INCOMPLETE metze (This used to be commit e9f2aa22f90208a5e530ef3b68664151960a0a22) --- source3/libads/sasl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads/sasl.c') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 0067a19d3b..b5f92044ef 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -114,7 +114,7 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) } data_blob_free(&tmp_blob); } else if (rc == LDAP_SASL_BIND_IN_PROGRESS) { - if (!spnego_parse_auth_response(blob, nt_status, + if (!spnego_parse_auth_response(blob, nt_status, OID_NTLMSSP, &blob_in)) { ntlmssp_end(&ntlmssp_state); -- cgit From 78c57f59ac7d47425ebb450205efc981575aab8d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 10 Apr 2007 16:04:22 +0000 Subject: r22153: fix LDAP SASL "GSSAPI" bind against w2k3, this isn't critical because we try "GSS-SPNEGO" first and all windows version support that. metze (This used to be commit 34a5badbded0b2537ee854287931e2a7dc3aeb37) --- source3/libads/sasl.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'source3/libads/sasl.c') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index b5f92044ef..2fc66bd929 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -441,7 +441,8 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) gss_release_buffer(&minor_status, &output_token); - output_token.value = SMB_MALLOC(strlen(ads->config.bind_path) + 8); + output_token.length = 4; + output_token.value = SMB_MALLOC(output_token.length); p = (uint8 *)output_token.value; *p++ = 1; /* no sign & seal selection */ @@ -449,10 +450,14 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) *p++ = max_msg_size>>16; *p++ = max_msg_size>>8; *p++ = max_msg_size; - snprintf((char *)p, strlen(ads->config.bind_path)+4, "dn:%s", ads->config.bind_path); - p += strlen((const char *)p); - - output_token.length = PTR_DIFF(p, output_token.value); + /* + * we used to add sprintf("dn:%s", ads->config.bind_path) here. + * but using ads->config.bind_path is the wrong! It should be + * the DN of the user object! + * + * w2k3 gives an error when we send an incorrect DN, but sending nothing + * is ok and matches the information flow used in GSS-SPNEGO. + */ gss_rc = gss_wrap(&minor_status, context_handle,0,GSS_C_QOP_DEFAULT, &output_token, (int *)&conf_state, -- cgit From b4a7b7a8889737e2891fc1176feabd4ce47f2737 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 14 May 2007 12:16:20 +0000 Subject: r22844: Introduce const DATA_BLOB data_blob_null = { NULL, 0, NULL }; and replace all data_blob(NULL, 0) calls. (This used to be commit 3d3d61687ef00181f4f04e001d42181d93ac931e) --- source3/libads/sasl.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'source3/libads/sasl.c') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 2fc66bd929..f1f0861535 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -28,10 +28,10 @@ */ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) { - DATA_BLOB msg1 = data_blob(NULL, 0); - DATA_BLOB blob = data_blob(NULL, 0); - DATA_BLOB blob_in = data_blob(NULL, 0); - DATA_BLOB blob_out = data_blob(NULL, 0); + DATA_BLOB msg1 = data_blob_null; + DATA_BLOB blob = data_blob_null; + DATA_BLOB blob_in = data_blob_null; + DATA_BLOB blob_out = data_blob_null; struct berval cred, *scred = NULL; int rc; NTSTATUS nt_status; @@ -54,7 +54,7 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) return ADS_ERROR_NT(nt_status); } - blob_in = data_blob(NULL, 0); + blob_in = data_blob_null; do { nt_status = ntlmssp_update(ntlmssp_state, @@ -90,7 +90,7 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) blob = data_blob(scred->bv_val, scred->bv_len); ber_bvfree(scred); } else { - blob = data_blob(NULL, 0); + blob = data_blob_null; } } else { @@ -102,7 +102,7 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) if ((turn == 1) && (rc == LDAP_SASL_BIND_IN_PROGRESS)) { - DATA_BLOB tmp_blob = data_blob(NULL, 0); + DATA_BLOB tmp_blob = data_blob_null; /* the server might give us back two challenges */ if (!spnego_parse_challenge(blob, &blob_in, &tmp_blob)) { @@ -142,9 +142,9 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) */ static ADS_STATUS ads_sasl_spnego_krb5_bind(ADS_STRUCT *ads, const char *principal) { - DATA_BLOB blob = data_blob(NULL, 0); + DATA_BLOB blob = data_blob_null; struct berval cred, *scred = NULL; - DATA_BLOB session_key = data_blob(NULL, 0); + DATA_BLOB session_key = data_blob_null; int rc; rc = spnego_gen_negTokenTarg(principal, ads->auth.time_offset, &blob, &session_key, 0, -- cgit From d824b98f80ba186030cbb70b3a1e5daf80469ecd Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 9 Jul 2007 19:25:36 +0000 Subject: r23779: Change from v2 or later to v3 or later. Jeremy. (This used to be commit 407e6e695b8366369b7c76af1ff76869b45347b3) --- source3/libads/sasl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads/sasl.c') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index f1f0861535..3be7ee67b6 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -5,7 +5,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, -- cgit From 5e54558c6dea67b56bbfaba5698f3a434d3dffb6 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 10 Jul 2007 00:52:41 +0000 Subject: r23784: use the GPLv3 boilerplate as recommended by the FSF and the license text (This used to be commit b0132e94fc5fef936aa766fb99a306b3628e9f07) --- source3/libads/sasl.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/libads/sasl.c') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 3be7ee67b6..9536ba31be 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -14,8 +14,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" -- cgit From 809c9d4d3136cc46dc228107918ca19d5a008a0a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 16 Jul 2007 11:08:00 +0000 Subject: r23888: move elements belonging to the current ldap connection to a substructure. metze (This used to be commit 00909194a6c1ed193dfdb296f50f58a53450583c) --- source3/libads/sasl.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source3/libads/sasl.c') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 9536ba31be..a73545f8e5 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -75,7 +75,7 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) cred.bv_val = (char *)msg1.data; cred.bv_len = msg1.length; scred = NULL; - rc = ldap_sasl_bind_s(ads->ld, NULL, "GSS-SPNEGO", &cred, NULL, NULL, &scred); + rc = ldap_sasl_bind_s(ads->ldap.ld, NULL, "GSS-SPNEGO", &cred, NULL, NULL, &scred); data_blob_free(&msg1); if ((rc != LDAP_SASL_BIND_IN_PROGRESS) && (rc != 0)) { if (scred) { @@ -157,7 +157,7 @@ static ADS_STATUS ads_sasl_spnego_krb5_bind(ADS_STRUCT *ads, const char *princip cred.bv_val = (char *)blob.data; cred.bv_len = blob.length; - rc = ldap_sasl_bind_s(ads->ld, NULL, "GSS-SPNEGO", &cred, NULL, NULL, &scred); + rc = ldap_sasl_bind_s(ads->ldap.ld, NULL, "GSS-SPNEGO", &cred, NULL, NULL, &scred); data_blob_free(&blob); data_blob_free(&session_key); @@ -183,7 +183,7 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) BOOL got_kerberos_mechanism = False; #endif - rc = ldap_sasl_bind_s(ads->ld, NULL, "GSS-SPNEGO", NULL, NULL, NULL, &scred); + rc = ldap_sasl_bind_s(ads->ldap.ld, NULL, "GSS-SPNEGO", NULL, NULL, NULL, &scred); if (rc != LDAP_SASL_BIND_IN_PROGRESS) { status = ADS_ERROR(rc); @@ -397,7 +397,7 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) cred.bv_val = (char *)output_token.value; cred.bv_len = output_token.length; - rc = ldap_sasl_bind_s(ads->ld, NULL, "GSSAPI", &cred, NULL, NULL, + rc = ldap_sasl_bind_s(ads->ldap.ld, NULL, "GSSAPI", &cred, NULL, NULL, &scred); if (rc != LDAP_SASL_BIND_IN_PROGRESS) { status = ADS_ERROR(rc); @@ -471,7 +471,7 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) cred.bv_val = (char *)input_token.value; cred.bv_len = input_token.length; - rc = ldap_sasl_bind_s(ads->ld, NULL, "GSSAPI", &cred, NULL, NULL, + rc = ldap_sasl_bind_s(ads->ldap.ld, NULL, "GSSAPI", &cred, NULL, NULL, &scred); status = ADS_ERROR(rc); @@ -515,7 +515,7 @@ ADS_STATUS ads_sasl_bind(ADS_STRUCT *ads) status = ads_do_search(ads, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res); if (!ADS_ERR_OK(status)) return status; - values = ldap_get_values(ads->ld, res, "supportedSASLMechanisms"); + values = ldap_get_values(ads->ldap.ld, res, "supportedSASLMechanisms"); /* try our supported mechanisms in order */ for (i=0;sasl_mechanisms[i].name;i++) { -- cgit From 07c034f7c443689749c2b4b138acb991da575c3a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 18 Jul 2007 07:45:16 +0000 Subject: r23945: add infrastructure to select plain, sign or seal LDAP connection metze (This used to be commit 2075c05b3d8baa7d6d8510cd962471a5781740a6) --- source3/libads/sasl.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'source3/libads/sasl.c') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index a73545f8e5..94600d7234 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -517,6 +517,14 @@ ADS_STATUS ads_sasl_bind(ADS_STRUCT *ads) values = ldap_get_values(ads->ldap.ld, res, "supportedSASLMechanisms"); + if (ads->auth.flags & ADS_AUTH_SASL_SEAL) { + ads->ldap.wrap_type = ADS_SASLWRAP_TYPE_SEAL; + } else if (ads->auth.flags & ADS_AUTH_SASL_SIGN) { + ads->ldap.wrap_type = ADS_SASLWRAP_TYPE_SIGN; + } else { + ads->ldap.wrap_type = ADS_SASLWRAP_TYPE_PLAIN; + } + /* try our supported mechanisms in order */ for (i=0;sasl_mechanisms[i].name;i++) { /* see if the server supports it */ -- cgit From ea3c3b9272e6f90b93e11d898250627009f1abd1 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 18 Jul 2007 08:15:42 +0000 Subject: r23946: add support for NTLMSSP sign and seal NOTE: windows servers are broken with sign only... metze (This used to be commit 408bb2e6e2171196a2bd314db181d9b124e931a1) --- source3/libads/sasl.c | 123 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 122 insertions(+), 1 deletion(-) (limited to 'source3/libads/sasl.c') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 94600d7234..08a6765e27 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -21,6 +21,95 @@ #ifdef HAVE_LDAP +static ADS_STATUS ads_sasl_ntlmssp_wrap(ADS_STRUCT *ads, uint8 *buf, uint32 len) +{ + struct ntlmssp_state *ntlmssp_state = ads->ldap.wrap_private_data; + ADS_STATUS status; + NTSTATUS nt_status; + DATA_BLOB sig; + uint8 *dptr = ads->ldap.out.buf + (4 + NTLMSSP_SIG_SIZE); + + /* copy the data to the right location */ + memcpy(dptr, buf, len); + + /* create the signature and may encrypt the data */ + if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SEAL) { + nt_status = ntlmssp_seal_packet(ntlmssp_state, + dptr, len, + dptr, len, + &sig); + } else { + nt_status = ntlmssp_sign_packet(ntlmssp_state, + dptr, len, + dptr, len, + &sig); + } + status = ADS_ERROR_NT(nt_status); + if (!ADS_ERR_OK(status)) return status; + + /* copy the signature to the right location */ + memcpy(ads->ldap.out.buf + 4, + sig.data, NTLMSSP_SIG_SIZE); + + data_blob_free(&sig); + + /* set how many bytes must be written to the underlying socket */ + ads->ldap.out.left = 4 + NTLMSSP_SIG_SIZE + len; + + return ADS_SUCCESS; +} + +static ADS_STATUS ads_sasl_ntlmssp_unwrap(ADS_STRUCT *ads) +{ + struct ntlmssp_state *ntlmssp_state = ads->ldap.wrap_private_data; + ADS_STATUS status; + NTSTATUS nt_status; + DATA_BLOB sig; + uint8 *dptr = ads->ldap.in.buf + (4 + NTLMSSP_SIG_SIZE); + uint32 dlen = ads->ldap.in.ofs - (4 + NTLMSSP_SIG_SIZE); + + /* wrap the signature into a DATA_BLOB */ + sig = data_blob_const(ads->ldap.in.buf + 4, NTLMSSP_SIG_SIZE); + + /* verify the signature and maybe decrypt the data */ + if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SEAL) { + nt_status = ntlmssp_unseal_packet(ntlmssp_state, + dptr, dlen, + dptr, dlen, + &sig); + } else { + nt_status = ntlmssp_check_packet(ntlmssp_state, + dptr, dlen, + dptr, dlen, + &sig); + } + status = ADS_ERROR_NT(nt_status); + if (!ADS_ERR_OK(status)) return status; + + /* set the amount of bytes for the upper layer and set the ofs to the data */ + ads->ldap.in.left = dlen; + ads->ldap.in.ofs = 4 + NTLMSSP_SIG_SIZE; + + return ADS_SUCCESS; +} + +static void ads_sasl_ntlmssp_disconnect(ADS_STRUCT *ads) +{ + struct ntlmssp_state *ntlmssp_state = ads->ldap.wrap_private_data; + + ntlmssp_end(&ntlmssp_state); + + ads->ldap.wrap_ops = NULL; + ads->ldap.wrap_private_data = NULL; +} + +static const struct ads_saslwrap_ops ads_sasl_ntlmssp_ops = { + .name = "ntlmssp", + .wrap = ads_sasl_ntlmssp_wrap, + .unwrap = ads_sasl_ntlmssp_unwrap, + .disconnect = ads_sasl_ntlmssp_disconnect +}; + /* perform a LDAP/SASL/SPNEGO/NTLMSSP bind (just how many layers can we fit on one socket??) @@ -35,6 +124,7 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) int rc; NTSTATUS nt_status; int turn = 1; + uint32 features = 0; struct ntlmssp_state *ntlmssp_state; @@ -53,6 +143,28 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) return ADS_ERROR_NT(nt_status); } + switch (ads->ldap.wrap_type) { + case ADS_SASLWRAP_TYPE_SEAL: + features = NTLMSSP_FEATURE_SIGN | NTLMSSP_FEATURE_SEAL; + break; + case ADS_SASLWRAP_TYPE_SIGN: + if (ads->auth.flags & ADS_AUTH_SASL_FORCE) { + features = NTLMSSP_FEATURE_SIGN; + } else { + /* + * windows servers are broken with sign only, + * so we need to use seal here too + */ + features = NTLMSSP_FEATURE_SIGN | NTLMSSP_FEATURE_SEAL; + ads->ldap.wrap_type = ADS_SASLWRAP_TYPE_SEAL; + } + break; + case ADS_SASLWRAP_TYPE_PLAIN: + break; + } + + ntlmssp_want_feature(ntlmssp_state, features); + blob_in = data_blob_null; do { @@ -130,7 +242,16 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) /* we have a reference conter on ntlmssp_state, if we are signing then the state will be kept by the signing engine */ - ntlmssp_end(&ntlmssp_state); + if (ads->ldap.wrap_type > ADS_SASLWRAP_TYPE_PLAIN) { + ads->ldap.out.min = 4; + ads->ldap.out.max = 0x0FFFFFFF - NTLMSSP_SIG_SIZE; + ads->ldap.out.sig_size = NTLMSSP_SIG_SIZE; + ads->ldap.in.min = 4; + ads->ldap.in.max = 0x0FFFFFFF; + ads_setup_sasl_wrapping(ads, &ads_sasl_ntlmssp_ops, ntlmssp_state); + } else { + ntlmssp_end(&ntlmssp_state); + } return ADS_ERROR(rc); } -- cgit From 14e81b300901a764d3c400d35991b04ad3d6a89c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 18 Jul 2007 08:19:13 +0000 Subject: r23948: add gsskrb5 sign and seal support for LDAP connections NOTE: only for the "GSSAPI" SASL mech yet metze (This used to be commit a079b66384b15e9d569dded0d9d6bd830e1a6dfa) --- source3/libads/sasl.c | 140 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 135 insertions(+), 5 deletions(-) (limited to 'source3/libads/sasl.c') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 08a6765e27..f423464a07 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -256,6 +256,105 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) return ADS_ERROR(rc); } +#ifdef HAVE_GSSAPI +static ADS_STATUS ads_sasl_gssapi_wrap(ADS_STRUCT *ads, uint8 *buf, uint32 len) +{ + gss_ctx_id_t context_handle = ads->ldap.wrap_private_data; + ADS_STATUS status; + int gss_rc; + uint32 minor_status; + gss_buffer_desc unwrapped, wrapped; + int conf_req_flag, conf_state; + + unwrapped.value = buf; + unwrapped.length = len; + + /* for now request sign and seal */ + conf_req_flag = (ads->ldap.wrap_type == ADS_SASLWRAP_TYPE_SEAL); + + gss_rc = gss_wrap(&minor_status, context_handle, + conf_req_flag, GSS_C_QOP_DEFAULT, + &unwrapped, &conf_state, + &wrapped); + status = ADS_ERROR_GSS(gss_rc, minor_status); + if (!ADS_ERR_OK(status)) return status; + + if (conf_req_flag && conf_state == 0) { + return ADS_ERROR_NT(NT_STATUS_ACCESS_DENIED); + } + + if ((ads->ldap.out.size - 4) < wrapped.length) { + return ADS_ERROR_NT(NT_STATUS_INTERNAL_ERROR); + } + + /* copy the wrapped blob to the right location */ + memcpy(ads->ldap.out.buf + 4, wrapped.value, wrapped.length); + + /* set how many bytes must be written to the underlying socket */ + ads->ldap.out.left = 4 + wrapped.length; + + gss_release_buffer(&minor_status, &wrapped); + + return ADS_SUCCESS; +} + +static ADS_STATUS ads_sasl_gssapi_unwrap(ADS_STRUCT *ads) +{ + gss_ctx_id_t context_handle = ads->ldap.wrap_private_data; + ADS_STATUS status; + int gss_rc; + uint32 minor_status; + gss_buffer_desc unwrapped, wrapped; + int conf_state; + + wrapped.value = ads->ldap.in.buf + 4; + wrapped.length = ads->ldap.in.ofs - 4; + + gss_rc = gss_unwrap(&minor_status, context_handle, + &wrapped, &unwrapped, + &conf_state, GSS_C_QOP_DEFAULT); + status = ADS_ERROR_GSS(gss_rc, minor_status); + if (!ADS_ERR_OK(status)) return status; + + if (ads->ldap.wrap_type == ADS_SASLWRAP_TYPE_SEAL && conf_state == 0) { + return ADS_ERROR_NT(NT_STATUS_ACCESS_DENIED); + } + + if (wrapped.length < wrapped.length) { + return ADS_ERROR_NT(NT_STATUS_INTERNAL_ERROR); + } + + /* copy the wrapped blob to the right location */ + memcpy(ads->ldap.in.buf + 4, unwrapped.value, unwrapped.length); + + /* set how many bytes must be written to the underlying socket */ + ads->ldap.in.left = unwrapped.length; + ads->ldap.in.ofs = 4; + + gss_release_buffer(&minor_status, &unwrapped); + + return ADS_SUCCESS; +} + +static void ads_sasl_gssapi_disconnect(ADS_STRUCT *ads) +{ + gss_ctx_id_t context_handle = ads->ldap.wrap_private_data; + uint32 minor_status; + + gss_delete_sec_context(&minor_status, &context_handle, GSS_C_NO_BUFFER); + + ads->ldap.wrap_ops = NULL; + ads->ldap.wrap_private_data = NULL; +} + +static const struct ads_saslwrap_ops ads_sasl_gssapi_ops = { + .name = "gssapi", + .wrap = ads_sasl_gssapi_wrap, + .unwrap = ads_sasl_gssapi_unwrap, + .disconnect = ads_sasl_gssapi_disconnect +}; +#endif + #ifdef HAVE_KRB5 /* perform a LDAP/SASL/SPNEGO/KRB5 bind @@ -424,7 +523,8 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) gss_ctx_id_t context_handle = GSS_C_NO_CONTEXT; gss_OID mech_type = GSS_C_NULL_OID; gss_buffer_desc output_token, input_token; - uint32 ret_flags, conf_state; + uint32 req_flags, ret_flags; + int conf_state; struct berval cred; struct berval *scred = NULL; int i=0; @@ -491,13 +591,25 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) input_token.value = NULL; input_token.length = 0; + req_flags = GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG; + switch (ads->ldap.wrap_type) { + case ADS_SASLWRAP_TYPE_SEAL: + req_flags |= GSS_C_INTEG_FLAG | GSS_C_CONF_FLAG; + break; + case ADS_SASLWRAP_TYPE_SIGN: + req_flags |= GSS_C_INTEG_FLAG; + break; + case ADS_SASLWRAP_TYPE_PLAIN: + break; + } + for (i=0; i < MAX_GSS_PASSES; i++) { gss_rc = gss_init_sec_context(&minor_status, GSS_C_NO_CREDENTIAL, &context_handle, serv_name, mech_type, - GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG, + req_flags, 0, NULL, &input_token, @@ -541,7 +653,7 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) } gss_rc = gss_unwrap(&minor_status,context_handle,&input_token,&output_token, - (int *)&conf_state,NULL); + &conf_state,NULL); if (gss_rc) { status = ADS_ERROR_GSS(gss_rc, minor_status); goto failed; @@ -565,7 +677,7 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) output_token.value = SMB_MALLOC(output_token.length); p = (uint8 *)output_token.value; - *p++ = 1; /* no sign & seal selection */ + *p++ = ads->ldap.wrap_type; /* choose the same size as the server gave us */ *p++ = max_msg_size>>16; *p++ = max_msg_size>>8; @@ -580,7 +692,7 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) */ gss_rc = gss_wrap(&minor_status, context_handle,0,GSS_C_QOP_DEFAULT, - &output_token, (int *)&conf_state, + &output_token, &conf_state, &input_token); if (gss_rc) { status = ADS_ERROR_GSS(gss_rc, minor_status); @@ -598,6 +710,24 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) gss_release_buffer(&minor_status, &input_token); + if (ads->ldap.wrap_type > ADS_SASLWRAP_TYPE_PLAIN) { + gss_rc = gss_wrap_size_limit(&minor_status, context_handle, + (ads->ldap.wrap_type == ADS_SASLWRAP_TYPE_SEAL), + GSS_C_QOP_DEFAULT, + max_msg_size, &ads->ldap.out.max); + if (gss_rc) { + status = ADS_ERROR_GSS(gss_rc, minor_status); + goto failed; + } + + ads->ldap.out.min = 4; + ads->ldap.out.sig_size = max_msg_size - ads->ldap.out.max; + ads->ldap.in.min = 4; + ads->ldap.in.max = max_msg_size; + ads_setup_sasl_wrapping(ads, &ads_sasl_gssapi_ops, context_handle); + /* make sure we don't free context_handle */ + context_handle = GSS_C_NO_CONTEXT; + } failed: gss_release_name(&minor_status, &serv_name); -- cgit From f5033a1e625f74c517751bdb13f12f625ad34eb4 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 18 Jul 2007 12:28:32 +0000 Subject: r23953: Some C++ warnings (This used to be commit 8716edf157bf8866328f82eb6cf25e71af7fea15) --- source3/libads/sasl.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'source3/libads/sasl.c') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index f423464a07..a3636ec2be 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -23,7 +23,8 @@ static ADS_STATUS ads_sasl_ntlmssp_wrap(ADS_STRUCT *ads, uint8 *buf, uint32 len) { - struct ntlmssp_state *ntlmssp_state = ads->ldap.wrap_private_data; + struct ntlmssp_state *ntlmssp_state = + (struct ntlmssp_state *)ads->ldap.wrap_private_data; ADS_STATUS status; NTSTATUS nt_status; DATA_BLOB sig; @@ -61,7 +62,8 @@ static ADS_STATUS ads_sasl_ntlmssp_wrap(ADS_STRUCT *ads, uint8 *buf, uint32 len) static ADS_STATUS ads_sasl_ntlmssp_unwrap(ADS_STRUCT *ads) { - struct ntlmssp_state *ntlmssp_state = ads->ldap.wrap_private_data; + struct ntlmssp_state *ntlmssp_state = + (struct ntlmssp_state *)ads->ldap.wrap_private_data; ADS_STATUS status; NTSTATUS nt_status; DATA_BLOB sig; @@ -95,7 +97,8 @@ static ADS_STATUS ads_sasl_ntlmssp_unwrap(ADS_STRUCT *ads) static void ads_sasl_ntlmssp_disconnect(ADS_STRUCT *ads) { - struct ntlmssp_state *ntlmssp_state = ads->ldap.wrap_private_data; + struct ntlmssp_state *ntlmssp_state = + (struct ntlmssp_state *)ads->ldap.wrap_private_data; ntlmssp_end(&ntlmssp_state); -- cgit From 6b5c55b0f0155a2615683faccee9427c0aaf4baa Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 25 Jul 2007 07:23:20 +0000 Subject: r24037: only setup sasl wrapping after a successful bind metze (This used to be commit 85d6cd3dfb5cbd9e899957265e352583ff608ed4) --- source3/libads/sasl.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source3/libads/sasl.c') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index a3636ec2be..d1cd9f4f0b 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -709,9 +709,11 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) rc = ldap_sasl_bind_s(ads->ldap.ld, NULL, "GSSAPI", &cred, NULL, NULL, &scred); - status = ADS_ERROR(rc); - gss_release_buffer(&minor_status, &input_token); + status = ADS_ERROR(rc); + if (!ADS_ERR_OK(status)) { + goto failed; + } if (ads->ldap.wrap_type > ADS_SASLWRAP_TYPE_PLAIN) { gss_rc = gss_wrap_size_limit(&minor_status, context_handle, -- cgit From 75ae998b9948c03956ead9c3f9c7344a96ab93dc Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 25 Jul 2007 10:34:16 +0000 Subject: r24042: add support for krb5 sign and seal in LDAP via "GSS-SPNEGO" metze (This used to be commit 34ab84aceb86195743abd26c46a631640409725e) --- source3/libads/sasl.c | 310 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 309 insertions(+), 1 deletion(-) (limited to 'source3/libads/sasl.c') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index d1cd9f4f0b..6c5a518e6a 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -356,19 +356,307 @@ static const struct ads_saslwrap_ops ads_sasl_gssapi_ops = { .unwrap = ads_sasl_gssapi_unwrap, .disconnect = ads_sasl_gssapi_disconnect }; + +/* + perform a LDAP/SASL/SPNEGO/GSSKRB5 bind +*/ +static ADS_STATUS ads_sasl_spnego_gsskrb5_bind(ADS_STRUCT *ads, const char *sname) +{ + ADS_STATUS status; + BOOL ok; + uint32 minor_status; + int gss_rc, rc; + gss_OID_desc krb5_mech_type = + {9, CONST_DISCARD(char *, "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02") }; + gss_OID mech_type = &krb5_mech_type; + gss_OID actual_mech_type = GSS_C_NULL_OID; + const char *spnego_mechs[] = {OID_KERBEROS5_OLD, OID_KERBEROS5, OID_NTLMSSP, NULL}; + gss_name_t serv_name; + gss_ctx_id_t context_handle = GSS_C_NO_CONTEXT; + gss_buffer_desc input_token, output_token; + uint32 req_flags, ret_flags; + uint32 req_tmp, ret_tmp; + DATA_BLOB unwrapped; + DATA_BLOB wrapped; + struct berval cred, *scred = NULL; + krb5_principal principal = NULL; + gss_buffer_desc input_name; + krb5_context ctx = NULL; + krb5_enctype enc_types[] = { +#ifdef ENCTYPE_ARCFOUR_HMAC + ENCTYPE_ARCFOUR_HMAC, +#endif + ENCTYPE_DES_CBC_MD5, + ENCTYPE_NULL}; + gss_OID_desc nt_principal = + {10, CONST_DISCARD(char *, "\052\206\110\206\367\022\001\002\002\002")}; + + initialize_krb5_error_table(); + status = ADS_ERROR_KRB5(krb5_init_context(&ctx)); + if (!ADS_ERR_OK(status)) { + return status; + } + status = ADS_ERROR_KRB5(krb5_set_default_tgs_ktypes(ctx, enc_types)); + if (!ADS_ERR_OK(status)) { + krb5_free_context(ctx); + return status; + } + status = ADS_ERROR_KRB5(smb_krb5_parse_name(ctx, sname, &principal)); + if (!ADS_ERR_OK(status)) { + krb5_free_context(ctx); + return status; + } + + /* + * The MIT libraries have a *HORRIBLE* bug - input_value.value needs + * to point to the *address* of the krb5_principal, and the gss libraries + * to a shallow copy of the krb5_principal pointer - so we need to keep + * the krb5_principal around until we do the gss_release_name. MIT *SUCKS* ! + * Just one more way in which MIT engineers screwed me over.... JRA. + */ + input_name.value = &principal; + input_name.length = sizeof(principal); + + gss_rc = gss_import_name(&minor_status, &input_name, &nt_principal, &serv_name); + if (gss_rc) { + krb5_free_principal(ctx, principal); + krb5_free_context(ctx); + return ADS_ERROR_GSS(gss_rc, minor_status); + } + + input_token.value = NULL; + input_token.length = 0; + + req_flags = GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG; + switch (ads->ldap.wrap_type) { + case ADS_SASLWRAP_TYPE_SEAL: + req_flags |= GSS_C_INTEG_FLAG | GSS_C_CONF_FLAG; + break; + case ADS_SASLWRAP_TYPE_SIGN: + req_flags |= GSS_C_INTEG_FLAG; + break; + case ADS_SASLWRAP_TYPE_PLAIN: + break; + } + + /* Note: here we explicit ask for the krb5 mech_type */ + gss_rc = gss_init_sec_context(&minor_status, + GSS_C_NO_CREDENTIAL, + &context_handle, + serv_name, + mech_type, + req_flags, + 0, + NULL, + &input_token, + &actual_mech_type, + &output_token, + &ret_flags, + NULL); + if (gss_rc && gss_rc != GSS_S_CONTINUE_NEEDED) { + status = ADS_ERROR_GSS(gss_rc, minor_status); + goto failed; + } + + /* + * As some gssapi krb5 mech implementations + * automaticly add GSS_C_INTEG_FLAG and GSS_C_CONF_FLAG + * to req_flags internaly, it's not possible to + * use plain or signing only connection via + * the gssapi interface. + * + * Because of this we need to check it the ret_flags + * has more flags as req_flags and correct the value + * of ads->ldap.wrap_type. + * + * I ads->auth.flags has ADS_AUTH_SASL_FORCE + * we need to give an error. + */ + req_tmp = req_flags & (GSS_C_INTEG_FLAG | GSS_C_CONF_FLAG); + ret_tmp = ret_flags & (GSS_C_INTEG_FLAG | GSS_C_CONF_FLAG); + + if (req_tmp == ret_tmp) { + /* everythings fine... */ + + } else if (req_flags & GSS_C_CONF_FLAG) { + /* + * here we wanted sealing but didn't got it + * from the gssapi library + */ + status = ADS_ERROR_NT(NT_STATUS_NOT_SUPPORTED); + goto failed; + + } else if (req_flags & GSS_C_INTEG_FLAG) { + /* + * here we wanted siging but didn't got it + * from the gssapi library + */ + status = ADS_ERROR_NT(NT_STATUS_NOT_SUPPORTED); + goto failed; + + } else if (ret_flags & GSS_C_CONF_FLAG) { + /* + * here we didn't want sealing + * but the gssapi library forces it + * so correct the needed wrap_type if + * the caller didn't forced siging only + */ + if (ads->auth.flags & ADS_AUTH_SASL_FORCE) { + status = ADS_ERROR_NT(NT_STATUS_NOT_SUPPORTED); + goto failed; + } + + ads->ldap.wrap_type = ADS_SASLWRAP_TYPE_SEAL; + req_flags = ret_flags; + + } else if (ret_flags & GSS_C_INTEG_FLAG) { + /* + * here we didn't want signing + * but the gssapi library forces it + * so correct the needed wrap_type if + * the caller didn't forced plain + */ + if (ads->auth.flags & ADS_AUTH_SASL_FORCE) { + status = ADS_ERROR_NT(NT_STATUS_NOT_SUPPORTED); + goto failed; + } + + ads->ldap.wrap_type = ADS_SASLWRAP_TYPE_SIGN; + req_flags = ret_flags; + } else { + /* + * This could (should?) not happen + */ + status = ADS_ERROR_NT(NT_STATUS_INTERNAL_ERROR); + goto failed; + + } + + /* and wrap that in a shiny SPNEGO wrapper */ + unwrapped = data_blob_const(output_token.value, output_token.length); + wrapped = gen_negTokenTarg(spnego_mechs, unwrapped); + gss_release_buffer(&minor_status, &output_token); + if (unwrapped.length > wrapped.length) { + status = ADS_ERROR_NT(NT_STATUS_NO_MEMORY); + goto failed; + } + + cred.bv_val = (char *)wrapped.data; + cred.bv_len = wrapped.length; + + rc = ldap_sasl_bind_s(ads->ldap.ld, NULL, "GSS-SPNEGO", &cred, NULL, NULL, + &scred); + data_blob_free(&wrapped); + if (rc != LDAP_SUCCESS) { + status = ADS_ERROR(rc); + goto failed; + } + + if (scred) { + wrapped = data_blob_const(scred->bv_val, scred->bv_len); + } else { + wrapped = data_blob_null; + } + + ok = spnego_parse_auth_response(wrapped, NT_STATUS_OK, + OID_KERBEROS5_OLD, + &unwrapped); + if (scred) ber_bvfree(scred); + if (!ok) { + status = ADS_ERROR_NT(NT_STATUS_INVALID_NETWORK_RESPONSE); + goto failed; + } + + input_token.value = unwrapped.data; + input_token.length = unwrapped.length; + + /* + * As we asked for mutal authentication + * we need to pass the servers response + * to gssapi + */ + gss_rc = gss_init_sec_context(&minor_status, + GSS_C_NO_CREDENTIAL, + &context_handle, + serv_name, + mech_type, + req_flags, + 0, + NULL, + &input_token, + &actual_mech_type, + &output_token, + &ret_flags, + NULL); + data_blob_free(&unwrapped); + if (gss_rc) { + status = ADS_ERROR_GSS(gss_rc, minor_status); + goto failed; + } + + gss_release_buffer(&minor_status, &output_token); + + /* + * If we the sign and seal options + * doesn't match after getting the response + * from the server, we don't want to use the connection + */ + req_tmp = req_flags & (GSS_C_INTEG_FLAG | GSS_C_CONF_FLAG); + ret_tmp = ret_flags & (GSS_C_INTEG_FLAG | GSS_C_CONF_FLAG); + + if (req_tmp != ret_tmp) { + /* everythings fine... */ + status = ADS_ERROR_NT(NT_STATUS_INVALID_NETWORK_RESPONSE); + goto failed; + } + + if (ads->ldap.wrap_type > ADS_SASLWRAP_TYPE_PLAIN) { + uint32 max_msg_size = 0x0A000000; + + gss_rc = gss_wrap_size_limit(&minor_status, context_handle, + (ads->ldap.wrap_type == ADS_SASLWRAP_TYPE_SEAL), + GSS_C_QOP_DEFAULT, + max_msg_size, &ads->ldap.out.max); + if (gss_rc) { + status = ADS_ERROR_GSS(gss_rc, minor_status); + goto failed; + } + + ads->ldap.out.min = 4; + ads->ldap.out.sig_size = max_msg_size - ads->ldap.out.max; + ads->ldap.in.min = 4; + ads->ldap.in.max = max_msg_size; + ads_setup_sasl_wrapping(ads, &ads_sasl_gssapi_ops, context_handle); + /* make sure we don't free context_handle */ + context_handle = GSS_C_NO_CONTEXT; + } + +failed: + gss_release_name(&minor_status, &serv_name); + if (context_handle != GSS_C_NO_CONTEXT) + gss_delete_sec_context(&minor_status, &context_handle, GSS_C_NO_BUFFER); + krb5_free_principal(ctx, principal); + krb5_free_context(ctx); + return status; +} + #endif #ifdef HAVE_KRB5 /* perform a LDAP/SASL/SPNEGO/KRB5 bind */ -static ADS_STATUS ads_sasl_spnego_krb5_bind(ADS_STRUCT *ads, const char *principal) +static ADS_STATUS ads_sasl_spnego_rawkrb5_bind(ADS_STRUCT *ads, const char *principal) { DATA_BLOB blob = data_blob_null; struct berval cred, *scred = NULL; DATA_BLOB session_key = data_blob_null; int rc; + if (ads->ldap.wrap_type > ADS_SASLWRAP_TYPE_PLAIN) { + return ADS_ERROR_NT(NT_STATUS_NOT_SUPPORTED); + } + rc = spnego_gen_negTokenTarg(principal, ads->auth.time_offset, &blob, &session_key, 0, &ads->auth.tgs_expire); @@ -389,6 +677,26 @@ static ADS_STATUS ads_sasl_spnego_krb5_bind(ADS_STRUCT *ads, const char *princip return ADS_ERROR(rc); } + +static ADS_STATUS ads_sasl_spnego_krb5_bind(ADS_STRUCT *ads, const char *principal) +{ +#ifdef HAVE_GSSAPI + /* + * we only use the gsskrb5 based implementation + * when sasl sign or seal is requested. + * + * This has the following reasons: + * - it's likely that the gssapi krb5 mech implementation + * doesn't support to negotiate plain connections + * - the ads_sasl_spnego_rawkrb5_bind is more robust + * against clock skew errors + */ + if (ads->ldap.wrap_type > ADS_SASLWRAP_TYPE_PLAIN) { + return ads_sasl_spnego_gsskrb5_bind(ads, principal); + } +#endif + return ads_sasl_spnego_rawkrb5_bind(ads, principal); +} #endif /* -- cgit From b4f6db40ab24742f4d9a8b1ff4885e62092b5930 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 27 Jul 2007 07:19:36 +0000 Subject: r24062: fix logic for broken krb5 libs which always force sign and seal... metze (This used to be commit 4a4fc8cccbcbe17eebcefcd0107f7de60d751f5c) --- source3/libads/sasl.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libads/sasl.c') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 6c5a518e6a..f5e540d304 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -486,7 +486,8 @@ static ADS_STATUS ads_sasl_spnego_gsskrb5_bind(ADS_STRUCT *ads, const char *snam status = ADS_ERROR_NT(NT_STATUS_NOT_SUPPORTED); goto failed; - } else if (req_flags & GSS_C_INTEG_FLAG) { + } else if ((req_flags & GSS_C_INTEG_FLAG) && + !(ret_flags & GSS_C_INTEG_FLAG)) { /* * here we wanted siging but didn't got it * from the gssapi library -- cgit From 062bca6675c120dcf533de18da72acc903b3eb8e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 31 Jul 2007 09:31:47 +0000 Subject: r24093: move gssapi/krb5 principal handling into a function metze (This used to be commit 83de27968d434d67d23851b0c285221c870ff75e) --- source3/libads/sasl.c | 234 +++++++++++++++++++++++++++++++------------------- 1 file changed, 146 insertions(+), 88 deletions(-) (limited to 'source3/libads/sasl.c') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index f5e540d304..732691942f 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -360,7 +360,7 @@ static const struct ads_saslwrap_ops ads_sasl_gssapi_ops = { /* perform a LDAP/SASL/SPNEGO/GSSKRB5 bind */ -static ADS_STATUS ads_sasl_spnego_gsskrb5_bind(ADS_STRUCT *ads, const char *sname) +static ADS_STATUS ads_sasl_spnego_gsskrb5_bind(ADS_STRUCT *ads, const gss_name_t serv_name) { ADS_STATUS status; BOOL ok; @@ -371,7 +371,6 @@ static ADS_STATUS ads_sasl_spnego_gsskrb5_bind(ADS_STRUCT *ads, const char *snam gss_OID mech_type = &krb5_mech_type; gss_OID actual_mech_type = GSS_C_NULL_OID; const char *spnego_mechs[] = {OID_KERBEROS5_OLD, OID_KERBEROS5, OID_NTLMSSP, NULL}; - gss_name_t serv_name; gss_ctx_id_t context_handle = GSS_C_NO_CONTEXT; gss_buffer_desc input_token, output_token; uint32 req_flags, ret_flags; @@ -379,50 +378,6 @@ static ADS_STATUS ads_sasl_spnego_gsskrb5_bind(ADS_STRUCT *ads, const char *snam DATA_BLOB unwrapped; DATA_BLOB wrapped; struct berval cred, *scred = NULL; - krb5_principal principal = NULL; - gss_buffer_desc input_name; - krb5_context ctx = NULL; - krb5_enctype enc_types[] = { -#ifdef ENCTYPE_ARCFOUR_HMAC - ENCTYPE_ARCFOUR_HMAC, -#endif - ENCTYPE_DES_CBC_MD5, - ENCTYPE_NULL}; - gss_OID_desc nt_principal = - {10, CONST_DISCARD(char *, "\052\206\110\206\367\022\001\002\002\002")}; - - initialize_krb5_error_table(); - status = ADS_ERROR_KRB5(krb5_init_context(&ctx)); - if (!ADS_ERR_OK(status)) { - return status; - } - status = ADS_ERROR_KRB5(krb5_set_default_tgs_ktypes(ctx, enc_types)); - if (!ADS_ERR_OK(status)) { - krb5_free_context(ctx); - return status; - } - status = ADS_ERROR_KRB5(smb_krb5_parse_name(ctx, sname, &principal)); - if (!ADS_ERR_OK(status)) { - krb5_free_context(ctx); - return status; - } - - /* - * The MIT libraries have a *HORRIBLE* bug - input_value.value needs - * to point to the *address* of the krb5_principal, and the gss libraries - * to a shallow copy of the krb5_principal pointer - so we need to keep - * the krb5_principal around until we do the gss_release_name. MIT *SUCKS* ! - * Just one more way in which MIT engineers screwed me over.... JRA. - */ - input_name.value = &principal; - input_name.length = sizeof(principal); - - gss_rc = gss_import_name(&minor_status, &input_name, &nt_principal, &serv_name); - if (gss_rc) { - krb5_free_principal(ctx, principal); - krb5_free_context(ctx); - return ADS_ERROR_GSS(gss_rc, minor_status); - } input_token.value = NULL; input_token.length = 0; @@ -633,17 +588,136 @@ static ADS_STATUS ads_sasl_spnego_gsskrb5_bind(ADS_STRUCT *ads, const char *snam } failed: - gss_release_name(&minor_status, &serv_name); if (context_handle != GSS_C_NO_CONTEXT) gss_delete_sec_context(&minor_status, &context_handle, GSS_C_NO_BUFFER); - krb5_free_principal(ctx, principal); - krb5_free_context(ctx); return status; } #endif #ifdef HAVE_KRB5 +struct ads_service_principal { + krb5_context ctx; + char *string; + krb5_principal principal; +#ifdef HAVE_GSSAPI + gss_name_t name; +#endif +}; + +static void ads_free_service_principal(struct ads_service_principal *p) +{ + SAFE_FREE(p->string); + +#ifdef HAVE_GSSAPI + if (p->name) { + uint32 minor_status; + gss_release_name(&minor_status, &p->name); + } +#endif + if (p->principal) { + krb5_free_principal(p->ctx, p->principal); + } + + if (p->ctx) { + krb5_free_context(p->ctx); + } + + ZERO_STRUCTP(p); +} + +static ADS_STATUS ads_generate_service_principal(ADS_STRUCT *ads, + const char *given_principal, + struct ads_service_principal *p) +{ + ADS_STATUS status; + krb5_enctype enc_types[] = { +#ifdef ENCTYPE_ARCFOUR_HMAC + ENCTYPE_ARCFOUR_HMAC, +#endif + ENCTYPE_DES_CBC_MD5, + ENCTYPE_NULL}; +#ifdef HAVE_GSSAPI + gss_buffer_desc input_name; + gss_OID_desc nt_principal = + {10, CONST_DISCARD(char *, "\052\206\110\206\367\022\001\002\002\002")}; + uint32 minor_status; + int gss_rc; +#endif + + ZERO_STRUCTP(p); + + /* I've seen a child Windows 2000 domain not send + the principal name back in the first round of + the SASL bind reply. So we guess based on server + name and realm. --jerry */ + if (given_principal) { + p->string = SMB_STRDUP(given_principal); + if (!p->string) { + return ADS_ERROR(LDAP_NO_MEMORY); + } + } else 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(&p->string, "ldap/%s@%s", server, server_realm); + + SAFE_FREE(server); + SAFE_FREE(server_realm); + + if (!p->string) { + return ADS_ERROR(LDAP_NO_MEMORY); + } + } + + initialize_krb5_error_table(); + status = ADS_ERROR_KRB5(krb5_init_context(&p->ctx)); + if (!ADS_ERR_OK(status)) { + ads_free_service_principal(p); + return status; + } + status = ADS_ERROR_KRB5(krb5_set_default_tgs_ktypes(p->ctx, enc_types)); + if (!ADS_ERR_OK(status)) { + ads_free_service_principal(p); + return status; + } + status = ADS_ERROR_KRB5(smb_krb5_parse_name(p->ctx, p->string, &p->principal)); + if (!ADS_ERR_OK(status)) { + ads_free_service_principal(p); + return status; + } + +#ifdef HAVE_GSSAPI + /* + * The MIT libraries have a *HORRIBLE* bug - input_value.value needs + * to point to the *address* of the krb5_principal, and the gss libraries + * to a shallow copy of the krb5_principal pointer - so we need to keep + * the krb5_principal around until we do the gss_release_name. MIT *SUCKS* ! + * Just one more way in which MIT engineers screwed me over.... JRA. + * + * That's the reason for principal not beeing a local var in this function + */ + input_name.value = &p->principal; + input_name.length = sizeof(p->principal); + + gss_rc = gss_import_name(&minor_status, &input_name, &nt_principal, &p->name); + if (gss_rc) { + ads_free_service_principal(p); + return ADS_ERROR_GSS(gss_rc, minor_status); + } +#endif + + return status; +} + /* perform a LDAP/SASL/SPNEGO/KRB5 bind */ @@ -679,7 +753,8 @@ static ADS_STATUS ads_sasl_spnego_rawkrb5_bind(ADS_STRUCT *ads, const char *prin return ADS_ERROR(rc); } -static ADS_STATUS ads_sasl_spnego_krb5_bind(ADS_STRUCT *ads, const char *principal) +static ADS_STATUS ads_sasl_spnego_krb5_bind(ADS_STRUCT *ads, + struct ads_service_principal *p) { #ifdef HAVE_GSSAPI /* @@ -693,10 +768,10 @@ static ADS_STATUS ads_sasl_spnego_krb5_bind(ADS_STRUCT *ads, const char *princip * against clock skew errors */ if (ads->ldap.wrap_type > ADS_SASLWRAP_TYPE_PLAIN) { - return ads_sasl_spnego_gsskrb5_bind(ads, principal); + return ads_sasl_spnego_gsskrb5_bind(ads, p->name); } #endif - return ads_sasl_spnego_rawkrb5_bind(ads, principal); + return ads_sasl_spnego_rawkrb5_bind(ads, p->string); } #endif @@ -709,7 +784,7 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) int rc, i; ADS_STATUS status; DATA_BLOB blob; - char *principal = NULL; + char *given_principal = NULL; char *OIDs[ASN1_MAX_OIDS]; #ifdef HAVE_KRB5 BOOL got_kerberos_mechanism = False; @@ -732,7 +807,7 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) /* the server sent us the first part of the SPNEGO exchange in the negprot reply */ - if (!spnego_parse_negTokenInit(blob, OIDs, &principal)) { + if (!spnego_parse_negTokenInit(blob, OIDs, &given_principal)) { data_blob_free(&blob); status = ADS_ERROR(LDAP_OPERATIONS_ERROR); goto failed; @@ -750,42 +825,23 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) #endif free(OIDs[i]); } - DEBUG(3,("ads_sasl_spnego_bind: got server principal name = %s\n", principal)); + DEBUG(3,("ads_sasl_spnego_bind: got server principal name = %s\n", given_principal)); #ifdef HAVE_KRB5 if (!(ads->auth.flags & ADS_AUTH_DISABLE_KERBEROS) && got_kerberos_mechanism) { - /* I've seen a child Windows 2000 domain not send - the principal name back in the first round of - the SASL bind reply. So we guess based on server - name and realm. --jerry */ - if ( !principal ) { - 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( &principal, "ldap/%s@%s", server, server_realm ); - - SAFE_FREE( server ); - SAFE_FREE( server_realm ); - - if ( !principal ) - return ADS_ERROR(LDAP_NO_MEMORY); - } - + struct ads_service_principal p; + + status = ads_generate_service_principal(ads, given_principal, &p); + SAFE_FREE(given_principal); + if (!ADS_ERR_OK(status)) { + return status; } - - status = ads_sasl_spnego_krb5_bind(ads, principal); + + status = ads_sasl_spnego_krb5_bind(ads, &p); if (ADS_ERR_OK(status)) { - SAFE_FREE(principal); + ads_free_service_principal(&p); return status; } @@ -795,19 +851,21 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) status = ADS_ERROR_KRB5(ads_kinit_password(ads)); if (ADS_ERR_OK(status)) { - status = ads_sasl_spnego_krb5_bind(ads, principal); + status = ads_sasl_spnego_krb5_bind(ads, &p); } + ads_free_service_principal(&p); + /* only fallback to NTLMSSP if allowed */ if (ADS_ERR_OK(status) || !(ads->auth.flags & ADS_AUTH_ALLOW_NTLMSSP)) { - SAFE_FREE(principal); return status; } - } + } else #endif - - SAFE_FREE(principal); + { + SAFE_FREE(given_principal); + } /* lets do NTLMSSP ... this has the big advantage that we don't need to sync clocks, and we don't rely on special versions of the krb5 -- cgit From db718085fd7a614215f1994f9001e9c04a37426b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 31 Jul 2007 09:37:25 +0000 Subject: r24095: add one more fallback alternative to construct the principal metze (This used to be commit b545667d2a45a79bba05c9fe9e93a19951d60af7) --- source3/libads/sasl.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'source3/libads/sasl.c') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 732691942f..4436551d88 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -673,6 +673,26 @@ static ADS_STATUS ads_generate_service_principal(ADS_STRUCT *ads, SAFE_FREE(server); SAFE_FREE(server_realm); + if (!p->string) { + return ADS_ERROR(LDAP_NO_MEMORY); + } + } 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(&p->string, "ldap/%s@%s", server, server_realm); + + SAFE_FREE(server); + SAFE_FREE(server_realm); + if (!p->string) { return ADS_ERROR(LDAP_NO_MEMORY); } -- cgit From 3edc6088aaff282530435ca19f70a96b22f045f4 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 31 Jul 2007 09:49:14 +0000 Subject: r24098: - make use of the ads_service_principal abstraction also for the "GSSAPI" sasl mech. - also use the ads_kinit_password() fallback logic from the "GSS-SPNEGO" sasl mech. metze (This used to be commit cbaf44de1e1f8007dc4ca249791ea30d2902c7c4) --- source3/libads/sasl.c | 93 ++++++++++++++++++--------------------------------- 1 file changed, 32 insertions(+), 61 deletions(-) (limited to 'source3/libads/sasl.c') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 4436551d88..0bc741c02a 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -905,11 +905,9 @@ failed: this routine is much less fragile see RFC2078 and RFC2222 for details */ -static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) +static ADS_STATUS ads_sasl_gssapi_do_bind(ADS_STRUCT *ads, const gss_name_t serv_name) { uint32 minor_status; - gss_name_t serv_name; - gss_buffer_desc input_name; gss_ctx_id_t context_handle = GSS_C_NO_CONTEXT; gss_OID mech_type = GSS_C_NULL_OID; gss_buffer_desc output_token, input_token; @@ -921,62 +919,7 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) int gss_rc, rc; uint8 *p; uint32 max_msg_size = 0; - char *sname = NULL; ADS_STATUS status; - krb5_principal principal = NULL; - krb5_context ctx = NULL; - krb5_enctype enc_types[] = { -#ifdef ENCTYPE_ARCFOUR_HMAC - ENCTYPE_ARCFOUR_HMAC, -#endif - ENCTYPE_DES_CBC_MD5, - ENCTYPE_NULL}; - gss_OID_desc nt_principal = - {10, CONST_DISCARD(char *, "\052\206\110\206\367\022\001\002\002\002")}; - - /* we need to fetch a service ticket as the ldap user in the - servers realm, regardless of our realm */ - asprintf(&sname, "ldap/%s@%s", ads->config.ldap_server_name, ads->config.realm); - - initialize_krb5_error_table(); - status = ADS_ERROR_KRB5(krb5_init_context(&ctx)); - if (!ADS_ERR_OK(status)) { - SAFE_FREE(sname); - return status; - } - status = ADS_ERROR_KRB5(krb5_set_default_tgs_ktypes(ctx, enc_types)); - if (!ADS_ERR_OK(status)) { - SAFE_FREE(sname); - krb5_free_context(ctx); - return status; - } - status = ADS_ERROR_KRB5(smb_krb5_parse_name(ctx, sname, &principal)); - if (!ADS_ERR_OK(status)) { - SAFE_FREE(sname); - krb5_free_context(ctx); - return status; - } - - input_name.value = &principal; - input_name.length = sizeof(principal); - - gss_rc = gss_import_name(&minor_status, &input_name, &nt_principal, &serv_name); - - /* - * The MIT libraries have a *HORRIBLE* bug - input_value.value needs - * to point to the *address* of the krb5_principal, and the gss libraries - * to a shallow copy of the krb5_principal pointer - so we need to keep - * the krb5_principal around until we do the gss_release_name. MIT *SUCKS* ! - * Just one more way in which MIT engineers screwed me over.... JRA. - */ - - SAFE_FREE(sname); - - if (gss_rc) { - krb5_free_principal(ctx, principal); - krb5_free_context(ctx); - return ADS_ERROR_GSS(gss_rc, minor_status); - } input_token.value = NULL; input_token.length = 0; @@ -1122,16 +1065,44 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) } failed: - gss_release_name(&minor_status, &serv_name); if (context_handle != GSS_C_NO_CONTEXT) gss_delete_sec_context(&minor_status, &context_handle, GSS_C_NO_BUFFER); - krb5_free_principal(ctx, principal); - krb5_free_context(ctx); if(scred) ber_bvfree(scred); return status; } + +static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) +{ + ADS_STATUS status; + struct ads_service_principal p; + + status = ads_generate_service_principal(ads, NULL, &p); + if (!ADS_ERR_OK(status)) { + return status; + } + + status = ads_sasl_gssapi_do_bind(ads, p.name); + if (ADS_ERR_OK(status)) { + ads_free_service_principal(&p); + return status; + } + + DEBUG(10,("ads_sasl_gssapi_do_bind failed with: %s, " + "calling kinit\n", ads_errstr(status))); + + status = ADS_ERROR_KRB5(ads_kinit_password(ads)); + + if (ADS_ERR_OK(status)) { + status = ads_sasl_gssapi_do_bind(ads, p.name); + } + + ads_free_service_principal(&p); + + return status; +} + #endif /* HAVE_GGSAPI */ /* mapping between SASL mechanisms and functions */ -- cgit From 56766b1f3ed8463a6a5c07658b0c350e4942bc9d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 31 Jul 2007 12:27:25 +0000 Subject: r24103: add some useful debug messages, as not all LDAP libraries support wrapping hooks... metze (This used to be commit 581a1d3a20ffed42ccc7f35f163fd343ed12ccd3) --- source3/libads/sasl.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) (limited to 'source3/libads/sasl.c') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 0bc741c02a..fa9afd7869 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -251,7 +251,13 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) ads->ldap.out.sig_size = NTLMSSP_SIG_SIZE; ads->ldap.in.min = 4; ads->ldap.in.max = 0x0FFFFFFF; - ads_setup_sasl_wrapping(ads, &ads_sasl_ntlmssp_ops, ntlmssp_state); + status = ads_setup_sasl_wrapping(ads, &ads_sasl_ntlmssp_ops, ntlmssp_state); + if (!ADS_ERR_OK(status)) { + DEBUG(0, "ads_setup_sasl_wrapping() failed: %s\n", + ads_errstr(status))); + ntlmssp_end(&ntlmssp_state); + return status; + } } else { ntlmssp_end(&ntlmssp_state); } @@ -582,7 +588,12 @@ static ADS_STATUS ads_sasl_spnego_gsskrb5_bind(ADS_STRUCT *ads, const gss_name_t ads->ldap.out.sig_size = max_msg_size - ads->ldap.out.max; ads->ldap.in.min = 4; ads->ldap.in.max = max_msg_size; - ads_setup_sasl_wrapping(ads, &ads_sasl_gssapi_ops, context_handle); + status = ads_setup_sasl_wrapping(ads, &ads_sasl_gssapi_ops, context_handle); + if (!ADS_ERR_OK(status)) { + DEBUG(0, "ads_setup_sasl_wrapping() failed: %s\n", + ads_errstr(status))); + goto failed; + } /* make sure we don't free context_handle */ context_handle = GSS_C_NO_CONTEXT; } @@ -1059,7 +1070,12 @@ static ADS_STATUS ads_sasl_gssapi_do_bind(ADS_STRUCT *ads, const gss_name_t serv ads->ldap.out.sig_size = max_msg_size - ads->ldap.out.max; ads->ldap.in.min = 4; ads->ldap.in.max = max_msg_size; - ads_setup_sasl_wrapping(ads, &ads_sasl_gssapi_ops, context_handle); + status = ads_setup_sasl_wrapping(ads, &ads_sasl_gssapi_ops, context_handle); + if (!ADS_ERR_OK(status)) { + DEBUG(0, "ads_setup_sasl_wrapping() failed: %s\n", + ads_errstr(status))); + goto failed; + } /* make sure we don't free context_handle */ context_handle = GSS_C_NO_CONTEXT; } -- cgit From e1b117719602f8d52228e63c50021db72f629515 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 31 Jul 2007 12:30:37 +0000 Subject: r24104: fix the build, sorry... metze (This used to be commit a5e1f9fd293fab26d664a72ee652eb8ca72128b7) --- source3/libads/sasl.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'source3/libads/sasl.c') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index fa9afd7869..5c4006e769 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -126,6 +126,7 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) struct berval cred, *scred = NULL; int rc; NTSTATUS nt_status; + ADS_STATUS status; int turn = 1; uint32 features = 0; @@ -253,7 +254,7 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) ads->ldap.in.max = 0x0FFFFFFF; status = ads_setup_sasl_wrapping(ads, &ads_sasl_ntlmssp_ops, ntlmssp_state); if (!ADS_ERR_OK(status)) { - DEBUG(0, "ads_setup_sasl_wrapping() failed: %s\n", + DEBUG(0, ("ads_setup_sasl_wrapping() failed: %s\n", ads_errstr(status))); ntlmssp_end(&ntlmssp_state); return status; @@ -590,7 +591,7 @@ static ADS_STATUS ads_sasl_spnego_gsskrb5_bind(ADS_STRUCT *ads, const gss_name_t ads->ldap.in.max = max_msg_size; status = ads_setup_sasl_wrapping(ads, &ads_sasl_gssapi_ops, context_handle); if (!ADS_ERR_OK(status)) { - DEBUG(0, "ads_setup_sasl_wrapping() failed: %s\n", + DEBUG(0, ("ads_setup_sasl_wrapping() failed: %s\n", ads_errstr(status))); goto failed; } @@ -1072,7 +1073,7 @@ static ADS_STATUS ads_sasl_gssapi_do_bind(ADS_STRUCT *ads, const gss_name_t serv ads->ldap.in.max = max_msg_size; status = ads_setup_sasl_wrapping(ads, &ads_sasl_gssapi_ops, context_handle); if (!ADS_ERR_OK(status)) { - DEBUG(0, "ads_setup_sasl_wrapping() failed: %s\n", + DEBUG(0, ("ads_setup_sasl_wrapping() failed: %s\n", ads_errstr(status))); goto failed; } -- cgit From d2900ddf1121f777ec8b28620fa93637b58e2a59 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 2 Aug 2007 15:11:37 +0000 Subject: r24128: fix double free in error path metze (This used to be commit 29e2d8e044c9213643a2f5f29891ce853a839347) --- source3/libads/sasl.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'source3/libads/sasl.c') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 5c4006e769..c727c8b50a 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -962,11 +962,10 @@ static ADS_STATUS ads_sasl_gssapi_do_bind(ADS_STRUCT *ads, const gss_name_t serv &output_token, &ret_flags, NULL); - - if (input_token.value) { - gss_release_buffer(&minor_status, &input_token); + if (scred) { + ber_bvfree(scred); + scred = NULL; } - if (gss_rc && gss_rc != GSS_S_CONTINUE_NEEDED) { status = ADS_ERROR_GSS(gss_rc, minor_status); goto failed; @@ -999,13 +998,15 @@ static ADS_STATUS ads_sasl_gssapi_do_bind(ADS_STRUCT *ads, const gss_name_t serv gss_rc = gss_unwrap(&minor_status,context_handle,&input_token,&output_token, &conf_state,NULL); + if (scred) { + ber_bvfree(scred); + scred = NULL; + } if (gss_rc) { status = ADS_ERROR_GSS(gss_rc, minor_status); goto failed; } - gss_release_buffer(&minor_status, &input_token); - p = (uint8 *)output_token.value; #if 0 -- cgit From cc8d70036477f30c6c9c8a6e37d1e2680107c0a6 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 2 Aug 2007 17:41:47 +0000 Subject: r24131: - make it more clear what the different min and max fields mean - with the "GSSAPI" sasl mech the plain, sign or seal negotiation is independed from the req_flags and ret_flags - verify the server supports the wrapping type we want - better handling on negotiated buffer sizes metze (This used to be commit d0ec7323870ca16b28d458ff5f7dacce278b7d54) --- source3/libads/sasl.c | 77 +++++++++++++++++++++++++++++---------------------- 1 file changed, 44 insertions(+), 33 deletions(-) (limited to 'source3/libads/sasl.c') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index c727c8b50a..bcd8833f30 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -247,11 +247,10 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) then the state will be kept by the signing engine */ if (ads->ldap.wrap_type > ADS_SASLWRAP_TYPE_PLAIN) { - ads->ldap.out.min = 4; - ads->ldap.out.max = 0x0FFFFFFF - NTLMSSP_SIG_SIZE; + ads->ldap.out.max_unwrapped = ADS_SASL_WRAPPING_OUT_MAX_WRAPPED - NTLMSSP_SIG_SIZE; ads->ldap.out.sig_size = NTLMSSP_SIG_SIZE; - ads->ldap.in.min = 4; - ads->ldap.in.max = 0x0FFFFFFF; + ads->ldap.in.min_wrapped = ads->ldap.out.sig_size; + ads->ldap.in.max_wrapped = ADS_SASL_WRAPPING_IN_MAX_WRAPPED; status = ads_setup_sasl_wrapping(ads, &ads_sasl_ntlmssp_ops, ntlmssp_state); if (!ADS_ERR_OK(status)) { DEBUG(0, ("ads_setup_sasl_wrapping() failed: %s\n", @@ -574,21 +573,20 @@ static ADS_STATUS ads_sasl_spnego_gsskrb5_bind(ADS_STRUCT *ads, const gss_name_t } if (ads->ldap.wrap_type > ADS_SASLWRAP_TYPE_PLAIN) { - uint32 max_msg_size = 0x0A000000; + uint32 max_msg_size = ADS_SASL_WRAPPING_OUT_MAX_WRAPPED; gss_rc = gss_wrap_size_limit(&minor_status, context_handle, (ads->ldap.wrap_type == ADS_SASLWRAP_TYPE_SEAL), GSS_C_QOP_DEFAULT, - max_msg_size, &ads->ldap.out.max); + max_msg_size, &ads->ldap.out.max_unwrapped); if (gss_rc) { status = ADS_ERROR_GSS(gss_rc, minor_status); goto failed; } - ads->ldap.out.min = 4; - ads->ldap.out.sig_size = max_msg_size - ads->ldap.out.max; - ads->ldap.in.min = 4; - ads->ldap.in.max = max_msg_size; + ads->ldap.out.sig_size = max_msg_size - ads->ldap.out.max_unwrapped; + ads->ldap.in.min_wrapped = 0x2C; /* taken from a capture with LDAP unbind */ + ads->ldap.in.max_wrapped = max_msg_size; status = ads_setup_sasl_wrapping(ads, &ads_sasl_gssapi_ops, context_handle); if (!ADS_ERR_OK(status)) { DEBUG(0, ("ads_setup_sasl_wrapping() failed: %s\n", @@ -930,23 +928,19 @@ static ADS_STATUS ads_sasl_gssapi_do_bind(ADS_STRUCT *ads, const gss_name_t serv int i=0; int gss_rc, rc; uint8 *p; - uint32 max_msg_size = 0; + uint32 max_msg_size = ADS_SASL_WRAPPING_OUT_MAX_WRAPPED; + uint8 wrap_type = ADS_SASLWRAP_TYPE_PLAIN; ADS_STATUS status; input_token.value = NULL; input_token.length = 0; - req_flags = GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG; - switch (ads->ldap.wrap_type) { - case ADS_SASLWRAP_TYPE_SEAL: - req_flags |= GSS_C_INTEG_FLAG | GSS_C_CONF_FLAG; - break; - case ADS_SASLWRAP_TYPE_SIGN: - req_flags |= GSS_C_INTEG_FLAG; - break; - case ADS_SASLWRAP_TYPE_PLAIN: - break; - } + /* + * Note: here we always ask the gssapi for sign and seal + * as this is negotiated later after the mutal + * authentication + */ + req_flags = GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG | GSS_C_INTEG_FLAG | GSS_C_CONF_FLAG; for (i=0; i < MAX_GSS_PASSES; i++) { gss_rc = gss_init_sec_context(&minor_status, @@ -1014,20 +1008,37 @@ static ADS_STATUS ads_sasl_gssapi_do_bind(ADS_STRUCT *ads, const gss_name_t serv #endif if (p) { - max_msg_size = (p[1]<<16) | (p[2]<<8) | p[3]; + wrap_type = CVAL(p,0); + SCVAL(p,0,0); + max_msg_size = RIVAL(p,0); } gss_release_buffer(&minor_status, &output_token); + if (!(wrap_type & ads->ldap.wrap_type)) { + /* + * the server doesn't supports the wrap + * type we want :-( + */ + DEBUG(0,("The ldap sasl wrap type doesn't match wanted[%d] server[%d]\n", + ads->ldap.wrap_type, wrap_type)); + DEBUGADD(0,("You may want to set the 'client ldap sasl wrapping' option\n")); + status = ADS_ERROR_NT(NT_STATUS_NOT_SUPPORTED); + goto failed; + } + + /* 0x58 is the minimum windows accepts */ + if (max_msg_size < 0x58) { + max_msg_size = 0x58; + } + output_token.length = 4; output_token.value = SMB_MALLOC(output_token.length); p = (uint8 *)output_token.value; - *p++ = ads->ldap.wrap_type; - /* choose the same size as the server gave us */ - *p++ = max_msg_size>>16; - *p++ = max_msg_size>>8; - *p++ = max_msg_size; + RSIVAL(p,0,max_msg_size); + SCVAL(p,0,ads->ldap.wrap_type); + /* * we used to add sprintf("dn:%s", ads->config.bind_path) here. * but using ads->config.bind_path is the wrong! It should be @@ -1062,16 +1073,15 @@ static ADS_STATUS ads_sasl_gssapi_do_bind(ADS_STRUCT *ads, const gss_name_t serv gss_rc = gss_wrap_size_limit(&minor_status, context_handle, (ads->ldap.wrap_type == ADS_SASLWRAP_TYPE_SEAL), GSS_C_QOP_DEFAULT, - max_msg_size, &ads->ldap.out.max); + max_msg_size, &ads->ldap.out.max_unwrapped); if (gss_rc) { status = ADS_ERROR_GSS(gss_rc, minor_status); goto failed; } - ads->ldap.out.min = 4; - ads->ldap.out.sig_size = max_msg_size - ads->ldap.out.max; - ads->ldap.in.min = 4; - ads->ldap.in.max = max_msg_size; + ads->ldap.out.sig_size = max_msg_size - ads->ldap.out.max_unwrapped; + ads->ldap.in.min_wrapped = 0x2C; /* taken from a capture with LDAP unbind */ + ads->ldap.in.max_wrapped = max_msg_size; status = ads_setup_sasl_wrapping(ads, &ads_sasl_gssapi_ops, context_handle); if (!ADS_ERR_OK(status)) { DEBUG(0, ("ads_setup_sasl_wrapping() failed: %s\n", @@ -1081,6 +1091,7 @@ static ADS_STATUS ads_sasl_gssapi_do_bind(ADS_STRUCT *ads, const gss_name_t serv /* make sure we don't free context_handle */ context_handle = GSS_C_NO_CONTEXT; } + failed: if (context_handle != GSS_C_NO_CONTEXT) -- cgit From bed0ea06936ba76deafd839c25a6abf438d63189 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 6 Aug 2007 13:48:57 +0000 Subject: r24251: Neverending fun: Heimdal doesn't accept all OIDs and gss_import_name() fails with GSS_S_BAD_NAMETYPE using this one. Use the GSS_KRB5_NT_PRINCIPAL_NAME OID instead (which works with at least MIT 1.6.1 and Heimdal 1.0.1). Guenther (This used to be commit f783b32b65ee50e3730ae2d039ca04c9fc5a201a) --- source3/libads/sasl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads/sasl.c') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index bcd8833f30..fb4fb2132d 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -650,7 +650,7 @@ static ADS_STATUS ads_generate_service_principal(ADS_STRUCT *ads, #ifdef HAVE_GSSAPI gss_buffer_desc input_name; gss_OID_desc nt_principal = - {10, CONST_DISCARD(char *, "\052\206\110\206\367\022\001\002\002\002")}; + {10, CONST_DISCARD(char *, "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x01")}; uint32 minor_status; int gss_rc; #endif -- cgit From 647abf0a7b46a10c25e4d147dca2c4885b3ada7c Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 30 Aug 2007 15:39:51 +0000 Subject: r24804: As a temporary workaround, also try to guess the server's principal in the "not_defined_in_RFC4178@please_ignore" case to make at least LDAP SASL binds succeed with windows server 2008. Guenther (This used to be commit f5b3de4d3069eaa750240e3422bac5cb169b6c0a) --- source3/libads/sasl.c | 53 ++++++++++++--------------------------------------- 1 file changed, 12 insertions(+), 41 deletions(-) (limited to 'source3/libads/sasl.c') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index fb4fb2132d..3752d3c2ac 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -657,52 +657,23 @@ static ADS_STATUS ads_generate_service_principal(ADS_STRUCT *ads, ZERO_STRUCTP(p); - /* I've seen a child Windows 2000 domain not send - the principal name back in the first round of + /* I've seen a child Windows 2000 domain not send + the principal name back in the first round of the SASL bind reply. So we guess based on server name and realm. --jerry */ - if (given_principal) { - p->string = SMB_STRDUP(given_principal); - if (!p->string) { - return ADS_ERROR(LDAP_NO_MEMORY); - } - } else 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(&p->string, "ldap/%s@%s", server, server_realm); - - SAFE_FREE(server); - SAFE_FREE(server_realm); - - if (!p->string) { - return ADS_ERROR(LDAP_NO_MEMORY); - } - } else if (ads->config.realm && ads->config.ldap_server_name) { - char *server, *server_realm; + /* Also try best guess when we get the w2k8 ignore + principal back - gd */ - server = SMB_STRDUP(ads->config.ldap_server_name); - server_realm = SMB_STRDUP(ads->config.realm); + if (!given_principal || + strequal(given_principal, ADS_IGNORE_PRINCIPAL)) { - if (!server || !server_realm) { - return ADS_ERROR(LDAP_NO_MEMORY); + status = ads_guess_service_principal(ads, given_principal, + &p->string); + if (!ADS_ERR_OK(status)) { + return status; } - - strlower_m(server); - strupper_m(server_realm); - asprintf(&p->string, "ldap/%s@%s", server, server_realm); - - SAFE_FREE(server); - SAFE_FREE(server_realm); - + } else { + p->string = SMB_STRDUP(given_principal); if (!p->string) { return ADS_ERROR(LDAP_NO_MEMORY); } -- cgit From dc58b03517f3cd68107e0645765725c5e9eb6fb1 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 11 Sep 2007 23:21:50 +0000 Subject: r25108: Make ifdef labyrinth in sasl code a bit more readable. Guenther (This used to be commit f31949ec3456134de474a0219a8cd5dcd15adea6) --- source3/libads/sasl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libads/sasl.c') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 3752d3c2ac..123ad491fb 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -603,7 +603,7 @@ failed: return status; } -#endif +#endif /* HAVE_GSSAPI */ #ifdef HAVE_KRB5 struct ads_service_principal { @@ -774,7 +774,7 @@ static ADS_STATUS ads_sasl_spnego_krb5_bind(ADS_STRUCT *ads, #endif return ads_sasl_spnego_rawkrb5_bind(ads, p->string); } -#endif +#endif /* HAVE_KRB5 */ /* this performs a SASL/SPNEGO bind -- cgit From 1ef2464451ee64023173637fa03e703405dc8c85 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 11 Sep 2007 23:35:17 +0000 Subject: r25109: Remove obsolete argument from ads_guess_service_principal(). Guenther (This used to be commit 2dea9464bba76af4315a8207ccd3e564ec19d146) --- source3/libads/sasl.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'source3/libads/sasl.c') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 123ad491fb..a92bef7ecf 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -667,8 +667,7 @@ static ADS_STATUS ads_generate_service_principal(ADS_STRUCT *ads, if (!given_principal || strequal(given_principal, ADS_IGNORE_PRINCIPAL)) { - status = ads_guess_service_principal(ads, given_principal, - &p->string); + status = ads_guess_service_principal(ads, &p->string); if (!ADS_ERR_OK(status)) { return status; } @@ -1103,7 +1102,7 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) return status; } -#endif /* HAVE_GGSAPI */ +#endif /* HAVE_GSSAPI */ /* mapping between SASL mechanisms and functions */ static struct { -- cgit From 1874c564db100600945c257b97d235757156dc24 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 13 Sep 2007 15:59:46 +0000 Subject: r25133: Fix sasl wrapping (for ldap sign&seal). The gss_import_name() broke as we switched from the internal MIT OID "gss_nt_krb5_principal" to "GSS_KRB5_NT_PRINCIPAL_NAME" and didn't switch from passing the krb5_principal (or better: a pointer to that, see MIT's "*HORRIBLE* bug") to pass the string principal directly. Jerry, Jeremy, neither I could figure out the need of passing in a krb5_principal at all nor could I reproduce the crash you were seeing. I sucessfully tested the code (now importing a string) with MIT 1.2.7, 1.3.6, 1.4.3, 1.5.1, 1.6.1 and Heimdal 0.7.2, 1.0, 1.0.1. Guenther (This used to be commit cb2dc715e33467c8b588161e816e72a948f6860c) --- source3/libads/sasl.c | 51 +++++---------------------------------------------- 1 file changed, 5 insertions(+), 46 deletions(-) (limited to 'source3/libads/sasl.c') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index a92bef7ecf..c4b383e026 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -607,9 +607,7 @@ failed: #ifdef HAVE_KRB5 struct ads_service_principal { - krb5_context ctx; char *string; - krb5_principal principal; #ifdef HAVE_GSSAPI gss_name_t name; #endif @@ -625,14 +623,6 @@ static void ads_free_service_principal(struct ads_service_principal *p) gss_release_name(&minor_status, &p->name); } #endif - if (p->principal) { - krb5_free_principal(p->ctx, p->principal); - } - - if (p->ctx) { - krb5_free_context(p->ctx); - } - ZERO_STRUCTP(p); } @@ -641,15 +631,10 @@ static ADS_STATUS ads_generate_service_principal(ADS_STRUCT *ads, struct ads_service_principal *p) { ADS_STATUS status; - krb5_enctype enc_types[] = { -#ifdef ENCTYPE_ARCFOUR_HMAC - ENCTYPE_ARCFOUR_HMAC, -#endif - ENCTYPE_DES_CBC_MD5, - ENCTYPE_NULL}; #ifdef HAVE_GSSAPI gss_buffer_desc input_name; - gss_OID_desc nt_principal = + /* GSS_KRB5_NT_PRINCIPAL_NAME */ + gss_OID_desc nt_principal = {10, CONST_DISCARD(char *, "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x01")}; uint32 minor_status; int gss_rc; @@ -678,35 +663,9 @@ static ADS_STATUS ads_generate_service_principal(ADS_STRUCT *ads, } } - initialize_krb5_error_table(); - status = ADS_ERROR_KRB5(krb5_init_context(&p->ctx)); - if (!ADS_ERR_OK(status)) { - ads_free_service_principal(p); - return status; - } - status = ADS_ERROR_KRB5(krb5_set_default_tgs_ktypes(p->ctx, enc_types)); - if (!ADS_ERR_OK(status)) { - ads_free_service_principal(p); - return status; - } - status = ADS_ERROR_KRB5(smb_krb5_parse_name(p->ctx, p->string, &p->principal)); - if (!ADS_ERR_OK(status)) { - ads_free_service_principal(p); - return status; - } - #ifdef HAVE_GSSAPI - /* - * The MIT libraries have a *HORRIBLE* bug - input_value.value needs - * to point to the *address* of the krb5_principal, and the gss libraries - * to a shallow copy of the krb5_principal pointer - so we need to keep - * the krb5_principal around until we do the gss_release_name. MIT *SUCKS* ! - * Just one more way in which MIT engineers screwed me over.... JRA. - * - * That's the reason for principal not beeing a local var in this function - */ - input_name.value = &p->principal; - input_name.length = sizeof(p->principal); + input_name.value = p->string; + input_name.length = strlen(p->string); gss_rc = gss_import_name(&minor_status, &input_name, &nt_principal, &p->name); if (gss_rc) { @@ -715,7 +674,7 @@ static ADS_STATUS ads_generate_service_principal(ADS_STRUCT *ads, } #endif - return status; + return ADS_SUCCESS; } /* -- cgit From 3309aacc991605a430bde23f284870eeb31a20a8 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 26 Sep 2007 01:02:52 +0000 Subject: r25328: When using ldap sasl wrapping with gssapi it's important to receive warnings for clock-skew errors. Guenther (This used to be commit 53c99d415d605ab03e3646f6096aff794457dd33) --- source3/libads/sasl.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source3/libads/sasl.c') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index c4b383e026..dec8756a86 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -811,6 +811,11 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) if (ADS_ERR_OK(status)) { status = ads_sasl_spnego_krb5_bind(ads, &p); + if (!ADS_ERR_OK(status)) { + DEBUG(0,("kinit succeeded but " + "ads_sasl_spnego_krb5_bind failed: %s\n", + ads_errstr(status))); + } } ads_free_service_principal(&p); -- cgit From 3529156971e17c7ec13f6a6243f7b613e4666cdd Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 28 Sep 2007 03:54:42 +0000 Subject: r25400: Windows 2008 (Longhorn) Interop fixes for AD specific auth2 flags, and client fixes. Patch from Todd Stetcher . (This used to be commit 8304ccba7346597425307e260e88647e49081f68) --- source3/libads/sasl.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source3/libads/sasl.c') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index dec8756a86..590052ec85 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -747,6 +747,7 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) 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); @@ -784,7 +785,8 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) #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) && -- cgit From 5221ebb299081da6a806362212c6a8ceb9cc70a8 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 28 Sep 2007 18:15:34 +0000 Subject: r25407: Revert Longhorn join patch as it is not correct for the 3.2 tree. The translate_name() used by cli_session_setup_spnego() cann rely Winbindd since it is needed by the join process (and hence before Winbind can be run). (This used to be commit 00a93ed336c5f36643e6e33bd277608eaf05677c) --- source3/libads/sasl.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'source3/libads/sasl.c') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 590052ec85..dec8756a86 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -747,7 +747,6 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) 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); @@ -785,8 +784,7 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) #endif free(OIDs[i]); } - DEBUG(3,("ads_sasl_spnego_bind: got server principal name = %s\n", - (given_principal ? given_principal : NULL))); + DEBUG(3,("ads_sasl_spnego_bind: got server principal name = %s\n", given_principal)); #ifdef HAVE_KRB5 if (!(ads->auth.flags & ADS_AUTH_DISABLE_KERBEROS) && -- cgit From b12e11f29f7b6f02960c1f87cb87c0341403246c Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Sat, 29 Sep 2007 06:44:39 +0000 Subject: r25422: Get rid of some cast warnings. (This used to be commit 3e155b249e03cc9f7bd0cbf3a3ab8a57536bf0ce) --- source3/libads/sasl.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libads/sasl.c') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index dec8756a86..d5eeb8e2b3 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -268,7 +268,7 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) #ifdef HAVE_GSSAPI static ADS_STATUS ads_sasl_gssapi_wrap(ADS_STRUCT *ads, uint8 *buf, uint32 len) { - gss_ctx_id_t context_handle = ads->ldap.wrap_private_data; + gss_ctx_id_t context_handle = (gss_ctx_id_t)ads->ldap.wrap_private_data; ADS_STATUS status; int gss_rc; uint32 minor_status; @@ -309,7 +309,7 @@ static ADS_STATUS ads_sasl_gssapi_wrap(ADS_STRUCT *ads, uint8 *buf, uint32 len) static ADS_STATUS ads_sasl_gssapi_unwrap(ADS_STRUCT *ads) { - gss_ctx_id_t context_handle = ads->ldap.wrap_private_data; + gss_ctx_id_t context_handle = (gss_ctx_id_t)ads->ldap.wrap_private_data; ADS_STATUS status; int gss_rc; uint32 minor_status; @@ -347,7 +347,7 @@ static ADS_STATUS ads_sasl_gssapi_unwrap(ADS_STRUCT *ads) static void ads_sasl_gssapi_disconnect(ADS_STRUCT *ads) { - gss_ctx_id_t context_handle = ads->ldap.wrap_private_data; + gss_ctx_id_t context_handle = (gss_ctx_id_t)ads->ldap.wrap_private_data; uint32 minor_status; gss_delete_sec_context(&minor_status, &context_handle, GSS_C_NO_BUFFER); -- cgit From 30191d1a5704ad2b158386b511558972d539ce47 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 18 Oct 2007 17:40:25 -0700 Subject: RIP BOOL. Convert BOOL -> bool. I found a few interesting bugs in various places whilst doing this (places that assumed BOOL == int). I also need to fix the Samba4 pidl generation (next checkin). Jeremy. (This used to be commit f35a266b3cbb3e5fa6a86be60f34fe340a3ca71f) --- source3/libads/sasl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libads/sasl.c') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index d5eeb8e2b3..3b3838e390 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -369,7 +369,7 @@ static const struct ads_saslwrap_ops ads_sasl_gssapi_ops = { static ADS_STATUS ads_sasl_spnego_gsskrb5_bind(ADS_STRUCT *ads, const gss_name_t serv_name) { ADS_STATUS status; - BOOL ok; + bool ok; uint32 minor_status; int gss_rc, rc; gss_OID_desc krb5_mech_type = @@ -746,7 +746,7 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) char *given_principal = NULL; char *OIDs[ASN1_MAX_OIDS]; #ifdef HAVE_KRB5 - BOOL got_kerberos_mechanism = False; + bool got_kerberos_mechanism = False; #endif rc = ldap_sasl_bind_s(ads->ldap.ld, NULL, "GSS-SPNEGO", NULL, NULL, NULL, &scred); -- cgit From 8fd3a7c43e925e452b7738c50811d8a00b35babb Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 6 Dec 2007 09:53:42 +0100 Subject: libads: fix typo metze (This used to be commit b55b19190d9c1199be13727a75a5936d6f5f15a8) --- source3/libads/sasl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads/sasl.c') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 3b3838e390..798d0b4365 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -329,7 +329,7 @@ static ADS_STATUS ads_sasl_gssapi_unwrap(ADS_STRUCT *ads) return ADS_ERROR_NT(NT_STATUS_ACCESS_DENIED); } - if (wrapped.length < wrapped.length) { + if (wrapped.length < unwrapped.length) { return ADS_ERROR_NT(NT_STATUS_INTERNAL_ERROR); } -- cgit From 1b26a7ea6d00e159b43deec906e6b3971617088a Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 23 Mar 2008 19:30:47 +0100 Subject: Fix Coverity ID 488 "status" was used uninitialized on success -- metze, please check (This used to be commit a0859529c853ffb756b1deee946923b6fff6136e) --- source3/libads/sasl.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/libads/sasl.c') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 798d0b4365..55bc16a1be 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -597,6 +597,8 @@ static ADS_STATUS ads_sasl_spnego_gsskrb5_bind(ADS_STRUCT *ads, const gss_name_t context_handle = GSS_C_NO_CONTEXT; } + status = ADS_SUCCESS; + failed: if (context_handle != GSS_C_NO_CONTEXT) gss_delete_sec_context(&minor_status, &context_handle, GSS_C_NO_BUFFER); -- cgit