verify_user.c revision 78527
155682Smarkm/*
272445Sassar * Copyright (c) 1997-2001 Kungliga Tekniska H�gskolan
355682Smarkm * (Royal Institute of Technology, Stockholm, Sweden).
455682Smarkm * All rights reserved.
555682Smarkm *
655682Smarkm * Redistribution and use in source and binary forms, with or without
755682Smarkm * modification, are permitted provided that the following conditions
855682Smarkm * are met:
955682Smarkm *
1055682Smarkm * 1. Redistributions of source code must retain the above copyright
1155682Smarkm *    notice, this list of conditions and the following disclaimer.
1255682Smarkm *
1355682Smarkm * 2. Redistributions in binary form must reproduce the above copyright
1455682Smarkm *    notice, this list of conditions and the following disclaimer in the
1555682Smarkm *    documentation and/or other materials provided with the distribution.
1655682Smarkm *
1755682Smarkm * 3. Neither the name of the Institute nor the names of its contributors
1855682Smarkm *    may be used to endorse or promote products derived from this software
1955682Smarkm *    without specific prior written permission.
2055682Smarkm *
2155682Smarkm * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
2255682Smarkm * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2355682Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2455682Smarkm * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
2555682Smarkm * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2655682Smarkm * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2755682Smarkm * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2855682Smarkm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2955682Smarkm * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3055682Smarkm * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3155682Smarkm * SUCH DAMAGE.
3255682Smarkm */
3355682Smarkm
3455682Smarkm#include "krb5_locl.h"
3555682Smarkm
3678527SassarRCSID("$Id: verify_user.c,v 1.14 2001/05/14 09:06:53 joda Exp $");
3755682Smarkm
3855682Smarkmstatic krb5_error_code
3955682Smarkmverify_common (krb5_context context,
4055682Smarkm	       krb5_principal principal,
4155682Smarkm	       krb5_ccache ccache,
4278527Sassar	       krb5_keytab keytab,
4355682Smarkm	       krb5_boolean secure,
4455682Smarkm	       const char *service,
4555682Smarkm	       krb5_creds cred)
4655682Smarkm{
4755682Smarkm    krb5_error_code ret;
4855682Smarkm    krb5_principal server;
4955682Smarkm    krb5_verify_init_creds_opt vopt;
5055682Smarkm    krb5_ccache id;
5155682Smarkm
5255682Smarkm    ret = krb5_sname_to_principal (context, NULL, service, KRB5_NT_SRV_HST,
5355682Smarkm				   &server);
5478527Sassar    if(ret)
5578527Sassar	return ret;
5655682Smarkm
5755682Smarkm    krb5_verify_init_creds_opt_init(&vopt);
5855682Smarkm    krb5_verify_init_creds_opt_set_ap_req_nofail(&vopt, secure);
5955682Smarkm
6055682Smarkm    ret = krb5_verify_init_creds(context,
6155682Smarkm				 &cred,
6255682Smarkm				 server,
6378527Sassar				 keytab,
6455682Smarkm				 NULL,
6555682Smarkm				 &vopt);
6655682Smarkm    krb5_free_principal(context, server);
6778527Sassar    if(ret)
6878527Sassar	return ret;
6955682Smarkm    if(ccache == NULL)
7055682Smarkm	ret = krb5_cc_default (context, &id);
7155682Smarkm    else
7255682Smarkm	id = ccache;
7355682Smarkm    if(ret == 0){
7455682Smarkm	ret = krb5_cc_initialize(context, id, principal);
7555682Smarkm	if(ret == 0){
7655682Smarkm	    ret = krb5_cc_store_cred(context, id, &cred);
7755682Smarkm	}
7855682Smarkm	if(ccache == NULL)
7955682Smarkm	    krb5_cc_close(context, id);
8055682Smarkm    }
8155682Smarkm    krb5_free_creds_contents(context, &cred);
8255682Smarkm    return ret;
8355682Smarkm}
8455682Smarkm
8555682Smarkm/*
8655682Smarkm * Verify user `principal' with `password'.
8755682Smarkm *
8855682Smarkm * If `secure', also verify against local service key for `service'.
8955682Smarkm *
9055682Smarkm * As a side effect, fresh tickets are obtained and stored in `ccache'.
9155682Smarkm */
9255682Smarkm
9378527Sassarvoid
9478527Sassarkrb5_verify_opt_init(krb5_verify_opt *opt)
9555682Smarkm{
9678527Sassar    memset(opt, 0, sizeof(*opt));
9778527Sassar    opt->secure = TRUE;
9878527Sassar    opt->service = "host";
9978527Sassar}
10055682Smarkm
10178527Sassarvoid
10278527Sassarkrb5_verify_opt_set_ccache(krb5_verify_opt *opt, krb5_ccache ccache)
10378527Sassar{
10478527Sassar    opt->ccache = ccache;
10578527Sassar}
10678527Sassar
10778527Sassarvoid
10878527Sassarkrb5_verify_opt_set_keytab(krb5_verify_opt *opt, krb5_keytab keytab)
10978527Sassar{
11078527Sassar    opt->keytab = keytab;
11178527Sassar}
11278527Sassar
11378527Sassarvoid
11478527Sassarkrb5_verify_opt_set_secure(krb5_verify_opt *opt, krb5_boolean secure)
11578527Sassar{
11678527Sassar    opt->secure = secure;
11778527Sassar}
11878527Sassar
11978527Sassarvoid
12078527Sassarkrb5_verify_opt_set_service(krb5_verify_opt *opt, const char *service)
12178527Sassar{
12278527Sassar    opt->service = service;
12378527Sassar}
12478527Sassar
12578527Sassarvoid
12678527Sassarkrb5_verify_opt_set_flags(krb5_verify_opt *opt, unsigned int flags)
12778527Sassar{
12878527Sassar    opt->flags |= flags;
12978527Sassar}
13078527Sassar
13178527Sassarstatic krb5_error_code
13278527Sassarverify_user_opt_int(krb5_context context,
13378527Sassar		    krb5_principal principal,
13478527Sassar		    const char *password,
13578527Sassar		    krb5_verify_opt *vopt)
13678527Sassar
13778527Sassar{
13855682Smarkm    krb5_error_code ret;
13955682Smarkm    krb5_get_init_creds_opt opt;
14055682Smarkm    krb5_creds cred;
14178527Sassar
14255682Smarkm    krb5_get_init_creds_opt_init (&opt);
14372445Sassar    krb5_get_init_creds_opt_set_default_flags(context, NULL,
14472445Sassar					      *krb5_princ_realm(context, principal),
14572445Sassar					      &opt);
14655682Smarkm    ret = krb5_get_init_creds_password (context,
14755682Smarkm					&cred,
14855682Smarkm					principal,
14955682Smarkm					(char*)password,
15055682Smarkm					krb5_prompter_posix,
15155682Smarkm					NULL,
15255682Smarkm					0,
15355682Smarkm					NULL,
15455682Smarkm					&opt);
15555682Smarkm    if(ret)
15655682Smarkm	return ret;
15778527Sassar#define OPT(V, D) ((vopt && (vopt->V)) ? (vopt->V) : (D))
15878527Sassar    return verify_common (context, principal, OPT(ccache, NULL),
15978527Sassar			  OPT(keytab, NULL), vopt ? vopt->secure : TRUE,
16078527Sassar			  OPT(service, "host"), cred);
16178527Sassar#undef OPT
16255682Smarkm}
16355682Smarkm
16478527Sassarkrb5_error_code
16578527Sassarkrb5_verify_user_opt(krb5_context context,
16678527Sassar		     krb5_principal principal,
16778527Sassar		     const char *password,
16878527Sassar		     krb5_verify_opt *opt)
16978527Sassar{
17078527Sassar    krb5_error_code ret;
17178527Sassar
17278527Sassar    if(opt && (opt->flags & KRB5_VERIFY_LREALMS)) {
17378527Sassar	krb5_realm *realms, *r;
17478527Sassar	ret = krb5_get_default_realms (context, &realms);
17578527Sassar	if (ret)
17678527Sassar	    return ret;
17778527Sassar	ret = KRB5_CONFIG_NODEFREALM;
17878527Sassar
17978527Sassar	for (r = realms; *r != NULL && ret != 0; ++r) {
18078527Sassar	    char *tmp = strdup (*r);
18178527Sassar
18278527Sassar	    if (tmp == NULL) {
18378527Sassar		krb5_free_host_realm (context, realms);
18478527Sassar		krb5_set_error_string (context, "malloc: out of memory");
18578527Sassar		return ENOMEM;
18678527Sassar	    }
18778527Sassar	    free (*krb5_princ_realm (context, principal));
18878527Sassar	    krb5_princ_set_realm (context, principal, &tmp);
18978527Sassar
19078527Sassar	    ret = verify_user_opt_int(context, principal, password, opt);
19178527Sassar	}
19278527Sassar	krb5_free_host_realm (context, realms);
19378527Sassar	if(ret)
19478527Sassar	    return ret;
19578527Sassar    } else
19678527Sassar	ret = verify_user_opt_int(context, principal, password, opt);
19778527Sassar    return ret;
19878527Sassar}
19978527Sassar
20078527Sassar/* compat function that calls above */
20178527Sassar
20278527Sassarkrb5_error_code
20378527Sassarkrb5_verify_user(krb5_context context,
20478527Sassar		 krb5_principal principal,
20578527Sassar		 krb5_ccache ccache,
20678527Sassar		 const char *password,
20778527Sassar		 krb5_boolean secure,
20878527Sassar		 const char *service)
20978527Sassar{
21078527Sassar    krb5_verify_opt opt;
21178527Sassar
21278527Sassar    krb5_verify_opt_init(&opt);
21378527Sassar
21478527Sassar    krb5_verify_opt_set_ccache(&opt, ccache);
21578527Sassar    krb5_verify_opt_set_secure(&opt, secure);
21678527Sassar    krb5_verify_opt_set_service(&opt, service);
21778527Sassar
21878527Sassar    return krb5_verify_user_opt(context, principal, password, &opt);
21978527Sassar}
22078527Sassar
22155682Smarkm/*
22255682Smarkm * A variant of `krb5_verify_user'.  The realm of `principal' is
22355682Smarkm * ignored and all the local realms are tried.
22455682Smarkm */
22555682Smarkm
22655682Smarkmkrb5_error_code
22755682Smarkmkrb5_verify_user_lrealm(krb5_context context,
22855682Smarkm			krb5_principal principal,
22955682Smarkm			krb5_ccache ccache,
23055682Smarkm			const char *password,
23155682Smarkm			krb5_boolean secure,
23255682Smarkm			const char *service)
23355682Smarkm{
23478527Sassar    krb5_verify_opt opt;
23555682Smarkm
23678527Sassar    krb5_verify_opt_init(&opt);
23778527Sassar
23878527Sassar    krb5_verify_opt_set_ccache(&opt, ccache);
23978527Sassar    krb5_verify_opt_set_secure(&opt, secure);
24078527Sassar    krb5_verify_opt_set_service(&opt, service);
24178527Sassar    krb5_verify_opt_set_flags(&opt, KRB5_VERIFY_LREALMS);
24278527Sassar
24378527Sassar    return krb5_verify_user_opt(context, principal, password, &opt);
24455682Smarkm}
245