Merge branch 'master' into lukeh/moonshot
This commit is contained in:
40
cf/db.m4
40
cf/db.m4
@@ -42,7 +42,6 @@ AS_IF([test "x$with_berkeley_db" != xno],
|
|||||||
db4/db.h \
|
db4/db.h \
|
||||||
db3/db.h \
|
db3/db.h \
|
||||||
db.h \
|
db.h \
|
||||||
db_185.h \
|
|
||||||
])])
|
])])
|
||||||
|
|
||||||
dnl db_create is used by db3 and db4 and db5
|
dnl db_create is used by db3 and db4 and db5
|
||||||
@@ -70,32 +69,29 @@ dnl db_create is used by db3 and db4 and db5
|
|||||||
DBLIB=""
|
DBLIB=""
|
||||||
fi
|
fi
|
||||||
AC_DEFINE(HAVE_DB3, 1, [define if you have a berkeley db3/4/5 library])
|
AC_DEFINE(HAVE_DB3, 1, [define if you have a berkeley db3/4/5 library])
|
||||||
else
|
fi
|
||||||
|
|
||||||
dnl dbopen is used by db1/db2
|
dnl dbopen is used by db1/db2
|
||||||
|
|
||||||
AC_FIND_FUNC_NO_LIBS(dbopen, db2 db, [
|
AC_FIND_FUNC_NO_LIBS(dbopen, db2 db, [
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#if defined(HAVE_DB2_DB_H)
|
#if defined(HAVE_DB2_DB_H)
|
||||||
#include <db2/db.h>
|
#include <db2/db.h>
|
||||||
#elif defined(HAVE_DB_185_H)
|
#elif defined(HAVE_DB_H)
|
||||||
#include <db_185.h>
|
#include <db.h>
|
||||||
#elif defined(HAVE_DB_H)
|
#else
|
||||||
#include <db.h>
|
#error no db.h
|
||||||
#else
|
#endif
|
||||||
#error no db.h
|
],[NULL, 0, 0, 0, NULL])
|
||||||
#endif
|
|
||||||
],[NULL, 0, 0, 0, NULL])
|
|
||||||
|
|
||||||
if test "$ac_cv_func_dbopen" = "yes"; then
|
if test "$ac_cv_func_dbopen" = "yes"; then
|
||||||
db_type=db1
|
db_type=db1
|
||||||
if test "$ac_cv_funclib_dbopen" != "yes"; then
|
if test "$ac_cv_funclib_dbopen" != "yes"; then
|
||||||
DBLIB="$ac_cv_funclib_dbopen"
|
DBLIB="$ac_cv_funclib_dbopen"
|
||||||
else
|
else
|
||||||
DBLIB=""
|
DBLIB=""
|
||||||
fi
|
|
||||||
AC_DEFINE(HAVE_DB1, 1, [define if you have a berkeley db1/2 library])
|
|
||||||
fi
|
fi
|
||||||
|
AC_DEFINE(HAVE_DB1, 1, [define if you have a berkeley db1/2 library])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
dnl test for ndbm compatability
|
dnl test for ndbm compatability
|
||||||
|
@@ -36,6 +36,24 @@
|
|||||||
HEIMDAL_MUTEX gssapi_keytab_mutex = HEIMDAL_MUTEX_INITIALIZER;
|
HEIMDAL_MUTEX gssapi_keytab_mutex = HEIMDAL_MUTEX_INITIALIZER;
|
||||||
krb5_keytab _gsskrb5_keytab;
|
krb5_keytab _gsskrb5_keytab;
|
||||||
|
|
||||||
|
static krb5_error_code
|
||||||
|
validate_keytab(krb5_context context, const char *name, krb5_keytab *id)
|
||||||
|
{
|
||||||
|
krb5_error_code ret;
|
||||||
|
|
||||||
|
ret = krb5_kt_resolve(context, name, id);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
ret = krb5_kt_have_content(context, *id);
|
||||||
|
if (ret) {
|
||||||
|
krb5_kt_close(context, *id);
|
||||||
|
*id = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
OM_uint32
|
OM_uint32
|
||||||
_gsskrb5_register_acceptor_identity (const char *identity)
|
_gsskrb5_register_acceptor_identity (const char *identity)
|
||||||
{
|
{
|
||||||
@@ -55,15 +73,23 @@ _gsskrb5_register_acceptor_identity (const char *identity)
|
|||||||
if (identity == NULL) {
|
if (identity == NULL) {
|
||||||
ret = krb5_kt_default(context, &_gsskrb5_keytab);
|
ret = krb5_kt_default(context, &_gsskrb5_keytab);
|
||||||
} else {
|
} else {
|
||||||
char *p = NULL;
|
/*
|
||||||
|
* First check if we can the keytab as is and if it has content...
|
||||||
ret = asprintf(&p, "FILE:%s", identity);
|
*/
|
||||||
if(ret < 0 || p == NULL) {
|
ret = validate_keytab(context, identity, &_gsskrb5_keytab);
|
||||||
HEIMDAL_MUTEX_unlock(&gssapi_keytab_mutex);
|
/*
|
||||||
return GSS_S_FAILURE;
|
* if it doesn't, lets prepend FILE: and try again
|
||||||
|
*/
|
||||||
|
if (ret) {
|
||||||
|
char *p = NULL;
|
||||||
|
ret = asprintf(&p, "FILE:%s", identity);
|
||||||
|
if(ret < 0 || p == NULL) {
|
||||||
|
HEIMDAL_MUTEX_unlock(&gssapi_keytab_mutex);
|
||||||
|
return GSS_S_FAILURE;
|
||||||
|
}
|
||||||
|
ret = validate_keytab(context, p, &_gsskrb5_keytab);
|
||||||
|
free(p);
|
||||||
}
|
}
|
||||||
ret = krb5_kt_resolve(context, p, &_gsskrb5_keytab);
|
|
||||||
free(p);
|
|
||||||
}
|
}
|
||||||
HEIMDAL_MUTEX_unlock(&gssapi_keytab_mutex);
|
HEIMDAL_MUTEX_unlock(&gssapi_keytab_mutex);
|
||||||
if(ret)
|
if(ret)
|
||||||
|
@@ -81,17 +81,18 @@ __gsskrb5_ccache_lifetime(OM_uint32 *minor_status,
|
|||||||
static krb5_error_code
|
static krb5_error_code
|
||||||
get_keytab(krb5_context context, krb5_keytab *keytab)
|
get_keytab(krb5_context context, krb5_keytab *keytab)
|
||||||
{
|
{
|
||||||
char kt_name[256];
|
|
||||||
krb5_error_code kret;
|
krb5_error_code kret;
|
||||||
|
|
||||||
HEIMDAL_MUTEX_lock(&gssapi_keytab_mutex);
|
HEIMDAL_MUTEX_lock(&gssapi_keytab_mutex);
|
||||||
|
|
||||||
if (_gsskrb5_keytab != NULL) {
|
if (_gsskrb5_keytab != NULL) {
|
||||||
kret = krb5_kt_get_name(context,
|
char *name = NULL;
|
||||||
_gsskrb5_keytab,
|
|
||||||
kt_name, sizeof(kt_name));
|
kret = krb5_kt_get_full_name(context, _gsskrb5_keytab, &name);
|
||||||
if (kret == 0)
|
if (kret == 0) {
|
||||||
kret = krb5_kt_resolve(context, kt_name, keytab);
|
kret = krb5_kt_resolve(context, name, keytab);
|
||||||
|
krb5_xfree(name);
|
||||||
|
}
|
||||||
} else
|
} else
|
||||||
kret = krb5_kt_default(context, keytab);
|
kret = krb5_kt_default(context, keytab);
|
||||||
|
|
||||||
|
@@ -123,23 +123,11 @@ OM_uint32 GSSAPI_CALLCONV _gsskrb5_add_cred (
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (cred->keytab) {
|
if (cred->keytab) {
|
||||||
char name[KRB5_KT_PREFIX_MAX_LEN + MAXPATHLEN];
|
char *name = NULL;
|
||||||
int len;
|
|
||||||
|
|
||||||
ret = GSS_S_FAILURE;
|
ret = GSS_S_FAILURE;
|
||||||
|
|
||||||
kret = krb5_kt_get_type(context, cred->keytab,
|
kret = krb5_kt_get_full_name(context, cred->keytab, &name);
|
||||||
name, KRB5_KT_PREFIX_MAX_LEN);
|
|
||||||
if (kret) {
|
|
||||||
*minor_status = kret;
|
|
||||||
goto failure;
|
|
||||||
}
|
|
||||||
len = strlen(name);
|
|
||||||
name[len++] = ':';
|
|
||||||
|
|
||||||
kret = krb5_kt_get_name(context, cred->keytab,
|
|
||||||
name + len,
|
|
||||||
sizeof(name) - len);
|
|
||||||
if (kret) {
|
if (kret) {
|
||||||
*minor_status = kret;
|
*minor_status = kret;
|
||||||
goto failure;
|
goto failure;
|
||||||
@@ -147,6 +135,7 @@ OM_uint32 GSSAPI_CALLCONV _gsskrb5_add_cred (
|
|||||||
|
|
||||||
kret = krb5_kt_resolve(context, name,
|
kret = krb5_kt_resolve(context, name,
|
||||||
&handle->keytab);
|
&handle->keytab);
|
||||||
|
krb5_xfree(name);
|
||||||
if (kret){
|
if (kret){
|
||||||
*minor_status = kret;
|
*minor_status = kret;
|
||||||
goto failure;
|
goto failure;
|
||||||
|
@@ -205,7 +205,7 @@ mdb_value2entry(krb5_context context, krb5_data *data, krb5_kvno kvno, hdb_entry
|
|||||||
uint32_t u32;
|
uint32_t u32;
|
||||||
uint16_t u16, num_keys, num_tl;
|
uint16_t u16, num_keys, num_tl;
|
||||||
size_t i, j;
|
size_t i, j;
|
||||||
char *p = NULL;
|
char *p;
|
||||||
|
|
||||||
sp = krb5_storage_from_data(data);
|
sp = krb5_storage_from_data(data);
|
||||||
if (sp == NULL) {
|
if (sp == NULL) {
|
||||||
@@ -215,7 +215,21 @@ mdb_value2entry(krb5_context context, krb5_data *data, krb5_kvno kvno, hdb_entry
|
|||||||
|
|
||||||
krb5_storage_set_byteorder(sp, KRB5_STORAGE_BYTEORDER_LE);
|
krb5_storage_set_byteorder(sp, KRB5_STORAGE_BYTEORDER_LE);
|
||||||
|
|
||||||
/* 16: baselength */
|
/*
|
||||||
|
* 16: baselength
|
||||||
|
*
|
||||||
|
* The story here is that these 16 bits have to be a constant:
|
||||||
|
* KDB_V1_BASE_LENGTH. Once upon a time a different value here
|
||||||
|
* would have been used to indicate the presence of "extra data"
|
||||||
|
* between the "base" contents and the {principal name, TL data,
|
||||||
|
* keys} that follow it. Nothing supports such "extra data"
|
||||||
|
* nowadays, so neither do we here.
|
||||||
|
*
|
||||||
|
* XXX But... surely we ought to log about this extra data, or skip
|
||||||
|
* it, or something, in case anyone has MIT KDBs with ancient
|
||||||
|
* entries in them... Logging would allow the admin to know which
|
||||||
|
* entries to dump with MIT krb5's kdb5_util.
|
||||||
|
*/
|
||||||
CHECK(ret = krb5_ret_uint16(sp, &u16));
|
CHECK(ret = krb5_ret_uint16(sp, &u16));
|
||||||
if (u16 != KDB_V1_BASE_LENGTH) { ret = EINVAL; goto out; }
|
if (u16 != KDB_V1_BASE_LENGTH) { ret = EINVAL; goto out; }
|
||||||
/* 32: attributes */
|
/* 32: attributes */
|
||||||
@@ -273,28 +287,44 @@ mdb_value2entry(krb5_context context, krb5_data *data, krb5_kvno kvno, hdb_entry
|
|||||||
CHECK(ret = krb5_ret_uint16(sp, &u16));
|
CHECK(ret = krb5_ret_uint16(sp, &u16));
|
||||||
/* length: principal */
|
/* length: principal */
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* Note that the principal name includes the NUL in the entry,
|
||||||
|
* but we don't want to take chances, so we add an extra NUL.
|
||||||
|
*/
|
||||||
p = malloc(u16 + 1);
|
p = malloc(u16 + 1);
|
||||||
|
if (p == NULL) {
|
||||||
|
ret = ENOMEM;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
krb5_storage_read(sp, p, u16);
|
krb5_storage_read(sp, p, u16);
|
||||||
p[u16] = '\0';
|
p[u16] = '\0';
|
||||||
CHECK(ret = krb5_parse_name(context, p, &entry->principal));
|
CHECK(ret = krb5_parse_name(context, p, &entry->principal));
|
||||||
free(p); p = NULL;
|
free(p);
|
||||||
}
|
}
|
||||||
/* for num tl data times
|
/* for num tl data times
|
||||||
16: tl data type
|
16: tl data type
|
||||||
16: tl data length
|
16: tl data length
|
||||||
length: length */
|
length: length */
|
||||||
for (i = 0; i < num_tl; i++) {
|
for (i = 0; i < num_tl; i++) {
|
||||||
|
/* 16: TL data type */
|
||||||
CHECK(ret = krb5_ret_uint16(sp, &u16));
|
CHECK(ret = krb5_ret_uint16(sp, &u16));
|
||||||
|
/* 16: TL data length */
|
||||||
CHECK(ret = krb5_ret_uint16(sp, &u16));
|
CHECK(ret = krb5_ret_uint16(sp, &u16));
|
||||||
krb5_storage_seek(sp, u16, SEEK_CUR);
|
krb5_storage_seek(sp, u16, SEEK_CUR);
|
||||||
}
|
}
|
||||||
/* for num key data times
|
/*
|
||||||
16: version (num keyblocks)
|
* for num key data times
|
||||||
16: kvno
|
* 16: "version"
|
||||||
for version times:
|
* 16: kvno
|
||||||
16: type
|
* for version times:
|
||||||
16: length
|
* 16: type
|
||||||
length: keydata */
|
* 16: length
|
||||||
|
* length: keydata
|
||||||
|
*
|
||||||
|
* "version" here is really 1 or 2, the first meaning there's only
|
||||||
|
* keys for this kvno, the second meaning there's keys and salt[s?].
|
||||||
|
* That's right... hold that gag reflex, you can do it.
|
||||||
|
*/
|
||||||
for (i = 0; i < num_keys; i++) {
|
for (i = 0; i < num_keys; i++) {
|
||||||
int keep = 0;
|
int keep = 0;
|
||||||
uint16_t version;
|
uint16_t version;
|
||||||
@@ -304,16 +334,28 @@ mdb_value2entry(krb5_context context, krb5_data *data, krb5_kvno kvno, hdb_entry
|
|||||||
version = u16;
|
version = u16;
|
||||||
CHECK(ret = krb5_ret_uint16(sp, &u16));
|
CHECK(ret = krb5_ret_uint16(sp, &u16));
|
||||||
|
|
||||||
if (((entry->kvno < u16) && kvno == 0) || kvno == u16) {
|
/*
|
||||||
|
* First time through, and until we find one matching key,
|
||||||
|
* entry->kvno == 0.
|
||||||
|
*/
|
||||||
|
if ((entry->kvno < u16) && (kvno == 0 || kvno == u16)) {
|
||||||
keep = 1;
|
keep = 1;
|
||||||
entry->kvno = u16;
|
entry->kvno = u16;
|
||||||
for (j = 0; j < entry->keys.len; j++) {
|
/*
|
||||||
|
* Found a higher kvno than earlier, so free the old highest
|
||||||
|
* kvno keys.
|
||||||
|
*
|
||||||
|
* XXX Of course, we actually want to extract the old kvnos
|
||||||
|
* as well, for some of the kadm5 APIs. We shouldn't free
|
||||||
|
* these keys, but keep them elsewhere.
|
||||||
|
*/
|
||||||
|
for (j = 0; j < entry->keys.len; j++)
|
||||||
free_Key(&entry->keys.val[j]);
|
free_Key(&entry->keys.val[j]);
|
||||||
free(entry->keys.val);
|
free(entry->keys.val);
|
||||||
entry->keys.len = 0;
|
entry->keys.len = 0;
|
||||||
entry->keys.val = NULL;
|
entry->keys.val = NULL;
|
||||||
}
|
|
||||||
} else if (entry->kvno == u16)
|
} else if (entry->kvno == u16)
|
||||||
|
/* Accumulate keys */
|
||||||
keep = 1;
|
keep = 1;
|
||||||
|
|
||||||
if (keep) {
|
if (keep) {
|
||||||
@@ -332,28 +374,40 @@ mdb_value2entry(krb5_context context, krb5_data *data, krb5_kvno kvno, hdb_entry
|
|||||||
memset(k, 0, sizeof(*k));
|
memset(k, 0, sizeof(*k));
|
||||||
entry->keys.len += 1;
|
entry->keys.len += 1;
|
||||||
|
|
||||||
entry->keys.val[i].mkvno = malloc(sizeof(*entry->keys.val[i].mkvno));
|
k->mkvno = malloc(sizeof(*k->mkvno));
|
||||||
if (entry->keys.val[i].mkvno == NULL) {
|
if (k->mkvno == NULL) {
|
||||||
ret = ENOMEM;
|
ret = ENOMEM;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
*entry->keys.val[i].mkvno = 1;
|
*k->mkvno = 1;
|
||||||
|
|
||||||
for (j = 0; j < version; j++) {
|
for (j = 0; j < version; j++) {
|
||||||
uint16_t type;
|
uint16_t type;
|
||||||
CHECK(ret = krb5_ret_uint16(sp, &type));
|
CHECK(ret = krb5_ret_uint16(sp, &type));
|
||||||
CHECK(ret = krb5_ret_uint16(sp, &u16));
|
CHECK(ret = krb5_ret_uint16(sp, &u16));
|
||||||
if (j == 0) { /* key */
|
if (j == 0) {
|
||||||
|
/* This "version" means we have a key */
|
||||||
k->key.keytype = type;
|
k->key.keytype = type;
|
||||||
if (u16 < 2) {
|
if (u16 < 2) {
|
||||||
ret = EINVAL;
|
ret = EINVAL;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
* MIT stores keys encrypted keys as {16-bit length
|
||||||
|
* of plaintext key, {encrypted key}}. The reason
|
||||||
|
* for this is that the Kerberos cryptosystem is not
|
||||||
|
* length-preserving. Heimdal's approach is to
|
||||||
|
* truncate the plaintext to the expected length of
|
||||||
|
* the key given its enctype, so we ignore this
|
||||||
|
* 16-bit length-of-plaintext-key field.
|
||||||
|
*/
|
||||||
krb5_storage_seek(sp, 2, SEEK_CUR); /* skip real length */
|
krb5_storage_seek(sp, 2, SEEK_CUR); /* skip real length */
|
||||||
k->key.keyvalue.length = u16 - 2;
|
k->key.keyvalue.length = u16 - 2; /* adjust cipher len */
|
||||||
k->key.keyvalue.data = malloc(k->key.keyvalue.length);
|
k->key.keyvalue.data = malloc(k->key.keyvalue.length);
|
||||||
krb5_storage_read(sp, k->key.keyvalue.data, k->key.keyvalue.length);
|
krb5_storage_read(sp, k->key.keyvalue.data,
|
||||||
} else if (j == 1) { /* salt */
|
k->key.keyvalue.length);
|
||||||
|
} else if (j == 1) {
|
||||||
|
/* This "version" means we have a salt */
|
||||||
k->salt = calloc(1, sizeof(*k->salt));
|
k->salt = calloc(1, sizeof(*k->salt));
|
||||||
if (k->salt == NULL) {
|
if (k->salt == NULL) {
|
||||||
ret = ENOMEM;
|
ret = ENOMEM;
|
||||||
@@ -371,15 +425,27 @@ mdb_value2entry(krb5_context context, krb5_data *data, krb5_kvno kvno, hdb_entry
|
|||||||
}
|
}
|
||||||
fix_salt(context, entry, entry->keys.len - 1);
|
fix_salt(context, entry, entry->keys.len - 1);
|
||||||
} else {
|
} else {
|
||||||
|
/*
|
||||||
|
* Whatever this "version" might be, we skip it
|
||||||
|
*
|
||||||
|
* XXX A krb5.conf parameter requesting that we log
|
||||||
|
* about strangeness like this, or return an error
|
||||||
|
* from here, might be nice.
|
||||||
|
*/
|
||||||
krb5_storage_seek(sp, u16, SEEK_CUR);
|
krb5_storage_seek(sp, u16, SEEK_CUR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* skip */
|
/*
|
||||||
|
* XXX For now we skip older kvnos, but we should extract
|
||||||
|
* them...
|
||||||
|
*/
|
||||||
for (j = 0; j < version; j++) {
|
for (j = 0; j < version; j++) {
|
||||||
|
/* enctype */
|
||||||
CHECK(ret = krb5_ret_uint16(sp, &u16));
|
CHECK(ret = krb5_ret_uint16(sp, &u16));
|
||||||
|
/* encrypted key (or plaintext salt) */
|
||||||
CHECK(ret = krb5_ret_uint16(sp, &u16));
|
CHECK(ret = krb5_ret_uint16(sp, &u16));
|
||||||
krb5_storage_seek(sp, u16, u16);
|
krb5_storage_seek(sp, u16, SEEK_CUR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -391,9 +457,9 @@ mdb_value2entry(krb5_context context, krb5_data *data, krb5_kvno kvno, hdb_entry
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
out:
|
out:
|
||||||
if (p)
|
if (ret == HEIM_ERR_EOF)
|
||||||
free(p);
|
/* Better error code than "end of file" */
|
||||||
free_hdb_entry(entry);
|
ret = HEIM_ERR_BAD_HDBENT_ENCODING;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -44,6 +44,7 @@ struct addr_operations {
|
|||||||
void (*h_addr2sockaddr)(const char *, struct sockaddr *, krb5_socklen_t *, int);
|
void (*h_addr2sockaddr)(const char *, struct sockaddr *, krb5_socklen_t *, int);
|
||||||
krb5_error_code (*h_addr2addr)(const char *, krb5_address *);
|
krb5_error_code (*h_addr2addr)(const char *, krb5_address *);
|
||||||
krb5_boolean (*uninteresting)(const struct sockaddr *);
|
krb5_boolean (*uninteresting)(const struct sockaddr *);
|
||||||
|
krb5_boolean (*is_loopback)(const struct sockaddr *);
|
||||||
void (*anyaddr)(struct sockaddr *, krb5_socklen_t *, int);
|
void (*anyaddr)(struct sockaddr *, krb5_socklen_t *, int);
|
||||||
int (*print_addr)(const krb5_address *, char *, size_t);
|
int (*print_addr)(const krb5_address *, char *, size_t);
|
||||||
int (*parse_addr)(krb5_context, const char*, krb5_address *);
|
int (*parse_addr)(krb5_context, const char*, krb5_address *);
|
||||||
@@ -136,6 +137,17 @@ ipv4_uninteresting (const struct sockaddr *sa)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static krb5_boolean
|
||||||
|
ipv4_is_loopback (const struct sockaddr *sa)
|
||||||
|
{
|
||||||
|
const struct sockaddr_in *sin4 = (const struct sockaddr_in *)sa;
|
||||||
|
|
||||||
|
if ((ntohl(sin4->sin_addr.s_addr) >> 24) == IN_LOOPBACKNET)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ipv4_anyaddr (struct sockaddr *sa, krb5_socklen_t *sa_size, int port)
|
ipv4_anyaddr (struct sockaddr *sa, krb5_socklen_t *sa_size, int port)
|
||||||
{
|
{
|
||||||
@@ -310,11 +322,19 @@ ipv6_uninteresting (const struct sockaddr *sa)
|
|||||||
const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *)sa;
|
const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *)sa;
|
||||||
const struct in6_addr *in6 = (const struct in6_addr *)&sin6->sin6_addr;
|
const struct in6_addr *in6 = (const struct in6_addr *)&sin6->sin6_addr;
|
||||||
|
|
||||||
return
|
return IN6_IS_ADDR_LINKLOCAL(in6)
|
||||||
IN6_IS_ADDR_LINKLOCAL(in6)
|
|
||||||
|| IN6_IS_ADDR_V4COMPAT(in6);
|
|| IN6_IS_ADDR_V4COMPAT(in6);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static krb5_boolean
|
||||||
|
ipv6_is_loopback (const struct sockaddr *sa)
|
||||||
|
{
|
||||||
|
const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *)sa;
|
||||||
|
const struct in6_addr *in6 = (const struct in6_addr *)&sin6->sin6_addr;
|
||||||
|
|
||||||
|
return (IN6_IS_ADDR_LOOPBACK(in6));
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ipv6_anyaddr (struct sockaddr *sa, krb5_socklen_t *sa_size, int port)
|
ipv6_anyaddr (struct sockaddr *sa, krb5_socklen_t *sa_size, int port)
|
||||||
{
|
{
|
||||||
@@ -713,8 +733,8 @@ static struct addr_operations at[] = {
|
|||||||
ipv4_addr2sockaddr,
|
ipv4_addr2sockaddr,
|
||||||
ipv4_h_addr2sockaddr,
|
ipv4_h_addr2sockaddr,
|
||||||
ipv4_h_addr2addr,
|
ipv4_h_addr2addr,
|
||||||
ipv4_uninteresting, ipv4_anyaddr, ipv4_print_addr, ipv4_parse_addr,
|
ipv4_uninteresting, ipv4_is_loopback, ipv4_anyaddr, ipv4_print_addr,
|
||||||
NULL, NULL, NULL, ipv4_mask_boundary },
|
ipv4_parse_addr, NULL, NULL, NULL, ipv4_mask_boundary },
|
||||||
#ifdef HAVE_IPV6
|
#ifdef HAVE_IPV6
|
||||||
{AF_INET6, KRB5_ADDRESS_INET6, sizeof(struct sockaddr_in6),
|
{AF_INET6, KRB5_ADDRESS_INET6, sizeof(struct sockaddr_in6),
|
||||||
ipv6_sockaddr2addr,
|
ipv6_sockaddr2addr,
|
||||||
@@ -722,18 +742,18 @@ static struct addr_operations at[] = {
|
|||||||
ipv6_addr2sockaddr,
|
ipv6_addr2sockaddr,
|
||||||
ipv6_h_addr2sockaddr,
|
ipv6_h_addr2sockaddr,
|
||||||
ipv6_h_addr2addr,
|
ipv6_h_addr2addr,
|
||||||
ipv6_uninteresting, ipv6_anyaddr, ipv6_print_addr, ipv6_parse_addr,
|
ipv6_uninteresting, ipv6_is_loopback, ipv6_anyaddr, ipv6_print_addr,
|
||||||
NULL, NULL, NULL, ipv6_mask_boundary } ,
|
ipv6_parse_addr, NULL, NULL, NULL, ipv6_mask_boundary } ,
|
||||||
#endif
|
#endif
|
||||||
#ifndef HEIMDAL_SMALLER
|
#ifndef HEIMDAL_SMALLER
|
||||||
/* fake address type */
|
/* fake address type */
|
||||||
{KRB5_ADDRESS_ARANGE, KRB5_ADDRESS_ARANGE, sizeof(struct arange),
|
{KRB5_ADDRESS_ARANGE, KRB5_ADDRESS_ARANGE, sizeof(struct arange),
|
||||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
arange_print_addr, arange_parse_addr,
|
arange_print_addr, arange_parse_addr,
|
||||||
arange_order_addr, arange_free, arange_copy },
|
arange_order_addr, arange_free, arange_copy },
|
||||||
#endif
|
#endif
|
||||||
{KRB5_ADDRESS_ADDRPORT, KRB5_ADDRESS_ADDRPORT, 0,
|
{KRB5_ADDRESS_ADDRPORT, KRB5_ADDRESS_ADDRPORT, 0,
|
||||||
NULL, NULL, NULL, NULL, NULL,
|
NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
NULL, NULL, addrport_print_addr, NULL, NULL, NULL, NULL }
|
NULL, NULL, addrport_print_addr, NULL, NULL, NULL, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -912,6 +932,15 @@ krb5_sockaddr_uninteresting(const struct sockaddr *sa)
|
|||||||
return (*a->uninteresting)(sa);
|
return (*a->uninteresting)(sa);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KRB5_LIB_FUNCTION krb5_boolean KRB5_LIB_CALL
|
||||||
|
krb5_sockaddr_is_loopback(const struct sockaddr *sa)
|
||||||
|
{
|
||||||
|
struct addr_operations *a = find_af(sa->sa_family);
|
||||||
|
if (a == NULL || a->is_loopback == NULL)
|
||||||
|
return TRUE;
|
||||||
|
return (*a->is_loopback)(sa);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* krb5_h_addr2sockaddr initializes a "struct sockaddr sa" from af and
|
* krb5_h_addr2sockaddr initializes a "struct sockaddr sa" from af and
|
||||||
* the "struct hostent" (see gethostbyname(3) ) h_addr_list
|
* the "struct hostent" (see gethostbyname(3) ) h_addr_list
|
||||||
|
@@ -82,8 +82,8 @@ gethostname_fallback (krb5_context context, krb5_addresses *res)
|
|||||||
}
|
}
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
LOOP = 1, /* do include loopback interfaces */
|
LOOP = 1, /* do include loopback addrs */
|
||||||
LOOP_IF_NONE = 2, /* include loopback if no other if's */
|
LOOP_IF_NONE = 2, /* include loopback addrs if no others */
|
||||||
EXTRA_ADDRESSES = 4, /* include extra addresses */
|
EXTRA_ADDRESSES = 4, /* include extra addresses */
|
||||||
SCAN_INTERFACES = 8 /* scan interfaces for addresses */
|
SCAN_INTERFACES = 8 /* scan interfaces for addresses */
|
||||||
};
|
};
|
||||||
@@ -146,11 +146,9 @@ find_all_addresses (krb5_context context, krb5_addresses *res, int flags)
|
|||||||
continue;
|
continue;
|
||||||
if (krb5_sockaddr_uninteresting(ifa->ifa_addr))
|
if (krb5_sockaddr_uninteresting(ifa->ifa_addr))
|
||||||
continue;
|
continue;
|
||||||
if ((ifa->ifa_flags & IFF_LOOPBACK) != 0) {
|
if (krb5_sockaddr_is_loopback(ifa->ifa_addr) && (flags & LOOP) == 0)
|
||||||
/* We'll deal with the LOOP_IF_NONE case later. */
|
/* We'll deal with the LOOP_IF_NONE case later. */
|
||||||
if ((flags & LOOP) == 0)
|
continue;
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = krb5_sockaddr2address(context, ifa->ifa_addr, &res->val[idx]);
|
ret = krb5_sockaddr2address(context, ifa->ifa_addr, &res->val[idx]);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
@@ -189,24 +187,22 @@ find_all_addresses (krb5_context context, krb5_addresses *res, int flags)
|
|||||||
continue;
|
continue;
|
||||||
if (krb5_sockaddr_uninteresting(ifa->ifa_addr))
|
if (krb5_sockaddr_uninteresting(ifa->ifa_addr))
|
||||||
continue;
|
continue;
|
||||||
|
if (!krb5_sockaddr_is_loopback(ifa->ifa_addr))
|
||||||
if ((ifa->ifa_flags & IFF_LOOPBACK) != 0) {
|
continue;
|
||||||
ret = krb5_sockaddr2address(context,
|
if ((ifa->ifa_flags & IFF_LOOPBACK) == 0)
|
||||||
ifa->ifa_addr, &res->val[idx]);
|
/* Presumably loopback addrs are only used on loopback ifs! */
|
||||||
if (ret) {
|
continue;
|
||||||
/*
|
ret = krb5_sockaddr2address(context,
|
||||||
* See comment above.
|
ifa->ifa_addr, &res->val[idx]);
|
||||||
*/
|
if (ret)
|
||||||
continue;
|
continue; /* We don't consider this failure fatal */
|
||||||
}
|
if((flags & EXTRA_ADDRESSES) &&
|
||||||
if((flags & EXTRA_ADDRESSES) &&
|
krb5_address_search(context, &res->val[idx],
|
||||||
krb5_address_search(context, &res->val[idx],
|
&ignore_addresses)) {
|
||||||
&ignore_addresses)) {
|
krb5_free_address(context, &res->val[idx]);
|
||||||
krb5_free_address(context, &res->val[idx]);
|
continue;
|
||||||
continue;
|
|
||||||
}
|
|
||||||
idx++;
|
|
||||||
}
|
}
|
||||||
|
idx++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -19,6 +19,7 @@ error_code BAD_MKEY, "Failed to get the master key"
|
|||||||
error_code SERVICE_NOMATCH, "Unacceptable service used"
|
error_code SERVICE_NOMATCH, "Unacceptable service used"
|
||||||
error_code NOT_SEEKABLE, "File descriptor not seekable"
|
error_code NOT_SEEKABLE, "File descriptor not seekable"
|
||||||
error_code TOO_BIG, "Offset too large"
|
error_code TOO_BIG, "Offset too large"
|
||||||
|
error_code BAD_HDBENT_ENCODING, "Invalid HDB entry encoding"
|
||||||
|
|
||||||
index 64
|
index 64
|
||||||
prefix HEIM_PKINIT
|
prefix HEIM_PKINIT
|
||||||
|
@@ -166,29 +166,27 @@ krb5_kt_register(krb5_context context,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static const char *
|
static const char *
|
||||||
keytab_name(const char * name, const char ** ptype, size_t * ptype_len)
|
keytab_name(const char *name, const char **type, size_t *type_len)
|
||||||
{
|
{
|
||||||
const char * residual;
|
const char *residual;
|
||||||
|
|
||||||
residual = strchr(name, ':');
|
residual = strchr(name, ':');
|
||||||
|
|
||||||
if (residual == NULL
|
if (residual == NULL ||
|
||||||
|
name[0] == '/'
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
|
||||||
/* Avoid treating <drive>:<path> as a keytab type
|
/* Avoid treating <drive>:<path> as a keytab type
|
||||||
* specification */
|
* specification */
|
||||||
|
|
||||||
|| name + 1 == residual
|
|| name + 1 == residual
|
||||||
#endif
|
#endif
|
||||||
) {
|
) {
|
||||||
|
|
||||||
*ptype = "FILE";
|
*type = "FILE";
|
||||||
*ptype_len = strlen(*ptype);
|
*type_len = strlen(*type);
|
||||||
residual = name;
|
residual = name;
|
||||||
} else {
|
} else {
|
||||||
*ptype = name;
|
*type = name;
|
||||||
*ptype_len = residual - name;
|
*type_len = residual - name;
|
||||||
residual++;
|
residual++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -850,3 +848,46 @@ krb5_kt_remove_entry(krb5_context context,
|
|||||||
}
|
}
|
||||||
return (*id->remove)(context, id, entry);
|
return (*id->remove)(context, id, entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return true if the keytab exists and have entries
|
||||||
|
*
|
||||||
|
* @param context a Keberos context.
|
||||||
|
* @param id a keytab.
|
||||||
|
*
|
||||||
|
* @return Return an error code or 0, see krb5_get_error_message().
|
||||||
|
*
|
||||||
|
* @ingroup krb5_keytab
|
||||||
|
*/
|
||||||
|
|
||||||
|
KRB5_LIB_FUNCTION krb5_boolean KRB5_LIB_CALL
|
||||||
|
krb5_kt_have_content(krb5_context context,
|
||||||
|
krb5_keytab id)
|
||||||
|
{
|
||||||
|
krb5_keytab_entry entry;
|
||||||
|
krb5_kt_cursor cursor;
|
||||||
|
krb5_error_code ret;
|
||||||
|
char *name;
|
||||||
|
|
||||||
|
ret = krb5_kt_start_seq_get(context, id, &cursor);
|
||||||
|
if (ret)
|
||||||
|
goto notfound;
|
||||||
|
|
||||||
|
ret = krb5_kt_next_entry(context, id, &entry, &cursor);
|
||||||
|
krb5_kt_end_seq_get(context, id, &cursor);
|
||||||
|
if (ret)
|
||||||
|
goto notfound;
|
||||||
|
|
||||||
|
krb5_kt_free_entry(context, &entry);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
notfound:
|
||||||
|
ret = krb5_kt_get_full_name(context, id, &name);
|
||||||
|
if (ret == 0) {
|
||||||
|
krb5_set_error_message(context, KRB5_KT_NOTFOUND,
|
||||||
|
N_("No entry in keytab: %s", ""), name);
|
||||||
|
free(name);
|
||||||
|
}
|
||||||
|
return KRB5_KT_NOTFOUND;
|
||||||
|
}
|
||||||
|
@@ -224,7 +224,8 @@ check_escaped_strings(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (*s || *e)
|
if (*s || *e)
|
||||||
errx(1, "Configuation string list for value [%s] has incorrect length.\n");
|
errx(1, "Configuation string list for value [%s] has incorrect length.",
|
||||||
|
config_strings_tests[i].name);
|
||||||
|
|
||||||
krb5_config_free_strings(ps);
|
krb5_config_free_strings(ps);
|
||||||
}
|
}
|
||||||
|
@@ -54,6 +54,10 @@ test_empty_keytab(krb5_context context, const char *keytab)
|
|||||||
|
|
||||||
krb5_kt_remove_entry(context, id, &entry);
|
krb5_kt_remove_entry(context, id, &entry);
|
||||||
|
|
||||||
|
ret = krb5_kt_have_content(context, id);
|
||||||
|
if (ret == 0)
|
||||||
|
krb5_errx(context, 1, "supposed to be empty keytab isn't");
|
||||||
|
|
||||||
ret = krb5_kt_close(context, id);
|
ret = krb5_kt_close(context, id);
|
||||||
if (ret)
|
if (ret)
|
||||||
krb5_err(context, 1, ret, "krb5_kt_close");
|
krb5_err(context, 1, ret, "krb5_kt_close");
|
||||||
|
@@ -421,6 +421,7 @@ HEIMDAL_KRB5_2.0 {
|
|||||||
krb5_kt_get_full_name;
|
krb5_kt_get_full_name;
|
||||||
krb5_kt_get_name;
|
krb5_kt_get_name;
|
||||||
krb5_kt_get_type;
|
krb5_kt_get_type;
|
||||||
|
krb5_kt_have_content;
|
||||||
krb5_kt_next_entry;
|
krb5_kt_next_entry;
|
||||||
krb5_kt_read_service_key;
|
krb5_kt_read_service_key;
|
||||||
krb5_kt_register;
|
krb5_kt_register;
|
||||||
|
@@ -16,11 +16,15 @@ lib_LTLIBRARIES = libotp.la
|
|||||||
libotp_la_LDFLAGS = -version-info 1:5:1
|
libotp_la_LDFLAGS = -version-info 1:5:1
|
||||||
libotp_la_LIBADD = $(LIB_hcrypto) $(LIB_roken) $(LIB_NDBM)
|
libotp_la_LIBADD = $(LIB_hcrypto) $(LIB_roken) $(LIB_NDBM)
|
||||||
|
|
||||||
|
if HAVE_DB1
|
||||||
|
ndbm_wrap = ndbm_wrap.c ndbm_wrap.h
|
||||||
|
else
|
||||||
if HAVE_DB3
|
if HAVE_DB3
|
||||||
ndbm_wrap = ndbm_wrap.c ndbm_wrap.h
|
ndbm_wrap = ndbm_wrap.c ndbm_wrap.h
|
||||||
else
|
else
|
||||||
ndbm_wrap =
|
ndbm_wrap =
|
||||||
endif
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
dist_libotp_la_SOURCES = \
|
dist_libotp_la_SOURCES = \
|
||||||
otp.c \
|
otp.c \
|
||||||
|
@@ -932,6 +932,7 @@ strptime (const char *, const char *, struct tm *);
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef HAVE_GETTIMEOFDAY
|
#ifndef HAVE_GETTIMEOFDAY
|
||||||
|
#define gettimeofday rk_gettimeofday
|
||||||
ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL
|
ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL
|
||||||
gettimeofday (struct timeval *, void *);
|
gettimeofday (struct timeval *, void *);
|
||||||
#endif
|
#endif
|
||||||
|
Reference in New Issue
Block a user