kdc: add accessor functions for KDC request structure

Add accessor functions for use by Samba and other plugin developers.
Documentation is in kdc/kdc-accessors.h.
This commit is contained in:
Luke Howard
2022-01-20 09:15:24 +11:00
parent ed4fe65794
commit ec24edf700
12 changed files with 773 additions and 134 deletions

View File

@@ -133,6 +133,7 @@ CLEANFILES = \
wind.h \
wind_err.h \
kdc-plugin.h \
kdc-accessors.h \
kdc-audit.h \
csr_authorizer_plugin.h \
gss_preauth_authorizer_plugin.h \

View File

@@ -244,7 +244,7 @@ include_HEADERS = kdc.h $(srcdir)/kdc-protos.h
noinst_HEADERS = $(srcdir)/kdc-private.h
krb5dir = $(includedir)/krb5
krb5_HEADERS = kdc-audit.h kdc-plugin.h token_validator_plugin.h csr_authorizer_plugin.h gss_preauth_authorizer_plugin.h
krb5_HEADERS = kdc-audit.h kdc-plugin.h kdc-accessors.h token_validator_plugin.h csr_authorizer_plugin.h gss_preauth_authorizer_plugin.h
build_HEADERZ = $(krb5_HEADERS) # XXX

View File

@@ -52,7 +52,8 @@ INCFILES=\
$(INCDIR)\kdc-protos.h \
$(INCDIR)\kdc-private.h \
$(INCDIR)\krb5\kdc-audit.h \
$(INCDIR)\krb5\kdc-plugin.h
$(INCDIR)\krb5\kdc-plugin.h \
$(INCDIR)\krb5\kdc-accessors.h
all:: $(INCFILES) $(LIBKDC) $(BINPROGRAMS) $(SBINPROGRAMS) $(LIBEXECPROGRAMS)

View File

@@ -397,7 +397,10 @@ authorize(void *ctx,
struct altsecid_gss_preauth_authorizer_context *c = ctx;
struct ad_server_tuple *server = NULL;
krb5_error_code ret;
krb5_const_realm realm = krb5_principal_get_realm(r->context, r->client->principal);
krb5_context context = kdc_request_get_context((kdc_request_t)r);
const hdb_entry *client = kdc_request_get_client(r);
krb5_const_principal server_princ = kdc_request_get_server_princ(r);
krb5_const_realm realm = krb5_principal_get_realm(context, client->principal);
krb5_boolean reconnect_p = FALSE;
krb5_boolean is_tgs;
heim_data_t requestor_sid = NULL;
@@ -405,11 +408,11 @@ authorize(void *ctx,
*authorized = FALSE;
*mapped_name = NULL;
if (!krb5_principal_is_federated(r->context, r->client->principal) ||
if (!krb5_principal_is_federated(context, client->principal) ||
(ret_flags & GSS_C_ANON_FLAG))
return KRB5_PLUGIN_NO_HANDLE;
is_tgs = krb5_principal_is_krbtgt(r->context, r->server_princ);
is_tgs = krb5_principal_is_krbtgt(context, server_princ);
HEIM_TAILQ_FOREACH(server, &c->servers, link) {
if (strcmp(realm, server->realm) == 0)
@@ -419,12 +422,12 @@ authorize(void *ctx,
if (server == NULL) {
server = calloc(1, sizeof(*server));
if (server == NULL)
return krb5_enomem(r->context);
return krb5_enomem(context);
server->realm = strdup(realm);
if (server->realm == NULL) {
free(server);
return krb5_enomem(r->context);
return krb5_enomem(context);
}
HEIM_TAILQ_INSERT_HEAD(&c->servers, server, link);
@@ -432,12 +435,12 @@ authorize(void *ctx,
do {
if (server->ld == NULL) {
ret = ad_connect(r->context, realm, server);
ret = ad_connect(context, realm, server);
if (ret)
return ret;
}
ret = ad_lookup(r->context, realm, server,
ret = ad_lookup(context, realm, server,
initiator_name, mech_type,
mapped_name, is_tgs ? &requestor_sid : NULL);
if (ret == KRB5KDC_ERR_SVC_UNAVAILABLE) {
@@ -472,8 +475,8 @@ finalize_pac(void *ctx, astgs_request_t r)
kdc_audit_setkv_object((kdc_request_t)r, "gss_requestor_sid", requestor_sid);
return krb5_pac_add_buffer(r->context, r->pac, PAC_REQUESTOR_SID,
heim_data_get_data(requestor_sid));
return kdc_request_add_pac_buffer(r, PAC_REQUESTOR_SID,
heim_data_get_data(requestor_sid));
}
static KRB5_LIB_CALL krb5_error_code

349
kdc/kdc-accessors.h Normal file
View File

@@ -0,0 +1,349 @@
/*
* Copyright (c) 2022, PADL Software Pty Ltd.
* 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 PADL Software 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 PADL SOFTWARE 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 PADL SOFTWARE 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.
*/
#ifndef HEIMDAL_KDC_KDC_ACCESSORS_H
#define HEIMDAL_KDC_KDC_ACCESSORS_H 1
/* read-only accessor */
#ifndef _KDC_REQUEST_GET_ACCESSOR
#define _KDC_REQUEST_GET_ACCESSOR(R, T, f) \
T \
kdc_request_get_ ## f(R);
#endif
#ifndef _KDC_REQUEST_SET_ACCESSOR
#define _KDC_REQUEST_SET_ACCESSOR(R, T, f) \
void \
kdc_request_set_ ## f(R, T);
#endif
#ifndef KDC_REQUEST_GET_ACCESSOR
#define KDC_REQUEST_GET_ACCESSOR(T, f) \
_KDC_REQUEST_GET_ACCESSOR(kdc_request_t, T, f)
#endif
#ifndef KDC_REQUEST_SET_ACCESSOR
#define KDC_REQUEST_SET_ACCESSOR(T, f) \
_KDC_REQUEST_SET_ACCESSOR(kdc_request_t, T, f)
#endif
#ifndef ASTGS_REQUEST_GET_ACCESSOR
#define ASTGS_REQUEST_GET_ACCESSOR(T, f) \
_KDC_REQUEST_GET_ACCESSOR(astgs_request_t, T, f)
#endif
#ifndef ASTGS_REQUEST_SET_ACCESSOR
#define ASTGS_REQUEST_SET_ACCESSOR(T, f) \
_KDC_REQUEST_SET_ACCESSOR(astgs_request_t, T, f)
#endif
/* get/set accessor for pointer type */
#ifndef _KDC_REQUEST_GET_ACCESSOR_PTR
#define _KDC_REQUEST_GET_ACCESSOR_PTR(R, T, f) \
const T \
kdc_request_get_ ## f(R);
#endif
#ifndef _KDC_REQUEST_SET_ACCESSOR_PTR
#define _KDC_REQUEST_SET_ACCESSOR_PTR(R, T, t, f) \
krb5_error_code \
kdc_request_set_ ## f(R, const T);
#endif
#ifndef KDC_REQUEST_GET_ACCESSOR_PTR
#define KDC_REQUEST_GET_ACCESSOR_PTR(T, f) \
_KDC_REQUEST_GET_ACCESSOR_PTR(kdc_request_t, T, f)
#endif
#ifndef KDC_REQUEST_SET_ACCESSOR_PTR
#define KDC_REQUEST_SET_ACCESSOR_PTR(T, t, f) \
_KDC_REQUEST_SET_ACCESSOR_PTR(kdc_request_t, T, t, f)
#endif
#ifndef ASTGS_REQUEST_GET_ACCESSOR_PTR
#define ASTGS_REQUEST_GET_ACCESSOR_PTR(T, f) \
_KDC_REQUEST_GET_ACCESSOR_PTR(astgs_request_t, T, f)
#endif
#ifndef ASTGS_REQUEST_SET_ACCESSOR_PTR
#define ASTGS_REQUEST_SET_ACCESSOR_PTR(T, t, f) \
_KDC_REQUEST_SET_ACCESSOR_PTR(astgs_request_t, T, t, f)
#endif
/* get/set accessor for struct type */
#ifndef _KDC_REQUEST_GET_ACCESSOR_STRUCT
#define _KDC_REQUEST_GET_ACCESSOR_STRUCT(R, T, f) \
const T * \
kdc_request_get_ ## f(R);
#endif
#ifndef _KDC_REQUEST_SET_ACCESSOR_STRUCT
#define _KDC_REQUEST_SET_ACCESSOR_STRUCT(R, T, t, f) \
krb5_error_code \
kdc_request_set_ ## f(R, const T *);
#endif
#ifndef KDC_REQUEST_GET_ACCESSOR_STRUCT
#define KDC_REQUEST_GET_ACCESSOR_STRUCT(T, f) \
_KDC_REQUEST_GET_ACCESSOR_STRUCT(kdc_request_t, T, f)
#endif
#ifndef KDC_REQUEST_SET_ACCESSOR_STRUCT
#define KDC_REQUEST_SET_ACCESSOR_STRUCT(T, t, f) \
_KDC_REQUEST_SET_ACCESSOR_STRUCT(kdc_request_t, T, t, f)
#endif
#ifndef ASTGS_REQUEST_GET_ACCESSOR_STRUCT
#define ASTGS_REQUEST_GET_ACCESSOR_STRUCT(T, f) \
_KDC_REQUEST_GET_ACCESSOR_STRUCT(astgs_request_t, T, f)
#endif
#ifndef ASTGS_REQUEST_SET_ACCESSOR_STRUCT
#define ASTGS_REQUEST_SET_ACCESSOR_STRUCT(T, t, f) \
_KDC_REQUEST_SET_ACCESSOR_STRUCT(astgs_request_t, T, t, f)
#endif
/*
* krb5_context
* kdc_request_get_context(kdc_request_t);
*/
KDC_REQUEST_GET_ACCESSOR(krb5_context, context)
/*
* krb5_kdc_configuration *
* kdc_request_get_config(kdc_request_t);
*/
KDC_REQUEST_GET_ACCESSOR(krb5_kdc_configuration *, config)
/*
* heim_log_facility *
* kdc_request_get_logf(kdc_request_t);
*/
KDC_REQUEST_GET_ACCESSOR(heim_log_facility *, logf)
/*
* const char *
* kdc_request_get_from(kdc_request_t);
*/
KDC_REQUEST_GET_ACCESSOR_PTR(char *, from)
/*
* const struct sockaddr *
* kdc_request_get_addr(kdc_request_t);
*/
KDC_REQUEST_GET_ACCESSOR_PTR(struct sockaddr *, addr)
/*
* krb5_data
* kdc_request_get_request(kdc_request_t);
*/
KDC_REQUEST_GET_ACCESSOR(krb5_data, request)
/*
* struct timeval
* kdc_request_get_tv_start(kdc_request_t);
*/
KDC_REQUEST_GET_ACCESSOR(struct timeval, tv_start)
/*
* struct timeval
* kdc_request_get_tv_end(kdc_request_t);
*/
KDC_REQUEST_GET_ACCESSOR(struct timeval, tv_end)
/*
* krb5_error_code
* kdc_request_get_error_code(kdc_request_t);
*/
KDC_REQUEST_GET_ACCESSOR(krb5_error_code, error_code)
/*
* void
* kdc_request_set_error_code(kdc_request_t, krb5_error_code);
*/
KDC_REQUEST_SET_ACCESSOR(krb5_error_code, error_code)
/*
* const KDC_REQ *
* kdc_request_get_req(astgs_request_t);
*/
ASTGS_REQUEST_GET_ACCESSOR_STRUCT(KDC_REQ, req)
/*
* const KDC_REP *
* kdc_request_get_rep(astgs_request_t);
*/
ASTGS_REQUEST_GET_ACCESSOR_STRUCT(KDC_REP, rep)
/*
* krb5_error_code
* kdc_request_set_rep(astgs_request_t, const KDC_REP *);
*/
ASTGS_REQUEST_SET_ACCESSOR_STRUCT(KDC_REP, KDC_REP, rep)
/*
* const char *
* kdc_request_get_cname(kdc_request_t);
*/
KDC_REQUEST_GET_ACCESSOR_PTR(char *, cname)
/*
* krb5_error_code
* kdc_request_set_cname(kdc_request_t, const char *);
*/
KDC_REQUEST_SET_ACCESSOR_PTR(char *, string_ptr, cname)
/*
* const Principal *
* kdc_request_get_client_princ(astgs_request_t);
*/
ASTGS_REQUEST_GET_ACCESSOR_PTR(Principal *, client_princ)
/*
* krb5_error_code
* kdc_request_set_client_princ(astgs_request_t, const Principal *);
*/
ASTGS_REQUEST_SET_ACCESSOR_PTR(Principal *, Principal_ptr, client_princ)
/*
* const Principal *
* kdc_request_get_canon_client_princ(astgs_request_t);
*/
ASTGS_REQUEST_GET_ACCESSOR_PTR(Principal *, canon_client_princ)
/*
* krb5_error_code
* kdc_request_set_canon_client_princ(astgs_request_t, const Principal *);
*/
ASTGS_REQUEST_SET_ACCESSOR_PTR(Principal *, Principal_ptr, canon_client_princ)
/*
* const HDB *
* kdc_request_get_clientdb(astgs_request_t);
*/
ASTGS_REQUEST_GET_ACCESSOR_PTR(HDB *, clientdb)
/*
* const hdb_entry *
* kdc_request_get_client(astgs_request_t);
*/
ASTGS_REQUEST_GET_ACCESSOR_PTR(hdb_entry *, client)
/*
* See client accessors
*/
KDC_REQUEST_GET_ACCESSOR_PTR(char *, sname)
KDC_REQUEST_SET_ACCESSOR_PTR(char *, string_ptr, sname)
ASTGS_REQUEST_GET_ACCESSOR_PTR(Principal *, server_princ)
ASTGS_REQUEST_SET_ACCESSOR_PTR(Principal *, Principal_ptr, server_princ)
ASTGS_REQUEST_GET_ACCESSOR_PTR(HDB *, serverdb)
ASTGS_REQUEST_GET_ACCESSOR_PTR(hdb_entry *, server)
/*
* See client accessors
*/
ASTGS_REQUEST_GET_ACCESSOR_PTR(Principal *, krbtgt_princ)
ASTGS_REQUEST_SET_ACCESSOR_PTR(Principal *, Principal_ptr, krbtgt_princ)
ASTGS_REQUEST_GET_ACCESSOR_PTR(HDB *, krbtgtdb)
ASTGS_REQUEST_GET_ACCESSOR_PTR(hdb_entry *, krbtgt)
/*
* krb5_ticket *
* kdc_request_get_ticket(astgs_request_t);
*/
ASTGS_REQUEST_GET_ACCESSOR(krb5_ticket *, ticket)
/*
* const krb5_keyblock *
* kdc_request_get_reply_key(astgs_request_t);
*/
ASTGS_REQUEST_GET_ACCESSOR_STRUCT(krb5_keyblock, reply_key)
/*
* krb5_error_code
* kdc_request_set_reply_key(astgs_request_t, const krb5_keyblock *);
*/
ASTGS_REQUEST_SET_ACCESSOR_STRUCT(krb5_keyblock, keyblock, reply_key)
/*
* krb5_const_pac
* kdc_request_get_pac(astgs_request_t);
*/
ASTGS_REQUEST_GET_ACCESSOR_PTR(struct krb5_pac_data *, pac)
/*
* krb5_error_code
* kdc_request_set_pac(astgs_request_t, krb5_const_pac);
*/
ASTGS_REQUEST_SET_ACCESSOR_PTR(struct krb5_pac_data *, pac, pac)
/*
* uint64_t
* kdc_request_get_pac_attributes(astgs_request_t);
*/
ASTGS_REQUEST_GET_ACCESSOR(uint64_t, pac_attributes)
/*
* void
* kdc_request_set_pac_attributes(astgs_request_t, uint64_t);
*/
ASTGS_REQUEST_SET_ACCESSOR(uint64_t, pac_attributes)
#endif /* HEIMDAL_KDC_KDC_ACCESSORS_H */

View File

@@ -3,6 +3,8 @@
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
* Portions (c) 2021, 2022 PADL Software Pty Ltd.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -305,3 +307,189 @@ kdc_get_instance(const char *libname)
return 0;
}
/*
* Plugin accessors
*/
krb5_error_code
kdc_request_add_reply_padata(astgs_request_t r, PA_DATA *md)
{
heim_assert(r->rep.padata != NULL, "reply padata not allocated");
return add_METHOD_DATA(r->rep.padata, md);
}
krb5_error_code
kdc_request_add_pac_buffer(astgs_request_t r, int32_t pactype, const krb5_data *d)
{
krb5_error_code ret;
krb5_pac pac;
if (r->pac == NULL) {
ret = krb5_pac_init(r->context, &pac);
if (ret)
return ret;
} else
pac = heim_retain(r->pac);
ret = krb5_pac_add_buffer(r->context, pac, pactype, d);
if (ret == 0 && r->pac == NULL)
r->pac = pac;
else
heim_release(pac);
return ret;
}
#undef _KDC_REQUEST_GET_ACCESSOR
#define _KDC_REQUEST_GET_ACCESSOR(R, T, f) \
T \
kdc_request_get_ ## f(R r) \
{ \
return r->f; \
}
#undef _KDC_REQUEST_SET_ACCESSOR
#define _KDC_REQUEST_SET_ACCESSOR(R, T, f) \
void \
kdc_request_set_ ## f(R r, T v) \
{ \
r->f = v; \
}
#undef _KDC_REQUEST_GET_ACCESSOR_PTR
#define _KDC_REQUEST_GET_ACCESSOR_PTR(R, T, f) \
const T \
kdc_request_get_ ## f(R r) \
{ \
return r->f; \
}
#undef _KDC_REQUEST_SET_ACCESSOR_PTR
#define _KDC_REQUEST_SET_ACCESSOR_PTR(R, T, t, f) \
krb5_error_code \
kdc_request_set_ ## f(R r, const T v) \
{ \
krb5_error_code ret; \
T tmp; \
\
if (v == r->f) \
return 0; \
else if (v) { \
ret = copy_##t(v, &tmp); \
if (ret) \
return ret; \
} else \
tmp = NULL; \
\
free_##t(r->f); \
r->f = tmp; \
\
return 0; \
}
#undef _KDC_REQUEST_GET_ACCESSOR_STRUCT
#define _KDC_REQUEST_GET_ACCESSOR_STRUCT(R, T, f) \
const T * \
kdc_request_get_ ## f(R r) \
{ \
return &r->f; \
}
#undef _KDC_REQUEST_SET_ACCESSOR_STRUCT
#define _KDC_REQUEST_SET_ACCESSOR_STRUCT(R, T, t, f) \
krb5_error_code \
kdc_request_set_ ## f(R r, const T *v) \
{ \
krb5_error_code ret; \
T tmp; \
\
if (v == NULL) \
return EINVAL; \
else if (v == &r->f) \
return 0; \
\
ret = copy_##t(v, &tmp); \
if (ret) \
return ret; \
\
free_##t(&r->f); \
r->f = tmp; \
\
return 0; \
}
static krb5_error_code
copy_string_ptr(const char *src, char **dst)
{
*dst = strdup(src);
if (*dst == NULL)
return ENOMEM;
return 0;
}
static void
free_string_ptr(char *s)
{
free(s);
}
static krb5_error_code
copy_Principal_ptr(krb5_const_principal src, krb5_principal *dst)
{
krb5_error_code ret;
krb5_principal p;
*dst = NULL;
p = calloc(1, sizeof(*p));
if (*dst == NULL)
return ENOMEM;
ret = copy_Principal(src, p);
if (ret == 0)
*dst = p;
else
free(p);
return ret;
}
static void
free_Principal_ptr(krb5_principal p)
{
if (p) {
free_Principal(p);
free(p);
}
}
static krb5_error_code
copy_pac(const struct krb5_pac_data *src, struct krb5_pac_data **dst)
{
/* FIXME use heim_copy() when it exists */
*dst = (krb5_pac)heim_retain((heim_object_t)src);
return 0;
}
static void
free_pac(struct krb5_pac_data *o)
{
heim_release(o);
}
static krb5_error_code
copy_keyblock(const EncryptionKey *src, EncryptionKey *dst)
{
return copy_EncryptionKey(src, dst);
}
static void
free_keyblock(EncryptionKey *key)
{
krb5_free_keyblock_contents(NULL, key);
}
#undef HEIMDAL_KDC_KDC_ACCESSORS_H
#include "kdc-accessors.h"

152
kdc/kdc.h
View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 1997-2003 Kungliga Tekniska Högskolan
* Copyright (c) 1997-2022 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
*
* Copyright (c) 2005 Andrew Bartlett <abartlet@samba.org>
@@ -46,129 +46,27 @@
#include <kx509_asn1.h>
#include <gssapi/gssapi.h>
#define heim_pcontext krb5_context
#define heim_pconfig krb5_kdc_configuration *
#include <heimbase-svc.h>
enum krb5_kdc_trpolicy {
TRPOLICY_ALWAYS_CHECK,
TRPOLICY_ALLOW_PER_PRINCIPAL,
TRPOLICY_ALWAYS_HONOUR_REQUEST
};
typedef struct krb5_kdc_configuration {
krb5_boolean require_preauth; /* require preauth for all principals */
time_t kdc_warn_pwexpire; /* time before expiration to print a warning */
struct krb5_kdc_configuration;
typedef struct krb5_kdc_configuration krb5_kdc_configuration;
struct HDB **db;
int num_db;
int num_kdc_processes;
krb5_boolean encode_as_rep_as_tgs_rep; /* bug compatibility */
/*
* Windows 2019 (and earlier versions) always sends the salt
* and Samba has testsuites that check this behaviour, so a
* Samba AD DC will set this flag to match the AS-REP packet
* exactly.
*/
krb5_boolean force_include_pa_etype_salt;
krb5_boolean tgt_use_strongest_session_key;
krb5_boolean preauth_use_strongest_session_key;
krb5_boolean svc_use_strongest_session_key;
krb5_boolean use_strongest_server_key;
krb5_boolean check_ticket_addresses;
krb5_boolean warn_ticket_addresses;
krb5_boolean allow_null_ticket_addresses;
krb5_boolean allow_anonymous;
krb5_boolean historical_anon_realm;
krb5_boolean strict_nametypes;
enum krb5_kdc_trpolicy trpolicy;
krb5_boolean require_pac;
krb5_boolean enable_armored_pa_enc_timestamp;
krb5_boolean enable_unarmored_pa_enc_timestamp;
krb5_boolean enable_pkinit;
krb5_boolean pkinit_princ_in_cert;
const char *pkinit_kdc_identity;
const char *pkinit_kdc_anchors;
const char *pkinit_kdc_friendly_name;
const char *pkinit_kdc_ocsp_file;
char **pkinit_kdc_cert_pool;
char **pkinit_kdc_revoke;
int pkinit_dh_min_bits;
/* XXX Turn these into bit-fields */
int pkinit_require_binding;
int pkinit_allow_proxy_certs;
int synthetic_clients;
int pkinit_max_life_from_cert_extension;
krb5_timestamp pkinit_max_life_from_cert;
krb5_timestamp pkinit_max_life_bound;
krb5_timestamp synthetic_clients_max_life;
krb5_timestamp synthetic_clients_max_renew;
krb5_log_facility *logf;
int enable_digest;
int digests_allowed;
int enable_gss_preauth;
int enable_gss_auth_data;
gss_OID_set gss_mechanisms_allowed;
gss_OID_set gss_cross_realm_mechanisms_allowed;
size_t max_datagram_reply_length;
int enable_kx509;
const char *app;
} krb5_kdc_configuration;
#define ASTGS_REQUEST_DESC_COMMON_ELEMENTS \
HEIM_SVC_REQUEST_DESC_COMMON_ELEMENTS; \
\
/* AS-REQ or TGS-REQ */ \
KDC_REQ req; \
\
/* AS-REP or TGS-REP */ \
KDC_REP rep; \
EncTicketPart et; \
EncKDCRepPart ek; \
\
/* client principal (AS) or TGT/S4U principal (TGS) */ \
krb5_principal client_princ; \
hdb_entry *client; \
HDB *clientdb; \
krb5_principal canon_client_princ; \
\
/* server principal */ \
krb5_principal server_princ; \
hdb_entry *server; \
HDB *serverdb; \
\
/* presented ticket in TGS-REQ (unused by AS) */ \
krb5_principal *krbtgt_princ; \
hdb_entry *krbtgt; \
HDB *krbtgtdb; \
krb5_ticket *ticket; \
\
krb5_keyblock reply_key; \
\
krb5_pac pac; \
uint64_t pac_attributes
#ifndef __KDC_LOCL_H__
struct astgs_request_desc {
ASTGS_REQUEST_DESC_COMMON_ELEMENTS;
};
#endif
/*
* Access to request fields by plugins and other out-of-tree
* consumers should be via the functions in kdc-accessors.h.
*/
struct kdc_request_desc;
typedef struct kdc_request_desc *kdc_request_t;
struct astgs_request_desc;
typedef struct astgs_request_desc *astgs_request_t;
struct kx509_req_context_desc;
typedef struct kx509_req_context_desc *kx509_req_context;
struct krb5_kdc_service {
@@ -179,9 +77,27 @@ struct krb5_kdc_service {
krb5_error_code (*process)(kdc_request_t *, int *claim);
};
/*
* The following fields are guaranteed stable within a major
* release of Heimdal and can be manipulated by applications
* that manage KDC requests themselves using libkdc.
*
* Applications can make custom KDC configuration available
* to libkdc by using krb5_set_config().
*/
#define KRB5_KDC_CONFIGURATION_COMMON_ELEMENTS \
krb5_log_facility *logf; \
struct HDB **db; \
size_t num_db; \
const char *app
#ifndef __KDC_LOCL_H__
struct krb5_kdc_configuration {
KRB5_KDC_CONFIGURATION_COMMON_ELEMENTS;
};
#endif
#include <kdc-protos.h>
#undef heim_pcontext
#undef heim_pconfig
#endif
#endif /* __KDC_H__ */

View File

@@ -66,8 +66,105 @@ struct kdc_request_desc {
struct kdc_patypes;
struct krb5_kdc_configuration {
KRB5_KDC_CONFIGURATION_COMMON_ELEMENTS;
int num_kdc_processes;
size_t max_datagram_reply_length;
time_t kdc_warn_pwexpire; /* time before expiration to print a warning */
unsigned int require_preauth : 1; /* require preauth for all principals */
unsigned int encode_as_rep_as_tgs_rep : 1; /* bug compatibility */
/*
* Windows 2019 (and earlier versions) always sends the salt
* and Samba has testsuites that check this behaviour, so a
* Samba AD DC will set this flag to match the AS-REP packet
* exactly.
*/
unsigned int force_include_pa_etype_salt : 1;
unsigned int tgt_use_strongest_session_key : 1;
unsigned int preauth_use_strongest_session_key : 1;
unsigned int svc_use_strongest_session_key : 1;
unsigned int use_strongest_server_key : 1;
unsigned int check_ticket_addresses : 1;
unsigned int warn_ticket_addresses : 1;
unsigned int allow_null_ticket_addresses : 1;
unsigned int allow_anonymous : 1;
unsigned int historical_anon_realm : 1;
unsigned int strict_nametypes : 1;
enum krb5_kdc_trpolicy trpolicy;
unsigned int require_pac : 1;
unsigned int enable_armored_pa_enc_timestamp : 1;
unsigned int enable_unarmored_pa_enc_timestamp : 1;
unsigned int enable_pkinit : 1;
unsigned int pkinit_princ_in_cert : 1;
const char *pkinit_kdc_identity;
const char *pkinit_kdc_anchors;
const char *pkinit_kdc_friendly_name;
const char *pkinit_kdc_ocsp_file;
char **pkinit_kdc_cert_pool;
char **pkinit_kdc_revoke;
int pkinit_dh_min_bits;
unsigned int pkinit_require_binding : 1;
unsigned int pkinit_allow_proxy_certs : 1;
unsigned int synthetic_clients : 1;
unsigned int pkinit_max_life_from_cert_extension : 1;
krb5_timestamp pkinit_max_life_from_cert;
krb5_timestamp pkinit_max_life_bound;
krb5_timestamp synthetic_clients_max_life;
krb5_timestamp synthetic_clients_max_renew;
int digests_allowed;
unsigned int enable_digest : 1;
unsigned int enable_kx509 : 1;
unsigned int enable_gss_preauth : 1;
unsigned int enable_gss_auth_data : 1;
gss_OID_set gss_mechanisms_allowed;
gss_OID_set gss_cross_realm_mechanisms_allowed;
};
struct astgs_request_desc {
ASTGS_REQUEST_DESC_COMMON_ELEMENTS;
HEIM_SVC_REQUEST_DESC_COMMON_ELEMENTS;
/* AS-REQ or TGS-REQ */
KDC_REQ req;
/* AS-REP or TGS-REP */
KDC_REP rep;
EncTicketPart et;
EncKDCRepPart ek;
/* client principal (AS) or TGT/S4U principal (TGS) */
krb5_principal client_princ;
hdb_entry *client;
HDB *clientdb;
krb5_principal canon_client_princ;
/* server principal */
krb5_principal server_princ;
HDB *serverdb;
hdb_entry *server;
/* presented ticket in TGS-REQ (unused by AS) */
krb5_principal krbtgt_princ;
hdb_entry *krbtgt;
HDB *krbtgtdb;
krb5_ticket *ticket;
krb5_keyblock reply_key;
krb5_pac pac;
uint64_t pac_attributes;
/* Only AS */
const struct kdc_patypes *pa_used;

View File

@@ -21,6 +21,45 @@ EXPORTS
kdc_request_get_attribute
kdc_request_copy_attribute
kdc_request_delete_attribute
kdc_request_add_pac_buffer
kdc_request_add_reply_padata
kdc_request_get_addr
kdc_request_get_canon_client_princ
kdc_request_get_client
kdc_request_get_clientdb
kdc_request_get_client_princ
kdc_request_get_context
kdc_request_get_config
kdc_request_get_cname
kdc_request_get_error_code
kdc_request_get_from
kdc_request_get_krbtgt
kdc_request_get_krbtgtdb
kdc_request_get_krbtgt_princ
kdc_request_get_pac
kdc_request_get_pac_attributes
kdc_request_get_rep
kdc_request_get_reply_key
kdc_request_get_req
kdc_request_get_request
kdc_request_get_server
kdc_request_get_serverdb
kdc_request_get_server_princ
kdc_request_get_sname
kdc_request_get_ticket
kdc_request_get_tv_end
kdc_request_get_tv_start
kdc_request_set_canon_client_princ
kdc_request_set_client_princ
kdc_request_set_cname
kdc_request_set_error_code
kdc_request_set_krbtgt_princ
kdc_request_set_pac
kdc_request_set_pac_attributes
kdc_request_set_rep
kdc_request_set_reply_key
kdc_request_set_server_princ
kdc_request_set_sname
kdc_audit_addkv
kdc_audit_addkv_number
kdc_audit_addkv_object

View File

@@ -24,6 +24,45 @@ HEIMDAL_KDC_1.0 {
kdc_request_get_attribute;
kdc_request_copy_attribute;
kdc_request_delete_attribute;
kdc_request_add_pac_buffer;
kdc_request_add_reply_padata;
kdc_request_get_addr;
kdc_request_get_canon_client_princ;
kdc_request_get_client;
kdc_request_get_clientdb;
kdc_request_get_client_princ;
kdc_request_get_context;
kdc_request_get_config;
kdc_request_get_cname;
kdc_request_get_error_code;
kdc_request_get_from;
kdc_request_get_krbtgt;
kdc_request_get_krbtgtdb;
kdc_request_get_krbtgt_princ;
kdc_request_get_pac;
kdc_request_get_pac_attributes;
kdc_request_get_rep;
kdc_request_get_reply_key;
kdc_request_get_req;
kdc_request_get_request;
kdc_request_get_server;
kdc_request_get_serverdb;
kdc_request_get_server_princ;
kdc_request_get_sname;
kdc_request_get_ticket;
kdc_request_get_tv_end;
kdc_request_get_tv_start;
kdc_request_set_canon_client_princ;
kdc_request_set_client_princ;
kdc_request_set_cname;
kdc_request_set_error_code;
kdc_request_set_krbtgt_princ;
kdc_request_set_pac;
kdc_request_set_pac_attributes;
kdc_request_set_rep;
kdc_request_set_reply_key;
kdc_request_set_server_princ;
kdc_request_set_sname;
kdc_audit_addkv;
kdc_audit_addkv_number;
kdc_audit_addkv_object;

View File

@@ -95,6 +95,7 @@ typedef struct krb5_ntlm_data *krb5_ntlm;
struct krb5_pac_data;
typedef struct krb5_pac_data *krb5_pac;
typedef const struct krb5_pac_data *krb5_const_pac;
typedef struct krb5_rd_req_in_ctx_data *krb5_rd_req_in_ctx;
typedef struct krb5_rd_req_out_ctx_data *krb5_rd_req_out_ctx;

View File

@@ -100,10 +100,14 @@ pac_verify(void *ctx,
static void logit(const char *what, astgs_request_t r)
{
krb5_warnx(r->context, "%s: client %s server %s",
krb5_context context = kdc_request_get_context((kdc_request_t)r);
const char *cname = kdc_request_get_cname((kdc_request_t)r);
const char *sname = kdc_request_get_sname((kdc_request_t)r);
krb5_warnx(context, "%s: client %s server %s",
what,
r->cname ? r->cname : "<unknown>",
r->sname ? r->sname : "<unknown>");
cname ? cname : "<unknown>",
sname ? sname : "<unknown>");
}
static krb5_error_code KRB5_CALLCONV
@@ -136,11 +140,12 @@ finalize_reply(void *ctx, astgs_request_t r)
static krb5_error_code KRB5_CALLCONV
audit(void *ctx, astgs_request_t r)
{
krb5_error_code ret = kdc_request_get_error_code((kdc_request_t)r);
heim_number_t n;
logit("audit", r);
if (r->ret)
if (ret)
return 0; /* finalize_reply only called in success */
n = kdc_request_get_attribute((kdc_request_t)r,