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:
Simon Wilkinson 2013-07-24 16:27:20 +01:00
commit 30922c5d91
54 changed files with 1884 additions and 622 deletions

View File

@ -1,8 +1,8 @@
AC_INIT(src/libafs/Makefile.common.in) 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) AC_CONFIG_HEADER(src/config/afsconfig.h)
MACOS_VERSION=1.4.12 MACOS_VERSION=1.4.15
LINUX_PKGVER=1.4.12 LINUX_PKGVER=1.4.15
LINUX_PKGREL=1.1 LINUX_PKGREL=1.1
#LINUX_PKGREL=0.pre4 #LINUX_PKGREL=0.pre4

View File

@ -1,8 +1,8 @@
AC_INIT(src/config/stds.h) 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) AC_CONFIG_HEADER(src/config/afsconfig.h)
MACOS_VERSION=1.4.12 MACOS_VERSION=1.4.15
LINUX_PKGVER=1.4.12 LINUX_PKGVER=1.4.15
LINUX_PKGREL=1.1 LINUX_PKGREL=1.1
#LINUX_PKGREL=0.pre3 #LINUX_PKGREL=0.pre3

View File

@ -73,6 +73,7 @@
#ifdef AFS_SUN5_ENV #ifdef AFS_SUN5_ENV
#include <sys/ioccom.h> #include <sys/ioccom.h>
#endif #endif
#include <afs/akimpersonate.h>
#include <afs/auth.h> #include <afs/auth.h>
#include <afs/cellconfig.h> #include <afs/cellconfig.h>
#include <afs/vice.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" #error "Must have either krb5_princ_size or krb5_principal_get_comp_string"
#endif #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) #if !defined(HAVE_KRB5_524_CONVERT_CREDS) && defined(HAVE_KRB524_CONVERT_CREDS_KDC)
#define krb5_524_convert_creds 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) #elif !defined(HAVE_KRB5_524_CONVERT_CREDS) && !defined(HAVE_KRB524_CONVERT_CREDS_KDC)
#define HAVE_NO_KRB5_524 #define HAVE_NO_KRB5_524
#endif #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 * 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 *p;
char k4name[ANAME_SZ], k4inst[INST_SZ], k4realm[REALM_SZ]; char k4name[ANAME_SZ], k4inst[INST_SZ], k4realm[REALM_SZ];
int len; int len;
void *inkey = get_cred_keydata(v5cred);
size_t inkey_sz = get_cred_keylen(v5cred);
if (dflag) if (dflag)
printf("Using Kerberos V5 ticket natively\n"); 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.kvno = RXKAD_TKT_TYPE_KERBEROS_V5;
atoken.startTime = v5cred->times.starttime;; atoken.startTime = v5cred->times.starttime;;
atoken.endTime = v5cred->times.endtime; atoken.endTime = v5cred->times.endtime;
memcpy(&atoken.sessionKey, get_cred_keydata(v5cred), if (tkt_DeriveDesKey(get_creds_enctype(v5cred), inkey, inkey_sz,
get_cred_keylen(v5cred)); &atoken.sessionKey) != 0)
return RXKADBADKEY;
atoken.ticketLen = v5cred->ticket.length; atoken.ticketLen = v5cred->ticket.length;
memcpy(atoken.ticket, v5cred->ticket.data, atoken.ticketLen); memcpy(atoken.ticket, v5cred->ticket.data, atoken.ticketLen);
#ifndef HAVE_NO_KRB5_524 #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, static krb5_error_code get_credv5(krb5_context context,
char *name, char *inst, char *realm, char *name, char *inst, char *realm,
krb5_creds **creds) krb5_creds **creds)
@ -1911,21 +1498,17 @@ static krb5_error_code get_credv5(krb5_context context,
increds.client = client_principal; increds.client = client_principal;
increds.times.endtime = 0; increds.times.endtime = 0;
/* Ask for DES since that is what V4 understands */ if (do524)
get_creds_enctype((&increds)) = ENCTYPE_DES_CBC_CRC; /* Ask for DES since that is what V4 understands */
get_creds_enctype((&increds)) = ENCTYPE_DES_CBC_CRC;
if (keytab) { if (keytab) {
int allowed_enctypes[] = {
ENCTYPE_DES_CBC_CRC, 0
};
r = get_credv5_akimpersonate(context, r = get_credv5_akimpersonate(context,
keytab, keytab,
increds.server, increds.server,
increds.client, increds.client,
300, ((~0U)>>1), 0, 0x7fffffff,
allowed_enctypes, NULL,
0 /* paddress */,
creds /* out */); creds /* out */);
} else { } else {
r = krb5_get_credentials(context, 0, _krb425_ccache, &increds, creds); r = krb5_get_credentials(context, 0, _krb425_ccache, &increds, creds);

View File

@ -701,8 +701,15 @@ CommandProc(struct cmd_syndesc *as, char *arock)
} }
atoken->startTime = afscred->times.starttime; atoken->startTime = afscred->times.starttime;
atoken->endTime = afscred->times.endtime; atoken->endTime = afscred->times.endtime;
memcpy(&atoken->sessionKey, get_cred_keydata(afscred), if (tkt_DeriveDesKey(get_creds_enctype(afscred),
get_cred_keylen(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, memcpy(atoken->ticket, enc_part->data,
atoken->ticketLen = enc_part->length); atoken->ticketLen = enc_part->length);
memset(aserver, 0, sizeof *aserver); memset(aserver, 0, sizeof *aserver);

View File

@ -9,15 +9,15 @@ srcdir=@srcdir@
include @TOP_OBJDIR@/src/config/Makefile.config include @TOP_OBJDIR@/src/config/Makefile.config
OBJS= cellconfig.o ktc.o userok.o writeconfig.o authcon.o \ 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 \ 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 \ LIBS=libauth.a \
${TOP_LIBDIR}/librxkad.a ${TOP_LIBDIR}/libdes.a \ ${TOP_LIBDIR}/librxkad.a ${TOP_LIBDIR}/libdes.a \
${TOP_LIBDIR}/librx.a ${TOP_LIBDIR}/libsys.a \ ${TOP_LIBDIR}/librx.a ${TOP_LIBDIR}/libsys.a \
${TOP_LIBDIR}/liblwp.a ${TOP_LIBDIR}/util.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 KSRCS=auth.h
UKSRCS=${KSRCS} cellconfig.h acfg_errors.c keys.h cellconfig.c \ UKSRCS=${KSRCS} cellconfig.h acfg_errors.c keys.h cellconfig.c \
ktc.c authcon.c ktc_errors.c ktc.c authcon.c ktc_errors.c
@ -30,13 +30,23 @@ all: \
depinstall: \ depinstall: \
${TOP_INCDIR}/afs/keys.h \ ${TOP_INCDIR}/afs/keys.h \
${TOP_INCDIR}/afs/cellconfig.h \ ${TOP_INCDIR}/afs/cellconfig.h \
${TOP_INCDIR}/afs/akimpersonate.h \
${TOP_INCDIR}/afs/auth.h \ ${TOP_INCDIR}/afs/auth.h \
${TOP_INCDIR}/afs/ktc.h ${TOP_INCDIR}/afs/ktc.h
cellconfig.o: cellconfig.c ${INCLS} cellconfig.o: cellconfig.c ${INCLS}
ktc.o: ktc.c ${INCLS} ${TOP_INCDIR}/afs/vice.h ktc.o: ktc.c ${INCLS} ${TOP_INCDIR}/afs/vice.h
writeconfig.o: writeconfig.c ${INCLS} writeconfig.o: writeconfig.c ${INCLS}
authcon.o: authcon.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} userok.o: userok.c ${INCLS}
cellconfig.o: cellconfig.c ${INCLS} cellconfig.o: cellconfig.c ${INCLS}
copyauth.o: copyauth.c ${INCLS} AFS_component_version_number.o 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 ${DEST}/include/afs/cellconfig.h: cellconfig.h
${INSTALL} $? $@ ${INSTALL} $? $@
${TOP_INCDIR}/afs/akimpersonate.h: akimpersonate.h
${INSTALL} $? $@
${DESTDIR}${includedir}/afs/auth.h: auth.h ${DESTDIR}${includedir}/afs/auth.h: auth.h
${INSTALL} $? $@ ${INSTALL} $? $@

766
src/auth/akimpersonate.c Normal file
View 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
View 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

View 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

View 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

View File

@ -45,10 +45,18 @@
#include <des.h> #include <des.h>
#include <des_prototypes.h> #include <des_prototypes.h>
#include <rx/rxkad.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 <rx/rx.h>
#include <errno.h>
#include "cellconfig.h" #include "cellconfig.h"
#include "keys.h" #include "keys.h"
#include "auth.h" #include "auth.h"
#if defined(USE_RXKAD_KEYTAB) && !defined(UKERNEL)
#include "akimpersonate.h"
#endif
#endif /* defined(UKERNEL) */ #endif /* defined(UKERNEL) */
/* return a null security object if nothing else can be done */ /* 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; 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; LOCK_GLOBAL_MUTEX;
tclass = (struct rx_securityClass *) tclass = (struct rx_securityClass *)
rxkad_NewServerSecurityObject(0, adir, afsconf_GetKey, NULL); rxkad_NewServerSecurityObject(0, adir, afsconf_GetKey, NULL);
if (tclass) { if (tclass) {
*astr = tclass; *astr = tclass;
*aindex = 2; /* kerberos security index */ *aindex = 2; /* kerberos security index */
#ifdef USE_RXKAD_KEYTAB
if (keytab_enable)
rxkad_BindKeytabDecrypt(tclass);
#endif
UNLOCK_GLOBAL_MUTEX; UNLOCK_GLOBAL_MUTEX;
return 0; return 0;
} else { } else {
@ -86,6 +112,77 @@ afsconf_ServerAuth(register struct afsconf_dir *adir,
} }
#endif /* !defined(UKERNEL) */ #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 static afs_int32
GenericAuth(struct afsconf_dir *adir, GenericAuth(struct afsconf_dir *adir,
struct rx_securityClass **astr, struct rx_securityClass **astr,
@ -99,6 +196,13 @@ GenericAuth(struct afsconf_dir *adir,
afs_int32 ticketLen; afs_int32 ticketLen;
register afs_int32 code; 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 */ /* first, find the right key and kvno to use */
code = afsconf_GetLatestKey(adir, &kvno, &key); code = afsconf_GetLatestKey(adir, &kvno, &key);
if (code) { if (code) {

View File

@ -78,12 +78,12 @@ bosoprocs.o: bosoprocs.c ${INCLS}
bos.o: bos.c ${INCLS} AFS_component_version_number.o bos.o: bos.c ${INCLS} AFS_component_version_number.o
bos: bos.o $(LIBS) libbos.a 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.o: bos_util.c ${INCLS} AFS_component_version_number.o
bos_util: bos_util.o $(LIBS) 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} 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) $@ $(RANLIB) $@
bosserver: $(OBJS) $(LIBS) 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 # Install targets

View File

@ -1028,6 +1028,10 @@ main(int argc, char **argv, char **envp)
bozo_rxsc[1] = (struct rx_securityClass *)0; bozo_rxsc[1] = (struct rx_securityClass *)0;
bozo_rxsc[2] = bozo_rxsc[2] =
rxkad_NewServerSecurityObject(0, tdir, afsconf_GetKey, NULL); 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 */ /* Disable jumbograms */
rx_SetNoJumbo(); rx_SetNoJumbo();

View File

@ -52,7 +52,7 @@ main.o: AFS_component_version_number.c
$(BACKOBJS): bc.h ${TOP_INCDIR}/afs/butc.h $(BACKOBJS): bc.h ${TOP_INCDIR}/afs/butc.h
backup: $(BACKOBJS) ${LIBS} 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 bucoord_errs.c bc.h: bucoord_errs.et bc.p.h
$(RM) -f bc.h bucoord_errs.c $(RM) -f bc.h bucoord_errs.c

View File

@ -71,7 +71,7 @@ struct_ops.o: budb_errs.h
server.o: server.c budb_errs.h ${INCLS} AFS_component_version_number.c server.o: server.c budb_errs.h ${INCLS} AFS_component_version_number.c
budb_server: $(SERVER_OBJS) ${LIBS} 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 budb.cs.c: budb.rg
${RXGEN} -A -u -C -o $@ ${srcdir}/budb.rg ${RXGEN} -A -u -C -o $@ ${srcdir}/budb.rg

View File

@ -524,6 +524,10 @@ main(argc, argv)
sca[RX_SCINDEX_KAD] = sca[RX_SCINDEX_KAD] =
rxkad_NewServerSecurityObject(rxkad_clear, BU_conf, afsconf_GetKey, rxkad_NewServerSecurityObject(rxkad_clear, BU_conf, afsconf_GetKey,
NULL); NULL);
#ifdef USE_RXKAD_KEYTAB
if (rxkad_InitKeytabDecrypt(AFSDIR_SERVER_RXKAD_KEYTAB_FILEPATH) == 0)
rxkad_BindKeytabDecrypt(sca[RX_SCINDEX_KAD]);
#endif
/* Disable jumbograms */ /* Disable jumbograms */
rx_SetNoJumbo(); rx_SetNoJumbo();

View File

@ -52,15 +52,15 @@ SOBJS=dbentries.o tcprocs.o lwps.o tcmain.o list.o recoverDb.o tcudbprocs.o \
all: butc read_tape all: butc read_tape
butc_test: ${TESTOBJS} ${LIBS} ${INCLS} ${HACKS} 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 tdump: tdump.c AFS_component_version_number.c
${CC} ${CFLAGS} ${srcdir}/tdump.c -o tdump ${CC} ${CFLAGS} ${srcdir}/tdump.c -o tdump
butc: ${SOBJS} ${LIBS} ${INCLS} ${HACKS} butc: ${SOBJS} ${LIBS} ${INCLS} ${HACKS}
@case ${SYS_NAME} in \ @case ${SYS_NAME} in \
rs_aix*) ${CC} ${CFLAGS} ${SOBJS} ${LIBS} ${XLIBS} /usr/lib/libc_r.a -o butc;; \ rs_aix*) ${CC} ${CFLAGS} ${SOBJS} ${LIBS} ${XLIBS} ${KRB5_LIBS} /usr/lib/libc_r.a -o butc;; \
*) ${CC} ${CFLAGS} ${SOBJS} ${LIBS} ${XLIBS} -o butc;; \ *) ${CC} ${CFLAGS} ${SOBJS} ${LIBS} ${XLIBS} ${KRB5_LIBS} -o butc;; \
esac esac
tcmain.o: tcmain.c ${INCLS} AFS_component_version_number.c tcmain.o: tcmain.c ${INCLS} AFS_component_version_number.c

View File

@ -56,11 +56,13 @@ if test X$conf_krb5 = XYES; then
AC_MSG_RESULT([Configuring support for Kerberos 5 utilities]) AC_MSG_RESULT([Configuring support for Kerberos 5 utilities])
BUILD_KRB5=yes BUILD_KRB5=yes
MAKE_KRB5= MAKE_KRB5=
AC_DEFINE([USE_RXKAD_KEYTAB], 1,
[Define to 1 if krb5 libraries are available and rxkad can use keytabs])
save_CPPFLAGS="$CPPFLAGS" save_CPPFLAGS="$CPPFLAGS"
CPPFLAGS="$CPPFLAGS $KRB5CFLAGS" CPPFLAGS="$CPPFLAGS $KRB5CFLAGS"
save_LIBS="$LIBS" save_LIBS="$LIBS"
LIBS="$LIBS $KRB5LIBS" 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([krb5_524_convert_creds], ,
[AC_CHECK_FUNCS([krb524_convert_creds_kdc], , [AC_CHECK_FUNCS([krb524_convert_creds_kdc], ,
[AC_CHECK_LIB([krb524], [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([kerberosIV/krb.h])
AC_CHECK_HEADERS([kerberosV/heim_err.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_CHECK_MEMBERS([krb5_creds.keyblock, krb5_creds.keyblock.enctype,
AC_CACHE_VAL(ac_cv_krb5_prompt_type_exists, krb5_creds.session, krb5_keytab_entry.key,
[ krb5_keytab_entry.keyblock, krb5_keyblock.enctype,
AC_TRY_COMPILE( krb5_keyblock.keytype, krb5_prompt.type], , ,
[#include <krb5.h>], [#include <krb5.h>])
[krb5_prompt _p; AC_CHECK_DECLS([krb5_free_keytab_entry_contents, krb5_kt_free_entry,
printf("%x\n", _p.type);], KRB5_KU_TICKET], [], [], [#include <krb5.h>])
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>])
CPPFLAGS="$save_CPPFLAGS" CPPFLAGS="$save_CPPFLAGS"
LIBS="$save_LIBS" LIBS="$save_LIBS"
fi fi
if test "x$ac_cv_krb5_cc_register_exists" = "xyes"; then if test "x$ac_cv_krb5_cc_register_exists" = "xyes"; then
AC_DEFINE(HAVE_KRB5_CC_REGISTER, 1, [define if krb5_cc_register exists]) AC_DEFINE(HAVE_KRB5_CC_REGISTER, 1, [define if krb5_cc_register exists])
fi fi

View File

@ -43,6 +43,7 @@ DEST = @DEST@
FSINCLUDES = @FSINCLUDES@ FSINCLUDES = @FSINCLUDES@
KERN_DBG = @KERN_DBG@ KERN_DBG = @KERN_DBG@
KERN_OPTMZ = @KERN_OPTMZ@ KERN_OPTMZ = @KERN_OPTMZ@
KRB5_LIBS = @KRB5LIBS@
LD = @LD@ LD = @LD@
LEX = @LEX@ LEX = @LEX@
LIB_AFSDB = @LIB_AFSDB@ LIB_AFSDB = @LIB_AFSDB@

View File

@ -41,7 +41,7 @@ fsprobe_callback.o: fsprobe_callback.c ${INCLS}
fsprobe_test: fsprobe_test.o libfsprobe.a ${LIBS} fsprobe_test: fsprobe_test.o libfsprobe.a ${LIBS}
${CC} ${CFLAGS} -o fsprobe_test fsprobe_test.o libfsprobe.a \ ${CC} ${CFLAGS} -o fsprobe_test fsprobe_test.o libfsprobe.a \
${LIBS} ${XLIBS} ${LIBS} ${XLIBS} ${KRB5_LIBS}
# #
# Install targets # Install targets

View File

@ -67,7 +67,7 @@ test tests: all
cd test; $(MAKE) 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) 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 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 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 \ ${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: AFS_component_version_number.o kauth.h kautils.h libkauth.a $(LIBS) \
klog.o 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.o: klog.c kauth.h kautils.h AFS_component_version_number.o
klog.krb: kauth.h kautils.h libkauth.krb.a $(KLIBS) klog.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 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 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 ${CC} ${CFLAGS} -c ${srcdir}/klogin.c -DKAUTH
klogin: libkauth.a $(LIBS) klogin.o 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 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 kpasswd.o: kauth.h kautils.h ${INCLS} kpasswd.c AFS_component_version_number.o
${CC} ${CFLAGS} -c ${srcdir}/kpasswd.c ${CC} ${CFLAGS} -c ${srcdir}/kpasswd.c
kpasswd: kauth.h kautils.h libkauth.a $(LIBS) kpasswd.o kkids.o 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 kpwvalid.o: kpwvalid.c AFS_component_version_number.o
${CC} ${CFLAGS} -c ${srcdir}/kpwvalid.c ${CC} ${CFLAGS} -c ${srcdir}/kpwvalid.c
kpwvalid: kpwvalid.o $(LIBS) 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 user.krb.o: user.c ${INCLS} ${TOP_INCDIR}/afs/vice.h
${CCOBJ} ${CFLAGS} -DAFS_KERBEROS_ENV -c ${srcdir}/user.c -o user.krb.o ${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 ${CCOBJ} ${CFLAGS} -c ${srcdir}/user.c
kdb: kdb.o ${INCLS} ${LIBS} libkauth.a 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 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) ${CC} ${LDFLAGS} -o krb_udp krb_udp.o libkauth.a $(KLIBS)
ka-forwarder: ka-forwarder.o 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.o: rebuild.c $(INCLS) AFS_component_version_number.o
rebuild: rebuild.o kautils.o $(LIBS) 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 # Install targets

View File

@ -23,6 +23,7 @@
#else #else
#include <netinet/in.h> #include <netinet/in.h>
#endif #endif
#include <limits.h>
#include <string.h> #include <string.h>
#include <rx/xdr.h> #include <rx/xdr.h>
#include <rx/rx.h> #include <rx/rx.h>
@ -247,7 +248,7 @@ acl_Internalize(elist, acl)
if (sscanf(elist, "%d\n%d\n", &p, &n) != 2) if (sscanf(elist, "%d\n%d\n", &p, &n) != 2)
return -1; return -1;
if (p + n > ACL_MAXENTRIES) if (p < 0 || n < 0 || p > INT_MAX - n || p + n > ACL_MAXENTRIES)
return (-1); return (-1);
acl_NewACL(p + n, acl); acl_NewACL(p + n, acl);
(*acl)->total = p + n; (*acl)->total = p + n;
@ -272,7 +273,7 @@ acl_Internalize(elist, acl)
nextc++; /* now at the beginning of the entry list */ nextc++; /* now at the beginning of the entry list */
for (i = 0; i < (*acl)->positive; i++) { for (i = 0; i < (*acl)->positive; i++) {
int k; 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); free(lnames.namelist_val);
return (-1); return (-1);
} }
@ -284,7 +285,7 @@ acl_Internalize(elist, acl)
for (i = (*acl)->total - 1; i >= (*acl)->total - (*acl)->negative; for (i = (*acl)->total - 1; i >= (*acl)->total - (*acl)->negative;
i--, j++) { i--, j++) {
if (sscanf 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) { &((*acl)->entries[j].rights)) != 2) {
free(lnames.namelist_val); free(lnames.namelist_val);
return (-1); return (-1);

View File

@ -1530,7 +1530,7 @@ afsclient_ACLEntryAdd(const char *directory, const char *user,
*/ */
is_dfs = 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); cur_acl.cell);
ptr = strchr(old_acl_string, '\n'); ptr = strchr(old_acl_string, '\n');
ptr++; ptr++;
@ -1555,7 +1555,7 @@ afsclient_ACLEntryAdd(const char *directory, const char *user,
*/ */
for (i = 0; i < (cur_acl.nplus + cur_acl.nminus); i++) { 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 * Skip the entry for the user we are replacing/adding
*/ */

View File

@ -32,7 +32,7 @@ AUTHOBJS = \
writeconfig.o \ writeconfig.o \
authcon.o \ authcon.o \
ktc_errors.o \ ktc_errors.o \
acfg_errors.o acfg_errors.o @MAKE_KRB5@ akimpersonate.o akimpersonate_v5gen.o
KAUTHOBJS = \ KAUTHOBJS = \
kauth.xdr.o \ kauth.xdr.o \
@ -63,7 +63,7 @@ UTILOBJS = \
fileutil.o fileutil.o
RXKADOBJS = \ RXKADOBJS = \
rxkad_errs.o rxkad_errs.o @MAKE_KRB5@ ticket5_keytab.o
SYSOBJS = \ SYSOBJS = \
rmtsysc.o \ rmtsysc.o \
@ -120,7 +120,13 @@ writeconfig.o: ${AUTH}/writeconfig.c
${CCRULE} ${CCRULE}
authcon.o: ${AUTH}/authcon.c 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 ktc_errors.o: ${AUTH}/ktc_errors.c
${CCRULE} ${CCRULE}
@ -197,6 +203,9 @@ pthread_glock.o: ${UTIL}/pthread_glock.c
rxkad_errs.o: ${RXKAD}/rxkad_errs.c rxkad_errs.o: ${RXKAD}/rxkad_errs.c
${CCRULE} ${CCRULE}
ticket5_keytab.o: ${RXKAD}/ticket5_keytab.c
${CCRULE} @KRB5CFLAGS@
ptclient.o: ${PTSERVER}/ptclient.c ptclient.o: ${PTSERVER}/ptclient.c
${CCRULE} ${CCRULE}

View File

@ -57,7 +57,7 @@ depinstall: \
# Build targets # Build targets
# #
ptserver: ptserver.o ptutils.o ptprocs.o ptint.ss.o ptint.xdr.o utils.o $(LIBS) ${TOP_LIBDIR}/libaudit.a map.o 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 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.o: db_verify.c ${INCLS} AFS_component_version_number.c
db_verify: db_verify.o pterror.o display.o $(LIBS) 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) 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 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) $@ $(RANLIB) $@
pts: pts.o libprot.a ${TOP_LIBDIR}/libcmd.a $(LIBS) 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 pts.o: pts.c ${LINCLS} ${TOP_INCDIR}/afs/cmd.h AFS_component_version_number.c
readgroup: readgroup.o libprot.a $(LIBS) 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 readgroup.o: readgroup.c ${LINCLS} AFS_component_version_number.c
readpwd: readpwd.o libprot.a $(LIBS) 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 readpwd.o: readpwd.c ${LINCLS} AFS_component_version_number.c
testpt: testpt.o libprot.a ${TOP_LIBDIR}/libcmd.a $(LIBS) testpt: testpt.o libprot.a ${TOP_LIBDIR}/libcmd.a $(LIBS)
case "$(SYS_NAME)" in \ case "$(SYS_NAME)" in \
*_darwin_12 ) \ *_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 esac
testpt.o: testpt.c ${INCLS} ${TOP_INCDIR}/afs/cmd.h AFS_component_version_number.c 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) 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} ubik.o: ubik.c ${INCLS}

View File

@ -691,7 +691,7 @@ idToName(call, aid, aname)
size = aid->idlist_len; size = aid->idlist_len;
if (size == 0) if (size == 0)
return 0; return 0;
if (size < 0) if (size < 0 || size > INT_MAX / PR_MAXNAMELEN)
return PRTOOMANY; return PRTOOMANY;
aname->namelist_val = (prname *) malloc(size * PR_MAXNAMELEN); aname->namelist_val = (prname *) malloc(size * PR_MAXNAMELEN);
aname->namelist_len = 0; aname->namelist_len = 0;

View File

@ -521,6 +521,10 @@ main(int argc, char **argv)
sc[1] = 0; sc[1] = 0;
if (kerberosKeys) { if (kerberosKeys) {
sc[2] = rxkad_NewServerSecurityObject(0, prdir, afsconf_GetKey, NULL); 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 } else
sc[2] = sc[0]; sc[2] = sc[0];

View File

@ -1218,27 +1218,8 @@ int rxk_ListenerPid; /* Used to signal process to wakeup at shutdown */
struct task_struct *rxk_ListenerTask; struct task_struct *rxk_ListenerTask;
#endif #endif
#ifdef AFS_SUN5_ENV
/*
* Run the listener as a kernel thread.
*/
void void
rxk_Listener(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; struct rx_packet *rxp = NULL;
int code; int code;
@ -1259,9 +1240,9 @@ rxk_Listener(void)
#elif defined(AFS_DARWIN_ENV) #elif defined(AFS_DARWIN_ENV)
rxk_ListenerPid = current_proc()->p_pid; rxk_ListenerPid = current_proc()->p_pid;
#endif #endif
#if defined(RX_ENABLE_LOCKS) && !defined(AFS_SUN5_ENV) #ifdef RX_ENABLE_LOCKS
AFS_GUNLOCK(); AFS_GUNLOCK();
#endif /* RX_ENABLE_LOCKS && !AFS_SUN5_ENV */ #endif /* RX_ENABLE_LOCKS */
while (afs_termState != AFSOP_STOP_RXK_LISTENER) { while (afs_termState != AFSOP_STOP_RXK_LISTENER) {
if (rxp) { if (rxp) {
rxi_RestoreDataBufs(rxp); rxi_RestoreDataBufs(rxp);
@ -1294,9 +1275,6 @@ rxk_Listener(void)
#if defined(AFS_SUN5_ENV) #if defined(AFS_SUN5_ENV)
osi_rxWakeup(&rxk_ListenerPid); osi_rxWakeup(&rxk_ListenerPid);
#endif #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) #if !defined(AFS_LINUX20_ENV) && !defined(AFS_SUN5_ENV) && !defined(AFS_DARWIN_ENV) && !defined(AFS_XBSD_ENV)

View File

@ -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 \ OBJS=rxkad_client.o rxkad_server.o rxkad_common.o rxkad_errs.o \
fcrypt.o crypt_conn.o ticket.o ticket5.o crc.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 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} crypt_conn.o: ${srcdir}/domestic/crypt_conn.c fcrypt.h private_data.h ${INCLS}
${CCOBJ} ${CFLAGS} -c ${srcdir}/domestic/crypt_conn.c ${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 tcrypt.o: ${srcdir}/domestic/tcrypt.c AFS_component_version_number.o
${CCOBJ} ${CFLAGS} -c ${srcdir}/domestic/fcrypt.c ${CCOBJ} ${CFLAGS} -c ${srcdir}/domestic/fcrypt.c

View File

@ -78,6 +78,7 @@ struct rxkad_sprivate {
int (*get_key) (); /* func. of kvno and server key ptr */ int (*get_key) (); /* func. of kvno and server key ptr */
int (*user_ok) (); /* func called with new client name */ int (*user_ok) (); /* func called with new client name */
afs_uint32 flags; /* configuration flags */ afs_uint32 flags; /* configuration flags */
rxkad_alt_decrypt_func alt_decrypt;
}; };
/* private data in server-side connection */ /* private data in server-side connection */

View File

@ -93,6 +93,11 @@ typedef char rxkad_level;
extern int rxkad_EpochWasSet; /* TRUE => we called rx_SetEpoch */ 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" #include "rxkad_prototypes.h"
#endif /* OPENAFS_RXKAD_RXKAD_H */ #endif /* OPENAFS_RXKAD_RXKAD_H */

View File

@ -124,6 +124,8 @@ extern afs_int32 rxkad_SetConfiguration(struct rx_securityClass *aobj,
struct rx_connection *aconn, struct rx_connection *aconn,
rx_securityConfigVariables atype, rx_securityConfigVariables atype,
void * avalue, void **aresult); void * avalue, void **aresult);
extern int rxkad_SetAltDecryptProc(struct rx_securityClass *aobj,
rxkad_alt_decrypt_func alt_decrypt);
/* ticket.c */ /* ticket.c */
extern int tkt_DecodeTicket(char *asecret, afs_int32 ticketLen, 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 *get_key_rock, int serv_kvno, char *name,
char *inst, char *cell, char *session_key, char *inst, char *cell, char *session_key,
afs_int32 * host, afs_int32 * start, 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 #endif

View File

@ -326,7 +326,8 @@ rxkad_CheckResponse(struct rx_securityClass *aobj,
tkt_DecodeTicket5(tix, tlen, tsp->get_key, tsp->get_key_rock, tkt_DecodeTicket5(tix, tlen, tsp->get_key, tsp->get_key_rock,
kvno, client.name, client.instance, client.cell, kvno, client.name, client.instance, client.cell,
&sessionkey, &host, &start, &end, &sessionkey, &host, &start, &end,
tsp->flags & RXS_CONFIG_FLAGS_DISABLE_DOTCHECK); tsp->flags & RXS_CONFIG_FLAGS_DISABLE_DOTCHECK,
tsp->alt_decrypt);
if (code) if (code)
return code; return code;
} }
@ -474,3 +475,13 @@ afs_int32 rxkad_SetConfiguration(struct rx_securityClass *aobj,
} }
return 0; 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;
}

View File

@ -83,6 +83,7 @@
#include <rx/xdr.h> #include <rx/xdr.h>
#include <rx/rx.h> #include <rx/rx.h>
#include <des.h> #include <des.h>
#include <des_prototypes.h>
#include "lifetimes.h" #include "lifetimes.h"
#include "rxkad.h" #include "rxkad.h"
#endif /* defined(UKERNEL) */ #endif /* defined(UKERNEL) */
@ -183,8 +184,11 @@ static const struct krb_convert sconv_list[] = {
static int static int
krb5_des_decrypt(struct ktc_encryptionKey *, int, void *, size_t, void *, krb5_des_decrypt(struct ktc_encryptionKey *, int, void *, size_t, void *,
size_t *); 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 int
@ -192,7 +196,8 @@ tkt_DecodeTicket5(char *ticket, afs_int32 ticket_len,
int (*get_key) (char *, int, struct ktc_encryptionKey *), int (*get_key) (char *, int, struct ktc_encryptionKey *),
char *get_key_rock, int serv_kvno, char *name, char *inst, char *get_key_rock, int serv_kvno, char *name, char *inst,
char *cell, char *session_key, afs_int32 * host, 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]; char plain[MAXKRB5TICKETLEN];
struct ktc_encryptionKey serv_key; struct ktc_encryptionKey serv_key;
@ -233,33 +238,41 @@ tkt_DecodeTicket5(char *ticket, afs_int32 ticket_len,
v5_serv_kvno = *t5.enc_part.kvno; 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) { switch (t5.enc_part.etype) {
case ETYPE_DES_CBC_CRC: case ETYPE_DES_CBC_CRC:
case ETYPE_DES_CBC_MD4: case ETYPE_DES_CBC_MD4:
case ETYPE_DES_CBC_MD5: case ETYPE_DES_CBC_MD5:
/* 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);
if (code)
goto unknown_key;
/* 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);
if (code != 0)
goto bad_ticket;
break; break;
default: default:
goto unknown_key; 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;
} }
/* check ticket */
if (t5.enc_part.cipher.length > sizeof(plain)
|| t5.enc_part.cipher.length % 8 != 0)
goto bad_ticket;
code = (*get_key) (get_key_rock, v5_serv_kvno, &serv_key);
if (code)
goto unknown_key;
/* 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);
if (code != 0)
goto bad_ticket;
/* Decode ticket */ /* Decode ticket */
code = decode_EncTicketPart(plain, plainsiz, &decr_part, &siz); code = decode_EncTicketPart(plain, plainsiz, &decr_part, &siz);
if (code != 0) if (code != 0)
@ -320,21 +333,9 @@ tkt_DecodeTicket5(char *ticket, afs_int32 ticket_len,
} }
/* Verify that decr_part.key is of right type */ /* Verify that decr_part.key is of right type */
switch (decr_part.key.keytype) { if (tkt_DeriveDesKey(decr_part.key.keytype, decr_part.key.keyvalue.data,
case ETYPE_DES_CBC_CRC: decr_part.key.keyvalue.length, session_key) != 0)
case ETYPE_DES_CBC_MD4:
case ETYPE_DES_CBC_MD5:
break;
default:
goto bad_ticket; 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 */ /* Check lifetimes and host addresses, flags etc */
{ {
time_t now = time(0); /* Use fast time package instead??? */ 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; 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
View 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);
}

View File

@ -49,7 +49,7 @@ all: scout
scout.o: scout.c ${INCLS} AFS_component_version_number.c scout.o: scout.c ${INCLS} AFS_component_version_number.c
scout: scout.o $(LIBS) 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 # Installation targets

View File

@ -37,7 +37,7 @@ AUTHOBJS = \
writeconfig.o \ writeconfig.o \
authcon.o \ authcon.o \
ktc_errors.o \ ktc_errors.o \
acfg_errors.o acfg_errors.o @MAKE_KRB5@ akimpersonate.o akimpersonate_v5gen.o
KAUTHOBJS = \ KAUTHOBJS = \
kauth.xdr.o \ kauth.xdr.o \
@ -68,7 +68,7 @@ UTILOBJS = \
fileutil.o fileutil.o
RXKADOBJS = \ RXKADOBJS = \
rxkad_errs.o rxkad_errs.o @MAKE_KRB5@ ticket5_keytab.o
SYSOBJS = \ SYSOBJS = \
rmtsysc.o \ rmtsysc.o \
@ -150,7 +150,13 @@ writeconfig.o: ${AUTH}/writeconfig.c
${CCRULE} ${CCRULE}
authcon.o: ${AUTH}/authcon.c 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 ktc_errors.o: ${AUTH}/ktc_errors.c
${CCRULE} ${CCRULE}
@ -227,6 +233,9 @@ pthread_glock.o: ${UTIL}/pthread_glock.c
rxkad_errs.o: ${RXKAD}/rxkad_errs.c rxkad_errs.o: ${RXKAD}/rxkad_errs.c
${CCRULE} ${CCRULE}
ticket5_keytab.o: ${RXKAD}/ticket5_keytab.c
${CCRULE} @KRB5CFLAGS@
ptclient.o: ${PTSERVER}/ptclient.c ptclient.o: ${PTSERVER}/ptclient.c
${CCRULE} ${CCRULE}

View File

@ -45,12 +45,14 @@
rxkad_GetServerInfo; rxkad_GetServerInfo;
rxkad_NewClientSecurityObject; rxkad_NewClientSecurityObject;
rxkad_NewServerSecurityObject; rxkad_NewServerSecurityObject;
rxkad_SetAltDecryptProc;
rxnull_NewClientSecurityObject; rxnull_NewClientSecurityObject;
rxnull_NewServerSecurityObject; rxnull_NewServerSecurityObject;
rxs_Release; rxs_Release;
time_to_life; time_to_life;
tkt_CheckTimes; tkt_CheckTimes;
tkt_DecodeTicket; tkt_DecodeTicket;
tkt_DeriveDesKey;
tkt_MakeTicket; tkt_MakeTicket;
xdrrx_create; xdrrx_create;
hton_syserr_conv; hton_syserr_conv;

View File

@ -66,7 +66,7 @@ BUTCLIBS=${TOP_LIBDIR}/libbudb.a \
all: butc all: butc
butc: ${BUTCOBJS} ${BUTCLIBS} 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 libbutm.a: ${BUTMOBJS} AFS_component_version_number.o
-$(RM) -f libbutm.a -$(RM) -f libbutm.a

View File

@ -72,13 +72,13 @@ clean:
$(RM) -f *.o $(AUTHLIBS) $(AUTHFILES) so_locations $(RM) -f *.o $(AUTHLIBS) $(AUTHFILES) so_locations
afs_dynamic_auth: ${AUTH_OBJS} ${AFSLIBS} ${AUTHFILES} 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} aklog_dynamic_auth: ${AUTH_KRB5_OBJS} ${AFSLIBS} ${AUTHFILES}
$(LD) -o $@ ${AUTH_KRB5_OBJS} $(AFSLIBS) ${AUTHFILES} @KRB5LIBS@ ${XLIBS} ${AKLDFLAGS} $(LD) -o $@ ${AUTH_KRB5_OBJS} $(AFSLIBS) ${AUTHFILES} @KRB5LIBS@ ${XLIBS} ${AKLDFLAGS}
afs_dynamic_kerbauth: ${AUTH_KRB_OBJS} ${KAFSLIBS} ${AUTHFILES} 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 aix_auth_common.o: ${srcdir}/aix_auth_common.c
${CCRULE} ${CCRULE}

View File

@ -186,7 +186,7 @@ afsint.xdr.o: ${FSINT}/afsint.xdr.c
${CCRULE} ${CCRULE}
fileserver: ${objects} ${LIBS} 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 ${DEST}/root.server/usr/afs/bin/fileserver: fileserver
${INSTALL} -ns $? $@ ${INSTALL} -ns $? $@

View File

@ -189,7 +189,7 @@ afsint.xdr.o: ${FSINT}/afsint.xdr.c
${COMPILE} ${COMPILE}
volserver: ${objects} ${LIBS} 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 ${DEST}/root.server/usr/afs/bin/volserver: volserver
${INSTALL} -ns $? $@ ${INSTALL} -ns $? $@

View File

@ -23,10 +23,10 @@ all: upserver upclient
# Build targets # Build targets
# #
upclient: client.o update.cs.o utils.o ${LIBS} 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} 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 utils.o: utils.c update.h global.h

View File

@ -314,7 +314,10 @@ main(int argc, char *argv[])
rxkad_NewServerSecurityObject(rxkad_clear, cdir, afsconf_GetKey, 0); rxkad_NewServerSecurityObject(rxkad_clear, cdir, afsconf_GetKey, 0);
if (securityObjects[2] == (struct rx_securityClass *)0) if (securityObjects[2] == (struct rx_securityClass *)0)
Quit("rxkad_NewServerSecurityObject"); 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 /* Instantiate a single UPDATE service. The rxgen-generated procedure
* which is called to decode requests is passed in here * which is called to decode requests is passed in here
* (UPDATE_ExecuteRequest). */ * (UPDATE_ExecuteRequest). */

View File

@ -46,7 +46,7 @@ OBJS = uss_procs.o \
y.tab.o y.tab.o
uss: uss.o ${OBJS} 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 uss.o: uss.c AFS_component_version_number.c
${CC} -c ${CFLAGS} ${srcdir}/uss.c ${CC} -c ${CFLAGS} ${srcdir}/uss.c

View File

@ -366,6 +366,9 @@ initDirPathArray(void)
pathp = dirPathArray[AFSDIR_SERVER_KRB_EXCL_FILEPATH_ID]; pathp = dirPathArray[AFSDIR_SERVER_KRB_EXCL_FILEPATH_ID];
AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_SERVER_ETC_DIR, AFSDIR_KRB_EXCL_FILE); 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 */ /* client file paths */
#ifdef AFS_NT40_ENV #ifdef AFS_NT40_ENV
strcpy(dirPathArray[AFSDIR_CLIENT_THISCELL_FILEPATH_ID], strcpy(dirPathArray[AFSDIR_CLIENT_THISCELL_FILEPATH_ID],

View File

@ -145,6 +145,7 @@ ConstructLocalLogPath(const char *cpath,
#define AFSDIR_VOLSERLOG_FILE "VolserLog" #define AFSDIR_VOLSERLOG_FILE "VolserLog"
#define AFSDIR_AUDIT_FILE "Audit" #define AFSDIR_AUDIT_FILE "Audit"
#define AFSDIR_KRB_EXCL_FILE "krb.excl" #define AFSDIR_KRB_EXCL_FILE "krb.excl"
#define AFSDIR_RXKAD_KEYTAB_FILE "rxkad.keytab"
#define AFSDIR_ROOTVOL_FILE "RootVolume" #define AFSDIR_ROOTVOL_FILE "RootVolume"
#define AFSDIR_HOSTDUMP_FILE "hosts.dump" #define AFSDIR_HOSTDUMP_FILE "hosts.dump"
@ -264,6 +265,7 @@ typedef enum afsdir_id {
AFSDIR_SERVER_BIN_FILE_DIRPATH_ID, AFSDIR_SERVER_BIN_FILE_DIRPATH_ID,
AFSDIR_CLIENT_CELLALIAS_FILEPATH_ID, AFSDIR_CLIENT_CELLALIAS_FILEPATH_ID,
AFSDIR_SERVER_KRB_EXCL_FILEPATH_ID, AFSDIR_SERVER_KRB_EXCL_FILEPATH_ID,
AFSDIR_SERVER_RXKAD_KEYTAB_FILEPATH_ID,
AFSDIR_PATHSTRING_MAX } afsdir_id_t; AFSDIR_PATHSTRING_MAX } afsdir_id_t;
/* getDirPath() returns a pointer to a string from an internal array of path strings /* 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_THRESHOLD_CONSTANTS_FILEPATH getDirPath(AFSDIR_SERVER_THRESHOLD_CONSTANTS_FILEPATH_ID)
#define AFSDIR_SERVER_MIGRATELOG_FILEPATH getDirPath(AFSDIR_SERVER_MIGRATELOG_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_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 */ /* client file paths */
#define AFSDIR_CLIENT_THISCELL_FILEPATH getDirPath(AFSDIR_CLIENT_THISCELL_FILEPATH_ID) #define AFSDIR_CLIENT_THISCELL_FILEPATH getDirPath(AFSDIR_CLIENT_THISCELL_FILEPATH_ID)

View File

@ -47,7 +47,7 @@ all: fs up fstrace cmdebug livesys kdump-build
# Build targets # Build targets
# #
cacheout: cacheout.o 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 cacheout.o: cacheout.c
@ -76,15 +76,15 @@ up: up.o
fs.o: fs.c ${INCLS} AFS_component_version_number.c fs.o: fs.c ${INCLS} AFS_component_version_number.c
fs: fs.o $(LIBS) 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.o: livesys.c ${INCLS} AFS_component_version_number.c
livesys: livesys.c $(LIBS) 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) 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) gcpags: gcpags.c $(LIBS)
${CC} ${CFLAGS} -o gcpags ${srcdir}/gcpags.c $(LIBS) ${XLIBS} ${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.o: whatfid.c ${INCLS} AFS_component_version_number.c
whatfid: whatfid.o ${LIBS} 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 fstrace.o: fstrace.c AFS_component_version_number.c
case ${SYS_NAME} in \ case ${SYS_NAME} in \
@ -121,8 +121,7 @@ fstrace: fstrace.o
cmdebug.o: cmdebug.c ${INCLS} AFS_component_version_number.c cmdebug.o: cmdebug.c ${INCLS} AFS_component_version_number.c
cmdebug: cmdebug.o ${CMLIBS} cmdebug: cmdebug.o ${CMLIBS}
$(CC) -o cmdebug cmdebug.o ${CFLAGS} ${CMLIBS} ${XLIBS} $(CC) -o cmdebug cmdebug.o ${CFLAGS} ${CMLIBS} ${XLIBS} ${KRB5_LIBS}
# #

View File

@ -561,7 +561,7 @@ EmptyAcl(char *astr)
tp->nplus = tp->nminus = 0; tp->nplus = tp->nminus = 0;
tp->pluslist = tp->minuslist = 0; tp->pluslist = tp->minuslist = 0;
tp->dfs = 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; return tp;
} }
@ -576,7 +576,7 @@ ParseAcl(char *astr)
ta = (struct Acl *)malloc(sizeof(struct Acl)); ta = (struct Acl *)malloc(sizeof(struct Acl));
assert(ta); assert(ta);
ta->dfs = 0; 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); astr = SkipLine(astr);
sscanf(astr, "%d", &ta->nminus); sscanf(astr, "%d", &ta->nminus);
astr = SkipLine(astr); astr = SkipLine(astr);
@ -587,7 +587,7 @@ ParseAcl(char *astr)
last = 0; last = 0;
first = 0; first = 0;
for (i = 0; i < nplus; i++) { for (i = 0; i < nplus; i++) {
sscanf(astr, "%100s %d", tname, &trights); sscanf(astr, "%99s %d", tname, &trights);
astr = SkipLine(astr); astr = SkipLine(astr);
tl = (struct AclEntry *)malloc(sizeof(struct AclEntry)); tl = (struct AclEntry *)malloc(sizeof(struct AclEntry));
assert(tl); assert(tl);
@ -605,7 +605,7 @@ ParseAcl(char *astr)
last = 0; last = 0;
first = 0; first = 0;
for (i = 0; i < nminus; i++) { for (i = 0; i < nminus; i++) {
sscanf(astr, "%100s %d", tname, &trights); sscanf(astr, "%99s %d", tname, &trights);
astr = SkipLine(astr); astr = SkipLine(astr);
tl = (struct AclEntry *)malloc(sizeof(struct AclEntry)); tl = (struct AclEntry *)malloc(sizeof(struct AclEntry));
assert(tl); assert(tl);

View File

@ -72,23 +72,23 @@ fileserver: ${objects} ${headers} ${LIBS}
case ${SYS_NAME} in \ case ${SYS_NAME} in \
rs_aix*) \ rs_aix*) \
${CC} -K ${LDFLAGS} -o fileserver ${objects} \ ${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} \ ${CC} ${LDFLAGS} -o fileserver ${objects} \
${TOP_LIBDIR}/libaudit.a ${LIBS} ${XLIBS} ;; \ ${TOP_LIBDIR}/libaudit.a ${LIBS} ${XLIBS} ${KRB5_LIBS} ;; \
esac esac
fsprobe.o: fsprobe.c AFS_component_version_number.c fsprobe.o: fsprobe.c AFS_component_version_number.c
${CC} ${CFLAGS} -DINTERPRET_DUMP -c ${srcdir}/fsprobe.c ${CC} ${CFLAGS} -DINTERPRET_DUMP -c ${srcdir}/fsprobe.c
fsprobe: fsprobe.o 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 cbd.o: callback.c AFS_component_version_number.c
${CC} ${CFLAGS} -DINTERPRET_DUMP -c -o cbd.o ${srcdir}/callback.c ${CC} ${CFLAGS} -DINTERPRET_DUMP -c -o cbd.o ${srcdir}/callback.c
cbd: cbd.o 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 ${DEST}/root.server/usr/afs/bin/fileserver: fileserver
@case ${SYS_NAME} in \ @case ${SYS_NAME} in \

View File

@ -1884,6 +1884,12 @@ main(int argc, char *argv[])
sc[1] = 0; /* rxvab_NewServerSecurityObject(key1, 0) */ sc[1] = 0; /* rxvab_NewServerSecurityObject(key1, 0) */
sc[2] = rxkad_NewServerSecurityObject(rxkad_clear, NULL, get_key, NULL); sc[2] = rxkad_NewServerSecurityObject(rxkad_clear, NULL, get_key, NULL);
sc[3] = rxkad_NewServerSecurityObject(rxkad_crypt, 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 */ tservice = rx_NewServiceHost(rx_bindhost, /* port */ 0, /* service id */
1, /*service name */ 1, /*service name */
"AFS", "AFS",

View File

@ -46,23 +46,23 @@ depinstall: \
${TOP_INCDIR}/afs/cnvldb.h ${TOP_INCDIR}/afs/cnvldb.h
vldb_check: vldb_check.o ${LIBS} 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 vldb_check.o: vldb_check.c AFS_component_version_number.o
cnvldb: cnvldb.o ${LIBS} 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 cnvldb.o: cnvldb.c cnvldb.h AFS_component_version_number.o
sascnvldb: sascnvldb.o ${LIBS} 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 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) 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 \ $(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 vlserver.o: vlserver.c ${INCLS} AFS_component_version_number.o
vlutils.o: vlutils.c ${INCLS} vlutils.o: vlutils.c ${INCLS}
@ -99,7 +99,7 @@ libvldb.a: $(OBJS) AFS_component_version_number.o
$(RANLIB) $@ $(RANLIB) $@
vlclient: vlclient.o libvldb.a $(LIBS) 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 vlclient.o: vlclient.c ${INCLS} AFS_component_version_number.o

View File

@ -355,7 +355,10 @@ main(argc, argv)
sc[0] = rxnull_NewServerSecurityObject(); sc[0] = rxnull_NewServerSecurityObject();
sc[1] = (struct rx_securityClass *)0; sc[1] = (struct rx_securityClass *)0;
sc[2] = rxkad_NewServerSecurityObject(0, tdir, afsconf_GetKey, NULL); 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 = tservice =
rx_NewServiceHost(host, 0, USER_SERVICE_ID, "Vldb server", sc, 3, rx_NewServiceHost(host, 0, USER_SERVICE_ID, "Vldb server", sc, 3,
VL_ExecuteRequest); VL_ExecuteRequest);

View File

@ -65,11 +65,11 @@ restorevol: restorevol.c
${TOP_LIBDIR}/libcmd.a ${TOP_LIBDIR}/util.a ${XLIBS} ${TOP_LIBDIR}/libcmd.a ${TOP_LIBDIR}/util.a ${XLIBS}
vos: vos.o ${VSOBJS} libvolser.a ${LIBS} 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 volserver: $(SOBJS) $(LIBS) ${TOP_LIBDIR}/libdir.a
${CC} ${DBG} -o volserver $(SOBJS) ${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} voldump: vol-dump.o ${VOLDUMP_LIBS}
${CC} ${CFLAGS} -o voldump vol-dump.o ${VOLDUMP_LIBS} ${XLIBS} ${CC} ${CFLAGS} -o voldump vol-dump.o ${VOLDUMP_LIBS} ${XLIBS}

View File

@ -494,6 +494,10 @@ main(int argc, char **argv)
rxkad_NewServerSecurityObject(0, tdir, afsconf_GetKey, NULL); rxkad_NewServerSecurityObject(0, tdir, afsconf_GetKey, NULL);
if (securityObjects[0] == (struct rx_securityClass *)0) if (securityObjects[0] == (struct rx_securityClass *)0)
Abort("rxnull_NewServerSecurityObject"); 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 = service =
rx_NewServiceHost(host, 0, VOLSERVICE_ID, "VOLSER", securityObjects, 3, rx_NewServiceHost(host, 0, VOLSERVICE_ID, "VOLSER", securityObjects, 3,
AFSVolExecuteRequest); AFSVolExecuteRequest);