summaryrefslogtreecommitdiff
path: root/source4/heimdal/lib
diff options
context:
space:
mode:
Diffstat (limited to 'source4/heimdal/lib')
-rw-r--r--source4/heimdal/lib/asn1/der_get.c14
-rw-r--r--source4/heimdal/lib/asn1/der_put.c9
-rw-r--r--source4/heimdal/lib/asn1/krb5.asn13
-rw-r--r--source4/heimdal/lib/asn1/main.c6
-rw-r--r--source4/heimdal/lib/gssapi/gssapi/gssapi.h27
-rw-r--r--source4/heimdal/lib/gssapi/gssapi/gssapi_krb5.h8
-rw-r--r--source4/heimdal/lib/gssapi/gssapi/gssapi_spnego.h8
-rw-r--r--source4/heimdal/lib/gssapi/gssapi_mech.h11
-rw-r--r--source4/heimdal/lib/gssapi/krb5/accept_sec_context.c12
-rw-r--r--source4/heimdal/lib/gssapi/krb5/acquire_cred.c4
-rw-r--r--source4/heimdal/lib/gssapi/krb5/canonicalize_name.c2
-rw-r--r--source4/heimdal/lib/gssapi/krb5/copy_ccache.c10
-rw-r--r--source4/heimdal/lib/gssapi/krb5/creds.c253
-rw-r--r--source4/heimdal/lib/gssapi/krb5/external.c5
-rw-r--r--source4/heimdal/lib/gssapi/krb5/import_name.c13
-rw-r--r--source4/heimdal/lib/gssapi/krb5/init_sec_context.c2
-rw-r--r--source4/heimdal/lib/gssapi/krb5/set_cred_option.c4
-rw-r--r--source4/heimdal/lib/gssapi/krb5/store_cred.c116
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_aeap.c16
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_cred.c224
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_release_name.c35
-rw-r--r--source4/heimdal/lib/gssapi/spnego/cred_stubs.c36
-rw-r--r--source4/heimdal/lib/gssapi/spnego/external.c8
-rw-r--r--source4/heimdal/lib/hcrypto/camellia-ntt.c6
-rw-r--r--source4/heimdal/lib/hcrypto/camellia.c8
-rw-r--r--source4/heimdal/lib/hdb/hdb.c1
-rw-r--r--source4/heimdal/lib/hdb/keytab.c171
-rw-r--r--source4/heimdal/lib/hx509/ks_file.c4
-rw-r--r--source4/heimdal/lib/hx509/name.c8
-rw-r--r--source4/heimdal/lib/krb5/crypto.c13
-rw-r--r--source4/heimdal/lib/krb5/get_cred.c60
-rw-r--r--source4/heimdal/lib/krb5/kcm.c2
-rw-r--r--source4/heimdal/lib/krb5/keytab_file.c2
-rw-r--r--source4/heimdal/lib/krb5/log.c7
-rw-r--r--source4/heimdal/lib/krb5/pkinit.c10
-rw-r--r--source4/heimdal/lib/krb5/plugin.c200
-rw-r--r--source4/heimdal/lib/krb5/principal.c38
-rw-r--r--source4/heimdal/lib/krb5/store_fd.c2
-rw-r--r--source4/heimdal/lib/krb5/store_mem.c6
-rw-r--r--source4/heimdal/lib/krb5/transited.c47
-rw-r--r--source4/heimdal/lib/krb5/warn.c6
-rw-r--r--source4/heimdal/lib/roken/base64.c5
-rw-r--r--source4/heimdal/lib/roken/strpool.c5
-rw-r--r--source4/heimdal/lib/roken/vis.hin9
44 files changed, 1090 insertions, 346 deletions
diff --git a/source4/heimdal/lib/asn1/der_get.c b/source4/heimdal/lib/asn1/der_get.c
index 8144639b9a..aee565040f 100644
--- a/source4/heimdal/lib/asn1/der_get.c
+++ b/source4/heimdal/lib/asn1/der_get.c
@@ -198,6 +198,13 @@ der_get_bmp_string (const unsigned char *p, size_t len,
for (i = 0; i < data->length; i++) {
data->data[i] = (p[0] << 8) | p[1];
p += 2;
+ /* check for NUL in the middle of the string */
+ if (data->data[i] == 0 && i != (data->length - 1)) {
+ free(data->data);
+ data->data = NULL;
+ data->length = 0;
+ return ASN1_BAD_CHARACTER;
+ }
}
if (size) *size = len;
@@ -222,6 +229,13 @@ der_get_universal_string (const unsigned char *p, size_t len,
for (i = 0; i < data->length; i++) {
data->data[i] = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
p += 4;
+ /* check for NUL in the middle of the string */
+ if (data->data[i] == 0 && i != (data->length - 1)) {
+ free(data->data);
+ data->data = NULL;
+ data->length = 0;
+ return ASN1_BAD_CHARACTER;
+ }
}
if (size) *size = len;
return 0;
diff --git a/source4/heimdal/lib/asn1/der_put.c b/source4/heimdal/lib/asn1/der_put.c
index 7e71443da5..10fc002334 100644
--- a/source4/heimdal/lib/asn1/der_put.c
+++ b/source4/heimdal/lib/asn1/der_put.c
@@ -165,7 +165,6 @@ der_put_general_string (unsigned char *p, size_t len,
if (len < slen)
return ASN1_OVERFLOW;
p -= slen;
- len -= slen;
memcpy (p+1, *str, slen);
*size = slen;
return 0;
@@ -200,7 +199,6 @@ der_put_bmp_string (unsigned char *p, size_t len,
if (len / 2 < data->length)
return ASN1_OVERFLOW;
p -= data->length * 2;
- len -= data->length * 2;
for (i = 0; i < data->length; i++) {
p[1] = (data->data[i] >> 8) & 0xff;
p[2] = data->data[i] & 0xff;
@@ -218,7 +216,6 @@ der_put_universal_string (unsigned char *p, size_t len,
if (len / 4 < data->length)
return ASN1_OVERFLOW;
p -= data->length * 4;
- len -= data->length * 4;
for (i = 0; i < data->length; i++) {
p[1] = (data->data[i] >> 24) & 0xff;
p[2] = (data->data[i] >> 16) & 0xff;
@@ -244,7 +241,6 @@ der_put_octet_string (unsigned char *p, size_t len,
if (len < data->length)
return ASN1_OVERFLOW;
p -= data->length;
- len -= data->length;
memcpy (p+1, data->data, data->length);
*size = data->length;
return 0;
@@ -421,8 +417,7 @@ der_put_length_and_tag (unsigned char *p, size_t len, size_t len_val,
e = der_put_tag (p, len, class, type, tag, &l);
if(e)
return e;
- p -= l;
- len -= l;
+
ret += l;
*size = ret;
return 0;
@@ -459,7 +454,7 @@ der_put_bit_string (unsigned char *p, size_t len,
if (len < data_size + 1)
return ASN1_OVERFLOW;
p -= data_size + 1;
- len -= data_size + 1;
+
memcpy (p+2, data->data, data_size);
if (data->length && (data->length % 8) != 0)
p[1] = 8 - (data->length % 8);
diff --git a/source4/heimdal/lib/asn1/krb5.asn1 b/source4/heimdal/lib/asn1/krb5.asn1
index 8edb0fde69..7080b095f8 100644
--- a/source4/heimdal/lib/asn1/krb5.asn1
+++ b/source4/heimdal/lib/asn1/krb5.asn1
@@ -16,7 +16,8 @@ NAME-TYPE ::= INTEGER {
KRB5_NT_WELLKNOWN(11), -- Wellknown
KRB5_NT_ENT_PRINCIPAL_AND_ID(-130), -- Windows 2000 UPN and SID
KRB5_NT_MS_PRINCIPAL(-128), -- NT 4 style name
- KRB5_NT_MS_PRINCIPAL_AND_ID(-129) -- NT style name and SID
+ KRB5_NT_MS_PRINCIPAL_AND_ID(-129), -- NT style name and SID
+ KRB5_NT_NTLM(-1200) -- NTLM name, realm is domain
}
-- message types
diff --git a/source4/heimdal/lib/asn1/main.c b/source4/heimdal/lib/asn1/main.c
index 115c82a9c7..5cef970d78 100644
--- a/source4/heimdal/lib/asn1/main.c
+++ b/source4/heimdal/lib/asn1/main.c
@@ -142,6 +142,10 @@ main(int argc, char **argv)
}
arg = calloc(2, sizeof(arg[0]));
+ if (arg == NULL) {
+ perror("calloc");
+ exit(1);
+ }
arg[0] = option_file;
arg[1] = NULL;
len = 1;
@@ -150,7 +154,7 @@ main(int argc, char **argv)
buf[strcspn(buf, "\n\r")] = '\0';
arg = realloc(arg, (len + 2) * sizeof(arg[0]));
- if (argv == NULL) {
+ if (arg == NULL) {
perror("malloc");
exit(1);
}
diff --git a/source4/heimdal/lib/gssapi/gssapi/gssapi.h b/source4/heimdal/lib/gssapi/gssapi/gssapi.h
index 91141808f5..6052ec8134 100644
--- a/source4/heimdal/lib/gssapi/gssapi/gssapi.h
+++ b/source4/heimdal/lib/gssapi/gssapi/gssapi.h
@@ -63,6 +63,14 @@
#endif
#endif
+#ifdef __cplusplus
+#define GSSAPI_CPP_START extern "C" {
+#define GSSAPI_CPP_END }
+#else
+#define GSSAPI_CPP_START
+#define GSSAPI_CPP_END
+#endif
+
/*
* Now define the three implementation-dependent types.
*/
@@ -243,9 +251,7 @@ typedef OM_uint32 gss_qop_t;
#define GSS_IOV_BUFFER_TYPE(_t) ((_t) & ~GSS_IOV_BUFFER_TYPE_FLAG_MASK)
#define GSS_IOV_BUFFER_FLAGS(_t) ((_t) & GSS_IOV_BUFFER_TYPE_FLAG_MASK)
-#ifdef __cplusplus
-extern "C" {
-#endif
+GSSAPI_CPP_START
/*
* The implementation must reserve static storage for a
@@ -894,8 +900,17 @@ OM_uint32 GSSAPI_LIB_FUNCTION
gss_release_iov_buffer(OM_uint32 *, gss_iov_buffer_desc *, int);
-#ifdef __cplusplus
-}
-#endif
+OM_uint32 GSSAPI_LIB_FUNCTION
+gss_export_cred(OM_uint32 * /* minor_status */,
+ gss_cred_id_t /* cred_handle */,
+ gss_buffer_t /* cred_token */);
+
+OM_uint32 GSSAPI_LIB_FUNCTION
+gss_import_cred(OM_uint32 * /* minor_status */,
+ gss_buffer_t /* cred_token */,
+ gss_cred_id_t * /* cred_handle */);
+
+
+GSSAPI_CPP_END
#endif /* GSSAPI_GSSAPI_H_ */
diff --git a/source4/heimdal/lib/gssapi/gssapi/gssapi_krb5.h b/source4/heimdal/lib/gssapi/gssapi/gssapi_krb5.h
index 0baccf5098..4d004d90b5 100644
--- a/source4/heimdal/lib/gssapi/gssapi/gssapi_krb5.h
+++ b/source4/heimdal/lib/gssapi/gssapi/gssapi_krb5.h
@@ -38,9 +38,7 @@
#include <gssapi.h>
-#ifdef __cplusplus
-extern "C" {
-#endif
+GSSAPI_CPP_START
#if !defined(__GNUC__) && !defined(__attribute__)
#define __attribute__(x)
@@ -246,8 +244,6 @@ gss_krb5_set_allowable_enctypes(OM_uint32 *minor_status,
OM_uint32 num_enctypes,
int32_t *enctypes);
-#ifdef __cplusplus
-}
-#endif
+GSSAPI_CPP_END
#endif /* GSSAPI_SPNEGO_H_ */
diff --git a/source4/heimdal/lib/gssapi/gssapi/gssapi_spnego.h b/source4/heimdal/lib/gssapi/gssapi/gssapi_spnego.h
index 3c4869f08d..c5d372d6dc 100644
--- a/source4/heimdal/lib/gssapi/gssapi/gssapi_spnego.h
+++ b/source4/heimdal/lib/gssapi/gssapi/gssapi_spnego.h
@@ -38,9 +38,7 @@
#include <gssapi.h>
-#ifdef __cplusplus
-extern "C" {
-#endif
+GSSAPI_CPP_START
/*
* RFC2478, SPNEGO:
@@ -51,8 +49,6 @@ extern "C" {
extern GSSAPI_LIB_VARIABLE gss_OID GSS_SPNEGO_MECHANISM;
#define gss_mech_spnego GSS_SPNEGO_MECHANISM
-#ifdef __cplusplus
-}
-#endif
+GSSAPI_CPP_END
#endif /* GSSAPI_SPNEGO_H_ */
diff --git a/source4/heimdal/lib/gssapi/gssapi_mech.h b/source4/heimdal/lib/gssapi/gssapi_mech.h
index 6470df30a0..206a24ef74 100644
--- a/source4/heimdal/lib/gssapi/gssapi_mech.h
+++ b/source4/heimdal/lib/gssapi/gssapi_mech.h
@@ -343,6 +343,15 @@ _gss_store_cred_t(OM_uint32 *minor_status,
gss_OID_set *elements_stored,
gss_cred_usage_t *cred_usage_stored);
+typedef OM_uint32
+_gss_export_cred_t(OM_uint32 *minor_status,
+ gss_cred_id_t cred_handle,
+ gss_buffer_t cred_token);
+
+typedef OM_uint32
+_gss_import_cred_t(OM_uint32 * minor_status,
+ gss_buffer_t cred_token,
+ gss_cred_id_t * cred_handle);
#define GMI_VERSION 2
@@ -389,6 +398,8 @@ typedef struct gssapi_mech_interface_desc {
_gss_unwrap_iov_t *gm_unwrap_iov;
_gss_wrap_iov_length_t *gm_wrap_iov_length;
_gss_store_cred_t *gm_store_cred;
+ _gss_export_cred_t *gm_export_cred;
+ _gss_import_cred_t *gm_import_cred;
} gssapi_mech_interface_desc, *gssapi_mech_interface;
gssapi_mech_interface
diff --git a/source4/heimdal/lib/gssapi/krb5/accept_sec_context.c b/source4/heimdal/lib/gssapi/krb5/accept_sec_context.c
index 8d998ed098..355d1c4332 100644
--- a/source4/heimdal/lib/gssapi/krb5/accept_sec_context.c
+++ b/source4/heimdal/lib/gssapi/krb5/accept_sec_context.c
@@ -170,12 +170,12 @@ gsskrb5_accept_delegated_token
if (delegated_cred_handle) {
gsskrb5_cred handle;
-
- ret = _gsskrb5_import_cred(minor_status,
- ccache,
- NULL,
- NULL,
- delegated_cred_handle);
+
+ ret = _gsskrb5_krb5_import_cred(minor_status,
+ ccache,
+ NULL,
+ NULL,
+ delegated_cred_handle);
if (ret != GSS_S_COMPLETE)
goto out;
diff --git a/source4/heimdal/lib/gssapi/krb5/acquire_cred.c b/source4/heimdal/lib/gssapi/krb5/acquire_cred.c
index 4f6f38e674..696171dcfa 100644
--- a/source4/heimdal/lib/gssapi/krb5/acquire_cred.c
+++ b/source4/heimdal/lib/gssapi/krb5/acquire_cred.c
@@ -339,8 +339,8 @@ OM_uint32 _gsskrb5_acquire_cred
if (desired_name != GSS_C_NO_NAME) {
- ret = _gsskrb5_canon_name(minor_status, context, 0, desired_name,
- &handle->principal);
+ ret = _gsskrb5_canon_name(minor_status, context, 0, NULL,
+ desired_name, &handle->principal);
if (ret) {
HEIMDAL_MUTEX_destroy(&handle->cred_id_mutex);
free(handle);
diff --git a/source4/heimdal/lib/gssapi/krb5/canonicalize_name.c b/source4/heimdal/lib/gssapi/krb5/canonicalize_name.c
index 7e0c3fe727..3de55d6e32 100644
--- a/source4/heimdal/lib/gssapi/krb5/canonicalize_name.c
+++ b/source4/heimdal/lib/gssapi/krb5/canonicalize_name.c
@@ -48,7 +48,7 @@ OM_uint32 _gsskrb5_canonicalize_name (
GSSAPI_KRB5_INIT (&context);
- ret = _gsskrb5_canon_name(minor_status, context, 1, input_name, &name);
+ ret = _gsskrb5_canon_name(minor_status, context, 1, NULL, input_name, &name);
if (ret)
return ret;
diff --git a/source4/heimdal/lib/gssapi/krb5/copy_ccache.c b/source4/heimdal/lib/gssapi/krb5/copy_ccache.c
index a4b28f91ed..4e65fc1cf3 100644
--- a/source4/heimdal/lib/gssapi/krb5/copy_ccache.c
+++ b/source4/heimdal/lib/gssapi/krb5/copy_ccache.c
@@ -63,11 +63,11 @@ gss_krb5_copy_ccache(OM_uint32 *minor_status,
OM_uint32
-_gsskrb5_import_cred(OM_uint32 *minor_status,
- krb5_ccache id,
- krb5_principal keytab_principal,
- krb5_keytab keytab,
- gss_cred_id_t *cred)
+_gsskrb5_krb5_import_cred(OM_uint32 *minor_status,
+ krb5_ccache id,
+ krb5_principal keytab_principal,
+ krb5_keytab keytab,
+ gss_cred_id_t *cred)
{
krb5_context context;
krb5_error_code kret;
diff --git a/source4/heimdal/lib/gssapi/krb5/creds.c b/source4/heimdal/lib/gssapi/krb5/creds.c
new file mode 100644
index 0000000000..c9befe9d77
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/krb5/creds.c
@@ -0,0 +1,253 @@
+/*
+ * Copyright (c) 2009 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 "gsskrb5_locl.h"
+
+OM_uint32
+_gsskrb5_export_cred(OM_uint32 *minor_status,
+ gss_cred_id_t cred_handle,
+ gss_buffer_t cred_token)
+{
+ gsskrb5_cred handle = (gsskrb5_cred)cred_handle;
+ krb5_context context;
+ krb5_error_code ret;
+ krb5_storage *sp;
+ krb5_data data, mech;
+ const char *type;
+ char *str;
+
+ GSSAPI_KRB5_INIT (&context);
+
+ if (handle->usage != GSS_C_INITIATE && handle->usage != GSS_C_BOTH) {
+ *minor_status = GSS_KRB5_S_G_BAD_USAGE;
+ return GSS_S_FAILURE;
+ }
+
+ sp = krb5_storage_emem();
+ if (sp == NULL) {
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+
+ type = krb5_cc_get_type(context, handle->ccache);
+ if (strcmp(type, "MEMORY") == 0) {
+ krb5_creds *creds;
+ ret = krb5_store_uint32(sp, 0);
+ if (ret) {
+ krb5_storage_free(sp);
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+
+ ret = _krb5_get_krbtgt(context, handle->ccache,
+ handle->principal->realm,
+ &creds);
+ if (ret) {
+ krb5_storage_free(sp);
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+
+ ret = krb5_store_creds(sp, creds);
+ krb5_free_creds(context, creds);
+ if (ret) {
+ krb5_storage_free(sp);
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+
+ } else {
+ ret = krb5_store_uint32(sp, 1);
+ if (ret) {
+ krb5_storage_free(sp);
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+
+ ret = krb5_cc_get_full_name(context, handle->ccache, &str);
+ if (ret) {
+ krb5_storage_free(sp);
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+
+ ret = krb5_store_string(sp, str);
+ free(str);
+ if (ret) {
+ krb5_storage_free(sp);
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+ }
+ ret = krb5_storage_to_data(sp, &data);
+ krb5_storage_free(sp);
+ if (ret) {
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+ sp = krb5_storage_emem();
+ if (sp == NULL) {
+ krb5_data_free(&data);
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+
+ mech.data = GSS_KRB5_MECHANISM->elements;
+ mech.length = GSS_KRB5_MECHANISM->length;
+
+ ret = krb5_store_data(sp, mech);
+ if (ret) {
+ krb5_data_free(&data);
+ krb5_storage_free(sp);
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+
+ ret = krb5_store_data(sp, data);
+ krb5_data_free(&data);
+ if (ret) {
+ krb5_storage_free(sp);
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+
+ ret = krb5_storage_to_data(sp, &data);
+ krb5_storage_free(sp);
+ if (ret) {
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+
+ cred_token->value = data.data;
+ cred_token->length = data.length;
+
+ return GSS_S_COMPLETE;
+}
+
+OM_uint32
+_gsskrb5_import_cred(OM_uint32 * minor_status,
+ gss_buffer_t cred_token,
+ gss_cred_id_t * cred_handle)
+{
+ krb5_context context;
+ krb5_error_code ret;
+ gsskrb5_cred handle;
+ krb5_ccache id;
+ krb5_storage *sp;
+ char *str;
+ uint32_t type;
+ int flags = 0;
+
+ *cred_handle = GSS_C_NO_CREDENTIAL;
+
+ GSSAPI_KRB5_INIT (&context);
+
+ sp = krb5_storage_from_mem(cred_token->value, cred_token->length);
+ if (sp == NULL) {
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+
+ ret = krb5_ret_uint32(sp, &type);
+ if (ret) {
+ krb5_storage_free(sp);
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+ switch (type) {
+ case 0: {
+ krb5_creds creds;
+
+ ret = krb5_ret_creds(sp, &creds);
+ krb5_storage_free(sp);
+ if (ret) {
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+
+ ret = krb5_cc_new_unique(context, "MEMORY", NULL, &id);
+ if (ret) {
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+
+ ret = krb5_cc_initialize(context, id, creds.client);
+ if (ret) {
+ krb5_cc_destroy(context, id);
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+
+ ret = krb5_cc_store_cred(context, id, &creds);
+ krb5_free_cred_contents(context, &creds);
+
+ flags |= GSS_CF_DESTROY_CRED_ON_RELEASE;
+
+ break;
+ }
+ case 1:
+ ret = krb5_ret_string(sp, &str);
+ krb5_storage_free(sp);
+ if (ret) {
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+
+ ret = krb5_cc_resolve(context, str, &id);
+ krb5_xfree(str);
+ if (ret) {
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+ break;
+
+ default:
+ krb5_storage_free(sp);
+ *minor_status = 0;
+ return GSS_S_NO_CRED;
+ }
+
+ handle = calloc(1, sizeof(*handle));
+ if (handle == NULL) {
+ krb5_cc_close(context, id);
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+
+ handle->usage = GSS_C_INITIATE;
+ krb5_cc_get_principal(context, id, &handle->principal);
+ handle->ccache = id;
+ handle->cred_flags = flags;
+
+ return GSS_S_COMPLETE;
+}
diff --git a/source4/heimdal/lib/gssapi/krb5/external.c b/source4/heimdal/lib/gssapi/krb5/external.c
index df23776a63..fc835bd845 100644
--- a/source4/heimdal/lib/gssapi/krb5/external.c
+++ b/source4/heimdal/lib/gssapi/krb5/external.c
@@ -470,7 +470,10 @@ static gssapi_mech_interface_desc krb5_mech = {
_gsskrb5_pseudo_random,
_gk_wrap_iov,
_gk_unwrap_iov,
- _gk_wrap_iov_length
+ _gk_wrap_iov_length,
+ _gsskrb5_store_cred,
+ _gsskrb5_export_cred,
+ _gsskrb5_import_cred
};
gssapi_mech_interface
diff --git a/source4/heimdal/lib/gssapi/krb5/import_name.c b/source4/heimdal/lib/gssapi/krb5/import_name.c
index d488ce754b..f1aca93ffd 100644
--- a/source4/heimdal/lib/gssapi/krb5/import_name.c
+++ b/source4/heimdal/lib/gssapi/krb5/import_name.c
@@ -83,9 +83,10 @@ import_krb5_name (OM_uint32 *minor_status,
OM_uint32
_gsskrb5_canon_name(OM_uint32 *minor_status, krb5_context context,
- int use_dns, gss_name_t name, krb5_principal *out)
+ int use_dns, krb5_const_principal sourcename, gss_name_t targetname,
+ krb5_principal *out)
{
- krb5_principal p = (krb5_principal)name;
+ krb5_principal p = (krb5_principal)targetname;
krb5_error_code ret;
char *hostname = NULL, *service;
@@ -96,8 +97,11 @@ _gsskrb5_canon_name(OM_uint32 *minor_status, krb5_context context,
ret = krb5_copy_principal(context, p, out);
} else if (!use_dns) {
ret = krb5_copy_principal(context, p, out);
- if (ret == 0)
- krb5_principal_set_type(context, *out, KRB5_NT_SRV_HST);
+ if (ret)
+ goto out;
+ krb5_principal_set_type(context, *out, KRB5_NT_SRV_HST);
+ if (sourcename)
+ ret = krb5_principal_set_realm(context, *out, sourcename->realm);
} else {
if (p->name.name_string.len == 0)
return GSS_S_BAD_NAME;
@@ -113,6 +117,7 @@ _gsskrb5_canon_name(OM_uint32 *minor_status, krb5_context context,
out);
}
+ out:
if (ret) {
*minor_status = ret;
return GSS_S_FAILURE;
diff --git a/source4/heimdal/lib/gssapi/krb5/init_sec_context.c b/source4/heimdal/lib/gssapi/krb5/init_sec_context.c
index 35ab9dd88d..b269d06798 100644
--- a/source4/heimdal/lib/gssapi/krb5/init_sec_context.c
+++ b/source4/heimdal/lib/gssapi/krb5/init_sec_context.c
@@ -191,7 +191,7 @@ gsskrb5_get_creds(
}
ret = _gsskrb5_canon_name(minor_status, context, use_dns,
- target_name, &ctx->target);
+ ctx->source, target_name, &ctx->target);
if (ret)
return ret;
diff --git a/source4/heimdal/lib/gssapi/krb5/set_cred_option.c b/source4/heimdal/lib/gssapi/krb5/set_cred_option.c
index 15d7632e4c..ee29bf8c66 100644
--- a/source4/heimdal/lib/gssapi/krb5/set_cred_option.c
+++ b/source4/heimdal/lib/gssapi/krb5/set_cred_option.c
@@ -119,8 +119,8 @@ import_cred(OM_uint32 *minor_status,
free(str);
str = NULL;
- major_stat = _gsskrb5_import_cred(minor_status, id, keytab_principal,
- keytab, cred_handle);
+ major_stat = _gsskrb5_krb5_import_cred(minor_status, id, keytab_principal,
+ keytab, cred_handle);
out:
if (id)
krb5_cc_close(context, id);
diff --git a/source4/heimdal/lib/gssapi/krb5/store_cred.c b/source4/heimdal/lib/gssapi/krb5/store_cred.c
new file mode 100644
index 0000000000..675a1d8e95
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/krb5/store_cred.c
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2003 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 "gsskrb5_locl.h"
+
+OM_uint32
+_gsskrb5_store_cred(OM_uint32 *minor_status,
+ gss_cred_id_t input_cred_handle,
+ gss_cred_usage_t cred_usage,
+ const gss_OID desired_mech,
+ OM_uint32 overwrite_cred,
+ OM_uint32 default_cred,
+ gss_OID_set *elements_stored,
+ gss_cred_usage_t *cred_usage_stored)
+{
+ krb5_context context;
+ krb5_error_code ret;
+ gsskrb5_cred cred;
+ krb5_ccache id;
+ int destroy = 0;
+
+ *minor_status = 0;
+
+ if (cred_usage != GSS_C_INITIATE) {
+ *minor_status = GSS_KRB5_S_G_BAD_USAGE;
+ return GSS_S_FAILURE;
+ }
+
+ if (gss_oid_equal(desired_mech, GSS_KRB5_MECHANISM) == 0)
+ return GSS_S_BAD_MECH;
+
+ cred = (gsskrb5_cred)input_cred_handle;
+ if (cred == NULL)
+ return GSS_S_NO_CRED;
+
+ GSSAPI_KRB5_INIT (&context);
+
+ HEIMDAL_MUTEX_lock(&cred->cred_id_mutex);
+ if (cred->usage != cred_usage && cred->usage != GSS_C_BOTH) {
+ HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex);
+ *minor_status = GSS_KRB5_S_G_BAD_USAGE;
+ return(GSS_S_FAILURE);
+ }
+
+ if (cred->principal == NULL) {
+ HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex);
+ *minor_status = GSS_KRB5_S_KG_TGT_MISSING;
+ return(GSS_S_FAILURE);
+ }
+
+ /* write out cred to credential cache */
+
+ ret = krb5_cc_cache_match(context, cred->principal, &id);
+ if (ret) {
+ ret = krb5_cc_new_unique(context, NULL, NULL, &id);
+ if (ret) {
+ HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex);
+ *minor_status = ret;
+ return(GSS_S_FAILURE);
+ }
+ destroy = 1;
+ }
+
+ ret = krb5_cc_initialize(context, id, cred->principal);
+ if (ret == 0)
+ ret = krb5_cc_copy_match_f(context, cred->ccache, id, NULL, NULL, NULL);
+ if (ret) {
+ if (destroy)
+ krb5_cc_destroy(context, id);
+ else
+ krb5_cc_close(context, id);
+ HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex);
+ *minor_status = ret;
+ return(GSS_S_FAILURE);
+ }
+
+ if (default_cred)
+ krb5_cc_switch(context, id);
+
+ krb5_cc_close(context, id);
+
+ HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex);
+
+ *minor_status = 0;
+ return GSS_S_COMPLETE;
+}
diff --git a/source4/heimdal/lib/gssapi/mech/gss_aeap.c b/source4/heimdal/lib/gssapi/mech/gss_aeap.c
index 9c784f42de..9a1835a039 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_aeap.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_aeap.c
@@ -66,11 +66,8 @@ gss_wrap_iov(OM_uint32 * minor_status,
m = ctx->gc_mech;
- if (m->gm_wrap_iov == NULL) {
- if (minor_status)
- *minor_status = 0;
+ if (m->gm_wrap_iov == NULL)
return GSS_S_UNAVAILABLE;
- }
return (m->gm_wrap_iov)(minor_status, ctx->gc_ctx,
conf_req_flag, qop_req, conf_state,
@@ -108,10 +105,8 @@ gss_unwrap_iov(OM_uint32 *minor_status,
m = ctx->gc_mech;
- if (m->gm_unwrap_iov == NULL) {
- *minor_status = 0;
+ if (m->gm_unwrap_iov == NULL)
return GSS_S_UNAVAILABLE;
- }
return (m->gm_unwrap_iov)(minor_status, ctx->gc_ctx,
conf_state, qop_state,
@@ -152,10 +147,8 @@ gss_wrap_iov_length(OM_uint32 * minor_status,
m = ctx->gc_mech;
- if (m->gm_wrap_iov_length == NULL) {
- *minor_status = 0;
+ if (m->gm_wrap_iov_length == NULL)
return GSS_S_UNAVAILABLE;
- }
return (m->gm_wrap_iov_length)(minor_status, ctx->gc_ctx,
conf_req_flag, qop_req, conf_state,
@@ -213,7 +206,8 @@ gss_context_query_attributes(OM_uint32 *minor_status,
void *data,
size_t len)
{
- *minor_status = 0;
+ if (minor_status)
+ *minor_status = 0;
if (gss_oid_equal(GSS_C_ATTR_STREAM_SIZES, attribute)) {
memset(data, 0, len);
diff --git a/source4/heimdal/lib/gssapi/mech/gss_cred.c b/source4/heimdal/lib/gssapi/mech/gss_cred.c
new file mode 100644
index 0000000000..66df50b55e
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/mech/gss_cred.c
@@ -0,0 +1,224 @@
+/*
+ * Copyright (c) 2009 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 KTH 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 KTH AND ITS 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 KTH OR ITS 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 "mech_locl.h"
+#include <krb5.h>
+
+/*
+ * format: any number of:
+ * mech-len: int32
+ * mech-data: char * (not alligned)
+ * cred-len: int32
+ * cred-data char * (not alligned)
+*/
+
+OM_uint32 GSSAPI_LIB_FUNCTION
+gss_export_cred(OM_uint32 * minor_status,
+ gss_cred_id_t cred_handle,
+ gss_buffer_t token)
+{
+ struct _gss_cred *cred = (struct _gss_cred *)cred_handle;
+ struct _gss_mechanism_cred *mc;
+ gss_buffer_desc buffer;
+ krb5_error_code ret;
+ krb5_storage *sp;
+ OM_uint32 major;
+ krb5_data data;
+
+ _mg_buffer_zero(token);
+
+ if (cred == NULL) {
+ *minor_status = 0;
+ return GSS_S_NO_CRED;
+ }
+
+ SLIST_FOREACH(mc, &cred->gc_mc, gmc_link) {
+ if (mc->gmc_mech->gm_export_cred == NULL) {
+ *minor_status = 0;
+ return GSS_S_NO_CRED;
+ }
+ }
+
+ sp = krb5_storage_emem();
+ if (sp == NULL) {
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+
+ SLIST_FOREACH(mc, &cred->gc_mc, gmc_link) {
+
+ major = mc->gmc_mech->gm_export_cred(minor_status,
+ mc->gmc_cred, &buffer);
+ if (major) {
+ krb5_storage_free(sp);
+ return major;
+ }
+
+ ret = krb5_storage_write(sp, buffer.value, buffer.length);
+ if (ret != buffer.length) {
+ gss_release_buffer(minor_status, &buffer);
+ krb5_storage_free(sp);
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+ }
+ gss_release_buffer(minor_status, &buffer);
+ }
+
+ ret = krb5_storage_to_data(sp, &data);
+ krb5_storage_free(sp);
+ if (ret) {
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+
+ token->value = data.data;
+ token->length = data.length;
+
+ return GSS_S_COMPLETE;
+}
+
+OM_uint32 GSSAPI_LIB_FUNCTION
+gss_import_cred(OM_uint32 * minor_status,
+ gss_buffer_t token,
+ gss_cred_id_t * cred_handle)
+{
+ gssapi_mech_interface m;
+ krb5_error_code ret;
+ struct _gss_cred *cred;
+ krb5_storage *sp = NULL;
+ OM_uint32 major, junk;
+ krb5_data data;
+
+ *cred_handle = GSS_C_NO_CREDENTIAL;
+
+ if (token->length == 0) {
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+
+ sp = krb5_storage_from_readonly_mem(token->value, token->length);
+ if (sp == NULL) {
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+
+ cred = calloc(1, sizeof(struct _gss_cred));
+ if (cred == NULL) {
+ krb5_storage_free(sp);
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+ SLIST_INIT(&cred->gc_mc);
+
+ *cred_handle = (gss_cred_id_t)cred;
+
+ while(1) {
+ struct _gss_mechanism_cred *mc;
+ gss_buffer_desc buffer;
+ gss_cred_id_t mcred;
+ gss_OID_desc oid;
+
+ ret = krb5_ret_data(sp, &data);
+ if (ret == HEIM_ERR_EOF) {
+ break;
+ } else if (ret) {
+ *minor_status = ret;
+ major = GSS_S_FAILURE;
+ goto out;
+ }
+ oid.elements = data.data;
+ oid.length = data.length;
+
+ m = __gss_get_mechanism(&oid);
+ krb5_data_free(&data);
+ if (!m) {
+ *minor_status = 0;
+ major = GSS_S_BAD_MECH;
+ goto out;
+ }
+
+ if (m->gm_import_cred == NULL) {
+ *minor_status = 0;
+ major = GSS_S_BAD_MECH;
+ goto out;
+ }
+
+ ret = krb5_ret_data(sp, &data);
+ if (ret) {
+ *minor_status = ret;
+ major = GSS_S_FAILURE;
+ goto out;
+ }
+
+ buffer.value = data.data;
+ buffer.length = data.length;
+
+ major = m->gm_import_cred(minor_status,
+ &buffer, &mcred);
+ krb5_data_free(&data);
+ if (major) {
+ goto out;
+ }
+
+ mc = malloc(sizeof(struct _gss_mechanism_cred));
+ if (mc == NULL) {
+ *minor_status = EINVAL;
+ major = GSS_S_FAILURE;
+ goto out;
+ }
+
+ mc->gmc_mech = m;
+ mc->gmc_mech_oid = &m->gm_mech_oid;
+ mc->gmc_cred = mcred;
+
+ SLIST_INSERT_HEAD(&cred->gc_mc, mc, gmc_link);
+ }
+ krb5_storage_free(sp);
+ sp = NULL;
+
+ if (SLIST_EMPTY(&cred->gc_mc)) {
+ major = GSS_S_NO_CRED;
+ goto out;
+ }
+
+ return GSS_S_COMPLETE;
+
+ out:
+ if (sp)
+ krb5_storage_free(sp);
+
+ gss_release_cred(&junk, cred_handle);
+
+ return major;
+
+}
diff --git a/source4/heimdal/lib/gssapi/mech/gss_release_name.c b/source4/heimdal/lib/gssapi/mech/gss_release_name.c
index ad07c60bda..c5e348d5c0 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_release_name.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_release_name.c
@@ -33,23 +33,28 @@ OM_uint32 GSSAPI_LIB_FUNCTION
gss_release_name(OM_uint32 *minor_status,
gss_name_t *input_name)
{
- struct _gss_name *name = (struct _gss_name *) *input_name;
+ struct _gss_name *name;
*minor_status = 0;
- if (name) {
- if (name->gn_type.elements)
- free(name->gn_type.elements);
- while (SLIST_FIRST(&name->gn_mn)) {
- struct _gss_mechanism_name *mn;
- mn = SLIST_FIRST(&name->gn_mn);
- SLIST_REMOVE_HEAD(&name->gn_mn, gmn_link);
- mn->gmn_mech->gm_release_name(minor_status,
- &mn->gmn_name);
- free(mn);
- }
- gss_release_buffer(minor_status, &name->gn_value);
- free(name);
- *input_name = GSS_C_NO_NAME;
+
+ if (input_name == NULL || *input_name == NULL)
+ return GSS_S_COMPLETE;
+
+ name = (struct _gss_name *) *input_name;
+
+ if (name->gn_type.elements)
+ free(name->gn_type.elements);
+ while (SLIST_FIRST(&name->gn_mn)) {
+ struct _gss_mechanism_name *mn;
+ mn = SLIST_FIRST(&name->gn_mn);
+ SLIST_REMOVE_HEAD(&name->gn_mn, gmn_link);
+ mn->gmn_mech->gm_release_name(minor_status,
+ &mn->gmn_name);
+ free(mn);
}
+ gss_release_buffer(minor_status, &name->gn_value);
+ free(name);
+ *input_name = GSS_C_NO_NAME;
+
return (GSS_S_COMPLETE);
}
diff --git a/source4/heimdal/lib/gssapi/spnego/cred_stubs.c b/source4/heimdal/lib/gssapi/spnego/cred_stubs.c
index a3a984e22c..a10a10f1ef 100644
--- a/source4/heimdal/lib/gssapi/spnego/cred_stubs.c
+++ b/source4/heimdal/lib/gssapi/spnego/cred_stubs.c
@@ -354,3 +354,39 @@ _gss_spnego_set_cred_option (OM_uint32 *minor_status,
value);
}
+
+OM_uint32
+_gss_spnego_export_cred (OM_uint32 *minor_status,
+ gss_cred_id_t cred_handle,
+ gss_buffer_t value)
+{
+ gssspnego_cred cred = (gssspnego_cred)cred_handle;
+
+ return gss_export_cred(minor_status, cred->negotiated_cred_id, value);
+}
+
+OM_uint32
+_gss_spnego_import_cred (OM_uint32 *minor_status,
+ gss_buffer_t value,
+ gss_cred_id_t *cred_handle)
+{
+ gssspnego_cred cred;
+ OM_uint32 major;
+
+ *cred_handle = GSS_C_NO_CREDENTIAL;
+
+ cred = calloc(1, sizeof(*cred));
+ if (cred == NULL) {
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+
+ major = gss_import_cred(minor_status, value, &cred->negotiated_cred_id);
+ if (major == GSS_S_COMPLETE)
+ *cred_handle = (gss_cred_id_t)cred;
+ else
+ free(cred);
+
+ return major;
+}
+
diff --git a/source4/heimdal/lib/gssapi/spnego/external.c b/source4/heimdal/lib/gssapi/spnego/external.c
index 2dc809bbba..f3edcba389 100644
--- a/source4/heimdal/lib/gssapi/spnego/external.c
+++ b/source4/heimdal/lib/gssapi/spnego/external.c
@@ -79,7 +79,13 @@ static gssapi_mech_interface_desc spnego_mech = {
_gss_spnego_inquire_cred_by_oid,
_gss_spnego_set_sec_context_option,
_gss_spnego_set_cred_option,
- _gss_spnego_pseudo_random
+ _gss_spnego_pseudo_random,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ _gss_spnego_export_cred,
+ _gss_spnego_import_cred
};
gssapi_mech_interface
diff --git a/source4/heimdal/lib/hcrypto/camellia-ntt.c b/source4/heimdal/lib/hcrypto/camellia-ntt.c
index 358221162f..79c5a884ec 100644
--- a/source4/heimdal/lib/hcrypto/camellia-ntt.c
+++ b/source4/heimdal/lib/hcrypto/camellia-ntt.c
@@ -23,11 +23,7 @@
* http://info.isl.ntt.co.jp/crypt/eng/camellia/specifications.html
*/
-#ifdef HAVE_CONFIG_H
#include "config.h"
-#endif
-
-#include <roken.h>
#include <string.h>
#include <stdlib.h>
@@ -35,6 +31,8 @@
#include <krb5-types.h>
#include "camellia-ntt.h"
+#include <roken.h>
+
/* key constants */
#define CAMELLIA_SIGMA1L (0xA09E667FL)
diff --git a/source4/heimdal/lib/hcrypto/camellia.c b/source4/heimdal/lib/hcrypto/camellia.c
index d78bbd4c0e..c88822db5c 100644
--- a/source4/heimdal/lib/hcrypto/camellia.c
+++ b/source4/heimdal/lib/hcrypto/camellia.c
@@ -31,14 +31,8 @@
* SUCH DAMAGE.
*/
-#ifdef HAVE_CONFIG_H
#include "config.h"
-RCSID("$Id: aes.c 20466 2007-04-20 08:29:05Z lha $");
-#endif
-
-#include <roken.h>
-
#ifdef KRB5
#include <krb5-types.h>
#endif
@@ -48,6 +42,8 @@ RCSID("$Id: aes.c 20466 2007-04-20 08:29:05Z lha $");
#include "camellia-ntt.h"
#include "camellia.h"
+#include <roken.h>
+
int
CAMELLIA_set_key(const unsigned char *userkey,
const int bits, CAMELLIA_KEY *key)
diff --git a/source4/heimdal/lib/hdb/hdb.c b/source4/heimdal/lib/hdb/hdb.c
index 9795f8b255..c5d91b8f9d 100644
--- a/source4/heimdal/lib/hdb/hdb.c
+++ b/source4/heimdal/lib/hdb/hdb.c
@@ -72,6 +72,7 @@ static struct hdb_method methods[] = {
{ HDB_INTERFACE_VERSION, "ldap:", hdb_ldap_create},
{ HDB_INTERFACE_VERSION, "ldapi:", hdb_ldapi_create},
#endif
+ { HDB_INTERFACE_VERSION, "sqlite:", hdb_sqlite_create},
{0, NULL, NULL}
};
diff --git a/source4/heimdal/lib/hdb/keytab.c b/source4/heimdal/lib/hdb/keytab.c
index 2ec7837ae3..a557de036d 100644
--- a/source4/heimdal/lib/hdb/keytab.c
+++ b/source4/heimdal/lib/hdb/keytab.c
@@ -43,7 +43,7 @@ struct hdb_data {
struct hdb_cursor {
HDB *db;
hdb_entry_ex hdb_entry;
- bool first, next;
+ int first, next;
int key_idx;
};
@@ -272,7 +272,10 @@ hdb_start_seq_get(krb5_context context,
HDB *db;
if (dbname == NULL) {
- /* We don't support enumerating without being told what backend to enumerate on */
+ /*
+ * We don't support enumerating without being told what
+ * backend to enumerate on
+ */
ret = KRB5_KT_NOTFOUND;
return ret;
}
@@ -301,91 +304,111 @@ hdb_start_seq_get(krb5_context context,
}
c->db = db;
- c->first = true;
- c->next = true;
+ c->first = TRUE;
+ c->next = TRUE;
c->key_idx = 0;
cursor->data = c;
return ret;
}
-static int hdb_next_entry(krb5_context context,
+static int
+hdb_next_entry(krb5_context context,
krb5_keytab id,
krb5_keytab_entry *entry,
krb5_kt_cursor *cursor)
{
- struct hdb_cursor *c = cursor->data;
- krb5_error_code ret;
-
- if (c->first) {
- c->first = false;
- ret = (c->db->hdb_firstkey)(context, c->db,
- HDB_F_DECRYPT|
- HDB_F_GET_CLIENT|HDB_F_GET_SERVER|HDB_F_GET_KRBTGT,
- &c->hdb_entry);
- if (ret == HDB_ERR_NOENTRY) {
- return KRB5_KT_END;
- } else if (ret) {
- return ret;
- }
-
- if (c->hdb_entry.entry.keys.len == 0) {
- hdb_free_entry(context, &c->hdb_entry);
- } else {
- c->next = false;
- }
- }
-
- while (c->next) {
- ret = (c->db->hdb_nextkey)(context, c->db,
- HDB_F_DECRYPT|
- HDB_F_GET_CLIENT|HDB_F_GET_SERVER|HDB_F_GET_KRBTGT,
- &c->hdb_entry);
- if (ret == HDB_ERR_NOENTRY) {
- return KRB5_KT_END;
- } else if (ret) {
- return ret;
- }
- if (c->hdb_entry.entry.keys.len == 0) {
- /* If no keys on this entry, try again */
- hdb_free_entry(context, &c->hdb_entry);
- } else {
- /* We have an entry, set the flag */
- c->next = false;
- }
- };
-
- /* return next enc type (keytabs are one slot per key, while hdb is one record per principal */
- krb5_copy_principal(context,
- c->hdb_entry.entry.principal,
- &entry->principal);
- entry->vno = c->hdb_entry.entry.kvno;
- krb5_copy_keyblock_contents(context,
- &c->hdb_entry.entry.keys.val[c->key_idx].key,
- &entry->keyblock);
- c->key_idx++;
-
- /* Once we get to the end of the list, signal that we want the next entry */
- if (c->key_idx == c->hdb_entry.entry.keys.len) {
- hdb_free_entry(context, &c->hdb_entry);
- c->next = true;
- c->key_idx = 0;
- }
- return 0;
+ struct hdb_cursor *c = cursor->data;
+ krb5_error_code ret;
+
+ memset(entry, 0, sizeof(*entry));
+
+ if (c->first) {
+ c->first = FALSE;
+ ret = (c->db->hdb_firstkey)(context, c->db,
+ HDB_F_DECRYPT|
+ HDB_F_GET_CLIENT|HDB_F_GET_SERVER|HDB_F_GET_KRBTGT,
+ &c->hdb_entry);
+ if (ret == HDB_ERR_NOENTRY)
+ return KRB5_KT_END;
+ else if (ret)
+ return ret;
+
+ if (c->hdb_entry.entry.keys.len == 0)
+ hdb_free_entry(context, &c->hdb_entry);
+ else
+ c->next = FALSE;
+ }
+
+ while (c->next) {
+ ret = (c->db->hdb_nextkey)(context, c->db,
+ HDB_F_DECRYPT|
+ HDB_F_GET_CLIENT|HDB_F_GET_SERVER|HDB_F_GET_KRBTGT,
+ &c->hdb_entry);
+ if (ret == HDB_ERR_NOENTRY)
+ return KRB5_KT_END;
+ else if (ret)
+ return ret;
+
+ /* If no keys on this entry, try again */
+ if (c->hdb_entry.entry.keys.len == 0)
+ hdb_free_entry(context, &c->hdb_entry);
+ else
+ c->next = FALSE;
+ }
+
+ /*
+ * Return next enc type (keytabs are one slot per key, while
+ * hdb is one record per principal.
+ */
+
+ ret = krb5_copy_principal(context,
+ c->hdb_entry.entry.principal,
+ &entry->principal);
+ if (ret)
+ return ret;
+
+ entry->vno = c->hdb_entry.entry.kvno;
+ ret = krb5_copy_keyblock_contents(context,
+ &c->hdb_entry.entry.keys.val[c->key_idx].key,
+ &entry->keyblock);
+ if (ret) {
+ krb5_free_principal(context, entry->principal);
+ memset(entry, 0, sizeof(*entry));
+ return ret;
+ }
+ c->key_idx++;
+
+ /*
+ * Once we get to the end of the list, signal that we want the
+ * next entry
+ */
+
+ if (c->key_idx == c->hdb_entry.entry.keys.len) {
+ hdb_free_entry(context, &c->hdb_entry);
+ c->next = TRUE;
+ c->key_idx = 0;
+ }
+
+ return 0;
}
-static int hdb_end_seq_get(krb5_context context,
- krb5_keytab id,
- krb5_kt_cursor *cursor) {
- struct hdb_cursor *c = cursor->data;
- (c->db->hdb_close)(context, c->db);
- (c->db->hdb_destroy)(context, c->db);
- if (!c->next) {
- hdb_free_entry(context, &c->hdb_entry);
- }
- free(c);
- return 0;
+static int
+hdb_end_seq_get(krb5_context context,
+ krb5_keytab id,
+ krb5_kt_cursor *cursor)
+{
+ struct hdb_cursor *c = cursor->data;
+
+ (c->db->hdb_close)(context, c->db);
+ (c->db->hdb_destroy)(context, c->db);
+
+ if (!c->next)
+ hdb_free_entry(context, &c->hdb_entry);
+
+ free(c);
+ return 0;
}
krb5_kt_ops hdb_kt_ops = {
diff --git a/source4/heimdal/lib/hx509/ks_file.c b/source4/heimdal/lib/hx509/ks_file.c
index 74808f7607..553191a774 100644
--- a/source4/heimdal/lib/hx509/ks_file.c
+++ b/source4/heimdal/lib/hx509/ks_file.c
@@ -340,7 +340,7 @@ pem_func(hx509_context context, const char *type,
ret = (*formats[j].func)(context, NULL, pem_ctx->c,
header, data, len, ai);
- if (ret) {
+ if (ret && (pem_ctx->flags & HX509_CERTS_UNPROTECT_ALL)) {
hx509_set_error_string(context, HX509_ERROR_APPEND, ret,
"Failed parseing PEM format %s", type);
return ret;
@@ -354,8 +354,6 @@ pem_func(hx509_context context, const char *type,
"Found no matching PEM format for %s", type);
return ret;
}
- if (ret && (pem_ctx->flags & HX509_CERTS_UNPROTECT_ALL))
- return ret;
return 0;
}
diff --git a/source4/heimdal/lib/hx509/name.c b/source4/heimdal/lib/hx509/name.c
index b8f48d5236..23736edde3 100644
--- a/source4/heimdal/lib/hx509/name.c
+++ b/source4/heimdal/lib/hx509/name.c
@@ -235,8 +235,10 @@ _hx509_Name_to_string(const Name *n, char **str)
if (ss == NULL)
_hx509_abort("allocation failure"); /* XXX */
ret = wind_ucs2utf8(bmp, bmplen, ss, NULL);
- if (ret)
+ if (ret) {
+ free(ss);
return ret;
+ }
ss[k] = '\0';
break;
}
@@ -260,8 +262,10 @@ _hx509_Name_to_string(const Name *n, char **str)
if (ss == NULL)
_hx509_abort("allocation failure"); /* XXX */
ret = wind_ucs4utf8(uni, unilen, ss, NULL);
- if (ret)
+ if (ret) {
+ free(ss);
return ret;
+ }
ss[k] = '\0';
break;
}
diff --git a/source4/heimdal/lib/krb5/crypto.c b/source4/heimdal/lib/krb5/crypto.c
index a30780d1ed..42e2fdf359 100644
--- a/source4/heimdal/lib/krb5/crypto.c
+++ b/source4/heimdal/lib/krb5/crypto.c
@@ -3260,10 +3260,8 @@ krb5_encrypt_iov_ivec(krb5_context context,
memcpy(q, data[i].data.data, data[i].data.length);
q += data[i].data.length;
}
- if (piv) {
+ if (piv)
memset(q, 0, piv->data.length);
- q += piv->data.length;
- }
ret = create_checksum(context,
et->keyed_checksum,
@@ -3299,10 +3297,9 @@ krb5_encrypt_iov_ivec(krb5_context context,
memcpy(q, data[i].data.data, data[i].data.length);
q += data[i].data.length;
}
- if (piv) {
+ if (piv)
memset(q, 0, piv->data.length);
- q += piv->data.length;
- }
+
ret = _get_derived_key(context, crypto, ENCRYPTION_USAGE(usage), &dkey);
if(ret) {
@@ -3333,10 +3330,8 @@ krb5_encrypt_iov_ivec(krb5_context context,
memcpy(data[i].data.data, q, data[i].data.length);
q += data[i].data.length;
}
- if (piv) {
+ if (piv)
memcpy(piv->data.data, q, pad_sz);
- q += pad_sz;
- }
free(p);
diff --git a/source4/heimdal/lib/krb5/get_cred.c b/source4/heimdal/lib/krb5/get_cred.c
index e609bcadcc..10417f1a52 100644
--- a/source4/heimdal/lib/krb5/get_cred.c
+++ b/source4/heimdal/lib/krb5/get_cred.c
@@ -652,13 +652,16 @@ krb5_get_kdc_cred(krb5_context context,
&krbtgt);
if(ret) {
free(*out_creds);
+ *out_creds = NULL;
return ret;
}
ret = get_cred_kdc(context, id, flags, addresses,
in_creds, krbtgt, NULL, NULL, *out_creds);
krb5_free_creds (context, krbtgt);
- if(ret)
+ if(ret) {
free(*out_creds);
+ *out_creds = NULL;
+ }
return ret;
}
@@ -1038,15 +1041,15 @@ out:
* codebase.
*/
-static krb5_error_code
-get_cred_kdc_any(krb5_context context,
- krb5_kdc_flags flags,
- krb5_ccache ccache,
- krb5_creds *in_creds,
- krb5_principal impersonate_principal,
- Ticket *second_ticket,
- krb5_creds **out_creds,
- krb5_creds ***ret_tgts)
+krb5_error_code
+_krb5_get_cred_kdc_any(krb5_context context,
+ krb5_kdc_flags flags,
+ krb5_ccache ccache,
+ krb5_creds *in_creds,
+ krb5_principal impersonate_principal,
+ Ticket *second_ticket,
+ krb5_creds **out_creds,
+ krb5_creds ***ret_tgts)
{
krb5_error_code ret;
@@ -1072,33 +1075,6 @@ get_cred_kdc_any(krb5_context context,
krb5_error_code KRB5_LIB_FUNCTION
-krb5_get_cred_from_kdc_opt(krb5_context context,
- krb5_ccache ccache,
- krb5_creds *in_creds,
- krb5_creds **out_creds,
- krb5_creds ***ret_tgts,
- krb5_flags flags)
-{
- krb5_kdc_flags f;
- f.i = flags;
- return get_cred_kdc_any(context, f, ccache,
- in_creds, NULL, NULL,
- out_creds, ret_tgts);
-}
-
-krb5_error_code KRB5_LIB_FUNCTION
-krb5_get_cred_from_kdc(krb5_context context,
- krb5_ccache ccache,
- krb5_creds *in_creds,
- krb5_creds **out_creds,
- krb5_creds ***ret_tgts)
-{
- return krb5_get_cred_from_kdc_opt(context, ccache,
- in_creds, out_creds, ret_tgts, 0);
-}
-
-
-krb5_error_code KRB5_LIB_FUNCTION
krb5_get_credentials_with_flags(krb5_context context,
krb5_flags options,
krb5_kdc_flags flags,
@@ -1166,8 +1142,8 @@ krb5_get_credentials_with_flags(krb5_context context,
options |= KRB5_GC_NO_STORE;
tgts = NULL;
- ret = get_cred_kdc_any(context, flags, ccache,
- in_creds, NULL, NULL, out_creds, &tgts);
+ ret = _krb5_get_cred_kdc_any(context, flags, ccache,
+ in_creds, NULL, NULL, out_creds, &tgts);
for(i = 0; tgts && tgts[i]; i++) {
krb5_cc_store_cred(context, ccache, tgts[i]);
krb5_free_creds(context, tgts[i]);
@@ -1387,9 +1363,9 @@ krb5_get_creds(krb5_context context,
flags.b.canonicalize = 1;
tgts = NULL;
- ret = get_cred_kdc_any(context, flags, ccache,
- &in_creds, opt->self, opt->ticket,
- out_creds, &tgts);
+ ret = _krb5_get_cred_kdc_any(context, flags, ccache,
+ &in_creds, opt->self, opt->ticket,
+ out_creds, &tgts);
krb5_free_principal(context, in_creds.client);
for(i = 0; tgts && tgts[i]; i++) {
krb5_cc_store_cred(context, ccache, tgts[i]);
diff --git a/source4/heimdal/lib/krb5/kcm.c b/source4/heimdal/lib/krb5/kcm.c
index f034341972..c94dea551f 100644
--- a/source4/heimdal/lib/krb5/kcm.c
+++ b/source4/heimdal/lib/krb5/kcm.c
@@ -1097,8 +1097,8 @@ _krb5_kcm_get_initial_ticket(krb5_context context,
krb5_principal server,
krb5_keyblock *key)
{
- krb5_error_code ret;
krb5_kcmcache *k = KCMCACHE(id);
+ krb5_error_code ret;
krb5_storage *request;
ret = kcm_storage_request(context, KCM_OP_GET_INITIAL_TICKET, &request);
diff --git a/source4/heimdal/lib/krb5/keytab_file.c b/source4/heimdal/lib/krb5/keytab_file.c
index 819366443f..9a21db0cbb 100644
--- a/source4/heimdal/lib/krb5/keytab_file.c
+++ b/source4/heimdal/lib/krb5/keytab_file.c
@@ -490,7 +490,7 @@ loop:
if(len + 4 + pos - curpos >= 8) {
ret = krb5_ret_uint32(cursor->sp, &utmp32);
if (ret == 0)
- entry->flags = tmp32;
+ entry->flags = utmp32;
} else
entry->flags = 0;
diff --git a/source4/heimdal/lib/krb5/log.c b/source4/heimdal/lib/krb5/log.c
index ee5c1159b1..5b84bc2f4c 100644
--- a/source4/heimdal/lib/krb5/log.c
+++ b/source4/heimdal/lib/krb5/log.c
@@ -220,17 +220,16 @@ log_file(const char *timestr,
{
struct file_data *f = data;
char *msgclean;
- size_t len = strlen(msg) + 1;
+ size_t len = strlen(msg);
if(f->keep_open == 0)
f->fd = fopen(f->filename, f->mode);
if(f->fd == NULL)
return;
/* make sure the log doesn't contain special chars */
- len *= 4;
- msgclean = malloc(len);
+ msgclean = malloc((len + 1) * 4);
if (msgclean == NULL)
goto out;
- strvisx(rk_UNCONST(msg), msgclean, len, VIS_OCTAL);
+ strvisx(msgclean, rk_UNCONST(msg), len, VIS_OCTAL);
fprintf(f->fd, "%s %s\n", timestr, msgclean);
free(msgclean);
out:
diff --git a/source4/heimdal/lib/krb5/pkinit.c b/source4/heimdal/lib/krb5/pkinit.c
index 18b5b5e017..af5568f44b 100644
--- a/source4/heimdal/lib/krb5/pkinit.c
+++ b/source4/heimdal/lib/krb5/pkinit.c
@@ -1402,6 +1402,7 @@ pk_rd_pa_reply_dh(krb5_context context,
kdc_dh_pubkey, ctx->u.dh);
if (dh_gen_keylen == -1) {
ret = KRB5KRB_ERR_GENERIC;
+ dh_gen_keylen = 0;
krb5_set_error_message(context, ret,
N_("PKINIT: Can't compute Diffie-Hellman key", ""));
goto out;
@@ -1446,6 +1447,7 @@ pk_rd_pa_reply_dh(krb5_context context,
EC_KEY_free(public);
if (dh_gen_keylen == -1) {
ret = KRB5KRB_ERR_GENERIC;
+ dh_gen_keylen = 0;
krb5_set_error_message(context, ret,
N_("PKINIT: Can't compute ECDH public key", ""));
goto out;
@@ -1455,6 +1457,14 @@ pk_rd_pa_reply_dh(krb5_context context,
#endif
}
+ if (dh_gen_keylen <= 0) {
+ ret = EINVAL;
+ krb5_set_error_message(context, ret,
+ N_("PKINIT: resulting DH key <= 0", ""));
+ dh_gen_keylen = 0;
+ goto out;
+ }
+
*key = malloc (sizeof (**key));
if (*key == NULL) {
ret = ENOMEM;
diff --git a/source4/heimdal/lib/krb5/plugin.c b/source4/heimdal/lib/krb5/plugin.c
index 844cb7ab88..027f2a72a7 100644
--- a/source4/heimdal/lib/krb5/plugin.c
+++ b/source4/heimdal/lib/krb5/plugin.c
@@ -40,19 +40,28 @@
struct krb5_plugin {
void *symbol;
- void *dsohandle;
struct krb5_plugin *next;
};
struct plugin {
- enum krb5_plugin_type type;
- void *name;
- void *symbol;
+ enum { DSO, SYMBOL } type;
+ union {
+ struct {
+ char *path;
+ void *dsohandle;
+ } dso;
+ struct {
+ enum krb5_plugin_type type;
+ char *name;
+ char *symbol;
+ } symbol;
+ } u;
struct plugin *next;
};
static HEIMDAL_MUTEX plugin_mutex = HEIMDAL_MUTEX_INITIALIZER;
static struct plugin *registered = NULL;
+static int plugins_needs_scan = 1;
static const char *sysplugin_dirs[] = {
LIBDIR "/plugin/krb5",
@@ -85,15 +94,14 @@ _krb5_plugin_get_next(struct krb5_plugin *p)
#ifdef HAVE_DLOPEN
static krb5_error_code
-loadlib(krb5_context context,
- enum krb5_plugin_type type,
- const char *name,
- const char *lib,
- struct krb5_plugin **e)
+loadlib(krb5_context context, char *path)
{
- *e = calloc(1, sizeof(**e));
- if (*e == NULL) {
+ struct plugin *e;
+
+ e = calloc(1, sizeof(*e));
+ if (e == NULL) {
krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
+ free(path);
return ENOMEM;
}
@@ -103,24 +111,13 @@ loadlib(krb5_context context,
#ifndef RTLD_LOCAL
#define RTLD_LOCAL 0
#endif
+ e->type = DSO;
+ /* ignore error from dlopen, and just keep it as negative cache entry */
+ e->u.dso.dsohandle = dlopen(path, RTLD_LOCAL|RTLD_LAZY);
+ e->u.dso.path = path;
- (*e)->dsohandle = dlopen(lib, RTLD_LOCAL|RTLD_LAZY);
- if ((*e)->dsohandle == NULL) {
- free(*e);
- *e = NULL;
- krb5_set_error_message(context, ENOMEM, "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_message(context);
- return ENOMEM;
- }
+ e->next = registered;
+ registered = e;
return 0;
}
@@ -146,26 +143,35 @@ krb5_plugin_register(krb5_context context,
{
struct plugin *e;
+ HEIMDAL_MUTEX_lock(&plugin_mutex);
+
/* check for duplicates */
- for (e = registered; e != NULL; e = e->next)
- if (e->type == type && strcmp(e->name,name)== 0 && e->symbol == symbol)
+ for (e = registered; e != NULL; e = e->next) {
+ if (e->type == SYMBOL &&
+ strcmp(e->u.symbol.name, name) == 0 &&
+ e->u.symbol.type == type && e->u.symbol.symbol == symbol) {
+ HEIMDAL_MUTEX_unlock(&plugin_mutex);
return 0;
+ }
+ }
e = calloc(1, sizeof(*e));
if (e == NULL) {
+ HEIMDAL_MUTEX_unlock(&plugin_mutex);
krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
return ENOMEM;
}
- e->type = type;
- e->name = strdup(name);
- if (e->name == NULL) {
+ e->type = SYMBOL;
+ e->u.symbol.type = type;
+ e->u.symbol.name = strdup(name);
+ if (e->u.symbol.name == NULL) {
+ HEIMDAL_MUTEX_unlock(&plugin_mutex);
free(e);
krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
return ENOMEM;
}
- e->symbol = symbol;
+ e->u.symbol.symbol = symbol;
- HEIMDAL_MUTEX_lock(&plugin_mutex);
e->next = registered;
registered = e;
HEIMDAL_MUTEX_unlock(&plugin_mutex);
@@ -173,41 +179,19 @@ krb5_plugin_register(krb5_context context,
return 0;
}
-krb5_error_code
-_krb5_plugin_find(krb5_context context,
- enum krb5_plugin_type type,
- const char *name,
- struct krb5_plugin **list)
+static krb5_error_code
+load_plugins(krb5_context context)
{
- struct krb5_plugin *e;
- struct plugin *p;
+ struct plugin *e;
krb5_error_code ret;
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);
- ret = ENOMEM;
- krb5_set_error_message(context, ret, "malloc: out of memory");
- goto out;
- }
- e->symbol = p->symbol;
- e->dsohandle = NULL;
- e->next = *list;
- *list = e;
- }
- HEIMDAL_MUTEX_unlock(&plugin_mutex);
+ if (!plugins_needs_scan)
+ return 0;
+ plugins_needs_scan = 0;
#ifdef HAVE_DLOPEN
@@ -244,21 +228,83 @@ _krb5_plugin_find(krb5_context context,
if (path == NULL) {
ret = ENOMEM;
krb5_set_error_message(context, ret, "malloc: out of memory");
- goto out;
+ return ret;
+ }
+
+ /* check if already tried */
+ for (e = registered; e != NULL; e = e->next)
+ if (e->type == DSO && strcmp(e->u.dso.path, path) == 0)
+ break;
+ if (e) {
+ free(path);
+ } else {
+ loadlib(context, path); /* store or frees path */
}
- ret = loadlib(context, type, name, path, &e);
- free(path);
- if (ret)
- continue;
-
- e->next = *list;
- *list = e;
}
closedir(d);
}
if (dirs != rk_UNCONST(sysplugin_dirs))
krb5_config_free_strings(dirs);
#endif /* HAVE_DLOPEN */
+ return 0;
+}
+
+static krb5_error_code
+add_symbol(krb5_context context, struct krb5_plugin **list, void *symbol)
+{
+ struct krb5_plugin *e;
+
+ e = calloc(1, sizeof(*e));
+ if (e == NULL) {
+ krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
+ return ENOMEM;
+ }
+ e->symbol = symbol;
+ e->next = *list;
+ *list = e;
+ return 0;
+}
+
+krb5_error_code
+_krb5_plugin_find(krb5_context context,
+ enum krb5_plugin_type type,
+ const char *name,
+ struct krb5_plugin **list)
+{
+ struct plugin *e;
+ krb5_error_code ret;
+
+ *list = NULL;
+
+ HEIMDAL_MUTEX_lock(&plugin_mutex);
+
+ load_plugins(context);
+
+ for (ret = 0, e = registered; e != NULL; e = e->next) {
+ switch(e->type) {
+ case DSO: {
+ void *sym;
+ if (e->u.dso.dsohandle == NULL)
+ continue;
+ sym = dlsym(e->u.dso.dsohandle, name);
+ if (sym)
+ ret = add_symbol(context, list, sym);
+ break;
+ }
+ case SYMBOL:
+ if (strcmp(e->u.symbol.name, name) == 0 && e->u.symbol.type == type)
+ ret = add_symbol(context, list, e->u.symbol.symbol);
+ break;
+ }
+ if (ret) {
+ _krb5_plugin_free(*list);
+ *list = NULL;
+ }
+ }
+
+ HEIMDAL_MUTEX_unlock(&plugin_mutex);
+ if (ret)
+ return ret;
if (*list == NULL) {
krb5_set_error_message(context, ENOENT, "Did not find a plugin for %s", name);
@@ -266,16 +312,6 @@ _krb5_plugin_find(krb5_context context,
}
return 0;
-
-out:
- if (dirs != rk_UNCONST(sysplugin_dirs))
- krb5_config_free_strings(dirs);
- if (d)
- closedir(d);
- _krb5_plugin_free(*list);
- *list = NULL;
-
- return ret;
}
void
@@ -284,8 +320,6 @@ _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;
}
diff --git a/source4/heimdal/lib/krb5/principal.c b/source4/heimdal/lib/krb5/principal.c
index 50b7bb8813..9899f5661f 100644
--- a/source4/heimdal/lib/krb5/principal.c
+++ b/source4/heimdal/lib/krb5/principal.c
@@ -496,6 +496,18 @@ unparse_name(krb5_context context,
return ret;
}
+/**
+ * Unparse the Kerberos name into a string
+ *
+ * @param context Kerberos 5 context
+ * @param principal principal to query
+ * @param name resulting string, free with krb5_xfree()
+ *
+ * @return An krb5 error code, see krb5_get_error_message().
+ *
+ * @ingroup krb5_principal
+ */
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_unparse_name(krb5_context context,
krb5_const_principal principal,
@@ -504,6 +516,19 @@ krb5_unparse_name(krb5_context context,
return unparse_name(context, principal, name, 0);
}
+/**
+ * Unparse the Kerberos name into a string
+ *
+ * @param context Kerberos 5 context
+ * @param principal principal to query
+ * @param flags flag to determine the behavior
+ * @param name resulting string, free with krb5_xfree()
+ *
+ * @return An krb5 error code, see krb5_get_error_message().
+ *
+ * @ingroup krb5_principal
+ */
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_unparse_name_flags(krb5_context context,
krb5_const_principal principal,
@@ -620,7 +645,6 @@ va_princ(krb5_context context, krb5_principal p, va_list ap)
}
}
-
static krb5_error_code
build_principal(krb5_context context,
krb5_principal *principal,
@@ -733,8 +757,16 @@ krb5_copy_principal(krb5_context context,
return 0;
}
-/*
- * return TRUE iff princ1 == princ2 (without considering the realm)
+/**
+ * Return TRUE iff princ1 == princ2 (without considering the realm)
+ *
+ * @param context Kerberos 5 context
+ * @param princ1 first principal to compare
+ * @param princ2 second principal to compare
+ *
+ * @return non zero if equal, 0 if not
+ *
+ * @ingroup krb5_principal
*/
krb5_boolean KRB5_LIB_FUNCTION
diff --git a/source4/heimdal/lib/krb5/store_fd.c b/source4/heimdal/lib/krb5/store_fd.c
index 38d67ae4d3..4150175927 100644
--- a/source4/heimdal/lib/krb5/store_fd.c
+++ b/source4/heimdal/lib/krb5/store_fd.c
@@ -79,7 +79,7 @@ fd_free(krb5_storage * sp)
*
* @ingroup krb5_storage
*
- * @sa krb5_storage_from_emem()
+ * @sa krb5_storage_emem()
* @sa krb5_storage_from_mem()
* @sa krb5_storage_from_readonly_mem()
* @sa krb5_storage_from_data()
diff --git a/source4/heimdal/lib/krb5/store_mem.c b/source4/heimdal/lib/krb5/store_mem.c
index db1abc1e90..a7b0c2d2dc 100644
--- a/source4/heimdal/lib/krb5/store_mem.c
+++ b/source4/heimdal/lib/krb5/store_mem.c
@@ -116,7 +116,7 @@ mem_no_trunc(krb5_storage *sp, off_t offset)
*
* @ingroup krb5_storage
*
- * @sa krb5_storage_from_emem()
+ * @sa krb5_storage_mem()
* @sa krb5_storage_from_readonly_mem()
* @sa krb5_storage_from_data()
* @sa krb5_storage_from_fd()
@@ -155,7 +155,7 @@ krb5_storage_from_mem(void *buf, size_t len)
*
* @ingroup krb5_storage
*
- * @sa krb5_storage_from_emem()
+ * @sa krb5_storage_mem()
* @sa krb5_storage_from_mem()
* @sa krb5_storage_from_readonly_mem()
* @sa krb5_storage_from_fd()
@@ -174,7 +174,7 @@ krb5_storage_from_data(krb5_data *data)
*
* @ingroup krb5_storage
*
- * @sa krb5_storage_from_emem()
+ * @sa krb5_storage_mem()
* @sa krb5_storage_from_mem()
* @sa krb5_storage_from_data()
* @sa krb5_storage_from_fd()
diff --git a/source4/heimdal/lib/krb5/transited.c b/source4/heimdal/lib/krb5/transited.c
index 196ef447ee..1ff4ce1658 100644
--- a/source4/heimdal/lib/krb5/transited.c
+++ b/source4/heimdal/lib/krb5/transited.c
@@ -62,9 +62,8 @@ static int
make_path(krb5_context context, struct tr_realm *r,
const char *from, const char *to)
{
- const char *p;
- struct tr_realm *path = r->next;
struct tr_realm *tmp;
+ const char *p;
if(strlen(from) < strlen(to)){
const char *str;
@@ -90,11 +89,12 @@ make_path(krb5_context context, struct tr_realm *r,
N_("malloc: out of memory", ""));
return ENOMEM;
}
- tmp->next = path;
- path = tmp;
- path->realm = strdup(p);
- if(path->realm == NULL){
- r->next = path; /* XXX */
+ tmp->next = r->next;
+ r->next = tmp;
+ tmp->realm = strdup(p);
+ if(tmp->realm == NULL){
+ r->next = tmp->next;
+ free(tmp);
krb5_set_error_message(context, ENOMEM,
N_("malloc: out of memory", ""));
return ENOMEM;;
@@ -104,10 +104,9 @@ make_path(krb5_context context, struct tr_realm *r,
p = from + strlen(from);
while(1){
while(p >= from && *p != '/') p--;
- if(p == from) {
- r->next = path; /* XXX */
+ if(p == from)
return KRB5KDC_ERR_POLICY;
- }
+
if(strncmp(to, from, p - from) == 0)
break;
tmp = calloc(1, sizeof(*tmp));
@@ -116,24 +115,24 @@ make_path(krb5_context context, struct tr_realm *r,
N_("malloc: out of memory", ""));
return ENOMEM;
}
- tmp->next = path;
- path = tmp;
- path->realm = malloc(p - from + 1);
- if(path->realm == NULL){
- r->next = path; /* XXX */
+ tmp->next = r->next;
+ r->next = tmp;
+ tmp->realm = malloc(p - from + 1);
+ if(tmp->realm == NULL){
+ r->next = tmp->next;
+ free(tmp);
krb5_set_error_message(context, ENOMEM,
N_("malloc: out of memory", ""));
return ENOMEM;
}
- memcpy(path->realm, from, p - from);
- path->realm[p - from] = '\0';
+ memcpy(tmp->realm, from, p - from);
+ tmp->realm[p - from] = '\0';
p--;
}
} else {
krb5_clear_error_message (context);
return KRB5KDC_ERR_POLICY;
}
- r->next = path;
return 0;
}
@@ -359,17 +358,15 @@ krb5_domain_x500_decode(krb5_context context,
return ret;
/* remove empty components and count realms */
- q = &r;
*num_realms = 0;
- for(p = r; p; ){
- if(p->realm[0] == '\0'){
+ for(q = &r; *q; ){
+ if((*q)->realm[0] == '\0'){
+ p = *q;
+ *q = (*q)->next;
free(p->realm);
- *q = p->next;
free(p);
- p = *q;
}else{
- q = &p->next;
- p = p->next;
+ q = &(*q)->next;
(*num_realms)++;
}
}
diff --git a/source4/heimdal/lib/krb5/warn.c b/source4/heimdal/lib/krb5/warn.c
index 58fb73189e..b88b2004fb 100644
--- a/source4/heimdal/lib/krb5/warn.c
+++ b/source4/heimdal/lib/krb5/warn.c
@@ -65,13 +65,13 @@ _warnerr(krb5_context context, int do_errtext,
err_str = krb5_get_error_message(context, code);
if (err_str != NULL) {
- *arg++ = err_str;
+ *arg = err_str;
} else {
err_msg = krb5_get_err_text(context, code);
if (err_msg)
- *arg++ = err_msg;
+ *arg = err_msg;
else
- *arg++ = "<unknown error>";
+ *arg= "<unknown error>";
}
}
diff --git a/source4/heimdal/lib/roken/base64.c b/source4/heimdal/lib/roken/base64.c
index 5e720eb6d4..bc74391b56 100644
--- a/source4/heimdal/lib/roken/base64.c
+++ b/source4/heimdal/lib/roken/base64.c
@@ -58,6 +58,11 @@ base64_encode(const void *data, int size, char **str)
int c;
const unsigned char *q;
+ if (size > INT_MAX/4 || size < 0) {
+ *str = NULL;
+ return -1;
+ }
+
p = s = (char *) malloc(size * 4 / 3 + 4);
if (p == NULL) {
*str = NULL;
diff --git a/source4/heimdal/lib/roken/strpool.c b/source4/heimdal/lib/roken/strpool.c
index dc56892144..642d335dec 100644
--- a/source4/heimdal/lib/roken/strpool.c
+++ b/source4/heimdal/lib/roken/strpool.c
@@ -100,7 +100,10 @@ rk_strpoolprintf(struct rk_strpool *p, const char *fmt, ...)
char * ROKEN_LIB_FUNCTION
rk_strpoolcollect(struct rk_strpool *p)
{
- char *str = p->str;
+ char *str;
+ if (p == NULL)
+ return strdup("");
+ str = p->str;
p->str = NULL;
free(p);
return str;
diff --git a/source4/heimdal/lib/roken/vis.hin b/source4/heimdal/lib/roken/vis.hin
index 06a250c6d8..737b2eb8f6 100644
--- a/source4/heimdal/lib/roken/vis.hin
+++ b/source4/heimdal/lib/roken/vis.hin
@@ -44,6 +44,8 @@
#include <sys/types.h>
+#include <roken.h>
+
/*
* to select alternate encoding format
*/
@@ -80,11 +82,8 @@
*/
#define UNVIS_END 1 /* no more characters */
-#ifdef HAVE_SYS_CDEFS_H
-#include <sys/cdefs.h>
-#endif
+ROKEN_CPP_START
-__BEGIN_DECLS
char * ROKEN_LIB_FUNCTION
rk_vis(char *, int, int, int);
char * ROKEN_LIB_FUNCTION
@@ -103,7 +102,7 @@ int ROKEN_LIB_FUNCTION
rk_strunvisx(char *, const char *, int);
int ROKEN_LIB_FUNCTION
rk_unvis(char *, int, int *, int);
-__END_DECLS
+ROKEN_CPP_END
#undef vis
#define vis(a,b,c,d) rk_vis(a,b,c,d)