1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-23 17:34:34 +03:00

r19681: Update to current lorikeet-heimdal. I'm looking at using the realm

lookup plugin, the new PAC validation code as well as Heimdal's SPNEGO
implementation.

Andrew Bartlett
(This used to be commit 05421f45ed)
This commit is contained in:
Andrew Bartlett 2006-11-13 03:19:59 +00:00 committed by Gerald (Jerry) Carter
parent 9d7856122e
commit 5a6288f458
23 changed files with 992 additions and 146 deletions

View File

@ -186,7 +186,6 @@ krb5_error_code
_kdc_pk_check_client (
krb5_context /*context*/,
krb5_kdc_configuration */*config*/,
krb5_principal /*client_princ*/,
const hdb_entry_ex */*client*/,
pk_client_params */*client_params*/,
char **/*subject_name*/);

View File

@ -33,7 +33,7 @@
#include "kdc_locl.h"
RCSID("$Id: kerberos5.c,v 1.224 2006/11/04 17:05:28 lha Exp $");
RCSID("$Id: kerberos5.c,v 1.225 2006/11/10 03:36:32 lha Exp $");
#define MAX_TIME ((time_t)((1U << 31) - 1))
@ -936,7 +936,6 @@ _kdc_as_rep(krb5_context context,
ret = _kdc_pk_check_client(context,
config,
client_princ,
client,
pkp,
&client_cert);

View File

@ -33,7 +33,7 @@
#include "kdc_locl.h"
RCSID("$Id: pkinit.c,v 1.73 2006/11/07 17:24:57 lha Exp $");
RCSID("$Id: pkinit.c,v 1.74 2006/11/10 03:37:43 lha Exp $");
#ifdef PKINIT
@ -1227,7 +1227,6 @@ out:
krb5_error_code
_kdc_pk_check_client(krb5_context context,
krb5_kdc_configuration *config,
krb5_principal client_princ,
const hdb_entry_ex *client,
pk_client_params *client_params,
char **subject_name)
@ -1255,7 +1254,7 @@ _kdc_pk_check_client(krb5_context context,
if (config->enable_pkinit_princ_in_cert) {
ret = pk_principal_from_X509(context, config,
client_params->cert,
client_princ);
client->entry.principal);
if (ret == 0) {
kdc_log(context, config, 5,
"Found matching PK-INIT SAN in certificate");
@ -1289,7 +1288,7 @@ _kdc_pk_check_client(krb5_context context,
krb5_boolean b;
b = krb5_principal_compare(context,
client_princ,
client->entry.principal,
principal_mappings.val[i].principal);
if (b == FALSE)
continue;

View File

@ -3,7 +3,7 @@
#
# This might look like a com_err file, but is not
#
id "$Id: asn1_err.et,v 1.5 1998/02/16 16:17:17 joda Exp $"
id "$Id: asn1_err.et,v 1.6 2006/10/24 14:11:20 lha Exp $"
error_table asn1
prefix ASN1
@ -17,4 +17,5 @@ error_code BAD_ID, "ASN.1 identifier doesn't match expected value"
error_code BAD_LENGTH, "ASN.1 length doesn't match expected value"
error_code BAD_FORMAT, "ASN.1 badly-formatted encoding"
error_code PARSE_ERROR, "ASN.1 parse error"
error_code EXTRA_DATA, "ASN.1 extra data past end of end structure"
end

View File

@ -31,7 +31,7 @@
* SUCH DAMAGE.
*/
/* $Id: gssapi.h,v 1.5 2006/10/19 07:11:14 lha Exp $ */
/* $Id: gssapi.h,v 1.6 2006/11/10 00:39:50 lha Exp $ */
#ifndef GSSAPI_GSSAPI_H_
#define GSSAPI_GSSAPI_H_
@ -377,57 +377,6 @@ extern gss_OID GSS_SASL_DIGEST_MD5_MECHANISM;
#define GSS_S_UNSEQ_TOKEN (1ul << (GSS_C_SUPPLEMENTARY_OFFSET + 3))
#define GSS_S_GAP_TOKEN (1ul << (GSS_C_SUPPLEMENTARY_OFFSET + 4))
/*
* From RFC1964:
*
* 4.1.1. Non-Kerberos-specific codes
*/
#define GSS_KRB5_S_G_BAD_SERVICE_NAME 1
/* "No @ in SERVICE-NAME name string" */
#define GSS_KRB5_S_G_BAD_STRING_UID 2
/* "STRING-UID-NAME contains nondigits" */
#define GSS_KRB5_S_G_NOUSER 3
/* "UID does not resolve to username" */
#define GSS_KRB5_S_G_VALIDATE_FAILED 4
/* "Validation error" */
#define GSS_KRB5_S_G_BUFFER_ALLOC 5
/* "Couldn't allocate gss_buffer_t data" */
#define GSS_KRB5_S_G_BAD_MSG_CTX 6
/* "Message context invalid" */
#define GSS_KRB5_S_G_WRONG_SIZE 7
/* "Buffer is the wrong size" */
#define GSS_KRB5_S_G_BAD_USAGE 8
/* "Credential usage type is unknown" */
#define GSS_KRB5_S_G_UNKNOWN_QOP 9
/* "Unknown quality of protection specified" */
/*
* 4.1.2. Kerberos-specific-codes
*/
#define GSS_KRB5_S_KG_CCACHE_NOMATCH 10
/* "Principal in credential cache does not match desired name" */
#define GSS_KRB5_S_KG_KEYTAB_NOMATCH 11
/* "No principal in keytab matches desired name" */
#define GSS_KRB5_S_KG_TGT_MISSING 12
/* "Credential cache has no TGT" */
#define GSS_KRB5_S_KG_NO_SUBKEY 13
/* "Authenticator has no subkey" */
#define GSS_KRB5_S_KG_CONTEXT_ESTABLISHED 14
/* "Context is already fully established" */
#define GSS_KRB5_S_KG_BAD_SIGN_TYPE 15
/* "Unknown signature type in token" */
#define GSS_KRB5_S_KG_BAD_LENGTH 16
/* "Invalid field length in token" */
#define GSS_KRB5_S_KG_CTX_INCOMPLETE 17
/* "Attempt to use incomplete security context" */
/*
* This is used to make sure mechs that don't want to have external
* references don't get any prototypes, and thus can get warnings.
*/
/*
* Finally, function prototypes for the GSS-API routines.
*/

View File

@ -31,7 +31,7 @@
* SUCH DAMAGE.
*/
/* $Id: gssapi_krb5.h,v 1.14 2006/11/08 23:01:01 lha Exp $ */
/* $Id: gssapi_krb5.h,v 1.17 2006/11/10 01:05:34 lha Exp $ */
#ifndef GSSAPI_KRB5_H_
#define GSSAPI_KRB5_H_
@ -78,6 +78,7 @@ extern gss_OID GSS_KRB5_GET_AUTHTIME_X;
extern gss_OID GSS_KRB5_GET_SERVICE_KEYBLOCK_X;
/* Extensions creds */
extern gss_OID GSS_KRB5_IMPORT_CRED_X;
extern gss_OID GSS_KRB5_SET_ALLOWABLE_ENCTYPES_X;
/*
* kerberos mechanism specific functions
@ -205,6 +206,11 @@ gss_krb5_free_lucid_sec_context(OM_uint32 *minor_status,
void *kctx);
OM_uint32
gss_krb5_set_allowable_enctypes(OM_uint32 *minor_status,
gss_cred_id_t cred,
OM_uint32 num_enctypes,
int32_t *enctypes);
#ifdef __cplusplus
}

View File

@ -0,0 +1,30 @@
#
# extended gss krb5 error messages
#
id "$Id: gkrb5_err.et,v 1.1 2006/11/09 23:52:17 lha Exp $"
error_table gk5
prefix GSS_KRB5_S
error_code G_BAD_SERVICE_NAME, "No @ in SERVICE-NAME name string"
error_code G_BAD_STRING_UID, "STRING-UID-NAME contains nondigits"
error_code G_NOUSER, "UID does not resolve to username"
error_code G_VALIDATE_FAILED, "Validation error"
error_code G_BUFFER_ALLOC, "Couldn't allocate gss_buffer_t data"
error_code G_BAD_MSG_CTX, "Message context invalid"
error_code G_WRONG_SIZE, "Buffer is the wrong size"
error_code G_BAD_USAGE, "Credential usage type is unknown"
error_code G_UNKNOWN_QOP, "Unknown quality of protection specified"
index 128
error_code KG_CCACHE_NOMATCH, "Principal in credential cache does not match desired name"
error_code KG_KEYTAB_NOMATCH, "No principal in keytab matches desired name"
error_code KG_TGT_MISSING, "Credential cache has no TGT"
error_code KG_NO_SUBKEY, "Authenticator has no subkey"
error_code KG_CONTEXT_ESTABLISHED, "Context is already fully established"
error_code KG_BAD_SIGN_TYPE, "Unknown signature type in token"
error_code KG_BAD_LENGTH, "Invalid field length in token"
error_code KG_CTX_INCOMPLETE, "Attempt to use incomplete security context"

View File

@ -31,7 +31,7 @@
* SUCH DAMAGE.
*/
/* $Id: gsskrb5_locl.h,v 1.7 2006/11/07 17:57:43 lha Exp $ */
/* $Id: gsskrb5_locl.h,v 1.8 2006/11/10 00:36:40 lha Exp $ */
#ifndef GSSKRB5_LOCL_H
#define GSSKRB5_LOCL_H
@ -41,6 +41,7 @@
#endif
#include <krb5_locl.h>
#include <gkrb5_err.h>
#include <gssapi.h>
#include <gssapi_mech.h>
#include <assert.h>

View File

@ -27,7 +27,108 @@
*/
#include "mech_locl.h"
RCSID("$Id: gss_accept_sec_context.c,v 1.6 2006/10/25 00:45:12 lha Exp $");
RCSID("$Id: gss_accept_sec_context.c,v 1.7 2006/11/10 03:30:12 lha Exp $");
static OM_uint32
parse_header(const gss_buffer_t input_token, gss_OID mech_oid)
{
unsigned char *p = input_token->value;
size_t len = input_token->length;
size_t a, b;
/*
* Token must start with [APPLICATION 0] SEQUENCE.
* But if it doesn't assume its DCE-STYLE Kerberos!
*/
if (len == 0)
return (GSS_S_DEFECTIVE_TOKEN);
p++;
len--;
/*
* Decode the length and make sure it agrees with the
* token length.
*/
if (len == 0)
return (GSS_S_DEFECTIVE_TOKEN);
if ((*p & 0x80) == 0) {
a = *p;
p++;
len--;
} else {
b = *p & 0x7f;
p++;
len--;
if (len < b)
return (GSS_S_DEFECTIVE_TOKEN);
a = 0;
while (b) {
a = (a << 8) | *p;
p++;
len--;
b--;
}
}
if (a != len)
return (GSS_S_DEFECTIVE_TOKEN);
/*
* Decode the OID for the mechanism. Simplify life by
* assuming that the OID length is less than 128 bytes.
*/
if (len < 2 || *p != 0x06)
return (GSS_S_DEFECTIVE_TOKEN);
if ((p[1] & 0x80) || p[1] > (len - 2))
return (GSS_S_DEFECTIVE_TOKEN);
mech_oid->length = p[1];
p += 2;
len -= 2;
mech_oid->elements = p;
return GSS_S_COMPLETE;
}
static gss_OID_desc krb5_mechanism =
{9, rk_UNCONST("\x2a\x86\x48\x86\xf7\x12\x01\x02\x02")};
static gss_OID_desc spnego_mechanism =
{6, rk_UNCONST("\x2b\x06\x01\x05\x05\x02")};
static OM_uint32
choose_mech(const gss_buffer_t input, gss_OID mech_oid)
{
OM_uint32 status;
/*
* First try to parse the gssapi token header and see if its a
* correct header, use that in the first hand.
*/
status = parse_header(input, mech_oid);
if (status == GSS_S_COMPLETE)
return GSS_S_COMPLETE;
/*
* Lets guess what mech is really is, callback function to mech ??
*/
if (input->length != 0 && ((const char *)input->value)[0] == 0x6E) {
/* Could be a raw AP-REQ (check for APPLICATION tag) */
*mech_oid = krb5_mechanism;
return GSS_S_COMPLETE;
} else if (input->length == 0) {
/*
* There is the a wiered mode of SPNEGO (in CIFS and
* SASL GSS-SPENGO where the first token is zero
* length and the acceptor returns a mech_list, lets
* home that is what is happening now.
*/
*mech_oid = spnego_mechanism;
return GSS_S_COMPLETE;
}
return status;
}
OM_uint32 gss_accept_sec_context(OM_uint32 *minor_status,
gss_ctx_id_t *context_handle,
@ -64,64 +165,12 @@ OM_uint32 gss_accept_sec_context(OM_uint32 *minor_status,
* parse the input token to figure out the mechanism to use.
*/
if (*context_handle == GSS_C_NO_CONTEXT) {
unsigned char *p = input_token->value;
size_t len = input_token->length;
size_t a, b;
gss_OID_desc mech_oid;
/*
* Token must start with [APPLICATION 0] SEQUENCE.
* But if it doesn't assume its DCE-STYLE Kerberos!
* And if it's not there at all, then we are requesting a mech list from SPNEGO
*/
if (len == 0) {
mech_oid = *GSS_SPNEGO_MECHANISM;
} else if (*p != 0x60) {
mech_oid = *GSS_KRB5_MECHANISM;
} else {
p++;
len--;
/*
* Decode the length and make sure it agrees with the
* token length.
*/
if (len == 0)
return (GSS_S_DEFECTIVE_TOKEN);
if ((*p & 0x80) == 0) {
a = *p;
p++;
len--;
} else {
b = *p & 0x7f;
p++;
len--;
if (len < b)
return (GSS_S_DEFECTIVE_TOKEN);
a = 0;
while (b) {
a = (a << 8) | *p;
p++;
len--;
b--;
}
}
if (a != len)
return (GSS_S_DEFECTIVE_TOKEN);
/*
* Decode the OID for the mechanism. Simplify life by
* assuming that the OID length is less than 128 bytes.
*/
if (len < 2 || *p != 0x06)
return (GSS_S_DEFECTIVE_TOKEN);
if ((p[1] & 0x80) || p[1] > (len - 2))
return (GSS_S_DEFECTIVE_TOKEN);
mech_oid.length = p[1];
p += 2;
len -= 2;
mech_oid.elements = p;
}
major_status = choose_mech(input_token, &mech_oid);
if (major_status != GSS_S_COMPLETE)
return major_status;
/*
* Now that we have a mechanism, we can find the
* implementation.

View File

@ -27,7 +27,7 @@
*/
#include "mech_locl.h"
RCSID("$Id: gss_krb5.c,v 1.20 2006/11/08 23:11:03 lha Exp $");
RCSID("$Id: gss_krb5.c,v 1.21 2006/11/10 00:57:27 lha Exp $");
#include <krb5.h>
#include <roken.h>
@ -421,13 +421,41 @@ gss_krb5_free_lucid_sec_context(OM_uint32 *minor_status, void *c)
*/
OM_uint32
gss_krb5_set_allowable_enctypes(OM_uint32 *minor_status,
gss_krb5_set_allowable_enctypes(OM_uint32 *min_status,
gss_cred_id_t cred,
OM_uint32 num_enctypes,
krb5_enctype *enctypes)
int32_t *enctypes)
{
*minor_status = 0;
return GSS_S_COMPLETE;
OM_uint32 maj_status;
gss_buffer_desc buffer;
krb5_storage *sp;
krb5_data data;
sp = krb5_storage_emem();
if (sp == NULL) {
*min_status = ENOMEM;
maj_status = GSS_S_FAILURE;
goto out;
}
while(*enctypes) {
krb5_store_int32(sp, *enctypes);
enctypes++;
}
krb5_storage_to_data(sp, &data);
buffer.value = data.data;
buffer.length = data.length;
maj_status = gss_set_cred_option(min_status,
&cred,
GSS_KRB5_SET_ALLOWABLE_ENCTYPES_X,
&buffer);
out:
if (sp)
krb5_storage_free(sp);
return maj_status;
}
/*

View File

@ -299,6 +299,37 @@ _krb5_oid_to_enctype (
const heim_oid */*oid*/,
krb5_enctype */*etype*/);
void
_krb5_pac_free (
krb5_context /*context*/,
struct krb5_pac */*pac*/);
krb5_error_code
_krb5_pac_parse (
krb5_context /*context*/,
const void */*ptr*/,
size_t /*len*/,
struct krb5_pac **/*pac*/);
krb5_error_code
_krb5_pac_sign (
krb5_context /*context*/,
struct krb5_pac */*p*/,
time_t /*authtime*/,
krb5_principal /*principal*/,
krb5_keyblock */*server_key*/,
krb5_keyblock */*priv_key*/,
krb5_data */*data*/);
krb5_error_code
_krb5_pac_verify (
krb5_context /*context*/,
struct krb5_pac */*pac*/,
time_t /*authtime*/,
krb5_principal /*principal*/,
krb5_keyblock */*server*/,
krb5_keyblock */*privsvr*/);
krb5_error_code
_krb5_parse_moduli (
krb5_context /*context*/,
@ -380,6 +411,29 @@ _krb5_pk_verify_sign (
krb5_data */*content*/,
struct krb5_pk_cert **/*signer*/);
krb5_error_code
_krb5_plugin_find (
krb5_context /*context*/,
enum plugin_type /*type*/,
const char */*name*/,
struct krb5_plugin **/*list*/);
void
_krb5_plugin_free (struct krb5_plugin */*list*/);
struct krb5_plugin *
_krb5_plugin_get_next (struct krb5_plugin */*p*/);
void *
_krb5_plugin_get_symbol (struct krb5_plugin */*p*/);
krb5_error_code
_krb5_plugin_register (
krb5_context /*context*/,
enum plugin_type /*type*/,
const char */*name*/,
void */*symbol*/);
krb5_error_code KRB5_LIB_FUNCTION
_krb5_principal2principalname (
PrincipalName */*p*/,

View File

@ -498,6 +498,12 @@ krb5_c_is_coll_proof_cksum (krb5_cksumtype /*ctype*/);
krb5_boolean KRB5_LIB_FUNCTION
krb5_c_is_keyed_cksum (krb5_cksumtype /*ctype*/);
krb5_error_code KRB5_LIB_FUNCTION
krb5_c_keylength (
krb5_context /*context*/,
krb5_enctype /*enctype*/,
size_t */*len*/);
krb5_error_code KRB5_LIB_FUNCTION
krb5_c_make_checksum (
krb5_context /*context*/,
@ -2165,6 +2171,9 @@ krb5_get_krbhst (
const krb5_realm */*realm*/,
char ***/*hostlist*/);
time_t KRB5_LIB_FUNCTION
krb5_get_max_time_skew (krb5_context /*context*/);
krb5_error_code KRB5_LIB_FUNCTION
krb5_get_pw_salt (
krb5_context /*context*/,
@ -2177,9 +2186,6 @@ krb5_get_server_rcache (
const krb5_data */*piece*/,
krb5_rcache */*id*/);
time_t KRB5_LIB_FUNCTION
krb5_get_time_wrap (krb5_context /*context*/);
krb5_boolean KRB5_LIB_FUNCTION
krb5_get_use_admin_kdc (krb5_context /*context*/);
@ -3165,6 +3171,11 @@ krb5_set_ignore_addresses (
krb5_context /*context*/,
const krb5_addresses */*addresses*/);
void KRB5_LIB_FUNCTION
krb5_set_max_time_skew (
krb5_context /*context*/,
time_t /*t*/);
krb5_error_code KRB5_LIB_FUNCTION
krb5_set_password (
krb5_context /*context*/,
@ -3197,11 +3208,6 @@ krb5_set_send_to_kdc_func (
krb5_send_to_kdc_func /*func*/,
void */*data*/);
void KRB5_LIB_FUNCTION
krb5_set_time_wrap (
krb5_context /*context*/,
time_t /*t*/);
void KRB5_LIB_FUNCTION
krb5_set_use_admin_kdc (
krb5_context /*context*/,
@ -3271,6 +3277,11 @@ krb5_storage_from_mem (
void */*buf*/,
size_t /*len*/);
krb5_storage * KRB5_LIB_FUNCTION
krb5_storage_from_readonly_mem (
const void */*buf*/,
size_t /*len*/);
krb5_flags KRB5_LIB_FUNCTION
krb5_storage_get_byteorder (
krb5_storage */*sp*/,

View File

@ -31,7 +31,7 @@
* SUCH DAMAGE.
*/
/* $Id: krb5.h,v 1.254 2006/11/07 00:17:42 lha Exp $ */
/* $Id: krb5.h,v 1.255 2006/11/12 08:33:07 lha Exp $ */
#ifndef __KRB5_H__
#define __KRB5_H__
@ -78,6 +78,8 @@ typedef struct krb5_get_creds_opt_data *krb5_get_creds_opt;
struct krb5_digest;
typedef struct krb5_digest *krb5_digest;
struct krb5_pac;
typedef struct krb5_rd_req_in_ctx *krb5_rd_req_in_ctx;
typedef struct krb5_rd_req_out_ctx *krb5_rd_req_out_ctx;

View File

@ -148,6 +148,12 @@ struct krb5_dh_moduli;
/* v4 glue */
struct _krb5_krb_auth_data;
struct krb5_plugin;
enum plugin_type {
PLUGIN_TYPE_DATA = 1,
PLUGIN_TYPE_FUNC
};
#include <der.h>
#include <krb5.h>

View File

@ -33,8 +33,9 @@
#include "krb5_locl.h"
#include <resolve.h>
#include "locate_plugin.h"
RCSID("$Id: krbhst.c,v 1.57 2006/10/06 17:11:02 lha Exp $");
RCSID("$Id: krbhst.c,v 1.58 2006/11/12 20:05:20 lha Exp $");
static int
string_to_proto(const char *string)
@ -147,6 +148,7 @@ struct krb5_krbhst_data {
#define KD_FALLBACK 16
#define KD_CONFIG_EXISTS 32
#define KD_LARGE_MSG 64
#define KD_PLUGIN 128
krb5_error_code (*get_next)(krb5_context, struct krb5_krbhst_data *,
krb5_krbhst_info**);
@ -460,8 +462,8 @@ fallback_get_hosts(krb5_context context, struct krb5_krbhst_data *kd,
hi->proto = proto;
hi->port = hi->def_port = port;
hi->ai = ai;
memmove(hi->hostname, host, hostlen - 1);
hi->hostname[hostlen - 1] = '\0';
memmove(hi->hostname, host, hostlen);
hi->hostname[hostlen] = '\0';
free(host);
append_host_hostinfo(kd, hi);
kd->fallback_count++;
@ -469,6 +471,88 @@ fallback_get_hosts(krb5_context context, struct krb5_krbhst_data *kd,
return 0;
}
/*
* Fetch hosts from plugin
*/
static krb5_error_code
add_locate(void *ctx, int type, struct sockaddr *addr)
{
struct krb5_krbhst_info *hi;
struct krb5_krbhst_data *kd = ctx;
char host[NI_MAXHOST], port[NI_MAXSERV];
struct addrinfo hints, *ai;
socklen_t socklen;
size_t hostlen;
int ret;
socklen = socket_sockaddr_size(addr);
ret = getnameinfo(addr, socklen, host, sizeof(host), port, sizeof(port),
NI_NUMERICHOST|NI_NUMERICSERV);
if (ret != 0)
return 0;
memset(&hints, 0, sizeof(hints));
ret = getaddrinfo(host, port, &hints, &ai);
if (ret)
return 0;
hostlen = strlen(host);
hi = calloc(1, sizeof(*hi) + hostlen);
if(hi == NULL) {
free(host);
return ENOMEM;
}
hi->proto = krbhst_get_default_proto(kd);
hi->port = hi->def_port = socket_get_port(addr);
hi->ai = ai;
memmove(hi->hostname, host, hostlen);
hi->hostname[hostlen] = '\0';
append_host_hostinfo(kd, hi);
return 0;
}
static void
plugin_get_hosts(krb5_context context,
struct krb5_krbhst_data *kd,
enum locate_service_type type)
{
struct krb5_plugin *list, *e;
krb5_error_code ret;
ret = _krb5_plugin_find(context, PLUGIN_TYPE_DATA, "resolve", &list);
if(ret != 0 || list == NULL)
return;
kd->flags |= KD_CONFIG_EXISTS;
for (e = list; e != NULL; e = _krb5_plugin_get_next(e)) {
krb5plugin_service_locate_ftable *service;
void *ctx;
service = _krb5_plugin_get_symbol(e);
if (service->minor_version != 0)
continue;
(*service->init)(context, &ctx);
ret = (*service->lookup)(ctx, type, kd->realm, 0, 0, add_locate, kd);
(*service->fini)(ctx);
if (ret) {
krb5_set_error_string(context, "Plugin failed to lookup");
break;
}
}
_krb5_plugin_free(list);
}
/*
*
*/
static krb5_error_code
kdc_get_next(krb5_context context,
struct krb5_krbhst_data *kd,
@ -476,6 +560,13 @@ kdc_get_next(krb5_context context,
{
krb5_error_code ret;
if ((kd->flags & KD_PLUGIN) == 0) {
plugin_get_hosts(context, kd, locate_service_kdc);
kd->flags |= KD_PLUGIN;
if(get_next(kd, host))
return 0;
}
if((kd->flags & KD_CONFIG) == 0) {
config_get_hosts(context, kd, "kdc");
kd->flags |= KD_CONFIG;

View File

@ -0,0 +1,64 @@
/*
* Copyright (c) 2006 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* 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.
*
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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.
*/
/* $Id: locate_plugin.h,v 1.1 2006/11/12 19:00:03 lha Exp $ */
#ifndef HEIMDAL_KRB5_LOCATE_PLUGIN_H
#define HEIMDAL_KRB5_LOCATE_PLUGIN_H 1
#include <krb5.h>
enum locate_service_type {
locate_service_kdc = 1,
locate_service_master_kdc,
locate_service_kadmin,
locate_service_krb524,
locate_service_kpasswd
};
typedef krb5_error_code
(*krb5plugin_service_locate_lookup) (void *, enum locate_service_type,
const char *, int, int,
int (*)(void *,int,struct sockaddr *),
void *);
typedef struct krb5plugin_service_locate_ftable {
int minor_version;
krb5_error_code (*init)(krb5_context, void **);
void (*fini)(void *);
krb5plugin_service_locate_lookup lookup;
} krb5plugin_service_locate_ftable;
#endif /* HEIMDAL_KRB5_LOCATE_PLUGIN_H */

View File

@ -32,7 +32,7 @@
*/
#include "krb5_locl.h"
RCSID("$Id: mit_glue.c,v 1.8 2006/10/14 09:51:02 lha Exp $");
RCSID("$Id: mit_glue.c,v 1.9 2006/11/09 21:24:16 lha Exp $");
/*
* Glue for MIT API
@ -325,3 +325,11 @@ krb5_c_make_random_key(krb5_context context,
{
return krb5_generate_random_keyblock(context, enctype, random_key);
}
krb5_error_code KRB5_LIB_FUNCTION
krb5_c_keylength(krb5_context context,
krb5_enctype enctype,
size_t *len)
{
return krb5_enctype_keysize(context, enctype, len);
}

View File

@ -0,0 +1,242 @@
/*
* Copyright (c) 2006 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* 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.
*
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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 "krb5_locl.h"
RCSID("$Id: plugin.c,v 1.2 2006/11/12 21:39:43 lha Exp $");
#ifdef HAVE_DLFCN_H
#include <dlfcn.h>
#endif
#include <dirent.h>
struct krb5_plugin {
void *symbol;
void *dsohandle;
struct krb5_plugin *next;
};
struct plugin {
enum plugin_type type;
void *name;
void *symbol;
struct plugin *next;
};
static HEIMDAL_MUTEX plugin_mutex = HEIMDAL_MUTEX_INITIALIZER;
static struct plugin *registered = NULL;
static const char *plugin_dir = LIBDIR "/plugin/krb5";
/*
*
*/
void *
_krb5_plugin_get_symbol(struct krb5_plugin *p)
{
return p->symbol;
}
struct krb5_plugin *
_krb5_plugin_get_next(struct krb5_plugin *p)
{
return p->next;
}
/*
*
*/
static krb5_error_code
loadlib(krb5_context context,
enum plugin_type type,
const char *name,
const char *lib,
struct krb5_plugin **e)
{
*e = calloc(1, sizeof(**e));
if (*e == NULL) {
krb5_set_error_string(context, "out of memory");
return ENOMEM;
}
(*e)->dsohandle = dlopen(lib, 0);
if ((*e)->dsohandle == NULL) {
free(*e);
krb5_set_error_string(context, "Failed to load %s: %s",
lib, dlerror());
return ENOMEM;
}
/* dlsym doesn't care about the type */
(*e)->symbol = dlsym((*e)->dsohandle, name);
if ((*e)->symbol == NULL) {
dlclose((*e)->dsohandle);
free(*e);
krb5_clear_error_string(context);
return ENOMEM;
}
return 0;
}
krb5_error_code
_krb5_plugin_register(krb5_context context,
enum plugin_type type,
const char *name,
void *symbol)
{
struct plugin *e;
e = calloc(1, sizeof(*e));
if (e == NULL) {
krb5_set_error_string(context, "out of memory");
return ENOMEM;
}
e->type = type;
e->name = strdup(name);
if (e->name == NULL) {
free(e);
krb5_set_error_string(context, "out of memory");
return ENOMEM;
}
e->symbol = symbol;
HEIMDAL_MUTEX_lock(&plugin_mutex);
e->next = registered;
registered = e;
HEIMDAL_MUTEX_unlock(&plugin_mutex);
return 0;
}
krb5_error_code
_krb5_plugin_find(krb5_context context,
enum plugin_type type,
const char *name,
struct krb5_plugin **list)
{
struct krb5_plugin *e;
struct plugin *p;
krb5_error_code ret;
char *sysdirs[2] = { NULL, NULL };
char **dirs = NULL, **di;
struct dirent *entry;
char *path;
DIR *d = NULL;
*list = NULL;
HEIMDAL_MUTEX_lock(&plugin_mutex);
for (p = registered; p != NULL; p = p->next) {
if (p->type != type || strcmp(p->name, name) != 0)
continue;
e = calloc(1, sizeof(*e));
if (e == NULL) {
HEIMDAL_MUTEX_unlock(&plugin_mutex);
krb5_set_error_string(context, "out of memory");
ret = ENOMEM;
goto out;
}
e->symbol = p->symbol;
e->dsohandle = NULL;
e->next = *list;
*list = e;
}
HEIMDAL_MUTEX_unlock(&plugin_mutex);
dirs = krb5_config_get_strings(context, NULL, "libdefaults",
"plugin_dir", NULL);
if (dirs == NULL) {
sysdirs[0] = rk_UNCONST(plugin_dir);
dirs = sysdirs;
}
for (di = dirs; *di != NULL; di++) {
d = opendir(*di);
if (d == NULL)
continue;
while ((entry = readdir(d)) != NULL) {
asprintf(&path, "%s/%s", *di, entry->d_name);
if (path == NULL) {
krb5_set_error_string(context, "out of memory");
ret = ENOMEM;
goto out;
}
ret = loadlib(context, type, name, path, &e);
free(path);
if (ret)
continue;
e->next = *list;
*list = e;
}
closedir(d);
}
if (dirs != sysdirs)
krb5_config_free_strings(dirs);
if (*list == NULL) {
krb5_set_error_string(context, "Did not find a plugin for %s", name);
return ENOENT;
}
return 0;
out:
if (dirs && dirs != sysdirs)
krb5_config_free_strings(dirs);
if (d)
closedir(d);
_krb5_plugin_free(*list);
*list = NULL;
return ret;
}
void
_krb5_plugin_free(struct krb5_plugin *list)
{
struct krb5_plugin *next;
while (list) {
next = list->next;
if (list->dsohandle)
dlclose(list->dsohandle);
free(list);
list = next;
}
}

View File

@ -0,0 +1,302 @@
/*
* Copyright (c) 1999 - 2000 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* 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.
*
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
RCSID("$Id: socket.c,v 1.11 2005/09/01 18:48:17 lha Exp $");
#endif
#include <roken.h>
#include <err.h>
/*
* Set `sa' to the unitialized address of address family `af'
*/
void ROKEN_LIB_FUNCTION
socket_set_any (struct sockaddr *sa, int af)
{
switch (af) {
case AF_INET : {
struct sockaddr_in *sin4 = (struct sockaddr_in *)sa;
memset (sin4, 0, sizeof(*sin4));
sin4->sin_family = AF_INET;
sin4->sin_port = 0;
sin4->sin_addr.s_addr = INADDR_ANY;
break;
}
#ifdef HAVE_IPV6
case AF_INET6 : {
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
memset (sin6, 0, sizeof(*sin6));
sin6->sin6_family = AF_INET6;
sin6->sin6_port = 0;
sin6->sin6_addr = in6addr_any;
break;
}
#endif
default :
errx (1, "unknown address family %d", sa->sa_family);
break;
}
}
/*
* set `sa' to (`ptr', `port')
*/
void ROKEN_LIB_FUNCTION
socket_set_address_and_port (struct sockaddr *sa, const void *ptr, int port)
{
switch (sa->sa_family) {
case AF_INET : {
struct sockaddr_in *sin4 = (struct sockaddr_in *)sa;
memset (sin4, 0, sizeof(*sin4));
sin4->sin_family = AF_INET;
sin4->sin_port = port;
memcpy (&sin4->sin_addr, ptr, sizeof(struct in_addr));
break;
}
#ifdef HAVE_IPV6
case AF_INET6 : {
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
memset (sin6, 0, sizeof(*sin6));
sin6->sin6_family = AF_INET6;
sin6->sin6_port = port;
memcpy (&sin6->sin6_addr, ptr, sizeof(struct in6_addr));
break;
}
#endif
default :
errx (1, "unknown address family %d", sa->sa_family);
break;
}
}
/*
* Return the size of an address of the type in `sa'
*/
size_t ROKEN_LIB_FUNCTION
socket_addr_size (const struct sockaddr *sa)
{
switch (sa->sa_family) {
case AF_INET :
return sizeof(struct in_addr);
#ifdef HAVE_IPV6
case AF_INET6 :
return sizeof(struct in6_addr);
#endif
default :
errx (1, "unknown address family %d", sa->sa_family);
break;
}
}
/*
* Return the size of a `struct sockaddr' in `sa'.
*/
size_t ROKEN_LIB_FUNCTION
socket_sockaddr_size (const struct sockaddr *sa)
{
switch (sa->sa_family) {
case AF_INET :
return sizeof(struct sockaddr_in);
#ifdef HAVE_IPV6
case AF_INET6 :
return sizeof(struct sockaddr_in6);
#endif
default :
errx (1, "unknown address family %d", sa->sa_family);
break;
}
}
/*
* Return the binary address of `sa'.
*/
void * ROKEN_LIB_FUNCTION
socket_get_address (struct sockaddr *sa)
{
switch (sa->sa_family) {
case AF_INET : {
struct sockaddr_in *sin4 = (struct sockaddr_in *)sa;
return &sin4->sin_addr;
}
#ifdef HAVE_IPV6
case AF_INET6 : {
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
return &sin6->sin6_addr;
}
#endif
default :
errx (1, "unknown address family %d", sa->sa_family);
break;
}
}
/*
* Return the port number from `sa'.
*/
int ROKEN_LIB_FUNCTION
socket_get_port (const struct sockaddr *sa)
{
switch (sa->sa_family) {
case AF_INET : {
const struct sockaddr_in *sin4 = (const struct sockaddr_in *)sa;
return sin4->sin_port;
}
#ifdef HAVE_IPV6
case AF_INET6 : {
const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *)sa;
return sin6->sin6_port;
}
#endif
default :
errx (1, "unknown address family %d", sa->sa_family);
break;
}
}
/*
* Set the port in `sa' to `port'.
*/
void ROKEN_LIB_FUNCTION
socket_set_port (struct sockaddr *sa, int port)
{
switch (sa->sa_family) {
case AF_INET : {
struct sockaddr_in *sin4 = (struct sockaddr_in *)sa;
sin4->sin_port = port;
break;
}
#ifdef HAVE_IPV6
case AF_INET6 : {
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
sin6->sin6_port = port;
break;
}
#endif
default :
errx (1, "unknown address family %d", sa->sa_family);
break;
}
}
/*
* Set the range of ports to use when binding with port = 0.
*/
void ROKEN_LIB_FUNCTION
socket_set_portrange (int sock, int restr, int af)
{
#if defined(IP_PORTRANGE)
if (af == AF_INET) {
int on = restr ? IP_PORTRANGE_HIGH : IP_PORTRANGE_DEFAULT;
if (setsockopt (sock, IPPROTO_IP, IP_PORTRANGE, &on,
sizeof(on)) < 0)
warn ("setsockopt IP_PORTRANGE (ignored)");
}
#endif
#if defined(IPV6_PORTRANGE)
if (af == AF_INET6) {
int on = restr ? IPV6_PORTRANGE_HIGH :
IPV6_PORTRANGE_DEFAULT;
if (setsockopt (sock, IPPROTO_IPV6, IPV6_PORTRANGE, &on,
sizeof(on)) < 0)
warn ("setsockopt IPV6_PORTRANGE (ignored)");
}
#endif
}
/*
* Enable debug on `sock'.
*/
void ROKEN_LIB_FUNCTION
socket_set_debug (int sock)
{
#if defined(SO_DEBUG) && defined(HAVE_SETSOCKOPT)
int on = 1;
if (setsockopt (sock, SOL_SOCKET, SO_DEBUG, (void *) &on, sizeof (on)) < 0)
warn ("setsockopt SO_DEBUG (ignored)");
#endif
}
/*
* Set the type-of-service of `sock' to `tos'.
*/
void ROKEN_LIB_FUNCTION
socket_set_tos (int sock, int tos)
{
#if defined(IP_TOS) && defined(HAVE_SETSOCKOPT)
if (setsockopt (sock, IPPROTO_IP, IP_TOS, (void *) &tos, sizeof (int)) < 0)
if (errno != EINVAL)
warn ("setsockopt TOS (ignored)");
#endif
}
/*
* set the reuse of addresses on `sock' to `val'.
*/
void ROKEN_LIB_FUNCTION
socket_set_reuseaddr (int sock, int val)
{
#if defined(SO_REUSEADDR) && defined(HAVE_SETSOCKOPT)
if(setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *)&val,
sizeof(val)) < 0)
err (1, "setsockopt SO_REUSEADDR");
#endif
}
/*
* Set the that the `sock' should bind to only IPv6 addresses.
*/
void ROKEN_LIB_FUNCTION
socket_set_ipv6only (int sock, int val)
{
#if defined(IPV6_V6ONLY) && defined(HAVE_SETSOCKOPT)
setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&val, sizeof(val));
#endif
}

View File

@ -251,6 +251,7 @@ OBJ_FILES = \
../heimdal/lib/krb5/n-fold.o \
../heimdal/lib/krb5/padata.o \
../heimdal/lib/krb5/pkinit.o \
../heimdal/lib/krb5/plugin.o \
../heimdal/lib/krb5/principal.o \
../heimdal/lib/krb5/rd_cred.o \
../heimdal/lib/krb5/rd_error.o \
@ -427,6 +428,7 @@ OBJ_FILES = \
../heimdal/lib/roken/issuid.o \
../heimdal/lib/roken/net_read.o \
../heimdal/lib/roken/net_write.o \
../heimdal/lib/roken/socket.o \
../heimdal/lib/roken/parse_time.o \
../heimdal/lib/roken/parse_units.o \
../heimdal/lib/roken/resolve.o \
@ -542,11 +544,12 @@ include perl_path_wrapper.sh asn1_deps.pl heimdal/lib/gssapi/mech/gssapi.asn1 gs
include perl_path_wrapper.sh asn1_deps.pl heimdal/lib/asn1/k5.asn1 krb5_asn1 --encode-rfc1510-bit-string --sequence=KRB5SignedPathPrincipals --sequence=AuthorizationData|
include perl_path_wrapper.sh asn1_deps.pl heimdal/lib/asn1/digest.asn1 digest_asn1|
include perl_path_wrapper.sh et_deps.pl heimdal/lib/asn1/asn1_err.et|
include perl_path_wrapper.sh et_deps.pl heimdal/lib/hdb/hdb_err.et|
include perl_path_wrapper.sh et_deps.pl heimdal/lib/krb5/heim_err.et|
include perl_path_wrapper.sh et_deps.pl heimdal/lib/krb5/k524_err.et|
include perl_path_wrapper.sh et_deps.pl heimdal/lib/krb5/krb5_err.et|
include perl_path_wrapper.sh et_deps.pl heimdal/lib/asn1/asn1_err.et heimdal/lib/asn1|
include perl_path_wrapper.sh et_deps.pl heimdal/lib/hdb/hdb_err.et heimdal/lib/hdb|
include perl_path_wrapper.sh et_deps.pl heimdal/lib/krb5/heim_err.et heimdal/lib/krb5|
include perl_path_wrapper.sh et_deps.pl heimdal/lib/krb5/k524_err.et heimdal/lib/krb5|
include perl_path_wrapper.sh et_deps.pl heimdal/lib/krb5/krb5_err.et heimdal/lib/krb5|
include perl_path_wrapper.sh et_deps.pl heimdal/lib/gssapi/krb5/gkrb5_err.et heimdal/lib/gssapi|
.SUFFIXES: .hin
.hin.h:

View File

@ -3,11 +3,11 @@
use File::Basename;
my $file = shift;
my $dirname = dirname($file);
my $dirname = shift;
my $basename = basename($file);
my $header = $file; $header =~ s/\.et$/.h/;
my $source = $file; $source =~ s/\.et$/.c/;
my $header = "$dirname/$basename"; $header =~ s/\.et$/.h/;
my $source = "$dirname/$basename"; $source =~ s/\.et$/.c/;
print "$header $source: $file bin/compile_et\n";
print "\t\@echo \"Compiling error table $file\"\n";
print "\t\@cd $dirname && ../../../bin/compile_et $basename\n\n";
print "\t\@startdir=`pwd` && cd $dirname && " . '$$startdir/bin/compile_et $$startdir/' . "$file\n\n";

View File

@ -9,6 +9,7 @@
/* HDB module dir - set to Samba LIBDIR/hdb ? */
#define HDBDIR "/usr/heimdal/lib"
#define LIBDIR "/usr/heimdal/lib"
/* Maximum values on all known systems */
#define MaxHostNameLen (64+4)

View File

@ -29,6 +29,7 @@ heimdal_basics: \
heimdal/lib/krb5/heim_err.h \
heimdal/lib/krb5/k524_err.h \
heimdal/lib/krb5/krb5_err.h \
heimdal/lib/gssapi/gkrb5_err.h \
heimdal/lib/des/hcrypto
proto: basics