summaryrefslogtreecommitdiffstats
path: root/src/lib/gssapi/ac_cred.c
blob: 38102630c7117308db214623513b1100fa0b5ead (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
/*
 * ac_cred.c --- gss_acquire_cred
 * 
 * $Source$
 * $Author$
 * $Header$
 * 
 * Copyright 1991 by the Massachusetts Institute of Technology.
 * All Rights Reserved.
 *
 * For copying and distribution information, please see the file
 * <krb5/copyright.h>.
 *
 */

/*
 * Note: There are really two kinds of credentials in Kerberos V5...
 * the first kind is for users, and we use a krb5_ccache to get at
 * that.  The second kind is for servers, and we use a krb5_keytab to
 * point at that.
 *
 * It is possible to convert from one to another, but we don't address
 * that right now.
 *
 * XXX We need to do something with time_rec.
 */

#include <gssapi.h>

char *gss_krb5_fetchfrom = NULL;

OM_uint32 gss_acquire_cred(minor_status, desired_name, time_req,
			   desired_mechs, cred_usage, output_cred_handle,
			   actual_mechs, time_rec)
	OM_uint32	*minor_status;
	gss_name_t	desired_name;
	OM_uint32	time_req;
	gss_OID_set	desired_mechs;
	int		cred_usage;
	gss_cred_id_t	*output_cred_handle;
	gss_OID_set	*actual_mechs;
	OM_uint32	*time_rec;
{
	krb5_keytab_entry	entry;
	krb5_keytab	keytabid;
	int		do_kerberos = 0;
	int		i;
	krb5_error_code	retval;
	
	*minor_status = 0;

	/*
	 * Figure out which mechanism we should be using.
	 */
	if (desired_mechs == GSS_C_NULL_OID_SET)
		do_kerberos++;
	else {
		for (i = 0; i <= desired_mechs->count; i++) {
			if (gss_compare_OID(&desired_mechs->elements[i],
					   &gss_OID_krb5))
				do_kerberos++;
		}
	}

	/*
	 * Should we return failure here?
	 */
	if (!do_kerberos)
		return(gss_make_re(GSS_RE_FAILURE));
	output_cred_handle->cred_flags = 0;

	/*
	 * This is Kerberos V5 specific stuff starting here.
	 * First, let's try to search the keytab file.
	 * Applications that know what they are doing can mess with
	 * the variable gss_krb_fetchfrom.  Otherwise, we use the
	 * system default keytab file.
	 */
	if (*minor_status = krb5_copy_principal(desired_name,
						&output_cred_handle->principal)) {
		return(gss_make_re(GSS_RE_FAILURE));
	}
	if (gss_krb5_fetchfrom) {
		/* use the named keytab */
		retval = krb5_kt_resolve(gss_krb5_fetchfrom, &keytabid);
	} else {
		/* use default keytab */
		retval = krb5_kt_default(&keytabid);
	}
	if (!retval) {
		retval = krb5_kt_get_entry(keytabid, desired_name, 0, 
						  &entry);
		(void) krb5_kt_close(keytabid);
		if (!retval) {
			output_cred_handle->cred_flags |= GSS_KRB_HAS_SRVTAB;
			output_cred_handle->kvno = entry.vno;
			output_cred_handle->srvtab = entry.key;
			krb5_free_principal(entry.principal);
		}
	}
	/*
	 * Now let's try opening the default credentials file and see
	 * if it contains the desired name.  We could try searching
	 * some directory (like /tmp) if we really cared, but not for
	 * now.
	 *
	 * We're not even looking in the default credentials file
	 * right now.  XXX
	 */

	/*
	 * We're done, clean up and get out.
	 */
	if (actual_mechs) {
		gss_OID_set	set;

		if (!(set = (gss_OID_set)
		      malloc (sizeof(struct gss_OID_set_desc)))) {
			*minor_status = ENOMEM;
			return(gss_make_re(GSS_RE_FAILURE));
		}
		set->count = 1;
		set->elements = &gss_OID_krb5;
		*actual_mechs = set;
	}
	return(GSS_S_COMPLETE);

}