verify_user.c revision 178825
155682Smarkm/*
2178825Sdfr * Copyright (c) 1997-2004 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
36178825SdfrRCSID("$Id: verify_user.c 19078 2006-11-20 18:12:41Z lha $");
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    }
81178825Sdfr    krb5_free_cred_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
93178825Sdfrvoid KRB5_LIB_FUNCTION
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
101178825Sdfrint KRB5_LIB_FUNCTION
102178825Sdfrkrb5_verify_opt_alloc(krb5_context context, krb5_verify_opt **opt)
103178825Sdfr{
104178825Sdfr    *opt = calloc(1, sizeof(**opt));
105178825Sdfr    if ((*opt) == NULL) {
106178825Sdfr	krb5_set_error_string(context, "malloc: out of memory");
107178825Sdfr	return ENOMEM;
108178825Sdfr    }
109178825Sdfr    krb5_verify_opt_init(*opt);
110178825Sdfr    return 0;
111178825Sdfr}
112178825Sdfr
113178825Sdfrvoid KRB5_LIB_FUNCTION
114178825Sdfrkrb5_verify_opt_free(krb5_verify_opt *opt)
115178825Sdfr{
116178825Sdfr    free(opt);
117178825Sdfr}
118178825Sdfr
119178825Sdfrvoid KRB5_LIB_FUNCTION
12078527Sassarkrb5_verify_opt_set_ccache(krb5_verify_opt *opt, krb5_ccache ccache)
12178527Sassar{
12278527Sassar    opt->ccache = ccache;
12378527Sassar}
12478527Sassar
125178825Sdfrvoid KRB5_LIB_FUNCTION
12678527Sassarkrb5_verify_opt_set_keytab(krb5_verify_opt *opt, krb5_keytab keytab)
12778527Sassar{
12878527Sassar    opt->keytab = keytab;
12978527Sassar}
13078527Sassar
131178825Sdfrvoid KRB5_LIB_FUNCTION
13278527Sassarkrb5_verify_opt_set_secure(krb5_verify_opt *opt, krb5_boolean secure)
13378527Sassar{
13478527Sassar    opt->secure = secure;
13578527Sassar}
13678527Sassar
137178825Sdfrvoid KRB5_LIB_FUNCTION
13878527Sassarkrb5_verify_opt_set_service(krb5_verify_opt *opt, const char *service)
13978527Sassar{
14078527Sassar    opt->service = service;
14178527Sassar}
14278527Sassar
143178825Sdfrvoid KRB5_LIB_FUNCTION
14478527Sassarkrb5_verify_opt_set_flags(krb5_verify_opt *opt, unsigned int flags)
14578527Sassar{
14678527Sassar    opt->flags |= flags;
14778527Sassar}
14878527Sassar
14978527Sassarstatic krb5_error_code
15078527Sassarverify_user_opt_int(krb5_context context,
15178527Sassar		    krb5_principal principal,
15278527Sassar		    const char *password,
15378527Sassar		    krb5_verify_opt *vopt)
15478527Sassar
15578527Sassar{
15655682Smarkm    krb5_error_code ret;
157178825Sdfr    krb5_get_init_creds_opt *opt;
15855682Smarkm    krb5_creds cred;
15978527Sassar
160178825Sdfr    ret = krb5_get_init_creds_opt_alloc (context, &opt);
161178825Sdfr    if (ret)
162178825Sdfr	return ret;
16372445Sassar    krb5_get_init_creds_opt_set_default_flags(context, NULL,
164178825Sdfr					      krb5_principal_get_realm(context, principal),
165178825Sdfr					      opt);
16655682Smarkm    ret = krb5_get_init_creds_password (context,
16755682Smarkm					&cred,
16855682Smarkm					principal,
169102644Snectar					password,
17055682Smarkm					krb5_prompter_posix,
17155682Smarkm					NULL,
17255682Smarkm					0,
17355682Smarkm					NULL,
174178825Sdfr					opt);
175178825Sdfr    krb5_get_init_creds_opt_free(context, opt);
17655682Smarkm    if(ret)
17755682Smarkm	return ret;
17878527Sassar#define OPT(V, D) ((vopt && (vopt->V)) ? (vopt->V) : (D))
17978527Sassar    return verify_common (context, principal, OPT(ccache, NULL),
18078527Sassar			  OPT(keytab, NULL), vopt ? vopt->secure : TRUE,
18178527Sassar			  OPT(service, "host"), cred);
18278527Sassar#undef OPT
18355682Smarkm}
18455682Smarkm
185178825Sdfrkrb5_error_code KRB5_LIB_FUNCTION
18678527Sassarkrb5_verify_user_opt(krb5_context context,
18778527Sassar		     krb5_principal principal,
18878527Sassar		     const char *password,
18978527Sassar		     krb5_verify_opt *opt)
19078527Sassar{
19178527Sassar    krb5_error_code ret;
19278527Sassar
19378527Sassar    if(opt && (opt->flags & KRB5_VERIFY_LREALMS)) {
19478527Sassar	krb5_realm *realms, *r;
19578527Sassar	ret = krb5_get_default_realms (context, &realms);
19678527Sassar	if (ret)
19778527Sassar	    return ret;
19878527Sassar	ret = KRB5_CONFIG_NODEFREALM;
19978527Sassar
20078527Sassar	for (r = realms; *r != NULL && ret != 0; ++r) {
20178527Sassar	    char *tmp = strdup (*r);
20278527Sassar
20378527Sassar	    if (tmp == NULL) {
20478527Sassar		krb5_free_host_realm (context, realms);
20578527Sassar		krb5_set_error_string (context, "malloc: out of memory");
20678527Sassar		return ENOMEM;
20778527Sassar	    }
20878527Sassar	    free (*krb5_princ_realm (context, principal));
20978527Sassar	    krb5_princ_set_realm (context, principal, &tmp);
21078527Sassar
21178527Sassar	    ret = verify_user_opt_int(context, principal, password, opt);
21278527Sassar	}
21378527Sassar	krb5_free_host_realm (context, realms);
21478527Sassar	if(ret)
21578527Sassar	    return ret;
21678527Sassar    } else
21778527Sassar	ret = verify_user_opt_int(context, principal, password, opt);
21878527Sassar    return ret;
21978527Sassar}
22078527Sassar
22178527Sassar/* compat function that calls above */
22278527Sassar
223178825Sdfrkrb5_error_code KRB5_LIB_FUNCTION
22478527Sassarkrb5_verify_user(krb5_context context,
22578527Sassar		 krb5_principal principal,
22678527Sassar		 krb5_ccache ccache,
22778527Sassar		 const char *password,
22878527Sassar		 krb5_boolean secure,
22978527Sassar		 const char *service)
23078527Sassar{
23178527Sassar    krb5_verify_opt opt;
23278527Sassar
23378527Sassar    krb5_verify_opt_init(&opt);
23478527Sassar
23578527Sassar    krb5_verify_opt_set_ccache(&opt, ccache);
23678527Sassar    krb5_verify_opt_set_secure(&opt, secure);
23778527Sassar    krb5_verify_opt_set_service(&opt, service);
23878527Sassar
23978527Sassar    return krb5_verify_user_opt(context, principal, password, &opt);
24078527Sassar}
24178527Sassar
24255682Smarkm/*
24355682Smarkm * A variant of `krb5_verify_user'.  The realm of `principal' is
24455682Smarkm * ignored and all the local realms are tried.
24555682Smarkm */
24655682Smarkm
247178825Sdfrkrb5_error_code KRB5_LIB_FUNCTION
24855682Smarkmkrb5_verify_user_lrealm(krb5_context context,
24955682Smarkm			krb5_principal principal,
25055682Smarkm			krb5_ccache ccache,
25155682Smarkm			const char *password,
25255682Smarkm			krb5_boolean secure,
25355682Smarkm			const char *service)
25455682Smarkm{
25578527Sassar    krb5_verify_opt opt;
25655682Smarkm
25778527Sassar    krb5_verify_opt_init(&opt);
25878527Sassar
25978527Sassar    krb5_verify_opt_set_ccache(&opt, ccache);
26078527Sassar    krb5_verify_opt_set_secure(&opt, secure);
26178527Sassar    krb5_verify_opt_set_service(&opt, service);
26278527Sassar    krb5_verify_opt_set_flags(&opt, KRB5_VERIFY_LREALMS);
26378527Sassar
26478527Sassar    return krb5_verify_user_opt(context, principal, password, &opt);
26555682Smarkm}
266