/*
Unix SMB/CIFS implementation.
kerberos utility library
Copyright (C) Andrew Tridgell 2001
Copyright (C) Remus Koos 2001
Copyright (C) Nalin Dahyabhai <nalin@redhat.com> 2004.
Copyright (C) Jeremy Allison 2004.
Copyright (C) Gerald Carter 2006.
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 3 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, see <http://www.gnu.org/licenses/>.
*/
#include "includes.h"
#include "libsmb/namequery.h"
#include "system/filesys.h"
#include "smb_krb5.h"
#include "../librpc/gen_ndr/ndr_misc.h"
#include "../librpc/gen_ndr/samr.h"
#include "libads/kerberos_proto.h"
#include "libads/netlogon_ping.h"
#include "secrets.h"
#include "../lib/tsocket/tsocket.h"
#include "../libcli/util/tstream.h"
#include "../lib/util/tevent_ntstatus.h"
#include "lib/util/asn1.h"
#include "librpc/gen_ndr/netlogon.h"
#ifdef HAVE_KRB5
/*
we use a prompter to avoid a crash bug in the kerberos libs when
dealing with empty passwords
this prompter is just a string copy ...
*/
static krb5_error_code
kerb_prompter(krb5_context ctx, void *data,
const char *name,
const char *banner,
int num_prompts,
krb5_prompt prompts[])
{
if (num_prompts == 0) return 0;
if (num_prompts == 2) {
/*
* only heimdal has a prompt type and we need to deal with it here to
* avoid loops.
*
* removing the prompter completely is not an option as at least these
* versions would crash: heimdal-1.0.2 and heimdal-1.1. Later heimdal
* version have looping detection and return with a proper error code.
*/
#if defined(HAVE_KRB5_PROMPT_TYPE) /* Heimdal */
if (prompts[0].type == KRB5_PROMPT_TYPE_NEW_PASSWORD &&
prompts[1].type == KRB5_PROMPT_TYPE_NEW_PASSWORD_AGAIN) {
/*
* We don't want to change passwords here. We're
* called from heimdal when the KDC returns
* KRB5KDC_ERR_KEY_EXPIRED, but at this point we don't
* have the chance to ask the user for a new
* password. If we return 0 (i.e. success), we will be
* spinning in the endless for-loop in
* change_password() in
* third_party/heimdal/lib/krb5/init_creds_pw.c
*/
return KRB5KDC_ERR_KEY_EXPIRED;
}
#elif defined(HAVE_KRB5_GET_PROMPT_TYPES) /* MIT */
krb5_prompt_type *prompt_types = NULL;
prompt_types = krb5_get_prompt_types(ctx);
if (prompt_types != NULL) {
if (prompt_types[0] == KRB5_PROMPT_TYPE_NEW_PASSWORD &&
prompt_types[1] == KRB5_PROMPT_TYPE_NEW_PASSWORD_AGAIN) {
return KRB5KDC_ERR_KEY_EXP;
|