2 * Copyright (c) 1995-2003 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the Institute nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 #include "kafs_locl.h"
36 struct krb5_kafs_data
{
39 krb5_const_realm realm
;
43 KAFS_RXKAD_2B_KVNO
= 213,
44 KAFS_RXKAD_K5_KVNO
= 256
48 v5_to_kt(krb5_creds
*cred
, uid_t uid
, struct kafs_token
*kt
, int local524
)
54 /* check if des key */
55 if (cred
->session
.keyvalue
.length
!= 8)
64 kvno
= KAFS_RXKAD_2B_KVNO
;
66 ret
= decode_Ticket(cred
->ticket
.data
, cred
->ticket
.length
, &t
, &len
);
72 ASN1_MALLOC_ENCODE(EncryptedData
, buf
, buf_len
, &t
.enc_part
,
79 return KRB5KRB_ERR_GENERIC
;
83 kt
->ticket_len
= buf_len
;
86 kvno
= KAFS_RXKAD_K5_KVNO
;
87 kt
->ticket
= malloc(cred
->ticket
.length
);
88 if (kt
->ticket
== NULL
)
90 kt
->ticket_len
= cred
->ticket
.length
;
91 memcpy(kt
->ticket
, cred
->ticket
.data
, kt
->ticket_len
);
98 * Build a struct ClearToken
101 kt
->ct
.AuthHandle
= kvno
;
102 memcpy(kt
->ct
.HandShakeKey
, cred
->session
.keyvalue
.data
, 8);
104 kt
->ct
.BeginTimestamp
= cred
->times
.starttime
;
105 kt
->ct
.EndTimestamp
= cred
->times
.endtime
;
107 _kafs_fixup_viceid(&kt
->ct
, uid
);
112 static krb5_error_code
113 v5_convert(krb5_context context
, krb5_ccache id
,
114 krb5_creds
*cred
, uid_t uid
,
116 struct kafs_token
*kt
)
125 krb5_appdefault_string (context
, "libkafs",
127 "afs-use-524", "2b", &val
);
130 if (strcasecmp(val
, "local") == 0 ||
131 strcasecmp(val
, "2b") == 0)
132 ret
= v5_to_kt(cred
, uid
, kt
, 1);
133 else if(strcasecmp(val
, "yes") == 0 ||
134 strcasecmp(val
, "true") == 0 ||
136 struct credentials cred4
;
139 ret
= krb524_convert_creds_kdc(context
, cred
, &cred4
);
141 ret
= krb524_convert_creds_kdc_ccache(context
, id
, cred
, &cred4
);
145 ret
= _kafs_v4_to_kt(&cred4
, uid
, kt
);
147 ret
= v5_to_kt(cred
, uid
, kt
, 0);
160 get_cred(struct kafs_data
*data
, const char *name
, const char *inst
,
161 const char *realm
, uid_t uid
, struct kafs_token
*kt
)
164 krb5_creds in_creds
, *out_creds
;
165 struct krb5_kafs_data
*d
= data
->data
;
168 memset(&in_creds
, 0, sizeof(in_creds
));
170 ret
= krb5_make_principal(d
->context
, &in_creds
.server
,
171 realm
, name
, inst
, NULL
);
174 ret
= krb5_cc_get_principal(d
->context
, d
->id
, &in_creds
.client
);
176 krb5_free_principal(d
->context
, in_creds
.server
);
180 in_creds
.session
.keytype
= ETYPE_DES_CBC_CRC
;
182 /* check if des is disable, and in that case enable it for afs */
183 invalid
= krb5_enctype_valid(d
->context
, in_creds
.session
.keytype
);
185 krb5_enctype_enable(d
->context
, in_creds
.session
.keytype
);
187 ret
= krb5_get_credentials(d
->context
, 0, d
->id
, &in_creds
, &out_creds
);
190 krb5_enctype_disable(d
->context
, in_creds
.session
.keytype
);
192 krb5_free_principal(d
->context
, in_creds
.server
);
193 krb5_free_principal(d
->context
, in_creds
.client
);
197 ret
= v5_convert(d
->context
, d
->id
, out_creds
, uid
,
198 (inst
!= NULL
&& inst
[0] != '\0') ? inst
: realm
, kt
);
199 krb5_free_creds(d
->context
, out_creds
);
205 get_error(struct kafs_data
*data
, int error
)
207 struct krb5_kafs_data
*d
= data
->data
;
208 return krb5_get_error_message(d
->context
, error
);
212 free_error(struct kafs_data
*data
, const char *str
)
214 struct krb5_kafs_data
*d
= data
->data
;
215 krb5_free_error_message(d
->context
, str
);
218 static krb5_error_code
219 afslog_uid_int(struct kafs_data
*data
, const char *cell
, const char *rh
,
220 uid_t uid
, const char *homedir
)
223 struct kafs_token kt
;
224 krb5_principal princ
;
225 const char *trealm
; /* ticket realm */
226 struct krb5_kafs_data
*d
= data
->data
;
228 if (cell
== 0 || cell
[0] == 0)
229 return _kafs_afslog_all_local_cells (data
, uid
, homedir
);
231 ret
= krb5_cc_get_principal (d
->context
, d
->id
, &princ
);
235 trealm
= krb5_principal_get_realm (d
->context
, princ
);
238 ret
= _kafs_get_cred(data
, cell
, d
->realm
, trealm
, uid
, &kt
);
239 krb5_free_principal (d
->context
, princ
);
242 ret
= kafs_settoken_rxkad(cell
, &kt
.ct
, kt
.ticket
, kt
.ticket_len
);
249 get_realm(struct kafs_data
*data
, const char *host
)
251 struct krb5_kafs_data
*d
= data
->data
;
254 if(krb5_get_host_realm(d
->context
, host
, &realms
))
256 r
= strdup(realms
[0]);
257 krb5_free_host_realm(d
->context
, realms
);
262 krb5_afslog_uid_home(krb5_context context
,
265 krb5_const_realm realm
,
270 struct krb5_kafs_data d
;
274 kd
.afslog_uid
= afslog_uid_int
;
275 kd
.get_cred
= get_cred
;
276 kd
.get_realm
= get_realm
;
277 kd
.get_error
= get_error
;
278 kd
.free_error
= free_error
;
280 if (context
== NULL
) {
281 ret
= krb5_init_context(&d
.context
);
287 ret
= krb5_cc_default(d
.context
, &d
.id
);
293 ret
= afslog_uid_int(&kd
, cell
, 0, uid
, homedir
);
295 krb5_cc_close(context
, d
.id
);
298 krb5_free_context(d
.context
);
303 krb5_afslog_uid(krb5_context context
,
306 krb5_const_realm realm
,
309 return krb5_afslog_uid_home (context
, id
, cell
, realm
, uid
, NULL
);
313 krb5_afslog(krb5_context context
,
316 krb5_const_realm realm
)
318 return krb5_afslog_uid (context
, id
, cell
, realm
, getuid());
322 krb5_afslog_home(krb5_context context
,
325 krb5_const_realm realm
,
328 return krb5_afslog_uid_home (context
, id
, cell
, realm
, getuid(), homedir
);
336 krb5_realm_of_cell(const char *cell
, char **realm
)
341 kd
.get_realm
= get_realm
;
342 kd
.get_error
= get_error
;
343 kd
.free_error
= free_error
;
344 return _kafs_realm_of_cell(&kd
, cell
, realm
);
352 kafs_settoken5(krb5_context context
, const char *cell
, uid_t uid
,
355 struct kafs_token kt
;
358 ret
= v5_convert(context
, NULL
, cred
, uid
, cell
, &kt
);
362 ret
= kafs_settoken_rxkad(cell
, &kt
.ct
, kt
.ticket
, kt
.ticket_len
);