mirror of
https://git.openafs.org/openafs.git
synced 2025-01-18 06:50:12 +00:00
Merge branch 'rxkad-kdf-1.4' into origin/openafs-stable-1_4_x
Merge the changes for OpenAFS-SA-2013-003 and OpenAFS-2013-004 back in to the stable branch Change-Id: I0cd53a568758e3e81b487ba4f955b7e6c021b89a
This commit is contained in:
commit
30922c5d91
@ -1,8 +1,8 @@
|
||||
AC_INIT(src/libafs/Makefile.common.in)
|
||||
AM_INIT_AUTOMAKE(openafs-libafs,1.4.12)
|
||||
AM_INIT_AUTOMAKE(openafs-libafs,1.4.15)
|
||||
AC_CONFIG_HEADER(src/config/afsconfig.h)
|
||||
MACOS_VERSION=1.4.12
|
||||
LINUX_PKGVER=1.4.12
|
||||
MACOS_VERSION=1.4.15
|
||||
LINUX_PKGVER=1.4.15
|
||||
LINUX_PKGREL=1.1
|
||||
#LINUX_PKGREL=0.pre4
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
AC_INIT(src/config/stds.h)
|
||||
AM_INIT_AUTOMAKE(openafs,1.4.12)
|
||||
AM_INIT_AUTOMAKE(openafs,1.4.15)
|
||||
AC_CONFIG_HEADER(src/config/afsconfig.h)
|
||||
MACOS_VERSION=1.4.12
|
||||
LINUX_PKGVER=1.4.12
|
||||
MACOS_VERSION=1.4.15
|
||||
LINUX_PKGVER=1.4.15
|
||||
LINUX_PKGREL=1.1
|
||||
#LINUX_PKGREL=0.pre3
|
||||
|
||||
|
@ -73,6 +73,7 @@
|
||||
#ifdef AFS_SUN5_ENV
|
||||
#include <sys/ioccom.h>
|
||||
#endif
|
||||
#include <afs/akimpersonate.h>
|
||||
#include <afs/auth.h>
|
||||
#include <afs/cellconfig.h>
|
||||
#include <afs/vice.h>
|
||||
@ -180,108 +181,12 @@ static int get_user_realm(krb5_context, char *);
|
||||
#error "Must have either krb5_princ_size or krb5_principal_get_comp_string"
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE_KRB5_ENCRYPT_TKT_PART) && defined(HAVE_ENCODE_KRB5_ENC_TKT_PART) && defined(HAVE_KRB5_C_ENCRYPT)
|
||||
krb5_error_code
|
||||
krb5_encrypt_tkt_part(krb5_context context,
|
||||
const krb5_keyblock *key,
|
||||
krb5_ticket *ticket)
|
||||
{
|
||||
krb5_data *data = 0;
|
||||
int code;
|
||||
size_t enclen;
|
||||
|
||||
if ((code = encode_krb5_enc_tkt_part(ticket->enc_part2, &data)))
|
||||
goto Done;
|
||||
if ((code = krb5_c_encrypt_length(context, key->enctype,
|
||||
data->length, &enclen)))
|
||||
goto Done;
|
||||
ticket->enc_part.ciphertext.length = enclen;
|
||||
if (!(ticket->enc_part.ciphertext.data = malloc(enclen))) {
|
||||
code = ENOMEM;
|
||||
goto Done;
|
||||
}
|
||||
if ((code = krb5_c_encrypt(context, key, KRB5_KEYUSAGE_KDC_REP_TICKET,
|
||||
0, data, &ticket->enc_part))) {
|
||||
free(ticket->enc_part.ciphertext.data);
|
||||
ticket->enc_part.ciphertext.data = 0;
|
||||
}
|
||||
Done:
|
||||
if (data) {
|
||||
if (data->data)
|
||||
free(data->data);
|
||||
free(data);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_KRB5_CREDS_KEYBLOCK)
|
||||
|
||||
#define get_cred_keydata(c) c->keyblock.contents
|
||||
#define get_cred_keylen(c) c->keyblock.length
|
||||
#define get_creds_enctype(c) c->keyblock.enctype
|
||||
|
||||
#elif defined(HAVE_KRB5_CREDS_SESSION)
|
||||
|
||||
#define get_cred_keydata(c) c->session.keyvalue.data
|
||||
#define get_cred_keylen(c) c->session.keyvalue.length
|
||||
#define get_creds_enctype(c) c->session.keytype
|
||||
|
||||
#else
|
||||
#error "Must have either keyblock or session member of krb5_creds"
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE_KRB5_524_CONVERT_CREDS) && defined(HAVE_KRB524_CONVERT_CREDS_KDC)
|
||||
#define krb5_524_convert_creds krb524_convert_creds_kdc
|
||||
#elif !defined(HAVE_KRB5_524_CONVERT_CREDS) && !defined(HAVE_KRB524_CONVERT_CREDS_KDC)
|
||||
#define HAVE_NO_KRB5_524
|
||||
#endif
|
||||
|
||||
#if USING_HEIMDAL
|
||||
#define deref_keyblock_enctype(kb) \
|
||||
((kb)->keytype)
|
||||
|
||||
#define deref_entry_keyblock(entry) \
|
||||
entry->keyblock
|
||||
|
||||
#define deref_session_key(creds) \
|
||||
creds->session
|
||||
|
||||
#define deref_enc_tkt_addrs(tkt) \
|
||||
tkt->caddr
|
||||
|
||||
#define deref_enc_length(enc) \
|
||||
((enc)->cipher.length)
|
||||
|
||||
#define deref_enc_data(enc) \
|
||||
((enc)->cipher.data)
|
||||
|
||||
#define krb5_free_keytab_entry_contents krb5_kt_free_entry
|
||||
|
||||
#else
|
||||
#define deref_keyblock_enctype(kb) \
|
||||
((kb)->enctype)
|
||||
|
||||
#define deref_entry_keyblock(entry) \
|
||||
entry->key
|
||||
|
||||
#define deref_session_key(creds) \
|
||||
creds->keyblock
|
||||
|
||||
#define deref_enc_tkt_addrs(tkt) \
|
||||
tkt->caddrs
|
||||
|
||||
#define deref_enc_length(enc) \
|
||||
((enc)->ciphertext.length)
|
||||
|
||||
#define deref_enc_data(enc) \
|
||||
((enc)->ciphertext.data)
|
||||
|
||||
#endif
|
||||
|
||||
#define deref_entry_enctype(entry) \
|
||||
deref_keyblock_enctype(&deref_entry_keyblock(entry))
|
||||
|
||||
/*
|
||||
* Provide a replacement for strerror if we don't have it
|
||||
*/
|
||||
@ -638,6 +543,8 @@ static int auth_to_cell(krb5_context context, char *cell, char *realm)
|
||||
char *p;
|
||||
char k4name[ANAME_SZ], k4inst[INST_SZ], k4realm[REALM_SZ];
|
||||
int len;
|
||||
void *inkey = get_cred_keydata(v5cred);
|
||||
size_t inkey_sz = get_cred_keylen(v5cred);
|
||||
|
||||
if (dflag)
|
||||
printf("Using Kerberos V5 ticket natively\n");
|
||||
@ -675,8 +582,9 @@ static int auth_to_cell(krb5_context context, char *cell, char *realm)
|
||||
atoken.kvno = RXKAD_TKT_TYPE_KERBEROS_V5;
|
||||
atoken.startTime = v5cred->times.starttime;;
|
||||
atoken.endTime = v5cred->times.endtime;
|
||||
memcpy(&atoken.sessionKey, get_cred_keydata(v5cred),
|
||||
get_cred_keylen(v5cred));
|
||||
if (tkt_DeriveDesKey(get_creds_enctype(v5cred), inkey, inkey_sz,
|
||||
&atoken.sessionKey) != 0)
|
||||
return RXKADBADKEY;
|
||||
atoken.ticketLen = v5cred->ticket.length;
|
||||
memcpy(atoken.ticket, v5cred->ticket.data, atoken.ticketLen);
|
||||
#ifndef HAVE_NO_KRB5_524
|
||||
@ -1549,327 +1457,6 @@ static int isdir(char *path, unsigned char *val)
|
||||
}
|
||||
}
|
||||
|
||||
static krb5_error_code get_credv5_akimpersonate(krb5_context context,
|
||||
char* keytab,
|
||||
krb5_principal service_principal,
|
||||
krb5_principal client_principal,
|
||||
time_t starttime,
|
||||
time_t endtime,
|
||||
int *allowed_enctypes,
|
||||
int *paddress,
|
||||
krb5_creds** out_creds /* out */ )
|
||||
{
|
||||
#if defined(USING_HEIMDAL) || (defined(HAVE_ENCODE_KRB5_ENC_TKT) && defined(HAVE_ENCODE_KRB5_TICKET) && defined(HAVE_KRB5_C_ENCRYPT))
|
||||
krb5_error_code code;
|
||||
krb5_keytab kt = 0;
|
||||
krb5_kt_cursor cursor[1];
|
||||
krb5_keytab_entry entry[1];
|
||||
krb5_ccache cc = 0;
|
||||
krb5_creds *creds = 0;
|
||||
krb5_enctype enctype;
|
||||
krb5_kvno kvno;
|
||||
krb5_keyblock session_key[1];
|
||||
#if USING_HEIMDAL
|
||||
Ticket ticket_reply[1];
|
||||
EncTicketPart enc_tkt_reply[1];
|
||||
krb5_address address[30];
|
||||
krb5_addresses faddr[1];
|
||||
int temp_vno[1];
|
||||
time_t temp_time[2];
|
||||
#else
|
||||
krb5_ticket ticket_reply[1];
|
||||
krb5_enc_tkt_part enc_tkt_reply[1];
|
||||
krb5_address address[30], *faddr[30];
|
||||
#endif
|
||||
krb5_data * temp;
|
||||
int i;
|
||||
static int any_enctype[] = {0};
|
||||
*out_creds = 0;
|
||||
if (!(creds = malloc(sizeof *creds))) {
|
||||
code = ENOMEM;
|
||||
goto cleanup;
|
||||
}
|
||||
if (!allowed_enctypes)
|
||||
allowed_enctypes = any_enctype;
|
||||
|
||||
cc = 0;
|
||||
enctype = 0; /* AKIMPERSONATE_IGNORE_ENCTYPE */
|
||||
kvno = 0; /* AKIMPERSONATE_IGNORE_VNO */
|
||||
memset((char*)creds, 0, sizeof *creds);
|
||||
memset((char*)entry, 0, sizeof *entry);
|
||||
memset((char*)session_key, 0, sizeof *session_key);
|
||||
memset((char*)ticket_reply, 0, sizeof *ticket_reply);
|
||||
memset((char*)enc_tkt_reply, 0, sizeof *enc_tkt_reply);
|
||||
code = krb5_kt_resolve(context, keytab, &kt);
|
||||
if (code) {
|
||||
if (keytab)
|
||||
afs_com_err(progname, code, "while resolving keytab %s", keytab);
|
||||
else
|
||||
afs_com_err(progname, code, "while resolving default keytab");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (service_principal) {
|
||||
for (i = 0; (enctype = allowed_enctypes[i]) || !i; ++i) {
|
||||
code = krb5_kt_get_entry(context,
|
||||
kt,
|
||||
service_principal,
|
||||
kvno,
|
||||
enctype,
|
||||
entry);
|
||||
if (!code) {
|
||||
if (allowed_enctypes[i])
|
||||
deref_keyblock_enctype(session_key) = allowed_enctypes[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (code) {
|
||||
afs_com_err(progname, code,"while scanning keytab entries");
|
||||
goto cleanup;
|
||||
}
|
||||
} else {
|
||||
krb5_keytab_entry new[1];
|
||||
int best = -1;
|
||||
memset(new, 0, sizeof *new);
|
||||
if ((code == krb5_kt_start_seq_get(context, kt, cursor))) {
|
||||
afs_com_err(progname, code, "while starting keytab scan");
|
||||
goto cleanup;
|
||||
}
|
||||
while (!(code = krb5_kt_next_entry(context, kt, new, cursor))) {
|
||||
for (i = 0;
|
||||
allowed_enctypes[i] && allowed_enctypes[i]
|
||||
!= deref_entry_enctype(new); ++i)
|
||||
;
|
||||
if ((!i || allowed_enctypes[i]) &&
|
||||
(best < 0 || best > i)) {
|
||||
krb5_free_keytab_entry_contents(context, entry);
|
||||
*entry = *new;
|
||||
memset(new, 0, sizeof *new);
|
||||
} else krb5_free_keytab_entry_contents(context, new);
|
||||
}
|
||||
if ((i = krb5_kt_end_seq_get(context, kt, cursor))) {
|
||||
afs_com_err(progname, i, "while ending keytab scan");
|
||||
code = i;
|
||||
goto cleanup;
|
||||
}
|
||||
if (best < 0) {
|
||||
afs_com_err(progname, code, "while scanning keytab");
|
||||
goto cleanup;
|
||||
}
|
||||
deref_keyblock_enctype(session_key) = deref_entry_enctype(entry);
|
||||
}
|
||||
|
||||
/* Make Ticket */
|
||||
|
||||
#if USING_HEIMDAL
|
||||
if ((code = krb5_generate_random_keyblock(context,
|
||||
deref_keyblock_enctype(session_key), session_key))) {
|
||||
afs_com_err(progname, code, "while making session key");
|
||||
goto cleanup;
|
||||
}
|
||||
enc_tkt_reply->flags.initial = 1;
|
||||
enc_tkt_reply->transited.tr_type = DOMAIN_X500_COMPRESS;
|
||||
enc_tkt_reply->cname = client_principal->name;
|
||||
enc_tkt_reply->crealm = client_principal->realm;
|
||||
enc_tkt_reply->key = *session_key;
|
||||
{
|
||||
static krb5_data empty_string;
|
||||
enc_tkt_reply->transited.contents = empty_string;
|
||||
}
|
||||
enc_tkt_reply->authtime = starttime;
|
||||
enc_tkt_reply->starttime = temp_time;
|
||||
*enc_tkt_reply->starttime = starttime;
|
||||
#if 0
|
||||
enc_tkt_reply->renew_till = temp_time + 1;
|
||||
*enc_tkt_reply->renew_till = endtime;
|
||||
#endif
|
||||
enc_tkt_reply->endtime = endtime;
|
||||
#else
|
||||
if ((code = krb5_c_make_random_key(context,
|
||||
deref_keyblock_enctype(session_key), session_key))) {
|
||||
afs_com_err(progname, code, "while making session key");
|
||||
goto cleanup;
|
||||
}
|
||||
enc_tkt_reply->magic = KV5M_ENC_TKT_PART;
|
||||
#define DATACAST (unsigned char *)
|
||||
enc_tkt_reply->flags |= TKT_FLG_INITIAL;
|
||||
enc_tkt_reply->transited.tr_type = KRB5_DOMAIN_X500_COMPRESS;
|
||||
enc_tkt_reply->session = session_key;
|
||||
enc_tkt_reply->client = client_principal;
|
||||
{
|
||||
static krb5_data empty_string;
|
||||
enc_tkt_reply->transited.tr_contents = empty_string;
|
||||
}
|
||||
enc_tkt_reply->times.authtime = starttime;
|
||||
enc_tkt_reply->times.starttime = starttime; /* krb524init needs this */
|
||||
enc_tkt_reply->times.endtime = endtime;
|
||||
#endif /* USING_HEIMDAL */
|
||||
/* NB: We will discard address for now--ignoring caddr field
|
||||
in any case. MIT branch does what it always did. */
|
||||
|
||||
if (paddress && *paddress) {
|
||||
deref_enc_tkt_addrs(enc_tkt_reply) = faddr;
|
||||
#if USING_HEIMDAL
|
||||
faddr->len = 0;
|
||||
faddr->val = address;
|
||||
#endif
|
||||
for (i = 0; paddress[i]; ++i) {
|
||||
#if USING_HEIMDAL
|
||||
address[i].addr_type = KRB5_ADDRESS_INET;
|
||||
address[i].address.data = (void*)(paddress+i);
|
||||
address[i].address.length = sizeof(paddress[i]);
|
||||
#else
|
||||
#if !USING_SSL
|
||||
address[i].magic = KV5M_ADDRESS;
|
||||
address[i].addrtype = ADDRTYPE_INET;
|
||||
#else
|
||||
address[i].addrtype = AF_INET;
|
||||
#endif
|
||||
address[i].contents = (void*)(paddress+i);
|
||||
address[i].length = sizeof(int);
|
||||
faddr[i] = address+i;
|
||||
#endif
|
||||
}
|
||||
#if USING_HEIMDAL
|
||||
faddr->len = i;
|
||||
#else
|
||||
faddr[i] = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if USING_HEIMDAL
|
||||
ticket_reply->sname = service_principal->name;
|
||||
ticket_reply->realm = service_principal->realm;
|
||||
|
||||
{ /* crypto block */
|
||||
krb5_crypto crypto = 0;
|
||||
unsigned char *buf = 0;
|
||||
size_t buf_size, buf_len;
|
||||
char *what;
|
||||
|
||||
ASN1_MALLOC_ENCODE(EncTicketPart, buf, buf_size,
|
||||
enc_tkt_reply, &buf_len, code);
|
||||
if(code) {
|
||||
afs_com_err(progname, code, "while encoding ticket");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if(buf_len != buf_size) {
|
||||
afs_com_err(progname, code,
|
||||
"%d != %d while encoding ticket (internal ASN.1 encoder error",
|
||||
buf_len, buf_size);
|
||||
goto cleanup;
|
||||
}
|
||||
what = "krb5_crypto_init";
|
||||
code = krb5_crypto_init(context,
|
||||
&deref_entry_keyblock(entry),
|
||||
deref_entry_enctype(entry),
|
||||
&crypto);
|
||||
if(!code) {
|
||||
what = "krb5_encrypt";
|
||||
code = krb5_encrypt_EncryptedData(context, crypto, KRB5_KU_TICKET,
|
||||
buf, buf_len, entry->vno, &(ticket_reply->enc_part));
|
||||
}
|
||||
if (buf) free(buf);
|
||||
if (crypto) krb5_crypto_destroy(context, crypto);
|
||||
if(code) {
|
||||
afs_com_err(progname, code, "while %s", what);
|
||||
goto cleanup;
|
||||
}
|
||||
} /* crypto block */
|
||||
ticket_reply->enc_part.etype = deref_entry_enctype(entry);
|
||||
ticket_reply->enc_part.kvno = temp_vno;
|
||||
*ticket_reply->enc_part.kvno = entry->vno;
|
||||
ticket_reply->tkt_vno = 5;
|
||||
#else
|
||||
ticket_reply->server = service_principal;
|
||||
ticket_reply->enc_part2 = enc_tkt_reply;
|
||||
if ((code = krb5_encrypt_tkt_part(context, &deref_entry_keyblock(entry), ticket_reply))) {
|
||||
afs_com_err(progname, code, "while making ticket");
|
||||
goto cleanup;
|
||||
}
|
||||
ticket_reply->enc_part.kvno = entry->vno;
|
||||
#endif
|
||||
|
||||
/* Construct Creds */
|
||||
|
||||
if ((code = krb5_copy_principal(context, service_principal,
|
||||
&creds->server))) {
|
||||
afs_com_err(progname, code, "while copying service principal");
|
||||
goto cleanup;
|
||||
}
|
||||
if ((code = krb5_copy_principal(context, client_principal,
|
||||
&creds->client))) {
|
||||
afs_com_err(progname, code, "while copying client principal");
|
||||
goto cleanup;
|
||||
}
|
||||
if ((code = krb5_copy_keyblock_contents(context, session_key,
|
||||
&deref_session_key(creds)))) {
|
||||
afs_com_err(progname, code, "while copying session key");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
#if USING_HEIMDAL
|
||||
creds->times.authtime = enc_tkt_reply->authtime;
|
||||
creds->times.starttime = *(enc_tkt_reply->starttime);
|
||||
creds->times.endtime = enc_tkt_reply->endtime;
|
||||
creds->times.renew_till = 0; /* *(enc_tkt_reply->renew_till) */
|
||||
creds->flags.b = enc_tkt_reply->flags;
|
||||
#else
|
||||
creds->times = enc_tkt_reply->times;
|
||||
creds->ticket_flags = enc_tkt_reply->flags;
|
||||
#endif
|
||||
if (!deref_enc_tkt_addrs(enc_tkt_reply))
|
||||
;
|
||||
else if ((code = krb5_copy_addresses(context,
|
||||
deref_enc_tkt_addrs(enc_tkt_reply), &creds->addresses))) {
|
||||
afs_com_err(progname, code, "while copying addresses");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
#if USING_HEIMDAL
|
||||
{
|
||||
size_t creds_tkt_len;
|
||||
ASN1_MALLOC_ENCODE(Ticket, creds->ticket.data, creds->ticket.length,
|
||||
ticket_reply, &creds_tkt_len, code);
|
||||
if(code) {
|
||||
afs_com_err(progname, code, "while encoding ticket");
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
#else
|
||||
if ((code = encode_krb5_ticket(ticket_reply, &temp))) {
|
||||
afs_com_err(progname, code, "while encoding ticket");
|
||||
goto cleanup;
|
||||
}
|
||||
creds->ticket = *temp;
|
||||
free(temp);
|
||||
#endif
|
||||
/* return creds */
|
||||
*out_creds = creds;
|
||||
creds = 0;
|
||||
cleanup:
|
||||
if (deref_enc_data(&ticket_reply->enc_part))
|
||||
free(deref_enc_data(&ticket_reply->enc_part));
|
||||
krb5_free_keytab_entry_contents(context, entry);
|
||||
if (client_principal)
|
||||
krb5_free_principal(context, client_principal);
|
||||
if (service_principal)
|
||||
krb5_free_principal(context, service_principal);
|
||||
if (cc)
|
||||
krb5_cc_close(context, cc);
|
||||
if (kt)
|
||||
krb5_kt_close(context, kt);
|
||||
if (creds) krb5_free_creds(context, creds);
|
||||
krb5_free_keyblock_contents(context, session_key);
|
||||
out:
|
||||
return code;
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static krb5_error_code get_credv5(krb5_context context,
|
||||
char *name, char *inst, char *realm,
|
||||
krb5_creds **creds)
|
||||
@ -1911,21 +1498,17 @@ static krb5_error_code get_credv5(krb5_context context,
|
||||
|
||||
increds.client = client_principal;
|
||||
increds.times.endtime = 0;
|
||||
if (do524)
|
||||
/* Ask for DES since that is what V4 understands */
|
||||
get_creds_enctype((&increds)) = ENCTYPE_DES_CBC_CRC;
|
||||
|
||||
if (keytab) {
|
||||
int allowed_enctypes[] = {
|
||||
ENCTYPE_DES_CBC_CRC, 0
|
||||
};
|
||||
|
||||
r = get_credv5_akimpersonate(context,
|
||||
keytab,
|
||||
increds.server,
|
||||
increds.client,
|
||||
300, ((~0U)>>1),
|
||||
allowed_enctypes,
|
||||
0 /* paddress */,
|
||||
0, 0x7fffffff,
|
||||
NULL,
|
||||
creds /* out */);
|
||||
} else {
|
||||
r = krb5_get_credentials(context, 0, _krb425_ccache, &increds, creds);
|
||||
|
@ -701,8 +701,15 @@ CommandProc(struct cmd_syndesc *as, char *arock)
|
||||
}
|
||||
atoken->startTime = afscred->times.starttime;
|
||||
atoken->endTime = afscred->times.endtime;
|
||||
memcpy(&atoken->sessionKey, get_cred_keydata(afscred),
|
||||
get_cred_keylen(afscred));
|
||||
if (tkt_DeriveDesKey(get_creds_enctype(afscred),
|
||||
get_cred_keydata(afscred),
|
||||
get_cred_keylen(afscred), &atoken->sessionKey)) {
|
||||
afs_com_err(rn, 0,
|
||||
"Cannot derive DES key from enctype %i of length %u",
|
||||
get_creds_enctype(afscred),
|
||||
(unsigned)get_cred_keylen(afscred));
|
||||
KLOGEXIT(1);
|
||||
}
|
||||
memcpy(atoken->ticket, enc_part->data,
|
||||
atoken->ticketLen = enc_part->length);
|
||||
memset(aserver, 0, sizeof *aserver);
|
||||
|
@ -9,15 +9,15 @@ srcdir=@srcdir@
|
||||
include @TOP_OBJDIR@/src/config/Makefile.config
|
||||
|
||||
OBJS= cellconfig.o ktc.o userok.o writeconfig.o authcon.o \
|
||||
acfg_errors.o ktc_errors.o
|
||||
acfg_errors.o ktc_errors.o @MAKE_KRB5@ akimpersonate.o akimpersonate_v5gen.o
|
||||
KOBJS= cellconfig.o ktc.krb.o userok.o writeconfig.o authcon.o \
|
||||
acfg_errors.o ktc_errors.o
|
||||
acfg_errors.o ktc_errors.o @MAKE_KRB5@ akimpersonate.o akimpersonate_v5gen.o
|
||||
|
||||
LIBS=libauth.a \
|
||||
${TOP_LIBDIR}/librxkad.a ${TOP_LIBDIR}/libdes.a \
|
||||
${TOP_LIBDIR}/librx.a ${TOP_LIBDIR}/libsys.a \
|
||||
${TOP_LIBDIR}/liblwp.a ${TOP_LIBDIR}/util.a
|
||||
INCLS=cellconfig.h auth.h keys.h
|
||||
INCLS=cellconfig.h auth.h keys.h akimpersonate.h akimpersonate_v5gen.h
|
||||
KSRCS=auth.h
|
||||
UKSRCS=${KSRCS} cellconfig.h acfg_errors.c keys.h cellconfig.c \
|
||||
ktc.c authcon.c ktc_errors.c
|
||||
@ -30,13 +30,23 @@ all: \
|
||||
depinstall: \
|
||||
${TOP_INCDIR}/afs/keys.h \
|
||||
${TOP_INCDIR}/afs/cellconfig.h \
|
||||
${TOP_INCDIR}/afs/akimpersonate.h \
|
||||
${TOP_INCDIR}/afs/auth.h \
|
||||
${TOP_INCDIR}/afs/ktc.h
|
||||
|
||||
cellconfig.o: cellconfig.c ${INCLS}
|
||||
ktc.o: ktc.c ${INCLS} ${TOP_INCDIR}/afs/vice.h
|
||||
writeconfig.o: writeconfig.c ${INCLS}
|
||||
|
||||
authcon.o: authcon.c ${INCLS}
|
||||
${CCOBJ} ${CFLAGS} -c ${srcdir}/authcon.c @KRB5CFLAGS@
|
||||
|
||||
akimpersonate.o: akimpersonate.c ${INCLS}
|
||||
${CCOBJ} ${CFLAGS} -c ${srcdir}/akimpersonate.c @KRB5CFLAGS@
|
||||
|
||||
akimpersonate_v5gen.o: akimpersonate_v5gen.c ${INCLS}
|
||||
${CCOBJ} ${CFLAGS} -c ${srcdir}/akimpersonate_v5gen.c @KRB5CFLAGS@ -I${srcdir}/../rxkad
|
||||
|
||||
userok.o: userok.c ${INCLS}
|
||||
cellconfig.o: cellconfig.c ${INCLS}
|
||||
copyauth.o: copyauth.c ${INCLS} AFS_component_version_number.o
|
||||
@ -134,6 +144,9 @@ ${TOP_INCDIR}/afs/cellconfig.h: cellconfig.h
|
||||
${DEST}/include/afs/cellconfig.h: cellconfig.h
|
||||
${INSTALL} $? $@
|
||||
|
||||
${TOP_INCDIR}/afs/akimpersonate.h: akimpersonate.h
|
||||
${INSTALL} $? $@
|
||||
|
||||
${DESTDIR}${includedir}/afs/auth.h: auth.h
|
||||
${INSTALL} $? $@
|
||||
|
||||
|
766
src/auth/akimpersonate.c
Normal file
766
src/auth/akimpersonate.c
Normal file
@ -0,0 +1,766 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2006
|
||||
* The Linux Box Corporation
|
||||
* ALL RIGHTS RESERVED
|
||||
*
|
||||
* Permission is granted to use, copy, create derivative works
|
||||
* and redistribute this software and such derivative works
|
||||
* for any purpose, so long as the name of the Linux Box
|
||||
* Corporation is not used in any advertising or publicity
|
||||
* pertaining to the use or distribution of this software
|
||||
* without specific, written prior authorization. If the
|
||||
* above copyright notice or any other identification of the
|
||||
* Linux Box Corporation is included in any copy of any
|
||||
* portion of this software, then the disclaimer below must
|
||||
* also be included.
|
||||
*
|
||||
* This software is provided as is, without representation
|
||||
* from the Linux Box Corporation as to its fitness for any
|
||||
* purpose, and without warranty by the Linux Box Corporation
|
||||
* of any kind, either express or implied, including
|
||||
* without limitation the implied warranties of
|
||||
* merchantability and fitness for a particular purpose. The
|
||||
* regents of the Linux Box Corporation shall not be liable
|
||||
* for any damages, including special, indirect, incidental, or
|
||||
* consequential damages, with respect to any claim arising
|
||||
* out of or in connection with the use of the software, even
|
||||
* if it has been or is hereafter advised of the possibility of
|
||||
* such damages.
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2013 by Alexander Chernyakhovsky and the
|
||||
* Massachusetts Institute of Technology.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <afsconfig.h>
|
||||
#include <afs/param.h>
|
||||
#include <afs/stds.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <krb5.h>
|
||||
|
||||
#include "akimpersonate.h"
|
||||
#include "akimpersonate_v5gen.h"
|
||||
|
||||
#ifdef HAVE_KRB5_CREDS_KEYBLOCK
|
||||
#define USING_MIT 1
|
||||
#endif
|
||||
#ifdef HAVE_KRB5_CREDS_SESSION
|
||||
#define USING_HEIMDAL 1
|
||||
#endif
|
||||
|
||||
#if USING_HEIMDAL
|
||||
#define deref_keyblock_enctype(kb) ((kb)->keytype)
|
||||
#define deref_entry_keyblock(entry) ((entry)->keyblock)
|
||||
#define deref_session_key(creds) ((creds)->session)
|
||||
#define deref_enc_tkt_addrs(tkt) ((tkt)->caddr)
|
||||
#define deref_enc_data(enc) ((enc)->cipher.data)
|
||||
#else
|
||||
#define deref_keyblock_enctype(kb) ((kb)->enctype)
|
||||
#define deref_entry_keyblock(entry) ((entry)->key)
|
||||
#define deref_session_key(creds) ((creds)->keyblock)
|
||||
#define deref_enc_tkt_addrs(tkt) ((tkt)->caddrs)
|
||||
#define deref_enc_data(enc) ((enc)->ciphertext.data)
|
||||
#endif
|
||||
#if HAVE_DECL_KRB5_FREE_KEYTAB_ENTRY_CONTENTS
|
||||
/* nothing */
|
||||
#elif HAVE_DECL_KRB5_KT_FREE_ENTRY
|
||||
#define krb5_free_keytab_entry_contents krb5_kt_free_entry
|
||||
#else
|
||||
static inline int
|
||||
krb5_free_keytab_entry_contents(krb5_context ctx, krb5_keytab_entry * ent)
|
||||
{
|
||||
krb5_free_principal(ctx, ent->principal);
|
||||
krb5_free_keyblock_contents(ctx, kte_keyblock(ent));
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#define deref_entry_enctype(entry) \
|
||||
deref_keyblock_enctype(&deref_entry_keyblock(entry))
|
||||
|
||||
#ifdef USING_MIT
|
||||
# if !defined(HAVE_ENCODE_KRB5_TICKET)
|
||||
/*
|
||||
* Solaris doesn't have encode_krb5_ticket and encode_krb5_enc_tkt_part, so we
|
||||
* need to implement our own. The akv5gen_* functions below are implemented
|
||||
* using v5gen code; so, they need to have no krb5 structures in their
|
||||
* arguments, since using system krb5 headers at the same time as v5gen
|
||||
* headers is problematic. That's why the ticket contents are exploded.
|
||||
*/
|
||||
static krb5_error_code
|
||||
encode_krb5_ticket(krb5_ticket *rep, krb5_data **a_out)
|
||||
{
|
||||
krb5_error_code code = 0;
|
||||
int i;
|
||||
char **names = NULL;
|
||||
krb5_data *out = NULL;
|
||||
size_t out_len = 0;
|
||||
char *out_data = NULL;
|
||||
|
||||
*a_out = NULL;
|
||||
|
||||
out = calloc(1, sizeof(*out));
|
||||
if (!out) {
|
||||
code = ENOMEM;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
names = calloc(rep->server->length, sizeof(names[0]));
|
||||
if (names == NULL) {
|
||||
code = ENOMEM;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
for (i = 0; i < rep->server->length; i++) {
|
||||
names[i] = rep->server->data[i].data;
|
||||
}
|
||||
|
||||
code = akv5gen_encode_krb5_ticket(rep->enc_part.kvno,
|
||||
rep->server->realm.data,
|
||||
rep->server->type,
|
||||
rep->server->length,
|
||||
names,
|
||||
rep->enc_part.enctype,
|
||||
rep->enc_part.ciphertext.length,
|
||||
rep->enc_part.ciphertext.data,
|
||||
&out_len,
|
||||
&out_data);
|
||||
if (code != 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
out->length = out_len;
|
||||
out->data = out_data;
|
||||
*a_out = out;
|
||||
out = NULL;
|
||||
|
||||
cleanup:
|
||||
free(names);
|
||||
free(out);
|
||||
return code;
|
||||
}
|
||||
# endif /* !HAVE_ENCODE_KRB5_TICKET */
|
||||
|
||||
# if !defined(HAVE_ENCODE_KRB5_ENC_TKT_PART)
|
||||
static krb5_error_code
|
||||
encode_krb5_enc_tkt_part(krb5_enc_tkt_part *encpart, krb5_data **a_out)
|
||||
{
|
||||
krb5_error_code code = 0;
|
||||
int i;
|
||||
char **names = NULL;
|
||||
krb5_data *out = NULL;
|
||||
size_t out_len = 0;
|
||||
char *out_data = NULL;
|
||||
|
||||
*a_out = NULL;
|
||||
|
||||
out = calloc(1, sizeof(*out));
|
||||
if (out == NULL) {
|
||||
code = ENOMEM;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
names = calloc(encpart->client->length, sizeof(names[0]));
|
||||
if (names == NULL) {
|
||||
code = ENOMEM;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
for (i = 0; i < encpart->client->length; i++)
|
||||
names[i] = encpart->client->data[i].data;
|
||||
|
||||
if (encpart->flags != TKT_FLG_INITIAL) {
|
||||
/* We assume the ticket has the flag _INITIAL set, and only that flag.
|
||||
* passing each individual flag to akv5gen would be really ugly, and
|
||||
* should be unnecessary. */
|
||||
goto invalid;
|
||||
}
|
||||
if (encpart->caddrs != NULL && encpart->caddrs[0] != NULL)
|
||||
goto invalid;
|
||||
if (encpart->authorization_data && encpart->authorization_data[0])
|
||||
goto invalid;
|
||||
|
||||
code = akv5gen_encode_krb5_enc_tkt_part(encpart->session->enctype,
|
||||
encpart->session->length,
|
||||
encpart->session->contents,
|
||||
encpart->client->realm.data,
|
||||
encpart->client->type,
|
||||
encpart->client->length,
|
||||
names,
|
||||
encpart->transited.tr_type,
|
||||
encpart->transited.tr_contents.length,
|
||||
encpart->transited.tr_contents.data,
|
||||
encpart->times.authtime,
|
||||
encpart->times.starttime,
|
||||
encpart->times.endtime,
|
||||
encpart->times.renew_till,
|
||||
&out_len,
|
||||
&out_data);
|
||||
if (code != 0)
|
||||
goto cleanup;
|
||||
|
||||
out->length = out_len;
|
||||
out->data = out_data;
|
||||
*a_out = out;
|
||||
out = NULL;
|
||||
|
||||
cleanup:
|
||||
free(names);
|
||||
free(out);
|
||||
return code;
|
||||
|
||||
invalid:
|
||||
/* We don't handle all possible ticket options, features, etc. If we are
|
||||
* given a ticket we can't handle, bail out with EINVAL. */
|
||||
code = EINVAL;
|
||||
goto cleanup;
|
||||
}
|
||||
# endif /* !HAVE_ENCODE_KRB5_ENC_TKT_PART */
|
||||
|
||||
# if !defined(HAVE_KRB5_ENCRYPT_TKT_PART)
|
||||
krb5_error_code
|
||||
krb5_encrypt_tkt_part(krb5_context context,
|
||||
const krb5_keyblock *key,
|
||||
krb5_ticket *ticket)
|
||||
{
|
||||
krb5_data *data = 0;
|
||||
int code;
|
||||
size_t enclen;
|
||||
|
||||
if ((code = encode_krb5_enc_tkt_part(ticket->enc_part2, &data)))
|
||||
goto Done;
|
||||
if ((code = krb5_c_encrypt_length(context, key->enctype,
|
||||
data->length, &enclen)))
|
||||
goto Done;
|
||||
ticket->enc_part.ciphertext.length = enclen;
|
||||
if (!(ticket->enc_part.ciphertext.data = malloc(enclen))) {
|
||||
code = ENOMEM;
|
||||
goto Done;
|
||||
}
|
||||
if ((code = krb5_c_encrypt(context, key, KRB5_KEYUSAGE_KDC_REP_TICKET,
|
||||
0, data, &ticket->enc_part))) {
|
||||
free(ticket->enc_part.ciphertext.data);
|
||||
ticket->enc_part.ciphertext.data = 0;
|
||||
}
|
||||
Done:
|
||||
if (data) {
|
||||
if (data->data)
|
||||
free(data->data);
|
||||
free(data);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
# endif /* HAVE_KRB5_ENCRYPT_TKT_PART */
|
||||
#endif /* USING_MIT */
|
||||
|
||||
static const int any_enctype[2] = {0, 0};
|
||||
static const krb5_data empty_string;
|
||||
|
||||
/*
|
||||
* Routines to allocate/free the extra storage involved in a ticket structure.
|
||||
* When changing one, ensure that the other is changed to reflect the
|
||||
* allocation contract.
|
||||
*/
|
||||
static int
|
||||
alloc_ticket(void **out)
|
||||
{
|
||||
#if USING_HEIMDAL
|
||||
Ticket *ticket_reply;
|
||||
#else
|
||||
krb5_ticket *ticket_reply;
|
||||
#endif
|
||||
|
||||
/* requisite aliasing for MIT/Heimdal support. */
|
||||
ticket_reply = *out = calloc(1, sizeof(*ticket_reply));
|
||||
if (ticket_reply == NULL)
|
||||
return ENOMEM;
|
||||
|
||||
#if USING_HEIMDAL
|
||||
ticket_reply->enc_part.kvno = malloc(sizeof(*ticket_reply->enc_part.kvno));
|
||||
if (ticket_reply->enc_part.kvno == NULL)
|
||||
return ENOMEM;
|
||||
#else
|
||||
/* No allocations needed for MIT's krb5_ticket structure. */
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
free_ticket(void *in)
|
||||
{
|
||||
#if USING_HEIMDAL
|
||||
Ticket *ticket_reply;
|
||||
#else
|
||||
krb5_ticket *ticket_reply;
|
||||
#endif
|
||||
|
||||
/* requisite aliasing for MIT/Heimdal support. */
|
||||
ticket_reply = in;
|
||||
if (ticket_reply == NULL)
|
||||
return;
|
||||
|
||||
#if USING_HEIMDAL
|
||||
if (ticket_reply->enc_part.kvno != NULL)
|
||||
free(ticket_reply->enc_part.kvno);
|
||||
#else
|
||||
/* No allocations needed for MIT's krb5_ticket structure. */
|
||||
#endif
|
||||
free(ticket_reply);
|
||||
}
|
||||
|
||||
/*
|
||||
* Routines to allocate/free the extra storage involved in an encrypted
|
||||
* ticket part structure.
|
||||
* When changing one, ensure that the other is changed to reflect the
|
||||
* allocation contract.
|
||||
*/
|
||||
static int
|
||||
alloc_enc_tkt_part(void **out)
|
||||
{
|
||||
#if USING_HEIMDAL
|
||||
EncTicketPart *enc_tkt_reply;
|
||||
#else
|
||||
krb5_enc_tkt_part *enc_tkt_reply;
|
||||
#endif
|
||||
|
||||
/* Aliasing for MIT/Heimdal support. */
|
||||
enc_tkt_reply = *out = calloc(1, sizeof(*enc_tkt_reply));
|
||||
if (enc_tkt_reply == NULL)
|
||||
return ENOMEM;
|
||||
|
||||
#if USING_HEIMDAL
|
||||
enc_tkt_reply->starttime = malloc(sizeof(*enc_tkt_reply->starttime));
|
||||
if (enc_tkt_reply->starttime == NULL)
|
||||
return ENOMEM;
|
||||
#else
|
||||
/* No allocations needed for MIT's krb5_enc_tkt_part structure. */
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
static void
|
||||
free_enc_tkt_part(void *in)
|
||||
{
|
||||
#if USING_HEIMDAL
|
||||
EncTicketPart *enc_tkt_reply;
|
||||
#else
|
||||
krb5_enc_tkt_part *enc_tkt_reply;
|
||||
#endif
|
||||
|
||||
/* Aliasing for MIT/Heimdal support. */
|
||||
enc_tkt_reply = in;
|
||||
if (enc_tkt_reply == NULL)
|
||||
return;
|
||||
|
||||
#if USING_HEIMDAL
|
||||
if (enc_tkt_reply->starttime != NULL)
|
||||
free(enc_tkt_reply->starttime);
|
||||
#else
|
||||
/* No allocations needed for MIT's krb5_enc_tkt_part structure. */
|
||||
#endif
|
||||
free(enc_tkt_reply);
|
||||
}
|
||||
|
||||
/*
|
||||
* Given a keytab, extract the principal name of the (first) entry with
|
||||
* the highest kvno in the keytab. This provides compatibility with the
|
||||
* rxkad KeyFile behavior of always using the highest kvno entry when
|
||||
* printing tickets. We could return the kvno as well, but krb5_kt_get_entry
|
||||
* can find the highest kvno on its own.
|
||||
*
|
||||
* Returns 0 on success, krb5 errors on failure.
|
||||
*/
|
||||
static int
|
||||
pick_principal(krb5_context context, krb5_keytab kt,
|
||||
krb5_principal *service_principal)
|
||||
{
|
||||
krb5_error_code code;
|
||||
krb5_kvno vno = 0;
|
||||
krb5_kt_cursor c;
|
||||
krb5_keytab_entry n_entry;
|
||||
|
||||
/* Nothing to do */
|
||||
if (*service_principal != NULL)
|
||||
return 0;
|
||||
|
||||
memset(&n_entry, 0, sizeof(n_entry));
|
||||
|
||||
code = krb5_kt_start_seq_get(context, kt, &c);
|
||||
if (code != 0)
|
||||
goto cleanup;
|
||||
while (code == 0 && krb5_kt_next_entry(context, kt, &n_entry, &c) == 0) {
|
||||
if (n_entry.vno > vno) {
|
||||
vno = n_entry.vno;
|
||||
(void)krb5_free_principal(context, *service_principal);
|
||||
code = krb5_copy_principal(context, n_entry.principal,
|
||||
service_principal);
|
||||
}
|
||||
(void)krb5_free_keytab_entry_contents(context, &n_entry);
|
||||
}
|
||||
if (code != 0) {
|
||||
(void)krb5_kt_end_seq_get(context, kt, &c);
|
||||
goto cleanup;
|
||||
}
|
||||
code = krb5_kt_end_seq_get(context, kt, &c);
|
||||
|
||||
cleanup:
|
||||
return code;
|
||||
}
|
||||
|
||||
/*
|
||||
* Given a keytab and a list of allowed enctypes, and optionally a known
|
||||
* service principal, choose an appropriate enctype, and choose a
|
||||
* service principal if one was not given. Return the keytab entry
|
||||
* corresponding to this service principal and enctype.
|
||||
*
|
||||
* The list of allowed enctypes must be zero-terminated.
|
||||
*/
|
||||
static int
|
||||
pick_enctype_and_principal(krb5_context context, krb5_keytab kt,
|
||||
const int *allowed_enctypes, krb5_enctype *enctype,
|
||||
krb5_principal *service_principal,
|
||||
krb5_keytab_entry *entry)
|
||||
{
|
||||
krb5_error_code code;
|
||||
int i;
|
||||
|
||||
if (*service_principal == NULL) {
|
||||
code = pick_principal(context, kt, service_principal);
|
||||
if (code != 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
/* We always have a service_principal, now. */
|
||||
i = 0;
|
||||
do {
|
||||
*enctype = allowed_enctypes[i];
|
||||
code = krb5_kt_get_entry(context, kt, *service_principal, 0 /* any */,
|
||||
*enctype, entry);
|
||||
if (code == 0) {
|
||||
if (*enctype == 0)
|
||||
*enctype = deref_entry_enctype(entry);
|
||||
break;
|
||||
}
|
||||
++i;
|
||||
} while(allowed_enctypes[i] != 0);
|
||||
if (code != 0)
|
||||
goto cleanup;
|
||||
|
||||
cleanup:
|
||||
return code;
|
||||
}
|
||||
|
||||
/*
|
||||
* Populate the encrypted part of the ticket.
|
||||
*/
|
||||
static void
|
||||
populate_enc_tkt(krb5_keyblock *session_key, krb5_principal client_principal,
|
||||
time_t starttime, time_t endtime, void *out)
|
||||
{
|
||||
#if USING_HEIMDAL
|
||||
EncTicketPart *enc_tkt_reply;
|
||||
#else
|
||||
krb5_enc_tkt_part *enc_tkt_reply;
|
||||
#endif
|
||||
int i;
|
||||
|
||||
/* Alias through void* since Heimdal and MIT's types differ. */
|
||||
enc_tkt_reply = out;
|
||||
|
||||
#if USING_HEIMDAL
|
||||
enc_tkt_reply->flags.initial = 1;
|
||||
enc_tkt_reply->transited.tr_type = DOMAIN_X500_COMPRESS;
|
||||
enc_tkt_reply->cname = client_principal->name;
|
||||
enc_tkt_reply->crealm = client_principal->realm;
|
||||
enc_tkt_reply->key = *session_key;
|
||||
enc_tkt_reply->transited.contents = empty_string;
|
||||
enc_tkt_reply->authtime = starttime;
|
||||
*enc_tkt_reply->starttime = starttime;
|
||||
enc_tkt_reply->endtime = endtime;
|
||||
#else
|
||||
enc_tkt_reply->magic = KV5M_ENC_TKT_PART;
|
||||
enc_tkt_reply->flags |= TKT_FLG_INITIAL;
|
||||
enc_tkt_reply->transited.tr_type = KRB5_DOMAIN_X500_COMPRESS;
|
||||
enc_tkt_reply->session = session_key;
|
||||
enc_tkt_reply->client = client_principal;
|
||||
enc_tkt_reply->transited.tr_contents = empty_string;
|
||||
enc_tkt_reply->times.authtime = starttime;
|
||||
enc_tkt_reply->times.starttime = starttime; /* krb524init needs this */
|
||||
enc_tkt_reply->times.endtime = endtime;
|
||||
#endif /* USING_HEIMDAL */
|
||||
}
|
||||
|
||||
/*
|
||||
* Encrypt the provided enc_tkt_part structure with the key from the keytab
|
||||
* entry entry, and place the resulting blob in the ticket_reply structure.
|
||||
*/
|
||||
static int
|
||||
encrypt_enc_tkt(krb5_context context, krb5_principal service_principal,
|
||||
krb5_keytab_entry *entry, void *tr_out, void *er_in)
|
||||
{
|
||||
krb5_error_code code;
|
||||
#if USING_HEIMDAL
|
||||
Ticket *ticket_reply;
|
||||
EncTicketPart *enc_tkt_reply;
|
||||
krb5_crypto crypto = 0;
|
||||
unsigned char *buf = 0;
|
||||
size_t buf_size, buf_len;
|
||||
#else
|
||||
krb5_ticket *ticket_reply;
|
||||
krb5_enc_tkt_part *enc_tkt_reply;
|
||||
#endif
|
||||
|
||||
/* Requisite aliasing for Heimdal/MIT support. */
|
||||
ticket_reply = tr_out;
|
||||
enc_tkt_reply = er_in;
|
||||
|
||||
#if USING_HEIMDAL
|
||||
ticket_reply->sname = service_principal->name;
|
||||
ticket_reply->realm = service_principal->realm;
|
||||
|
||||
ASN1_MALLOC_ENCODE(EncTicketPart, buf, buf_size, enc_tkt_reply,
|
||||
&buf_len, code);
|
||||
if (code != 0)
|
||||
goto cleanup;
|
||||
|
||||
if (buf_len != buf_size)
|
||||
goto cleanup;
|
||||
code = krb5_crypto_init(context,
|
||||
&deref_entry_keyblock(entry),
|
||||
deref_entry_enctype(entry),
|
||||
&crypto);
|
||||
if (code != 0)
|
||||
goto cleanup;
|
||||
code = krb5_encrypt_EncryptedData(context, crypto, KRB5_KU_TICKET, buf,
|
||||
buf_len, entry->vno,
|
||||
&(ticket_reply->enc_part));
|
||||
if (code != 0)
|
||||
goto cleanup;
|
||||
ticket_reply->enc_part.etype = deref_entry_enctype(entry);
|
||||
*ticket_reply->enc_part.kvno = entry->vno;
|
||||
ticket_reply->tkt_vno = 5;
|
||||
#else
|
||||
ticket_reply->server = service_principal;
|
||||
ticket_reply->enc_part2 = enc_tkt_reply;
|
||||
code = krb5_encrypt_tkt_part(context, &deref_entry_keyblock(entry),
|
||||
ticket_reply);
|
||||
if (code != 0)
|
||||
goto cleanup;
|
||||
ticket_reply->enc_part.kvno = entry->vno;
|
||||
#endif
|
||||
|
||||
cleanup:
|
||||
#if USING_HEIMDAL
|
||||
if (buf != NULL)
|
||||
free(buf);
|
||||
if (crypto != NULL)
|
||||
krb5_crypto_destroy(context, crypto);
|
||||
#endif
|
||||
return code;
|
||||
}
|
||||
|
||||
/*
|
||||
* Populate the credentials structure corresponding to the ticket we are
|
||||
* printing.
|
||||
*/
|
||||
static int
|
||||
populate_creds(krb5_context context, krb5_principal service_principal,
|
||||
krb5_principal client_principal, krb5_keyblock *session_key,
|
||||
void *tr_in, void *er_in, krb5_creds *creds)
|
||||
{
|
||||
krb5_error_code code;
|
||||
#if USING_HEIMDAL
|
||||
Ticket *ticket_reply;
|
||||
EncTicketPart *enc_tkt_reply;
|
||||
size_t dummy;
|
||||
#else
|
||||
krb5_ticket *ticket_reply;
|
||||
krb5_enc_tkt_part *enc_tkt_reply;
|
||||
krb5_data *temp = NULL;
|
||||
#endif
|
||||
|
||||
/* Requisite aliasing for Heimdal/MIT support. */
|
||||
ticket_reply = tr_in;
|
||||
enc_tkt_reply = er_in;
|
||||
|
||||
code = krb5_copy_principal(context, service_principal, &creds->server);
|
||||
if (code != 0)
|
||||
goto cleanup;
|
||||
code = krb5_copy_principal(context, client_principal, &creds->client);
|
||||
if (code != 0)
|
||||
goto cleanup;
|
||||
code = krb5_copy_keyblock_contents(context, session_key,
|
||||
&deref_session_key(creds));
|
||||
if (code != 0)
|
||||
goto cleanup;
|
||||
|
||||
#if USING_HEIMDAL
|
||||
creds->times.authtime = enc_tkt_reply->authtime;
|
||||
creds->times.starttime = *(enc_tkt_reply->starttime);
|
||||
creds->times.endtime = enc_tkt_reply->endtime;
|
||||
creds->times.renew_till = 0; /* *(enc_tkt_reply->renew_till) */
|
||||
creds->flags.b = enc_tkt_reply->flags;
|
||||
#else
|
||||
creds->times = enc_tkt_reply->times;
|
||||
creds->ticket_flags = enc_tkt_reply->flags;
|
||||
#endif
|
||||
|
||||
#if USING_HEIMDAL
|
||||
ASN1_MALLOC_ENCODE(Ticket, creds->ticket.data, creds->ticket.length,
|
||||
ticket_reply, &dummy, code);
|
||||
if (code != 0 || dummy != creds->ticket.length)
|
||||
goto cleanup;
|
||||
#else
|
||||
code = encode_krb5_ticket(ticket_reply, &temp);
|
||||
if (code != 0)
|
||||
goto cleanup;
|
||||
creds->ticket = *temp;
|
||||
#endif
|
||||
|
||||
cleanup:
|
||||
#if USING_HEIMDAL
|
||||
/* nothing */
|
||||
#else
|
||||
free(temp);
|
||||
#endif
|
||||
return code;
|
||||
}
|
||||
|
||||
/*
|
||||
* Print a krb5 ticket in our service key, for the supplied client principal.
|
||||
* The path to a keytab is mandatory, but the service principal may be
|
||||
* guessed from the keytab contents if desired. The keytab entry must be
|
||||
* one of the allowed_enctypes (a zero-terminated list) if a non-NULL
|
||||
* parameter is passed.
|
||||
*/
|
||||
krb5_error_code
|
||||
get_credv5_akimpersonate(krb5_context context, char* keytab,
|
||||
krb5_principal service_principal,
|
||||
krb5_principal client_principal, time_t starttime,
|
||||
time_t endtime, const int *allowed_enctypes,
|
||||
krb5_creds** out_creds /* out */ )
|
||||
{
|
||||
krb5_error_code code;
|
||||
krb5_keytab kt = 0;
|
||||
krb5_keytab_entry entry[1];
|
||||
krb5_creds *creds = 0;
|
||||
krb5_enctype enctype;
|
||||
krb5_keyblock session_key[1];
|
||||
#if USING_HEIMDAL
|
||||
Ticket *ticket_reply;
|
||||
EncTicketPart *enc_tkt_reply;
|
||||
#else
|
||||
krb5_ticket *ticket_reply;
|
||||
krb5_enc_tkt_part *enc_tkt_reply;
|
||||
#endif
|
||||
int i;
|
||||
*out_creds = NULL;
|
||||
enctype = 0; /* AKIMPERSONATE_IGNORE_ENCTYPE */
|
||||
memset(entry, 0, sizeof *entry);
|
||||
memset(session_key, 0, sizeof *session_key);
|
||||
ticket_reply = NULL;
|
||||
enc_tkt_reply = NULL;
|
||||
|
||||
creds = calloc(1, sizeof(*creds));
|
||||
if (creds == NULL) {
|
||||
code = ENOMEM;
|
||||
goto cleanup;
|
||||
}
|
||||
code = alloc_ticket(&ticket_reply);
|
||||
if (code != 0)
|
||||
goto cleanup;
|
||||
code = alloc_enc_tkt_part(&enc_tkt_reply);
|
||||
if (code != 0)
|
||||
goto cleanup;
|
||||
/* Empty list of allowed etypes must fail. Do it here to avoid issues. */
|
||||
if (allowed_enctypes != NULL && *allowed_enctypes == 0) {
|
||||
code = KRB5_BAD_ENCTYPE;
|
||||
goto cleanup;
|
||||
}
|
||||
if (allowed_enctypes == NULL)
|
||||
allowed_enctypes = any_enctype;
|
||||
|
||||
if (keytab != NULL)
|
||||
code = krb5_kt_resolve(context, keytab, &kt);
|
||||
else
|
||||
code = krb5_kt_default(context, &kt);
|
||||
if (code != 0)
|
||||
goto cleanup;
|
||||
|
||||
code = pick_enctype_and_principal(context, kt, allowed_enctypes,
|
||||
&enctype, &service_principal, entry);
|
||||
if (code != 0)
|
||||
goto cleanup;
|
||||
|
||||
/* Conjure up a random session key */
|
||||
deref_keyblock_enctype(session_key) = enctype;
|
||||
#if USING_HEIMDAL
|
||||
code = krb5_generate_random_keyblock(context, enctype, session_key);
|
||||
#else
|
||||
code = krb5_c_make_random_key(context, enctype, session_key);
|
||||
#endif
|
||||
if (code != 0)
|
||||
goto cleanup;
|
||||
|
||||
populate_enc_tkt(session_key, client_principal, starttime, endtime,
|
||||
enc_tkt_reply);
|
||||
|
||||
code = encrypt_enc_tkt(context, service_principal, entry, ticket_reply,
|
||||
enc_tkt_reply);
|
||||
if (code != 0)
|
||||
goto cleanup;
|
||||
|
||||
code = populate_creds(context, service_principal, client_principal,
|
||||
session_key, ticket_reply, enc_tkt_reply, creds);
|
||||
if (code != 0)
|
||||
goto cleanup;
|
||||
|
||||
/* return creds */
|
||||
*out_creds = creds;
|
||||
creds = NULL;
|
||||
cleanup:
|
||||
if (deref_enc_data(&ticket_reply->enc_part) != NULL)
|
||||
free(deref_enc_data(&ticket_reply->enc_part));
|
||||
krb5_free_keytab_entry_contents(context, entry);
|
||||
if (client_principal != NULL)
|
||||
krb5_free_principal(context, client_principal);
|
||||
if (service_principal != NULL)
|
||||
krb5_free_principal(context, service_principal);
|
||||
if (kt != NULL)
|
||||
krb5_kt_close(context, kt);
|
||||
if (creds != NULL)
|
||||
krb5_free_creds(context, creds);
|
||||
krb5_free_keyblock_contents(context, session_key);
|
||||
free_ticket(ticket_reply);
|
||||
free_enc_tkt_part(enc_tkt_reply);
|
||||
return code;
|
||||
}
|
21
src/auth/akimpersonate.h
Normal file
21
src/auth/akimpersonate.h
Normal file
@ -0,0 +1,21 @@
|
||||
#ifndef __AKIMPERSONATE_H__
|
||||
#define __AKIMPERSONATE_H__
|
||||
|
||||
#if defined(HAVE_KRB5_CREDS_KEYBLOCK)
|
||||
#define get_cred_keydata(c) ((c)->keyblock.contents)
|
||||
#define get_cred_keylen(c) ((c)->keyblock.length)
|
||||
#define get_creds_enctype(c) ((c)->keyblock.enctype)
|
||||
#elif defined(HAVE_KRB5_CREDS_SESSION)
|
||||
#define get_cred_keydata(c) ((c)->session.keyvalue.data)
|
||||
#define get_cred_keylen(c) ((c)->session.keyvalue.length)
|
||||
#define get_creds_enctype(c) ((c)->session.keytype)
|
||||
#else
|
||||
#error "Must have either keyblock or session member of krb5_creds"
|
||||
#endif
|
||||
|
||||
/* The caller must include krb5.h to get prototypes for the types used. */
|
||||
krb5_error_code
|
||||
get_credv5_akimpersonate(krb5_context, char*, krb5_principal, krb5_principal,
|
||||
time_t, time_t, const int *, krb5_creds**);
|
||||
|
||||
#endif
|
176
src/auth/akimpersonate_v5gen.c
Normal file
176
src/auth/akimpersonate_v5gen.c
Normal file
@ -0,0 +1,176 @@
|
||||
/*
|
||||
* Copyright (c) 2013 Sine Nomine Associates
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <afsconfig.h>
|
||||
#include <afs/param.h>
|
||||
|
||||
/* are we using MIT krb5, and are we missing the functions encode_krb5_ticket
|
||||
* and encode_krb5_enc_tkt_part? */
|
||||
#if defined(HAVE_KRB5_CREDS_KEYBLOCK) && !defined(HAVE_KRB5_CREDS_SESSION) \
|
||||
&& !defined(HAVE_ENCODE_KRB5_TICKET) && !defined(HAVE_ENCODE_KRB5_ENC_TKT_PART)
|
||||
|
||||
# include <afs/stds.h>
|
||||
|
||||
# include <sys/types.h>
|
||||
# include <time.h>
|
||||
# include <errno.h>
|
||||
# include <netinet/in.h>
|
||||
# include <string.h>
|
||||
# include <rx/xdr.h>
|
||||
# include <rx/rx.h>
|
||||
# include <des.h>
|
||||
# include <des_prototypes.h>
|
||||
|
||||
# include "lifetimes.h"
|
||||
# include "rxkad.h"
|
||||
|
||||
# include "v5gen-rewrite.h"
|
||||
# include "v5gen.h"
|
||||
# include "der.h"
|
||||
|
||||
# include "akimpersonate_v5gen.h"
|
||||
|
||||
int
|
||||
akv5gen_encode_krb5_ticket(int kvno,
|
||||
char *realm,
|
||||
int name_type,
|
||||
int name_len,
|
||||
char **name_parts,
|
||||
int enctype,
|
||||
size_t cipher_len,
|
||||
char *cipher_data,
|
||||
size_t *a_out_len,
|
||||
char **a_out_data)
|
||||
{
|
||||
Ticket v5gen_tkt;
|
||||
int code = 0;
|
||||
size_t dummy;
|
||||
char *outdata = NULL;
|
||||
size_t outlen = 0;
|
||||
|
||||
memset(&v5gen_tkt, 0, sizeof(v5gen_tkt));
|
||||
|
||||
v5gen_tkt.tkt_vno = 5;
|
||||
v5gen_tkt.realm = realm;
|
||||
|
||||
v5gen_tkt.sname.name_type = name_type;
|
||||
v5gen_tkt.sname.name_string.len = name_len;
|
||||
v5gen_tkt.sname.name_string.val = name_parts;
|
||||
|
||||
v5gen_tkt.enc_part.etype = enctype;
|
||||
v5gen_tkt.enc_part.kvno = &kvno;
|
||||
v5gen_tkt.enc_part.cipher.length = cipher_len;
|
||||
v5gen_tkt.enc_part.cipher.data = cipher_data;
|
||||
|
||||
ASN1_MALLOC_ENCODE(Ticket, outdata, outlen,
|
||||
&v5gen_tkt, &dummy, code);
|
||||
if (code == 0 && dummy != outlen)
|
||||
code = EINVAL;
|
||||
if (code)
|
||||
goto cleanup;
|
||||
|
||||
*a_out_len = outlen;
|
||||
*a_out_data = outdata;
|
||||
outdata = NULL;
|
||||
|
||||
cleanup:
|
||||
free(outdata);
|
||||
return code;
|
||||
}
|
||||
|
||||
int
|
||||
akv5gen_encode_krb5_enc_tkt_part(int enctype,
|
||||
size_t key_len,
|
||||
char *key_data,
|
||||
char *realm,
|
||||
int name_type,
|
||||
int name_len,
|
||||
char **name_parts,
|
||||
int transited_type,
|
||||
int transited_len,
|
||||
char *transited_data,
|
||||
time_t authtime,
|
||||
time_t starttime,
|
||||
time_t endtime,
|
||||
time_t renew_till,
|
||||
size_t *a_out_len,
|
||||
char **a_out_data)
|
||||
{
|
||||
EncTicketPart v5gen_enc;
|
||||
size_t dummy;
|
||||
int i;
|
||||
int code = 0;
|
||||
char *outdata = NULL;
|
||||
size_t outlen = 0;
|
||||
|
||||
memset(&v5gen_enc, 0, sizeof(v5gen_enc));
|
||||
|
||||
/* assume the only flag that should be set is _INITIAL */
|
||||
v5gen_enc.flags.initial = 1;
|
||||
|
||||
v5gen_enc.key.keytype = enctype;
|
||||
v5gen_enc.key.keyvalue.length = key_len;
|
||||
v5gen_enc.key.keyvalue.data = key_data;
|
||||
|
||||
v5gen_enc.crealm = realm;
|
||||
|
||||
v5gen_enc.cname.name_type = name_type;
|
||||
v5gen_enc.cname.name_string.len = name_len;
|
||||
v5gen_enc.cname.name_string.val = name_parts;
|
||||
|
||||
v5gen_enc.transited.tr_type = transited_type;
|
||||
v5gen_enc.transited.contents.length = transited_len;
|
||||
v5gen_enc.transited.contents.data = transited_data;
|
||||
|
||||
v5gen_enc.authtime = authtime;
|
||||
v5gen_enc.starttime = &starttime;
|
||||
v5gen_enc.endtime = endtime;
|
||||
v5gen_enc.renew_till = &renew_till;
|
||||
|
||||
/* assume we have no addresses */
|
||||
v5gen_enc.caddr = NULL;
|
||||
|
||||
/* assume we have no authz data */
|
||||
v5gen_enc.authorization_data = NULL;
|
||||
|
||||
ASN1_MALLOC_ENCODE(EncTicketPart, outdata, outlen,
|
||||
&v5gen_enc, &dummy, code);
|
||||
if (code == 0 && dummy != outlen)
|
||||
code = EINVAL;
|
||||
if (code)
|
||||
goto cleanup;
|
||||
|
||||
*a_out_len = outlen;
|
||||
*a_out_data = outdata;
|
||||
outdata = NULL;
|
||||
|
||||
cleanup:
|
||||
free(outdata);
|
||||
return code;
|
||||
}
|
||||
|
||||
#endif
|
30
src/auth/akimpersonate_v5gen.h
Normal file
30
src/auth/akimpersonate_v5gen.h
Normal file
@ -0,0 +1,30 @@
|
||||
#ifndef __AKIMPERSONATE_V5GEN_H__
|
||||
#define __AKIMPERSONATE_V5GEN_H__
|
||||
extern int akv5gen_encode_krb5_ticket(int kvno,
|
||||
char *realm,
|
||||
int name_type,
|
||||
int name_len,
|
||||
char **name_parts,
|
||||
int enctype,
|
||||
size_t cipher_len,
|
||||
char *cipher_data,
|
||||
size_t *a_out_len,
|
||||
char **a_out_data);
|
||||
|
||||
extern int akv5gen_encode_krb5_enc_tkt_part(int enctype,
|
||||
size_t key_len,
|
||||
char *key_data,
|
||||
char *realm,
|
||||
int name_type,
|
||||
int name_len,
|
||||
char **name_parts,
|
||||
int transited_type,
|
||||
int transited_len,
|
||||
char *transited_data,
|
||||
time_t authtime,
|
||||
time_t starttime,
|
||||
time_t endtime,
|
||||
time_t renew_till,
|
||||
size_t *a_out_len,
|
||||
char **a_out_data);
|
||||
#endif
|
@ -45,10 +45,18 @@
|
||||
#include <des.h>
|
||||
#include <des_prototypes.h>
|
||||
#include <rx/rxkad.h>
|
||||
#if defined(USE_RXKAD_KEYTAB) && !defined(UKERNEL)
|
||||
#include <afs/dirpath.h>
|
||||
#include <krb5.h>
|
||||
#endif
|
||||
#include <rx/rx.h>
|
||||
#include <errno.h>
|
||||
#include "cellconfig.h"
|
||||
#include "keys.h"
|
||||
#include "auth.h"
|
||||
#if defined(USE_RXKAD_KEYTAB) && !defined(UKERNEL)
|
||||
#include "akimpersonate.h"
|
||||
#endif
|
||||
#endif /* defined(UKERNEL) */
|
||||
|
||||
/* return a null security object if nothing else can be done */
|
||||
@ -71,12 +79,30 @@ afsconf_ServerAuth(register struct afsconf_dir *adir,
|
||||
{
|
||||
register struct rx_securityClass *tclass;
|
||||
|
||||
#ifdef USE_RXKAD_KEYTAB
|
||||
int keytab_enable = 0;
|
||||
char *keytab_name;
|
||||
size_t ktlen;
|
||||
ktlen = 5 + strlen(adir->name) + 1 + strlen(AFSDIR_RXKAD_KEYTAB_FILE) + 1;
|
||||
keytab_name = malloc(ktlen);
|
||||
if (keytab_name != NULL) {
|
||||
strcompose(keytab_name, ktlen, "FILE:", adir->name, "/",
|
||||
AFSDIR_RXKAD_KEYTAB_FILE, (char *)NULL);
|
||||
if (rxkad_InitKeytabDecrypt(keytab_name) == 0)
|
||||
keytab_enable = 1;
|
||||
free(keytab_name);
|
||||
}
|
||||
#endif
|
||||
LOCK_GLOBAL_MUTEX;
|
||||
tclass = (struct rx_securityClass *)
|
||||
rxkad_NewServerSecurityObject(0, adir, afsconf_GetKey, NULL);
|
||||
if (tclass) {
|
||||
*astr = tclass;
|
||||
*aindex = 2; /* kerberos security index */
|
||||
#ifdef USE_RXKAD_KEYTAB
|
||||
if (keytab_enable)
|
||||
rxkad_BindKeytabDecrypt(tclass);
|
||||
#endif
|
||||
UNLOCK_GLOBAL_MUTEX;
|
||||
return 0;
|
||||
} else {
|
||||
@ -86,6 +112,77 @@ afsconf_ServerAuth(register struct afsconf_dir *adir,
|
||||
}
|
||||
#endif /* !defined(UKERNEL) */
|
||||
|
||||
#if defined(USE_RXKAD_KEYTAB) && !defined(UKERNEL)
|
||||
static afs_int32
|
||||
K5Auth(struct afsconf_dir *adir,
|
||||
struct rx_securityClass **astr,
|
||||
afs_int32 *aindex,
|
||||
rxkad_level enclevel)
|
||||
{
|
||||
struct rx_securityClass *tclass;
|
||||
krb5_context context = NULL;
|
||||
krb5_creds* fake_princ = NULL;
|
||||
krb5_principal service_princ = NULL;
|
||||
krb5_principal client_princ = NULL;
|
||||
krb5_error_code r = 0;
|
||||
struct ktc_encryptionKey session;
|
||||
char *keytab_name = NULL;
|
||||
size_t ktlen;
|
||||
|
||||
ktlen = 5 + strlen(adir->name) + 1 + strlen(AFSDIR_RXKAD_KEYTAB_FILE) + 1;
|
||||
keytab_name = malloc(ktlen);
|
||||
if (!keytab_name) {
|
||||
return errno;
|
||||
}
|
||||
strcompose(keytab_name, ktlen, "FILE:", adir->name, "/",
|
||||
AFSDIR_RXKAD_KEYTAB_FILE, (char *)NULL);
|
||||
|
||||
r = krb5_init_context(&context);
|
||||
if (r)
|
||||
goto cleanup;
|
||||
|
||||
r = krb5_build_principal(context, &client_princ, 1, "\0", "afs", NULL);
|
||||
if (r)
|
||||
goto cleanup;
|
||||
|
||||
r = get_credv5_akimpersonate(context, keytab_name,
|
||||
NULL, client_princ,
|
||||
0, 0x7fffffff,
|
||||
NULL,
|
||||
&fake_princ);
|
||||
|
||||
if (r == 0) {
|
||||
if (tkt_DeriveDesKey(get_creds_enctype(fake_princ),
|
||||
get_cred_keydata(fake_princ),
|
||||
get_cred_keylen(fake_princ),
|
||||
&session) != 0) {
|
||||
r = RXKADBADKEY;
|
||||
goto cleanup;
|
||||
}
|
||||
tclass = (struct rx_securityClass *)
|
||||
rxkad_NewClientSecurityObject(enclevel, &session,
|
||||
RXKAD_TKT_TYPE_KERBEROS_V5,
|
||||
fake_princ->ticket.length,
|
||||
fake_princ->ticket.data);
|
||||
if (tclass != NULL) {
|
||||
*astr = tclass;
|
||||
*aindex = 2;
|
||||
r = 0;
|
||||
goto cleanup;
|
||||
}
|
||||
r = 1;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
free(keytab_name);
|
||||
if (fake_princ != NULL)
|
||||
krb5_free_creds(context, fake_princ);
|
||||
if (context != NULL)
|
||||
krb5_free_context(context);
|
||||
return r;
|
||||
}
|
||||
#endif
|
||||
|
||||
static afs_int32
|
||||
GenericAuth(struct afsconf_dir *adir,
|
||||
struct rx_securityClass **astr,
|
||||
@ -99,6 +196,13 @@ GenericAuth(struct afsconf_dir *adir,
|
||||
afs_int32 ticketLen;
|
||||
register afs_int32 code;
|
||||
|
||||
#if defined(USE_RXKAD_KEYTAB) && !defined(UKERNEL)
|
||||
/* Try to do things the v5 way, before switching down to v4 */
|
||||
code = K5Auth(adir, astr, aindex, enclevel);
|
||||
if (code == 0)
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
/* first, find the right key and kvno to use */
|
||||
code = afsconf_GetLatestKey(adir, &kvno, &key);
|
||||
if (code) {
|
||||
|
@ -78,12 +78,12 @@ bosoprocs.o: bosoprocs.c ${INCLS}
|
||||
bos.o: bos.c ${INCLS} AFS_component_version_number.o
|
||||
|
||||
bos: bos.o $(LIBS) libbos.a
|
||||
${CC} ${CFLAGS} -o bos bos.o libbos.a $(LIBS) ${XLIBS}
|
||||
${CC} ${CFLAGS} -o bos bos.o libbos.a $(LIBS) ${XLIBS} ${KRB5_LIBS}
|
||||
|
||||
bos_util.o: bos_util.c ${INCLS} AFS_component_version_number.o
|
||||
|
||||
bos_util: bos_util.o $(LIBS)
|
||||
${CC} ${CFLAGS} -o bos_util bos_util.o $(LIBS) ${XLIBS}
|
||||
${CC} ${CFLAGS} -o bos_util bos_util.o $(LIBS) ${XLIBS} ${KRB5_LIBS}
|
||||
|
||||
ezbnodeops.o: ezbnodeops.c ${INCLS}
|
||||
|
||||
@ -95,7 +95,7 @@ libbos.a: bosint.xdr.o bosint.cs.o boserr.o AFS_component_version_number.o
|
||||
$(RANLIB) $@
|
||||
|
||||
bosserver: $(OBJS) $(LIBS)
|
||||
${CC} $(CFLAGS) -o bosserver $(OBJS) ${TOP_LIBDIR}/libaudit.a $(LIBS) ${XLIBS}
|
||||
${CC} $(CFLAGS) -o bosserver $(OBJS) ${TOP_LIBDIR}/libaudit.a $(LIBS) ${XLIBS} ${KRB5_LIBS}
|
||||
|
||||
#
|
||||
# Install targets
|
||||
|
@ -1028,6 +1028,10 @@ main(int argc, char **argv, char **envp)
|
||||
bozo_rxsc[1] = (struct rx_securityClass *)0;
|
||||
bozo_rxsc[2] =
|
||||
rxkad_NewServerSecurityObject(0, tdir, afsconf_GetKey, NULL);
|
||||
#ifdef USE_RXKAD_KEYTAB
|
||||
if (rxkad_InitKeytabDecrypt(AFSDIR_SERVER_RXKAD_KEYTAB_FILEPATH) == 0)
|
||||
rxkad_BindKeytabDecrypt(bozo_rxsc[2]);
|
||||
#endif
|
||||
|
||||
/* Disable jumbograms */
|
||||
rx_SetNoJumbo();
|
||||
|
@ -52,7 +52,7 @@ main.o: AFS_component_version_number.c
|
||||
$(BACKOBJS): bc.h ${TOP_INCDIR}/afs/butc.h
|
||||
|
||||
backup: $(BACKOBJS) ${LIBS}
|
||||
${CC} ${CFLAGS} -o backup $(BACKOBJS) ${LIBS} ${XLIBS}
|
||||
${CC} ${CFLAGS} -o backup $(BACKOBJS) ${LIBS} ${XLIBS} ${KRB5_LIBS}
|
||||
|
||||
bucoord_errs.c bc.h: bucoord_errs.et bc.p.h
|
||||
$(RM) -f bc.h bucoord_errs.c
|
||||
|
@ -71,7 +71,7 @@ struct_ops.o: budb_errs.h
|
||||
server.o: server.c budb_errs.h ${INCLS} AFS_component_version_number.c
|
||||
|
||||
budb_server: $(SERVER_OBJS) ${LIBS}
|
||||
${CC} ${LDFLAGS} -o budb_server $(SERVER_OBJS) ${LIBS} ${XLIBS}
|
||||
${CC} ${LDFLAGS} -o budb_server $(SERVER_OBJS) ${LIBS} ${XLIBS} ${KRB5_LIBS}
|
||||
|
||||
budb.cs.c: budb.rg
|
||||
${RXGEN} -A -u -C -o $@ ${srcdir}/budb.rg
|
||||
|
@ -524,6 +524,10 @@ main(argc, argv)
|
||||
sca[RX_SCINDEX_KAD] =
|
||||
rxkad_NewServerSecurityObject(rxkad_clear, BU_conf, afsconf_GetKey,
|
||||
NULL);
|
||||
#ifdef USE_RXKAD_KEYTAB
|
||||
if (rxkad_InitKeytabDecrypt(AFSDIR_SERVER_RXKAD_KEYTAB_FILEPATH) == 0)
|
||||
rxkad_BindKeytabDecrypt(sca[RX_SCINDEX_KAD]);
|
||||
#endif
|
||||
|
||||
/* Disable jumbograms */
|
||||
rx_SetNoJumbo();
|
||||
|
@ -52,15 +52,15 @@ SOBJS=dbentries.o tcprocs.o lwps.o tcmain.o list.o recoverDb.o tcudbprocs.o \
|
||||
all: butc read_tape
|
||||
|
||||
butc_test: ${TESTOBJS} ${LIBS} ${INCLS} ${HACKS}
|
||||
${CC} ${CFLAGS} ${TESTOBJS} ${LIBS} ${XLIBS} -o butc_test
|
||||
${CC} ${CFLAGS} ${TESTOBJS} ${LIBS} ${XLIBS} ${KRB5_LIBS} -o butc_test
|
||||
|
||||
tdump: tdump.c AFS_component_version_number.c
|
||||
${CC} ${CFLAGS} ${srcdir}/tdump.c -o tdump
|
||||
|
||||
butc: ${SOBJS} ${LIBS} ${INCLS} ${HACKS}
|
||||
@case ${SYS_NAME} in \
|
||||
rs_aix*) ${CC} ${CFLAGS} ${SOBJS} ${LIBS} ${XLIBS} /usr/lib/libc_r.a -o butc;; \
|
||||
*) ${CC} ${CFLAGS} ${SOBJS} ${LIBS} ${XLIBS} -o butc;; \
|
||||
rs_aix*) ${CC} ${CFLAGS} ${SOBJS} ${LIBS} ${XLIBS} ${KRB5_LIBS} /usr/lib/libc_r.a -o butc;; \
|
||||
*) ${CC} ${CFLAGS} ${SOBJS} ${LIBS} ${XLIBS} ${KRB5_LIBS} -o butc;; \
|
||||
esac
|
||||
|
||||
tcmain.o: tcmain.c ${INCLS} AFS_component_version_number.c
|
||||
|
@ -56,11 +56,13 @@ if test X$conf_krb5 = XYES; then
|
||||
AC_MSG_RESULT([Configuring support for Kerberos 5 utilities])
|
||||
BUILD_KRB5=yes
|
||||
MAKE_KRB5=
|
||||
AC_DEFINE([USE_RXKAD_KEYTAB], 1,
|
||||
[Define to 1 if krb5 libraries are available and rxkad can use keytabs])
|
||||
save_CPPFLAGS="$CPPFLAGS"
|
||||
CPPFLAGS="$CPPFLAGS $KRB5CFLAGS"
|
||||
save_LIBS="$LIBS"
|
||||
LIBS="$LIBS $KRB5LIBS"
|
||||
AC_CHECK_FUNCS([add_to_error_table add_error_table krb5_princ_size krb5_principal_get_comp_string encode_krb5_enc_tkt_part encode_krb5_ticket krb5_c_encrypt krb5_c_encrypt_length krb5_cc_register krb5_decode_ticket krb5_get_prompt_types krb5_allow_weak_crypto krb5_enctype_enable])
|
||||
AC_CHECK_FUNCS([add_to_error_table add_error_table krb5_princ_size krb5_principal_get_comp_string encode_krb5_enc_tkt_part encode_krb5_ticket krb5_c_encrypt krb5_c_encrypt_length krb5_c_decrypt krb5_cc_register krb5_decode_ticket krb5_get_prompt_types krb5_allow_weak_crypto krb5_enctype_enable krb5_crypto_init krb5_encrypt_tkt_part krb5_decrypt_tkt_part])
|
||||
AC_CHECK_FUNCS([krb5_524_convert_creds], ,
|
||||
[AC_CHECK_FUNCS([krb524_convert_creds_kdc], ,
|
||||
[AC_CHECK_LIB([krb524], [krb524_convert_creds_kdc],
|
||||
@ -71,54 +73,17 @@ if test X$conf_krb5 = XYES; then
|
||||
AC_CHECK_HEADERS([kerberosIV/krb.h])
|
||||
AC_CHECK_HEADERS([kerberosV/heim_err.h])
|
||||
|
||||
AC_MSG_CHECKING(for krb5_creds.keyblock existence)
|
||||
AC_CACHE_VAL(ac_cv_krb5_creds_keyblock_exists,
|
||||
[
|
||||
AC_TRY_COMPILE(
|
||||
[#include <krb5.h>],
|
||||
[krb5_creds _c;
|
||||
printf("%x\n", _c.keyblock);],
|
||||
ac_cv_krb5_creds_keyblock_exists=yes,
|
||||
ac_cv_krb5_creds_keyblock_exists=no)])
|
||||
AC_MSG_RESULT($ac_cv_krb5_creds_keyblock_exists)
|
||||
|
||||
AC_MSG_CHECKING(for krb5_creds.session existence)
|
||||
AC_CACHE_VAL(ac_cv_krb5_creds_session_exists,
|
||||
[
|
||||
AC_TRY_COMPILE(
|
||||
[#include <krb5.h>],
|
||||
[krb5_creds _c;
|
||||
printf("%x\n", _c.session);],
|
||||
ac_cv_krb5_creds_session_exists=yes,
|
||||
ac_cv_krb5_creds_session_exists=no)])
|
||||
AC_MSG_RESULT($ac_cv_krb5_creds_session_exists)
|
||||
|
||||
AC_MSG_CHECKING(for krb5_prompt.type existence)
|
||||
AC_CACHE_VAL(ac_cv_krb5_prompt_type_exists,
|
||||
[
|
||||
AC_TRY_COMPILE(
|
||||
[#include <krb5.h>],
|
||||
[krb5_prompt _p;
|
||||
printf("%x\n", _p.type);],
|
||||
ac_cv_krb5_prompt_type_exists=yes,
|
||||
ac_cv_krb5_prompt_type_exists=no)])
|
||||
AC_MSG_RESULT($ac_cv_krb5_prompt_type_exists)
|
||||
|
||||
if test "x$ac_cv_krb5_creds_keyblock_exists" = "xyes"; then
|
||||
AC_DEFINE(HAVE_KRB5_CREDS_KEYBLOCK, 1, [define if krb5_creds has keyblock])
|
||||
fi
|
||||
if test "x$ac_cv_krb5_creds_session_exists" = "xyes"; then
|
||||
AC_DEFINE(HAVE_KRB5_CREDS_SESSION, 1, [define if krb5_creds has session])
|
||||
fi
|
||||
if test "x$ac_cv_krb5_prompt_type_exists" = "xyes"; then
|
||||
AC_DEFINE(HAVE_KRB5_PROMPT_TYPE, 1, [define if krb5_prompt has type])
|
||||
fi
|
||||
|
||||
dnl AC_CHECK_MEMBERS([krb5_creds.keyblock, krb5_creds.session],,, [#include <krb5.h>])
|
||||
AC_CHECK_MEMBERS([krb5_creds.keyblock, krb5_creds.keyblock.enctype,
|
||||
krb5_creds.session, krb5_keytab_entry.key,
|
||||
krb5_keytab_entry.keyblock, krb5_keyblock.enctype,
|
||||
krb5_keyblock.keytype, krb5_prompt.type], , ,
|
||||
[#include <krb5.h>])
|
||||
AC_CHECK_DECLS([krb5_free_keytab_entry_contents, krb5_kt_free_entry,
|
||||
KRB5_KU_TICKET], [], [], [#include <krb5.h>])
|
||||
CPPFLAGS="$save_CPPFLAGS"
|
||||
LIBS="$save_LIBS"
|
||||
fi
|
||||
|
||||
if test "x$ac_cv_krb5_cc_register_exists" = "xyes"; then
|
||||
AC_DEFINE(HAVE_KRB5_CC_REGISTER, 1, [define if krb5_cc_register exists])
|
||||
fi
|
||||
|
@ -43,6 +43,7 @@ DEST = @DEST@
|
||||
FSINCLUDES = @FSINCLUDES@
|
||||
KERN_DBG = @KERN_DBG@
|
||||
KERN_OPTMZ = @KERN_OPTMZ@
|
||||
KRB5_LIBS = @KRB5LIBS@
|
||||
LD = @LD@
|
||||
LEX = @LEX@
|
||||
LIB_AFSDB = @LIB_AFSDB@
|
||||
|
@ -41,7 +41,7 @@ fsprobe_callback.o: fsprobe_callback.c ${INCLS}
|
||||
|
||||
fsprobe_test: fsprobe_test.o libfsprobe.a ${LIBS}
|
||||
${CC} ${CFLAGS} -o fsprobe_test fsprobe_test.o libfsprobe.a \
|
||||
${LIBS} ${XLIBS}
|
||||
${LIBS} ${XLIBS} ${KRB5_LIBS}
|
||||
|
||||
#
|
||||
# Install targets
|
||||
|
@ -67,7 +67,7 @@ test tests: all
|
||||
cd test; $(MAKE)
|
||||
|
||||
kaserver: kautils.o kalocalcell.o kadatabase.o kaprocs.o kalog.o kauth.ss.o kauth.xdr.o kaserver.o kaaux.o krb_udp.o kaauxdb.o $(LIBS)
|
||||
${CC} ${LDFLAGS} -o kaserver kaserver.o kautils.o kalocalcell.o kadatabase.o krb_udp.o kaprocs.o kalog.o kauth.ss.o kauth.xdr.o kaaux.o kaauxdb.o $(LIBS) ${XLIBS} ${TOP_LIBDIR}/libaudit.a
|
||||
${CC} ${LDFLAGS} -o kaserver kaserver.o kautils.o kalocalcell.o kadatabase.o krb_udp.o kaprocs.o kalog.o kauth.ss.o kauth.xdr.o kaaux.o kaauxdb.o $(LIBS) ${XLIBS} ${TOP_LIBDIR}/libaudit.a ${KRB5_LIBS}
|
||||
|
||||
kaserver.o: kaserver.c ${INCLS} AFS_component_version_number.o
|
||||
|
||||
@ -147,19 +147,19 @@ krb_tf.o: krb_tf.c ${INCLS}
|
||||
|
||||
kas: kauth.h kautils.h admin_tools.o libkauth.a $(LIBS) kas.o kkids.o
|
||||
${CC} ${LDFLAGS} -o kas kas.o admin_tools.o kkids.o libkauth.a \
|
||||
${LIBS} ${XLIBS}
|
||||
${LIBS} ${XLIBS} ${KRB5_LIBS}
|
||||
|
||||
klog: AFS_component_version_number.o kauth.h kautils.h libkauth.a $(LIBS) \
|
||||
klog.o
|
||||
${CC} ${LDFLAGS} -o klog klog.o libkauth.a ${LIBS} ${XLIBS}
|
||||
${CC} ${LDFLAGS} -o klog klog.o libkauth.a ${LIBS} ${XLIBS} ${KRB5_LIBS}
|
||||
|
||||
klog.o: klog.c kauth.h kautils.h AFS_component_version_number.o
|
||||
|
||||
klog.krb: kauth.h kautils.h libkauth.krb.a $(KLIBS) klog.o
|
||||
${CC} ${LDFLAGS} -o klog.krb klog.o libkauth.krb.a ${KLIBS} ${XLIBS}
|
||||
${CC} ${LDFLAGS} -o klog.krb klog.o libkauth.krb.a ${KLIBS} ${XLIBS} ${KRB5_LIBS}
|
||||
|
||||
knfs: kauth.h kautils.h libkauth.a $(LIBS) knfs.o
|
||||
${CC} ${LDFLAGS} -o knfs knfs.o libkauth.a ${LIBS} ${XLIBS}
|
||||
${CC} ${LDFLAGS} -o knfs knfs.o libkauth.a ${LIBS} ${XLIBS} ${KRB5_LIBS}
|
||||
|
||||
knfs.o: knfs.c AFS_component_version_number.o
|
||||
|
||||
@ -167,22 +167,22 @@ klogin.o: klogin.c ${INCLS} AFS_component_version_number.o
|
||||
${CC} ${CFLAGS} -c ${srcdir}/klogin.c -DKAUTH
|
||||
|
||||
klogin: libkauth.a $(LIBS) klogin.o
|
||||
${CC} ${LDFLAGS} -o klogin klogin.o libkauth.a ${LIBS} ${XLIBS}
|
||||
${CC} ${LDFLAGS} -o klogin klogin.o libkauth.a ${LIBS} ${XLIBS} ${KRB5_LIBS}
|
||||
|
||||
klogin.krb: libkauth.a $(KLIBS) klogin.o
|
||||
${CC} ${LDFLAGS} -o klogin.krb klogin.o libkauth.krb.a ${KLIBS} ${XLIBS}
|
||||
${CC} ${LDFLAGS} -o klogin.krb klogin.o libkauth.krb.a ${KLIBS} ${XLIBS} ${KRB5_LIBS}
|
||||
|
||||
kpasswd.o: kauth.h kautils.h ${INCLS} kpasswd.c AFS_component_version_number.o
|
||||
${CC} ${CFLAGS} -c ${srcdir}/kpasswd.c
|
||||
|
||||
kpasswd: kauth.h kautils.h libkauth.a $(LIBS) kpasswd.o kkids.o
|
||||
${CC} ${LDFLAGS} -o kpasswd kpasswd.o kkids.o libkauth.a ${LIBS} ${XLIBS}
|
||||
${CC} ${LDFLAGS} -o kpasswd kpasswd.o kkids.o libkauth.a ${LIBS} ${XLIBS} ${KRB5_LIBS}
|
||||
|
||||
kpwvalid.o: kpwvalid.c AFS_component_version_number.o
|
||||
${CC} ${CFLAGS} -c ${srcdir}/kpwvalid.c
|
||||
|
||||
kpwvalid: kpwvalid.o $(LIBS)
|
||||
${CC} ${LDFLAGS} -o kpwvalid kpwvalid.o ${LIBS} ${XLIBS}
|
||||
${CC} ${LDFLAGS} -o kpwvalid kpwvalid.o ${LIBS} ${XLIBS} ${KRB5_LIBS}
|
||||
|
||||
user.krb.o: user.c ${INCLS} ${TOP_INCDIR}/afs/vice.h
|
||||
${CCOBJ} ${CFLAGS} -DAFS_KERBEROS_ENV -c ${srcdir}/user.c -o user.krb.o
|
||||
@ -191,7 +191,7 @@ user.o: user.c ${INCLS} ${TOP_INCDIR}/afs/vice.h
|
||||
${CCOBJ} ${CFLAGS} -c ${srcdir}/user.c
|
||||
|
||||
kdb: kdb.o ${INCLS} ${LIBS} libkauth.a
|
||||
${CC} ${LDFLAGS} -o kdb kdb.o libkauth.a ${LIBS} ${XLIBS}
|
||||
${CC} ${LDFLAGS} -o kdb kdb.o libkauth.a ${LIBS} ${XLIBS} ${KRB5_LIBS}
|
||||
|
||||
kdb.o: kdb.c AFS_component_version_number.o
|
||||
|
||||
@ -201,12 +201,12 @@ krb_udp: krb_udp.o libkauth.a $(KLIBS)
|
||||
${CC} ${LDFLAGS} -o krb_udp krb_udp.o libkauth.a $(KLIBS)
|
||||
|
||||
ka-forwarder: ka-forwarder.o
|
||||
${CC} -o $@ ${CFLAGS} ka-forwarder.o ${LIBS} ${XLIBS}
|
||||
${CC} -o $@ ${CFLAGS} ka-forwarder.o ${LIBS} ${XLIBS} ${KRB5_LIBS}
|
||||
|
||||
rebuild.o: rebuild.c $(INCLS) AFS_component_version_number.o
|
||||
|
||||
rebuild: rebuild.o kautils.o $(LIBS)
|
||||
${CC} ${LDFLAGS} -o rebuild rebuild.o kautils.o $(LIBS)
|
||||
${CC} ${LDFLAGS} -o rebuild rebuild.o kautils.o $(LIBS) ${KRB5_LIBS}
|
||||
|
||||
#
|
||||
# Install targets
|
||||
|
@ -23,6 +23,7 @@
|
||||
#else
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
#include <rx/xdr.h>
|
||||
#include <rx/rx.h>
|
||||
@ -247,7 +248,7 @@ acl_Internalize(elist, acl)
|
||||
|
||||
if (sscanf(elist, "%d\n%d\n", &p, &n) != 2)
|
||||
return -1;
|
||||
if (p + n > ACL_MAXENTRIES)
|
||||
if (p < 0 || n < 0 || p > INT_MAX - n || p + n > ACL_MAXENTRIES)
|
||||
return (-1);
|
||||
acl_NewACL(p + n, acl);
|
||||
(*acl)->total = p + n;
|
||||
@ -272,7 +273,7 @@ acl_Internalize(elist, acl)
|
||||
nextc++; /* now at the beginning of the entry list */
|
||||
for (i = 0; i < (*acl)->positive; i++) {
|
||||
int k;
|
||||
if (sscanf(nextc, "%s\t%d\n", lnames.namelist_val[i], &k) != 2) {
|
||||
if (sscanf(nextc, "%63s\t%d\n", lnames.namelist_val[i], &k) != 2) {
|
||||
free(lnames.namelist_val);
|
||||
return (-1);
|
||||
}
|
||||
@ -284,7 +285,7 @@ acl_Internalize(elist, acl)
|
||||
for (i = (*acl)->total - 1; i >= (*acl)->total - (*acl)->negative;
|
||||
i--, j++) {
|
||||
if (sscanf
|
||||
(nextc, "%s\t%d\n", lnames.namelist_val[j],
|
||||
(nextc, "%63s\t%d\n", lnames.namelist_val[j],
|
||||
&((*acl)->entries[j].rights)) != 2) {
|
||||
free(lnames.namelist_val);
|
||||
return (-1);
|
||||
|
@ -1530,7 +1530,7 @@ afsclient_ACLEntryAdd(const char *directory, const char *user,
|
||||
*/
|
||||
|
||||
is_dfs =
|
||||
sscanf(old_acl_string, "%d dfs:%d %s", &cur_acl.nplus, &cur_acl.dfs,
|
||||
sscanf(old_acl_string, "%d dfs:%d %1024s", &cur_acl.nplus, &cur_acl.dfs,
|
||||
cur_acl.cell);
|
||||
ptr = strchr(old_acl_string, '\n');
|
||||
ptr++;
|
||||
@ -1555,7 +1555,7 @@ afsclient_ACLEntryAdd(const char *directory, const char *user,
|
||||
*/
|
||||
|
||||
for (i = 0; i < (cur_acl.nplus + cur_acl.nminus); i++) {
|
||||
sscanf(ptr, "%s%d\n", cur_user, &cur_user_acl);
|
||||
sscanf(ptr, "%63s%d\n", cur_user, &cur_user_acl);
|
||||
/*
|
||||
* Skip the entry for the user we are replacing/adding
|
||||
*/
|
||||
|
@ -32,7 +32,7 @@ AUTHOBJS = \
|
||||
writeconfig.o \
|
||||
authcon.o \
|
||||
ktc_errors.o \
|
||||
acfg_errors.o
|
||||
acfg_errors.o @MAKE_KRB5@ akimpersonate.o akimpersonate_v5gen.o
|
||||
|
||||
KAUTHOBJS = \
|
||||
kauth.xdr.o \
|
||||
@ -63,7 +63,7 @@ UTILOBJS = \
|
||||
fileutil.o
|
||||
|
||||
RXKADOBJS = \
|
||||
rxkad_errs.o
|
||||
rxkad_errs.o @MAKE_KRB5@ ticket5_keytab.o
|
||||
|
||||
SYSOBJS = \
|
||||
rmtsysc.o \
|
||||
@ -120,7 +120,13 @@ writeconfig.o: ${AUTH}/writeconfig.c
|
||||
${CCRULE}
|
||||
|
||||
authcon.o: ${AUTH}/authcon.c
|
||||
${CCRULE}
|
||||
${CCRULE} @KRB5CFLAGS@
|
||||
|
||||
akimpersonate.o: ${AUTH}/akimpersonate.c
|
||||
${CCRULE} -I../auth @KRB5CFLAGS@
|
||||
|
||||
akimpersonate_v5gen.o: ${AUTH}/akimpersonate_v5gen.c
|
||||
${CCRULE} -I../auth @KRB5CFLAGS@ -I../rxkad
|
||||
|
||||
ktc_errors.o: ${AUTH}/ktc_errors.c
|
||||
${CCRULE}
|
||||
@ -197,6 +203,9 @@ pthread_glock.o: ${UTIL}/pthread_glock.c
|
||||
rxkad_errs.o: ${RXKAD}/rxkad_errs.c
|
||||
${CCRULE}
|
||||
|
||||
ticket5_keytab.o: ${RXKAD}/ticket5_keytab.c
|
||||
${CCRULE} @KRB5CFLAGS@
|
||||
|
||||
ptclient.o: ${PTSERVER}/ptclient.c
|
||||
${CCRULE}
|
||||
|
||||
|
@ -57,7 +57,7 @@ depinstall: \
|
||||
# Build targets
|
||||
#
|
||||
ptserver: ptserver.o ptutils.o ptprocs.o ptint.ss.o ptint.xdr.o utils.o $(LIBS) ${TOP_LIBDIR}/libaudit.a map.o
|
||||
$(CC) ${CFLAGS} -o ptserver ptserver.o ptutils.o ptprocs.o ptint.ss.o ptint.xdr.o utils.o map.o $(LIBS) ${XLIBS} ${TOP_LIBDIR}/libaudit.a
|
||||
$(CC) ${CFLAGS} -o ptserver ptserver.o ptutils.o ptprocs.o ptint.ss.o ptint.xdr.o utils.o map.o $(LIBS) ${XLIBS} ${TOP_LIBDIR}/libaudit.a ${KRB5_LIBS}
|
||||
|
||||
ptserver.o: ptserver.c ${INCLS} AFS_component_version_number.c
|
||||
|
||||
@ -103,10 +103,10 @@ display.o: display.c ${INCLS}
|
||||
db_verify.o: db_verify.c ${INCLS} AFS_component_version_number.c
|
||||
|
||||
db_verify: db_verify.o pterror.o display.o $(LIBS)
|
||||
$(CC) ${CFLAGS} -o db_verify db_verify.o display.o pterror.o $(LIBS) ${XLIBS}
|
||||
$(CC) ${CFLAGS} -o db_verify db_verify.o display.o pterror.o $(LIBS) ${XLIBS} ${KRB5_LIBS}
|
||||
|
||||
ptclient: ptclient.o display.o libprot.a $(LIBS)
|
||||
$(CC) ${CFLAGS} -o ptclient ptclient.o display.o libprot.a $(LIBS) ${XLIBS}
|
||||
$(CC) ${CFLAGS} -o ptclient ptclient.o display.o libprot.a $(LIBS) ${XLIBS} ${KRB5_LIBS}
|
||||
|
||||
ptclient.o: ptclient.c ${INCLS} AFS_component_version_number.c
|
||||
|
||||
@ -122,32 +122,32 @@ libprot.a: ptuser.o pterror.o ptint.cs.o ptint.xdr.o AFS_component_version_numbe
|
||||
$(RANLIB) $@
|
||||
|
||||
pts: pts.o libprot.a ${TOP_LIBDIR}/libcmd.a $(LIBS)
|
||||
$(CC) ${CFLAGS} -o pts pts.o ${TOP_LIBDIR}/libcmd.a libprot.a ${LIBS} ${XLIBS}
|
||||
$(CC) ${CFLAGS} -o pts pts.o ${TOP_LIBDIR}/libcmd.a libprot.a ${LIBS} ${XLIBS} ${KRB5_LIBS}
|
||||
|
||||
pts.o: pts.c ${LINCLS} ${TOP_INCDIR}/afs/cmd.h AFS_component_version_number.c
|
||||
|
||||
readgroup: readgroup.o libprot.a $(LIBS)
|
||||
$(CC) ${CFLAGS} -o readgroup readgroup.o libprot.a ${LIBS} ${XLIBS}
|
||||
$(CC) ${CFLAGS} -o readgroup readgroup.o libprot.a ${LIBS} ${XLIBS} ${KRB5_LIBS}
|
||||
|
||||
readgroup.o: readgroup.c ${LINCLS} AFS_component_version_number.c
|
||||
|
||||
readpwd: readpwd.o libprot.a $(LIBS)
|
||||
$(CC) ${CFLAGS} -o readpwd readpwd.o libprot.a ${LIBS} ${XLIBS}
|
||||
$(CC) ${CFLAGS} -o readpwd readpwd.o libprot.a ${LIBS} ${XLIBS} ${KRB5_LIBS}
|
||||
|
||||
readpwd.o: readpwd.c ${LINCLS} AFS_component_version_number.c
|
||||
|
||||
testpt: testpt.o libprot.a ${TOP_LIBDIR}/libcmd.a $(LIBS)
|
||||
case "$(SYS_NAME)" in \
|
||||
*_darwin_12 ) \
|
||||
$(CC) ${CFLAGS} -o testpt testpt.o ${TOP_LIBDIR}/libcmd.a libprot.a $(LIBS) ;; \
|
||||
$(CC) ${CFLAGS} -o testpt testpt.o ${TOP_LIBDIR}/libcmd.a libprot.a $(LIBS) ${KRB5_LIBS} ;; \
|
||||
* ) \
|
||||
$(CC) ${CFLAGS} -o testpt testpt.o -lm ${TOP_LIBDIR}/libcmd.a libprot.a $(LIBS) ${XLIBS} ;; \
|
||||
$(CC) ${CFLAGS} -o testpt testpt.o -lm ${TOP_LIBDIR}/libcmd.a libprot.a $(LIBS) ${XLIBS} ${KRB5_LIBS} ;; \
|
||||
esac
|
||||
|
||||
testpt.o: testpt.c ${INCLS} ${TOP_INCDIR}/afs/cmd.h AFS_component_version_number.c
|
||||
|
||||
pt_util: pt_util.o ptutils.o ubik.o utils.o map.o libprot.a $(LIBS)
|
||||
$(CC) ${CFLAGS} -o pt_util pt_util.o ptutils.o ubik.o utils.o map.o libprot.a ${TOP_LIBDIR}/libcmd.a $(LIBS) ${XLIBS}
|
||||
$(CC) ${CFLAGS} -o pt_util pt_util.o ptutils.o ubik.o utils.o map.o libprot.a ${TOP_LIBDIR}/libcmd.a $(LIBS) ${XLIBS} ${KRB5_LIBS}
|
||||
|
||||
ubik.o: ubik.c ${INCLS}
|
||||
|
||||
|
@ -691,7 +691,7 @@ idToName(call, aid, aname)
|
||||
size = aid->idlist_len;
|
||||
if (size == 0)
|
||||
return 0;
|
||||
if (size < 0)
|
||||
if (size < 0 || size > INT_MAX / PR_MAXNAMELEN)
|
||||
return PRTOOMANY;
|
||||
aname->namelist_val = (prname *) malloc(size * PR_MAXNAMELEN);
|
||||
aname->namelist_len = 0;
|
||||
|
@ -521,6 +521,10 @@ main(int argc, char **argv)
|
||||
sc[1] = 0;
|
||||
if (kerberosKeys) {
|
||||
sc[2] = rxkad_NewServerSecurityObject(0, prdir, afsconf_GetKey, NULL);
|
||||
#ifdef USE_RXKAD_KEYTAB
|
||||
if (rxkad_InitKeytabDecrypt(AFSDIR_SERVER_RXKAD_KEYTAB_FILEPATH) == 0)
|
||||
rxkad_BindKeytabDecrypt(sc[2]);
|
||||
#endif
|
||||
} else
|
||||
sc[2] = sc[0];
|
||||
|
||||
|
@ -1218,27 +1218,8 @@ int rxk_ListenerPid; /* Used to signal process to wakeup at shutdown */
|
||||
struct task_struct *rxk_ListenerTask;
|
||||
#endif
|
||||
|
||||
#ifdef AFS_SUN5_ENV
|
||||
/*
|
||||
* Run the listener as a kernel thread.
|
||||
*/
|
||||
void
|
||||
rxk_Listener(void)
|
||||
{
|
||||
extern id_t syscid;
|
||||
void rxk_ListenerProc(void);
|
||||
if (thread_create
|
||||
(NULL, DEFAULTSTKSZ, rxk_ListenerProc, 0, 0, &p0, TS_RUN,
|
||||
minclsyspri) == NULL)
|
||||
osi_Panic("rxk_Listener: failed to start listener thread!\n");
|
||||
}
|
||||
|
||||
void
|
||||
rxk_ListenerProc(void)
|
||||
#else /* AFS_SUN5_ENV */
|
||||
void
|
||||
rxk_Listener(void)
|
||||
#endif /* AFS_SUN5_ENV */
|
||||
{
|
||||
struct rx_packet *rxp = NULL;
|
||||
int code;
|
||||
@ -1259,9 +1240,9 @@ rxk_Listener(void)
|
||||
#elif defined(AFS_DARWIN_ENV)
|
||||
rxk_ListenerPid = current_proc()->p_pid;
|
||||
#endif
|
||||
#if defined(RX_ENABLE_LOCKS) && !defined(AFS_SUN5_ENV)
|
||||
#ifdef RX_ENABLE_LOCKS
|
||||
AFS_GUNLOCK();
|
||||
#endif /* RX_ENABLE_LOCKS && !AFS_SUN5_ENV */
|
||||
#endif /* RX_ENABLE_LOCKS */
|
||||
while (afs_termState != AFSOP_STOP_RXK_LISTENER) {
|
||||
if (rxp) {
|
||||
rxi_RestoreDataBufs(rxp);
|
||||
@ -1294,9 +1275,6 @@ rxk_Listener(void)
|
||||
#if defined(AFS_SUN5_ENV)
|
||||
osi_rxWakeup(&rxk_ListenerPid);
|
||||
#endif
|
||||
#ifdef AFS_SUN5_ENV
|
||||
AFS_GUNLOCK();
|
||||
#endif /* AFS_SUN5_ENV */
|
||||
}
|
||||
|
||||
#if !defined(AFS_LINUX20_ENV) && !defined(AFS_SUN5_ENV) && !defined(AFS_DARWIN_ENV) && !defined(AFS_XBSD_ENV)
|
||||
|
@ -17,7 +17,7 @@ INCLS=${TOP_INCDIR}/rx/rx.h ${TOP_INCDIR}/rx/xdr.h \
|
||||
|
||||
OBJS=rxkad_client.o rxkad_server.o rxkad_common.o rxkad_errs.o \
|
||||
fcrypt.o crypt_conn.o ticket.o ticket5.o crc.o \
|
||||
md4.o md5.o
|
||||
md4.o md5.o @MAKE_KRB5@ ticket5_keytab.o
|
||||
|
||||
fc_test_OBJS=fc_test.o
|
||||
|
||||
@ -94,6 +94,9 @@ fcrypt.o: ${srcdir}/domestic/fcrypt.c fcrypt.h sboxes.h rxkad.h rxkad_prototypes
|
||||
crypt_conn.o: ${srcdir}/domestic/crypt_conn.c fcrypt.h private_data.h ${INCLS}
|
||||
${CCOBJ} ${CFLAGS} -c ${srcdir}/domestic/crypt_conn.c
|
||||
|
||||
ticket5_keytab.o: ticket5_keytab.c ${INCLS}
|
||||
${CCOBJ} ${CFLAGS} -c ${srcdir}/ticket5_keytab.c @KRB5CFLAGS@
|
||||
|
||||
tcrypt.o: ${srcdir}/domestic/tcrypt.c AFS_component_version_number.o
|
||||
${CCOBJ} ${CFLAGS} -c ${srcdir}/domestic/fcrypt.c
|
||||
|
||||
|
@ -78,6 +78,7 @@ struct rxkad_sprivate {
|
||||
int (*get_key) (); /* func. of kvno and server key ptr */
|
||||
int (*user_ok) (); /* func called with new client name */
|
||||
afs_uint32 flags; /* configuration flags */
|
||||
rxkad_alt_decrypt_func alt_decrypt;
|
||||
};
|
||||
|
||||
/* private data in server-side connection */
|
||||
|
@ -93,6 +93,11 @@ typedef char rxkad_level;
|
||||
|
||||
extern int rxkad_EpochWasSet; /* TRUE => we called rx_SetEpoch */
|
||||
|
||||
/* An alternate decryption function for rxkad. Using the given kvno and
|
||||
* enctype, decrypt the input data + length to output data + length. */
|
||||
typedef int (*rxkad_alt_decrypt_func)(int, int, void *, size_t, void *,
|
||||
size_t *);
|
||||
|
||||
#include "rxkad_prototypes.h"
|
||||
|
||||
#endif /* OPENAFS_RXKAD_RXKAD_H */
|
||||
|
@ -124,6 +124,8 @@ extern afs_int32 rxkad_SetConfiguration(struct rx_securityClass *aobj,
|
||||
struct rx_connection *aconn,
|
||||
rx_securityConfigVariables atype,
|
||||
void * avalue, void **aresult);
|
||||
extern int rxkad_SetAltDecryptProc(struct rx_securityClass *aobj,
|
||||
rxkad_alt_decrypt_func alt_decrypt);
|
||||
|
||||
/* ticket.c */
|
||||
extern int tkt_DecodeTicket(char *asecret, afs_int32 ticketLen,
|
||||
@ -149,6 +151,16 @@ extern int tkt_DecodeTicket5(char *ticket, afs_int32 ticket_len,
|
||||
char *get_key_rock, int serv_kvno, char *name,
|
||||
char *inst, char *cell, char *session_key,
|
||||
afs_int32 * host, afs_int32 * start,
|
||||
afs_int32 * end, afs_int32 disableDotCheck);
|
||||
afs_int32 * end, afs_int32 disableDotCheck,
|
||||
rxkad_alt_decrypt_func alt_decrypt);
|
||||
/*
|
||||
* Compute a des key from a key of a semi-arbitrary kerberos 5 enctype.
|
||||
* Modifies keydata if enctype is 3des.
|
||||
*/
|
||||
extern int tkt_DeriveDesKey(int enctype, void *keydata, size_t keylen, struct ktc_encryptionKey
|
||||
*output);
|
||||
/* ticket5_keytab.c */
|
||||
extern int rxkad_InitKeytabDecrypt(const char *);
|
||||
extern int rxkad_BindKeytabDecrypt(struct rx_securityClass *);
|
||||
|
||||
#endif
|
||||
|
@ -326,7 +326,8 @@ rxkad_CheckResponse(struct rx_securityClass *aobj,
|
||||
tkt_DecodeTicket5(tix, tlen, tsp->get_key, tsp->get_key_rock,
|
||||
kvno, client.name, client.instance, client.cell,
|
||||
&sessionkey, &host, &start, &end,
|
||||
tsp->flags & RXS_CONFIG_FLAGS_DISABLE_DOTCHECK);
|
||||
tsp->flags & RXS_CONFIG_FLAGS_DISABLE_DOTCHECK,
|
||||
tsp->alt_decrypt);
|
||||
if (code)
|
||||
return code;
|
||||
}
|
||||
@ -474,3 +475,13 @@ afs_int32 rxkad_SetConfiguration(struct rx_securityClass *aobj,
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rxkad_SetAltDecryptProc(struct rx_securityClass *aobj,
|
||||
rxkad_alt_decrypt_func alt_decrypt)
|
||||
{
|
||||
struct rxkad_sprivate *private =
|
||||
(struct rxkad_sprivate *)aobj->privateData;
|
||||
|
||||
private->alt_decrypt = alt_decrypt;
|
||||
return 0;
|
||||
}
|
||||
|
@ -83,6 +83,7 @@
|
||||
#include <rx/xdr.h>
|
||||
#include <rx/rx.h>
|
||||
#include <des.h>
|
||||
#include <des_prototypes.h>
|
||||
#include "lifetimes.h"
|
||||
#include "rxkad.h"
|
||||
#endif /* defined(UKERNEL) */
|
||||
@ -183,8 +184,11 @@ static const struct krb_convert sconv_list[] = {
|
||||
static int
|
||||
krb5_des_decrypt(struct ktc_encryptionKey *, int, void *, size_t, void *,
|
||||
size_t *);
|
||||
|
||||
|
||||
static int rxkad_derive_des_key(const void *, size_t,
|
||||
struct ktc_encryptionKey *);
|
||||
static int compress_parity_bits(void *, size_t *);
|
||||
static void hmac_md5_iov(const void *, size_t, const struct iovec *,
|
||||
unsigned int, void *);
|
||||
|
||||
|
||||
int
|
||||
@ -192,7 +196,8 @@ tkt_DecodeTicket5(char *ticket, afs_int32 ticket_len,
|
||||
int (*get_key) (char *, int, struct ktc_encryptionKey *),
|
||||
char *get_key_rock, int serv_kvno, char *name, char *inst,
|
||||
char *cell, char *session_key, afs_int32 * host,
|
||||
afs_int32 * start, afs_int32 * end, afs_int32 disableCheckdot)
|
||||
afs_int32 * start, afs_int32 * end, afs_int32 disableCheckdot,
|
||||
rxkad_alt_decrypt_func alt_decrypt)
|
||||
{
|
||||
char plain[MAXKRB5TICKETLEN];
|
||||
struct ktc_encryptionKey serv_key;
|
||||
@ -233,19 +238,15 @@ tkt_DecodeTicket5(char *ticket, afs_int32 ticket_len,
|
||||
v5_serv_kvno = *t5.enc_part.kvno;
|
||||
}
|
||||
|
||||
/* Check that the key type really fit into 8 bytes */
|
||||
/* check ticket */
|
||||
if (t5.enc_part.cipher.length > sizeof(plain))
|
||||
goto bad_ticket;
|
||||
switch (t5.enc_part.etype) {
|
||||
case ETYPE_DES_CBC_CRC:
|
||||
case ETYPE_DES_CBC_MD4:
|
||||
case ETYPE_DES_CBC_MD5:
|
||||
break;
|
||||
default:
|
||||
goto unknown_key;
|
||||
}
|
||||
|
||||
/* check ticket */
|
||||
if (t5.enc_part.cipher.length > sizeof(plain)
|
||||
|| t5.enc_part.cipher.length % 8 != 0)
|
||||
/* Check that the key type really fit into 8 bytes */
|
||||
if (t5.enc_part.cipher.length % 8 != 0)
|
||||
goto bad_ticket;
|
||||
|
||||
code = (*get_key) (get_key_rock, v5_serv_kvno, &serv_key);
|
||||
@ -255,10 +256,22 @@ tkt_DecodeTicket5(char *ticket, afs_int32 ticket_len,
|
||||
/* Decrypt data here, save in plain, assume it will shrink */
|
||||
code =
|
||||
krb5_des_decrypt(&serv_key, t5.enc_part.etype,
|
||||
t5.enc_part.cipher.data, t5.enc_part.cipher.length,
|
||||
plain, &plainsiz);
|
||||
t5.enc_part.cipher.data,
|
||||
t5.enc_part.cipher.length, plain, &plainsiz);
|
||||
if (code != 0)
|
||||
goto bad_ticket;
|
||||
break;
|
||||
default:
|
||||
if (alt_decrypt != NULL) {
|
||||
plainsiz = sizeof(plain);
|
||||
code = alt_decrypt(v5_serv_kvno, t5.enc_part.etype,
|
||||
t5.enc_part.cipher.data,
|
||||
t5.enc_part.cipher.length, plain, &plainsiz);
|
||||
if (code != 0)
|
||||
goto cleanup;
|
||||
} else
|
||||
goto unknown_key;
|
||||
}
|
||||
|
||||
/* Decode ticket */
|
||||
code = decode_EncTicketPart(plain, plainsiz, &decr_part, &siz);
|
||||
@ -320,21 +333,9 @@ tkt_DecodeTicket5(char *ticket, afs_int32 ticket_len,
|
||||
}
|
||||
|
||||
/* Verify that decr_part.key is of right type */
|
||||
switch (decr_part.key.keytype) {
|
||||
case ETYPE_DES_CBC_CRC:
|
||||
case ETYPE_DES_CBC_MD4:
|
||||
case ETYPE_DES_CBC_MD5:
|
||||
break;
|
||||
default:
|
||||
if (tkt_DeriveDesKey(decr_part.key.keytype, decr_part.key.keyvalue.data,
|
||||
decr_part.key.keyvalue.length, session_key) != 0)
|
||||
goto bad_ticket;
|
||||
}
|
||||
|
||||
if (decr_part.key.keyvalue.length != 8)
|
||||
goto bad_ticket;
|
||||
|
||||
/* Extract session key */
|
||||
memcpy(session_key, decr_part.key.keyvalue.data, 8);
|
||||
|
||||
/* Check lifetimes and host addresses, flags etc */
|
||||
{
|
||||
time_t now = time(0); /* Use fast time package instead??? */
|
||||
@ -482,3 +483,176 @@ krb5_des_decrypt(struct ktc_encryptionKey *key, int etype, void *in,
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Use NIST SP800-108 with HMAC(MD5) in counter mode as the PRF to derive a
|
||||
* des key from another type of key.
|
||||
*
|
||||
* L is 64, as we take 64 random bits and turn them into a 56-bit des key.
|
||||
* The output of hmac_md5 is 128 bits; we take the first 64 only, so n
|
||||
* properly should be 1. However, we apply a slight variation due to the
|
||||
* possibility of producing a weak des key. If the output key is weak, do NOT
|
||||
* simply correct it, instead, the counter is advanced and the next output
|
||||
* used. As such, we code so as to have n be the full 255 permitted by our
|
||||
* encoding of the counter i in an 8-bit field. L itself is encoded as a
|
||||
* 32-bit field, big-endian. We use the constant string "rxkad" as a label
|
||||
* for this key derivation, the standard NUL byte separator, and omit a
|
||||
* key-derivation context. The input key is unique to the krb5 service ticket,
|
||||
* which is unlikely to be used in an other location. If it is used in such
|
||||
* a fashion, both locations will derive the same des key from the PRF, but
|
||||
* this is no different from if a krb5 des key had been used in the same way,
|
||||
* as traditional krb5 rxkad uses the ticket session key directly as the token
|
||||
* key.
|
||||
*/
|
||||
static int
|
||||
rxkad_derive_des_key(const void *in, size_t insize,
|
||||
struct ktc_encryptionKey *out)
|
||||
{
|
||||
unsigned char i;
|
||||
char Lbuf[4]; /* bits of output, as 32 bit word, MSB first */
|
||||
char tmp[16];
|
||||
struct iovec iov[3];
|
||||
des_cblock ktmp;
|
||||
|
||||
Lbuf[0] = 0;
|
||||
Lbuf[1] = 0;
|
||||
Lbuf[2] = 0;
|
||||
Lbuf[3] = 64;
|
||||
|
||||
iov[0].iov_base = &i;
|
||||
iov[0].iov_len = 1;
|
||||
iov[1].iov_base = "rxkad";
|
||||
iov[1].iov_len = strlen("rxkad") + 1; /* includes label and separator */
|
||||
iov[2].iov_base = Lbuf;
|
||||
iov[2].iov_len = 4;
|
||||
|
||||
/* stop when 8 bit counter wraps to 0 */
|
||||
for (i = 1; i ; i++) {
|
||||
hmac_md5_iov(in, insize, iov, 3, tmp);
|
||||
memcpy(ktmp, tmp, 8);
|
||||
des_fixup_key_parity(ktmp);
|
||||
if (!des_is_weak_key(ktmp)) {
|
||||
memcpy(out->data, ktmp, 8);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is the inverse of the random-to-key for 3des specified in
|
||||
* rfc3961, converting blocks of 8 bytes to blocks of 7 bytes by distributing
|
||||
* the bits of each 8th byte as the lsb of the previous 7 bytes.
|
||||
*/
|
||||
static int
|
||||
compress_parity_bits(void *buffer, size_t *bufsiz)
|
||||
{
|
||||
unsigned char *cb, tmp;
|
||||
int i, j, nk;
|
||||
|
||||
if (*bufsiz % 8 != 0)
|
||||
return 1;
|
||||
cb = (unsigned char *)buffer;
|
||||
nk = *bufsiz / 8;
|
||||
for (i = 0; i < nk; i++) {
|
||||
tmp = cb[8 * i + 7] >> 1;
|
||||
for (j = 0; j < 7; j++) {
|
||||
cb[8 * i + j] &= 0xfe;
|
||||
cb[8 * i + j] |= tmp & 0x1;
|
||||
tmp >>= 1;
|
||||
}
|
||||
}
|
||||
for (i = 1; i < nk; i++)
|
||||
memmove(cb + 7 * i, cb + 8 * i, 7);
|
||||
*bufsiz = 7 * nk;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* HMAC: Keyed-Hashing for Message Authentication, using MD5 as the hash.
|
||||
* See RFC 2104.
|
||||
*
|
||||
* The constants 64 and 16 are the input block size and output length,
|
||||
* respectively, of md5.
|
||||
*/
|
||||
static void
|
||||
hmac_md5_iov(const void *key, size_t ks,
|
||||
const struct iovec *data, unsigned int niov, void *output)
|
||||
{
|
||||
MD5_CTX md5;
|
||||
const unsigned char *kp;
|
||||
unsigned int i;
|
||||
unsigned char tmp[16], tmpk[16], i_pad[64], o_pad[64];
|
||||
if (ks > 64) {
|
||||
MD5_Init(&md5);
|
||||
MD5_Update(&md5, key, ks);
|
||||
MD5_Final(tmpk, &md5);
|
||||
key = tmpk;
|
||||
ks = 16;
|
||||
}
|
||||
kp = key;
|
||||
for (i = 0; i < ks; i++)
|
||||
i_pad[i] = kp[i] ^ 0x36;
|
||||
memset(i_pad + ks, 0x36, 64 - ks);
|
||||
MD5_Init(&md5);
|
||||
MD5_Update(&md5, i_pad, 64);
|
||||
for (i = 0; i < niov; i++)
|
||||
MD5_Update(&md5, data[i].iov_base, data[i].iov_len);
|
||||
MD5_Final(tmp, &md5);
|
||||
for (i = 0; i < ks; i++)
|
||||
o_pad[i] = kp[i] ^ 0x5c;
|
||||
memset(o_pad + ks, 0x5c, 64 - ks);
|
||||
MD5_Init(&md5);
|
||||
MD5_Update(&md5, o_pad, 64);
|
||||
MD5_Update(&md5, tmp, 16);
|
||||
MD5_Final(output, &md5);
|
||||
}
|
||||
|
||||
/*
|
||||
* Enctype-specific knowledge about how to derive a des key from a given
|
||||
* key. If given a des key, use it directly; otherwise, perform any
|
||||
* parity fixup that may be needed and pass through to the hmad-md5 bits.
|
||||
*/
|
||||
int
|
||||
tkt_DeriveDesKey(int enctype, void *keydata, size_t keylen,
|
||||
struct ktc_encryptionKey *output)
|
||||
{
|
||||
switch (enctype) {
|
||||
case ETYPE_DES_CBC_CRC:
|
||||
case ETYPE_DES_CBC_MD4:
|
||||
case ETYPE_DES_CBC_MD5:
|
||||
if (keylen != 8)
|
||||
return 1;
|
||||
|
||||
/* Extract session key */
|
||||
memcpy(output, keydata, 8);
|
||||
break;
|
||||
case ETYPE_NULL:
|
||||
case 4:
|
||||
case 6:
|
||||
case 8:
|
||||
case 9:
|
||||
case 10:
|
||||
case 11:
|
||||
case 12:
|
||||
case 13:
|
||||
case 14:
|
||||
case 15:
|
||||
return 1;
|
||||
/*In order to become a "Cryptographic Key" as specified in
|
||||
* SP800-108, it must be indistinguishable from a random bitstring. */
|
||||
case ETYPE_DES3_CBC_MD5:
|
||||
case ETYPE_OLD_DES3_CBC_SHA1:
|
||||
case ETYPE_DES3_CBC_SHA1:
|
||||
if (compress_parity_bits(keydata, &keylen))
|
||||
return 1;
|
||||
/* FALLTHROUGH */
|
||||
default:
|
||||
if (enctype < 0)
|
||||
return 1;
|
||||
if (keylen < 7)
|
||||
return 1;
|
||||
if (rxkad_derive_des_key(keydata, keylen, output) != 0)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
358
src/rxkad/ticket5_keytab.c
Normal file
358
src/rxkad/ticket5_keytab.c
Normal file
@ -0,0 +1,358 @@
|
||||
/*
|
||||
* Copyright (c) 2013 Chaskiel Grundman <cg2v@andrew.cmu.edu>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <afsconfig.h>
|
||||
#include <afs/param.h>
|
||||
#include <afs/stds.h>
|
||||
#include <afs/dirpath.h>
|
||||
#include <rx/rx.h>
|
||||
#include <rx/rxkad.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <krb5.h>
|
||||
|
||||
#ifdef RX_ENABLE_LOCKS
|
||||
static afs_kmutex_t krb5_lock;
|
||||
#endif
|
||||
|
||||
/* these globals are expected to be set only once, so locking is not needed */
|
||||
static char *keytab_name;
|
||||
static int have_keytab_keys;
|
||||
|
||||
/*
|
||||
* krb5_lock must be held to use/set these globals, including any
|
||||
* krb5 api use with k5ctx
|
||||
*/
|
||||
static krb5_context k5ctx;
|
||||
static int nkeys;
|
||||
static krb5_keytab_entry *ktent;
|
||||
static time_t last_reload;
|
||||
|
||||
#ifdef HAVE_KRB5_KEYBLOCK_ENCTYPE
|
||||
# define kb_enctype(keyblock) ((keyblock)->enctype)
|
||||
#elif defined(HAVE_KRB5_KEYBLOCK_KEYTYPE)
|
||||
# define kb_enctype(keyblock) ((keyblock)->keytype)
|
||||
#else
|
||||
# error Cannot figure out how keyblocks work
|
||||
#endif
|
||||
#ifdef HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK
|
||||
# define kte_keyblock(kte) (&(kte).keyblock)
|
||||
#elif defined(HAVE_KRB5_KEYTAB_ENTRY_KEY)
|
||||
# define kte_keyblock(kte) (&(kte).key)
|
||||
#else
|
||||
# error Cannot figure out how keytab entries work
|
||||
#endif
|
||||
#if HAVE_DECL_KRB5_FREE_KEYTAB_ENTRY_CONTENTS
|
||||
/* nothing */
|
||||
#elif HAVE_DECL_KRB5_KT_FREE_ENTRY
|
||||
# define krb5_free_keytab_entry_contents krb5_kt_free_entry
|
||||
#else
|
||||
static_inline int
|
||||
krb5_free_keytab_entry_contents(krb5_context ctx, krb5_keytab_entry *ent)
|
||||
{
|
||||
krb5_free_principal(ctx, ent->principal);
|
||||
krb5_free_keyblock_contents(ctx, kte_keyblock(ent));
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#ifndef KRB5_KEYUSAGE_KDC_REP_TICKET
|
||||
# ifdef HAVE_DECL_KRB5_KU_TICKET
|
||||
# define KRB5_KEYUSAGE_KDC_REP_TICKET KRB5_KU_TICKET
|
||||
# else
|
||||
# define KRB5_KEYUSAGE_KDC_REP_TICKET 2
|
||||
# endif
|
||||
#endif
|
||||
|
||||
static krb5_error_code
|
||||
reload_keys(void)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
krb5_keytab fkeytab = NULL;
|
||||
krb5_kt_cursor c;
|
||||
krb5_keytab_entry kte;
|
||||
int i, n_nkeys, o_nkeys;
|
||||
krb5_keytab_entry *n_ktent = NULL, *o_ktent;
|
||||
struct stat tstat;
|
||||
|
||||
if (stat(AFSDIR_SERVER_CELLSERVDB_FILEPATH, &tstat) == 0) {
|
||||
if (have_keytab_keys && tstat.st_mtime == last_reload) {
|
||||
/* We haven't changed since the last time we loaded our keys, so
|
||||
* there's nothing to do. */
|
||||
ret = 0;
|
||||
goto cleanup;
|
||||
}
|
||||
last_reload = tstat.st_mtime;
|
||||
} else if (have_keytab_keys) {
|
||||
/* stat() failed, but we already have keys, so don't do anything. */
|
||||
ret = 0;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (keytab_name != NULL)
|
||||
ret = krb5_kt_resolve(k5ctx, keytab_name, &fkeytab);
|
||||
else
|
||||
ret = krb5_kt_default(k5ctx, &fkeytab);
|
||||
if (ret != 0)
|
||||
goto cleanup;
|
||||
ret = krb5_kt_start_seq_get(k5ctx, fkeytab, &c);
|
||||
if (ret != 0)
|
||||
goto cleanup;
|
||||
n_nkeys = 0;
|
||||
while (krb5_kt_next_entry(k5ctx, fkeytab, &kte, &c) == 0) {
|
||||
krb5_free_keytab_entry_contents(k5ctx, &kte);
|
||||
n_nkeys++;
|
||||
}
|
||||
krb5_kt_end_seq_get(k5ctx, fkeytab, &c);
|
||||
if (n_nkeys == 0) {
|
||||
ret = KRB5_KT_NOTFOUND;
|
||||
goto cleanup;
|
||||
}
|
||||
n_ktent = calloc(n_nkeys, sizeof(krb5_keytab_entry));
|
||||
if (n_ktent == NULL) {
|
||||
ret = KRB5_KT_NOTFOUND;
|
||||
goto cleanup;
|
||||
}
|
||||
ret = krb5_kt_start_seq_get(k5ctx, fkeytab, &c);
|
||||
if (ret != 0)
|
||||
goto cleanup;
|
||||
for (i = 0; i < n_nkeys; i++)
|
||||
if (krb5_kt_next_entry(k5ctx, fkeytab, &n_ktent[i], &c) != 0)
|
||||
break;
|
||||
krb5_kt_end_seq_get(k5ctx, fkeytab, &c);
|
||||
if (i < n_nkeys)
|
||||
goto cleanup;
|
||||
have_keytab_keys = 1;
|
||||
o_ktent = ktent;
|
||||
ktent = n_ktent;
|
||||
|
||||
o_nkeys = nkeys;
|
||||
nkeys = n_nkeys;
|
||||
|
||||
/* for cleanup */
|
||||
n_ktent = o_ktent;
|
||||
n_nkeys = o_nkeys;
|
||||
cleanup:
|
||||
if (n_ktent != NULL) {
|
||||
for (i = 0; i < n_nkeys; i++)
|
||||
krb5_free_keytab_entry_contents(k5ctx, &n_ktent[i]);
|
||||
free(n_ktent);
|
||||
}
|
||||
if (fkeytab != NULL) {
|
||||
krb5_kt_close(k5ctx, fkeytab);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if defined(HAVE_KRB5_DECRYPT_TKT_PART) && !defined(HAVE_KRB5_C_DECRYPT)
|
||||
extern krb5_error_code
|
||||
encode_krb5_enc_tkt_part(krb5_enc_tkt_part *encpart, krb5_data **a_out);
|
||||
/*
|
||||
* AIX krb5 has krb5_decrypt_tkt_part, but no krb5_c_decrypt. So, implement our
|
||||
* own krb5_c_decrypt. Note that this krb5_c_decrypt is only suitable for
|
||||
* decrypting an encrypted krb5_enc_tkt_part. But since that's all we ever use
|
||||
* it for, that should be fine.
|
||||
*/
|
||||
static krb5_error_code
|
||||
krb5_c_decrypt(krb5_context context, const krb5_keyblock *key,
|
||||
krb5_keyusage usage, const krb5_data *cipher_state,
|
||||
const krb5_enc_data *input, krb5_data *output)
|
||||
{
|
||||
krb5_ticket tkt;
|
||||
krb5_error_code code;
|
||||
krb5_data *tout = NULL;
|
||||
|
||||
/* We only handle a subset of possible arguments; if we somehow get passed
|
||||
* something else, bail out with EINVAL. */
|
||||
if (cipher_state != NULL)
|
||||
return EINVAL;
|
||||
if (usage != KRB5_KEYUSAGE_KDC_REP_TICKET)
|
||||
return EINVAL;
|
||||
|
||||
memset(&tkt, 0, sizeof(tkt));
|
||||
|
||||
tkt.enc_part = *input;
|
||||
|
||||
code = krb5_decrypt_tkt_part(context, key, &tkt);
|
||||
if (code != 0)
|
||||
return code;
|
||||
|
||||
code = encode_krb5_enc_tkt_part(tkt.enc_part2, &tout);
|
||||
if (code != 0)
|
||||
return code;
|
||||
|
||||
if (tout->length > output->length) {
|
||||
/* This should never happen, but don't assert since we may be dealing
|
||||
* with untrusted user data. */
|
||||
code = EINVAL;
|
||||
goto error;
|
||||
}
|
||||
|
||||
memcpy(output->data, tout->data, tout->length);
|
||||
output->length = tout->length;
|
||||
|
||||
error:
|
||||
if (tout)
|
||||
krb5_free_data(context, tout);
|
||||
return code;
|
||||
}
|
||||
#endif /* HAVE_KRB5_DECRYPT_TKT_PART && !HAVE_KRB5_C_DECRYPT */
|
||||
|
||||
static int
|
||||
rxkad_keytab_decrypt(int kvno, int et, void *in, size_t inlen,
|
||||
void *out, size_t *outlen)
|
||||
{
|
||||
krb5_error_code code;
|
||||
/* use heimdal api if available, since heimdal's interface to
|
||||
krb5_c_decrypt is non-standard and annoying to use */
|
||||
#ifdef HAVE_KRB5_CRYPTO_INIT
|
||||
krb5_crypto kcrypto;
|
||||
#else
|
||||
krb5_enc_data ind;
|
||||
#endif
|
||||
krb5_data outd;
|
||||
int i, foundkey;
|
||||
MUTEX_ENTER(&krb5_lock);
|
||||
reload_keys();
|
||||
if (have_keytab_keys == 0) {
|
||||
MUTEX_EXIT(&krb5_lock);
|
||||
return RXKADUNKNOWNKEY;
|
||||
}
|
||||
foundkey = 0;
|
||||
code = -1;
|
||||
for (i = 0; i < nkeys; i++) {
|
||||
/* foundkey determines what error code we return for failure */
|
||||
if (ktent[i].vno == kvno)
|
||||
foundkey = 1;
|
||||
/* but check against all keys if the enctype matches, for robustness */
|
||||
if (kb_enctype(kte_keyblock(ktent[i])) == et) {
|
||||
#ifdef HAVE_KRB5_CRYPTO_INIT
|
||||
code = krb5_crypto_init(k5ctx, kte_keyblock(ktent[i]), et,
|
||||
&kcrypto);
|
||||
if (code == 0) {
|
||||
code = krb5_decrypt(k5ctx, kcrypto,
|
||||
KRB5_KEYUSAGE_KDC_REP_TICKET, in, inlen,
|
||||
&outd);
|
||||
krb5_crypto_destroy(k5ctx, kcrypto);
|
||||
}
|
||||
if (code == 0) {
|
||||
if (outd.length > *outlen) {
|
||||
/* This should never happen, but don't assert since we may
|
||||
* be dealing with untrusted user data. */
|
||||
code = EINVAL;
|
||||
krb5_data_free(&outd);
|
||||
outd.data = NULL;
|
||||
}
|
||||
}
|
||||
if (code == 0) {
|
||||
/* heimdal allocates new memory for the decrypted data; put
|
||||
* the data back into the requested 'out' buffer */
|
||||
*outlen = outd.length;
|
||||
memcpy(out, outd.data, outd.length);
|
||||
krb5_data_free(&outd);
|
||||
break;
|
||||
}
|
||||
#else
|
||||
outd.length = *outlen;
|
||||
outd.data = out;
|
||||
ind.ciphertext.length = inlen;
|
||||
ind.ciphertext.data = in;
|
||||
ind.enctype = et;
|
||||
ind.kvno = kvno;
|
||||
code = krb5_c_decrypt(k5ctx, kte_keyblock(ktent[i]),
|
||||
KRB5_KEYUSAGE_KDC_REP_TICKET, NULL, &ind,
|
||||
&outd);
|
||||
if (code == 0) {
|
||||
*outlen = outd.length;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
MUTEX_EXIT(&krb5_lock);
|
||||
if (code == 0)
|
||||
return 0;
|
||||
if (foundkey != 0)
|
||||
return RXKADBADTICKET;
|
||||
return RXKADUNKNOWNKEY;
|
||||
}
|
||||
|
||||
#ifdef RX_ENABLE_LOCKS
|
||||
static void
|
||||
init_krb5_lock(void)
|
||||
{
|
||||
MUTEX_INIT(&krb5_lock, "krb5 api", MUTEX_DEFAULT, 0);
|
||||
}
|
||||
|
||||
static pthread_once_t rxkad_keytab_once_init = PTHREAD_ONCE_INIT;
|
||||
#define INIT_PTHREAD_LOCKS osi_Assert(pthread_once(&rxkad_keytab_once_init, init_krb5_lock)==0)
|
||||
#else
|
||||
#define INIT_PTHREAD_LOCKS
|
||||
#endif
|
||||
int
|
||||
rxkad_InitKeytabDecrypt(const char *ktname)
|
||||
{
|
||||
int code;
|
||||
static int keytab_init;
|
||||
INIT_PTHREAD_LOCKS;
|
||||
MUTEX_ENTER(&krb5_lock);
|
||||
if (keytab_init) {
|
||||
MUTEX_EXIT(&krb5_lock);
|
||||
return 0;
|
||||
}
|
||||
k5ctx = NULL;
|
||||
keytab_name = NULL;
|
||||
code = krb5_init_context(&k5ctx);
|
||||
if (code != 0)
|
||||
goto cleanup;
|
||||
if (ktname != NULL) {
|
||||
keytab_name = strdup(ktname);
|
||||
if (keytab_name == NULL) {
|
||||
code = KRB5_KT_BADNAME;
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
keytab_init=1;
|
||||
reload_keys();
|
||||
MUTEX_EXIT(&krb5_lock);
|
||||
return 0;
|
||||
cleanup:
|
||||
if (keytab_name != NULL) {
|
||||
free(keytab_name);
|
||||
}
|
||||
if (k5ctx != NULL) {
|
||||
krb5_free_context(k5ctx);
|
||||
}
|
||||
MUTEX_EXIT(&krb5_lock);
|
||||
return code;
|
||||
}
|
||||
|
||||
int
|
||||
rxkad_BindKeytabDecrypt(struct rx_securityClass *aclass)
|
||||
{
|
||||
return rxkad_SetAltDecryptProc(aclass, rxkad_keytab_decrypt);
|
||||
}
|
@ -49,7 +49,7 @@ all: scout
|
||||
scout.o: scout.c ${INCLS} AFS_component_version_number.c
|
||||
|
||||
scout: scout.o $(LIBS)
|
||||
${CC} ${LDFLAGS} -o scout scout.o $(LIBS) ${TXLIBS} ${TOP_LIBDIR}/libtermlib.a ${XLIBS}
|
||||
${CC} ${LDFLAGS} -o scout scout.o $(LIBS) ${TXLIBS} ${TOP_LIBDIR}/libtermlib.a ${XLIBS} ${KRB5_LIBS}
|
||||
|
||||
#
|
||||
# Installation targets
|
||||
|
@ -37,7 +37,7 @@ AUTHOBJS = \
|
||||
writeconfig.o \
|
||||
authcon.o \
|
||||
ktc_errors.o \
|
||||
acfg_errors.o
|
||||
acfg_errors.o @MAKE_KRB5@ akimpersonate.o akimpersonate_v5gen.o
|
||||
|
||||
KAUTHOBJS = \
|
||||
kauth.xdr.o \
|
||||
@ -68,7 +68,7 @@ UTILOBJS = \
|
||||
fileutil.o
|
||||
|
||||
RXKADOBJS = \
|
||||
rxkad_errs.o
|
||||
rxkad_errs.o @MAKE_KRB5@ ticket5_keytab.o
|
||||
|
||||
SYSOBJS = \
|
||||
rmtsysc.o \
|
||||
@ -150,7 +150,13 @@ writeconfig.o: ${AUTH}/writeconfig.c
|
||||
${CCRULE}
|
||||
|
||||
authcon.o: ${AUTH}/authcon.c
|
||||
${CCRULE}
|
||||
${CCRULE} @KRB5CFLAGS@
|
||||
|
||||
akimpersonate.o: ${AUTH}/akimpersonate.c
|
||||
${CCRULE} @KRB5CFLAGS@
|
||||
|
||||
akimpersonate_v5gen.o: ${AUTH}/akimpersonate_v5gen.c
|
||||
${CCRULE} @KRB5CFLAGS@ -I../rxkad
|
||||
|
||||
ktc_errors.o: ${AUTH}/ktc_errors.c
|
||||
${CCRULE}
|
||||
@ -227,6 +233,9 @@ pthread_glock.o: ${UTIL}/pthread_glock.c
|
||||
rxkad_errs.o: ${RXKAD}/rxkad_errs.c
|
||||
${CCRULE}
|
||||
|
||||
ticket5_keytab.o: ${RXKAD}/ticket5_keytab.c
|
||||
${CCRULE} @KRB5CFLAGS@
|
||||
|
||||
ptclient.o: ${PTSERVER}/ptclient.c
|
||||
${CCRULE}
|
||||
|
||||
|
@ -45,12 +45,14 @@
|
||||
rxkad_GetServerInfo;
|
||||
rxkad_NewClientSecurityObject;
|
||||
rxkad_NewServerSecurityObject;
|
||||
rxkad_SetAltDecryptProc;
|
||||
rxnull_NewClientSecurityObject;
|
||||
rxnull_NewServerSecurityObject;
|
||||
rxs_Release;
|
||||
time_to_life;
|
||||
tkt_CheckTimes;
|
||||
tkt_DecodeTicket;
|
||||
tkt_DeriveDesKey;
|
||||
tkt_MakeTicket;
|
||||
xdrrx_create;
|
||||
hton_syserr_conv;
|
||||
|
@ -66,7 +66,7 @@ BUTCLIBS=${TOP_LIBDIR}/libbudb.a \
|
||||
all: butc
|
||||
|
||||
butc: ${BUTCOBJS} ${BUTCLIBS}
|
||||
${CC} ${CFLAGS} ${BUTCOBJS} ${BUTCLIBS} ${MT_LIBS} ${XLIBS} -o butc
|
||||
${CC} ${CFLAGS} ${BUTCOBJS} ${BUTCLIBS} ${MT_LIBS} ${XLIBS} ${KRB5_LIBS} -o butc
|
||||
|
||||
libbutm.a: ${BUTMOBJS} AFS_component_version_number.o
|
||||
-$(RM) -f libbutm.a
|
||||
|
@ -72,13 +72,13 @@ clean:
|
||||
$(RM) -f *.o $(AUTHLIBS) $(AUTHFILES) so_locations
|
||||
|
||||
afs_dynamic_auth: ${AUTH_OBJS} ${AFSLIBS} ${AUTHFILES}
|
||||
$(LD) -o $@ ${AUTH_OBJS} $(AFSLIBS) ${AUTHFILES} ${XLIBS} ${LDFLAGS}
|
||||
$(LD) -o $@ ${AUTH_OBJS} $(AFSLIBS) ${AUTHFILES} @KRB5LIBS@ ${XLIBS} ${LDFLAGS}
|
||||
|
||||
aklog_dynamic_auth: ${AUTH_KRB5_OBJS} ${AFSLIBS} ${AUTHFILES}
|
||||
$(LD) -o $@ ${AUTH_KRB5_OBJS} $(AFSLIBS) ${AUTHFILES} @KRB5LIBS@ ${XLIBS} ${AKLDFLAGS}
|
||||
|
||||
afs_dynamic_kerbauth: ${AUTH_KRB_OBJS} ${KAFSLIBS} ${AUTHFILES}
|
||||
$(LD) -o $@ ${AUTH_KRB_OBJS} $(KAFSLIBS) ${AUTHFILES} ${XLIBS} ${LDFLAGS}
|
||||
$(LD) -o $@ ${AUTH_KRB_OBJS} $(KAFSLIBS) ${AUTHFILES} @KRB5LIBS@ ${XLIBS} ${LDFLAGS}
|
||||
|
||||
aix_auth_common.o: ${srcdir}/aix_auth_common.c
|
||||
${CCRULE}
|
||||
|
@ -186,7 +186,7 @@ afsint.xdr.o: ${FSINT}/afsint.xdr.c
|
||||
${CCRULE}
|
||||
|
||||
fileserver: ${objects} ${LIBS}
|
||||
${CC} ${LDFLAGS} -o fileserver ${objects} ${LIBS} ${MT_LIBS} ${XLIBS}
|
||||
${CC} ${LDFLAGS} -o fileserver ${objects} ${LIBS} ${MT_LIBS} ${XLIBS} ${KRB5_LIBS}
|
||||
|
||||
${DEST}/root.server/usr/afs/bin/fileserver: fileserver
|
||||
${INSTALL} -ns $? $@
|
||||
|
@ -189,7 +189,7 @@ afsint.xdr.o: ${FSINT}/afsint.xdr.c
|
||||
${COMPILE}
|
||||
|
||||
volserver: ${objects} ${LIBS}
|
||||
${CC} ${LDFLAGS} -o volserver ${objects} ${LIBS} ${MT_LIBS} ${XLIBS}
|
||||
${CC} ${LDFLAGS} -o volserver ${objects} ${LIBS} ${MT_LIBS} ${XLIBS} ${KRB5_LIBS}
|
||||
|
||||
${DEST}/root.server/usr/afs/bin/volserver: volserver
|
||||
${INSTALL} -ns $? $@
|
||||
|
@ -23,10 +23,10 @@ all: upserver upclient
|
||||
# Build targets
|
||||
#
|
||||
upclient: client.o update.cs.o utils.o ${LIBS}
|
||||
${CC} ${CFLAGS} -o upclient client.o update.cs.o utils.o ${LIBS} ${XLIBS}
|
||||
${CC} ${CFLAGS} -o upclient client.o update.cs.o utils.o ${LIBS} ${XLIBS} ${KRB5_LIBS}
|
||||
|
||||
upserver: server.o utils.o update.ss.o ${LIBS}
|
||||
${CC} ${CFLAGS} -o upserver server.o utils.o update.ss.o ${LIBS} ${XLIBS}
|
||||
${CC} ${CFLAGS} -o upserver server.o utils.o update.ss.o ${LIBS} ${XLIBS} ${KRB5_LIBS}
|
||||
|
||||
utils.o: utils.c update.h global.h
|
||||
|
||||
|
@ -314,7 +314,10 @@ main(int argc, char *argv[])
|
||||
rxkad_NewServerSecurityObject(rxkad_clear, cdir, afsconf_GetKey, 0);
|
||||
if (securityObjects[2] == (struct rx_securityClass *)0)
|
||||
Quit("rxkad_NewServerSecurityObject");
|
||||
|
||||
#ifdef USE_RXKAD_KEYTAB
|
||||
if (rxkad_InitKeytabDecrypt(AFSDIR_SERVER_RXKAD_KEYTAB_FILEPATH) == 0)
|
||||
rxkad_BindKeytabDecrypt(securityObjects[2]);
|
||||
#endif
|
||||
/* Instantiate a single UPDATE service. The rxgen-generated procedure
|
||||
* which is called to decode requests is passed in here
|
||||
* (UPDATE_ExecuteRequest). */
|
||||
|
@ -46,7 +46,7 @@ OBJS = uss_procs.o \
|
||||
y.tab.o
|
||||
|
||||
uss: uss.o ${OBJS}
|
||||
${CC} ${CFLAGS} -o uss uss.o ${OBJS} ${LIBS}
|
||||
${CC} ${CFLAGS} -o uss uss.o ${OBJS} ${LIBS} ${KRB5_LIBS}
|
||||
|
||||
uss.o: uss.c AFS_component_version_number.c
|
||||
${CC} -c ${CFLAGS} ${srcdir}/uss.c
|
||||
|
@ -366,6 +366,9 @@ initDirPathArray(void)
|
||||
pathp = dirPathArray[AFSDIR_SERVER_KRB_EXCL_FILEPATH_ID];
|
||||
AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_SERVER_ETC_DIR, AFSDIR_KRB_EXCL_FILE);
|
||||
|
||||
pathp = dirPathArray[AFSDIR_SERVER_RXKAD_KEYTAB_FILEPATH_ID];
|
||||
AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_SERVER_ETC_DIR, AFSDIR_RXKAD_KEYTAB_FILE);
|
||||
|
||||
/* client file paths */
|
||||
#ifdef AFS_NT40_ENV
|
||||
strcpy(dirPathArray[AFSDIR_CLIENT_THISCELL_FILEPATH_ID],
|
||||
|
@ -145,6 +145,7 @@ ConstructLocalLogPath(const char *cpath,
|
||||
#define AFSDIR_VOLSERLOG_FILE "VolserLog"
|
||||
#define AFSDIR_AUDIT_FILE "Audit"
|
||||
#define AFSDIR_KRB_EXCL_FILE "krb.excl"
|
||||
#define AFSDIR_RXKAD_KEYTAB_FILE "rxkad.keytab"
|
||||
|
||||
#define AFSDIR_ROOTVOL_FILE "RootVolume"
|
||||
#define AFSDIR_HOSTDUMP_FILE "hosts.dump"
|
||||
@ -264,6 +265,7 @@ typedef enum afsdir_id {
|
||||
AFSDIR_SERVER_BIN_FILE_DIRPATH_ID,
|
||||
AFSDIR_CLIENT_CELLALIAS_FILEPATH_ID,
|
||||
AFSDIR_SERVER_KRB_EXCL_FILEPATH_ID,
|
||||
AFSDIR_SERVER_RXKAD_KEYTAB_FILEPATH_ID,
|
||||
AFSDIR_PATHSTRING_MAX } afsdir_id_t;
|
||||
|
||||
/* getDirPath() returns a pointer to a string from an internal array of path strings
|
||||
@ -332,6 +334,7 @@ const char *getDirPath(afsdir_id_t string_id);
|
||||
#define AFSDIR_SERVER_THRESHOLD_CONSTANTS_FILEPATH getDirPath(AFSDIR_SERVER_THRESHOLD_CONSTANTS_FILEPATH_ID)
|
||||
#define AFSDIR_SERVER_MIGRATELOG_FILEPATH getDirPath(AFSDIR_SERVER_MIGRATELOG_FILEPATH_ID)
|
||||
#define AFSDIR_SERVER_KRB_EXCL_FILEPATH getDirPath(AFSDIR_SERVER_KRB_EXCL_FILEPATH_ID)
|
||||
#define AFSDIR_SERVER_RXKAD_KEYTAB_FILEPATH getDirPath(AFSDIR_SERVER_RXKAD_KEYTAB_FILEPATH_ID)
|
||||
|
||||
/* client file paths */
|
||||
#define AFSDIR_CLIENT_THISCELL_FILEPATH getDirPath(AFSDIR_CLIENT_THISCELL_FILEPATH_ID)
|
||||
|
@ -47,7 +47,7 @@ all: fs up fstrace cmdebug livesys kdump-build
|
||||
# Build targets
|
||||
#
|
||||
cacheout: cacheout.o
|
||||
$(CC) ${CFLAGS} -o cacheout cacheout.o ${LIBS} ${XLIBS} ${CMLIBS}
|
||||
$(CC) ${CFLAGS} -o cacheout cacheout.o ${LIBS} ${XLIBS} ${CMLIBS} ${KRB5_LIBS}
|
||||
|
||||
cacheout.o: cacheout.c
|
||||
|
||||
@ -76,15 +76,15 @@ up: up.o
|
||||
fs.o: fs.c ${INCLS} AFS_component_version_number.c
|
||||
|
||||
fs: fs.o $(LIBS)
|
||||
${CC} ${CFLAGS} -o fs fs.o ${TOP_LIBDIR}/libprot.a $(LIBS) ${XLIBS}
|
||||
${CC} ${CFLAGS} -o fs fs.o ${TOP_LIBDIR}/libprot.a $(LIBS) ${XLIBS} ${KRB5_LIBS}
|
||||
|
||||
livesys.o: livesys.c ${INCLS} AFS_component_version_number.c
|
||||
|
||||
livesys: livesys.c $(LIBS)
|
||||
${CC} ${CFLAGS} -o livesys ${srcdir}/livesys.c $(LIBS) ${XLIBS}
|
||||
${CC} ${CFLAGS} -o livesys ${srcdir}/livesys.c $(LIBS) ${XLIBS} ${KRB5_LIBS}
|
||||
|
||||
twiddle: twiddle.c $(LIBS)
|
||||
${CC} ${CFLAGS} -o twiddle ${srcdir}/twiddle.c $(LIBS) ${XLIBS}
|
||||
${CC} ${CFLAGS} -o twiddle ${srcdir}/twiddle.c $(LIBS) ${XLIBS} ${KRB5_LIBS}
|
||||
|
||||
gcpags: gcpags.c $(LIBS)
|
||||
${CC} ${CFLAGS} -o gcpags ${srcdir}/gcpags.c $(LIBS) ${XLIBS}
|
||||
@ -92,7 +92,7 @@ gcpags: gcpags.c $(LIBS)
|
||||
whatfid.o: whatfid.c ${INCLS} AFS_component_version_number.c
|
||||
|
||||
whatfid: whatfid.o ${LIBS}
|
||||
${CC} ${CFLAGS} -o whatfid whatfid.o ${LIBS} ${XLIBS}
|
||||
${CC} ${CFLAGS} -o whatfid whatfid.o ${LIBS} ${XLIBS} ${KRB5_LIBS}
|
||||
|
||||
fstrace.o: fstrace.c AFS_component_version_number.c
|
||||
case ${SYS_NAME} in \
|
||||
@ -121,8 +121,7 @@ fstrace: fstrace.o
|
||||
cmdebug.o: cmdebug.c ${INCLS} AFS_component_version_number.c
|
||||
|
||||
cmdebug: cmdebug.o ${CMLIBS}
|
||||
$(CC) -o cmdebug cmdebug.o ${CFLAGS} ${CMLIBS} ${XLIBS}
|
||||
|
||||
$(CC) -o cmdebug cmdebug.o ${CFLAGS} ${CMLIBS} ${XLIBS} ${KRB5_LIBS}
|
||||
|
||||
|
||||
#
|
||||
|
@ -561,7 +561,7 @@ EmptyAcl(char *astr)
|
||||
tp->nplus = tp->nminus = 0;
|
||||
tp->pluslist = tp->minuslist = 0;
|
||||
tp->dfs = 0;
|
||||
sscanf(astr, "%d dfs:%d %s", &junk, &tp->dfs, tp->cell);
|
||||
sscanf(astr, "%d dfs:%d %1024s", &junk, &tp->dfs, tp->cell);
|
||||
return tp;
|
||||
}
|
||||
|
||||
@ -576,7 +576,7 @@ ParseAcl(char *astr)
|
||||
ta = (struct Acl *)malloc(sizeof(struct Acl));
|
||||
assert(ta);
|
||||
ta->dfs = 0;
|
||||
sscanf(astr, "%d dfs:%d %s", &ta->nplus, &ta->dfs, ta->cell);
|
||||
sscanf(astr, "%d dfs:%d %1024s", &ta->nplus, &ta->dfs, ta->cell);
|
||||
astr = SkipLine(astr);
|
||||
sscanf(astr, "%d", &ta->nminus);
|
||||
astr = SkipLine(astr);
|
||||
@ -587,7 +587,7 @@ ParseAcl(char *astr)
|
||||
last = 0;
|
||||
first = 0;
|
||||
for (i = 0; i < nplus; i++) {
|
||||
sscanf(astr, "%100s %d", tname, &trights);
|
||||
sscanf(astr, "%99s %d", tname, &trights);
|
||||
astr = SkipLine(astr);
|
||||
tl = (struct AclEntry *)malloc(sizeof(struct AclEntry));
|
||||
assert(tl);
|
||||
@ -605,7 +605,7 @@ ParseAcl(char *astr)
|
||||
last = 0;
|
||||
first = 0;
|
||||
for (i = 0; i < nminus; i++) {
|
||||
sscanf(astr, "%100s %d", tname, &trights);
|
||||
sscanf(astr, "%99s %d", tname, &trights);
|
||||
astr = SkipLine(astr);
|
||||
tl = (struct AclEntry *)malloc(sizeof(struct AclEntry));
|
||||
assert(tl);
|
||||
|
@ -72,23 +72,23 @@ fileserver: ${objects} ${headers} ${LIBS}
|
||||
case ${SYS_NAME} in \
|
||||
rs_aix*) \
|
||||
${CC} -K ${LDFLAGS} -o fileserver ${objects} \
|
||||
${TOP_LIBDIR}/libaudit.a ${LIBS} ${XLIBS} ;; \
|
||||
${TOP_LIBDIR}/libaudit.a ${LIBS} ${XLIBS} ${KRB5_LIBS} ;; \
|
||||
*) \
|
||||
${CC} ${LDFLAGS} -o fileserver ${objects} \
|
||||
${TOP_LIBDIR}/libaudit.a ${LIBS} ${XLIBS} ;; \
|
||||
${TOP_LIBDIR}/libaudit.a ${LIBS} ${XLIBS} ${KRB5_LIBS} ;; \
|
||||
esac
|
||||
|
||||
fsprobe.o: fsprobe.c AFS_component_version_number.c
|
||||
${CC} ${CFLAGS} -DINTERPRET_DUMP -c ${srcdir}/fsprobe.c
|
||||
|
||||
fsprobe: fsprobe.o
|
||||
${CC} ${CFLAGS} -o fsprobe fsprobe.o ${LIBS} ${XLIBS}
|
||||
${CC} ${CFLAGS} -o fsprobe fsprobe.o ${LIBS} ${XLIBS} ${KRB5_LIBS}
|
||||
|
||||
cbd.o: callback.c AFS_component_version_number.c
|
||||
${CC} ${CFLAGS} -DINTERPRET_DUMP -c -o cbd.o ${srcdir}/callback.c
|
||||
|
||||
cbd: cbd.o
|
||||
${CC} ${CFLAGS} -DINTERPRET_DUMP -o cbd cbd.o ${LIBS} ${XLIBS}
|
||||
${CC} ${CFLAGS} -DINTERPRET_DUMP -o cbd cbd.o ${LIBS} ${XLIBS} ${KRB5_LIBS}
|
||||
|
||||
${DEST}/root.server/usr/afs/bin/fileserver: fileserver
|
||||
@case ${SYS_NAME} in \
|
||||
|
@ -1884,6 +1884,12 @@ main(int argc, char *argv[])
|
||||
sc[1] = 0; /* rxvab_NewServerSecurityObject(key1, 0) */
|
||||
sc[2] = rxkad_NewServerSecurityObject(rxkad_clear, NULL, get_key, NULL);
|
||||
sc[3] = rxkad_NewServerSecurityObject(rxkad_crypt, NULL, get_key, NULL);
|
||||
#ifdef USE_RXKAD_KEYTAB
|
||||
if (rxkad_InitKeytabDecrypt(AFSDIR_SERVER_RXKAD_KEYTAB_FILEPATH) == 0) {
|
||||
rxkad_BindKeytabDecrypt(sc[2]);
|
||||
rxkad_BindKeytabDecrypt(sc[3]);
|
||||
}
|
||||
#endif
|
||||
tservice = rx_NewServiceHost(rx_bindhost, /* port */ 0, /* service id */
|
||||
1, /*service name */
|
||||
"AFS",
|
||||
|
@ -46,23 +46,23 @@ depinstall: \
|
||||
${TOP_INCDIR}/afs/cnvldb.h
|
||||
|
||||
vldb_check: vldb_check.o ${LIBS}
|
||||
$(CC) ${CFLAGS} -o vldb_check vldb_check.o ${LIBS} ${XLIBS}
|
||||
$(CC) ${CFLAGS} -o vldb_check vldb_check.o ${LIBS} ${XLIBS} ${KRB5_LIBS}
|
||||
|
||||
vldb_check.o: vldb_check.c AFS_component_version_number.o
|
||||
|
||||
cnvldb: cnvldb.o ${LIBS}
|
||||
$(CC) ${CFLAGS} -o cnvldb cnvldb.o ${LIBS} ${XLIBS}
|
||||
$(CC) ${CFLAGS} -o cnvldb cnvldb.o ${LIBS} ${XLIBS} ${KRB5_LIBS}
|
||||
|
||||
cnvldb.o: cnvldb.c cnvldb.h AFS_component_version_number.o
|
||||
|
||||
sascnvldb: sascnvldb.o ${LIBS}
|
||||
$(CC) ${CFLAGS} -o sascnvldb sascnvldb.o ${LIBS} ${XLIBS}
|
||||
$(CC) ${CFLAGS} -o sascnvldb sascnvldb.o ${LIBS} ${XLIBS} ${KRB5_LIBS}
|
||||
|
||||
sascnvldb.o: sascnvldb.c cnvldb.h AFS_component_version_number.o
|
||||
|
||||
vlserver: vlserver.o vlutils.o vlprocs.o vldbint.ss.o vldbint.xdr.o $(LIBS)
|
||||
$(CC) ${CFLAGS} -o vlserver vlserver.o vlutils.o vlprocs.o vldbint.ss.o \
|
||||
vldbint.xdr.o $(LIBS) ${XLIBS} ${TOP_LIBDIR}/libaudit.a
|
||||
vldbint.xdr.o $(LIBS) ${XLIBS} ${TOP_LIBDIR}/libaudit.a ${KRB5_LIBS}
|
||||
|
||||
vlserver.o: vlserver.c ${INCLS} AFS_component_version_number.o
|
||||
vlutils.o: vlutils.c ${INCLS}
|
||||
@ -99,7 +99,7 @@ libvldb.a: $(OBJS) AFS_component_version_number.o
|
||||
$(RANLIB) $@
|
||||
|
||||
vlclient: vlclient.o libvldb.a $(LIBS)
|
||||
$(CC) ${CFLAGS} -o vlclient vlclient.o libvldb.a $(LIBS) ${XLIBS} ${TOP_LIBDIR}/libcmd.a
|
||||
$(CC) ${CFLAGS} -o vlclient vlclient.o libvldb.a $(LIBS) ${XLIBS} ${TOP_LIBDIR}/libcmd.a ${KRB5_LIBS}
|
||||
|
||||
vlclient.o: vlclient.c ${INCLS} AFS_component_version_number.o
|
||||
|
||||
|
@ -355,7 +355,10 @@ main(argc, argv)
|
||||
sc[0] = rxnull_NewServerSecurityObject();
|
||||
sc[1] = (struct rx_securityClass *)0;
|
||||
sc[2] = rxkad_NewServerSecurityObject(0, tdir, afsconf_GetKey, NULL);
|
||||
|
||||
#ifdef USE_RXKAD_KEYTAB
|
||||
if (rxkad_InitKeytabDecrypt(AFSDIR_SERVER_RXKAD_KEYTAB_FILEPATH) == 0)
|
||||
rxkad_BindKeytabDecrypt(sc[2]);
|
||||
#endif
|
||||
tservice =
|
||||
rx_NewServiceHost(host, 0, USER_SERVICE_ID, "Vldb server", sc, 3,
|
||||
VL_ExecuteRequest);
|
||||
|
@ -65,11 +65,11 @@ restorevol: restorevol.c
|
||||
${TOP_LIBDIR}/libcmd.a ${TOP_LIBDIR}/util.a ${XLIBS}
|
||||
|
||||
vos: vos.o ${VSOBJS} libvolser.a ${LIBS}
|
||||
${CC} ${LDFLAGS} -o vos vos.o $(VSOBJS) libvolser.a ${LIBS} ${XLIBS}
|
||||
${CC} ${LDFLAGS} -o vos vos.o $(VSOBJS) libvolser.a ${LIBS} ${XLIBS} ${KRB5_LIBS}
|
||||
|
||||
volserver: $(SOBJS) $(LIBS) ${TOP_LIBDIR}/libdir.a
|
||||
${CC} ${DBG} -o volserver $(SOBJS) ${TOP_LIBDIR}/libdir.a \
|
||||
${LDFLAGS} $(LIBS) ${XLIBS}
|
||||
${LDFLAGS} $(LIBS) ${XLIBS} ${KRB5_LIBS}
|
||||
|
||||
voldump: vol-dump.o ${VOLDUMP_LIBS}
|
||||
${CC} ${CFLAGS} -o voldump vol-dump.o ${VOLDUMP_LIBS} ${XLIBS}
|
||||
|
@ -494,6 +494,10 @@ main(int argc, char **argv)
|
||||
rxkad_NewServerSecurityObject(0, tdir, afsconf_GetKey, NULL);
|
||||
if (securityObjects[0] == (struct rx_securityClass *)0)
|
||||
Abort("rxnull_NewServerSecurityObject");
|
||||
#ifdef USE_RXKAD_KEYTAB
|
||||
if (securityObjects[2] != NULL && rxkad_InitKeytabDecrypt(AFSDIR_SERVER_RXKAD_KEYTAB_FILEPATH) == 0)
|
||||
rxkad_BindKeytabDecrypt(securityObjects[2]);
|
||||
#endif
|
||||
service =
|
||||
rx_NewServiceHost(host, 0, VOLSERVICE_ID, "VOLSER", securityObjects, 3,
|
||||
AFSVolExecuteRequest);
|
||||
|
Loading…
Reference in New Issue
Block a user