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,
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 <http://www.gnu.org/licenses/>.
*/
#include "includes.h"
+#include "lib/events/events.h"
#include "system/kerberos.h"
#include "heimdal/lib/gssapi/gssapi/gssapi.h"
#include "auth/kerberos/kerberos.h"
#include "auth/credentials/credentials.h"
#include "auth/credentials/credentials_krb5.h"
#include "auth/gensec/gensec.h"
+#include "param/param.h"
enum gensec_gssapi_sasl_state
{
OM_uint32 disp_min_stat, disp_maj_stat;
gss_buffer_desc maj_error_message;
gss_buffer_desc min_error_message;
+ char *maj_error_string, *min_error_string;
OM_uint32 msg_ctx = 0;
char *ret;
maj_error_message.value = NULL;
min_error_message.value = NULL;
+ maj_error_message.length = 0;
+ min_error_message.length = 0;
disp_maj_stat = gss_display_status(&disp_min_stat, maj_stat, GSS_C_GSS_CODE,
mech, &msg_ctx, &maj_error_message);
disp_maj_stat = gss_display_status(&disp_min_stat, min_stat, GSS_C_MECH_CODE,
mech, &msg_ctx, &min_error_message);
- ret = talloc_asprintf(mem_ctx, "%s: %s", (char *)maj_error_message.value, (char *)min_error_message.value);
+
+ maj_error_string = talloc_strndup(mem_ctx, (char *)maj_error_message.value, maj_error_message.length);
+
+ min_error_string = talloc_strndup(mem_ctx, (char *)min_error_message.value, min_error_message.length);
+
+ ret = talloc_asprintf(mem_ctx, "%s: %s", maj_error_string, min_error_string);
+
+ talloc_free(maj_error_string);
+ talloc_free(min_error_string);
gss_release_buffer(&disp_min_stat, &maj_error_message);
gss_release_buffer(&disp_min_stat, &min_error_message);
gensec_gssapi_state->gss_exchange_count = 0;
gensec_gssapi_state->max_wrap_buf_size
- = lp_parm_int(-1, "gensec_gssapi", "max wrap buf size", 65536);
+ = lp_parm_int(NULL, "gensec_gssapi", "max wrap buf size", 65536);
gensec_gssapi_state->sasl = False;
gensec_gssapi_state->sasl_state = STAGE_GSS_NEG;
gensec_gssapi_state->input_chan_bindings = GSS_C_NO_CHANNEL_BINDINGS;
gensec_gssapi_state->want_flags = 0;
- if (lp_parm_bool(-1, "gensec_gssapi", "mutual", True)) {
+ if (lp_parm_bool(NULL, "gensec_gssapi", "mutual", true)) {
gensec_gssapi_state->want_flags |= GSS_C_MUTUAL_FLAG;
}
- if (lp_parm_bool(-1, "gensec_gssapi", "delegation", True)) {
+ if (lp_parm_bool(NULL, "gensec_gssapi", "delegation", true)) {
gensec_gssapi_state->want_flags |= GSS_C_DELEG_FLAG;
}
- if (lp_parm_bool(-1, "gensec_gssapi", "replay", True)) {
+ if (lp_parm_bool(NULL, "gensec_gssapi", "replay", true)) {
gensec_gssapi_state->want_flags |= GSS_C_REPLAY_FLAG;
}
- if (lp_parm_bool(-1, "gensec_gssapi", "sequence", True)) {
+ if (lp_parm_bool(NULL, "gensec_gssapi", "sequence", true)) {
gensec_gssapi_state->want_flags |= GSS_C_SEQUENCE_FLAG;
}
}
/* don't do DNS lookups of any kind, it might/will fail for a netbios name */
- ret = gsskrb5_set_dns_canonicalize(FALSE);
+ ret = gsskrb5_set_dns_canonicalize(lp_parm_bool(NULL, "krb5", "set_dns_canonicalize", false));
if (ret) {
DEBUG(1,("gensec_krb5_start: gsskrb5_set_dns_canonicalize failed\n"));
talloc_free(gensec_gssapi_state);
}
ret = smb_krb5_init_context(gensec_gssapi_state,
+ gensec_security->event_ctx,
&gensec_gssapi_state->smb_krb5_context);
if (ret) {
DEBUG(1,("gensec_krb5_start: krb5_init_context failed (%s)\n",
principal = gensec_get_target_principal(gensec_security);
if (principal && lp_client_use_spnego_principal()) {
- name_token.value = discard_const_p(uint8_t, principal);
- name_token.length = strlen(principal);
-
name_type = GSS_C_NULL_OID;
} else {
principal = talloc_asprintf(gensec_gssapi_state, "%s@%s",
gensec_get_target_service(gensec_security),
hostname);
- name_token.value = discard_const_p(uint8_t, principal);
- name_token.length = strlen(principal);
-
name_type = GSS_C_NT_HOSTBASED_SERVICE;
}
+ name_token.value = discard_const_p(uint8_t, principal);
+ name_token.length = strlen(principal);
+
maj_stat = gss_import_name (&min_stat,
&name_token,
switch (ret) {
case 0:
break;
+ case KRB5KDC_ERR_PREAUTH_FAILED:
+ return NT_STATUS_LOGON_FAILURE;
case KRB5_KDC_UNREACH:
- DEBUG(3, ("Cannot reach a KDC we require\n"));
+ DEBUG(3, ("Cannot reach a KDC we require to contact %s\n", principal));
return NT_STATUS_INVALID_PARAMETER; /* Make SPNEGO ignore us, we can't go any further here */
default:
DEBUG(1, ("Aquiring initiator credentails failed\n"));
}
gensec_gssapi_state->client_cred = gcc;
-
+ if (!talloc_reference(gensec_gssapi_state, gcc)) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
return NT_STATUS_OK;
}
return NT_STATUS_FOOBAR;
}
- principal_string = talloc_strndup(mem_ctx, name_token.value, name_token.length);
+ principal_string = talloc_strndup(mem_ctx,
+ (const char *)name_token.value,
+ name_token.length);
gss_release_buffer(&min_stat, &name_token);
talloc_free(mem_ctx);
return nt_status;
}
- } else if (!lp_parm_bool(-1, "gensec", "require_pac", False)) {
+ } else if (!lp_parm_bool(NULL, "gensec", "require_pac", false)) {
DEBUG(1, ("Unable to find PAC, resorting to local user lookup: %s\n",
gssapi_error_string(mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid)));
nt_status = sam_get_server_info_principal(mem_ctx, principal_string,
return NT_STATUS_NO_MEMORY;
}
+ cli_credentials_set_event_context(session_info->credentials, gensec_security->event_ctx);
cli_credentials_set_conf(session_info->credentials);
+ /* Just so we don't segfault trying to get at a username */
+ cli_credentials_set_anonymous(session_info->credentials);
ret = cli_credentials_set_client_gss_creds(session_info->credentials,
gensec_gssapi_state->delegated_cred_handle,
talloc_free(mem_ctx);
return NT_STATUS_NO_MEMORY;
}
+
+ /* This credential handle isn't useful for password authentication, so ensure nobody tries to do that */
+ cli_credentials_set_kerberos_state(session_info->credentials, CRED_MUST_USE_KERBEROS);
+
/* It has been taken from this place... */
gensec_gssapi_state->delegated_cred_handle = GSS_C_NO_CREDENTIAL;
}