s4:heimdal: import lorikeet-heimdal-200908050050 (commit 8714779fa7376fd9f7761587639e...
authorAndrew Bartlett <abartlet@samba.org>
Wed, 5 Aug 2009 01:25:50 +0000 (11:25 +1000)
committerAndrew Bartlett <abartlet@samba.org>
Wed, 5 Aug 2009 02:18:17 +0000 (12:18 +1000)
This also adds a new hdb-glue.c file, to cope with Heimdal's
uncondtional enabling of SQLITE.

(Very reasonable, but not required for Samba4's use).

Andrew Bartlett

50 files changed:
source4/heimdal/kdc/kdc_locl.h
source4/heimdal/kdc/kerberos5.c
source4/heimdal/kdc/misc.c
source4/heimdal/kdc/pkinit.c
source4/heimdal/lib/asn1/der_get.c
source4/heimdal/lib/asn1/der_put.c
source4/heimdal/lib/asn1/krb5.asn1
source4/heimdal/lib/asn1/main.c
source4/heimdal/lib/gssapi/gssapi/gssapi.h
source4/heimdal/lib/gssapi/gssapi/gssapi_krb5.h
source4/heimdal/lib/gssapi/gssapi/gssapi_spnego.h
source4/heimdal/lib/gssapi/gssapi_mech.h
source4/heimdal/lib/gssapi/krb5/accept_sec_context.c
source4/heimdal/lib/gssapi/krb5/acquire_cred.c
source4/heimdal/lib/gssapi/krb5/canonicalize_name.c
source4/heimdal/lib/gssapi/krb5/copy_ccache.c
source4/heimdal/lib/gssapi/krb5/creds.c [new file with mode: 0644]
source4/heimdal/lib/gssapi/krb5/external.c
source4/heimdal/lib/gssapi/krb5/import_name.c
source4/heimdal/lib/gssapi/krb5/init_sec_context.c
source4/heimdal/lib/gssapi/krb5/set_cred_option.c
source4/heimdal/lib/gssapi/krb5/store_cred.c [new file with mode: 0644]
source4/heimdal/lib/gssapi/mech/gss_aeap.c
source4/heimdal/lib/gssapi/mech/gss_cred.c [new file with mode: 0644]
source4/heimdal/lib/gssapi/mech/gss_release_name.c
source4/heimdal/lib/gssapi/spnego/cred_stubs.c
source4/heimdal/lib/gssapi/spnego/external.c
source4/heimdal/lib/hcrypto/camellia-ntt.c
source4/heimdal/lib/hcrypto/camellia.c
source4/heimdal/lib/hdb/hdb.c
source4/heimdal/lib/hdb/keytab.c
source4/heimdal/lib/hx509/ks_file.c
source4/heimdal/lib/hx509/name.c
source4/heimdal/lib/krb5/crypto.c
source4/heimdal/lib/krb5/get_cred.c
source4/heimdal/lib/krb5/kcm.c
source4/heimdal/lib/krb5/keytab_file.c
source4/heimdal/lib/krb5/log.c
source4/heimdal/lib/krb5/pkinit.c
source4/heimdal/lib/krb5/plugin.c
source4/heimdal/lib/krb5/principal.c
source4/heimdal/lib/krb5/store_fd.c
source4/heimdal/lib/krb5/store_mem.c
source4/heimdal/lib/krb5/transited.c
source4/heimdal/lib/krb5/warn.c
source4/heimdal/lib/roken/base64.c
source4/heimdal/lib/roken/strpool.c
source4/heimdal/lib/roken/vis.hin
source4/heimdal_build/hdb-glue.c [new file with mode: 0644]
source4/heimdal_build/internal.mk

index daf155839cd691e9b4fd97c81514ec429ca86f55..024937e763366943510203712c23280641c0310d 100644 (file)
@@ -67,6 +67,9 @@ extern const struct units _kdc_digestunits[];
 extern struct timeval _kdc_now;
 #define kdc_time (_kdc_now.tv_sec)
 
+extern char *runas_string;
+extern char *chroot_string;
+
 void
 loop(krb5_context context, krb5_kdc_configuration *config);
 
index 53e9f54537f52db5fe684039116be376a7f6f10c..8edc07a49b1429a6957bda7efbf6168e3013067a 100644 (file)
@@ -1208,19 +1208,13 @@ _kdc_as_rep(krb5_context context,
                        (unsigned)abs(kdc_time - p.patimestamp),
                        context->max_skew,
                        client_name);
-#if 1
-               /* This code is from samba, needs testing */
+
                /*
-                * the following is needed to make windows clients
-                * to retry using the timestamp in the error message
-                *
-                * this is maybe a bug in windows to not trying when e_text
-                * is present...
+                * The following is needed to make windows clients to
+                * retry using the timestamp in the error message, if
+                * there is a e_text, they become unhappy.
                 */
                e_text = NULL;
-#else
-               e_text = "Too large time skew";
-#endif
                goto out;
            }
            et.flags.pre_authent = 1;
index 247cb575de0eed7acfa16aa1e25d7ba7abadbcd3..e016183615612eecf0de11d04c1c639e19bd5559 100644 (file)
@@ -65,12 +65,15 @@ _kdc_db_fetch(krb5_context context,
                                       "malformed request: "
                                       "enterprise name with %d name components",
                                       principal->name.name_string.len);
+               free(ent);
                return ret;
            }
            ret = krb5_parse_name(context, principal->name.name_string.val[0],
                                  &enterprise_principal);
-           if (ret)
+           if (ret) {
+               free(ent);
                return ret;
+           }
 
            principal = enterprise_principal;
        }
@@ -98,7 +101,8 @@ _kdc_db_fetch(krb5_context context,
        }
     }
     free(ent);
-    krb5_set_error_message(context, HDB_ERR_NOENTRY, "no such entry found in hdb");
+    krb5_set_error_message(context, HDB_ERR_NOENTRY,
+                          "no such entry found in hdb");
     return HDB_ERR_NOENTRY;
 }
 
index 644eae0fe483982f858d2a5e2347a4384224b41c..0d00ef21732c384bc140ca2f233ec835cb2aa00f 100644 (file)
@@ -284,7 +284,7 @@ generate_dh_keyblock(krb5_context context,
        dh_gen_keylen = ECDH_compute_key(dh_gen_key, size, 
                                         EC_KEY_get0_public_key(client_params->u.ecdh.public_key),
                                         client_params->u.ecdh.key, NULL);
-       ret = 0;
+
 #endif /* HAVE_OPENSSL */
     } else {
        ret = KRB5KRB_ERR_GENERIC;
@@ -1450,8 +1450,10 @@ _kdc_pk_mk_pa_reply(krb5_context context,
 
        ret = krb5_generate_random_keyblock(context, sessionetype, 
                                            sessionkey);
-       if (ret)
+       if (ret) {
+           free(buf);
            goto out;
+       }
 
     } else
        krb5_abortx(context, "PK-INIT internal error");
@@ -1981,12 +1983,14 @@ _kdc_pk_initialize(krb5_context context,
                hx509_name name;
                char *str;
                ret = hx509_cert_get_subject(cert, &name);
-               hx509_name_to_string(name, &str);
-               krb5_warnx(context, "WARNING Found KDC certificate (%s)"
-                          "is missing the PK-INIT KDC EKU, this is bad for "
-                          "interoperability.", str);
-               hx509_name_free(&name);
-               free(str);
+               if (ret == 0) {
+                   hx509_name_to_string(name, &str);
+                   krb5_warnx(context, "WARNING Found KDC certificate (%s)"
+                              "is missing the PK-INIT KDC EKU, this is bad for "
+                              "interoperability.", str);
+                   hx509_name_free(&name);
+                   free(str);
+               }
            }
            hx509_cert_free(cert);
        } else
index 8144639b9a940fb41f853eaa16e7f8a4a1c9f7ea..aee565040fd61168d76b9b17249f7244502c5aee 100644 (file)
@@ -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;
index 7e71443da5b36184bc56f86da364c4f4b4f21488..10fc0023341b895dea4dd444bd0fe56c79908c15 100644 (file)
@@ -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);
index 8edb0fde69753c0bfb55f328798ae2677651312c..7080b095f8f2d22094ba9331a7a3c767e6e1d73b 100644 (file)
@@ -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
index 115c82a9c7d1d23cea019bb1979d4954c978dfde..5cef970d784c0b1281cd1f7145788444c16a2093 100644 (file)
@@ -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);
            }
index 91141808f54426dde8c960763e6e4af23384a346..6052ec81348df4c5668e39ea8c322a3c77b30b15 100644 (file)
 #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_ */
index 0baccf5098f65ad750363e8d0deace89393f070d..4d004d90b59d98a61fb05a7be04f36f6db2b1ee6 100644 (file)
@@ -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_ */
index 3c4869f08dc1469d306527e36c6093d3880738c0..c5d372d6dc4618a462c4eefeb045b556f4ca8b10 100644 (file)
@@ -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_ */
index 6470df30a031c56c0c531444bea96782d25e8019..206a24ef74ea34e1492d422b86994b1e891ed3a9 100644 (file)
@@ -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
index 8d998ed0988f3ec3b5d033ccb761f0b006dcb913..355d1c4332421153627639049905fcac0aba152b 100644 (file)
@@ -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;
 
index 4f6f38e6743d8edba818a661d25c7d6affeea457..696171dcfa39effb20cceb4564755c8dac0856c1 100644 (file)
@@ -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);
index 7e0c3fe72703b17f8b99267e58e580720f184d96..3de55d6e32b34a651d3efbc92a5ca217207862be 100644 (file)
@@ -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;
 
index a4b28f91ed04b22c156d444e7db2ac788d70543c..4e65fc1cf30448aae2c87475317327b69e024e80 100644 (file)
@@ -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 (file)
index 0000000..c9befe9
--- /dev/null
@@ -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;
+}
index df23776a63c35da9c82b7fe6450d0c2083a4cb4f..fc835bd845df0ce608ac42f01035f96c06f2de07 100644 (file)
@@ -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
index d488ce754b893e75a91ccaf493d81b23c4a86e1b..f1aca93ffda479b940e97d231d895837b4c06a24 100644 (file)
@@ -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;
index 35ab9dd88d3abbfb353dbe6030a02e12a3b93d53..b269d067988ea8b7b7fcd9fc7837a10f5afd8476 100644 (file)
@@ -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;
 
index 15d7632e4c99bc2c83da9410b02e973fb1f0990d..ee29bf8c66d9c762f75d2d4f859fb5f128d5d461 100644 (file)
@@ -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 (file)
index 0000000..675a1d8
--- /dev/null
@@ -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;
+}
index 9c784f42de108f42a37d84decc8beeaeaf663cdd..9a1835a039627c5346b81f1a45fbda556b168516 100644 (file)
@@ -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 (file)
index 0000000..66df50b
--- /dev/null
@@ -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;
+
+}
index ad07c60bda5bad1d1cde59b9741ac0f396d49554..c5e348d5c0efd8693b03c6f5957078e4571bc854 100644 (file)
@@ -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);
 }
index a3a984e22c3eb05137b7e569fd9b1ca64b7677f8..a10a10f1efedd970fe55f50580eff7d190ce5531 100644 (file)
@@ -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;
+}
+
index 2dc809bbbaa58af610b3e1d0c54064b36f69f560..f3edcba389f85a4da8327c7d3e8705f7c27df588 100644 (file)
@@ -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
index 358221162fd073eb1814a41fb1f6aa676ea4fd82..79c5a884ecd112fb18c947864f6631a77ce79c29 100644 (file)
  *  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)
index d78bbd4c0e6567a8457e9a8087f805b954bb7ded..c88822db5c7d8820557c3ef25cf39e38976d8466 100644 (file)
  * 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)
index 9795f8b255b75b885c6d1da8f69e936816c2f34d..c5d91b8f9d0e5b75cb4075ac7d4dceedf41dd567 100644 (file)
@@ -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}
 };
 
index 2ec7837ae33b50ceb65dc5e08231e39d14037377..a557de036d0312fef289db3e5ec1fc62b4e97c53 100644 (file)
@@ -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 = {
index 74808f760765a97c2ac098f911785ff7d463dd80..553191a774c918bc8e93e9624d012b88250fa7c9 100644 (file)
@@ -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;
 }
 
index b8f48d5236b7428fdf3e264480ef5fdb0aede709..23736edde3b551a11da9bcbe25a5a078257ede0f 100644 (file)
@@ -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;
            }
index a30780d1edcfc0b665b8688b0bfde436e37b2072..42e2fdf359564226a6c1108a0f5b36e57f890ecc 100644 (file)
@@ -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);
 
index e609bcadcca560e7a9ac0f5920f811f0b45ba29c..10417f1a529f1bcb309a3cf4b995cc2787b46ca7 100644 (file)
@@ -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;
 
@@ -1071,33 +1074,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,
@@ -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]);
index f0343419725f5aa0a8569f328ba478128f6a2537..c94dea551f865613cd2dbb233ecefb3d3485bbe2 100644 (file)
@@ -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);
index 819366443ff4ceb6fa5d92293d0da4bcc9cefea7..9a21db0cbb297dfc6fe7325ed531cf7b5545cd5b 100644 (file)
@@ -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;
 
index ee5c1159b138baa91e430cd0c0ef02dea84191a8..5b84bc2f4c4e8dbbe3a85c188617283d0b8ba3c4 100644 (file)
@@ -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:
index 18b5b5e0171e659167a2e6e7e966bf3345eb8b83..af5568f44be9199d8093d1c7b6b6765619f60f8b 100644 (file)
@@ -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;
index 844cb7ab889a3df800d4d6caf8f0787464299a7c..027f2a72a707dc7934083eb7bac6a78e52e8450e 100644 (file)
 
 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;
     }
index 50b7bb8813239e79aff77468a34fbf568ddbdbfb..9899f5661f834ec1e6ff8af115db4fe242cc0298 100644 (file)
@@ -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
index 38d67ae4d3d0f42a390832bafd62a93f294dc11b..4150175927ee685a03179d964db681d4d9b44e35 100644 (file)
@@ -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()
index db1abc1e906ac2a2d027ac0ae02d05baadc7a38f..a7b0c2d2dc050b54559295ddf7cd6f7ab3a5c278 100644 (file)
@@ -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()
index 196ef447ee9ddf6ac0c7e2a47a5194467446fb6f..1ff4ce1658ef9b3c6522e599dae2ab55dbea071b 100644 (file)
@@ -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)++;
        }
     }
index 58fb73189eff308ae4dfd9d73f881cbb690a1a4f..b88b2004fbb00acbb7568aaaee365839379f846e 100644 (file)
@@ -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>";
        }
     }
        
index 5e720eb6d4c95002c819f09817a6c4cba2acc285..bc74391b564222be1b8991d9f41cd6a837aa90a3 100644 (file)
@@ -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;
index dc56892144ba3bc36c99be3e426604c8210d18a8..642d335dec874baf4a9995ed3edf4cde534da607 100644 (file)
@@ -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;
index 06a250c6d856b7b8131db20893cce304d63e6daf..737b2eb8f6dd83ba3fc76160e5e2b72b6bcf724e 100644 (file)
@@ -44,6 +44,8 @@
 
 #include <sys/types.h>
 
+#include <roken.h>
+
 /*
  * to select alternate encoding format
  */
  */
 #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)
diff --git a/source4/heimdal_build/hdb-glue.c b/source4/heimdal_build/hdb-glue.c
new file mode 100644 (file)
index 0000000..c25a2f9
--- /dev/null
@@ -0,0 +1,35 @@
+/* 
+   Unix SMB/CIFS implementation.
+
+   provide glue functions between heimdal and samba
+
+   Copyright (C) Andrew Bartlett <abartlet@samba.org> 2009
+   
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include "system/network.h"
+#include "system/kerberos.h"
+#include "lib/socket/netif.h"
+#include "param/param.h"
+
+#include "heimdal/lib/hdb/hdb_locl.h"
+
+krb5_error_code
+hdb_sqlite_create(krb5_context context, HDB **db, const char *argument)
+{
+       return EINVAL;
+}
+
index 52281807b5065d7c073c26eb0a626289096d915e..439f94aaf5869825099beb1aa20553db1db29af6 100644 (file)
@@ -93,7 +93,8 @@ HEIMDAL_HDB_OBJ_FILES = \
        $(heimdalsrcdir)/lib/hdb/keytab.o \
        $(heimdalsrcdir)/lib/hdb/mkey.o \
        $(heimdalsrcdir)/lib/hdb/ndbm.o \
-       $(heimdalsrcdir)/lib/hdb/hdb_err.o
+       $(heimdalsrcdir)/lib/hdb/hdb_err.o \
+       $(heimdalbuildsrcdir)/hdb-glue.o
 
 $(eval $(call heimdal_proto_header_template, \
   $(heimdalsrcdir)/lib/hdb/hdb-protos.h, \
@@ -169,8 +170,10 @@ HEIMDAL_GSSAPI_KRB5_OBJ_FILES = \
        $(heimdalsrcdir)/lib/gssapi/krb5/release_buffer.o \
        $(heimdalsrcdir)/lib/gssapi/krb5/external.o \
        $(heimdalsrcdir)/lib/gssapi/krb5/compat.o \
+       $(heimdalsrcdir)/lib/gssapi/krb5/creds.o \
        $(heimdalsrcdir)/lib/gssapi/krb5/acquire_cred.o \
        $(heimdalsrcdir)/lib/gssapi/krb5/release_cred.o \
+       $(heimdalsrcdir)/lib/gssapi/krb5/store_cred.o \
        $(heimdalsrcdir)/lib/gssapi/krb5/set_cred_option.o \
        $(heimdalsrcdir)/lib/gssapi/krb5/decapsulate.o \
        $(heimdalsrcdir)/lib/gssapi/krb5/verify_mic.o \
@@ -197,6 +200,7 @@ HEIMDAL_GSSAPI_OBJ_FILES = \
        $(heimdalsrcdir)/lib/gssapi/mech/gss_buffer_set.o \
        $(heimdalsrcdir)/lib/gssapi/mech/gss_aeap.o \
        $(heimdalsrcdir)/lib/gssapi/mech/gss_add_cred.o \
+       $(heimdalsrcdir)/lib/gssapi/mech/gss_cred.o \
        $(heimdalsrcdir)/lib/gssapi/mech/gss_add_oid_set_member.o \
        $(heimdalsrcdir)/lib/gssapi/mech/gss_compare_name.o \
        $(heimdalsrcdir)/lib/gssapi/mech/gss_release_oid_set.o \