Merge pull request #138 from abartlet/lorikeet-heimdal-for-upstream
Samba Cross-realm support patches from metze These patches were posted to heimdal-discuss by metze, and there were no objections there.
This commit is contained in:
1067
doc/standardisation/rfc6806.txt
Normal file
1067
doc/standardisation/rfc6806.txt
Normal file
File diff suppressed because it is too large
Load Diff
16
kdc/fast.c
16
kdc/fast.c
@@ -244,8 +244,9 @@ _kdc_fast_mk_error(krb5_context context,
|
||||
const KDC_REQ_BODY *req_body,
|
||||
krb5_error_code outer_error,
|
||||
const char *e_text,
|
||||
krb5_principal error_client,
|
||||
krb5_principal error_server,
|
||||
const PrincipalName *error_client_name,
|
||||
const Realm *error_client_realm,
|
||||
time_t *csec, int *cusec,
|
||||
krb5_data *error_msg)
|
||||
{
|
||||
@@ -264,12 +265,13 @@ _kdc_fast_mk_error(krb5_context context,
|
||||
|
||||
/* first add the KRB-ERROR to the fast errors */
|
||||
|
||||
ret = krb5_mk_error(context,
|
||||
ret = krb5_mk_error_ext(context,
|
||||
outer_error,
|
||||
e_text,
|
||||
NULL,
|
||||
error_client,
|
||||
error_server,
|
||||
error_client_name,
|
||||
error_client_realm,
|
||||
NULL,
|
||||
NULL,
|
||||
&e_data);
|
||||
@@ -285,7 +287,8 @@ _kdc_fast_mk_error(krb5_context context,
|
||||
}
|
||||
|
||||
if (/* hide_principal */ 0) {
|
||||
error_client = NULL;
|
||||
error_client_name = NULL;
|
||||
error_client_realm = NULL;
|
||||
error_server = NULL;
|
||||
e_text = NULL;
|
||||
}
|
||||
@@ -325,12 +328,13 @@ _kdc_fast_mk_error(krb5_context context,
|
||||
krb5_abortx(context, "internal asn.1 error");
|
||||
}
|
||||
|
||||
ret = krb5_mk_error(context,
|
||||
ret = krb5_mk_error_ext(context,
|
||||
outer_error,
|
||||
e_text,
|
||||
(e_data.length ? &e_data : NULL),
|
||||
error_client,
|
||||
error_server,
|
||||
error_client_name,
|
||||
error_client_realm,
|
||||
csec,
|
||||
cusec,
|
||||
error_msg);
|
||||
|
@@ -1712,6 +1712,31 @@ _kdc_as_rep(kdc_request_t r,
|
||||
kdc_log(context, config, 5, "client %s does not have secrets at this KDC, need to proxy",
|
||||
r->client_name);
|
||||
goto out;
|
||||
} else if (ret == HDB_ERR_WRONG_REALM) {
|
||||
char *fixed_client_name = NULL;
|
||||
|
||||
ret = krb5_unparse_name(context, r->client->entry.principal,
|
||||
&fixed_client_name);
|
||||
if (ret) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
kdc_log(context, config, 0, "WRONG_REALM - %s -> %s",
|
||||
r->client_name, fixed_client_name);
|
||||
free(fixed_client_name);
|
||||
|
||||
ret = _kdc_fast_mk_error(context, r,
|
||||
&error_method,
|
||||
r->armor_crypto,
|
||||
&req->req_body,
|
||||
KRB5_KDC_ERR_WRONG_REALM,
|
||||
NULL,
|
||||
r->server_princ,
|
||||
NULL,
|
||||
&r->client->entry.principal->realm,
|
||||
NULL, NULL,
|
||||
reply);
|
||||
goto out;
|
||||
} else if(ret){
|
||||
const char *msg = krb5_get_error_message(context, ret);
|
||||
kdc_log(context, config, 0, "UNKNOWN -- %s: %s", r->client_name, msg);
|
||||
@@ -2193,13 +2218,15 @@ out:
|
||||
/*
|
||||
* In case of a non proxy error, build an error message.
|
||||
*/
|
||||
if(ret != 0 && ret != HDB_ERR_NOT_FOUND_HERE) {
|
||||
if(ret != 0 && ret != HDB_ERR_NOT_FOUND_HERE && reply->length == 0) {
|
||||
ret = _kdc_fast_mk_error(context, r,
|
||||
&error_method,
|
||||
r->armor_crypto,
|
||||
&req->req_body,
|
||||
ret, r->e_text,
|
||||
r->client_princ, r->server_princ,
|
||||
r->server_princ,
|
||||
&r->client_princ->name,
|
||||
&r->client_princ->realm,
|
||||
NULL, NULL,
|
||||
reply);
|
||||
if (ret)
|
||||
|
@@ -1121,15 +1121,14 @@ need_referral(krb5_context context, krb5_kdc_configuration *config,
|
||||
|
||||
if (server->name.name_string.len == 1)
|
||||
name = server->name.name_string.val[0];
|
||||
else if (server->name.name_string.len == 3 &&
|
||||
strcasecmp("E3514235-4B06-11D1-AB04-00C04FC2DCD2", server->name.name_string.val[0]) == 0) {
|
||||
else if (server->name.name_string.len == 3) {
|
||||
/*
|
||||
This is used to give referrals for the
|
||||
E3514235-4B06-11D1-AB04-00C04FC2DCD2/NTDSGUID/DNSDOMAIN
|
||||
SPN form, which is used for inter-domain communication in AD
|
||||
*/
|
||||
name = server->name.name_string.val[2];
|
||||
kdc_log(context, config, 0, "Giving 3 part DRSUAPI referral for %s", name);
|
||||
kdc_log(context, config, 0, "Giving 3 part referral for %s", name);
|
||||
*realms = malloc(sizeof(char *)*2);
|
||||
if (*realms == NULL) {
|
||||
krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
|
||||
@@ -1648,6 +1647,32 @@ server_lookup:
|
||||
if(ret == HDB_ERR_NOT_FOUND_HERE) {
|
||||
kdc_log(context, config, 5, "target %s does not have secrets at this KDC, need to proxy", sp);
|
||||
goto out;
|
||||
} else if (ret == HDB_ERR_WRONG_REALM) {
|
||||
if (ref_realm)
|
||||
free(ref_realm);
|
||||
ref_realm = strdup(server->entry.principal->realm);
|
||||
if (ref_realm == NULL) {
|
||||
ret = ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
kdc_log(context, config, 5,
|
||||
"Returning a referral to realm %s for "
|
||||
"server %s.",
|
||||
ref_realm, spn);
|
||||
krb5_free_principal(context, sp);
|
||||
sp = NULL;
|
||||
free(spn);
|
||||
spn = NULL;
|
||||
ret = krb5_make_principal(context, &sp, r, KRB5_TGS_NAME,
|
||||
ref_realm, NULL);
|
||||
if (ret)
|
||||
goto out;
|
||||
ret = krb5_unparse_name(context, sp, &spn);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
goto server_lookup;
|
||||
} else if(ret){
|
||||
const char *new_rlm, *msg;
|
||||
Realm req_rlm;
|
||||
@@ -2457,6 +2482,7 @@ out:
|
||||
NULL,
|
||||
NULL,
|
||||
ret, NULL,
|
||||
NULL,
|
||||
NULL, NULL,
|
||||
csec, cusec,
|
||||
data);
|
||||
|
@@ -101,6 +101,13 @@ _kdc_db_fetch(krb5_context context,
|
||||
config->db[i]->hdb_close(context, config->db[i]);
|
||||
|
||||
switch (ret) {
|
||||
case HDB_ERR_WRONG_REALM:
|
||||
/*
|
||||
* the ent->entry.principal just contains hints for the client
|
||||
* to retry. This is important for enterprise principal routing
|
||||
* between trusts.
|
||||
*/
|
||||
/* fall through */
|
||||
case 0:
|
||||
if (db)
|
||||
*db = config->db[i];
|
||||
|
@@ -46,6 +46,9 @@ _gk_wrap_iov(OM_uint32 * minor_status,
|
||||
{
|
||||
const gsskrb5_ctx ctx = (const gsskrb5_ctx) context_handle;
|
||||
krb5_context context;
|
||||
OM_uint32 ret;
|
||||
krb5_keyblock *key;
|
||||
krb5_keytype keytype;
|
||||
|
||||
GSSAPI_KRB5_INIT (&context);
|
||||
|
||||
@@ -54,8 +57,31 @@ _gk_wrap_iov(OM_uint32 * minor_status,
|
||||
conf_req_flag, conf_state,
|
||||
iov, iov_count);
|
||||
|
||||
HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
|
||||
ret = _gsskrb5i_get_token_key(ctx, context, &key);
|
||||
HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
|
||||
if (ret) {
|
||||
*minor_status = ret;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
krb5_enctype_to_keytype(context, key->keytype, &keytype);
|
||||
|
||||
switch (keytype) {
|
||||
case KEYTYPE_ARCFOUR:
|
||||
case KEYTYPE_ARCFOUR_56:
|
||||
ret = _gssapi_wrap_iov_arcfour(minor_status, ctx, context,
|
||||
conf_req_flag, conf_state,
|
||||
iov, iov_count, key);
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = GSS_S_FAILURE;
|
||||
break;
|
||||
}
|
||||
|
||||
krb5_free_keyblock(context, key);
|
||||
return ret;
|
||||
}
|
||||
|
||||
OM_uint32 GSSAPI_CALLCONV
|
||||
_gk_unwrap_iov(OM_uint32 *minor_status,
|
||||
@@ -67,6 +93,9 @@ _gk_unwrap_iov(OM_uint32 *minor_status,
|
||||
{
|
||||
const gsskrb5_ctx ctx = (const gsskrb5_ctx) context_handle;
|
||||
krb5_context context;
|
||||
OM_uint32 ret;
|
||||
krb5_keytype keytype;
|
||||
krb5_keyblock *key;
|
||||
|
||||
GSSAPI_KRB5_INIT (&context);
|
||||
|
||||
@@ -74,8 +103,31 @@ _gk_unwrap_iov(OM_uint32 *minor_status,
|
||||
return _gssapi_unwrap_cfx_iov(minor_status, ctx, context,
|
||||
conf_state, qop_state, iov, iov_count);
|
||||
|
||||
HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
|
||||
ret = _gsskrb5i_get_token_key(ctx, context, &key);
|
||||
HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
|
||||
if (ret) {
|
||||
*minor_status = ret;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
krb5_enctype_to_keytype(context, key->keytype, &keytype);
|
||||
|
||||
switch (keytype) {
|
||||
case KEYTYPE_ARCFOUR:
|
||||
case KEYTYPE_ARCFOUR_56:
|
||||
ret = _gssapi_unwrap_iov_arcfour(minor_status, ctx, context,
|
||||
conf_state, qop_state,
|
||||
iov, iov_count, key);
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = GSS_S_FAILURE;
|
||||
break;
|
||||
}
|
||||
|
||||
krb5_free_keyblock(context, key);
|
||||
return ret;
|
||||
}
|
||||
|
||||
OM_uint32 GSSAPI_CALLCONV
|
||||
_gk_wrap_iov_length(OM_uint32 * minor_status,
|
||||
@@ -88,6 +140,9 @@ _gk_wrap_iov_length(OM_uint32 * minor_status,
|
||||
{
|
||||
const gsskrb5_ctx ctx = (const gsskrb5_ctx) context_handle;
|
||||
krb5_context context;
|
||||
OM_uint32 ret;
|
||||
krb5_keytype keytype;
|
||||
krb5_keyblock *key;
|
||||
|
||||
GSSAPI_KRB5_INIT (&context);
|
||||
|
||||
@@ -96,5 +151,28 @@ _gk_wrap_iov_length(OM_uint32 * minor_status,
|
||||
conf_req_flag, qop_req, conf_state,
|
||||
iov, iov_count);
|
||||
|
||||
HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
|
||||
ret = _gsskrb5i_get_token_key(ctx, context, &key);
|
||||
HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
|
||||
if (ret) {
|
||||
*minor_status = ret;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
krb5_enctype_to_keytype(context, key->keytype, &keytype);
|
||||
|
||||
switch (keytype) {
|
||||
case KEYTYPE_ARCFOUR:
|
||||
case KEYTYPE_ARCFOUR_56:
|
||||
ret = _gssapi_wrap_iov_length_arcfour(minor_status, ctx, context,
|
||||
conf_req_flag, qop_req, conf_state,
|
||||
iov, iov_count);
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = GSS_S_FAILURE;
|
||||
break;
|
||||
}
|
||||
|
||||
krb5_free_keyblock(context, key);
|
||||
return ret;
|
||||
}
|
||||
|
@@ -69,7 +69,7 @@
|
||||
|
||||
static krb5_error_code
|
||||
arcfour_mic_key(krb5_context context, krb5_keyblock *key,
|
||||
void *cksum_data, size_t cksum_size,
|
||||
const void *cksum_data, size_t cksum_size,
|
||||
void *key6_data, size_t key6_size)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
@@ -112,30 +112,73 @@ arcfour_mic_key(krb5_context context, krb5_keyblock *key,
|
||||
|
||||
|
||||
static krb5_error_code
|
||||
arcfour_mic_cksum(krb5_context context,
|
||||
arcfour_mic_cksum_iov(krb5_context context,
|
||||
krb5_keyblock *key, unsigned usage,
|
||||
u_char *sgn_cksum, size_t sgn_cksum_sz,
|
||||
const u_char *v1, size_t l1,
|
||||
const void *v2, size_t l2,
|
||||
const void *v3, size_t l3)
|
||||
const gss_iov_buffer_desc *iov,
|
||||
int iov_count,
|
||||
const gss_iov_buffer_desc *padding)
|
||||
{
|
||||
Checksum CKSUM;
|
||||
u_char *ptr;
|
||||
size_t len;
|
||||
size_t ofs = 0;
|
||||
int i;
|
||||
krb5_crypto crypto;
|
||||
krb5_error_code ret;
|
||||
|
||||
assert(sgn_cksum_sz == 8);
|
||||
|
||||
len = l1 + l2 + l3;
|
||||
len = l1 + l2;
|
||||
|
||||
for (i=0; i < iov_count; i++) {
|
||||
switch (GSS_IOV_BUFFER_TYPE(iov[i].type)) {
|
||||
case GSS_IOV_BUFFER_TYPE_DATA:
|
||||
case GSS_IOV_BUFFER_TYPE_SIGN_ONLY:
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
|
||||
len += iov[i].buffer.length;
|
||||
}
|
||||
|
||||
if (padding) {
|
||||
len += padding->buffer.length;
|
||||
}
|
||||
|
||||
ptr = malloc(len);
|
||||
if (ptr == NULL)
|
||||
return ENOMEM;
|
||||
|
||||
memcpy(ptr, v1, l1);
|
||||
memcpy(ptr + l1, v2, l2);
|
||||
memcpy(ptr + l1 + l2, v3, l3);
|
||||
memcpy(ptr + ofs, v1, l1);
|
||||
ofs += l1;
|
||||
memcpy(ptr + ofs, v2, l2);
|
||||
ofs += l2;
|
||||
|
||||
for (i=0; i < iov_count; i++) {
|
||||
switch (GSS_IOV_BUFFER_TYPE(iov[i].type)) {
|
||||
case GSS_IOV_BUFFER_TYPE_DATA:
|
||||
case GSS_IOV_BUFFER_TYPE_SIGN_ONLY:
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
|
||||
memcpy(ptr + ofs,
|
||||
iov[i].buffer.value,
|
||||
iov[i].buffer.length);
|
||||
ofs += iov[i].buffer.length;
|
||||
}
|
||||
|
||||
if (padding) {
|
||||
memcpy(ptr + ofs,
|
||||
padding->buffer.value,
|
||||
padding->buffer.length);
|
||||
ofs += padding->buffer.length;
|
||||
}
|
||||
|
||||
ret = krb5_crypto_init(context, key, 0, &crypto);
|
||||
if (ret) {
|
||||
@@ -149,6 +192,7 @@ arcfour_mic_cksum(krb5_context context,
|
||||
0,
|
||||
ptr, len,
|
||||
&CKSUM);
|
||||
memset(ptr, 0, len);
|
||||
free(ptr);
|
||||
if (ret == 0) {
|
||||
memcpy(sgn_cksum, CKSUM.checksum.data, sgn_cksum_sz);
|
||||
@@ -159,6 +203,26 @@ arcfour_mic_cksum(krb5_context context,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static krb5_error_code
|
||||
arcfour_mic_cksum(krb5_context context,
|
||||
krb5_keyblock *key, unsigned usage,
|
||||
u_char *sgn_cksum, size_t sgn_cksum_sz,
|
||||
const u_char *v1, size_t l1,
|
||||
const void *v2, size_t l2,
|
||||
const void *v3, size_t l3)
|
||||
{
|
||||
gss_iov_buffer_desc iov;
|
||||
|
||||
iov.type = GSS_IOV_BUFFER_TYPE_SIGN_ONLY;
|
||||
iov.buffer.value = rk_UNCONST(v3);
|
||||
iov.buffer.length = l3;
|
||||
|
||||
return arcfour_mic_cksum_iov(context, key, usage,
|
||||
sgn_cksum, sgn_cksum_sz,
|
||||
v1, l1, v2, l2,
|
||||
&iov, 1, NULL);
|
||||
}
|
||||
|
||||
|
||||
OM_uint32
|
||||
_gssapi_get_mic_arcfour(OM_uint32 * minor_status,
|
||||
@@ -760,3 +824,562 @@ _gssapi_wrap_size_arcfour(OM_uint32 *minor_status,
|
||||
|
||||
return GSS_S_COMPLETE;
|
||||
}
|
||||
|
||||
OM_uint32
|
||||
_gssapi_wrap_iov_length_arcfour(OM_uint32 *minor_status,
|
||||
gsskrb5_ctx ctx,
|
||||
krb5_context context,
|
||||
int conf_req_flag,
|
||||
gss_qop_t qop_req,
|
||||
int *conf_state,
|
||||
gss_iov_buffer_desc *iov,
|
||||
int iov_count)
|
||||
{
|
||||
OM_uint32 major_status;
|
||||
size_t data_len = 0;
|
||||
int i;
|
||||
gss_iov_buffer_desc *header = NULL;
|
||||
gss_iov_buffer_desc *padding = NULL;
|
||||
gss_iov_buffer_desc *trailer = NULL;
|
||||
|
||||
*minor_status = 0;
|
||||
|
||||
for (i = 0; i < iov_count; i++) {
|
||||
switch(GSS_IOV_BUFFER_TYPE(iov[i].type)) {
|
||||
case GSS_IOV_BUFFER_TYPE_EMPTY:
|
||||
break;
|
||||
case GSS_IOV_BUFFER_TYPE_DATA:
|
||||
data_len += iov[i].buffer.length;
|
||||
break;
|
||||
case GSS_IOV_BUFFER_TYPE_HEADER:
|
||||
if (header != NULL) {
|
||||
*minor_status = EINVAL;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
header = &iov[i];
|
||||
break;
|
||||
case GSS_IOV_BUFFER_TYPE_TRAILER:
|
||||
if (trailer != NULL) {
|
||||
*minor_status = EINVAL;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
trailer = &iov[i];
|
||||
break;
|
||||
case GSS_IOV_BUFFER_TYPE_PADDING:
|
||||
if (padding != NULL) {
|
||||
*minor_status = EINVAL;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
padding = &iov[i];
|
||||
break;
|
||||
case GSS_IOV_BUFFER_TYPE_SIGN_ONLY:
|
||||
break;
|
||||
default:
|
||||
*minor_status = EINVAL;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
major_status = _gk_verify_buffers(minor_status, ctx, header, padding, trailer);
|
||||
if (major_status != GSS_S_COMPLETE) {
|
||||
return major_status;
|
||||
}
|
||||
|
||||
if (IS_DCE_STYLE(ctx)) {
|
||||
size_t len = GSS_ARCFOUR_WRAP_TOKEN_SIZE;
|
||||
size_t total_len;
|
||||
_gssapi_encap_length(len, &len, &total_len, GSS_KRB5_MECHANISM);
|
||||
header->buffer.length = total_len;
|
||||
} else {
|
||||
size_t len;
|
||||
size_t total_len;
|
||||
if (padding) {
|
||||
data_len += 1; /* padding */
|
||||
}
|
||||
len = data_len + GSS_ARCFOUR_WRAP_TOKEN_SIZE;
|
||||
_gssapi_encap_length(len, &len, &total_len, GSS_KRB5_MECHANISM);
|
||||
header->buffer.length = total_len - data_len;
|
||||
}
|
||||
|
||||
if (trailer) {
|
||||
trailer->buffer.length = 0;
|
||||
}
|
||||
|
||||
if (padding) {
|
||||
padding->buffer.length = 1;
|
||||
}
|
||||
|
||||
return GSS_S_COMPLETE;
|
||||
}
|
||||
|
||||
OM_uint32
|
||||
_gssapi_wrap_iov_arcfour(OM_uint32 *minor_status,
|
||||
gsskrb5_ctx ctx,
|
||||
krb5_context context,
|
||||
int conf_req_flag,
|
||||
int *conf_state,
|
||||
gss_iov_buffer_desc *iov,
|
||||
int iov_count,
|
||||
krb5_keyblock *key)
|
||||
{
|
||||
OM_uint32 major_status, junk;
|
||||
gss_iov_buffer_desc *header, *padding, *trailer;
|
||||
krb5_error_code kret;
|
||||
int32_t seq_number;
|
||||
u_char Klocaldata[16], k6_data[16], *p, *p0;
|
||||
size_t make_len = 0;
|
||||
size_t header_len = 0;
|
||||
size_t data_len = 0;
|
||||
krb5_keyblock Klocal;
|
||||
int i;
|
||||
|
||||
header = _gk_find_buffer(iov, iov_count, GSS_IOV_BUFFER_TYPE_HEADER);
|
||||
padding = _gk_find_buffer(iov, iov_count, GSS_IOV_BUFFER_TYPE_PADDING);
|
||||
trailer = _gk_find_buffer(iov, iov_count, GSS_IOV_BUFFER_TYPE_TRAILER);
|
||||
|
||||
major_status = _gk_verify_buffers(minor_status, ctx, header, padding, trailer);
|
||||
if (major_status != GSS_S_COMPLETE) {
|
||||
return major_status;
|
||||
}
|
||||
|
||||
for (i = 0; i < iov_count; i++) {
|
||||
switch (GSS_IOV_BUFFER_TYPE(iov[i].type)) {
|
||||
case GSS_IOV_BUFFER_TYPE_DATA:
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
|
||||
data_len += iov[i].buffer.length;
|
||||
}
|
||||
|
||||
if (padding) {
|
||||
data_len += 1;
|
||||
}
|
||||
|
||||
if (IS_DCE_STYLE(ctx)) {
|
||||
size_t unwrapped_len;
|
||||
unwrapped_len = GSS_ARCFOUR_WRAP_TOKEN_SIZE;
|
||||
_gssapi_encap_length(unwrapped_len,
|
||||
&make_len,
|
||||
&header_len,
|
||||
GSS_KRB5_MECHANISM);
|
||||
} else {
|
||||
size_t unwrapped_len;
|
||||
unwrapped_len = GSS_ARCFOUR_WRAP_TOKEN_SIZE + data_len;
|
||||
_gssapi_encap_length(unwrapped_len,
|
||||
&make_len,
|
||||
&header_len,
|
||||
GSS_KRB5_MECHANISM);
|
||||
header_len -= data_len;
|
||||
}
|
||||
|
||||
if (GSS_IOV_BUFFER_FLAGS(header->type) & GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATE) {
|
||||
major_status = _gk_allocate_buffer(minor_status, header,
|
||||
header_len);
|
||||
if (major_status != GSS_S_COMPLETE)
|
||||
goto failure;
|
||||
} else if (header->buffer.length < header_len) {
|
||||
*minor_status = KRB5_BAD_MSIZE;
|
||||
major_status = GSS_S_FAILURE;
|
||||
goto failure;
|
||||
} else {
|
||||
header->buffer.length = header_len;
|
||||
}
|
||||
|
||||
if (padding) {
|
||||
if (GSS_IOV_BUFFER_FLAGS(padding->type) & GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATE) {
|
||||
major_status = _gk_allocate_buffer(minor_status, padding, 1);
|
||||
if (major_status != GSS_S_COMPLETE)
|
||||
goto failure;
|
||||
} else if (padding->buffer.length < 1) {
|
||||
*minor_status = KRB5_BAD_MSIZE;
|
||||
major_status = GSS_S_FAILURE;
|
||||
goto failure;
|
||||
} else {
|
||||
padding->buffer.length = 1;
|
||||
}
|
||||
memset(padding->buffer.value, 1, 1);
|
||||
}
|
||||
|
||||
if (trailer) {
|
||||
trailer->buffer.length = 0;
|
||||
trailer->buffer.value = NULL;
|
||||
}
|
||||
|
||||
p0 = _gssapi_make_mech_header(header->buffer.value,
|
||||
make_len,
|
||||
GSS_KRB5_MECHANISM);
|
||||
p = p0;
|
||||
|
||||
*p++ = 0x02; /* TOK_ID */
|
||||
*p++ = 0x01;
|
||||
*p++ = 0x11; /* SGN_ALG */
|
||||
*p++ = 0x00;
|
||||
if (conf_req_flag) {
|
||||
*p++ = 0x10; /* SEAL_ALG */
|
||||
*p++ = 0x00;
|
||||
} else {
|
||||
*p++ = 0xff; /* SEAL_ALG */
|
||||
*p++ = 0xff;
|
||||
}
|
||||
*p++ = 0xff; /* Filler */
|
||||
*p++ = 0xff;
|
||||
|
||||
p = NULL;
|
||||
|
||||
HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
|
||||
krb5_auth_con_getlocalseqnumber(context,
|
||||
ctx->auth_context,
|
||||
&seq_number);
|
||||
_gsskrb5_encode_be_om_uint32(seq_number, p0 + 8);
|
||||
|
||||
krb5_auth_con_setlocalseqnumber(context,
|
||||
ctx->auth_context,
|
||||
++seq_number);
|
||||
HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
|
||||
|
||||
memset(p0 + 8 + 4,
|
||||
(ctx->more_flags & LOCAL) ? 0 : 0xff,
|
||||
4);
|
||||
|
||||
krb5_generate_random_block(p0 + 24, 8); /* fill in Confounder */
|
||||
|
||||
/* Sign Data */
|
||||
kret = arcfour_mic_cksum_iov(context,
|
||||
key, KRB5_KU_USAGE_SEAL,
|
||||
p0 + 16, 8, /* SGN_CKSUM */
|
||||
p0, 8, /* TOK_ID, SGN_ALG, SEAL_ALG, Filler */
|
||||
p0 + 24, 8, /* Confounder */
|
||||
iov, iov_count, /* Data + SignOnly */
|
||||
padding); /* padding */
|
||||
if (kret) {
|
||||
*minor_status = kret;
|
||||
major_status = GSS_S_FAILURE;
|
||||
goto failure;
|
||||
}
|
||||
|
||||
Klocal.keytype = key->keytype;
|
||||
Klocal.keyvalue.data = Klocaldata;
|
||||
Klocal.keyvalue.length = sizeof(Klocaldata);
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
Klocaldata[i] = ((u_char *)key->keyvalue.data)[i] ^ 0xF0;
|
||||
}
|
||||
kret = arcfour_mic_key(context, &Klocal,
|
||||
p0 + 8, 4, /* SND_SEQ */
|
||||
k6_data, sizeof(k6_data));
|
||||
memset(Klocaldata, 0, sizeof(Klocaldata));
|
||||
if (kret) {
|
||||
*minor_status = kret;
|
||||
major_status = GSS_S_FAILURE;
|
||||
goto failure;
|
||||
}
|
||||
|
||||
if (conf_req_flag) {
|
||||
EVP_CIPHER_CTX rc4_key;
|
||||
|
||||
EVP_CIPHER_CTX_init(&rc4_key);
|
||||
EVP_CipherInit_ex(&rc4_key, EVP_rc4(), NULL, k6_data, NULL, 1);
|
||||
|
||||
/* Confounder */
|
||||
EVP_Cipher(&rc4_key, p0 + 24, p0 + 24, 8);
|
||||
|
||||
/* Seal Data */
|
||||
for (i=0; i < iov_count; i++) {
|
||||
switch (GSS_IOV_BUFFER_TYPE(iov[i].type)) {
|
||||
case GSS_IOV_BUFFER_TYPE_DATA:
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
|
||||
EVP_Cipher(&rc4_key, iov[i].buffer.value,
|
||||
iov[i].buffer.value, iov[i].buffer.length);
|
||||
}
|
||||
|
||||
/* Padding */
|
||||
if (padding) {
|
||||
EVP_Cipher(&rc4_key, padding->buffer.value,
|
||||
padding->buffer.value, padding->buffer.length);
|
||||
}
|
||||
|
||||
EVP_CIPHER_CTX_cleanup(&rc4_key);
|
||||
}
|
||||
memset(k6_data, 0, sizeof(k6_data));
|
||||
|
||||
kret = arcfour_mic_key(context, key,
|
||||
p0 + 16, 8, /* SGN_CKSUM */
|
||||
k6_data, sizeof(k6_data));
|
||||
if (kret) {
|
||||
*minor_status = kret;
|
||||
major_status = GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
{
|
||||
EVP_CIPHER_CTX rc4_key;
|
||||
|
||||
EVP_CIPHER_CTX_init(&rc4_key);
|
||||
EVP_CipherInit_ex(&rc4_key, EVP_rc4(), NULL, k6_data, NULL, 1);
|
||||
EVP_Cipher(&rc4_key, p0 + 8, p0 + 8, 8); /* SND_SEQ */
|
||||
EVP_CIPHER_CTX_cleanup(&rc4_key);
|
||||
|
||||
memset(k6_data, 0, sizeof(k6_data));
|
||||
}
|
||||
|
||||
if (conf_state)
|
||||
*conf_state = conf_req_flag;
|
||||
|
||||
*minor_status = 0;
|
||||
return GSS_S_COMPLETE;
|
||||
|
||||
failure:
|
||||
|
||||
gss_release_iov_buffer(&junk, iov, iov_count);
|
||||
|
||||
return major_status;
|
||||
}
|
||||
|
||||
OM_uint32
|
||||
_gssapi_unwrap_iov_arcfour(OM_uint32 *minor_status,
|
||||
gsskrb5_ctx ctx,
|
||||
krb5_context context,
|
||||
int *pconf_state,
|
||||
gss_qop_t *pqop_state,
|
||||
gss_iov_buffer_desc *iov,
|
||||
int iov_count,
|
||||
krb5_keyblock *key)
|
||||
{
|
||||
OM_uint32 major_status;
|
||||
gss_iov_buffer_desc *header, *padding, *trailer;
|
||||
krb5_keyblock Klocal;
|
||||
uint8_t Klocaldata[16];
|
||||
uint8_t k6_data[16], snd_seq[8], Confounder[8];
|
||||
uint8_t cksum_data[8];
|
||||
uint8_t *_p = NULL;
|
||||
const uint8_t *p, *p0;
|
||||
size_t verify_len = 0;
|
||||
uint32_t seq_number;
|
||||
size_t hlen = 0;
|
||||
int conf_state;
|
||||
int cmp;
|
||||
size_t i;
|
||||
krb5_error_code kret;
|
||||
OM_uint32 ret;
|
||||
|
||||
if (pconf_state != NULL) {
|
||||
*pconf_state = 0;
|
||||
}
|
||||
if (pqop_state != NULL) {
|
||||
*pqop_state = 0;
|
||||
}
|
||||
|
||||
header = _gk_find_buffer(iov, iov_count, GSS_IOV_BUFFER_TYPE_HEADER);
|
||||
padding = _gk_find_buffer(iov, iov_count, GSS_IOV_BUFFER_TYPE_PADDING);
|
||||
trailer = _gk_find_buffer(iov, iov_count, GSS_IOV_BUFFER_TYPE_TRAILER);
|
||||
|
||||
/* Check if the packet is correct */
|
||||
major_status = _gk_verify_buffers(minor_status,
|
||||
ctx,
|
||||
header,
|
||||
padding,
|
||||
trailer);
|
||||
if (major_status != GSS_S_COMPLETE) {
|
||||
return major_status;
|
||||
}
|
||||
|
||||
if (padding != NULL && padding->buffer.length != 1) {
|
||||
*minor_status = EINVAL;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
if (IS_DCE_STYLE(context)) {
|
||||
verify_len = GSS_ARCFOUR_WRAP_TOKEN_SIZE +
|
||||
GSS_ARCFOUR_WRAP_TOKEN_DCE_DER_HEADER_SIZE;
|
||||
if (header->buffer.length > verify_len) {
|
||||
return GSS_S_BAD_MECH;
|
||||
}
|
||||
} else {
|
||||
verify_len = header->buffer.length;
|
||||
}
|
||||
_p = header->buffer.value;
|
||||
|
||||
ret = _gssapi_verify_mech_header(&_p,
|
||||
verify_len,
|
||||
GSS_KRB5_MECHANISM);
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
p0 = _p;
|
||||
|
||||
/* length of mech header */
|
||||
hlen = (p0 - (uint8_t *)header->buffer.value);
|
||||
hlen += GSS_ARCFOUR_WRAP_TOKEN_SIZE;
|
||||
|
||||
if (hlen > header->buffer.length) {
|
||||
return GSS_S_BAD_MECH;
|
||||
}
|
||||
|
||||
p = p0;
|
||||
|
||||
if (memcmp(p, "\x02\x01", 2) != 0)
|
||||
return GSS_S_BAD_SIG;
|
||||
p += 2;
|
||||
if (memcmp(p, "\x11\x00", 2) != 0) /* SGN_ALG = HMAC MD5 ARCFOUR */
|
||||
return GSS_S_BAD_SIG;
|
||||
p += 2;
|
||||
|
||||
if (memcmp (p, "\x10\x00", 2) == 0)
|
||||
conf_state = 1;
|
||||
else if (memcmp (p, "\xff\xff", 2) == 0)
|
||||
conf_state = 0;
|
||||
else
|
||||
return GSS_S_BAD_SIG;
|
||||
|
||||
p += 2;
|
||||
if (memcmp (p, "\xff\xff", 2) != 0)
|
||||
return GSS_S_BAD_MIC;
|
||||
p = NULL;
|
||||
|
||||
kret = arcfour_mic_key(context,
|
||||
key,
|
||||
p0 + 16, /* SGN_CKSUM */
|
||||
8, /* SGN_CKSUM_LEN */
|
||||
k6_data,
|
||||
sizeof(k6_data));
|
||||
if (kret) {
|
||||
*minor_status = kret;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
{
|
||||
EVP_CIPHER_CTX rc4_key;
|
||||
|
||||
EVP_CIPHER_CTX_init(&rc4_key);
|
||||
EVP_CipherInit_ex(&rc4_key, EVP_rc4(), NULL, k6_data, NULL, 1);
|
||||
EVP_Cipher(&rc4_key, snd_seq, p0 + 8, 8); /* SND_SEQ */
|
||||
EVP_CIPHER_CTX_cleanup(&rc4_key);
|
||||
|
||||
memset(k6_data, 0, sizeof(k6_data));
|
||||
}
|
||||
|
||||
_gsskrb5_decode_be_om_uint32(snd_seq, &seq_number);
|
||||
|
||||
if (ctx->more_flags & LOCAL) {
|
||||
cmp = memcmp(&snd_seq[4], "\xff\xff\xff\xff", 4);
|
||||
} else {
|
||||
cmp = memcmp(&snd_seq[4], "\x00\x00\x00\x00", 4);
|
||||
}
|
||||
if (cmp != 0) {
|
||||
*minor_status = 0;
|
||||
return GSS_S_BAD_MIC;
|
||||
}
|
||||
|
||||
if (ctx->more_flags & LOCAL) {
|
||||
cmp = memcmp(&snd_seq[4], "\xff\xff\xff\xff", 4);
|
||||
} else {
|
||||
cmp = memcmp(&snd_seq[4], "\x00\x00\x00\x00", 4);
|
||||
}
|
||||
if (cmp != 0) {
|
||||
*minor_status = 0;
|
||||
return GSS_S_BAD_MIC;
|
||||
}
|
||||
|
||||
/* keyblock */
|
||||
Klocal.keytype = key->keytype;
|
||||
Klocal.keyvalue.data = Klocaldata;
|
||||
Klocal.keyvalue.length = sizeof(Klocaldata);
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
Klocaldata[i] = ((u_char *)key->keyvalue.data)[i] ^ 0xF0;
|
||||
}
|
||||
|
||||
kret = arcfour_mic_key(context,
|
||||
&Klocal,
|
||||
snd_seq,
|
||||
4,
|
||||
k6_data, sizeof(k6_data));
|
||||
memset(Klocaldata, 0, sizeof(Klocaldata));
|
||||
if (kret) {
|
||||
*minor_status = kret;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
if (conf_state == 1) {
|
||||
EVP_CIPHER_CTX rc4_key;
|
||||
|
||||
EVP_CIPHER_CTX_init(&rc4_key);
|
||||
EVP_CipherInit_ex(&rc4_key, EVP_rc4(), NULL, k6_data, NULL, 1);
|
||||
|
||||
/* Confounder */
|
||||
EVP_Cipher(&rc4_key, Confounder, p0 + 24, 8);
|
||||
|
||||
/* Data */
|
||||
for (i = 0; i < iov_count; i++) {
|
||||
switch (GSS_IOV_BUFFER_TYPE(iov[i].type)) {
|
||||
case GSS_IOV_BUFFER_TYPE_DATA:
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
|
||||
EVP_Cipher(&rc4_key, iov[i].buffer.value,
|
||||
iov[i].buffer.value, iov[i].buffer.length);
|
||||
}
|
||||
|
||||
/* Padding */
|
||||
if (padding) {
|
||||
EVP_Cipher(&rc4_key, padding->buffer.value,
|
||||
padding->buffer.value, padding->buffer.length);
|
||||
}
|
||||
|
||||
EVP_CIPHER_CTX_cleanup(&rc4_key);
|
||||
} else {
|
||||
/* Confounder */
|
||||
memcpy(Confounder, p0 + 24, 8);
|
||||
}
|
||||
memset(k6_data, 0, sizeof(k6_data));
|
||||
|
||||
/* Prepare the buffer for signing */
|
||||
kret = arcfour_mic_cksum_iov(context,
|
||||
key, KRB5_KU_USAGE_SEAL,
|
||||
cksum_data, sizeof(cksum_data),
|
||||
p0, 8,
|
||||
Confounder, sizeof(Confounder),
|
||||
iov, iov_count,
|
||||
padding);
|
||||
if (kret) {
|
||||
*minor_status = kret;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
cmp = memcmp(cksum_data, p0 + 16, 8); /* SGN_CKSUM */
|
||||
if (cmp != 0) {
|
||||
*minor_status = 0;
|
||||
return GSS_S_BAD_MIC;
|
||||
}
|
||||
|
||||
if (padding) {
|
||||
size_t plen;
|
||||
|
||||
ret = _gssapi_verify_pad(&padding->buffer, 1, &plen);
|
||||
if (ret) {
|
||||
*minor_status = 0;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
|
||||
ret = _gssapi_msg_order_check(ctx->order, seq_number);
|
||||
HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (pconf_state) {
|
||||
*pconf_state = conf_state;
|
||||
}
|
||||
|
||||
*minor_status = 0;
|
||||
return GSS_S_COMPLETE;
|
||||
}
|
||||
|
@@ -190,6 +190,9 @@ _gssapi_verify_pad(gss_buffer_t wrapped_token,
|
||||
size_t padlength;
|
||||
int i;
|
||||
|
||||
if (wrapped_token->length < 1)
|
||||
return GSS_S_BAD_MECH;
|
||||
|
||||
pad = (u_char *)wrapped_token->value + wrapped_token->length - 1;
|
||||
padlength = *pad;
|
||||
|
||||
|
@@ -28,5 +28,6 @@ error_code NO_WRITE_SUPPORT, "HDB backend doesn't contain write support"
|
||||
error_code NOT_FOUND_HERE, "The secret for this entry is not replicated to this database"
|
||||
error_code MISUSE, "Incorrect use of the API"
|
||||
error_code KVNO_NOT_FOUND, "Entry key version number not found"
|
||||
error_code WRONG_REALM, "The principal exists in another realm."
|
||||
|
||||
end
|
||||
|
@@ -2330,6 +2330,17 @@ krb5_init_creds_step(krb5_context context,
|
||||
ret = krb5_principal_set_realm(context,
|
||||
ctx->cred.client,
|
||||
*ctx->error.crealm);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
if (krb5_principal_is_krbtgt(context, ctx->cred.server)) {
|
||||
ret = krb5_init_creds_set_service(context, ctx, NULL);
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
|
||||
free_AS_REQ(&ctx->as_req);
|
||||
memset(&ctx->as_req, 0, sizeof(ctx->as_req));
|
||||
|
||||
ctx->used_pa_types = 0;
|
||||
} else if (ret == KRB5KDC_ERR_KEY_EXP && ctx->runflags.change_password == 0 && ctx->prompter) {
|
||||
@@ -2379,6 +2390,15 @@ krb5_init_creds_step(krb5_context context,
|
||||
}
|
||||
}
|
||||
|
||||
if (ctx->as_req.req_body.cname == NULL) {
|
||||
ret = init_as_req(context, ctx->flags, &ctx->cred,
|
||||
ctx->addrs, ctx->etypes, &ctx->as_req);
|
||||
if (ret) {
|
||||
free_init_creds_ctx(context, ctx);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (ctx->as_req.padata) {
|
||||
free_METHOD_DATA(ctx->as_req.padata);
|
||||
free(ctx->as_req.padata);
|
||||
|
@@ -440,6 +440,7 @@ EXPORTS
|
||||
krb5_make_principal
|
||||
krb5_max_sockaddr_size
|
||||
krb5_mk_error
|
||||
krb5_mk_error_ext
|
||||
krb5_mk_priv
|
||||
krb5_mk_rep
|
||||
krb5_mk_req
|
||||
|
@@ -34,12 +34,13 @@
|
||||
#include "krb5_locl.h"
|
||||
|
||||
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
|
||||
krb5_mk_error(krb5_context context,
|
||||
krb5_mk_error_ext(krb5_context context,
|
||||
krb5_error_code error_code,
|
||||
const char *e_text,
|
||||
const krb5_data *e_data,
|
||||
const krb5_principal client,
|
||||
const krb5_principal server,
|
||||
const PrincipalName *client_name,
|
||||
const Realm *client_realm,
|
||||
time_t *client_time,
|
||||
int *client_usec,
|
||||
krb5_data *reply)
|
||||
@@ -78,10 +79,8 @@ krb5_mk_error(krb5_context context,
|
||||
static char unspec[] = "<unspecified realm>";
|
||||
msg.realm = unspec;
|
||||
}
|
||||
if(client){
|
||||
msg.crealm = &client->realm;
|
||||
msg.cname = &client->name;
|
||||
}
|
||||
msg.crealm = rk_UNCONST(client_realm);
|
||||
msg.cname = rk_UNCONST(client_name);
|
||||
|
||||
ASN1_MALLOC_ENCODE(KRB_ERROR, reply->data, reply->length, &msg, &len, ret);
|
||||
if (e_text2)
|
||||
@@ -92,3 +91,27 @@ krb5_mk_error(krb5_context context,
|
||||
krb5_abortx(context, "internal error in ASN.1 encoder");
|
||||
return 0;
|
||||
}
|
||||
|
||||
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
|
||||
krb5_mk_error(krb5_context context,
|
||||
krb5_error_code error_code,
|
||||
const char *e_text,
|
||||
const krb5_data *e_data,
|
||||
const krb5_principal client,
|
||||
const krb5_principal server,
|
||||
time_t *client_time,
|
||||
int *client_usec,
|
||||
krb5_data *reply)
|
||||
{
|
||||
const PrincipalName *client_name = NULL;
|
||||
const Realm *client_realm = NULL;
|
||||
|
||||
if (client) {
|
||||
client_realm = &client->realm;
|
||||
client_name = &client->name;
|
||||
}
|
||||
|
||||
return krb5_mk_error_ext(context, error_code, e_text, e_data,
|
||||
server, client_name, client_realm,
|
||||
client_time, client_usec, reply);
|
||||
}
|
||||
|
@@ -595,11 +595,12 @@ verify_logonname(krb5_context context,
|
||||
krb5_const_principal principal)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
krb5_principal p2;
|
||||
uint32_t time1, time2;
|
||||
krb5_storage *sp;
|
||||
uint16_t len;
|
||||
char *s;
|
||||
char *s = NULL;
|
||||
char *principal_string = NULL;
|
||||
char *logon_string = NULL;
|
||||
|
||||
sp = krb5_storage_from_readonly_mem((const char *)data->data + logon_name->offset_lo,
|
||||
logon_name->buffersize);
|
||||
@@ -670,31 +671,36 @@ verify_logonname(krb5_context context,
|
||||
return ret;
|
||||
}
|
||||
u8len += 1; /* Add space for NUL */
|
||||
s = malloc(u8len);
|
||||
if (s == NULL) {
|
||||
logon_string = malloc(u8len);
|
||||
if (logon_string == NULL) {
|
||||
free(ucs2);
|
||||
return krb5_enomem(context);
|
||||
}
|
||||
ret = wind_ucs2utf8(ucs2, ucs2len, s, &u8len);
|
||||
ret = wind_ucs2utf8(ucs2, ucs2len, logon_string, &u8len);
|
||||
free(ucs2);
|
||||
if (ret) {
|
||||
free(s);
|
||||
free(logon_string);
|
||||
krb5_set_error_message(context, ret, "Failed to convert to UTF-8");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
ret = krb5_parse_name_flags(context, s,
|
||||
KRB5_PRINCIPAL_PARSE_NO_REALM |
|
||||
KRB5_PRINCIPAL_PARSE_ENTERPRISE, &p2);
|
||||
free(s);
|
||||
if (ret)
|
||||
ret = krb5_unparse_name_flags(context, principal,
|
||||
KRB5_PRINCIPAL_UNPARSE_NO_REALM |
|
||||
KRB5_PRINCIPAL_UNPARSE_DISPLAY,
|
||||
&principal_string);
|
||||
if (ret) {
|
||||
free(logon_string);
|
||||
return ret;
|
||||
|
||||
if (krb5_principal_compare_any_realm(context, principal, p2) != TRUE) {
|
||||
ret = EINVAL;
|
||||
krb5_set_error_message(context, ret, "PAC logon name mismatch");
|
||||
}
|
||||
krb5_free_principal(context, p2);
|
||||
|
||||
ret = strcmp(logon_string, principal_string);
|
||||
if (ret != 0) {
|
||||
ret = EINVAL;
|
||||
krb5_set_error_message(context, ret, "PAC logon name [%s] mismatch principal name [%s]",
|
||||
logon_string, principal_string);
|
||||
}
|
||||
free(logon_string);
|
||||
free(principal_string);
|
||||
return ret;
|
||||
out:
|
||||
return ret;
|
||||
|
@@ -433,6 +433,7 @@ HEIMDAL_KRB5_2.0 {
|
||||
krb5_make_principal;
|
||||
krb5_max_sockaddr_size;
|
||||
krb5_mk_error;
|
||||
krb5_mk_error_ext;
|
||||
krb5_mk_priv;
|
||||
krb5_mk_rep;
|
||||
krb5_mk_req;
|
||||
|
@@ -23,6 +23,7 @@ $(libheimntlm_la_OBJECTS): $(srcdir)/version-script.map
|
||||
|
||||
libheimntlm_la_LIBADD = \
|
||||
../krb5/libkrb5.la \
|
||||
$(top_builddir)/lib/wind/libwind.la \
|
||||
$(LIB_hcrypto) \
|
||||
$(LIBADD_roken)
|
||||
|
||||
|
Reference in New Issue
Block a user