diff options
233 files changed, 10176 insertions, 3563 deletions
diff --git a/source4/heimdal/README b/source4/heimdal/README index 131cc574fb..88ab7fd121 100644 --- a/source4/heimdal/README +++ b/source4/heimdal/README @@ -1,6 +1,19 @@ -This directory contains a copy of portions of a project known as -'lorikeet-heimdal', a branch of the Heimdal Kerberos distribution. +$Id: README 8839 2000-07-27 02:33:54Z assar $ -The purpose of these files is to provide kerberos support to Samba4 in -a predicatable manner, without reliance on the system kerberos -libraries. +Heimdal is a Kerberos 5 implementation. + +Please see the manual in doc, by default installed in +/usr/heimdal/info/heimdal.info for information on how to install. +There are also briefer man pages for most of the commands. + +Bug reports and bugs are appreciated, see more under Bug reports in +the manual on how we prefer them. + +For more information see the web-page at +<http://www.pdc.kth.se/heimdal/> or the mailing lists: + +heimdal-announce@sics.se low-volume announcement +heimdal-discuss@sics.se high-volume discussion + +send a mail to heimdal-announce-request@sics.se and +heimdal-discuss-request@sics.se respectively to subscribe. diff --git a/source4/heimdal/cf/check-var.m4 b/source4/heimdal/cf/check-var.m4 index 1f06b479c6..ffa61915e9 100644 --- a/source4/heimdal/cf/check-var.m4 +++ b/source4/heimdal/cf/check-var.m4 @@ -1,4 +1,4 @@ -dnl $Id: check-var.m4,v 1.12 2005/06/16 18:59:10 lha Exp $ +dnl $Id: check-var.m4 15422 2005-06-16 18:59:29Z lha $ dnl dnl rk_CHECK_VAR(variable, includes) AC_DEFUN([rk_CHECK_VAR], [ @@ -23,4 +23,5 @@ if test "$ac_foo" = yes; then fi ]) +dnl AC_WARNING_ENABLE([obsolete]) AU_DEFUN([AC_CHECK_VAR], [rk_CHECK_VAR([$2], [$1])], [foo]) diff --git a/source4/heimdal/cf/find-func-no-libs.m4 b/source4/heimdal/cf/find-func-no-libs.m4 index 03ff6dc02b..76965a84ee 100644 --- a/source4/heimdal/cf/find-func-no-libs.m4 +++ b/source4/heimdal/cf/find-func-no-libs.m4 @@ -1,4 +1,4 @@ -dnl $Id: find-func-no-libs.m4,v 1.6 2004/02/12 14:20:45 lha Exp $ +dnl $Id: find-func-no-libs.m4 13338 2004-02-12 14:21:14Z lha $ dnl dnl dnl Look for function in any of the specified libraries diff --git a/source4/heimdal/cf/find-func-no-libs2.m4 b/source4/heimdal/cf/find-func-no-libs2.m4 index 2e7c8b7d4b..617a09e8da 100644 --- a/source4/heimdal/cf/find-func-no-libs2.m4 +++ b/source4/heimdal/cf/find-func-no-libs2.m4 @@ -1,4 +1,4 @@ -dnl $Id: find-func-no-libs2.m4,v 1.9 2004/08/26 12:35:42 joda Exp $ +dnl $Id: find-func-no-libs2.m4 14166 2004-08-26 12:35:42Z joda $ dnl dnl dnl Look for function in any of the specified libraries diff --git a/source4/heimdal/cf/find-func.m4 b/source4/heimdal/cf/find-func.m4 index aa500283f2..2354f38e5e 100644 --- a/source4/heimdal/cf/find-func.m4 +++ b/source4/heimdal/cf/find-func.m4 @@ -1,4 +1,4 @@ -dnl $Id: find-func.m4,v 1.2 2004/02/12 14:20:47 lha Exp $ +dnl $Id: find-func.m4 13338 2004-02-12 14:21:14Z lha $ dnl dnl AC_FIND_FUNC(func, libraries, includes, arguments) AC_DEFUN([AC_FIND_FUNC], [ diff --git a/source4/heimdal/cf/resolv.m4 b/source4/heimdal/cf/resolv.m4 index 20e85a8400..8bb5e4ecbb 100644 --- a/source4/heimdal/cf/resolv.m4 +++ b/source4/heimdal/cf/resolv.m4 @@ -1,6 +1,6 @@ dnl stuff used by DNS resolv code in roken dnl -dnl $Id: resolv.m4,v 1.1 2005/09/02 10:17:38 lha Exp $ +dnl $Id: resolv.m4 16009 2005-09-02 10:17:38Z lha $ dnl AC_DEFUN([rk_RESOLV],[ diff --git a/source4/heimdal/kdc/default_config.c b/source4/heimdal/kdc/default_config.c index 5f336e3275..33a2c297fa 100644 --- a/source4/heimdal/kdc/default_config.c +++ b/source4/heimdal/kdc/default_config.c @@ -36,7 +36,7 @@ #include <getarg.h> #include <parse_bytes.h> -RCSID("$Id: default_config.c 21405 2007-07-04 10:35:45Z lha $"); +RCSID("$Id: default_config.c 23316 2008-06-23 04:32:32Z lha $"); krb5_error_code krb5_kdc_get_config(krb5_context context, krb5_kdc_configuration **config) @@ -45,7 +45,7 @@ krb5_kdc_get_config(krb5_context context, krb5_kdc_configuration **config) c = calloc(1, sizeof(*c)); if (c == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } diff --git a/source4/heimdal/kdc/digest.c b/source4/heimdal/kdc/digest.c index b845b0f9a8..bf1e45b328 100644 --- a/source4/heimdal/kdc/digest.c +++ b/source4/heimdal/kdc/digest.c @@ -34,7 +34,7 @@ #include "kdc_locl.h" #include <hex.h> -RCSID("$Id: digest.c 22374 2007-12-28 18:36:52Z lha $"); +RCSID("$Id: digest.c 23316 2008-06-23 04:32:32Z lha $"); #define MS_CHAP_V2 0x20 #define CHAP_MD5 0x10 @@ -44,13 +44,13 @@ RCSID("$Id: digest.c 22374 2007-12-28 18:36:52Z lha $"); #define NTLM_V1 0x01 const struct units _kdc_digestunits[] = { - {"ms-chap-v2", 1U << 5}, - {"chap-md5", 1U << 4}, - {"digest-md5", 1U << 3}, - {"ntlm-v2", 1U << 2}, - {"ntlm-v1-session", 1U << 1}, - {"ntlm-v1", 1U << 0}, - {NULL, 0} + {"ms-chap-v2", 1U << 5}, + {"chap-md5", 1U << 4}, + {"digest-md5", 1U << 3}, + {"ntlm-v2", 1U << 2}, + {"ntlm-v1-session", 1U << 1}, + {"ntlm-v1", 1U << 0}, + {NULL, 0} }; @@ -121,10 +121,10 @@ fill_targetinfo(krb5_context context, strcmp("imap", str) == 0 || strcmp("pop", str) == 0 || strcmp("smtp", str))) - { - str = krb5_principal_get_comp_string(context, p, 1); - ti.dnsservername = rk_UNCONST(str); - } + { + str = krb5_principal_get_comp_string(context, p, 1); + ti.dnsservername = rk_UNCONST(str); + } ret = heim_ntlm_encode_targetinfo(&ti, 1, &d); if (ret) @@ -186,7 +186,7 @@ get_password_entry(krb5_context context, if (ret || password == NULL) { if (ret == 0) { ret = EINVAL; - krb5_set_error_string(context, "password missing"); + krb5_set_error_message(context, ret, "password missing"); } memset(user, 0, sizeof(*user)); } @@ -263,7 +263,7 @@ _kdc_do_digest(krb5_context context, goto out; ret = EINVAL; - krb5_set_error_string(context, "Wrong digest server principal used"); + krb5_set_error_message(context, ret, "Wrong digest server principal used"); p = krb5_principal_get_comp_string(context, principal, 0); if (p == NULL) { krb5_free_principal(context, principal); @@ -323,9 +323,9 @@ _kdc_do_digest(krb5_context context, "Client %s tried to use digest " "but is not allowed to", client_name); - krb5_set_error_string(context, - "Client is not permitted to use digest"); ret = KRB5KDC_ERR_POLICY; + krb5_set_error_message(context, ret, + "Client is not permitted to use digest"); goto out; } } @@ -338,8 +338,8 @@ _kdc_do_digest(krb5_context context, if (ret) goto out; if (key == NULL) { - krb5_set_error_string(context, "digest: remote subkey not found"); ret = EINVAL; + krb5_set_error_message(context, ret, "digest: remote subkey not found"); goto out; } @@ -359,7 +359,7 @@ _kdc_do_digest(krb5_context context, ret = decode_DigestReqInner(buf.data, buf.length, &ireq, NULL); krb5_data_free(&buf); if (ret) { - krb5_set_error_string(context, "Failed to decode digest inner request"); + krb5_set_error_message(context, ret, "Failed to decode digest inner request"); goto out; } @@ -386,15 +386,15 @@ _kdc_do_digest(krb5_context context, hex_encode(server_nonce, sizeof(server_nonce), &r.u.initReply.nonce); if (r.u.initReply.nonce == NULL) { - krb5_set_error_string(context, "Failed to decode server nonce"); ret = ENOMEM; + krb5_set_error_message(context, ret, "Failed to decode server nonce"); goto out; } sp = krb5_storage_emem(); if (sp == NULL) { ret = ENOMEM; - krb5_set_error_string(context, "out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } ret = krb5_store_stringz(sp, ireq.u.init.type); @@ -410,9 +410,9 @@ _kdc_do_digest(krb5_context context, ireq.u.init.channel->cb_type, ireq.u.init.channel->cb_binding); if (s == NULL) { - krb5_set_error_string(context, "Failed to allocate " - "channel binding"); ret = ENOMEM; + krb5_set_error_message(context, ret, + "Failed to allocate channel binding"); goto out; } free(r.u.initReply.nonce); @@ -429,15 +429,15 @@ _kdc_do_digest(krb5_context context, r.u.initReply.identifier = malloc(sizeof(*r.u.initReply.identifier)); if (r.u.initReply.identifier == NULL) { - krb5_set_error_string(context, "out of memory"); ret = ENOMEM; + krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } asprintf(r.u.initReply.identifier, "%02X", identifier & 0xff); if (*r.u.initReply.identifier == NULL) { - krb5_set_error_string(context, "out of memory"); ret = ENOMEM; + krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } @@ -478,8 +478,8 @@ _kdc_do_digest(krb5_context context, ASN1_MALLOC_ENCODE(Checksum, buf.data, buf.length, &res, &size, ret); free_Checksum(&res); if (ret) { - krb5_set_error_string(context, "Failed to encode " - "checksum in digest request"); + krb5_set_error_message(context, ret, "Failed to encode " + "checksum in digest request"); goto out; } if (size != buf.length) @@ -502,7 +502,7 @@ _kdc_do_digest(krb5_context context, sp = krb5_storage_emem(); if (sp == NULL) { ret = ENOMEM; - krb5_set_error_string(context, "out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } ret = krb5_store_stringz(sp, ireq.u.digestRequest.type); @@ -524,15 +524,15 @@ _kdc_do_digest(krb5_context context, buf.length = strlen(ireq.u.digestRequest.opaque); buf.data = malloc(buf.length); if (buf.data == NULL) { - krb5_set_error_string(context, "out of memory"); ret = ENOMEM; + krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } ret = hex_decode(ireq.u.digestRequest.opaque, buf.data, buf.length); if (ret <= 0) { - krb5_set_error_string(context, "Failed to decode opaque"); ret = ENOMEM; + krb5_set_error_message(context, ret, "Failed to decode opaque"); goto out; } buf.length = ret; @@ -540,7 +540,7 @@ _kdc_do_digest(krb5_context context, ret = decode_Checksum(buf.data, buf.length, &res, NULL); free(buf.data); if (ret) { - krb5_set_error_string(context, "Failed to decode digest Checksum"); + krb5_set_error_message(context, ret, "Failed to decode digest Checksum"); goto out; } @@ -553,8 +553,8 @@ _kdc_do_digest(krb5_context context, serverNonce.length = strlen(ireq.u.digestRequest.serverNonce); serverNonce.data = malloc(serverNonce.length); if (serverNonce.data == NULL) { - krb5_set_error_string(context, "out of memory"); ret = ENOMEM; + krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } @@ -568,8 +568,8 @@ _kdc_do_digest(krb5_context context, ssize = hex_decode(ireq.u.digestRequest.serverNonce, serverNonce.data, serverNonce.length); if (ssize <= 0) { - krb5_set_error_string(context, "Failed to decode serverNonce"); ret = ENOMEM; + krb5_set_error_message(context, ret, "Failed to decode serverNonce"); goto out; } serverNonce.length = ssize; @@ -593,15 +593,15 @@ _kdc_do_digest(krb5_context context, uint32_t t; if (serverNonce.length < 4) { - krb5_set_error_string(context, "server nonce too short"); ret = EINVAL; + krb5_set_error_message(context, ret, "server nonce too short"); goto out; } t = p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24); if (abs((kdc_time & 0xffffffff) - t) > context->max_skew) { - krb5_set_error_string(context, "time screw in server nonce "); ret = EINVAL; + krb5_set_error_message(context, ret, "time screw in server nonce "); goto out; } } @@ -618,15 +618,15 @@ _kdc_do_digest(krb5_context context, } if (ireq.u.digestRequest.identifier == NULL) { - krb5_set_error_string(context, "Identifier missing " - "from CHAP request"); ret = EINVAL; + krb5_set_error_message(context, ret, "Identifier missing " + "from CHAP request"); goto out; } if (hex_decode(*ireq.u.digestRequest.identifier, &id, 1) != 1) { - krb5_set_error_string(context, "failed to decode identifier"); ret = EINVAL; + krb5_set_error_message(context, ret, "failed to decode identifier"); goto out; } @@ -714,8 +714,8 @@ _kdc_do_digest(krb5_context context, MD5_Final(md, &ctx); hex_encode(md, sizeof(md), &A1); if (A1 == NULL) { - krb5_set_error_string(context, "out of memory"); ret = ENOMEM; + krb5_set_error_message(context, ret, "malloc: out of memory"); goto failed; } @@ -733,8 +733,8 @@ _kdc_do_digest(krb5_context context, MD5_Final(md, &ctx); hex_encode(md, sizeof(md), &A2); if (A2 == NULL) { - krb5_set_error_string(context, "out of memory"); ret = ENOMEM; + krb5_set_error_message(context, ret, "malloc: out of memory"); free(A1); goto failed; } @@ -795,15 +795,15 @@ _kdc_do_digest(krb5_context context, } if (ireq.u.digestRequest.clientNonce == NULL) { - krb5_set_error_string(context, - "MS-CHAP-V2 clientNonce missing"); ret = EINVAL; + krb5_set_error_message(context, ret, + "MS-CHAP-V2 clientNonce missing"); goto failed; } if (serverNonce.length != 16) { - krb5_set_error_string(context, - "MS-CHAP-V2 serverNonce wrong length"); ret = EINVAL; + krb5_set_error_message(context, ret, + "MS-CHAP-V2 serverNonce wrong length"); goto failed; } @@ -824,16 +824,16 @@ _kdc_do_digest(krb5_context context, clientNonce.data = malloc(clientNonce.length); if (clientNonce.data == NULL) { ret = ENOMEM; - krb5_set_error_string(context, "out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } ssize = hex_decode(*ireq.u.digestRequest.clientNonce, clientNonce.data, clientNonce.length); if (ssize != 16) { - krb5_set_error_string(context, - "Failed to decode clientNonce"); ret = ENOMEM; + krb5_set_error_message(context, ret, + "Failed to decode clientNonce"); goto out; } SHA1_Update(&ctx, clientNonce.data, ssize); @@ -852,18 +852,18 @@ _kdc_do_digest(krb5_context context, HDB_F_GET_CLIENT, NULL, &user); krb5_free_principal(context, clientprincipal); if (ret) { - krb5_set_error_string(context, - "MS-CHAP-V2 user %s not in database", - username); + krb5_set_error_message(context, ret, + "MS-CHAP-V2 user %s not in database", + username); goto failed; } ret = hdb_enctype2key(context, &user->entry, ETYPE_ARCFOUR_HMAC_MD5, &key); if (ret) { - krb5_set_error_string(context, - "MS-CHAP-V2 missing arcfour key %s", - username); + krb5_set_error_message(context, ret, + "MS-CHAP-V2 missing arcfour key %s", + username); goto failed; } @@ -872,7 +872,7 @@ _kdc_do_digest(krb5_context context, key->key.keyvalue.length, challange, &answer); if (ret) { - krb5_set_error_string(context, "NTLM missing arcfour key"); + krb5_set_error_message(context, ret, "NTLM missing arcfour key"); goto failed; } @@ -967,8 +967,8 @@ _kdc_do_digest(krb5_context context, asprintf(&r.u.error.reason, "Unsupported digest type %s", ireq.u.digestRequest.type); if (r.u.error.reason == NULL) { - krb5_set_error_string(context, "out of memory"); ret = ENOMEM; + krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } r.u.error.code = EINVAL; @@ -1021,29 +1021,29 @@ _kdc_do_digest(krb5_context context, r.u.ntlmInitReply.targetname = get_ntlm_targetname(context, client); if (r.u.ntlmInitReply.targetname == NULL) { - krb5_set_error_string(context, "out of memory"); ret = ENOMEM; + krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } r.u.ntlmInitReply.challange.data = malloc(8); if (r.u.ntlmInitReply.challange.data == NULL) { - krb5_set_error_string(context, "out of memory"); ret = ENOMEM; + krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } r.u.ntlmInitReply.challange.length = 8; if (RAND_bytes(r.u.ntlmInitReply.challange.data, r.u.ntlmInitReply.challange.length) != 1) - { - krb5_set_error_string(context, "out of random error"); - ret = ENOMEM; - goto out; - } + { + ret = ENOMEM; + krb5_set_error_message(context, ret, "out of random error"); + goto out; + } /* XXX fix targetinfo */ ALLOC(r.u.ntlmInitReply.targetinfo); if (r.u.ntlmInitReply.targetinfo == NULL) { - krb5_set_error_string(context, "out of memory"); ret = ENOMEM; + krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } @@ -1052,8 +1052,8 @@ _kdc_do_digest(krb5_context context, client, r.u.ntlmInitReply.targetinfo); if (ret) { - krb5_set_error_string(context, "out of memory"); ret = ENOMEM; + krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } @@ -1064,14 +1064,14 @@ _kdc_do_digest(krb5_context context, sp = krb5_storage_emem(); if (sp == NULL) { ret = ENOMEM; - krb5_set_error_string(context, "out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } ret = krb5_storage_write(sp, r.u.ntlmInitReply.challange.data, 8); if (ret != 8) { ret = ENOMEM; - krb5_set_error_string(context, "storage write challange"); + krb5_set_error_message(context, ret, "storage write challange"); goto out; } ret = krb5_store_uint32(sp, r.u.ntlmInitReply.flags); @@ -1127,8 +1127,8 @@ _kdc_do_digest(krb5_context context, HDB_F_GET_CLIENT, NULL, &user); krb5_free_principal(context, clientprincipal); if (ret) { - krb5_set_error_string(context, "NTLM user %s not in database", - ireq.u.ntlmRequest.username); + krb5_set_error_message(context, ret, "NTLM user %s not in database", + ireq.u.ntlmRequest.username); goto failed; } @@ -1150,33 +1150,33 @@ _kdc_do_digest(krb5_context context, sp = krb5_storage_from_data(&buf); if (sp == NULL) { ret = ENOMEM; - krb5_set_error_string(context, "out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } ret = krb5_storage_read(sp, challange, sizeof(challange)); if (ret != sizeof(challange)) { - krb5_set_error_string(context, "NTLM storage read challange"); ret = ENOMEM; + krb5_set_error_message(context, ret, "NTLM storage read challange"); goto out; } ret = krb5_ret_uint32(sp, &flags); if (ret) { - krb5_set_error_string(context, "NTLM storage read flags"); + krb5_set_error_message(context, ret, "NTLM storage read flags"); goto out; } krb5_data_free(&buf); if ((flags & NTLM_NEG_NTLM) == 0) { ret = EINVAL; - krb5_set_error_string(context, "NTLM not negotiated"); + krb5_set_error_message(context, ret, "NTLM not negotiated"); goto out; } ret = hdb_enctype2key(context, &user->entry, ETYPE_ARCFOUR_HMAC_MD5, &key); if (ret) { - krb5_set_error_string(context, "NTLM missing arcfour key"); + krb5_set_error_message(context, ret, "NTLM missing arcfour key"); goto out; } @@ -1194,8 +1194,8 @@ _kdc_do_digest(krb5_context context, targetname = get_ntlm_targetname(context, client); if (targetname == NULL) { - krb5_set_error_string(context, "out of memory"); ret = ENOMEM; + krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } @@ -1213,7 +1213,7 @@ _kdc_do_digest(krb5_context context, sessionkey); free(targetname); if (ret) { - krb5_set_error_string(context, "NTLM v2 verify failed"); + krb5_set_error_message(context, ret, "NTLM v2 verify failed"); goto failed; } @@ -1238,9 +1238,9 @@ _kdc_do_digest(krb5_context context, } if (ireq.u.ntlmRequest.lm.length != 24) { - krb5_set_error_string(context, "LM hash have wrong length " - "for NTLM session key"); ret = EINVAL; + krb5_set_error_message(context, ret, "LM hash have wrong length " + "for NTLM session key"); goto failed; } @@ -1260,18 +1260,18 @@ _kdc_do_digest(krb5_context context, key->key.keyvalue.length, challange, &answer); if (ret) { - krb5_set_error_string(context, "NTLM missing arcfour key"); + krb5_set_error_message(context, ret, "NTLM missing arcfour key"); goto failed; } if (ireq.u.ntlmRequest.ntlm.length != answer.length || memcmp(ireq.u.ntlmRequest.ntlm.data, answer.data, answer.length) != 0) - { - free(answer.data); - ret = EINVAL; - krb5_set_error_string(context, "NTLM hash mismatch"); - goto failed; - } + { + free(answer.data); + ret = EINVAL; + krb5_set_error_message(context, ret, "NTLM hash mismatch"); + goto failed; + } free(answer.data); { @@ -1290,18 +1290,19 @@ _kdc_do_digest(krb5_context context, size_t len; if ((flags & NTLM_NEG_KEYEX) == 0) { - krb5_set_error_string(context, - "NTLM client failed to neg key " - "exchange but still sent key"); ret = EINVAL; + krb5_set_error_message(context, ret, + "NTLM client failed to neg key " + "exchange but still sent key"); goto failed; } len = ireq.u.ntlmRequest.sessionkey->length; if (len != sizeof(masterkey)){ - krb5_set_error_string(context, - "NTLM master key wrong length: %lu", - (unsigned long)len); + ret = EINVAL; + krb5_set_error_message(context, ret, + "NTLM master key wrong length: %lu", + (unsigned long)len); goto failed; } @@ -1315,14 +1316,15 @@ _kdc_do_digest(krb5_context context, r.u.ntlmResponse.sessionkey = malloc(sizeof(*r.u.ntlmResponse.sessionkey)); if (r.u.ntlmResponse.sessionkey == NULL) { - krb5_set_error_string(context, "out of memory"); + ret = EINVAL; + krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } ret = krb5_data_copy(r.u.ntlmResponse.sessionkey, masterkey, sizeof(masterkey)); if (ret) { - krb5_set_error_string(context, "out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } } @@ -1354,11 +1356,11 @@ _kdc_do_digest(krb5_context context, break; default: { - char *s; - krb5_set_error_string(context, "unknown operation to digest"); + const char *s; ret = EINVAL; + krb5_set_error_message(context, ret, "unknown operation to digest"); - failed: + failed: s = krb5_get_error_message(context, ret); if (s == NULL) { @@ -1370,10 +1372,10 @@ _kdc_do_digest(krb5_context context, r.element = choice_DigestRepInner_error; r.u.error.reason = strdup("unknown error"); - krb5_free_error_string(context, s); + krb5_free_error_message(context, s); if (r.u.error.reason == NULL) { - krb5_set_error_string(context, "out of memory"); ret = ENOMEM; + krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } r.u.error.code = EINVAL; @@ -1383,7 +1385,7 @@ _kdc_do_digest(krb5_context context, ASN1_MALLOC_ENCODE(DigestRepInner, buf.data, buf.length, &r, &size, ret); if (ret) { - krb5_set_error_string(context, "Failed to encode inner digest reply"); + krb5_set_error_message(context, ret, "Failed to encode inner digest reply"); goto out; } if (size != buf.length) @@ -1414,14 +1416,14 @@ _kdc_do_digest(krb5_context context, ASN1_MALLOC_ENCODE(DigestREP, reply->data, reply->length, &rep, &size, ret); if (ret) { - krb5_set_error_string(context, "Failed to encode digest reply"); + krb5_set_error_message(context, ret, "Failed to encode digest reply"); goto out; } if (size != reply->length) krb5_abortx(context, "ASN1 internal error"); -out: + out: if (ac) krb5_auth_con_free(context, ac); if (ret) diff --git a/source4/heimdal/kdc/kaserver.c b/source4/heimdal/kdc/kaserver.c index 27f497ea66..4f257d717e 100644 --- a/source4/heimdal/kdc/kaserver.c +++ b/source4/heimdal/kdc/kaserver.c @@ -33,7 +33,7 @@ #include "kdc_locl.h" -RCSID("$Id: kaserver.c 21654 2007-07-21 17:30:18Z lha $"); +RCSID("$Id: kaserver.c 23110 2008-04-27 18:51:17Z lha $"); #include <krb5-v4compat.h> #include <rx.h> @@ -366,7 +366,7 @@ create_reply_ticket (krb5_context context, DES_cblock deskey; memcpy (&deskey, key->keyvalue.data, sizeof(deskey)); - DES_set_key (&deskey, &schedule); + DES_set_key_unchecked (&deskey, &schedule); DES_pcbc_encrypt (enc_data.data, enc_data.data, enc_data.length, @@ -524,7 +524,7 @@ do_authenticate (krb5_context context, /* try to decode the `request' */ memcpy (&key, ckey->key.keyvalue.data, sizeof(key)); - DES_set_key (&key, &schedule); + DES_set_key_unchecked (&key, &schedule); DES_pcbc_encrypt (request.data, request.data, request.length, @@ -801,7 +801,7 @@ do_getticket (krb5_context context, /* decrypt the times */ memcpy(&session, ad.session.keyvalue.data, sizeof(session)); - DES_set_key (&session, &schedule); + DES_set_key_unchecked (&session, &schedule); DES_ecb_encrypt (times.data, times.data, &schedule, diff --git a/source4/heimdal/kdc/kerberos5.c b/source4/heimdal/kdc/kerberos5.c index f1dea6499d..2a2c48c233 100644 --- a/source4/heimdal/kdc/kerberos5.c +++ b/source4/heimdal/kdc/kerberos5.c @@ -33,7 +33,7 @@ #include "kdc_locl.h" -RCSID("$Id: kerberos5.c 22071 2007-11-14 20:04:50Z lha $"); +RCSID("$Id: kerberos5.c 23316 2008-06-23 04:32:32Z lha $"); #define MAX_TIME ((time_t)((1U << 31) - 1)) @@ -1648,7 +1648,7 @@ _kdc_as_rep(krb5_context context, memset(&canon, 0, sizeof(canon)); canon.names.requested_name = *b->cname; - canon.names.real_name = client->entry.principal->name; + canon.names.mapped_name = client->entry.principal->name; ASN1_MALLOC_ENCODE(PA_ClientCanonicalizedNames, data.data, data.length, &canon.names, &len, ret); @@ -1807,7 +1807,7 @@ _kdc_tkt_add_if_relevant_ad(krb5_context context, if (tkt->authorization_data == NULL) { tkt->authorization_data = calloc(1, sizeof(*tkt->authorization_data)); if (tkt->authorization_data == NULL) { - krb5_set_error_string(context, "out of memory"); + krb5_set_error_message(context, ENOMEM, "out of memory"); return ENOMEM; } } @@ -1822,7 +1822,7 @@ _kdc_tkt_add_if_relevant_ad(krb5_context context, ret = add_AuthorizationData(&ad, &ade); if (ret) { - krb5_set_error_string(context, "add AuthorizationData failed"); + krb5_set_error_message(context, ret, "add AuthorizationData failed"); return ret; } @@ -1833,8 +1833,8 @@ _kdc_tkt_add_if_relevant_ad(krb5_context context, &ad, &size, ret); free_AuthorizationData(&ad); if (ret) { - krb5_set_error_string(context, "ASN.1 encode of " - "AuthorizationData failed"); + krb5_set_error_message(context, ret, "ASN.1 encode of " + "AuthorizationData failed"); return ret; } if (ade.ad_data.length != size) @@ -1843,7 +1843,7 @@ _kdc_tkt_add_if_relevant_ad(krb5_context context, ret = add_AuthorizationData(tkt->authorization_data, &ade); der_free_octet_string(&ade.ad_data); if (ret) { - krb5_set_error_string(context, "add AuthorizationData failed"); + krb5_set_error_message(context, ret, "add AuthorizationData failed"); return ret; } } diff --git a/source4/heimdal/kdc/krb5tgs.c b/source4/heimdal/kdc/krb5tgs.c index 32bdee9799..071a30d5a7 100644 --- a/source4/heimdal/kdc/krb5tgs.c +++ b/source4/heimdal/kdc/krb5tgs.c @@ -1,45 +1,45 @@ /* - * Copyright (c) 1997-2007 Kungliga Tekniska Högskolan - * (Royal Institute of Technology, Stockholm, Sweden). - * All rights reserved. + * Copyright (c) 1997-2008 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: + * 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. + * 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. + * 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. + * 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. + * 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 "kdc_locl.h" -RCSID("$Id: krb5tgs.c 22071 2007-11-14 20:04:50Z lha $"); +RCSID("$Id: krb5tgs.c 23316 2008-06-23 04:32:32Z lha $"); /* * return the realm of a krbtgt-ticket or NULL */ -static Realm +static Realm get_krbtgt_realm(const PrincipalName *p) { if(p->name_string.len == 2 @@ -80,8 +80,8 @@ find_KRB5SignedPath(krb5_context context, &child, NULL); if (ret) { - krb5_set_error_string(context, "Failed to decode " - "IF_RELEVANT with %d", ret); + krb5_set_error_message(context, ret, "Failed to decode " + "IF_RELEVANT with %d", ret); return ret; } @@ -168,7 +168,7 @@ _kdc_add_KRB5SignedPath(krb5_context context, if (data.length != size) krb5_abortx(context, "internal asn.1 encoder error"); - + /* * Add IF-RELEVANT(KRB5SignedPath) to the last slot in * authorization data field. @@ -187,13 +187,14 @@ check_KRB5SignedPath(krb5_context context, hdb_entry_ex *krbtgt, EncTicketPart *tkt, KRB5SignedPathPrincipals **delegated, - int require_signedpath) + int *signedpath) { krb5_error_code ret; krb5_data data; krb5_crypto crypto = NULL; - *delegated = NULL; + if (delegated) + *delegated = NULL; ret = find_KRB5SignedPath(context, tkt->authorization_data, &data); if (ret == 0) { @@ -236,8 +237,8 @@ check_KRB5SignedPath(krb5_context context, return ret; } } - ret = krb5_verify_checksum(context, crypto, KRB5_KU_KRB5SIGNEDPATH, - data.data, data.length, + ret = krb5_verify_checksum(context, crypto, KRB5_KU_KRB5SIGNEDPATH, + data.data, data.length, &sp.cksum); krb5_crypto_destroy(context, crypto); free(data.data); @@ -246,7 +247,7 @@ check_KRB5SignedPath(krb5_context context, return ret; } - if (sp.delegated) { + if (delegated && sp.delegated) { *delegated = malloc(sizeof(*sp.delegated)); if (*delegated == NULL) { @@ -263,10 +264,8 @@ check_KRB5SignedPath(krb5_context context, } } free_KRB5SignedPath(&sp); - - } else { - if (require_signedpath) - return KRB5KDC_ERR_BADOPTION; + + *signedpath = 1; } return 0; @@ -286,7 +285,7 @@ check_PAC(krb5_context context, const EncryptionKey *krbtgt_key, EncTicketPart *tkt, krb5_data *rspac, - int *require_signedpath) + int *signedpath) { AuthorizationData *ad = tkt->authorization_data; unsigned i, j; @@ -306,8 +305,8 @@ check_PAC(krb5_context context, &child, NULL); if (ret) { - krb5_set_error_string(context, "Failed to decode " - "IF_RELEVANT with %d", ret); + krb5_set_error_message(context, ret, "Failed to decode " + "IF_RELEVANT with %d", ret); return ret; } for (j = 0; j < child.len; j++) { @@ -324,7 +323,7 @@ check_PAC(krb5_context context, if (ret) return ret; - ret = krb5_pac_verify(context, pac, tkt->authtime, + ret = krb5_pac_verify(context, pac, tkt->authtime, client_principal, krbtgt_key, NULL); if (ret) { @@ -332,13 +331,13 @@ check_PAC(krb5_context context, return ret; } - ret = _kdc_pac_verify(context, client_principal, + ret = _kdc_pac_verify(context, client_principal, client, server, &pac); if (ret) { krb5_pac_free(context, pac); return ret; } - *require_signedpath = 0; + *signedpath = 1; ret = _krb5_pac_sign(context, pac, tkt->authtime, client_principal, @@ -359,7 +358,7 @@ check_PAC(krb5_context context, */ static krb5_error_code -check_tgs_flags(krb5_context context, +check_tgs_flags(krb5_context context, krb5_kdc_configuration *config, KDC_REQ_BODY *b, const EncTicketPart *tgt, EncTicketPart *et) { @@ -379,7 +378,7 @@ check_tgs_flags(krb5_context context, /* XXX tkt = tgt */ et->flags.invalid = 0; }else if(tgt->flags.invalid){ - kdc_log(context, config, 0, + kdc_log(context, config, 0, "Ticket-granting ticket has INVALID flag set"); return KRB5KRB_AP_ERR_TKT_INVALID; } @@ -473,8 +472,8 @@ check_tgs_flags(krb5_context context, et->endtime = *et->starttime + old_life; if (et->renew_till != NULL) et->endtime = min(*et->renew_till, et->endtime); - } - + } + #if 0 /* checks for excess flags */ if(f.request_anonymous && !config->allow_anonymous){ @@ -491,7 +490,7 @@ check_tgs_flags(krb5_context context, */ static krb5_error_code -check_constrained_delegation(krb5_context context, +check_constrained_delegation(krb5_context context, krb5_kdc_configuration *config, hdb_entry_ex *client, krb5_const_principal server) @@ -522,7 +521,7 @@ check_constrained_delegation(krb5_context context, */ static krb5_error_code -verify_flags (krb5_context context, +verify_flags (krb5_context context, krb5_kdc_configuration *config, const EncTicketPart *et, const char *pstr) @@ -543,18 +542,18 @@ verify_flags (krb5_context context, */ static krb5_error_code -fix_transited_encoding(krb5_context context, +fix_transited_encoding(krb5_context context, krb5_kdc_configuration *config, krb5_boolean check_policy, - const TransitedEncoding *tr, - EncTicketPart *et, - const char *client_realm, - const char *server_realm, + const TransitedEncoding *tr, + EncTicketPart *et, + const char *client_realm, + const char *server_realm, const char *tgt_realm) { krb5_error_code ret = 0; char **realms, **tmp; - int num_realms; + unsigned int num_realms; int i; switch (tr->tr_type) { @@ -576,9 +575,9 @@ fix_transited_encoding(krb5_context context, return KRB5KDC_ERR_TRTYPE_NOSUPP; } - ret = krb5_domain_x500_decode(context, + ret = krb5_domain_x500_decode(context, tr->contents, - &realms, + &realms, &num_realms, client_realm, server_realm); @@ -589,7 +588,7 @@ fix_transited_encoding(krb5_context context, } if(strcmp(client_realm, tgt_realm) && strcmp(server_realm, tgt_realm)) { /* not us, so add the previous realm to transited set */ - if (num_realms < 0 || num_realms + 1 > UINT_MAX/sizeof(*realms)) { + if (num_realms + 1 > UINT_MAX/sizeof(*realms)) { ret = ERANGE; goto free_realms; } @@ -607,7 +606,7 @@ fix_transited_encoding(krb5_context context, num_realms++; } if(num_realms == 0) { - if(strcmp(client_realm, server_realm)) + if(strcmp(client_realm, server_realm)) kdc_log(context, config, 0, "cross-realm %s -> %s", client_realm, server_realm); } else { @@ -630,11 +629,11 @@ fix_transited_encoding(krb5_context context, } } if(check_policy) { - ret = krb5_check_transited(context, client_realm, - server_realm, + ret = krb5_check_transited(context, client_realm, + server_realm, realms, num_realms, NULL); if(ret) { - krb5_warn(context, ret, "cross-realm %s -> %s", + krb5_warn(context, ret, "cross-realm %s -> %s", client_realm, server_realm); goto free_realms; } @@ -653,23 +652,24 @@ fix_transited_encoding(krb5_context context, static krb5_error_code -tgs_make_reply(krb5_context context, +tgs_make_reply(krb5_context context, krb5_kdc_configuration *config, - KDC_REQ_BODY *b, + KDC_REQ_BODY *b, krb5_const_principal tgt_name, - const EncTicketPart *tgt, + const EncTicketPart *tgt, const EncryptionKey *serverkey, const krb5_keyblock *sessionkey, krb5_kvno kvno, AuthorizationData *auth_data, - hdb_entry_ex *server, - const char *server_name, - hdb_entry_ex *client, - krb5_principal client_principal, + hdb_entry_ex *server, + const char *server_name, + hdb_entry_ex *client, + krb5_principal client_principal, hdb_entry_ex *krbtgt, krb5_enctype krbtgt_etype, KRB5SignedPathPrincipals *spp, const krb5_data *rspac, + const METHOD_DATA *enc_pa_data, const char **e_text, krb5_data *reply) { @@ -678,11 +678,11 @@ tgs_make_reply(krb5_context context, EncTicketPart et; KDCOptions f = b->kdc_options; krb5_error_code ret; - + memset(&rep, 0, sizeof(rep)); memset(&et, 0, sizeof(et)); memset(&ek, 0, sizeof(ek)); - + rep.pvno = 5; rep.msg_type = krb_tgs_rep; @@ -691,7 +691,7 @@ tgs_make_reply(krb5_context context, et.endtime = min(tgt->endtime, *b->till); ALLOC(et.starttime); *et.starttime = kdc_time; - + ret = check_tgs_flags(context, config, b, tgt, &et); if(ret) goto out; @@ -715,11 +715,11 @@ tgs_make_reply(krb5_context context, #define PRINCIPAL_FORCE_TRANSITED_CHECK(P) 0 #define PRINCIPAL_ALLOW_DISABLE_TRANSITED_CHECK(P) 0 - ret = fix_transited_encoding(context, config, + ret = fix_transited_encoding(context, config, !f.disable_transited_check || GLOBAL_FORCE_TRANSITED_CHECK || PRINCIPAL_FORCE_TRANSITED_CHECK(server) || - !((GLOBAL_ALLOW_PER_PRINCIPAL && + !((GLOBAL_ALLOW_PER_PRINCIPAL && PRINCIPAL_ALLOW_DISABLE_TRANSITED_CHECK(server)) || GLOBAL_ALLOW_DISABLE_TRANSITED_CHECK), &tgt->transited, &et, @@ -729,7 +729,7 @@ tgs_make_reply(krb5_context context, if(ret) goto out; - copy_Realm(krb5_princ_realm(context, server->entry.principal), + copy_Realm(krb5_princ_realm(context, server->entry.principal), &rep.ticket.realm); _krb5_principal2principalname(&rep.ticket.sname, server->entry.principal); copy_Realm(&tgt_name->realm, &rep.crealm); @@ -754,7 +754,7 @@ tgs_make_reply(krb5_context context, life = min(life, *server->entry.max_life); et.endtime = *et.starttime + life; } - if(f.renewable_ok && tgt->flags.renewable && + if(f.renewable_ok && tgt->flags.renewable && et.renew_till == NULL && et.endtime < *b->till){ et.flags.renewable = 1; ALLOC(et.renew_till); @@ -769,13 +769,13 @@ tgs_make_reply(krb5_context context, renew = min(renew, *server->entry.max_renew); *et.renew_till = et.authtime + renew; } - + if(et.renew_till){ *et.renew_till = min(*et.renew_till, *tgt->renew_till); *et.starttime = min(*et.starttime, *et.renew_till); et.endtime = min(et.endtime, *et.renew_till); } - + *et.starttime = min(*et.starttime, et.endtime); if(*et.starttime == et.endtime){ @@ -787,12 +787,12 @@ tgs_make_reply(krb5_context context, et.renew_till = NULL; et.flags.renewable = 0; } - + et.flags.pre_authent = tgt->flags.pre_authent; et.flags.hw_authent = tgt->flags.hw_authent; et.flags.anonymous = tgt->flags.anonymous; et.flags.ok_as_delegate = server->entry.flags.ok_as_delegate; - + if (auth_data) { /* XXX Check enc-authorization-data */ et.authorization_data = calloc(1, sizeof(*et.authorization_data)); @@ -836,7 +836,7 @@ tgs_make_reply(krb5_context context, goto out; et.crealm = tgt->crealm; et.cname = tgt_name->name; - + ek.key = et.key; /* MIT must have at least one last_req */ ek.last_req.len = 1; @@ -853,8 +853,8 @@ tgs_make_reply(krb5_context context, ek.renew_till = et.renew_till; ek.srealm = rep.ticket.realm; ek.sname = rep.ticket.sname; - - _kdc_log_timestamp(context, config, "TGS-REQ", et.authtime, et.starttime, + + _kdc_log_timestamp(context, config, "TGS-REQ", et.authtime, et.starttime, et.endtime, et.renew_till); /* Don't sign cross realm tickets, they can't be checked anyway */ @@ -874,6 +874,17 @@ tgs_make_reply(krb5_context context, } } + if (enc_pa_data->len) { + rep.padata = calloc(1, sizeof(*rep.padata)); + if (rep.padata == NULL) { + ret = ENOMEM; + goto out; + } + ret = copy_METHOD_DATA(enc_pa_data, rep.padata); + if (ret) + goto out; + } + /* It is somewhat unclear where the etype in the following encryption should come from. What we have is a session key in the passed tgt, and a list of preferred etypes @@ -884,9 +895,9 @@ tgs_make_reply(krb5_context context, CAST session key. Should the DES3 etype be added to the etype list, even if we don't want a session key with DES3? */ - ret = _kdc_encode_reply(context, config, + ret = _kdc_encode_reply(context, config, &rep, &et, &ek, et.key.keytype, - kvno, + kvno, serverkey, 0, &tgt->key, e_text, reply); out: free_TGS_REP(&rep); @@ -906,10 +917,10 @@ out: } static krb5_error_code -tgs_check_authenticator(krb5_context context, +tgs_check_authenticator(krb5_context context, krb5_kdc_configuration *config, krb5_auth_context ac, - KDC_REQ_BODY *b, + KDC_REQ_BODY *b, const char **e_text, krb5_keyblock *key) { @@ -919,7 +930,7 @@ tgs_check_authenticator(krb5_context context, size_t buf_size; krb5_error_code ret; krb5_crypto crypto; - + krb5_auth_con_getauthenticator(context, ac, &auth); if(auth->cksum == NULL){ kdc_log(context, config, 0, "No authenticator in request"); @@ -936,7 +947,7 @@ tgs_check_authenticator(krb5_context context, || #endif !krb5_checksum_is_collision_proof(context, auth->cksum->cksumtype)) { - kdc_log(context, config, 0, "Bad checksum type in authenticator: %d", + kdc_log(context, config, 0, "Bad checksum type in authenticator: %d", auth->cksum->cksumtype); ret = KRB5KRB_AP_ERR_INAPP_CKSUM; goto out; @@ -945,7 +956,7 @@ tgs_check_authenticator(krb5_context context, /* XXX should not re-encode this */ ASN1_MALLOC_ENCODE(KDC_REQ_BODY, buf, buf_size, b, &len, ret); if(ret){ - kdc_log(context, config, 0, "Failed to encode KDC-REQ-BODY: %s", + kdc_log(context, config, 0, "Failed to encode KDC-REQ-BODY: %s", krb5_get_err_text(context, ret)); goto out; } @@ -966,14 +977,14 @@ tgs_check_authenticator(krb5_context context, ret = krb5_verify_checksum(context, crypto, KRB5_KU_TGS_REQ_AUTH_CKSUM, - buf, + buf, len, auth->cksum); free(buf); krb5_crypto_destroy(context, crypto); if(ret){ kdc_log(context, config, 0, - "Failed to verify authenticator checksum: %s", + "Failed to verify authenticator checksum: %s", krb5_get_err_text(context, ret)); } out: @@ -991,27 +1002,38 @@ find_rpath(krb5_context context, Realm crealm, Realm srealm) { const char *new_realm = krb5_config_get_string(context, NULL, - "capaths", + "capaths", crealm, srealm, NULL); return new_realm; } - + static krb5_boolean -need_referral(krb5_context context, krb5_principal server, krb5_realm **realms) +need_referral(krb5_context context, krb5_kdc_configuration *config, + const KDCOptions * const options, krb5_principal server, + krb5_realm **realms) { - if(server->name.name_type != KRB5_NT_SRV_INST || - server->name.name_string.len != 2) + const char *name; + + if(!options->canonicalize && server->name.name_type != KRB5_NT_SRV_INST) + return FALSE; + + if (server->name.name_string.len == 1) + name = server->name.name_string.val[0]; + if (server->name.name_string.len > 1) + name = server->name.name_string.val[1]; + else return FALSE; - - return _krb5_get_host_realm_int(context, server->name.name_string.val[1], - FALSE, realms) == 0; + + kdc_log(context, config, 0, "Searching referral for %s", name); + + return _krb5_get_host_realm_int(context, name, FALSE, realms) == 0; } static krb5_error_code -tgs_parse_request(krb5_context context, +tgs_parse_request(krb5_context context, krb5_kdc_configuration *config, KDC_REQ_BODY *b, const PA_DATA *tgs_req, @@ -1041,7 +1063,7 @@ tgs_parse_request(krb5_context context, memset(&ap_req, 0, sizeof(ap_req)); ret = krb5_decode_ap_req(context, &tgs_req->padata_value, &ap_req); if(ret){ - kdc_log(context, config, 0, "Failed to decode AP-REQ: %s", + kdc_log(context, config, 0, "Failed to decode AP-REQ: %s", krb5_get_err_text(context, ret)); goto out; } @@ -1052,12 +1074,12 @@ tgs_parse_request(krb5_context context, ret = KRB5KDC_ERR_POLICY; /* ? */ goto out; } - + _krb5_principalname2krb5_principal(context, &princ, ap_req.ticket.sname, ap_req.ticket.realm); - + ret = _kdc_db_fetch(context, config, princ, HDB_F_GET_KRBTGT, NULL, krbtgt); if(ret) { @@ -1074,8 +1096,8 @@ tgs_parse_request(krb5_context context, ret = KRB5KRB_AP_ERR_NOT_US; goto out; } - - if(ap_req.ticket.enc_part.kvno && + + if(ap_req.ticket.enc_part.kvno && *ap_req.ticket.enc_part.kvno != (*krbtgt)->entry.kvno){ char *p; @@ -1084,7 +1106,7 @@ tgs_parse_request(krb5_context context, if (ret != 0) p = "<unparse_name failed>"; kdc_log(context, config, 0, - "Ticket kvno = %d, DB kvno = %d (%s)", + "Ticket kvno = %d, DB kvno = %d (%s)", *ap_req.ticket.enc_part.kvno, (*krbtgt)->entry.kvno, p); @@ -1096,7 +1118,7 @@ tgs_parse_request(krb5_context context, *krbtgt_etype = ap_req.ticket.enc_part.etype; - ret = hdb_enctype2key(context, &(*krbtgt)->entry, + ret = hdb_enctype2key(context, &(*krbtgt)->entry, ap_req.ticket.enc_part.etype, &tkey); if(ret){ char *str = NULL, *p = NULL; @@ -1112,7 +1134,7 @@ tgs_parse_request(krb5_context context, ret = KRB5KRB_AP_ERR_BADKEYVER; goto out; } - + if (b->kdc_options.validate) verify_ap_req_flags = KRB5_VERIFY_AP_REQ_IGNORE_INVALID; else @@ -1127,10 +1149,10 @@ tgs_parse_request(krb5_context context, &ap_req_options, ticket, KRB5_KU_TGS_REQ_AUTH); - + krb5_free_principal(context, princ); if(ret) { - kdc_log(context, config, 0, "Failed to verify AP-REQ: %s", + kdc_log(context, config, 0, "Failed to verify AP-REQ: %s", krb5_get_err_text(context, ret)); goto out; } @@ -1158,7 +1180,7 @@ tgs_parse_request(krb5_context context, } } - ret = tgs_check_authenticator(context, config, + ret = tgs_check_authenticator(context, config, ac, b, e_text, &(*ticket)->ticket.key); if (ret) { krb5_auth_con_free(context, ac); @@ -1175,7 +1197,7 @@ tgs_parse_request(krb5_context context, &subkey); if(ret){ krb5_auth_con_free(context, ac); - kdc_log(context, config, 0, "Failed to get remote subkey: %s", + kdc_log(context, config, 0, "Failed to get remote subkey: %s", krb5_get_err_text(context, ret)); goto out; } @@ -1184,7 +1206,7 @@ tgs_parse_request(krb5_context context, ret = krb5_auth_con_getkey(context, ac, &subkey); if(ret) { krb5_auth_con_free(context, ac); - kdc_log(context, config, 0, "Failed to get session key: %s", + kdc_log(context, config, 0, "Failed to get session key: %s", krb5_get_err_text(context, ret)); goto out; } @@ -1211,7 +1233,7 @@ tgs_parse_request(krb5_context context, krb5_crypto_destroy(context, crypto); if(ret){ krb5_auth_con_free(context, ac); - kdc_log(context, config, 0, + kdc_log(context, config, 0, "Failed to decrypt enc-authorization-data"); ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; /* ? */ goto out; @@ -1235,17 +1257,95 @@ tgs_parse_request(krb5_context context, } krb5_auth_con_free(context, ac); - + out: free_AP_REQ(&ap_req); - + return ret; } static krb5_error_code -tgs_build_reply(krb5_context context, +build_server_referral(krb5_context context, + krb5_kdc_configuration *config, + krb5_crypto session, + krb5_const_realm referred_realm, + const PrincipalName *true_principal_name, + const PrincipalName *requested_principal, + krb5_data *outdata) +{ + PA_ServerReferralData ref; + krb5_error_code ret; + EncryptedData ed; + krb5_data data; + size_t size; + + memset(&ref, 0, sizeof(ref)); + + if (referred_realm) { + ref.referred_realm = malloc(sizeof(ref.referred_realm)); + if (ref.referred_realm == NULL) + goto eout; + *ref.referred_realm = strdup(referred_realm); + if (*ref.referred_realm == NULL) + goto eout; + } + if (true_principal_name) { + ref.true_principal_name = + malloc(sizeof(ref.true_principal_name)); + if (ref.true_principal_name == NULL) + goto eout; + ret = copy_PrincipalName(true_principal_name, ref.true_principal_name); + if (ret) + goto eout; + } + if (requested_principal) { + ref.requested_principal_name = + malloc(sizeof(ref.requested_principal_name)); + if (ref.requested_principal_name == NULL) + goto eout; + ret = copy_PrincipalName(requested_principal, + ref.requested_principal_name); + if (ret) + goto eout; + } + + ASN1_MALLOC_ENCODE(PA_ServerReferralData, + data.data, data.length, + &ref, &size, ret); + free_PA_ServerReferralData(&ref); + if (ret) + return ret; + if (data.length != size) + krb5_abortx(context, "internal asn.1 encoder error"); + + ret = krb5_encrypt_EncryptedData(context, session, + KRB5_KU_PA_SERVER_REFERRAL, + data.data, data.length, + 0 /* kvno */, &ed); + free(data.data); + if (ret) + return ret; + + ASN1_MALLOC_ENCODE(EncryptedData, + outdata->data, outdata->length, + &ed, &size, ret); + free_EncryptedData(&ed); + if (ret) + return ret; + if (outdata->length != size) + krb5_abortx(context, "internal asn.1 encoder error"); + + return 0; +eout: + free_PA_ServerReferralData(&ref); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); + return ENOMEM; +} + +static krb5_error_code +tgs_build_reply(krb5_context context, krb5_kdc_configuration *config, - KDC_REQ *req, + KDC_REQ *req, KDC_REQ_BODY *b, hdb_entry_ex *krbtgt, krb5_enctype krbtgt_etype, @@ -1253,7 +1353,7 @@ tgs_build_reply(krb5_context context, krb5_data *reply, const char *from, const char **e_text, - AuthorizationData *auth_data, + AuthorizationData **auth_data, const struct sockaddr *from_addr, int datagram_reply) { @@ -1262,6 +1362,7 @@ tgs_build_reply(krb5_context context, krb5_principal client_principal = NULL; char *spn = NULL, *cpn = NULL; hdb_entry_ex *server = NULL, *client = NULL; + krb5_realm ref_realm = NULL; EncTicketPart *tgt = &ticket->ticket; KRB5SignedPathPrincipals *spp = NULL; const EncryptionKey *ekey; @@ -1270,16 +1371,19 @@ tgs_build_reply(krb5_context context, krb5_data rspac; int cross_realm = 0; + METHOD_DATA enc_pa_data; + PrincipalName *s; Realm r; int nloop = 0; EncTicketPart adtkt; char opt_str[128]; - int require_signedpath = 0; + int signedpath = 0; memset(&sessionkey, 0, sizeof(sessionkey)); memset(&adtkt, 0, sizeof(adtkt)); krb5_data_zero(&rspac); + memset(&enc_pa_data, 0, sizeof(enc_pa_data)); s = b->sname; r = b->realm; @@ -1289,8 +1393,8 @@ tgs_build_reply(krb5_context context, hdb_entry_ex *uu; krb5_principal p; Key *uukey; - - if(b->additional_tickets == NULL || + + if(b->additional_tickets == NULL || b->additional_tickets->len == 0){ ret = KRB5KDC_ERR_BADOPTION; /* ? */ kdc_log(context, config, 0, @@ -1305,8 +1409,8 @@ tgs_build_reply(krb5_context context, goto out; } _krb5_principalname2krb5_principal(context, &p, t->sname, t->realm); - ret = _kdc_db_fetch(context, config, p, - HDB_F_GET_CLIENT|HDB_F_GET_SERVER, + ret = _kdc_db_fetch(context, config, p, + HDB_F_GET_CLIENT|HDB_F_GET_SERVER, NULL, &uu); krb5_free_principal(context, p); if(ret){ @@ -1314,7 +1418,7 @@ tgs_build_reply(krb5_context context, ret = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN; goto out; } - ret = hdb_enctype2key(context, &uu->entry, + ret = hdb_enctype2key(context, &uu->entry, t->enc_part.etype, &uukey); if(ret){ _kdc_free_ent(context, uu); @@ -1347,7 +1451,7 @@ tgs_build_reply(krb5_context context, opt_str, sizeof(opt_str)); if(*opt_str) kdc_log(context, config, 0, - "TGS-REQ %s from %s for %s [%s]", + "TGS-REQ %s from %s for %s [%s]", cpn, from, spn, opt_str); else kdc_log(context, config, 0, @@ -1370,20 +1474,23 @@ server_lookup: new_rlm = find_rpath(context, tgt->crealm, req_rlm); if(new_rlm) { kdc_log(context, config, 5, "krbtgt for realm %s " - "not found, trying %s", + "not found, trying %s", req_rlm, new_rlm); krb5_free_principal(context, sp); free(spn); - krb5_make_principal(context, &sp, r, + krb5_make_principal(context, &sp, r, KRB5_TGS_NAME, new_rlm, NULL); ret = krb5_unparse_name(context, sp, &spn); if (ret) goto out; - auth_data = NULL; /* ms don't handle AD in referals */ + + if (ref_realm) + free(ref_realm); + ref_realm = strdup(new_rlm); goto server_lookup; } } - } else if(need_referral(context, sp, &realms)) { + } else if(need_referral(context, config, &b->kdc_options, sp, &realms)) { if (strcmp(realms[0], sp->realm) != 0) { kdc_log(context, config, 5, "Returning a referral to realm %s for " @@ -1396,8 +1503,12 @@ server_lookup: ret = krb5_unparse_name(context, sp, &spn); if (ret) goto out; + + if (ref_realm) + free(ref_realm); + ref_realm = strdup(realms[0]); + krb5_free_host_realm(context, realms); - auth_data = NULL; /* ms don't handle AD in referals */ goto server_lookup; } krb5_free_host_realm(context, realms); @@ -1412,7 +1523,7 @@ server_lookup: ret = _kdc_db_fetch(context, config, cp, HDB_F_GET_CLIENT, NULL, &client); if(ret) { - const char *krbtgt_realm; + const char *krbtgt_realm; /* * If the client belongs to the same realm as our krbtgt, it @@ -1420,8 +1531,8 @@ server_lookup: * */ - krbtgt_realm = - krb5_principal_get_comp_string(context, + krbtgt_realm = + krb5_principal_get_comp_string(context, krbtgt->entry.principal, 1); if(strcmp(krb5_principal_get_realm(context, cp), krbtgt_realm) == 0) { @@ -1437,16 +1548,60 @@ server_lookup: cross_realm = 1; } - + + /* + * Select enctype, return key and kvno. + */ + + { + krb5_enctype etype; + + if(b->kdc_options.enc_tkt_in_skey) { + int i; + ekey = &adtkt.key; + for(i = 0; i < b->etype.len; i++) + if (b->etype.val[i] == adtkt.key.keytype) + break; + if(i == b->etype.len) { + kdc_log(context, config, 0, + "Addition ticket have not matching etypes", spp); + krb5_clear_error_string(context); + return KRB5KDC_ERR_ETYPE_NOSUPP; + } + etype = b->etype.val[i]; + kvno = 0; + } else { + Key *skey; + + ret = _kdc_find_etype(context, server, b->etype.val, b->etype.len, + &skey, &etype); + if(ret) { + kdc_log(context, config, 0, + "Server (%s) has no support for etypes", spn); + return ret; + } + ekey = &skey->key; + kvno = server->entry.kvno; + } + + ret = krb5_generate_random_keyblock(context, etype, &sessionkey); + if (ret) + goto out; + } + + /* + * Validate authoriation data + */ + /* * Check that service is in the same realm as the krbtgt. If it's * not the same, it's someone that is using a uni-directional trust * backward. */ - + if (strcmp(krb5_principal_get_realm(context, sp), - krb5_principal_get_comp_string(context, - krbtgt->entry.principal, + krb5_principal_get_comp_string(context, + krbtgt->entry.principal, 1)) != 0) { char *tpn; ret = krb5_unparse_name(context, krbtgt->entry.principal, &tpn); @@ -1459,8 +1614,45 @@ server_lookup: goto out; } + /* check PAC if not cross realm and if there is one */ + if (!cross_realm) { + Key *tkey; + + ret = hdb_enctype2key(context, &krbtgt->entry, + krbtgt_etype, &tkey); + if(ret) { + kdc_log(context, config, 0, + "Failed to find key for krbtgt PAC check"); + goto out; + } + + ret = check_PAC(context, config, cp, + client, server, ekey, &tkey->key, + tgt, &rspac, &signedpath); + if (ret) { + kdc_log(context, config, 0, + "Verify PAC failed for %s (%s) from %s with %s", + spn, cpn, from, krb5_get_err_text(context, ret)); + goto out; + } + } + + /* also check the krbtgt for signature */ + ret = check_KRB5SignedPath(context, + config, + krbtgt, + tgt, + &spp, + &signedpath); + if (ret) { + kdc_log(context, config, 0, + "KRB5SignedPath check failed for %s (%s) from %s with %s", + spn, cpn, from, krb5_get_err_text(context, ret)); + goto out; + } + /* - * + * Process request */ client_principal = cp; @@ -1477,7 +1669,7 @@ server_lookup: char *selfcpn = NULL; const char *str; - ret = decode_PA_S4U2Self(sdata->padata_value.data, + ret = decode_PA_S4U2Self(sdata->padata_value.data, sdata->padata_value.length, &self, NULL); if (ret) { @@ -1501,14 +1693,14 @@ server_lookup: ret = krb5_verify_checksum(context, crypto, KRB5_KU_OTHER_CKSUM, - datack.data, - datack.length, + datack.data, + datack.length, &self.cksum); krb5_data_free(&datack); krb5_crypto_destroy(context, crypto); if (ret) { free_PA_S4U2Self(&self); - kdc_log(context, config, 0, + kdc_log(context, config, 0, "krb5_verify_checksum failed for S4U2Self: %s", krb5_get_err_text(context, ret)); goto out; @@ -1566,13 +1758,26 @@ server_lookup: && b->additional_tickets->len != 0 && b->kdc_options.enc_tkt_in_skey == 0) { + int ad_signedpath = 0; Key *clientkey; Ticket *t; char *str; + /* + * Require that the KDC have issued the service's krbtgt (not + * self-issued ticket with kimpersonate(1). + */ + if (!signedpath) { + ret = KRB5KDC_ERR_BADOPTION; + kdc_log(context, config, 0, + "Constrained delegation done on service ticket %s/%s", + cpn, spn); + goto out; + } + t = &b->additional_tickets->val[0]; - ret = hdb_enctype2key(context, &client->entry, + ret = hdb_enctype2key(context, &client->entry, t->enc_part.etype, &clientkey); if(ret){ ret = KRB5KDC_ERR_ETYPE_NOSUPP; /* XXX */ @@ -1588,19 +1793,18 @@ server_lookup: } /* check that ticket is valid */ - if (adtkt.flags.forwardable == 0) { kdc_log(context, config, 0, "Missing forwardable flag on ticket for " "constrained delegation from %s to %s ", spn, cpn); - ret = KRB5KDC_ERR_ETYPE_NOSUPP; /* XXX */ + ret = KRB5KDC_ERR_BADOPTION; goto out; } ret = check_constrained_delegation(context, config, client, sp); if (ret) { kdc_log(context, config, 0, - "constrained delegation from %s to %s not allowed", + "constrained delegation from %s to %s not allowed", spn, cpn); goto out; } @@ -1623,16 +1827,16 @@ server_lookup: } /* - * Check KRB5SignedPath in authorization data and add new entry to - * make sure servers can't fake a ticket to us. + * Check that the KDC issued the user's ticket. */ - ret = check_KRB5SignedPath(context, config, krbtgt, &adtkt, - &spp, - 1); + NULL, + &ad_signedpath); + if (ret == 0 && !ad_signedpath) + ret = KRB5KDC_ERR_BADOPTION; if (ret) { kdc_log(context, config, 0, "KRB5SignedPath check from service %s failed " @@ -1646,27 +1850,21 @@ server_lookup: kdc_log(context, config, 0, "constrained delegation for %s " "from %s to %s", str, cpn, spn); free(str); - - /* - * Also require that the KDC have issue the service's krbtgt - * used to do the request. - */ - require_signedpath = 1; } /* * Check flags */ - ret = _kdc_check_flags(context, config, + ret = _kdc_check_flags(context, config, client, cpn, server, spn, FALSE); if(ret) goto out; - if((b->kdc_options.validate || b->kdc_options.renew) && - !krb5_principal_compare(context, + if((b->kdc_options.validate || b->kdc_options.renew) && + !krb5_principal_compare(context, krbtgt->entry.principal, server->entry.principal)){ kdc_log(context, config, 0, "Inconsistent request."); @@ -1682,108 +1880,68 @@ server_lookup: } /* - * Select enctype, return key and kvno. + * If this is an referral, add server referral data to the + * auth_data reply . */ + if (ref_realm) { + PA_DATA pa; + krb5_crypto crypto; - { - krb5_enctype etype; + kdc_log(context, config, 0, + "Adding server referral to %s", ref_realm); - if(b->kdc_options.enc_tkt_in_skey) { - int i; - ekey = &adtkt.key; - for(i = 0; i < b->etype.len; i++) - if (b->etype.val[i] == adtkt.key.keytype) - break; - if(i == b->etype.len) { - krb5_clear_error_string(context); - return KRB5KDC_ERR_ETYPE_NOSUPP; - } - etype = b->etype.val[i]; - kvno = 0; - } else { - Key *skey; - - ret = _kdc_find_etype(context, server, b->etype.val, b->etype.len, - &skey, &etype); - if(ret) { - kdc_log(context, config, 0, - "Server (%s) has no support for etypes", spp); - return ret; - } - ekey = &skey->key; - kvno = server->entry.kvno; - } - - ret = krb5_generate_random_keyblock(context, etype, &sessionkey); + ret = krb5_crypto_init(context, &sessionkey, 0, &crypto); if (ret) goto out; - } - - /* check PAC if not cross realm and if there is one */ - if (!cross_realm) { - Key *tkey; - ret = hdb_enctype2key(context, &krbtgt->entry, - krbtgt_etype, &tkey); - if(ret) { + ret = build_server_referral(context, config, crypto, ref_realm, + NULL, s, &pa.padata_value); + krb5_crypto_destroy(context, crypto); + if (ret) { kdc_log(context, config, 0, - "Failed to find key for krbtgt PAC check"); + "Failed building server referral"); goto out; } + pa.padata_type = KRB5_PADATA_SERVER_REFERRAL; - ret = check_PAC(context, config, client_principal, - client, server, ekey, &tkey->key, - tgt, &rspac, &require_signedpath); + ret = add_METHOD_DATA(&enc_pa_data, &pa); + krb5_data_free(&pa.padata_value); if (ret) { kdc_log(context, config, 0, - "Verify PAC failed for %s (%s) from %s with %s", - spn, cpn, from, krb5_get_err_text(context, ret)); + "Add server referral METHOD-DATA failed"); goto out; } } - /* also check the krbtgt for signature */ - ret = check_KRB5SignedPath(context, - config, - krbtgt, - tgt, - &spp, - require_signedpath); - if (ret) { - kdc_log(context, config, 0, - "KRB5SignedPath check failed for %s (%s) from %s with %s", - spn, cpn, from, krb5_get_err_text(context, ret)); - goto out; - } - /* * */ ret = tgs_make_reply(context, - config, - b, + config, + b, client_principal, - tgt, + tgt, ekey, &sessionkey, kvno, - auth_data, - server, + *auth_data, + server, spn, - client, - cp, - krbtgt, + client, + cp, + krbtgt, krbtgt_etype, spp, &rspac, + &enc_pa_data, e_text, reply); out: free(spn); free(cpn); - + krb5_data_free(&rspac); krb5_free_keyblock_contents(context, &sessionkey); if(server) @@ -1797,6 +1955,9 @@ out: krb5_free_principal(context, cp); if (sp) krb5_free_principal(context, sp); + if (ref_realm) + free(ref_realm); + free_METHOD_DATA(&enc_pa_data); free_EncTicketPart(&adtkt); @@ -1808,9 +1969,9 @@ out: */ krb5_error_code -_kdc_tgs_rep(krb5_context context, +_kdc_tgs_rep(krb5_context context, krb5_kdc_configuration *config, - KDC_REQ *req, + KDC_REQ *req, krb5_data *data, const char *from, struct sockaddr *from_addr, @@ -1835,17 +1996,17 @@ _kdc_tgs_rep(krb5_context context, "TGS-REQ from %s without PA-DATA", from); goto out; } - + tgs_req = _kdc_find_padata(req, &i, KRB5_PADATA_TGS_REQ); if(tgs_req == NULL){ ret = KRB5KDC_ERR_PADATA_TYPE_NOSUPP; - kdc_log(context, config, 0, + kdc_log(context, config, 0, "TGS-REQ from %s without PA-TGS-REQ", from); goto out; } - ret = tgs_parse_request(context, config, + ret = tgs_parse_request(context, config, &req->req_body, tgs_req, &krbtgt, &krbtgt_etype, @@ -1855,7 +2016,7 @@ _kdc_tgs_rep(krb5_context context, &csec, &cusec, &auth_data); if (ret) { - kdc_log(context, config, 0, + kdc_log(context, config, 0, "Failed parsing TGS-REQ from %s", from); goto out; } @@ -1870,11 +2031,11 @@ _kdc_tgs_rep(krb5_context context, data, from, &e_text, - auth_data, + &auth_data, from_addr, datagram_reply); if (ret) { - kdc_log(context, config, 0, + kdc_log(context, config, 0, "Failed building TGS-REP to %s", from); goto out; } diff --git a/source4/heimdal/kdc/kx509.c b/source4/heimdal/kdc/kx509.c index b1b861efef..8f117cebc0 100644 --- a/source4/heimdal/kdc/kx509.c +++ b/source4/heimdal/kdc/kx509.c @@ -36,7 +36,7 @@ #include <rfc2459_asn1.h> #include <hx509.h> -RCSID("$Id: kx509.c 21607 2007-07-17 07:04:52Z lha $"); +RCSID("$Id: kx509.c 23316 2008-06-23 04:32:32Z lha $"); /* * @@ -67,8 +67,9 @@ verify_req_hash(krb5_context context, HMAC_CTX ctx; if (req->pk_hash.length != sizeof(digest)) { - krb5_set_error_string(context, "pk-hash have wrong length: %lu", - (unsigned long)req->pk_hash.length); + krb5_set_error_message(context, KRB5KDC_ERR_PREAUTH_FAILED, + "pk-hash have wrong length: %lu", + (unsigned long)req->pk_hash.length); return KRB5KDC_ERR_PREAUTH_FAILED; } @@ -84,7 +85,8 @@ verify_req_hash(krb5_context context, HMAC_CTX_cleanup(&ctx); if (memcmp(req->pk_hash.data, digest, sizeof(digest)) != 0) { - krb5_set_error_string(context, "pk-hash is not correct"); + krb5_set_error_message(context, KRB5KDC_ERR_PREAUTH_FAILED, + "pk-hash is not correct"); return KRB5KDC_ERR_PREAUTH_FAILED; } return 0; @@ -106,7 +108,7 @@ calculate_reply_hash(krb5_context context, rep->hash->data = malloc(rep->hash->length); if (rep->hash->data == NULL) { HMAC_CTX_cleanup(&ctx); - krb5_set_error_string(context, "out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } @@ -157,12 +159,8 @@ build_certificate(krb5_context context, ret = hx509_context_init(&hxctx); if (ret) goto out; - - ret = hx509_env_init(hxctx, &env); - if (ret) - goto out; - - ret = hx509_env_add(hxctx, env, "principal-name", + + ret = hx509_env_add(hxctx, &env, "principal-name", krb5_principal_get_comp_string(context, principal, 0)); if (ret) goto out; @@ -280,7 +278,7 @@ out: hx509_cert_free(signer); if (hxctx) hx509_context_free(&hxctx); - krb5_set_error_string(context, "cert creation failed"); + krb5_set_error_message(context, ret, "cert creation failed"); return ret; } @@ -358,16 +356,18 @@ _kdc_do_kx509(krb5_context context, krb5_free_principal(context, principal); if (ret != TRUE) { ret = KRB5KDC_ERR_SERVER_NOMATCH; - krb5_set_error_string(context, - "User %s used wrong Kx509 service principal", - cname); + krb5_set_error_message(context, ret, + "User %s used wrong Kx509 service principal", + cname); goto out; } } ret = krb5_auth_con_getkey(context, ac, &key); - if (ret || key == NULL) { - krb5_set_error_string(context, "Kx509 can't get session key"); + if (ret == 0 && key == NULL) + ret = KRB5KDC_ERR_NULL_KEY; + if (ret) { + krb5_set_error_message(context, ret, "Kx509 can't get session key"); goto out; } @@ -418,7 +418,7 @@ _kdc_do_kx509(krb5_context context, ASN1_MALLOC_ENCODE(Kx509Response, data.data, data.length, &rep, &size, ret); if (ret) { - krb5_set_error_string(context, "Failed to encode kx509 reply"); + krb5_set_error_message(context, ret, "Failed to encode kx509 reply"); goto out; } if (size != data.length) diff --git a/source4/heimdal/kdc/misc.c b/source4/heimdal/kdc/misc.c index 072df44042..528b9e6a3b 100644 --- a/source4/heimdal/kdc/misc.c +++ b/source4/heimdal/kdc/misc.c @@ -33,7 +33,7 @@ #include "kdc_locl.h" -RCSID("$Id: misc.c 21106 2007-06-18 10:18:11Z lha $"); +RCSID("$Id: misc.c 23316 2008-06-23 04:32:32Z lha $"); struct timeval _kdc_now; @@ -51,7 +51,7 @@ _kdc_db_fetch(krb5_context context, ent = calloc (1, sizeof (*ent)); if (ent == NULL) { - krb5_set_error_string(context, "out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } @@ -76,8 +76,8 @@ _kdc_db_fetch(krb5_context context, } } free(ent); - krb5_set_error_string(context, "no such entry found in hdb"); - return HDB_ERR_NOENTRY; + krb5_set_error_message(context, HDB_ERR_NOENTRY, "no such entry found in hdb"); + return HDB_ERR_NOENTRY; } void @@ -116,7 +116,8 @@ _kdc_get_preferred_key(krb5_context context, } } - krb5_set_error_string(context, "No valid kerberos key found for %s", name); + krb5_set_error_message(context, EINVAL, + "No valid kerberos key found for %s", name); return EINVAL; } diff --git a/source4/heimdal/kdc/pkinit.c b/source4/heimdal/kdc/pkinit.c index bf248af588..9f6d57f588 100755 --- a/source4/heimdal/kdc/pkinit.c +++ b/source4/heimdal/kdc/pkinit.c @@ -33,7 +33,7 @@ #include "kdc_locl.h" -RCSID("$Id: pkinit.c 22243 2007-12-08 23:39:30Z lha $"); +RCSID("$Id: pkinit.c 23316 2008-06-23 04:32:32Z lha $"); #ifdef PKINIT @@ -45,23 +45,8 @@ RCSID("$Id: pkinit.c 22243 2007-12-08 23:39:30Z lha $"); #include <hx509.h> #include "crypto-headers.h" -/* XXX copied from lib/krb5/pkinit.c */ -struct krb5_pk_identity { - hx509_context hx509ctx; - hx509_verify_ctx verify_ctx; - hx509_certs certs; - hx509_certs anchors; - hx509_certs certpool; - hx509_revoke_ctx revoke; -}; - -enum pkinit_type { - PKINIT_COMPAT_WIN2K = 1, - PKINIT_COMPAT_27 = 3 -}; - struct pk_client_params { - enum pkinit_type type; + enum krb5_pk_type type; BIGNUM *dh_public_key; hx509_cert cert; unsigned nonce; @@ -202,13 +187,13 @@ generate_dh_keyblock(krb5_context context, pk_client_params *client_params, memset(&key, 0, sizeof(key)); if (!DH_generate_key(client_params->dh)) { - krb5_set_error_string(context, "Can't generate Diffie-Hellman keys"); ret = KRB5KRB_ERR_GENERIC; + krb5_set_error_message(context, ret, "Can't generate Diffie-Hellman keys"); goto out; } if (client_params->dh_public_key == NULL) { - krb5_set_error_string(context, "dh_public_key"); ret = KRB5KRB_ERR_GENERIC; + krb5_set_error_message(context, ret, "dh_public_key"); goto out; } @@ -219,8 +204,8 @@ generate_dh_keyblock(krb5_context context, pk_client_params *client_params, dh_gen_key = malloc(size); if (dh_gen_key == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); ret = ENOMEM; + krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } memset(dh_gen_key, 0, size - dh_gen_keylen); @@ -229,8 +214,8 @@ generate_dh_keyblock(krb5_context context, pk_client_params *client_params, client_params->dh_public_key, client_params->dh); if (dh_gen_keylen == -1) { - krb5_set_error_string(context, "Can't compute Diffie-Hellman key"); ret = KRB5KRB_ERR_GENERIC; + krb5_set_error_message(context, ret, "Can't compute Diffie-Hellman key"); goto out; } @@ -256,7 +241,8 @@ integer_to_BN(krb5_context context, const char *field, heim_integer *f) bn = BN_bin2bn((const unsigned char *)f->data, f->length, NULL); if (bn == NULL) { - krb5_set_error_string(context, "PKINIT: parsing BN failed %s", field); + krb5_set_error_message(context, KRB5_BADMSGTYPE, + "PKINIT: parsing BN failed %s", field); return NULL; } BN_set_negative(bn, f->negative); @@ -276,13 +262,14 @@ get_dh_param(krb5_context context, memset(&dhparam, 0, sizeof(dhparam)); if (der_heim_oid_cmp(&dh_key_info->algorithm.algorithm, oid_id_dhpublicnumber())) { - krb5_set_error_string(context, - "PKINIT invalid oid in clientPublicValue"); + krb5_set_error_message(context, KRB5_BADMSGTYPE, + "PKINIT invalid oid in clientPublicValue"); return KRB5_BADMSGTYPE; } if (dh_key_info->algorithm.parameters == NULL) { - krb5_set_error_string(context, "PKINIT missing algorithm parameter " + krb5_set_error_message(context, KRB5_BADMSGTYPE, + "PKINIT missing algorithm parameter " "in clientPublicValue"); return KRB5_BADMSGTYPE; } @@ -292,15 +279,16 @@ get_dh_param(krb5_context context, &dhparam, NULL); if (ret) { - krb5_set_error_string(context, "Can't decode algorithm " - "parameters in clientPublicValue"); + krb5_set_error_message(context, ret, "Can't decode algorithm " + "parameters in clientPublicValue"); goto out; } if ((dh_key_info->subjectPublicKey.length % 8) != 0) { ret = KRB5_BADMSGTYPE; - krb5_set_error_string(context, "PKINIT: subjectPublicKey not aligned " - "to 8 bit boundary"); + krb5_set_error_message(context, ret, + "PKINIT: subjectPublicKey not aligned " + "to 8 bit boundary"); goto out; } @@ -315,8 +303,8 @@ get_dh_param(krb5_context context, dh = DH_new(); if (dh == NULL) { - krb5_set_error_string(context, "Cannot create DH structure"); ret = ENOMEM; + krb5_set_error_message(context, ret, "Cannot create DH structure"); goto out; } ret = KRB5_BADMSGTYPE; @@ -347,8 +335,10 @@ get_dh_param(krb5_context context, "subjectPublicKey", &glue); der_free_heim_integer(&glue); - if (client_params->dh_public_key == NULL) + if (client_params->dh_public_key == NULL) { + ret = KRB5_BADMSGTYPE; goto out; + } } client_params->dh = dh; @@ -385,7 +375,7 @@ _kdc_pk_rd_padata(krb5_context context, return 0; } - hx509_verify_set_time(kdc_identity->verify_ctx, _kdc_now.tv_sec); + hx509_verify_set_time(kdc_identity->verify_ctx, kdc_time); client_params = calloc(1, sizeof(*client_params)); if (client_params == NULL) { @@ -404,8 +394,8 @@ _kdc_pk_rd_padata(krb5_context context, &r, NULL); if (ret) { - krb5_set_error_string(context, "Can't decode " - "PK-AS-REQ-Win2k: %d", ret); + krb5_set_error_message(context, ret, "Can't decode " + "PK-AS-REQ-Win2k: %d", ret); goto out; } @@ -415,7 +405,8 @@ _kdc_pk_rd_padata(krb5_context context, &have_data); free_PA_PK_AS_REQ_Win2k(&r); if (ret) { - krb5_set_error_string(context, "Can't decode PK-AS-REQ: %d", ret); + krb5_set_error_message(context, ret, + "Can't decode PK-AS-REQ: %d", ret); goto out; } @@ -429,7 +420,7 @@ _kdc_pk_rd_padata(krb5_context context, &r, NULL); if (ret) { - krb5_set_error_string(context, "Can't decode PK-AS-REQ: %d", ret); + krb5_set_error_message(context, ret, "Can't decode PK-AS-REQ: %d", ret); goto out; } @@ -443,7 +434,7 @@ _kdc_pk_rd_padata(krb5_context context, 0, NULL, &client_params->client_anchors); if (ret) { - krb5_set_error_string(context, "Can't allocate client anchors: %d", ret); + krb5_set_error_message(context, ret, "Can't allocate client anchors: %d", ret); goto out; } @@ -458,7 +449,7 @@ _kdc_pk_rd_padata(krb5_context context, ret = hx509_query_alloc(kdc_identity->hx509ctx, &q); if (ret) { - krb5_set_error_string(context, + krb5_set_error_message(context, ret, "Failed to allocate hx509_query"); goto out; } @@ -495,7 +486,8 @@ _kdc_pk_rd_padata(krb5_context context, &have_data); free_PA_PK_AS_REQ(&r); if (ret) { - krb5_set_error_string(context, "Can't unwrap ContentInfo: %d", ret); + krb5_set_error_message(context, ret, + "Can't unwrap ContentInfo: %d", ret); goto out; } @@ -507,16 +499,16 @@ _kdc_pk_rd_padata(krb5_context context, ret = der_heim_oid_cmp(&contentInfoOid, oid_id_pkcs7_signedData()); if (ret != 0) { - krb5_set_error_string(context, "PK-AS-REQ-Win2k invalid content " - "type oid"); ret = KRB5KRB_ERR_GENERIC; + krb5_set_error_message(context, ret, + "PK-AS-REQ-Win2k invalid content type oid"); goto out; } if (!have_data) { - krb5_set_error_string(context, - "PK-AS-REQ-Win2k no signed auth pack"); ret = KRB5KRB_ERR_GENERIC; + krb5_set_error_message(context, ret, + "PK-AS-REQ-Win2k no signed auth pack"); goto out; } @@ -551,8 +543,8 @@ _kdc_pk_rd_padata(krb5_context context, if (der_heim_oid_cmp(&eContentType, oid_id_pkcs7_data()) != 0 && der_heim_oid_cmp(&eContentType, oid_id_pkauthdata()) != 0) { - krb5_set_error_string(context, "got wrong oid for pkauthdata"); ret = KRB5_BADMSGTYPE; + krb5_set_error_message(context, ret, "got wrong oid for pkauthdata"); goto out; } @@ -564,7 +556,7 @@ _kdc_pk_rd_padata(krb5_context context, &ap, NULL); if (ret) { - krb5_set_error_string(context, "can't decode AuthPack: %d", ret); + krb5_set_error_message(context, ret, "can't decode AuthPack: %d", ret); goto out; } @@ -576,12 +568,12 @@ _kdc_pk_rd_padata(krb5_context context, goto out; } - client_params->type = PKINIT_COMPAT_WIN2K; + client_params->type = PKINIT_WIN2K; client_params->nonce = ap.pkAuthenticator.nonce; if (ap.clientPublicValue) { - krb5_set_error_string(context, "DH not supported for windows"); ret = KRB5KRB_ERR_GENERIC; + krb5_set_error_message(context, ret, "DH not supported for windows"); goto out; } free_AuthPack_Win2k(&ap); @@ -594,7 +586,7 @@ _kdc_pk_rd_padata(krb5_context context, &ap, NULL); if (ret) { - krb5_set_error_string(context, "can't decode AuthPack: %d", ret); + krb5_set_error_message(context, ret, "can't decode AuthPack: %d", ret); free_AuthPack(&ap); goto out; } @@ -607,7 +599,7 @@ _kdc_pk_rd_padata(krb5_context context, goto out; } - client_params->type = PKINIT_COMPAT_27; + client_params->type = PKINIT_27; client_params->nonce = ap.pkAuthenticator.nonce; if (ap.clientPublicValue) { @@ -700,7 +692,7 @@ pk_mk_pa_reply_enckey(krb5_context context, */ switch (client_params->type) { - case PKINIT_COMPAT_WIN2K: { + case PKINIT_WIN2K: { int i = 0; if (_kdc_find_padata(req, &i, KRB5_PADATA_PK_AS_09_BINDING) == NULL && config->pkinit_require_binding == 0) @@ -709,7 +701,7 @@ pk_mk_pa_reply_enckey(krb5_context context, } break; } - case PKINIT_COMPAT_27: + case PKINIT_27: break; default: krb5_abortx(context, "internal pkinit error"); @@ -769,8 +761,8 @@ pk_mk_pa_reply_enckey(krb5_context context, free_ReplyKeyPack(&kp); } if (ret) { - krb5_set_error_string(context, "ASN.1 encoding of ReplyKeyPack " - "failed (%d)", ret); + krb5_set_error_message(context, ret, "ASN.1 encoding of ReplyKeyPack " + "failed (%d)", ret); goto out; } if (buf.length != size) @@ -813,7 +805,7 @@ pk_mk_pa_reply_enckey(krb5_context context, if (ret) goto out; - if (client_params->type == PKINIT_COMPAT_WIN2K) { + if (client_params->type == PKINIT_WIN2K) { ret = hx509_cms_wrap_ContentInfo(oid_id_pkcs7_signedData(), &signed_data, &buf); @@ -874,9 +866,8 @@ pk_mk_pa_reply_dh(krb5_context context, ASN1_MALLOC_ENCODE(DHPublicKey, buf.data, buf.length, &i, &size, ret); if (ret) { - krb5_set_error_string(context, "ASN.1 encoding of " - "DHPublicKey failed (%d)", ret); - krb5_clear_error_string(context); + krb5_set_error_message(context, ret, "ASN.1 encoding of " + "DHPublicKey failed (%d)", ret); return ret; } if (buf.length != size) @@ -890,8 +881,8 @@ pk_mk_pa_reply_dh(krb5_context context, ASN1_MALLOC_ENCODE(KDCDHKeyInfo, buf.data, buf.length, &dh_info, &size, ret); if (ret) { - krb5_set_error_string(context, "ASN.1 encoding of " - "KdcDHKeyInfo failed (%d)", ret); + krb5_set_error_message(context, ret, "ASN.1 encoding of " + "KdcDHKeyInfo failed (%d)", ret); goto out; } if (buf.length != size) @@ -990,15 +981,15 @@ _kdc_pk_mk_pa_reply(krb5_context context, break; if (req->req_body.etype.len <= i) { ret = KRB5KRB_ERR_GENERIC; - krb5_set_error_string(context, - "No valid enctype available from client"); + krb5_set_error_message(context, ret, + "No valid enctype available from client"); goto out; } enctype = req->req_body.etype.val[i]; } else enctype = ETYPE_DES3_CBC_SHA1; - if (client_params->type == PKINIT_COMPAT_27) { + if (client_params->type == PKINIT_27) { PA_PK_AS_REP rep; const char *type, *other = ""; @@ -1035,8 +1026,8 @@ _kdc_pk_mk_pa_reply(krb5_context context, ret); free_ContentInfo(&info); if (ret) { - krb5_set_error_string(context, "encoding of Key ContentInfo " - "failed %d", ret); + krb5_set_error_message(context, ret, "encoding of Key ContentInfo " + "failed %d", ret); free_PA_PK_AS_REP(&rep); goto out; } @@ -1068,8 +1059,8 @@ _kdc_pk_mk_pa_reply(krb5_context context, ret); free_ContentInfo(&info); if (ret) { - krb5_set_error_string(context, "encoding of Key ContentInfo " - "failed %d", ret); + krb5_set_error_message(context, ret, "encoding of Key ContentInfo " + "failed %d", ret); free_PA_PK_AS_REP(&rep); goto out; } @@ -1085,8 +1076,8 @@ _kdc_pk_mk_pa_reply(krb5_context context, ASN1_MALLOC_ENCODE(PA_PK_AS_REP, buf, len, &rep, &size, ret); free_PA_PK_AS_REP(&rep); if (ret) { - krb5_set_error_string(context, "encode PA-PK-AS-REP failed %d", - ret); + krb5_set_error_message(context, ret, "encode PA-PK-AS-REP failed %d", + ret); goto out; } if (len != size) @@ -1094,13 +1085,13 @@ _kdc_pk_mk_pa_reply(krb5_context context, kdc_log(context, config, 0, "PK-INIT using %s %s", type, other); - } else if (client_params->type == PKINIT_COMPAT_WIN2K) { + } else if (client_params->type == PKINIT_WIN2K) { PA_PK_AS_REP_Win2k rep; ContentInfo info; if (client_params->dh) { - krb5_set_error_string(context, "Windows PK-INIT doesn't support DH"); ret = KRB5KRB_ERR_GENERIC; + krb5_set_error_message(context, ret, "Windows PK-INIT doesn't support DH"); goto out; } @@ -1131,7 +1122,7 @@ _kdc_pk_mk_pa_reply(krb5_context context, ret); free_ContentInfo(&info); if (ret) { - krb5_set_error_string(context, "encoding of Key ContentInfo " + krb5_set_error_message(context, ret, "encoding of Key ContentInfo " "failed %d", ret); free_PA_PK_AS_REP_Win2k(&rep); goto out; @@ -1142,7 +1133,7 @@ _kdc_pk_mk_pa_reply(krb5_context context, ASN1_MALLOC_ENCODE(PA_PK_AS_REP_Win2k, buf, len, &rep, &size, ret); free_PA_PK_AS_REP_Win2k(&rep); if (ret) { - krb5_set_error_string(context, + krb5_set_error_message(context, ret, "encode PA-PK-AS-REP-Win2k failed %d", ret); goto out; } @@ -1155,7 +1146,7 @@ _kdc_pk_mk_pa_reply(krb5_context context, ret = krb5_padata_add(context, md, pa_type, buf, len); if (ret) { - krb5_set_error_string(context, "failed adding PA-PK-AS-REP %d", ret); + krb5_set_error_message(context, ret, "failed adding PA-PK-AS-REP %d", ret); free(buf); goto out; } @@ -1229,8 +1220,8 @@ _kdc_pk_mk_pa_reply(krb5_context context, KRB5_PADATA_PA_PK_OCSP_RESPONSE, ocsp.data.data, ocsp.data.length); if (ret) { - krb5_set_error_string(context, - "Failed adding OCSP response %d", ret); + krb5_set_error_message(context, ret, + "Failed adding OCSP response %d", ret); goto out; } } @@ -1453,7 +1444,8 @@ _kdc_pk_check_client(krb5_context context, return 0; } - krb5_set_error_string(context, + ret = KRB5_KDC_ERR_CLIENT_NAME_MISMATCH; + krb5_set_error_message(context, ret, "PKINIT no matching principals for %s", *subject_name); @@ -1464,7 +1456,7 @@ _kdc_pk_check_client(krb5_context context, free(*subject_name); *subject_name = NULL; - return KRB5_KDC_ERR_CLIENT_NAME_MISMATCH; + return ret; } static krb5_error_code diff --git a/source4/heimdal/kdc/process.c b/source4/heimdal/kdc/process.c index 1d0a01a215..550bfb04b2 100644 --- a/source4/heimdal/kdc/process.c +++ b/source4/heimdal/kdc/process.c @@ -34,7 +34,7 @@ #include "kdc_locl.h" -RCSID("$Id: process.c 20959 2007-06-07 04:46:06Z lha $"); +RCSID("$Id: process.c 23316 2008-06-23 04:32:32Z lha $"); /* * @@ -177,14 +177,15 @@ krb5_kdc_save_request(krb5_context context, fd = open(fn, O_WRONLY|O_CREAT|O_APPEND, 0600); if (fd < 0) { - krb5_set_error_string(context, "Failed to open: %s", fn); - return errno; + int saved_errno = errno; + krb5_set_error_message(context, saved_errno, "Failed to open: %s", fn); + return saved_errno; } sp = krb5_storage_from_fd(fd); close(fd); if (sp == NULL) { - krb5_set_error_string(context, "Storage failed to open fd"); + krb5_set_error_message(context, ENOMEM, "Storage failed to open fd"); return ENOMEM; } diff --git a/source4/heimdal/kdc/windc.c b/source4/heimdal/kdc/windc.c index 85e4d7f725..621757f6dc 100644 --- a/source4/heimdal/kdc/windc.c +++ b/source4/heimdal/kdc/windc.c @@ -33,7 +33,7 @@ #include "kdc_locl.h" -RCSID("$Id: windc.c 20559 2007-04-24 16:00:07Z lha $"); +RCSID("$Id: windc.c 23316 2008-06-23 04:32:32Z lha $"); static krb5plugin_windc_ftable *windcft; static void *windcctx; @@ -63,7 +63,7 @@ krb5_kdc_windc_init(krb5_context context) } if (e == NULL) { _krb5_plugin_free(list); - krb5_set_error_string(context, "Did not find any WINDC plugin"); + krb5_set_error_message(context, ENOENT, "Did not find any WINDC plugin"); windcft = NULL; return ENOENT; } @@ -91,7 +91,7 @@ _kdc_pac_verify(krb5_context context, krb5_pac *pac) { if (windcft == NULL) { - krb5_set_error_string(context, "Can't verify PAC, no function"); + krb5_set_error_message(context, EINVAL, "Can't verify PAC, no function"); return EINVAL; } return (windcft->pac_verify)(windcctx, context, diff --git a/source4/heimdal/kdc/windc_plugin.h b/source4/heimdal/kdc/windc_plugin.h index 3ae0c94681..44aab9e22b 100644 --- a/source4/heimdal/kdc/windc_plugin.h +++ b/source4/heimdal/kdc/windc_plugin.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: windc_plugin.h 19798 2007-01-10 15:24:51Z lha $ */ +/* $Id: windc_plugin.h 22693 2008-03-19 08:57:49Z lha $ */ #ifndef HEIMDAL_KRB5_PAC_PLUGIN_H #define HEIMDAL_KRB5_PAC_PLUGIN_H 1 @@ -67,7 +67,7 @@ typedef krb5_error_code void *, krb5_context, struct hdb_entry_ex *, KDC_REQ *, krb5_data *); -#define KRB5_WINDC_PLUGING_MINOR 2 +#define KRB5_WINDC_PLUGING_MINOR 3 typedef struct krb5plugin_windc_ftable { int minor_version; diff --git a/source4/heimdal/kuser/kinit.c b/source4/heimdal/kuser/kinit.c index 2676309859..0e03dc4d37 100644 --- a/source4/heimdal/kuser/kinit.c +++ b/source4/heimdal/kuser/kinit.c @@ -32,7 +32,7 @@ */ #include "kuser_locl.h" -RCSID("$Id: kinit.c 22116 2007-12-03 21:22:58Z lha $"); +RCSID("$Id: kinit.c 23418 2008-07-26 18:36:48Z lha $"); #include "krb5-v4compat.h" @@ -66,6 +66,8 @@ char *pk_user_id = NULL; char *pk_x509_anchors = NULL; int pk_use_enckey = 0; static int canonicalize_flag = 0; +static int ok_as_delegate_flag = 0; +static int windows_flag = 0; static char *ntlm_domain; static char *krb4_cc_name; @@ -161,6 +163,12 @@ static struct getargs args[] = { { "ntlm-domain", 0, arg_string, &ntlm_domain, "NTLM domain", "domain" }, + { "ok-as-delegate", 0, arg_flag, &ok_as_delegate_flag, + "honor ok-as-delegate on tickets" }, + + { "windows", 0, arg_flag, &windows_flag, + "get windows behavior" }, + { "version", 0, arg_flag, &version_flag }, { "help", 0, arg_flag, &help_flag } }; @@ -329,36 +337,25 @@ out: } static krb5_error_code -store_ntlmkey(krb5_context context, krb5_ccache id, - const char *domain, krb5_const_principal client, - struct ntlm_buf *buf) +store_ntlmkey(krb5_context context, krb5_ccache id, + const char *domain, struct ntlm_buf *buf) { krb5_error_code ret; - krb5_creds cred; - - memset(&cred, 0, sizeof(cred)); + krb5_data data; + char *name; - ret = krb5_make_principal(context, &cred.server, - krb5_principal_get_realm(context, client), - "@ntlm-key", domain, NULL); - if (ret) - goto out; - ret = krb5_copy_principal(context, client, &cred.client); - if (ret) - goto out; + asprintf(&name, "ntlm-key-%s", domain); + if (name == NULL) { + krb5_clear_error_string(context); + return ENOMEM; + } - cred.times.authtime = time(NULL); - cred.times.endtime = time(NULL) + 3600 * 24 * 30; /* XXX */ - cred.session.keytype = ENCTYPE_ARCFOUR_HMAC_MD5; - ret = krb5_data_copy(&cred.session.keyvalue, buf->data, buf->length); - if (ret) - goto out; - - ret = krb5_cc_store_cred(context, id, &cred); + data.length = buf->length; + data.data = buf->data; -out: - krb5_free_cred_contents (context, &cred); - return 0; + ret = krb5_cc_set_config(context, id, NULL, name, &data); + free(name); + return ret; } static krb5_error_code @@ -598,7 +595,17 @@ get_new_tickets(krb5_context context, krb5_err (context, 1, ret, "krb5_cc_move"); if (ntlm_domain && ntlmkey.data) - store_ntlmkey(context, ccache, ntlm_domain, principal, &ntlmkey); + store_ntlmkey(context, ccache, ntlm_domain, &ntlmkey); + + if (ok_as_delegate_flag || windows_flag) { + krb5_data data; + + data.length = 1; + data.data = "\x01"; + + krb5_cc_set_config(context, ccache, NULL, "realm-config", &data); + } + if (enctype) free(enctype); diff --git a/source4/heimdal/lib/asn1/der.h b/source4/heimdal/lib/asn1/der.h index 13e39320d4..0484137192 100644 --- a/source4/heimdal/lib/asn1/der.h +++ b/source4/heimdal/lib/asn1/der.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: der.h 18437 2006-10-14 05:16:08Z lha $ */ +/* $Id: der.h 23183 2008-05-22 09:56:51Z lha $ */ #ifndef __DER_H__ #define __DER_H__ diff --git a/source4/heimdal/lib/asn1/der_free.c b/source4/heimdal/lib/asn1/der_free.c index 851cb1d407..f59ec72eb7 100644 --- a/source4/heimdal/lib/asn1/der_free.c +++ b/source4/heimdal/lib/asn1/der_free.c @@ -33,7 +33,7 @@ #include "der_locl.h" -RCSID("$Id: der_free.c 19539 2006-12-28 17:15:05Z lha $"); +RCSID("$Id: der_free.c 23182 2008-05-22 02:59:04Z lha $"); void der_free_general_string (heim_general_string *str) diff --git a/source4/heimdal/lib/asn1/gen.c b/source4/heimdal/lib/asn1/gen.c index 499f8eab36..39dba89e4e 100644 --- a/source4/heimdal/lib/asn1/gen.c +++ b/source4/heimdal/lib/asn1/gen.c @@ -33,7 +33,7 @@ #include "gen_locl.h" -RCSID("$Id: gen.c 22429 2008-01-13 10:25:50Z lha $"); +RCSID("$Id: gen.c 22896 2008-04-07 18:52:24Z lha $"); FILE *headerfile, *codefile, *logfile; @@ -294,13 +294,18 @@ generate_constant (const Symbol *s) break; case objectidentifiervalue: { struct objid *o, **list; - int i, len; + unsigned int i, len; generate_header_of_codefile(s->gen_name); len = 0; for (o = s->value->u.objectidentifiervalue; o != NULL; o = o->next) len++; + if (len == 0) { + printf("s->gen_name: %s",s->gen_name); + fflush(stdout); + break; + } list = emalloc(sizeof(*list) * len); i = 0; @@ -308,8 +313,8 @@ generate_constant (const Symbol *s) list[i++] = o; fprintf (headerfile, "/* OBJECT IDENTIFIER %s ::= { ", s->name); - for (i = len - 1 ; i >= 0; i--) { - o = list[i]; + for (i = len ; i > 0; i--) { + o = list[i - 1]; fprintf(headerfile, "%s(%d) ", o->label ? o->label : "label-less", o->value); } @@ -320,8 +325,8 @@ generate_constant (const Symbol *s) fprintf (codefile, "static unsigned oid_%s_variable_num[%d] = {", s->gen_name, len); - for (i = len - 1 ; i >= 0; i--) { - fprintf(codefile, "%d%s ", list[i]->value, i > 0 ? "," : ""); + for (i = len ; i > 0; i--) { + fprintf(codefile, "%d%s ", list[i - 1]->value, i > 1 ? "," : ""); } fprintf(codefile, "};\n"); diff --git a/source4/heimdal/lib/asn1/k5.asn1 b/source4/heimdal/lib/asn1/k5.asn1 index 18f1e1541b..ea20eb99d2 100644 --- a/source4/heimdal/lib/asn1/k5.asn1 +++ b/source4/heimdal/lib/asn1/k5.asn1 @@ -1,4 +1,4 @@ --- $Id: k5.asn1 21965 2007-10-18 18:24:36Z lha $ +-- $Id: k5.asn1 22745 2008-03-24 12:07:54Z lha $ KERBEROS5 DEFINITIONS ::= BEGIN @@ -634,18 +634,18 @@ KRB5SignedPath ::= SEQUENCE { } PA-ClientCanonicalizedNames ::= SEQUENCE{ - requested-name [0] PrincipalName, - real-name [1] PrincipalName + requested-name [0] PrincipalName, + mapped-name [1] PrincipalName } PA-ClientCanonicalized ::= SEQUENCE { - names [0] PA-ClientCanonicalizedNames, - canon-checksum [1] Checksum + names [0] PA-ClientCanonicalizedNames, + canon-checksum [1] Checksum } AD-LoginAlias ::= SEQUENCE { -- ad-type number TBD -- - login-alias [0] PrincipalName, - checksum [1] Checksum + login-alias [0] PrincipalName, + checksum [1] Checksum } -- old ms referral @@ -654,6 +654,16 @@ PA-SvrReferralData ::= SEQUENCE { referred-realm [0] Realm } +PA-SERVER-REFERRAL-DATA ::= EncryptedData + +PA-ServerReferralData ::= SEQUENCE { + referred-realm [0] Realm OPTIONAL, + true-principal-name [1] PrincipalName OPTIONAL, + requested-principal-name [2] PrincipalName OPTIONAL, + referral-valid-until [3] KerberosTime OPTIONAL, + ... +} + END -- etags -r '/\([A-Za-z][-A-Za-z0-9]*\).*::=/\1/' k5.asn1 diff --git a/source4/heimdal/lib/asn1/lex.c b/source4/heimdal/lib/asn1/lex.c index da4f729c3d..175760be44 100644 --- a/source4/heimdal/lib/asn1/lex.c +++ b/source4/heimdal/lib/asn1/lex.c @@ -1,5 +1,6 @@ +#include "config.h" -#line 3 "lex.c" +#line 3 "heimdal/lib/asn1/lex.c" #define YY_INT_ALIGNED short int @@ -8,7 +9,7 @@ #define FLEX_SCANNER #define YY_FLEX_MAJOR_VERSION 2 #define YY_FLEX_MINOR_VERSION 5 -#define YY_FLEX_SUBMINOR_VERSION 33 +#define YY_FLEX_SUBMINOR_VERSION 34 #if YY_FLEX_SUBMINOR_VERSION > 0 #define FLEX_BETA #endif @@ -30,7 +31,7 @@ /* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */ -#if __STDC_VERSION__ >= 199901L +#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, * if you want the limit (max/min) macros for int types. @@ -93,11 +94,12 @@ typedef unsigned int flex_uint32_t; #else /* ! __cplusplus */ -#if __STDC__ +/* C99 requires __STDC__ to be defined as 1. */ +#if defined (__STDC__) #define YY_USE_CONST -#endif /* __STDC__ */ +#endif /* defined (__STDC__) */ #endif /* ! __cplusplus */ #ifdef YY_USE_CONST @@ -180,11 +182,13 @@ extern FILE *yyin, *yyout; /* The following is because we cannot portably get our hands on size_t * (without autoconf's help, which isn't available because we want * flex-generated scanners to compile on their own). + * Given that the standard has decreed that size_t exists since 1989, + * I guess we can afford to depend on it. Manoj. */ #ifndef YY_TYPEDEF_YY_SIZE_T #define YY_TYPEDEF_YY_SIZE_T -typedef unsigned int yy_size_t; +typedef size_t yy_size_t; #endif #ifndef YY_STRUCT_YY_BUFFER_STATE @@ -851,7 +855,7 @@ static unsigned lineno = 1; static void unterminated(const char *, unsigned); /* This is for broken old lexes (solaris 10 and hpux) */ -#line 855 "lex.c" +#line 858 "heimdal/lib/asn1/lex.c" #define INITIAL 0 @@ -869,35 +873,6 @@ static void unterminated(const char *, unsigned); static int yy_init_globals (void ); -/* Accessor methods to globals. - These are made visible to non-reentrant scanners for convenience. */ - -int yylex_destroy (void ); - -int yyget_debug (void ); - -void yyset_debug (int debug_flag ); - -YY_EXTRA_TYPE yyget_extra (void ); - -void yyset_extra (YY_EXTRA_TYPE user_defined ); - -FILE *yyget_in (void ); - -void yyset_in (FILE * in_str ); - -FILE *yyget_out (void ); - -void yyset_out (FILE * out_str ); - -int yyget_leng (void ); - -char *yyget_text (void ); - -int yyget_lineno (void ); - -void yyset_lineno (int line_number ); - /* Macros after this point can all be overridden by user definitions in * section 1. */ @@ -940,7 +915,7 @@ static int input (void ); /* This used to be an fputs(), but since the string might contain NUL's, * we now use fwrite(). */ -#define ECHO (void) fwrite( yytext, yyleng, 1, yyout ) +#define ECHO fwrite( yytext, yyleng, 1, yyout ) #endif /* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, @@ -951,7 +926,7 @@ static int input (void ); if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ { \ int c = '*'; \ - size_t n; \ + int n; \ for ( n = 0; n < max_size && \ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ buf[n] = (char) c; \ @@ -1035,7 +1010,7 @@ YY_DECL #line 68 "lex.l" -#line 1039 "lex.c" +#line 1013 "heimdal/lib/asn1/lex.c" if ( !(yy_init) ) { @@ -1704,7 +1679,7 @@ YY_RULE_SETUP #line 274 "lex.l" ECHO; YY_BREAK -#line 1708 "lex.c" +#line 1682 "heimdal/lib/asn1/lex.c" case YY_STATE_EOF(INITIAL): yyterminate(); @@ -1935,7 +1910,7 @@ static int yy_get_next_buffer (void) /* Read in more data. */ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), - (yy_n_chars), num_to_read ); + (yy_n_chars), (size_t) num_to_read ); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } @@ -1959,6 +1934,14 @@ static int yy_get_next_buffer (void) else ret_val = EOB_ACT_CONTINUE_SCAN; + if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { + /* Extend the array by 50%, plus the number we really need. */ + yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ); + if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); + } + (yy_n_chars) += number_to_move; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; @@ -2374,7 +2357,9 @@ static void yyensure_buffer_stack (void) (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc (num_to_alloc * sizeof(struct yy_buffer_state*) ); - + if ( ! (yy_buffer_stack) ) + YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); + memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); (yy_buffer_stack_max) = num_to_alloc; @@ -2392,6 +2377,8 @@ static void yyensure_buffer_stack (void) ((yy_buffer_stack), num_to_alloc * sizeof(struct yy_buffer_state*) ); + if ( ! (yy_buffer_stack) ) + YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); /* zero only the new slots.*/ memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); @@ -2436,7 +2423,7 @@ YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size ) /** Setup the input buffer state to scan a string. The next call to yylex() will * scan from a @e copy of @a str. - * @param str a NUL-terminated string to scan + * @param yystr a NUL-terminated string to scan * * @return the newly allocated buffer state object. * @note If you want to scan bytes that may contain NUL values, then use diff --git a/source4/heimdal/lib/asn1/lex.l b/source4/heimdal/lib/asn1/lex.l index 6ec7b67bb9..ec744220e9 100644 --- a/source4/heimdal/lib/asn1/lex.l +++ b/source4/heimdal/lib/asn1/lex.l @@ -32,7 +32,7 @@ * SUCH DAMAGE. */ -/* $Id: lex.l,v 1.31 2006/10/21 11:57:22 lha Exp $ */ +/* $Id: lex.l 18738 2006-10-21 11:57:22Z lha $ */ #ifdef HAVE_CONFIG_H #include <config.h> diff --git a/source4/heimdal/lib/asn1/pkinit.asn1 b/source4/heimdal/lib/asn1/pkinit.asn1 index 989b26581b..758af6f86e 100644 --- a/source4/heimdal/lib/asn1/pkinit.asn1 +++ b/source4/heimdal/lib/asn1/pkinit.asn1 @@ -17,6 +17,11 @@ id-pkrkeydata OBJECT IDENTIFIER ::= { id-pkinit 3 } id-pkekuoid OBJECT IDENTIFIER ::= { id-pkinit 4 } id-pkkdcekuoid OBJECT IDENTIFIER ::= { id-pkinit 5 } +id-pkinit-kdf OBJECT IDENTIFIER ::= { id-pkinit 6 } +id-pkinit-kdf-ah-sha1 OBJECT IDENTIFIER ::= { id-pkinit-kdf 1 } +id-pkinit-kdf-ah-sha256 OBJECT IDENTIFIER ::= { id-pkinit-kdf 2 } +id-pkinit-kdf-ah-sha512 OBJECT IDENTIFIER ::= { id-pkinit-kdf 3 } + id-pkinit-san OBJECT IDENTIFIER ::= { iso(1) org(3) dod(6) internet(1) security(5) kerberosv5(2) x509-sanan(2) } @@ -171,6 +176,14 @@ ReplyKeyPack-Win2k ::= SEQUENCE { ... } +PkinitSP80056AOtherInfo ::= SEQUENCE { + algorithmID AlgorithmIdentifier, + partyUInfo [0] OCTET STRING, + partyVInfo [1] OCTET STRING, + suppPubInfo [2] OCTET STRING OPTIONAL, + suppPrivInfo [3] OCTET STRING OPTIONAL +} + PkinitSuppPubInfo ::= SEQUENCE { enctype [0] INTEGER (-2147483648..2147483647), as-REQ [1] OCTET STRING, diff --git a/source4/heimdal/lib/asn1/test.gen b/source4/heimdal/lib/asn1/test.gen index 9a1f354791..d0fc7d98a4 100644 --- a/source4/heimdal/lib/asn1/test.gen +++ b/source4/heimdal/lib/asn1/test.gen @@ -1,4 +1,4 @@ -# $Id: test.gen,v 1.2 2005/07/12 06:27:41 lha Exp $ +# $Id: test.gen 15617 2005-07-12 06:27:42Z lha $ # Sample for TESTSeq in test.asn1 # diff --git a/source4/heimdal/lib/com_err/lex.c b/source4/heimdal/lib/com_err/lex.c index 3c6ea3beb7..b70ef4749f 100644 --- a/source4/heimdal/lib/com_err/lex.c +++ b/source4/heimdal/lib/com_err/lex.c @@ -1,5 +1,6 @@ +#include "config.h" -#line 3 "lex.c" +#line 3 "heimdal/lib/com_err/lex.c" #define YY_INT_ALIGNED short int @@ -8,7 +9,7 @@ #define FLEX_SCANNER #define YY_FLEX_MAJOR_VERSION 2 #define YY_FLEX_MINOR_VERSION 5 -#define YY_FLEX_SUBMINOR_VERSION 33 +#define YY_FLEX_SUBMINOR_VERSION 34 #if YY_FLEX_SUBMINOR_VERSION > 0 #define FLEX_BETA #endif @@ -30,7 +31,7 @@ /* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */ -#if __STDC_VERSION__ >= 199901L +#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, * if you want the limit (max/min) macros for int types. @@ -93,11 +94,12 @@ typedef unsigned int flex_uint32_t; #else /* ! __cplusplus */ -#if __STDC__ +/* C99 requires __STDC__ to be defined as 1. */ +#if defined (__STDC__) #define YY_USE_CONST -#endif /* __STDC__ */ +#endif /* defined (__STDC__) */ #endif /* ! __cplusplus */ #ifdef YY_USE_CONST @@ -180,11 +182,13 @@ extern FILE *yyin, *yyout; /* The following is because we cannot portably get our hands on size_t * (without autoconf's help, which isn't available because we want * flex-generated scanners to compile on their own). + * Given that the standard has decreed that size_t exists since 1989, + * I guess we can afford to depend on it. Manoj. */ #ifndef YY_TYPEDEF_YY_SIZE_T #define YY_TYPEDEF_YY_SIZE_T -typedef unsigned int yy_size_t; +typedef size_t yy_size_t; #endif #ifndef YY_STRUCT_YY_BUFFER_STATE @@ -532,7 +536,7 @@ static int getstring(void); #undef ECHO -#line 536 "lex.c" +#line 539 "heimdal/lib/com_err/lex.c" #define INITIAL 0 @@ -550,35 +554,6 @@ static int getstring(void); static int yy_init_globals (void ); -/* Accessor methods to globals. - These are made visible to non-reentrant scanners for convenience. */ - -int yylex_destroy (void ); - -int yyget_debug (void ); - -void yyset_debug (int debug_flag ); - -YY_EXTRA_TYPE yyget_extra (void ); - -void yyset_extra (YY_EXTRA_TYPE user_defined ); - -FILE *yyget_in (void ); - -void yyset_in (FILE * in_str ); - -FILE *yyget_out (void ); - -void yyset_out (FILE * out_str ); - -int yyget_leng (void ); - -char *yyget_text (void ); - -int yyget_lineno (void ); - -void yyset_lineno (int line_number ); - /* Macros after this point can all be overridden by user definitions in * section 1. */ @@ -621,7 +596,7 @@ static int input (void ); /* This used to be an fputs(), but since the string might contain NUL's, * we now use fwrite(). */ -#define ECHO (void) fwrite( yytext, yyleng, 1, yyout ) +#define ECHO fwrite( yytext, yyleng, 1, yyout ) #endif /* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, @@ -632,7 +607,7 @@ static int input (void ); if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ { \ int c = '*'; \ - size_t n; \ + int n; \ for ( n = 0; n < max_size && \ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ buf[n] = (char) c; \ @@ -716,7 +691,7 @@ YY_DECL #line 59 "lex.l" -#line 720 "lex.c" +#line 694 "heimdal/lib/com_err/lex.c" if ( !(yy_init) ) { @@ -880,7 +855,7 @@ YY_RULE_SETUP #line 75 "lex.l" ECHO; YY_BREAK -#line 884 "lex.c" +#line 858 "heimdal/lib/com_err/lex.c" case YY_STATE_EOF(INITIAL): yyterminate(); @@ -1111,7 +1086,7 @@ static int yy_get_next_buffer (void) /* Read in more data. */ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), - (yy_n_chars), num_to_read ); + (yy_n_chars), (size_t) num_to_read ); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } @@ -1135,6 +1110,14 @@ static int yy_get_next_buffer (void) else ret_val = EOB_ACT_CONTINUE_SCAN; + if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { + /* Extend the array by 50%, plus the number we really need. */ + yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ); + if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); + } + (yy_n_chars) += number_to_move; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; @@ -1550,7 +1533,9 @@ static void yyensure_buffer_stack (void) (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc (num_to_alloc * sizeof(struct yy_buffer_state*) ); - + if ( ! (yy_buffer_stack) ) + YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); + memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); (yy_buffer_stack_max) = num_to_alloc; @@ -1568,6 +1553,8 @@ static void yyensure_buffer_stack (void) ((yy_buffer_stack), num_to_alloc * sizeof(struct yy_buffer_state*) ); + if ( ! (yy_buffer_stack) ) + YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); /* zero only the new slots.*/ memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); @@ -1612,7 +1599,7 @@ YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size ) /** Setup the input buffer state to scan a string. The next call to yylex() will * scan from a @e copy of @a str. - * @param str a NUL-terminated string to scan + * @param yystr a NUL-terminated string to scan * * @return the newly allocated buffer state object. * @note If you want to scan bytes that may contain NUL values, then use diff --git a/source4/heimdal/lib/com_err/lex.l b/source4/heimdal/lib/com_err/lex.l index d60e67c136..08aef516b3 100644 --- a/source4/heimdal/lib/com_err/lex.l +++ b/source4/heimdal/lib/com_err/lex.l @@ -44,7 +44,7 @@ #include "parse.h" #include "lex.h" -RCSID("$Id: lex.l,v 1.8 2005/05/16 08:52:54 lha Exp $"); +RCSID("$Id: lex.l 15143 2005-05-16 08:52:54Z lha $"); static unsigned lineno = 1; static int getstring(void); diff --git a/source4/heimdal/lib/gssapi/gssapi/gssapi.h b/source4/heimdal/lib/gssapi/gssapi/gssapi.h index fbc638c48f..63f66f7313 100644 --- a/source4/heimdal/lib/gssapi/gssapi/gssapi.h +++ b/source4/heimdal/lib/gssapi/gssapi/gssapi.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: gssapi.h 21004 2007-06-08 01:53:10Z lha $ */ +/* $Id: gssapi.h 23025 2008-04-17 10:01:57Z lha $ */ #ifndef GSSAPI_GSSAPI_H_ #define GSSAPI_GSSAPI_H_ @@ -43,6 +43,16 @@ #include <krb5-types.h> +#ifndef BUILD_GSSAPI_LIB +#if defined(_WIN32) +#define GSSAPI_LIB_FUNCTION _stdcall __declspec(dllimport) +#define GSSAPI_LIB_VARIABLE __declspec(dllimport) +#else +#define GSSAPI_LIB_FUNCTION +#define GSSAPI_LIB_VARIABLE +#endif +#endif + /* * Now define the three implementation-dependent types. */ @@ -210,7 +220,7 @@ extern "C" { * GSS_C_NT_USER_NAME should be initialized to point * to that gss_OID_desc. */ -extern gss_OID GSS_C_NT_USER_NAME; +extern GSSAPI_LIB_VARIABLE gss_OID GSS_C_NT_USER_NAME; /* * The implementation must reserve static storage for a @@ -223,7 +233,7 @@ extern gss_OID GSS_C_NT_USER_NAME; * The constant GSS_C_NT_MACHINE_UID_NAME should be * initialized to point to that gss_OID_desc. */ -extern gss_OID GSS_C_NT_MACHINE_UID_NAME; +extern GSSAPI_LIB_VARIABLE gss_OID GSS_C_NT_MACHINE_UID_NAME; /* * The implementation must reserve static storage for a @@ -236,7 +246,7 @@ extern gss_OID GSS_C_NT_MACHINE_UID_NAME; * The constant GSS_C_NT_STRING_UID_NAME should be * initialized to point to that gss_OID_desc. */ -extern gss_OID GSS_C_NT_STRING_UID_NAME; +extern GSSAPI_LIB_VARIABLE gss_OID GSS_C_NT_STRING_UID_NAME; /* * The implementation must reserve static storage for a @@ -255,7 +265,7 @@ extern gss_OID GSS_C_NT_STRING_UID_NAME; * parameter, but should not be emitted by GSS-API * implementations */ -extern gss_OID GSS_C_NT_HOSTBASED_SERVICE_X; +extern GSSAPI_LIB_VARIABLE gss_OID GSS_C_NT_HOSTBASED_SERVICE_X; /* * The implementation must reserve static storage for a @@ -268,7 +278,7 @@ extern gss_OID GSS_C_NT_HOSTBASED_SERVICE_X; * GSS_C_NT_HOSTBASED_SERVICE should be initialized * to point to that gss_OID_desc. */ -extern gss_OID GSS_C_NT_HOSTBASED_SERVICE; +extern GSSAPI_LIB_VARIABLE gss_OID GSS_C_NT_HOSTBASED_SERVICE; /* * The implementation must reserve static storage for a @@ -280,7 +290,7 @@ extern gss_OID GSS_C_NT_HOSTBASED_SERVICE; * and GSS_C_NT_ANONYMOUS should be initialized to point * to that gss_OID_desc. */ -extern gss_OID GSS_C_NT_ANONYMOUS; +extern GSSAPI_LIB_VARIABLE gss_OID GSS_C_NT_ANONYMOUS; /* * The implementation must reserve static storage for a @@ -292,19 +302,19 @@ extern gss_OID GSS_C_NT_ANONYMOUS; * GSS_C_NT_EXPORT_NAME should be initialized to point * to that gss_OID_desc. */ -extern gss_OID GSS_C_NT_EXPORT_NAME; +extern GSSAPI_LIB_VARIABLE gss_OID GSS_C_NT_EXPORT_NAME; /* * Digest mechanism */ -extern gss_OID GSS_SASL_DIGEST_MD5_MECHANISM; +extern GSSAPI_LIB_VARIABLE gss_OID GSS_SASL_DIGEST_MD5_MECHANISM; /* * NTLM mechanism */ -extern gss_OID GSS_NTLM_MECHANISM; +extern GSSAPI_LIB_VARIABLE gss_OID GSS_NTLM_MECHANISM; /* Major status codes */ @@ -387,7 +397,7 @@ extern gss_OID GSS_NTLM_MECHANISM; * Finally, function prototypes for the GSS-API routines. */ -OM_uint32 gss_acquire_cred +OM_uint32 GSSAPI_LIB_FUNCTION gss_acquire_cred (OM_uint32 * /*minor_status*/, const gss_name_t /*desired_name*/, OM_uint32 /*time_req*/, @@ -398,12 +408,12 @@ OM_uint32 gss_acquire_cred OM_uint32 * /*time_rec*/ ); -OM_uint32 gss_release_cred +OM_uint32 GSSAPI_LIB_FUNCTION gss_release_cred (OM_uint32 * /*minor_status*/, gss_cred_id_t * /*cred_handle*/ ); -OM_uint32 gss_init_sec_context +OM_uint32 GSSAPI_LIB_FUNCTION gss_init_sec_context (OM_uint32 * /*minor_status*/, const gss_cred_id_t /*initiator_cred_handle*/, gss_ctx_id_t * /*context_handle*/, @@ -419,7 +429,7 @@ OM_uint32 gss_init_sec_context OM_uint32 * /*time_rec*/ ); -OM_uint32 gss_accept_sec_context +OM_uint32 GSSAPI_LIB_FUNCTION gss_accept_sec_context (OM_uint32 * /*minor_status*/, gss_ctx_id_t * /*context_handle*/, const gss_cred_id_t /*acceptor_cred_handle*/, @@ -433,25 +443,25 @@ OM_uint32 gss_accept_sec_context gss_cred_id_t * /*delegated_cred_handle*/ ); -OM_uint32 gss_process_context_token +OM_uint32 GSSAPI_LIB_FUNCTION gss_process_context_token (OM_uint32 * /*minor_status*/, const gss_ctx_id_t /*context_handle*/, const gss_buffer_t /*token_buffer*/ ); -OM_uint32 gss_delete_sec_context +OM_uint32 GSSAPI_LIB_FUNCTION gss_delete_sec_context (OM_uint32 * /*minor_status*/, gss_ctx_id_t * /*context_handle*/, gss_buffer_t /*output_token*/ ); -OM_uint32 gss_context_time +OM_uint32 GSSAPI_LIB_FUNCTION gss_context_time (OM_uint32 * /*minor_status*/, const gss_ctx_id_t /*context_handle*/, OM_uint32 * /*time_rec*/ ); -OM_uint32 gss_get_mic +OM_uint32 GSSAPI_LIB_FUNCTION gss_get_mic (OM_uint32 * /*minor_status*/, const gss_ctx_id_t /*context_handle*/, gss_qop_t /*qop_req*/, @@ -459,7 +469,7 @@ OM_uint32 gss_get_mic gss_buffer_t /*message_token*/ ); -OM_uint32 gss_verify_mic +OM_uint32 GSSAPI_LIB_FUNCTION gss_verify_mic (OM_uint32 * /*minor_status*/, const gss_ctx_id_t /*context_handle*/, const gss_buffer_t /*message_buffer*/, @@ -467,7 +477,7 @@ OM_uint32 gss_verify_mic gss_qop_t * /*qop_state*/ ); -OM_uint32 gss_wrap +OM_uint32 GSSAPI_LIB_FUNCTION gss_wrap (OM_uint32 * /*minor_status*/, const gss_ctx_id_t /*context_handle*/, int /*conf_req_flag*/, @@ -477,7 +487,7 @@ OM_uint32 gss_wrap gss_buffer_t /*output_message_buffer*/ ); -OM_uint32 gss_unwrap +OM_uint32 GSSAPI_LIB_FUNCTION gss_unwrap (OM_uint32 * /*minor_status*/, const gss_ctx_id_t /*context_handle*/, const gss_buffer_t /*input_message_buffer*/, @@ -486,7 +496,7 @@ OM_uint32 gss_unwrap gss_qop_t * /*qop_state*/ ); -OM_uint32 gss_display_status +OM_uint32 GSSAPI_LIB_FUNCTION gss_display_status (OM_uint32 * /*minor_status*/, OM_uint32 /*status_value*/, int /*status_type*/, @@ -495,54 +505,54 @@ OM_uint32 gss_display_status gss_buffer_t /*status_string*/ ); -OM_uint32 gss_indicate_mechs +OM_uint32 GSSAPI_LIB_FUNCTION gss_indicate_mechs (OM_uint32 * /*minor_status*/, gss_OID_set * /*mech_set*/ ); -OM_uint32 gss_compare_name +OM_uint32 GSSAPI_LIB_FUNCTION gss_compare_name (OM_uint32 * /*minor_status*/, const gss_name_t /*name1*/, const gss_name_t /*name2*/, int * /*name_equal*/ ); -OM_uint32 gss_display_name +OM_uint32 GSSAPI_LIB_FUNCTION gss_display_name (OM_uint32 * /*minor_status*/, const gss_name_t /*input_name*/, gss_buffer_t /*output_name_buffer*/, gss_OID * /*output_name_type*/ ); -OM_uint32 gss_import_name +OM_uint32 GSSAPI_LIB_FUNCTION gss_import_name (OM_uint32 * /*minor_status*/, const gss_buffer_t /*input_name_buffer*/, const gss_OID /*input_name_type*/, gss_name_t * /*output_name*/ ); -OM_uint32 gss_export_name +OM_uint32 GSSAPI_LIB_FUNCTION gss_export_name (OM_uint32 * /*minor_status*/, const gss_name_t /*input_name*/, gss_buffer_t /*exported_name*/ ); -OM_uint32 gss_release_name +OM_uint32 GSSAPI_LIB_FUNCTION gss_release_name (OM_uint32 * /*minor_status*/, gss_name_t * /*input_name*/ ); -OM_uint32 gss_release_buffer +OM_uint32 GSSAPI_LIB_FUNCTION gss_release_buffer (OM_uint32 * /*minor_status*/, gss_buffer_t /*buffer*/ ); -OM_uint32 gss_release_oid_set +OM_uint32 GSSAPI_LIB_FUNCTION gss_release_oid_set (OM_uint32 * /*minor_status*/, gss_OID_set * /*set*/ ); -OM_uint32 gss_inquire_cred +OM_uint32 GSSAPI_LIB_FUNCTION gss_inquire_cred (OM_uint32 * /*minor_status*/, const gss_cred_id_t /*cred_handle*/, gss_name_t * /*name*/, @@ -551,7 +561,7 @@ OM_uint32 gss_inquire_cred gss_OID_set * /*mechanisms*/ ); -OM_uint32 gss_inquire_context ( +OM_uint32 GSSAPI_LIB_FUNCTION gss_inquire_context ( OM_uint32 * /*minor_status*/, const gss_ctx_id_t /*context_handle*/, gss_name_t * /*src_name*/, @@ -563,7 +573,7 @@ OM_uint32 gss_inquire_context ( int * /*open_context*/ ); -OM_uint32 gss_wrap_size_limit ( +OM_uint32 GSSAPI_LIB_FUNCTION gss_wrap_size_limit ( OM_uint32 * /*minor_status*/, const gss_ctx_id_t /*context_handle*/, int /*conf_req_flag*/, @@ -572,7 +582,7 @@ OM_uint32 gss_wrap_size_limit ( OM_uint32 * /*max_input_size*/ ); -OM_uint32 gss_add_cred ( +OM_uint32 GSSAPI_LIB_FUNCTION gss_add_cred ( OM_uint32 * /*minor_status*/, const gss_cred_id_t /*input_cred_handle*/, const gss_name_t /*desired_name*/, @@ -586,7 +596,7 @@ OM_uint32 gss_add_cred ( OM_uint32 * /*acceptor_time_rec*/ ); -OM_uint32 gss_inquire_cred_by_mech ( +OM_uint32 GSSAPI_LIB_FUNCTION gss_inquire_cred_by_mech ( OM_uint32 * /*minor_status*/, const gss_cred_id_t /*cred_handle*/, const gss_OID /*mech_type*/, @@ -596,80 +606,81 @@ OM_uint32 gss_inquire_cred_by_mech ( gss_cred_usage_t * /*cred_usage*/ ); -OM_uint32 gss_export_sec_context ( +OM_uint32 GSSAPI_LIB_FUNCTION gss_export_sec_context ( OM_uint32 * /*minor_status*/, gss_ctx_id_t * /*context_handle*/, gss_buffer_t /*interprocess_token*/ ); -OM_uint32 gss_import_sec_context ( +OM_uint32 GSSAPI_LIB_FUNCTION gss_import_sec_context ( OM_uint32 * /*minor_status*/, const gss_buffer_t /*interprocess_token*/, gss_ctx_id_t * /*context_handle*/ ); -OM_uint32 gss_create_empty_oid_set ( +OM_uint32 GSSAPI_LIB_FUNCTION gss_create_empty_oid_set ( OM_uint32 * /*minor_status*/, gss_OID_set * /*oid_set*/ ); -OM_uint32 gss_add_oid_set_member ( +OM_uint32 GSSAPI_LIB_FUNCTION gss_add_oid_set_member ( OM_uint32 * /*minor_status*/, const gss_OID /*member_oid*/, gss_OID_set * /*oid_set*/ ); -OM_uint32 gss_test_oid_set_member ( +OM_uint32 GSSAPI_LIB_FUNCTION gss_test_oid_set_member ( OM_uint32 * /*minor_status*/, const gss_OID /*member*/, const gss_OID_set /*set*/, int * /*present*/ ); -OM_uint32 gss_inquire_names_for_mech ( +OM_uint32 GSSAPI_LIB_FUNCTION gss_inquire_names_for_mech ( OM_uint32 * /*minor_status*/, const gss_OID /*mechanism*/, gss_OID_set * /*name_types*/ ); -OM_uint32 gss_inquire_mechs_for_name ( +OM_uint32 GSSAPI_LIB_FUNCTION gss_inquire_mechs_for_name ( OM_uint32 * /*minor_status*/, const gss_name_t /*input_name*/, gss_OID_set * /*mech_types*/ ); -OM_uint32 gss_canonicalize_name ( +OM_uint32 GSSAPI_LIB_FUNCTION gss_canonicalize_name ( OM_uint32 * /*minor_status*/, const gss_name_t /*input_name*/, const gss_OID /*mech_type*/, gss_name_t * /*output_name*/ ); -OM_uint32 gss_duplicate_name ( +OM_uint32 GSSAPI_LIB_FUNCTION gss_duplicate_name ( OM_uint32 * /*minor_status*/, const gss_name_t /*src_name*/, gss_name_t * /*dest_name*/ ); -OM_uint32 gss_duplicate_oid ( +OM_uint32 GSSAPI_LIB_FUNCTION gss_duplicate_oid ( OM_uint32 * /* minor_status */, gss_OID /* src_oid */, gss_OID * /* dest_oid */ ); -OM_uint32 + +OM_uint32 GSSAPI_LIB_FUNCTION gss_release_oid (OM_uint32 * /*minor_status*/, gss_OID * /* oid */ ); -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gss_oid_to_str( OM_uint32 * /*minor_status*/, gss_OID /* oid */, gss_buffer_t /* str */ ); -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gss_inquire_sec_context_by_oid( OM_uint32 * minor_status, const gss_ctx_id_t context_handle, @@ -677,38 +688,38 @@ gss_inquire_sec_context_by_oid( gss_buffer_set_t *data_set ); -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gss_set_sec_context_option (OM_uint32 *minor_status, gss_ctx_id_t *context_handle, const gss_OID desired_object, const gss_buffer_t value); -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gss_set_cred_option (OM_uint32 *minor_status, gss_cred_id_t *cred_handle, const gss_OID object, const gss_buffer_t value); -int +int GSSAPI_LIB_FUNCTION gss_oid_equal(const gss_OID a, const gss_OID b); -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gss_create_empty_buffer_set (OM_uint32 * minor_status, gss_buffer_set_t *buffer_set); -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gss_add_buffer_set_member (OM_uint32 * minor_status, const gss_buffer_t member_buffer, gss_buffer_set_t *buffer_set); -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gss_release_buffer_set (OM_uint32 * minor_status, gss_buffer_set_t *buffer_set); -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gss_inquire_cred_by_oid(OM_uint32 *minor_status, const gss_cred_id_t cred_handle, const gss_OID desired_object, @@ -721,7 +732,7 @@ gss_inquire_cred_by_oid(OM_uint32 *minor_status, #define GSS_C_PRF_KEY_FULL 0 #define GSS_C_PRF_KEY_PARTIAL 1 -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gss_pseudo_random (OM_uint32 *minor_status, gss_ctx_id_t context, @@ -742,7 +753,7 @@ gss_pseudo_random * obsolete versions of these routines and their current forms. */ -OM_uint32 gss_sign +OM_uint32 GSSAPI_LIB_FUNCTION gss_sign (OM_uint32 * /*minor_status*/, gss_ctx_id_t /*context_handle*/, int /*qop_req*/, @@ -750,7 +761,7 @@ OM_uint32 gss_sign gss_buffer_t /*message_token*/ ); -OM_uint32 gss_verify +OM_uint32 GSSAPI_LIB_FUNCTION gss_verify (OM_uint32 * /*minor_status*/, gss_ctx_id_t /*context_handle*/, gss_buffer_t /*message_buffer*/, @@ -758,7 +769,7 @@ OM_uint32 gss_verify int * /*qop_state*/ ); -OM_uint32 gss_seal +OM_uint32 GSSAPI_LIB_FUNCTION gss_seal (OM_uint32 * /*minor_status*/, gss_ctx_id_t /*context_handle*/, int /*conf_req_flag*/, @@ -768,7 +779,7 @@ OM_uint32 gss_seal gss_buffer_t /*output_message_buffer*/ ); -OM_uint32 gss_unseal +OM_uint32 GSSAPI_LIB_FUNCTION gss_unseal (OM_uint32 * /*minor_status*/, gss_ctx_id_t /*context_handle*/, gss_buffer_t /*input_message_buffer*/, @@ -781,18 +792,18 @@ OM_uint32 gss_unseal * */ -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gss_inquire_sec_context_by_oid (OM_uint32 *minor_status, const gss_ctx_id_t context_handle, const gss_OID desired_object, gss_buffer_set_t *data_set); -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gss_encapsulate_token(gss_buffer_t /* input_token */, gss_OID /* oid */, gss_buffer_t /* output_token */); -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gss_decapsulate_token(gss_buffer_t /* input_token */, gss_OID /* oid */, gss_buffer_t /* output_token */); diff --git a/source4/heimdal/lib/gssapi/gssapi/gssapi_krb5.h b/source4/heimdal/lib/gssapi/gssapi/gssapi_krb5.h index 2223f4f22f..55f7886658 100644 --- a/source4/heimdal/lib/gssapi/gssapi/gssapi_krb5.h +++ b/source4/heimdal/lib/gssapi/gssapi/gssapi_krb5.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: gssapi_krb5.h 22655 2008-02-26 12:40:35Z lha $ */ +/* $Id: gssapi_krb5.h 23420 2008-07-26 18:37:48Z lha $ */ #ifndef GSSAPI_KRB5_H_ #define GSSAPI_KRB5_H_ @@ -46,12 +46,12 @@ extern "C" { * This is for kerberos5 names. */ -extern gss_OID GSS_KRB5_NT_PRINCIPAL_NAME; -extern gss_OID GSS_KRB5_NT_USER_NAME; -extern gss_OID GSS_KRB5_NT_MACHINE_UID_NAME; -extern gss_OID GSS_KRB5_NT_STRING_UID_NAME; +extern GSSAPI_LIB_VARIABLE gss_OID GSS_KRB5_NT_PRINCIPAL_NAME; +extern GSSAPI_LIB_VARIABLE gss_OID GSS_KRB5_NT_USER_NAME; +extern GSSAPI_LIB_VARIABLE gss_OID GSS_KRB5_NT_MACHINE_UID_NAME; +extern GSSAPI_LIB_VARIABLE gss_OID GSS_KRB5_NT_STRING_UID_NAME; -extern gss_OID GSS_KRB5_MECHANISM; +extern GSSAPI_LIB_VARIABLE gss_OID GSS_KRB5_MECHANISM; /* for compatibility with MIT api */ @@ -59,28 +59,30 @@ extern gss_OID GSS_KRB5_MECHANISM; #define gss_krb5_nt_general_name GSS_KRB5_NT_PRINCIPAL_NAME /* Extensions set contexts options */ -extern gss_OID GSS_KRB5_COPY_CCACHE_X; -extern gss_OID GSS_KRB5_COMPAT_DES3_MIC_X; -extern gss_OID GSS_KRB5_REGISTER_ACCEPTOR_IDENTITY_X; -extern gss_OID GSS_KRB5_SET_DNS_CANONICALIZE_X; -extern gss_OID GSS_KRB5_SEND_TO_KDC_X; -extern gss_OID GSS_KRB5_SET_DEFAULT_REALM_X; -extern gss_OID GSS_KRB5_CCACHE_NAME_X; +extern GSSAPI_LIB_VARIABLE gss_OID GSS_KRB5_COPY_CCACHE_X; +extern GSSAPI_LIB_VARIABLE gss_OID GSS_KRB5_COMPAT_DES3_MIC_X; +extern GSSAPI_LIB_VARIABLE gss_OID GSS_KRB5_REGISTER_ACCEPTOR_IDENTITY_X; +extern GSSAPI_LIB_VARIABLE gss_OID GSS_KRB5_SET_DNS_CANONICALIZE_X; +extern GSSAPI_LIB_VARIABLE gss_OID GSS_KRB5_SEND_TO_KDC_X; +extern GSSAPI_LIB_VARIABLE gss_OID GSS_KRB5_SET_DEFAULT_REALM_X; +extern GSSAPI_LIB_VARIABLE gss_OID GSS_KRB5_CCACHE_NAME_X; +extern GSSAPI_LIB_VARIABLE gss_OID GSS_KRB5_SET_TIME_OFFSET_X; +extern GSSAPI_LIB_VARIABLE gss_OID GSS_KRB5_GET_TIME_OFFSET_X; /* Extensions inquire context */ -extern gss_OID GSS_KRB5_GET_TKT_FLAGS_X; -extern gss_OID GSS_KRB5_EXTRACT_AUTHZ_DATA_FROM_SEC_CONTEXT_X; -extern gss_OID GSS_C_PEER_HAS_UPDATED_SPNEGO; -extern gss_OID GSS_KRB5_EXPORT_LUCID_CONTEXT_X; -extern gss_OID GSS_KRB5_EXPORT_LUCID_CONTEXT_V1_X; -extern gss_OID GSS_KRB5_GET_SUBKEY_X; -extern gss_OID GSS_KRB5_GET_INITIATOR_SUBKEY_X; -extern gss_OID GSS_KRB5_GET_ACCEPTOR_SUBKEY_X; -extern gss_OID GSS_KRB5_GET_AUTHTIME_X; -extern gss_OID GSS_KRB5_GET_SERVICE_KEYBLOCK_X; +extern GSSAPI_LIB_VARIABLE gss_OID GSS_KRB5_GET_TKT_FLAGS_X; +extern GSSAPI_LIB_VARIABLE gss_OID GSS_KRB5_EXTRACT_AUTHZ_DATA_FROM_SEC_CONTEXT_X; +extern GSSAPI_LIB_VARIABLE gss_OID GSS_C_PEER_HAS_UPDATED_SPNEGO; +extern GSSAPI_LIB_VARIABLE gss_OID GSS_KRB5_EXPORT_LUCID_CONTEXT_X; +extern GSSAPI_LIB_VARIABLE gss_OID GSS_KRB5_EXPORT_LUCID_CONTEXT_V1_X; +extern GSSAPI_LIB_VARIABLE gss_OID GSS_KRB5_GET_SUBKEY_X; +extern GSSAPI_LIB_VARIABLE gss_OID GSS_KRB5_GET_INITIATOR_SUBKEY_X; +extern GSSAPI_LIB_VARIABLE gss_OID GSS_KRB5_GET_ACCEPTOR_SUBKEY_X; +extern GSSAPI_LIB_VARIABLE gss_OID GSS_KRB5_GET_AUTHTIME_X; +extern GSSAPI_LIB_VARIABLE gss_OID GSS_KRB5_GET_SERVICE_KEYBLOCK_X; /* Extensions creds */ -extern gss_OID GSS_KRB5_IMPORT_CRED_X; -extern gss_OID GSS_KRB5_SET_ALLOWABLE_ENCTYPES_X; -extern gss_OID GSS_KRB5_CRED_NO_CI_FLAGS_X; +extern GSSAPI_LIB_VARIABLE gss_OID GSS_KRB5_IMPORT_CRED_X; +extern GSSAPI_LIB_VARIABLE gss_OID GSS_KRB5_SET_ALLOWABLE_ENCTYPES_X; +extern GSSAPI_LIB_VARIABLE gss_OID GSS_KRB5_CRED_NO_CI_FLAGS_X; /* * kerberos mechanism specific functions @@ -90,39 +92,42 @@ struct krb5_keytab_data; struct krb5_ccache_data; struct Principal; -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gss_krb5_ccache_name(OM_uint32 * /*minor_status*/, const char * /*name */, const char ** /*out_name */); -OM_uint32 gsskrb5_register_acceptor_identity +OM_uint32 GSSAPI_LIB_FUNCTION gsskrb5_register_acceptor_identity (const char */*identity*/); -OM_uint32 gss_krb5_copy_ccache +OM_uint32 GSSAPI_LIB_FUNCTION krb5_gss_register_acceptor_identity + (const char */*identity*/); + +OM_uint32 GSSAPI_LIB_FUNCTION gss_krb5_copy_ccache (OM_uint32 */*minor*/, gss_cred_id_t /*cred*/, struct krb5_ccache_data */*out*/); -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gss_krb5_import_cred(OM_uint32 */*minor*/, struct krb5_ccache_data * /*in*/, struct Principal * /*keytab_principal*/, struct krb5_keytab_data * /*keytab*/, gss_cred_id_t */*out*/); -OM_uint32 gss_krb5_get_tkt_flags +OM_uint32 GSSAPI_LIB_FUNCTION gss_krb5_get_tkt_flags (OM_uint32 */*minor*/, gss_ctx_id_t /*context_handle*/, OM_uint32 */*tkt_flags*/); -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gsskrb5_extract_authz_data_from_sec_context (OM_uint32 * /*minor_status*/, gss_ctx_id_t /*context_handle*/, int /*ad_type*/, gss_buffer_t /*ad_data*/); -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gsskrb5_set_dns_canonicalize(int); struct gsskrb5_send_to_kdc { @@ -130,30 +135,36 @@ struct gsskrb5_send_to_kdc { void *ptr; }; -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gsskrb5_set_send_to_kdc(struct gsskrb5_send_to_kdc *); -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gsskrb5_set_default_realm(const char *); -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gsskrb5_extract_authtime_from_sec_context(OM_uint32 *, gss_ctx_id_t, time_t *); struct EncryptionKey; -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gsskrb5_extract_service_keyblock(OM_uint32 *minor_status, gss_ctx_id_t context_handle, struct EncryptionKey **out); -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gsskrb5_get_initiator_subkey(OM_uint32 *minor_status, gss_ctx_id_t context_handle, struct EncryptionKey **out); -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gsskrb5_get_subkey(OM_uint32 *minor_status, gss_ctx_id_t context_handle, struct EncryptionKey **out); +OM_uint32 GSSAPI_LIB_FUNCTION +gsskrb5_set_time_offset(int); + +OM_uint32 GSSAPI_LIB_FUNCTION +gsskrb5_get_time_offset(int *); + /* * Lucid - NFSv4 interface to GSS-API KRB5 to expose key material to * do GSS content token handling in-kernel. @@ -196,19 +207,19 @@ typedef struct gss_krb5_lucid_context_version { * Function declarations */ -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gss_krb5_export_lucid_sec_context(OM_uint32 *minor_status, gss_ctx_id_t *context_handle, OM_uint32 version, void **kctx); -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gss_krb5_free_lucid_sec_context(OM_uint32 *minor_status, void *kctx); -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gss_krb5_set_allowable_enctypes(OM_uint32 *minor_status, gss_cred_id_t cred, OM_uint32 num_enctypes, diff --git a/source4/heimdal/lib/gssapi/gssapi/gssapi_spnego.h b/source4/heimdal/lib/gssapi/gssapi/gssapi_spnego.h index fbb7906369..3358863a80 100644 --- a/source4/heimdal/lib/gssapi/gssapi/gssapi_spnego.h +++ b/source4/heimdal/lib/gssapi/gssapi/gssapi_spnego.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: gssapi_spnego.h 18335 2006-10-07 22:26:21Z lha $ */ +/* $Id: gssapi_spnego.h 23025 2008-04-17 10:01:57Z lha $ */ #ifndef GSSAPI_SPNEGO_H_ #define GSSAPI_SPNEGO_H_ @@ -48,7 +48,7 @@ extern "C" { * negotiation token is identified by the Object Identifier * iso.org.dod.internet.security.mechanism.snego (1.3.6.1.5.5.2). */ -extern gss_OID GSS_SPNEGO_MECHANISM; +extern GSSAPI_LIB_VARIABLE gss_OID GSS_SPNEGO_MECHANISM; #define gss_mech_spnego GSS_SPNEGO_MECHANISM #ifdef __cplusplus diff --git a/source4/heimdal/lib/gssapi/krb5/accept_sec_context.c b/source4/heimdal/lib/gssapi/krb5/accept_sec_context.c index 73b93ceba4..8dbd087da6 100644 --- a/source4/heimdal/lib/gssapi/krb5/accept_sec_context.c +++ b/source4/heimdal/lib/gssapi/krb5/accept_sec_context.c @@ -33,7 +33,7 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: accept_sec_context.c 20199 2007-02-07 22:36:39Z lha $"); +RCSID("$Id: accept_sec_context.c 23433 2008-07-26 18:44:26Z lha $"); HEIMDAL_MUTEX gssapi_keytab_mutex = HEIMDAL_MUTEX_INITIALIZER; krb5_keytab _gsskrb5_keytab; @@ -251,6 +251,62 @@ gsskrb5_acceptor_ready(OM_uint32 * minor_status, } static OM_uint32 +send_error_token(OM_uint32 *minor_status, + krb5_context context, + krb5_error_code kret, + krb5_principal server, + krb5_data *indata, + gss_buffer_t output_token) +{ + krb5_principal ap_req_server = NULL; + krb5_error_code ret; + krb5_data outbuf; + + /* build server from request if the acceptor had not selected one */ + if (server == NULL) { + AP_REQ ap_req; + + ret = krb5_decode_ap_req(context, indata, &ap_req); + if (ret) { + *minor_status = ret; + return GSS_S_FAILURE; + } + ret = _krb5_principalname2krb5_principal(context, + &ap_req_server, + ap_req.ticket.sname, + ap_req.ticket.realm); + free_AP_REQ(&ap_req); + if (ret) { + *minor_status = ret; + return GSS_S_FAILURE; + } + server = ap_req_server; + } + + ret = krb5_mk_error(context, kret, NULL, NULL, NULL, + server, NULL, NULL, &outbuf); + if (ap_req_server) + krb5_free_principal(context, ap_req_server); + if (ret) { + *minor_status = ret; + return GSS_S_FAILURE; + } + + ret = _gsskrb5_encapsulate(minor_status, + &outbuf, + output_token, + "\x03\x00", + GSS_KRB5_MECHANISM); + krb5_data_free (&outbuf); + if (ret) + return ret; + + *minor_status = 0; + return GSS_S_CONTINUE_NEEDED; +} + + +static OM_uint32 gsskrb5_acceptor_start(OM_uint32 * minor_status, gsskrb5_ctx ctx, krb5_context context, @@ -304,6 +360,10 @@ gsskrb5_acceptor_start(OM_uint32 * minor_status, { krb5_rd_req_in_ctx in = NULL; krb5_rd_req_out_ctx out = NULL; + krb5_principal server = NULL; + + if (acceptor_cred) + server = acceptor_cred->principal; kret = krb5_rd_req_in_ctx_alloc(context, &in); if (kret == 0) @@ -319,17 +379,20 @@ gsskrb5_acceptor_start(OM_uint32 * minor_status, kret = krb5_rd_req_ctx(context, &ctx->auth_context, &indata, - (acceptor_cred_handle == GSS_C_NO_CREDENTIAL) ? NULL : acceptor_cred->principal, + server, in, &out); krb5_rd_req_in_ctx_free(context, in); if (kret) { - ret = GSS_S_FAILURE; - *minor_status = kret; - return ret; + /* + * No reply in non-MUTUAL mode, but we don't know that its + * non-MUTUAL mode yet, thats inside the 8003 checksum. + */ + return send_error_token(minor_status, context, kret, + server, &indata, output_token); } /* - * We need to remember some data on the context_handle. + * we need to remember some data on the context_handle. */ kret = krb5_rd_req_out_get_ap_req_options(context, out, &ap_options); diff --git a/source4/heimdal/lib/gssapi/krb5/delete_sec_context.c b/source4/heimdal/lib/gssapi/krb5/delete_sec_context.c index abad986550..9c618ac6a6 100644 --- a/source4/heimdal/lib/gssapi/krb5/delete_sec_context.c +++ b/source4/heimdal/lib/gssapi/krb5/delete_sec_context.c @@ -33,7 +33,7 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: delete_sec_context.c 19031 2006-11-13 18:02:57Z lha $"); +RCSID("$Id: delete_sec_context.c 23420 2008-07-26 18:37:48Z lha $"); OM_uint32 _gsskrb5_delete_sec_context(OM_uint32 * minor_status, @@ -61,6 +61,8 @@ _gsskrb5_delete_sec_context(OM_uint32 * minor_status, HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex); krb5_auth_con_free (context, ctx->auth_context); + if (ctx->kcred) + krb5_free_creds(context, ctx->kcred); if(ctx->source) krb5_free_principal (context, ctx->source); if(ctx->target) diff --git a/source4/heimdal/lib/gssapi/krb5/display_status.c b/source4/heimdal/lib/gssapi/krb5/display_status.c index c0192522a7..f932261ffa 100644 --- a/source4/heimdal/lib/gssapi/krb5/display_status.c +++ b/source4/heimdal/lib/gssapi/krb5/display_status.c @@ -33,7 +33,7 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: display_status.c 19031 2006-11-13 18:02:57Z lha $"); +RCSID("$Id: display_status.c 23316 2008-06-23 04:32:32Z lha $"); static const char * calling_error(OM_uint32 v) @@ -135,7 +135,7 @@ _gsskrb5_set_status (const char *fmt, ...) vasprintf(&str, fmt, args); va_end(args); if (str) { - krb5_set_error_string(context, str); + krb5_set_error_message(context, 0, str); free(str); } } diff --git a/source4/heimdal/lib/gssapi/krb5/external.c b/source4/heimdal/lib/gssapi/krb5/external.c index 03fe61dc57..2ee018708a 100644 --- a/source4/heimdal/lib/gssapi/krb5/external.c +++ b/source4/heimdal/lib/gssapi/krb5/external.c @@ -34,7 +34,7 @@ #include "krb5/gsskrb5_locl.h" #include <gssapi_mech.h> -RCSID("$Id: external.c 22128 2007-12-04 00:56:55Z lha $"); +RCSID("$Id: external.c 23420 2008-07-26 18:37:48Z lha $"); /* * The implementation must reserve static storage for a @@ -49,9 +49,10 @@ RCSID("$Id: external.c 22128 2007-12-04 00:56:55Z lha $"); */ static gss_OID_desc gss_c_nt_user_name_oid_desc = -{10, rk_UNCONST("\x2a\x86\x48\x86\xf7\x12" "\x01\x02\x01\x01")}; + {10, rk_UNCONST("\x2a\x86\x48\x86\xf7\x12" "\x01\x02\x01\x01")}; -gss_OID GSS_C_NT_USER_NAME = &gss_c_nt_user_name_oid_desc; +gss_OID GSSAPI_LIB_VARIABLE GSS_C_NT_USER_NAME = + &gss_c_nt_user_name_oid_desc; /* * The implementation must reserve static storage for a @@ -66,9 +67,10 @@ gss_OID GSS_C_NT_USER_NAME = &gss_c_nt_user_name_oid_desc; */ static gss_OID_desc gss_c_nt_machine_uid_name_oid_desc = -{10, rk_UNCONST("\x2a\x86\x48\x86\xf7\x12" "\x01\x02\x01\x02")}; + {10, rk_UNCONST("\x2a\x86\x48\x86\xf7\x12" "\x01\x02\x01\x02")}; -gss_OID GSS_C_NT_MACHINE_UID_NAME = &gss_c_nt_machine_uid_name_oid_desc; +gss_OID GSSAPI_LIB_VARIABLE GSS_C_NT_MACHINE_UID_NAME = + &gss_c_nt_machine_uid_name_oid_desc; /* * The implementation must reserve static storage for a @@ -83,9 +85,10 @@ gss_OID GSS_C_NT_MACHINE_UID_NAME = &gss_c_nt_machine_uid_name_oid_desc; */ static gss_OID_desc gss_c_nt_string_uid_name_oid_desc = -{10, rk_UNCONST("\x2a\x86\x48\x86\xf7\x12" "\x01\x02\x01\x03")}; + {10, rk_UNCONST("\x2a\x86\x48\x86\xf7\x12" "\x01\x02\x01\x03")}; -gss_OID GSS_C_NT_STRING_UID_NAME = &gss_c_nt_string_uid_name_oid_desc; +gss_OID GSSAPI_LIB_VARIABLE GSS_C_NT_STRING_UID_NAME = + &gss_c_nt_string_uid_name_oid_desc; /* * The implementation must reserve static storage for a @@ -106,9 +109,10 @@ gss_OID GSS_C_NT_STRING_UID_NAME = &gss_c_nt_string_uid_name_oid_desc; */ static gss_OID_desc gss_c_nt_hostbased_service_x_oid_desc = -{6, rk_UNCONST("\x2b\x06\x01\x05\x06\x02")}; + {6, rk_UNCONST("\x2b\x06\x01\x05\x06\x02")}; -gss_OID GSS_C_NT_HOSTBASED_SERVICE_X = &gss_c_nt_hostbased_service_x_oid_desc; +gss_OID GSSAPI_LIB_VARIABLE GSS_C_NT_HOSTBASED_SERVICE_X = + &gss_c_nt_hostbased_service_x_oid_desc; /* * The implementation must reserve static storage for a @@ -122,9 +126,10 @@ gss_OID GSS_C_NT_HOSTBASED_SERVICE_X = &gss_c_nt_hostbased_service_x_oid_desc; * to point to that gss_OID_desc. */ static gss_OID_desc gss_c_nt_hostbased_service_oid_desc = -{10, rk_UNCONST("\x2a\x86\x48\x86\xf7\x12" "\x01\x02\x01\x04")}; + {10, rk_UNCONST("\x2a\x86\x48\x86\xf7\x12" "\x01\x02\x01\x04")}; -gss_OID GSS_C_NT_HOSTBASED_SERVICE = &gss_c_nt_hostbased_service_oid_desc; +gss_OID GSSAPI_LIB_VARIABLE GSS_C_NT_HOSTBASED_SERVICE = + &gss_c_nt_hostbased_service_oid_desc; /* * The implementation must reserve static storage for a @@ -138,9 +143,10 @@ gss_OID GSS_C_NT_HOSTBASED_SERVICE = &gss_c_nt_hostbased_service_oid_desc; */ static gss_OID_desc gss_c_nt_anonymous_oid_desc = -{6, rk_UNCONST("\x2b\x06\01\x05\x06\x03")}; + {6, rk_UNCONST("\x2b\x06\01\x05\x06\x03")}; -gss_OID GSS_C_NT_ANONYMOUS = &gss_c_nt_anonymous_oid_desc; +gss_OID GSSAPI_LIB_VARIABLE GSS_C_NT_ANONYMOUS = + &gss_c_nt_anonymous_oid_desc; /* * The implementation must reserve static storage for a @@ -154,9 +160,10 @@ gss_OID GSS_C_NT_ANONYMOUS = &gss_c_nt_anonymous_oid_desc; */ static gss_OID_desc gss_c_nt_export_name_oid_desc = -{6, rk_UNCONST("\x2b\x06\x01\x05\x06\x04") }; + {6, rk_UNCONST("\x2b\x06\x01\x05\x06\x04") }; -gss_OID GSS_C_NT_EXPORT_NAME = &gss_c_nt_export_name_oid_desc; +gss_OID GSSAPI_LIB_VARIABLE GSS_C_NT_EXPORT_NAME = + &gss_c_nt_export_name_oid_desc; /* * This name form shall be represented by the Object Identifier {iso(1) @@ -166,9 +173,10 @@ gss_OID GSS_C_NT_EXPORT_NAME = &gss_c_nt_export_name_oid_desc; */ static gss_OID_desc gss_krb5_nt_principal_name_oid_desc = -{10, rk_UNCONST("\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x01") }; + {10, rk_UNCONST("\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x01") }; -gss_OID GSS_KRB5_NT_PRINCIPAL_NAME = &gss_krb5_nt_principal_name_oid_desc; +gss_OID GSSAPI_LIB_VARIABLE GSS_KRB5_NT_PRINCIPAL_NAME = + &gss_krb5_nt_principal_name_oid_desc; /* * This name form shall be represented by the Object Identifier {iso(1) @@ -177,7 +185,8 @@ gss_OID GSS_KRB5_NT_PRINCIPAL_NAME = &gss_krb5_nt_principal_name_oid_desc; * type is "GSS_KRB5_NT_USER_NAME". */ -gss_OID GSS_KRB5_NT_USER_NAME = &gss_c_nt_user_name_oid_desc; +gss_OID GSSAPI_LIB_VARIABLE GSS_KRB5_NT_USER_NAME = + &gss_c_nt_user_name_oid_desc; /* * This name form shall be represented by the Object Identifier {iso(1) @@ -186,7 +195,8 @@ gss_OID GSS_KRB5_NT_USER_NAME = &gss_c_nt_user_name_oid_desc; * this type is "GSS_KRB5_NT_MACHINE_UID_NAME". */ -gss_OID GSS_KRB5_NT_MACHINE_UID_NAME = &gss_c_nt_machine_uid_name_oid_desc; +gss_OID GSSAPI_LIB_VARIABLE GSS_KRB5_NT_MACHINE_UID_NAME = + &gss_c_nt_machine_uid_name_oid_desc; /* * This name form shall be represented by the Object Identifier {iso(1) @@ -195,7 +205,8 @@ gss_OID GSS_KRB5_NT_MACHINE_UID_NAME = &gss_c_nt_machine_uid_name_oid_desc; * this type is "GSS_KRB5_NT_STRING_UID_NAME". */ -gss_OID GSS_KRB5_NT_STRING_UID_NAME = &gss_c_nt_string_uid_name_oid_desc; +gss_OID GSSAPI_LIB_VARIABLE GSS_KRB5_NT_STRING_UID_NAME = + &gss_c_nt_string_uid_name_oid_desc; /* * To support ongoing experimentation, testing, and evolution of the @@ -217,14 +228,15 @@ gss_OID GSS_KRB5_NT_STRING_UID_NAME = &gss_c_nt_string_uid_name_oid_desc; #if 0 /* This is the old OID */ static gss_OID_desc gss_krb5_mechanism_oid_desc = -{5, rk_UNCONST("\x2b\x05\x01\x05\x02")}; + {5, rk_UNCONST("\x2b\x05\x01\x05\x02")}; #endif static gss_OID_desc gss_krb5_mechanism_oid_desc = -{9, rk_UNCONST("\x2a\x86\x48\x86\xf7\x12\x01\x02\x02") }; + {9, rk_UNCONST("\x2a\x86\x48\x86\xf7\x12\x01\x02\x02") }; -gss_OID GSS_KRB5_MECHANISM = &gss_krb5_mechanism_oid_desc; +gss_OID GSSAPI_LIB_VARIABLE GSS_KRB5_MECHANISM = + &gss_krb5_mechanism_oid_desc; /* * draft-ietf-cat-iakerb-09, IAKERB: @@ -240,23 +252,26 @@ gss_OID GSS_KRB5_MECHANISM = &gss_krb5_mechanism_oid_desc; */ static gss_OID_desc gss_iakerb_proxy_mechanism_oid_desc = -{7, rk_UNCONST("\x2b\x06\x01\x05\x05\x0a\x01")}; + {7, rk_UNCONST("\x2b\x06\x01\x05\x05\x0a\x01")}; -gss_OID GSS_IAKERB_PROXY_MECHANISM = &gss_iakerb_proxy_mechanism_oid_desc; +gss_OID GSSAPI_LIB_VARIABLE GSS_IAKERB_PROXY_MECHANISM = + &gss_iakerb_proxy_mechanism_oid_desc; static gss_OID_desc gss_iakerb_min_msg_mechanism_oid_desc = -{7, rk_UNCONST("\x2b\x06\x01\x05\x05\x0a\x02") }; + {7, rk_UNCONST("\x2b\x06\x01\x05\x05\x0a\x02") }; -gss_OID GSS_IAKERB_MIN_MSG_MECHANISM = &gss_iakerb_min_msg_mechanism_oid_desc; +gss_OID GSSAPI_LIB_VARIABLE GSS_IAKERB_MIN_MSG_MECHANISM = + &gss_iakerb_min_msg_mechanism_oid_desc; /* * */ static gss_OID_desc gss_c_peer_has_updated_spnego_oid_desc = -{9, (void *)"\x2b\x06\x01\x04\x01\xa9\x4a\x13\x05"}; + {9, (void *)"\x2b\x06\x01\x04\x01\xa9\x4a\x13\x05"}; -gss_OID GSS_C_PEER_HAS_UPDATED_SPNEGO = &gss_c_peer_has_updated_spnego_oid_desc; +gss_OID GSSAPI_LIB_VARIABLE GSS_C_PEER_HAS_UPDATED_SPNEGO = + &gss_c_peer_has_updated_spnego_oid_desc; /* * 1.2.752.43.13 Heimdal GSS-API Extentions @@ -264,111 +279,143 @@ gss_OID GSS_C_PEER_HAS_UPDATED_SPNEGO = &gss_c_peer_has_updated_spnego_oid_desc; /* 1.2.752.43.13.1 */ static gss_OID_desc gss_krb5_copy_ccache_x_oid_desc = -{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x01")}; + {6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x01")}; -gss_OID GSS_KRB5_COPY_CCACHE_X = &gss_krb5_copy_ccache_x_oid_desc; +gss_OID GSSAPI_LIB_VARIABLE GSS_KRB5_COPY_CCACHE_X = + &gss_krb5_copy_ccache_x_oid_desc; /* 1.2.752.43.13.2 */ static gss_OID_desc gss_krb5_get_tkt_flags_x_oid_desc = -{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x02")}; + {6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x02")}; -gss_OID GSS_KRB5_GET_TKT_FLAGS_X = &gss_krb5_get_tkt_flags_x_oid_desc; +gss_OID GSSAPI_LIB_VARIABLE GSS_KRB5_GET_TKT_FLAGS_X = + &gss_krb5_get_tkt_flags_x_oid_desc; /* 1.2.752.43.13.3 */ static gss_OID_desc gss_krb5_extract_authz_data_from_sec_context_x_oid_desc = -{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x03")}; + {6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x03")}; -gss_OID GSS_KRB5_EXTRACT_AUTHZ_DATA_FROM_SEC_CONTEXT_X = &gss_krb5_extract_authz_data_from_sec_context_x_oid_desc; +gss_OID GSSAPI_LIB_VARIABLE GSS_KRB5_EXTRACT_AUTHZ_DATA_FROM_SEC_CONTEXT_X = + &gss_krb5_extract_authz_data_from_sec_context_x_oid_desc; /* 1.2.752.43.13.4 */ static gss_OID_desc gss_krb5_compat_des3_mic_x_oid_desc = -{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x04")}; + {6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x04")}; -gss_OID GSS_KRB5_COMPAT_DES3_MIC_X = &gss_krb5_compat_des3_mic_x_oid_desc; +gss_OID GSSAPI_LIB_VARIABLE GSS_KRB5_COMPAT_DES3_MIC_X = + &gss_krb5_compat_des3_mic_x_oid_desc; /* 1.2.752.43.13.5 */ static gss_OID_desc gss_krb5_register_acceptor_identity_x_desc = -{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x05")}; + {6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x05")}; -gss_OID GSS_KRB5_REGISTER_ACCEPTOR_IDENTITY_X = &gss_krb5_register_acceptor_identity_x_desc; +gss_OID GSSAPI_LIB_VARIABLE GSS_KRB5_REGISTER_ACCEPTOR_IDENTITY_X = + &gss_krb5_register_acceptor_identity_x_desc; /* 1.2.752.43.13.6 */ static gss_OID_desc gss_krb5_export_lucid_context_x_desc = -{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x06")}; + {6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x06")}; -gss_OID GSS_KRB5_EXPORT_LUCID_CONTEXT_X = &gss_krb5_export_lucid_context_x_desc; +gss_OID GSSAPI_LIB_VARIABLE GSS_KRB5_EXPORT_LUCID_CONTEXT_X = + &gss_krb5_export_lucid_context_x_desc; /* 1.2.752.43.13.6.1 */ static gss_OID_desc gss_krb5_export_lucid_context_v1_x_desc = -{7, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x06\x01")}; + {7, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x06\x01")}; -gss_OID GSS_KRB5_EXPORT_LUCID_CONTEXT_V1_X = &gss_krb5_export_lucid_context_v1_x_desc; +gss_OID GSSAPI_LIB_VARIABLE GSS_KRB5_EXPORT_LUCID_CONTEXT_V1_X = + &gss_krb5_export_lucid_context_v1_x_desc; /* 1.2.752.43.13.7 */ static gss_OID_desc gss_krb5_set_dns_canonicalize_x_desc = -{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x07")}; + {6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x07")}; -gss_OID GSS_KRB5_SET_DNS_CANONICALIZE_X = &gss_krb5_set_dns_canonicalize_x_desc; +gss_OID GSSAPI_LIB_VARIABLE GSS_KRB5_SET_DNS_CANONICALIZE_X = + &gss_krb5_set_dns_canonicalize_x_desc; /* 1.2.752.43.13.8 */ static gss_OID_desc gss_krb5_get_subkey_x_desc = -{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x08")}; + {6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x08")}; -gss_OID GSS_KRB5_GET_SUBKEY_X = &gss_krb5_get_subkey_x_desc; +gss_OID GSSAPI_LIB_VARIABLE GSS_KRB5_GET_SUBKEY_X = + &gss_krb5_get_subkey_x_desc; /* 1.2.752.43.13.9 */ static gss_OID_desc gss_krb5_get_initiator_subkey_x_desc = -{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x09")}; + {6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x09")}; -gss_OID GSS_KRB5_GET_INITIATOR_SUBKEY_X = &gss_krb5_get_initiator_subkey_x_desc; +gss_OID GSSAPI_LIB_VARIABLE GSS_KRB5_GET_INITIATOR_SUBKEY_X = + &gss_krb5_get_initiator_subkey_x_desc; /* 1.2.752.43.13.10 */ static gss_OID_desc gss_krb5_get_acceptor_subkey_x_desc = -{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x0a")}; + {6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x0a")}; -gss_OID GSS_KRB5_GET_ACCEPTOR_SUBKEY_X = &gss_krb5_get_acceptor_subkey_x_desc; +gss_OID GSSAPI_LIB_VARIABLE GSS_KRB5_GET_ACCEPTOR_SUBKEY_X = + &gss_krb5_get_acceptor_subkey_x_desc; /* 1.2.752.43.13.11 */ static gss_OID_desc gss_krb5_send_to_kdc_x_desc = -{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x0b")}; + {6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x0b")}; -gss_OID GSS_KRB5_SEND_TO_KDC_X = &gss_krb5_send_to_kdc_x_desc; +gss_OID GSSAPI_LIB_VARIABLE GSS_KRB5_SEND_TO_KDC_X = + &gss_krb5_send_to_kdc_x_desc; /* 1.2.752.43.13.12 */ static gss_OID_desc gss_krb5_get_authtime_x_desc = -{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x0c")}; + {6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x0c")}; -gss_OID GSS_KRB5_GET_AUTHTIME_X = &gss_krb5_get_authtime_x_desc; +gss_OID GSSAPI_LIB_VARIABLE GSS_KRB5_GET_AUTHTIME_X = + &gss_krb5_get_authtime_x_desc; /* 1.2.752.43.13.13 */ static gss_OID_desc gss_krb5_get_service_keyblock_x_desc = -{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x0d")}; + {6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x0d")}; -gss_OID GSS_KRB5_GET_SERVICE_KEYBLOCK_X = &gss_krb5_get_service_keyblock_x_desc; +gss_OID GSSAPI_LIB_VARIABLE GSS_KRB5_GET_SERVICE_KEYBLOCK_X = + &gss_krb5_get_service_keyblock_x_desc; /* 1.2.752.43.13.14 */ static gss_OID_desc gss_krb5_set_allowable_enctypes_x_desc = -{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x0e")}; + {6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x0e")}; -gss_OID GSS_KRB5_SET_ALLOWABLE_ENCTYPES_X = &gss_krb5_set_allowable_enctypes_x_desc; +gss_OID GSSAPI_LIB_VARIABLE GSS_KRB5_SET_ALLOWABLE_ENCTYPES_X = + &gss_krb5_set_allowable_enctypes_x_desc; /* 1.2.752.43.13.15 */ static gss_OID_desc gss_krb5_set_default_realm_x_desc = -{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x0f")}; + {6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x0f")}; -gss_OID GSS_KRB5_SET_DEFAULT_REALM_X = &gss_krb5_set_default_realm_x_desc; +gss_OID GSSAPI_LIB_VARIABLE GSS_KRB5_SET_DEFAULT_REALM_X = + &gss_krb5_set_default_realm_x_desc; /* 1.2.752.43.13.16 */ static gss_OID_desc gss_krb5_ccache_name_x_desc = -{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x10")}; + {6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x10")}; -gss_OID GSS_KRB5_CCACHE_NAME_X = &gss_krb5_ccache_name_x_desc; +gss_OID GSSAPI_LIB_VARIABLE GSS_KRB5_CCACHE_NAME_X = + &gss_krb5_ccache_name_x_desc; + +/* 1.2.752.43.13.17 */ +static gss_OID_desc gss_krb5_set_time_offset_x_desc = + {6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x11")}; + +gss_OID GSSAPI_LIB_VARIABLE GSS_KRB5_SET_TIME_OFFSET_X = + &gss_krb5_set_time_offset_x_desc; + +/* 1.2.752.43.13.18 */ +static gss_OID_desc gss_krb5_get_time_offset_x_desc = + {6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x12")}; + +gss_OID GSSAPI_LIB_VARIABLE GSS_KRB5_GET_TIME_OFFSET_X = + &gss_krb5_get_time_offset_x_desc; /* 1.2.752.43.14.1 */ static gss_OID_desc gss_sasl_digest_md5_mechanism_desc = -{6, rk_UNCONST("\x2a\x85\x70\x2b\x0e\x01") }; + {6, rk_UNCONST("\x2a\x85\x70\x2b\x0e\x01") }; -gss_OID GSS_SASL_DIGEST_MD5_MECHANISM = &gss_sasl_digest_md5_mechanism_desc; +gss_OID GSSAPI_LIB_VARIABLE GSS_SASL_DIGEST_MD5_MECHANISM = + &gss_sasl_digest_md5_mechanism_desc; /* * Context for krb5 calls. diff --git a/source4/heimdal/lib/gssapi/krb5/get_mic.c b/source4/heimdal/lib/gssapi/krb5/get_mic.c index 133481ffe1..f689e624a8 100644 --- a/source4/heimdal/lib/gssapi/krb5/get_mic.c +++ b/source4/heimdal/lib/gssapi/krb5/get_mic.c @@ -33,7 +33,7 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: get_mic.c 19031 2006-11-13 18:02:57Z lha $"); +RCSID("$Id: get_mic.c 23112 2008-04-27 18:51:26Z lha $"); static OM_uint32 mic_des @@ -88,7 +88,7 @@ mic_des memset (&zero, 0, sizeof(zero)); memcpy (&deskey, key->keyvalue.data, sizeof(deskey)); - DES_set_key (&deskey, &schedule); + DES_set_key_unchecked (&deskey, &schedule); DES_cbc_cksum ((void *)hash, (void *)hash, sizeof(hash), &schedule, &zero); memcpy (p - 8, hash, 8); /* SGN_CKSUM */ @@ -108,7 +108,7 @@ mic_des (ctx->more_flags & LOCAL) ? 0 : 0xFF, 4); - DES_set_key (&deskey, &schedule); + DES_set_key_unchecked (&deskey, &schedule); DES_cbc_encrypt ((void *)p, (void *)p, 8, &schedule, (DES_cblock *)(p + 8), DES_ENCRYPT); diff --git a/source4/heimdal/lib/gssapi/krb5/gsskrb5_locl.h b/source4/heimdal/lib/gssapi/krb5/gsskrb5_locl.h index 3e8c1b8fa6..d9af44f960 100644 --- a/source4/heimdal/lib/gssapi/krb5/gsskrb5_locl.h +++ b/source4/heimdal/lib/gssapi/krb5/gsskrb5_locl.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997 - 2006 Kungliga Tekniska Högskolan + * Copyright (c) 1997 - 2008 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: gsskrb5_locl.h 22655 2008-02-26 12:40:35Z lha $ */ +/* $Id: gsskrb5_locl.h 23435 2008-07-26 20:49:35Z lha $ */ #ifndef GSSKRB5_LOCL_H #define GSSKRB5_LOCL_H @@ -62,11 +62,14 @@ typedef struct { enum { LOCAL = 1, OPEN = 2, COMPAT_OLD_DES3 = 4, COMPAT_OLD_DES3_SELECTED = 8, - ACCEPTOR_SUBKEY = 16 + ACCEPTOR_SUBKEY = 16, + RETRIED = 32, + CLOSE_CCACHE = 64 } more_flags; enum gss_ctx_id_t_state { /* initiator states */ INITIATOR_START, + INITIATOR_RESTART, INITIATOR_WAIT_FOR_MUTAL, INITIATOR_READY, /* acceptor states */ @@ -74,6 +77,8 @@ typedef struct { ACCEPTOR_WAIT_FOR_DCESTYLE, ACCEPTOR_READY } state; + krb5_creds *kcred; + krb5_ccache ccache; struct krb5_ticket *ticket; OM_uint32 lifetime; HEIMDAL_MUTEX ctx_id_mutex; diff --git a/source4/heimdal/lib/gssapi/krb5/import_sec_context.c b/source4/heimdal/lib/gssapi/krb5/import_sec_context.c index 3300036a81..5fd8c94104 100644 --- a/source4/heimdal/lib/gssapi/krb5/import_sec_context.c +++ b/source4/heimdal/lib/gssapi/krb5/import_sec_context.c @@ -33,7 +33,7 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: import_sec_context.c 19031 2006-11-13 18:02:57Z lha $"); +RCSID("$Id: import_sec_context.c 22997 2008-04-15 19:36:25Z lha $"); OM_uint32 _gsskrb5_import_sec_context ( @@ -52,8 +52,7 @@ _gsskrb5_import_sec_context ( krb5_data data; gss_buffer_desc buffer; krb5_keyblock keyblock; - int32_t tmp; - int32_t flags; + int32_t flags, tmp; gsskrb5_ctx ctx; gss_name_t name; @@ -96,8 +95,9 @@ _gsskrb5_import_sec_context ( /* retrieve the auth context */ ac = ctx->auth_context; - if (krb5_ret_uint32 (sp, &ac->flags) != 0) + if (krb5_ret_int32 (sp, &tmp) != 0) goto failure; + ac->flags = tmp; if (flags & SC_LOCAL_ADDRESS) { if (krb5_ret_address (sp, localp = &local) != 0) goto failure; diff --git a/source4/heimdal/lib/gssapi/krb5/init_sec_context.c b/source4/heimdal/lib/gssapi/krb5/init_sec_context.c index c455a5dc8b..c9b9e15588 100644 --- a/source4/heimdal/lib/gssapi/krb5/init_sec_context.c +++ b/source4/heimdal/lib/gssapi/krb5/init_sec_context.c @@ -33,7 +33,7 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: init_sec_context.c 22671 2008-03-09 23:57:54Z lha $"); +RCSID("$Id: init_sec_context.c 23422 2008-07-26 18:38:29Z lha $"); /* * copy the addresses from `input_chan_bindings' (if any) to @@ -121,6 +121,8 @@ _gsskrb5_create_ctx( ctx->auth_context = NULL; ctx->source = NULL; ctx->target = NULL; + ctx->kcred = NULL; + ctx->ccache = NULL; ctx->state = state; ctx->flags = 0; ctx->more_flags = 0; @@ -134,9 +136,7 @@ _gsskrb5_create_ctx( kret = krb5_auth_con_init (context, &ctx->auth_context); if (kret) { *minor_status = kret; - HEIMDAL_MUTEX_destroy(&ctx->ctx_id_mutex); - return GSS_S_FAILURE; } @@ -232,27 +232,32 @@ gsskrb5_initiator_ready( gsskrb5_ctx ctx, krb5_context context) { - OM_uint32 ret; - int32_t seq_number; - int is_cfx = 0; - OM_uint32 flags = ctx->flags; - - krb5_auth_getremoteseqnumber (context, - ctx->auth_context, - &seq_number); - - _gsskrb5i_is_cfx(ctx, &is_cfx); - - ret = _gssapi_msg_order_create(minor_status, - &ctx->order, - _gssapi_msg_order_f(flags), - seq_number, 0, is_cfx); - if (ret) return ret; + OM_uint32 ret; + int32_t seq_number; + int is_cfx = 0; + OM_uint32 flags = ctx->flags; + + krb5_free_creds(context, ctx->kcred); + ctx->kcred = NULL; - ctx->state = INITIATOR_READY; - ctx->more_flags |= OPEN; + if (ctx->more_flags & CLOSE_CCACHE) + krb5_cc_close(context, ctx->ccache); + ctx->ccache = NULL; - return GSS_S_COMPLETE; + krb5_auth_getremoteseqnumber (context, ctx->auth_context, &seq_number); + + _gsskrb5i_is_cfx(ctx, &is_cfx); + + ret = _gssapi_msg_order_create(minor_status, + &ctx->order, + _gssapi_msg_order_f(flags), + seq_number, 0, is_cfx); + if (ret) return ret; + + ctx->state = INITIATOR_READY; + ctx->more_flags |= OPEN; + + return GSS_S_COMPLETE; } /* @@ -333,7 +338,6 @@ init_auth const gss_OID mech_type, OM_uint32 req_flags, OM_uint32 time_req, - const gss_channel_bindings_t input_chan_bindings, const gss_buffer_t input_token, gss_OID * actual_mech_type, gss_buffer_t output_token, @@ -343,14 +347,7 @@ init_auth { OM_uint32 ret = GSS_S_FAILURE; krb5_error_code kret; - krb5_flags ap_options; - krb5_creds *kcred = NULL; krb5_data outbuf; - krb5_ccache ccache = NULL; - uint32_t flags; - krb5_data authenticator; - Checksum cksum; - krb5_enctype enctype; krb5_data fwd_data; OM_uint32 lifetime_rec; @@ -363,16 +360,17 @@ init_auth *actual_mech_type = GSS_KRB5_MECHANISM; if (cred == NULL) { - kret = krb5_cc_default (context, &ccache); + kret = krb5_cc_default (context, &ctx->ccache); if (kret) { *minor_status = kret; ret = GSS_S_FAILURE; goto failure; } + ctx->more_flags |= CLOSE_CCACHE; } else - ccache = cred->ccache; + ctx->ccache = cred->ccache; - kret = krb5_cc_get_principal (context, ccache, &ctx->source); + kret = krb5_cc_get_principal (context, ctx->ccache, &ctx->source); if (kret) { *minor_status = kret; ret = GSS_S_FAILURE; @@ -407,16 +405,16 @@ init_auth ret = gsskrb5_get_creds(minor_status, context, - ccache, + ctx->ccache, ctx, ctx->target, time_req, time_rec, - &kcred); + &ctx->kcred); if (ret) goto failure; - ctx->lifetime = kcred->times.endtime; + ctx->lifetime = ctx->kcred->times.endtime; ret = _gsskrb5_lifetime_left(minor_status, context, @@ -434,17 +432,59 @@ init_auth krb5_auth_con_setkey(context, ctx->auth_context, - &kcred->session); + &ctx->kcred->session); kret = krb5_auth_con_generatelocalsubkey(context, ctx->auth_context, - &kcred->session); + &ctx->kcred->session); if(kret) { *minor_status = kret; ret = GSS_S_FAILURE; goto failure; } - + + return GSS_S_COMPLETE; + +failure: + if (ctx->ccache && (ctx->more_flags & CLOSE_CCACHE)) + krb5_cc_close(context, ctx->ccache); + ctx->ccache = NULL; + + return ret; + +} + +static OM_uint32 +init_auth_restart +(OM_uint32 * minor_status, + gsskrb5_cred cred, + gsskrb5_ctx ctx, + krb5_context context, + OM_uint32 req_flags, + const gss_channel_bindings_t input_chan_bindings, + const gss_buffer_t input_token, + gss_OID * actual_mech_type, + gss_buffer_t output_token, + OM_uint32 * ret_flags, + OM_uint32 * time_rec + ) +{ + OM_uint32 ret = GSS_S_FAILURE; + krb5_error_code kret; + krb5_flags ap_options; + krb5_data outbuf; + uint32_t flags; + krb5_data authenticator; + Checksum cksum; + krb5_enctype enctype; + krb5_data fwd_data, timedata; + int32_t offset = 0, oldoffset; + + krb5_data_zero(&outbuf); + krb5_data_zero(&fwd_data); + + *minor_status = 0; + /* * If the credential doesn't have ok-as-delegate, check what local * policy say about ok-as-delegate, default is FALSE that makes @@ -452,12 +492,24 @@ init_auth * requested. If it is TRUE, strip of the GSS_C_DELEG_FLAG if the * KDC doesn't set ok-as-delegate. */ - if (!kcred->flags.b.ok_as_delegate) { - krb5_boolean delegate; + if (!ctx->kcred->flags.b.ok_as_delegate) { + krb5_boolean delegate, realm_setting; + krb5_data data; - krb5_appdefault_boolean(context, - "gssapi", name->realm, - "ok-as-delegate", FALSE, &delegate); + realm_setting = FALSE; + + ret = krb5_cc_get_config(context, ctx->ccache, NULL, + "realm-config", &data); + if (ret == 0) { + /* XXX 1 is use ok-as-delegate */ + if (data.length > 0 && (((unsigned char *)data.data)[0]) & 1) + realm_setting = TRUE; + krb5_data_free(&data); + } + + krb5_appdefault_boolean(context, "gssapi", ctx->target->realm, + "ok-as-delegate", realm_setting, + &delegate); if (delegate) req_flags &= ~GSS_C_DELEG_FLAG; } @@ -467,7 +519,8 @@ init_auth if (req_flags & GSS_C_DELEG_FLAG) do_delegation (context, ctx->auth_context, - ccache, kcred, name, &fwd_data, &flags); + ctx->ccache, ctx->kcred, ctx->target, + &fwd_data, &flags); if (req_flags & GSS_C_MUTUAL_FLAG) { flags |= GSS_C_MUTUAL_FLAG; @@ -518,16 +571,33 @@ init_auth enctype = ctx->auth_context->keyblock->keytype; + ret = krb5_cc_get_config(context, ctx->ccache, ctx->target, + "time-offset", &timedata); + if (ret == 0) { + if (timedata.length == 4) { + const u_char *p = timedata.data; + offset = (p[0] <<24) | (p[1] << 16) | (p[2] << 8) | (p[3] << 0); + } + krb5_data_free(&timedata); + } + + if (offset) { + krb5_get_kdc_sec_offset (context, &oldoffset, NULL); + krb5_set_kdc_sec_offset (context, offset, -1); + } + kret = krb5_build_authenticator (context, ctx->auth_context, enctype, - kcred, + ctx->kcred, &cksum, NULL, &authenticator, KRB5_KU_AP_REQ_AUTH); if (kret) { + if (offset) + krb5_set_kdc_sec_offset (context, oldoffset, -1); *minor_status = kret; ret = GSS_S_FAILURE; goto failure; @@ -535,11 +605,12 @@ init_auth kret = krb5_build_ap_req (context, enctype, - kcred, + ctx->kcred, ap_options, authenticator, &outbuf); - + if (offset) + krb5_set_kdc_sec_offset (context, oldoffset, -1); if (kret) { *minor_status = kret; ret = GSS_S_FAILURE; @@ -552,16 +623,12 @@ init_auth } else { ret = _gsskrb5_encapsulate (minor_status, &outbuf, output_token, (u_char *)"\x01\x00", GSS_KRB5_MECHANISM); + krb5_data_free (&outbuf); if (ret) goto failure; - - krb5_data_free (&outbuf); } - krb5_free_creds(context, kcred); free_Checksum(&cksum); - if (cred == NULL) - krb5_cc_close(context, ccache); if (flags & GSS_C_MUTUAL_FLAG) { ctx->state = INITIATOR_WAIT_FOR_MUTAL; @@ -570,15 +637,14 @@ init_auth return gsskrb5_initiator_ready(minor_status, ctx, context); failure: - if(kcred) - krb5_free_creds(context, kcred); - if (ccache && cred == NULL) - krb5_cc_close(context, ccache); + if (ctx->ccache && (ctx->more_flags & CLOSE_CCACHE)) + krb5_cc_close(context, ctx->ccache); + ctx->ccache = NULL; return ret; - } + static OM_uint32 repl_mutual (OM_uint32 * minor_status, @@ -617,8 +683,46 @@ repl_mutual &indata, "\x02\x00", GSS_KRB5_MECHANISM); - if (ret) { - /* XXX - Handle AP_ERROR */ + if (ret == GSS_S_DEFECTIVE_TOKEN) { + /* check if there is an error token sent instead */ + ret = _gsskrb5_decapsulate (minor_status, + input_token, + &indata, + "\x03\x00", + GSS_KRB5_MECHANISM); + if (ret == GSS_S_COMPLETE) { + KRB_ERROR error; + + kret = krb5_rd_error(context, &indata, &error); + if (kret == 0) { + kret = krb5_error_from_rd_error(context, &error, NULL); + + /* save the time skrew for this host */ + if (kret == KRB5KRB_AP_ERR_SKEW) { + krb5_data timedata; + unsigned char p[4]; + int32_t t = error.stime - time(NULL); + + p[0] = (t >> 24) & 0xFF; + p[1] = (t >> 16) & 0xFF; + p[2] = (t >> 8) & 0xFF; + p[3] = (t >> 0) & 0xFF; + + timedata.data = p; + timedata.length = sizeof(p); + + krb5_cc_set_config(context, ctx->ccache, ctx->target, + "time-offset", &timedata); + + if ((ctx->more_flags & RETRIED) == 0) + ctx->state = INITIATOR_RESTART; + ctx->more_flags |= RETRIED; + } + free_KRB_ERROR (&error); + } + *minor_status = kret; + return GSS_S_FAILURE; + } return ret; } } @@ -661,30 +765,31 @@ repl_mutual *ret_flags = ctx->flags; if (req_flags & GSS_C_DCE_STYLE) { - int32_t con_flags; + int32_t local_seq, remote_seq; krb5_data outbuf; - /* Do don't do sequence number for the mk-rep */ - krb5_auth_con_removeflags(context, - ctx->auth_context, - KRB5_AUTH_CONTEXT_DO_SEQUENCE, - &con_flags); + /* + * So DCE_STYLE is strange. The client echos the seq number + * that the server used in the server's mk_rep in its own + * mk_rep(). After when done, it resets to it's own seq number + * for the gss_wrap calls. + */ - kret = krb5_mk_rep(context, - ctx->auth_context, - &outbuf); + krb5_auth_getremoteseqnumber(context, ctx->auth_context, &remote_seq); + krb5_auth_con_getlocalseqnumber(context, ctx->auth_context, &local_seq); + krb5_auth_con_setlocalseqnumber(context, ctx->auth_context, remote_seq); + + kret = krb5_mk_rep(context, ctx->auth_context, &outbuf); if (kret) { *minor_status = kret; return GSS_S_FAILURE; } + /* reset local seq number */ + krb5_auth_con_setlocalseqnumber(context, ctx->auth_context, local_seq); + output_token->length = outbuf.length; output_token->value = outbuf.data; - - krb5_auth_con_removeflags(context, - ctx->auth_context, - KRB5_AUTH_CONTEXT_DO_SEQUENCE, - NULL); } return gsskrb5_initiator_ready(minor_status, ctx, context); @@ -768,6 +873,7 @@ OM_uint32 _gsskrb5_init_sec_context HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex); + again: switch (ctx->state) { case INITIATOR_START: ret = init_auth(minor_status, @@ -778,12 +884,26 @@ OM_uint32 _gsskrb5_init_sec_context mech_type, req_flags, time_req, - input_chan_bindings, input_token, actual_mech_type, output_token, ret_flags, time_rec); + if (ret != GSS_S_COMPLETE) + break; + /* FALL THOUGH */ + case INITIATOR_RESTART: + ret = init_auth_restart(minor_status, + cred, + ctx, + context, + req_flags, + input_chan_bindings, + input_token, + actual_mech_type, + output_token, + ret_flags, + time_rec); break; case INITIATOR_WAIT_FOR_MUTAL: ret = repl_mutual(minor_status, @@ -798,6 +918,8 @@ OM_uint32 _gsskrb5_init_sec_context output_token, ret_flags, time_rec); + if (ctx->state == INITIATOR_RESTART) + goto again; break; case INITIATOR_READY: /* diff --git a/source4/heimdal/lib/gssapi/krb5/set_cred_option.c b/source4/heimdal/lib/gssapi/krb5/set_cred_option.c index 85b50d0322..8c554fb8e0 100644 --- a/source4/heimdal/lib/gssapi/krb5/set_cred_option.c +++ b/source4/heimdal/lib/gssapi/krb5/set_cred_option.c @@ -32,7 +32,7 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: set_cred_option.c 22655 2008-02-26 12:40:35Z lha $"); +RCSID("$Id: set_cred_option.c 23331 2008-06-27 12:01:48Z lha $"); /* 1.2.752.43.13.17 */ static gss_OID_desc gss_krb5_cred_no_ci_flags_x_oid_desc = diff --git a/source4/heimdal/lib/gssapi/krb5/set_sec_context_option.c b/source4/heimdal/lib/gssapi/krb5/set_sec_context_option.c index 50441a11ad..fd76838af5 100644 --- a/source4/heimdal/lib/gssapi/krb5/set_sec_context_option.c +++ b/source4/heimdal/lib/gssapi/krb5/set_sec_context_option.c @@ -36,7 +36,7 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: set_sec_context_option.c 20384 2007-04-18 08:51:06Z lha $"); +RCSID("$Id: set_sec_context_option.c 23420 2008-07-26 18:37:48Z lha $"); static OM_uint32 get_bool(OM_uint32 *minor_status, @@ -70,6 +70,36 @@ get_string(OM_uint32 *minor_status, return GSS_S_COMPLETE; } +static OM_uint32 +get_int32(OM_uint32 *minor_status, + const gss_buffer_t value, + OM_uint32 *ret) +{ + *minor_status = 0; + if (value == NULL || value->length == 0) + *ret = 0; + else if (value->length == sizeof(*ret)) + memcpy(ret, value->value, sizeof(*ret)); + else + return GSS_S_UNAVAILABLE; + + return GSS_S_COMPLETE; +} + +static OM_uint32 +set_int32(OM_uint32 *minor_status, + const gss_buffer_t value, + OM_uint32 set) +{ + *minor_status = 0; + if (value->length == sizeof(set)) + memcpy(value->value, &set, sizeof(set)); + else + return GSS_S_UNAVAILABLE; + + return GSS_S_COMPLETE; +} + OM_uint32 _gsskrb5_set_sec_context_option (OM_uint32 *minor_status, @@ -185,6 +215,35 @@ _gsskrb5_set_sec_context_option return GSS_S_FAILURE; return GSS_S_COMPLETE; + } else if (gss_oid_equal(desired_object, GSS_KRB5_SET_TIME_OFFSET_X)) { + OM_uint32 offset; + time_t t; + + maj_stat = get_int32(minor_status, value, &offset); + if (maj_stat != GSS_S_COMPLETE) + return maj_stat; + + t = time(NULL) + offset; + + krb5_set_real_time(context, t, 0); + + *minor_status = 0; + return GSS_S_COMPLETE; + } else if (gss_oid_equal(desired_object, GSS_KRB5_GET_TIME_OFFSET_X)) { + krb5_timestamp sec; + int32_t usec; + time_t t; + + t = time(NULL); + + krb5_us_timeofday (context, &sec, &usec); + + maj_stat = set_int32(minor_status, value, sec - t); + if (maj_stat != GSS_S_COMPLETE) + return maj_stat; + + *minor_status = 0; + return GSS_S_COMPLETE; } *minor_status = EINVAL; diff --git a/source4/heimdal/lib/gssapi/krb5/unwrap.c b/source4/heimdal/lib/gssapi/krb5/unwrap.c index d0a33d86fb..eec4078a70 100644 --- a/source4/heimdal/lib/gssapi/krb5/unwrap.c +++ b/source4/heimdal/lib/gssapi/krb5/unwrap.c @@ -33,7 +33,7 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: unwrap.c 19031 2006-11-13 18:02:57Z lha $"); +RCSID("$Id: unwrap.c 23112 2008-04-27 18:51:26Z lha $"); static OM_uint32 unwrap_des @@ -93,7 +93,7 @@ unwrap_des for (i = 0; i < sizeof(deskey); ++i) deskey[i] ^= 0xf0; - DES_set_key (&deskey, &schedule); + DES_set_key_unchecked (&deskey, &schedule); memset (&zero, 0, sizeof(zero)); DES_cbc_encrypt ((void *)p, (void *)p, @@ -119,7 +119,7 @@ unwrap_des memset (&zero, 0, sizeof(zero)); memcpy (&deskey, key->keyvalue.data, sizeof(deskey)); - DES_set_key (&deskey, &schedule); + DES_set_key_unchecked (&deskey, &schedule); DES_cbc_cksum ((void *)hash, (void *)hash, sizeof(hash), &schedule, &zero); if (memcmp (p - 8, hash, 8) != 0) @@ -130,7 +130,7 @@ unwrap_des HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); p -= 16; - DES_set_key (&deskey, &schedule); + DES_set_key_unchecked (&deskey, &schedule); DES_cbc_encrypt ((void *)p, (void *)p, 8, &schedule, (DES_cblock *)hash, DES_DECRYPT); diff --git a/source4/heimdal/lib/gssapi/krb5/verify_mic.c b/source4/heimdal/lib/gssapi/krb5/verify_mic.c index 52381afcc2..560c14bc89 100644 --- a/source4/heimdal/lib/gssapi/krb5/verify_mic.c +++ b/source4/heimdal/lib/gssapi/krb5/verify_mic.c @@ -33,7 +33,7 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: verify_mic.c 19031 2006-11-13 18:02:57Z lha $"); +RCSID("$Id: verify_mic.c 23112 2008-04-27 18:51:26Z lha $"); static OM_uint32 verify_mic_des @@ -83,7 +83,7 @@ verify_mic_des memset (&zero, 0, sizeof(zero)); memcpy (&deskey, key->keyvalue.data, sizeof(deskey)); - DES_set_key (&deskey, &schedule); + DES_set_key_unchecked (&deskey, &schedule); DES_cbc_cksum ((void *)hash, (void *)hash, sizeof(hash), &schedule, &zero); if (memcmp (p - 8, hash, 8) != 0) { @@ -97,7 +97,7 @@ verify_mic_des HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); p -= 16; - DES_set_key (&deskey, &schedule); + DES_set_key_unchecked (&deskey, &schedule); DES_cbc_encrypt ((void *)p, (void *)p, 8, &schedule, (DES_cblock *)hash, DES_DECRYPT); diff --git a/source4/heimdal/lib/gssapi/krb5/wrap.c b/source4/heimdal/lib/gssapi/krb5/wrap.c index d41379870a..6d00f2adcf 100644 --- a/source4/heimdal/lib/gssapi/krb5/wrap.c +++ b/source4/heimdal/lib/gssapi/krb5/wrap.c @@ -33,7 +33,7 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: wrap.c 19035 2006-11-14 09:49:56Z lha $"); +RCSID("$Id: wrap.c 23316 2008-06-23 04:32:32Z lha $"); /* * Return initiator subkey, or if that doesn't exists, the subkey. @@ -61,7 +61,7 @@ _gsskrb5i_get_initiator_subkey(const gsskrb5_ctx ctx, ctx->auth_context, key); if (ret == 0 && *key == NULL) { - krb5_set_error_string(context, "No initiator subkey available"); + krb5_set_error_message(context, 0, "No initiator subkey available"); return GSS_KRB5_S_KG_NO_SUBKEY; } return ret; @@ -85,7 +85,7 @@ _gsskrb5i_get_acceptor_subkey(const gsskrb5_ctx ctx, key); } if (ret == 0 && *key == NULL) { - krb5_set_error_string(context, "No acceptor subkey available"); + krb5_set_error_message(context, 0, "No acceptor subkey available"); return GSS_KRB5_S_KG_NO_SUBKEY; } return ret; @@ -106,7 +106,7 @@ _gsskrb5i_get_token_key(const gsskrb5_ctx ctx, _gsskrb5i_get_initiator_subkey(ctx, context, key); } if (*key == NULL) { - krb5_set_error_string(context, "No token key available"); + krb5_set_error_message(context, 0, "No token key available"); return GSS_KRB5_S_KG_NO_SUBKEY; } return 0; @@ -259,7 +259,7 @@ wrap_des memset (&zero, 0, sizeof(zero)); memcpy (&deskey, key->keyvalue.data, sizeof(deskey)); - DES_set_key (&deskey, &schedule); + DES_set_key_unchecked (&deskey, &schedule); DES_cbc_cksum ((void *)hash, (void *)hash, sizeof(hash), &schedule, &zero); memcpy (p - 8, hash, 8); @@ -279,7 +279,7 @@ wrap_des (ctx->more_flags & LOCAL) ? 0 : 0xFF, 4); - DES_set_key (&deskey, &schedule); + DES_set_key_unchecked (&deskey, &schedule); DES_cbc_encrypt ((void *)p, (void *)p, 8, &schedule, (DES_cblock *)(p + 8), DES_ENCRYPT); @@ -296,7 +296,7 @@ wrap_des for (i = 0; i < sizeof(deskey); ++i) deskey[i] ^= 0xf0; - DES_set_key (&deskey, &schedule); + DES_set_key_unchecked (&deskey, &schedule); memset (&zero, 0, sizeof(zero)); DES_cbc_encrypt ((void *)p, (void *)p, diff --git a/source4/heimdal/lib/gssapi/mech/gss_acquire_cred.c b/source4/heimdal/lib/gssapi/mech/gss_acquire_cred.c index cb1b62308c..a2757140ae 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_acquire_cred.c +++ b/source4/heimdal/lib/gssapi/mech/gss_acquire_cred.c @@ -27,9 +27,9 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_acquire_cred.c 21478 2007-07-10 16:32:01Z lha $"); +RCSID("$Id: gss_acquire_cred.c 23025 2008-04-17 10:01:57Z lha $"); -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gss_acquire_cred(OM_uint32 *minor_status, const gss_name_t desired_name, OM_uint32 time_req, diff --git a/source4/heimdal/lib/gssapi/mech/gss_add_cred.c b/source4/heimdal/lib/gssapi/mech/gss_add_cred.c index 09b592b5da..49efa20c8b 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_add_cred.c +++ b/source4/heimdal/lib/gssapi/mech/gss_add_cred.c @@ -27,7 +27,7 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_add_cred.c 21474 2007-07-10 16:30:23Z lha $"); +RCSID("$Id: gss_add_cred.c 23025 2008-04-17 10:01:57Z lha $"); static struct _gss_mechanism_cred * _gss_copy_cred(struct _gss_mechanism_cred *mc) @@ -71,7 +71,7 @@ _gss_copy_cred(struct _gss_mechanism_cred *mc) return (new_mc); } -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gss_add_cred(OM_uint32 *minor_status, const gss_cred_id_t input_cred_handle, const gss_name_t desired_name, diff --git a/source4/heimdal/lib/gssapi/mech/gss_add_oid_set_member.c b/source4/heimdal/lib/gssapi/mech/gss_add_oid_set_member.c index 87d1ab3725..d89adbf63a 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_add_oid_set_member.c +++ b/source4/heimdal/lib/gssapi/mech/gss_add_oid_set_member.c @@ -32,9 +32,9 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_add_oid_set_member.c 18817 2006-10-22 09:36:13Z lha $"); +RCSID("$Id: gss_add_oid_set_member.c 23025 2008-04-17 10:01:57Z lha $"); -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gss_add_oid_set_member (OM_uint32 * minor_status, const gss_OID member_oid, gss_OID_set * oid_set) diff --git a/source4/heimdal/lib/gssapi/mech/gss_buffer_set.c b/source4/heimdal/lib/gssapi/mech/gss_buffer_set.c index 56e0039379..091e219367 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_buffer_set.c +++ b/source4/heimdal/lib/gssapi/mech/gss_buffer_set.c @@ -31,9 +31,9 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_buffer_set.c 18885 2006-10-24 21:53:02Z lha $"); +RCSID("$Id: gss_buffer_set.c 23025 2008-04-17 10:01:57Z lha $"); -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gss_create_empty_buffer_set (OM_uint32 * minor_status, gss_buffer_set_t *buffer_set) @@ -55,7 +55,7 @@ gss_create_empty_buffer_set return GSS_S_COMPLETE; } -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gss_add_buffer_set_member (OM_uint32 * minor_status, const gss_buffer_t member_buffer, @@ -97,7 +97,7 @@ gss_add_buffer_set_member return GSS_S_COMPLETE; } -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gss_release_buffer_set(OM_uint32 * minor_status, gss_buffer_set_t *buffer_set) { diff --git a/source4/heimdal/lib/gssapi/mech/gss_canonicalize_name.c b/source4/heimdal/lib/gssapi/mech/gss_canonicalize_name.c index c950c03166..d242c56a90 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_canonicalize_name.c +++ b/source4/heimdal/lib/gssapi/mech/gss_canonicalize_name.c @@ -27,9 +27,9 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_canonicalize_name.c 21476 2007-07-10 16:31:27Z lha $"); +RCSID("$Id: gss_canonicalize_name.c 23025 2008-04-17 10:01:57Z lha $"); -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gss_canonicalize_name(OM_uint32 *minor_status, const gss_name_t input_name, const gss_OID mech_type, diff --git a/source4/heimdal/lib/gssapi/mech/gss_compare_name.c b/source4/heimdal/lib/gssapi/mech/gss_compare_name.c index 617ff13d98..1eb7625ee2 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_compare_name.c +++ b/source4/heimdal/lib/gssapi/mech/gss_compare_name.c @@ -27,9 +27,9 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_compare_name.c 21475 2007-07-10 16:31:03Z lha $"); +RCSID("$Id: gss_compare_name.c 23025 2008-04-17 10:01:57Z lha $"); -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gss_compare_name(OM_uint32 *minor_status, const gss_name_t name1_arg, const gss_name_t name2_arg, diff --git a/source4/heimdal/lib/gssapi/mech/gss_context_time.c b/source4/heimdal/lib/gssapi/mech/gss_context_time.c index 47999f35cf..8dce822a9f 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_context_time.c +++ b/source4/heimdal/lib/gssapi/mech/gss_context_time.c @@ -27,9 +27,9 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_context_time.c 17700 2006-06-28 09:00:26Z lha $"); +RCSID("$Id: gss_context_time.c 23025 2008-04-17 10:01:57Z lha $"); -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gss_context_time(OM_uint32 *minor_status, const gss_ctx_id_t context_handle, OM_uint32 *time_rec) diff --git a/source4/heimdal/lib/gssapi/mech/gss_create_empty_oid_set.c b/source4/heimdal/lib/gssapi/mech/gss_create_empty_oid_set.c index 841271b1fd..8dd3527349 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_create_empty_oid_set.c +++ b/source4/heimdal/lib/gssapi/mech/gss_create_empty_oid_set.c @@ -27,9 +27,9 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_create_empty_oid_set.c 19951 2007-01-17 10:14:58Z lha $"); +RCSID("$Id: gss_create_empty_oid_set.c 23025 2008-04-17 10:01:57Z lha $"); -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gss_create_empty_oid_set(OM_uint32 *minor_status, gss_OID_set *oid_set) { diff --git a/source4/heimdal/lib/gssapi/mech/gss_decapsulate_token.c b/source4/heimdal/lib/gssapi/mech/gss_decapsulate_token.c index e8b86e4d22..8f93925585 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_decapsulate_token.c +++ b/source4/heimdal/lib/gssapi/mech/gss_decapsulate_token.c @@ -32,9 +32,9 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_decapsulate_token.c 19951 2007-01-17 10:14:58Z lha $"); +RCSID("$Id: gss_decapsulate_token.c 23025 2008-04-17 10:01:57Z lha $"); -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gss_decapsulate_token(gss_buffer_t input_token, gss_OID oid, gss_buffer_t output_token) diff --git a/source4/heimdal/lib/gssapi/mech/gss_delete_sec_context.c b/source4/heimdal/lib/gssapi/mech/gss_delete_sec_context.c index 8c40994739..91273bcf56 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_delete_sec_context.c +++ b/source4/heimdal/lib/gssapi/mech/gss_delete_sec_context.c @@ -27,9 +27,9 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_delete_sec_context.c 19951 2007-01-17 10:14:58Z lha $"); +RCSID("$Id: gss_delete_sec_context.c 23025 2008-04-17 10:01:57Z lha $"); -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gss_delete_sec_context(OM_uint32 *minor_status, gss_ctx_id_t *context_handle, gss_buffer_t output_token) diff --git a/source4/heimdal/lib/gssapi/mech/gss_display_name.c b/source4/heimdal/lib/gssapi/mech/gss_display_name.c index fc10933692..0d82400246 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_display_name.c +++ b/source4/heimdal/lib/gssapi/mech/gss_display_name.c @@ -27,9 +27,9 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_display_name.c 21246 2007-06-20 15:25:19Z lha $"); +RCSID("$Id: gss_display_name.c 23025 2008-04-17 10:01:57Z lha $"); -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gss_display_name(OM_uint32 *minor_status, const gss_name_t input_name, gss_buffer_t output_name_buffer, diff --git a/source4/heimdal/lib/gssapi/mech/gss_display_status.c b/source4/heimdal/lib/gssapi/mech/gss_display_status.c index 37ded26db6..5bbc89b1ec 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_display_status.c +++ b/source4/heimdal/lib/gssapi/mech/gss_display_status.c @@ -59,7 +59,7 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_display_status.c 21247 2007-06-21 00:37:27Z lha $"); +RCSID("$Id: gss_display_status.c 23025 2008-04-17 10:01:57Z lha $"); static const char * calling_error(OM_uint32 v) @@ -136,7 +136,7 @@ supplementary_error(OM_uint32 v) } -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gss_display_status(OM_uint32 *minor_status, OM_uint32 status_value, int status_type, diff --git a/source4/heimdal/lib/gssapi/mech/gss_encapsulate_token.c b/source4/heimdal/lib/gssapi/mech/gss_encapsulate_token.c index 476d451375..32ecbbacb2 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_encapsulate_token.c +++ b/source4/heimdal/lib/gssapi/mech/gss_encapsulate_token.c @@ -32,9 +32,9 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_encapsulate_token.c 19954 2007-01-17 11:50:23Z lha $"); +RCSID("$Id: gss_encapsulate_token.c 23025 2008-04-17 10:01:57Z lha $"); -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gss_encapsulate_token(gss_buffer_t input_token, gss_OID oid, gss_buffer_t output_token) diff --git a/source4/heimdal/lib/gssapi/mech/gss_export_name.c b/source4/heimdal/lib/gssapi/mech/gss_export_name.c index 11c9dd2db5..22053202aa 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_export_name.c +++ b/source4/heimdal/lib/gssapi/mech/gss_export_name.c @@ -27,9 +27,9 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_export_name.c 19954 2007-01-17 11:50:23Z lha $"); +RCSID("$Id: gss_export_name.c 23025 2008-04-17 10:01:57Z lha $"); -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gss_export_name(OM_uint32 *minor_status, const gss_name_t input_name, gss_buffer_t exported_name) diff --git a/source4/heimdal/lib/gssapi/mech/gss_export_sec_context.c b/source4/heimdal/lib/gssapi/mech/gss_export_sec_context.c index cf13bc0cd3..053d203ba1 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_export_sec_context.c +++ b/source4/heimdal/lib/gssapi/mech/gss_export_sec_context.c @@ -27,9 +27,9 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_export_sec_context.c 19954 2007-01-17 11:50:23Z lha $"); +RCSID("$Id: gss_export_sec_context.c 23025 2008-04-17 10:01:57Z lha $"); -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gss_export_sec_context(OM_uint32 *minor_status, gss_ctx_id_t *context_handle, gss_buffer_t interprocess_token) diff --git a/source4/heimdal/lib/gssapi/mech/gss_get_mic.c b/source4/heimdal/lib/gssapi/mech/gss_get_mic.c index 496dd2065c..7b33ac0ed9 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_get_mic.c +++ b/source4/heimdal/lib/gssapi/mech/gss_get_mic.c @@ -27,9 +27,9 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_get_mic.c 19954 2007-01-17 11:50:23Z lha $"); +RCSID("$Id: gss_get_mic.c 23025 2008-04-17 10:01:57Z lha $"); -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gss_get_mic(OM_uint32 *minor_status, const gss_ctx_id_t context_handle, gss_qop_t qop_req, diff --git a/source4/heimdal/lib/gssapi/mech/gss_import_name.c b/source4/heimdal/lib/gssapi/mech/gss_import_name.c index 6f55a1d61c..104452f5b9 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_import_name.c +++ b/source4/heimdal/lib/gssapi/mech/gss_import_name.c @@ -27,7 +27,7 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_import_name.c 19954 2007-01-17 11:50:23Z lha $"); +RCSID("$Id: gss_import_name.c 23025 2008-04-17 10:01:57Z lha $"); static OM_uint32 _gss_import_export_name(OM_uint32 *minor_status, @@ -139,7 +139,7 @@ _gss_import_export_name(OM_uint32 *minor_status, return (GSS_S_COMPLETE); } -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gss_import_name(OM_uint32 *minor_status, const gss_buffer_t input_name_buffer, const gss_OID input_name_type, diff --git a/source4/heimdal/lib/gssapi/mech/gss_import_sec_context.c b/source4/heimdal/lib/gssapi/mech/gss_import_sec_context.c index 44ca1b2677..c68849ce00 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_import_sec_context.c +++ b/source4/heimdal/lib/gssapi/mech/gss_import_sec_context.c @@ -27,9 +27,9 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_import_sec_context.c 19956 2007-01-17 12:04:16Z lha $"); +RCSID("$Id: gss_import_sec_context.c 23025 2008-04-17 10:01:57Z lha $"); -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gss_import_sec_context(OM_uint32 *minor_status, const gss_buffer_t interprocess_token, gss_ctx_id_t *context_handle) diff --git a/source4/heimdal/lib/gssapi/mech/gss_indicate_mechs.c b/source4/heimdal/lib/gssapi/mech/gss_indicate_mechs.c index 00c6ed28ee..cafb660991 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_indicate_mechs.c +++ b/source4/heimdal/lib/gssapi/mech/gss_indicate_mechs.c @@ -27,9 +27,9 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_indicate_mechs.c 17803 2006-07-05 22:36:49Z lha $"); +RCSID("$Id: gss_indicate_mechs.c 23025 2008-04-17 10:01:57Z lha $"); -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gss_indicate_mechs(OM_uint32 *minor_status, gss_OID_set *mech_set) { diff --git a/source4/heimdal/lib/gssapi/mech/gss_init_sec_context.c b/source4/heimdal/lib/gssapi/mech/gss_init_sec_context.c index b9a1680dcb..d0e92f41ce 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_init_sec_context.c +++ b/source4/heimdal/lib/gssapi/mech/gss_init_sec_context.c @@ -27,7 +27,7 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_init_sec_context.c 21479 2007-07-10 16:32:19Z lha $"); +RCSID("$Id: gss_init_sec_context.c 23025 2008-04-17 10:01:57Z lha $"); static gss_cred_id_t _gss_mech_cred_find(gss_cred_id_t cred_handle, gss_OID mech_type) @@ -45,7 +45,7 @@ _gss_mech_cred_find(gss_cred_id_t cred_handle, gss_OID mech_type) return GSS_C_NO_CREDENTIAL; } -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gss_init_sec_context(OM_uint32 * minor_status, const gss_cred_id_t initiator_cred_handle, gss_ctx_id_t * context_handle, diff --git a/source4/heimdal/lib/gssapi/mech/gss_inquire_context.c b/source4/heimdal/lib/gssapi/mech/gss_inquire_context.c index d45baac602..26f4038071 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_inquire_context.c +++ b/source4/heimdal/lib/gssapi/mech/gss_inquire_context.c @@ -27,9 +27,9 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_inquire_context.c 21125 2007-06-18 20:11:07Z lha $"); +RCSID("$Id: gss_inquire_context.c 23025 2008-04-17 10:01:57Z lha $"); -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gss_inquire_context(OM_uint32 *minor_status, const gss_ctx_id_t context_handle, gss_name_t *src_name, diff --git a/source4/heimdal/lib/gssapi/mech/gss_inquire_cred.c b/source4/heimdal/lib/gssapi/mech/gss_inquire_cred.c index 97c3628225..1610be5538 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_inquire_cred.c +++ b/source4/heimdal/lib/gssapi/mech/gss_inquire_cred.c @@ -27,7 +27,7 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_inquire_cred.c 20626 2007-05-08 13:56:49Z lha $"); +RCSID("$Id: gss_inquire_cred.c 23025 2008-04-17 10:01:57Z lha $"); #define AUSAGE 1 #define IUSAGE 2 @@ -43,7 +43,7 @@ updateusage(gss_cred_usage_t usage, int *usagemask) *usagemask |= IUSAGE; } -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gss_inquire_cred(OM_uint32 *minor_status, const gss_cred_id_t cred_handle, gss_name_t *name_ret, diff --git a/source4/heimdal/lib/gssapi/mech/gss_inquire_cred_by_mech.c b/source4/heimdal/lib/gssapi/mech/gss_inquire_cred_by_mech.c index aa83efb0c2..fedd963ffa 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_inquire_cred_by_mech.c +++ b/source4/heimdal/lib/gssapi/mech/gss_inquire_cred_by_mech.c @@ -27,9 +27,9 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_inquire_cred_by_mech.c 21124 2007-06-18 20:08:24Z lha $"); +RCSID("$Id: gss_inquire_cred_by_mech.c 23025 2008-04-17 10:01:57Z lha $"); -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gss_inquire_cred_by_mech(OM_uint32 *minor_status, const gss_cred_id_t cred_handle, const gss_OID mech_type, diff --git a/source4/heimdal/lib/gssapi/mech/gss_inquire_cred_by_oid.c b/source4/heimdal/lib/gssapi/mech/gss_inquire_cred_by_oid.c index 7b53a2ff4a..c1bbf3a724 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_inquire_cred_by_oid.c +++ b/source4/heimdal/lib/gssapi/mech/gss_inquire_cred_by_oid.c @@ -31,9 +31,9 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_inquire_cred_by_oid.c 19960 2007-01-17 15:09:24Z lha $"); +RCSID("$Id: gss_inquire_cred_by_oid.c 23025 2008-04-17 10:01:57Z lha $"); -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gss_inquire_cred_by_oid (OM_uint32 *minor_status, const gss_cred_id_t cred_handle, const gss_OID desired_object, diff --git a/source4/heimdal/lib/gssapi/mech/gss_inquire_mechs_for_name.c b/source4/heimdal/lib/gssapi/mech/gss_inquire_mechs_for_name.c index 5330a747a6..6b06a33053 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_inquire_mechs_for_name.c +++ b/source4/heimdal/lib/gssapi/mech/gss_inquire_mechs_for_name.c @@ -27,9 +27,9 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_inquire_mechs_for_name.c 17844 2006-07-20 02:04:00Z lha $"); +RCSID("$Id: gss_inquire_mechs_for_name.c 23025 2008-04-17 10:01:57Z lha $"); -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gss_inquire_mechs_for_name(OM_uint32 *minor_status, const gss_name_t input_name, gss_OID_set *mech_types) diff --git a/source4/heimdal/lib/gssapi/mech/gss_inquire_names_for_mech.c b/source4/heimdal/lib/gssapi/mech/gss_inquire_names_for_mech.c index 65b52cbbc3..1ba1ee0563 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_inquire_names_for_mech.c +++ b/source4/heimdal/lib/gssapi/mech/gss_inquire_names_for_mech.c @@ -27,9 +27,9 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_inquire_names_for_mech.c 19960 2007-01-17 15:09:24Z lha $"); +RCSID("$Id: gss_inquire_names_for_mech.c 23025 2008-04-17 10:01:57Z lha $"); -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gss_inquire_names_for_mech(OM_uint32 *minor_status, const gss_OID mechanism, gss_OID_set *name_types) diff --git a/source4/heimdal/lib/gssapi/mech/gss_inquire_sec_context_by_oid.c b/source4/heimdal/lib/gssapi/mech/gss_inquire_sec_context_by_oid.c index fd8219ce02..b06a3e10f0 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_inquire_sec_context_by_oid.c +++ b/source4/heimdal/lib/gssapi/mech/gss_inquire_sec_context_by_oid.c @@ -31,9 +31,9 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_inquire_sec_context_by_oid.c 19961 2007-01-17 15:57:51Z lha $"); +RCSID("$Id: gss_inquire_sec_context_by_oid.c 23025 2008-04-17 10:01:57Z lha $"); -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gss_inquire_sec_context_by_oid (OM_uint32 *minor_status, const gss_ctx_id_t context_handle, const gss_OID desired_object, diff --git a/source4/heimdal/lib/gssapi/mech/gss_krb5.c b/source4/heimdal/lib/gssapi/mech/gss_krb5.c index 03081cb70f..d6b89e3e23 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_krb5.c +++ b/source4/heimdal/lib/gssapi/mech/gss_krb5.c @@ -27,13 +27,13 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_krb5.c 21889 2007-08-09 07:43:24Z lha $"); +RCSID("$Id: gss_krb5.c 23420 2008-07-26 18:37:48Z lha $"); #include <krb5.h> #include <roken.h> -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gss_krb5_copy_ccache(OM_uint32 *minor_status, gss_cred_id_t cred, krb5_ccache out) @@ -91,7 +91,7 @@ gss_krb5_copy_ccache(OM_uint32 *minor_status, return ret; } -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gss_krb5_import_cred(OM_uint32 *minor_status, krb5_ccache id, krb5_principal keytab_principal, @@ -186,7 +186,7 @@ out: return major_status; } -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gsskrb5_register_acceptor_identity(const char *identity) { struct _gss_mech_switch *m; @@ -208,7 +208,14 @@ gsskrb5_register_acceptor_identity(const char *identity) return (GSS_S_COMPLETE); } -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION +krb5_gss_register_acceptor_identity(const char *identity) +{ + return gsskrb5_register_acceptor_identity(identity); +} + + +OM_uint32 GSSAPI_LIB_FUNCTION gsskrb5_set_dns_canonicalize(int flag) { struct _gss_mech_switch *m; @@ -253,7 +260,7 @@ free_key(gss_krb5_lucid_key_t *key) memset(key, 0, sizeof(*key)); } -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gss_krb5_export_lucid_sec_context(OM_uint32 *minor_status, gss_ctx_id_t *context_handle, OM_uint32 version, @@ -396,7 +403,7 @@ out: return GSS_S_COMPLETE; } -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gss_krb5_free_lucid_sec_context(OM_uint32 *minor_status, void *c) { gss_krb5_lucid_context_v1_t *ctx = c; @@ -424,7 +431,7 @@ gss_krb5_free_lucid_sec_context(OM_uint32 *minor_status, void *c) * */ -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gss_krb5_set_allowable_enctypes(OM_uint32 *minor_status, gss_cred_id_t cred, OM_uint32 num_enctypes, @@ -478,7 +485,7 @@ out: * */ -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gsskrb5_set_send_to_kdc(struct gsskrb5_send_to_kdc *c) { struct _gss_mech_switch *m; @@ -509,7 +516,7 @@ gsskrb5_set_send_to_kdc(struct gsskrb5_send_to_kdc *c) * */ -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gss_krb5_ccache_name(OM_uint32 *minor_status, const char *name, const char **out_name) @@ -541,7 +548,7 @@ gss_krb5_ccache_name(OM_uint32 *minor_status, * */ -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gsskrb5_extract_authtime_from_sec_context(OM_uint32 *minor_status, gss_ctx_id_t context_handle, time_t *authtime) @@ -596,7 +603,7 @@ gsskrb5_extract_authtime_from_sec_context(OM_uint32 *minor_status, * */ -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gsskrb5_extract_authz_data_from_sec_context(OM_uint32 *minor_status, gss_ctx_id_t context_handle, int ad_type, @@ -769,7 +776,7 @@ out: * */ -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gsskrb5_extract_service_keyblock(OM_uint32 *minor_status, gss_ctx_id_t context_handle, krb5_keyblock **keyblock) @@ -780,7 +787,7 @@ gsskrb5_extract_service_keyblock(OM_uint32 *minor_status, keyblock); } -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gsskrb5_get_initiator_subkey(OM_uint32 *minor_status, gss_ctx_id_t context_handle, krb5_keyblock **keyblock) @@ -791,7 +798,7 @@ gsskrb5_get_initiator_subkey(OM_uint32 *minor_status, keyblock); } -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gsskrb5_get_subkey(OM_uint32 *minor_status, gss_ctx_id_t context_handle, krb5_keyblock **keyblock) @@ -802,7 +809,7 @@ gsskrb5_get_subkey(OM_uint32 *minor_status, keyblock); } -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gsskrb5_set_default_realm(const char *realm) { struct _gss_mech_switch *m; @@ -824,7 +831,7 @@ gsskrb5_set_default_realm(const char *realm) return (GSS_S_COMPLETE); } -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gss_krb5_get_tkt_flags(OM_uint32 *minor_status, gss_ctx_id_t context_handle, OM_uint32 *tkt_flags) @@ -863,3 +870,53 @@ gss_krb5_get_tkt_flags(OM_uint32 *minor_status, return GSS_S_COMPLETE; } +OM_uint32 GSSAPI_LIB_FUNCTION +gsskrb5_set_time_offset(int offset) +{ + struct _gss_mech_switch *m; + gss_buffer_desc buffer; + OM_uint32 junk; + int32_t o = offset; + + _gss_load_mech(); + + buffer.value = &o; + buffer.length = sizeof(o); + + SLIST_FOREACH(m, &_gss_mechs, gm_link) { + if (m->gm_mech.gm_set_sec_context_option == NULL) + continue; + m->gm_mech.gm_set_sec_context_option(&junk, NULL, + GSS_KRB5_SET_TIME_OFFSET_X, &buffer); + } + + return (GSS_S_COMPLETE); +} + +OM_uint32 GSSAPI_LIB_FUNCTION +gsskrb5_get_time_offset(int *offset) +{ + struct _gss_mech_switch *m; + gss_buffer_desc buffer; + OM_uint32 maj_stat, junk; + int32_t o; + + _gss_load_mech(); + + buffer.value = &o; + buffer.length = sizeof(o); + + SLIST_FOREACH(m, &_gss_mechs, gm_link) { + if (m->gm_mech.gm_set_sec_context_option == NULL) + continue; + maj_stat = m->gm_mech.gm_set_sec_context_option(&junk, NULL, + GSS_KRB5_GET_TIME_OFFSET_X, &buffer); + + if (maj_stat == GSS_S_COMPLETE) { + *offset = o; + return maj_stat; + } + } + + return (GSS_S_UNAVAILABLE); +} diff --git a/source4/heimdal/lib/gssapi/mech/gss_mech_switch.c b/source4/heimdal/lib/gssapi/mech/gss_mech_switch.c index fe65ad1ae1..8abbb7d0cc 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_mech_switch.c +++ b/source4/heimdal/lib/gssapi/mech/gss_mech_switch.c @@ -28,7 +28,7 @@ #include "mech_locl.h" #include <heim_threads.h> -RCSID("$Id: gss_mech_switch.c 21698 2007-07-26 19:07:11Z lha $"); +RCSID("$Id: gss_mech_switch.c 23471 2008-07-27 12:17:49Z lha $"); #ifndef _PATH_GSS_MECH #define _PATH_GSS_MECH "/etc/gss/mech" @@ -46,7 +46,7 @@ static int _gss_string_to_oid(const char* s, gss_OID oid) { int number_count, i, j; - int byte_count; + size_t byte_count; const char *p, *q; char *res; @@ -118,7 +118,7 @@ _gss_string_to_oid(const char* s, gss_OID oid) * The number is encoded in seven bit chunks. */ unsigned int t; - int bytes; + unsigned int bytes; bytes = 0; for (t = number; t; t >>= 7) @@ -229,6 +229,7 @@ _gss_load_mech(void) HEIMDAL_MUTEX_unlock(&_gss_mech_mutex); return; } + rk_cloexec_file(fp); while (fgets(buf, sizeof(buf), fp)) { if (*buf == '#') diff --git a/source4/heimdal/lib/gssapi/mech/gss_oid_equal.c b/source4/heimdal/lib/gssapi/mech/gss_oid_equal.c index 8c75410cc1..b272316115 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_oid_equal.c +++ b/source4/heimdal/lib/gssapi/mech/gss_oid_equal.c @@ -32,9 +32,9 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_oid_equal.c 17702 2006-06-28 09:07:08Z lha $"); +RCSID("$Id: gss_oid_equal.c 23025 2008-04-17 10:01:57Z lha $"); -int +int GSSAPI_LIB_FUNCTION gss_oid_equal(const gss_OID a, const gss_OID b) { if (a == b) diff --git a/source4/heimdal/lib/gssapi/mech/gss_oid_to_str.c b/source4/heimdal/lib/gssapi/mech/gss_oid_to_str.c index e2cecaf6b4..4678a3e710 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_oid_to_str.c +++ b/source4/heimdal/lib/gssapi/mech/gss_oid_to_str.c @@ -32,9 +32,9 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_oid_to_str.c 21409 2007-07-04 14:19:11Z lha $"); +RCSID("$Id: gss_oid_to_str.c 23025 2008-04-17 10:01:57Z lha $"); -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gss_oid_to_str(OM_uint32 *minor_status, gss_OID oid, gss_buffer_t oid_str) { int ret; diff --git a/source4/heimdal/lib/gssapi/mech/gss_process_context_token.c b/source4/heimdal/lib/gssapi/mech/gss_process_context_token.c index dff6b04f14..db55bc24be 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_process_context_token.c +++ b/source4/heimdal/lib/gssapi/mech/gss_process_context_token.c @@ -27,9 +27,9 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_process_context_token.c 17700 2006-06-28 09:00:26Z lha $"); +RCSID("$Id: gss_process_context_token.c 23025 2008-04-17 10:01:57Z lha $"); -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gss_process_context_token(OM_uint32 *minor_status, const gss_ctx_id_t context_handle, const gss_buffer_t token_buffer) diff --git a/source4/heimdal/lib/gssapi/mech/gss_release_buffer.c b/source4/heimdal/lib/gssapi/mech/gss_release_buffer.c index fc55cae030..eb1bf34985 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_release_buffer.c +++ b/source4/heimdal/lib/gssapi/mech/gss_release_buffer.c @@ -27,9 +27,9 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_release_buffer.c 19962 2007-01-17 15:59:04Z lha $"); +RCSID("$Id: gss_release_buffer.c 23025 2008-04-17 10:01:57Z lha $"); -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gss_release_buffer(OM_uint32 *minor_status, gss_buffer_t buffer) { diff --git a/source4/heimdal/lib/gssapi/mech/gss_release_cred.c b/source4/heimdal/lib/gssapi/mech/gss_release_cred.c index b26dbd7865..9648929c91 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_release_cred.c +++ b/source4/heimdal/lib/gssapi/mech/gss_release_cred.c @@ -27,9 +27,9 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_release_cred.c 19963 2007-01-17 16:01:22Z lha $"); +RCSID("$Id: gss_release_cred.c 23025 2008-04-17 10:01:57Z lha $"); -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gss_release_cred(OM_uint32 *minor_status, gss_cred_id_t *cred_handle) { struct _gss_cred *cred = (struct _gss_cred *) *cred_handle; diff --git a/source4/heimdal/lib/gssapi/mech/gss_release_name.c b/source4/heimdal/lib/gssapi/mech/gss_release_name.c index 313eab8245..d8c36c10a7 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_release_name.c +++ b/source4/heimdal/lib/gssapi/mech/gss_release_name.c @@ -27,9 +27,9 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_release_name.c 18812 2006-10-22 07:59:06Z lha $"); +RCSID("$Id: gss_release_name.c 23025 2008-04-17 10:01:57Z lha $"); -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gss_release_name(OM_uint32 *minor_status, gss_name_t *input_name) { diff --git a/source4/heimdal/lib/gssapi/mech/gss_release_oid.c b/source4/heimdal/lib/gssapi/mech/gss_release_oid.c index 7754787fa8..ccc59638fb 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_release_oid.c +++ b/source4/heimdal/lib/gssapi/mech/gss_release_oid.c @@ -33,9 +33,9 @@ #include "mech_locl.h" -RCSID("$Id: gss_release_oid.c 17747 2006-06-30 09:34:54Z lha $"); +RCSID("$Id: gss_release_oid.c 23025 2008-04-17 10:01:57Z lha $"); -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gss_release_oid(OM_uint32 *minor_status, gss_OID *oid) { gss_OID o = *oid; diff --git a/source4/heimdal/lib/gssapi/mech/gss_release_oid_set.c b/source4/heimdal/lib/gssapi/mech/gss_release_oid_set.c index 388cfdbf4c..00b1f4656d 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_release_oid_set.c +++ b/source4/heimdal/lib/gssapi/mech/gss_release_oid_set.c @@ -27,9 +27,9 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_release_oid_set.c 22144 2007-12-04 17:31:55Z lha $"); +RCSID("$Id: gss_release_oid_set.c 23025 2008-04-17 10:01:57Z lha $"); -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gss_release_oid_set(OM_uint32 *minor_status, gss_OID_set *set) { diff --git a/source4/heimdal/lib/gssapi/mech/gss_seal.c b/source4/heimdal/lib/gssapi/mech/gss_seal.c index 71c5e70dc7..7979455430 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_seal.c +++ b/source4/heimdal/lib/gssapi/mech/gss_seal.c @@ -27,9 +27,9 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_seal.c 17700 2006-06-28 09:00:26Z lha $"); +RCSID("$Id: gss_seal.c 23025 2008-04-17 10:01:57Z lha $"); -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gss_seal(OM_uint32 *minor_status, gss_ctx_id_t context_handle, int conf_req_flag, diff --git a/source4/heimdal/lib/gssapi/mech/gss_set_cred_option.c b/source4/heimdal/lib/gssapi/mech/gss_set_cred_option.c index c32291396f..bbd75c9849 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_set_cred_option.c +++ b/source4/heimdal/lib/gssapi/mech/gss_set_cred_option.c @@ -31,9 +31,9 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_set_cred_option.c 21126 2007-06-18 20:19:59Z lha $"); +RCSID("$Id: gss_set_cred_option.c 23025 2008-04-17 10:01:57Z lha $"); -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gss_set_cred_option (OM_uint32 *minor_status, gss_cred_id_t *cred_handle, const gss_OID object, diff --git a/source4/heimdal/lib/gssapi/mech/gss_set_sec_context_option.c b/source4/heimdal/lib/gssapi/mech/gss_set_sec_context_option.c index d312251f53..48377fd6bc 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_set_sec_context_option.c +++ b/source4/heimdal/lib/gssapi/mech/gss_set_sec_context_option.c @@ -31,9 +31,9 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_set_sec_context_option.c 19928 2007-01-16 10:37:54Z lha $"); +RCSID("$Id: gss_set_sec_context_option.c 23025 2008-04-17 10:01:57Z lha $"); -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gss_set_sec_context_option (OM_uint32 *minor_status, gss_ctx_id_t *context_handle, const gss_OID object, diff --git a/source4/heimdal/lib/gssapi/mech/gss_sign.c b/source4/heimdal/lib/gssapi/mech/gss_sign.c index 5268197c61..c91b6490d2 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_sign.c +++ b/source4/heimdal/lib/gssapi/mech/gss_sign.c @@ -27,9 +27,9 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_sign.c 17700 2006-06-28 09:00:26Z lha $"); +RCSID("$Id: gss_sign.c 23025 2008-04-17 10:01:57Z lha $"); -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gss_sign(OM_uint32 *minor_status, gss_ctx_id_t context_handle, int qop_req, diff --git a/source4/heimdal/lib/gssapi/mech/gss_test_oid_set_member.c b/source4/heimdal/lib/gssapi/mech/gss_test_oid_set_member.c index fc3c5ddeef..ee42cc5d1a 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_test_oid_set_member.c +++ b/source4/heimdal/lib/gssapi/mech/gss_test_oid_set_member.c @@ -27,9 +27,9 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_test_oid_set_member.c 17700 2006-06-28 09:00:26Z lha $"); +RCSID("$Id: gss_test_oid_set_member.c 23025 2008-04-17 10:01:57Z lha $"); -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gss_test_oid_set_member(OM_uint32 *minor_status, const gss_OID member, const gss_OID_set set, diff --git a/source4/heimdal/lib/gssapi/mech/gss_unseal.c b/source4/heimdal/lib/gssapi/mech/gss_unseal.c index 205cc6e326..d6f73c5522 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_unseal.c +++ b/source4/heimdal/lib/gssapi/mech/gss_unseal.c @@ -27,9 +27,9 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_unseal.c 17700 2006-06-28 09:00:26Z lha $"); +RCSID("$Id: gss_unseal.c 23025 2008-04-17 10:01:57Z lha $"); -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gss_unseal(OM_uint32 *minor_status, gss_ctx_id_t context_handle, gss_buffer_t input_message_buffer, diff --git a/source4/heimdal/lib/gssapi/mech/gss_unwrap.c b/source4/heimdal/lib/gssapi/mech/gss_unwrap.c index 69c125356b..4866bacbe5 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_unwrap.c +++ b/source4/heimdal/lib/gssapi/mech/gss_unwrap.c @@ -27,9 +27,9 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_unwrap.c 17700 2006-06-28 09:00:26Z lha $"); +RCSID("$Id: gss_unwrap.c 23025 2008-04-17 10:01:57Z lha $"); -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gss_unwrap(OM_uint32 *minor_status, const gss_ctx_id_t context_handle, const gss_buffer_t input_message_buffer, diff --git a/source4/heimdal/lib/gssapi/mech/gss_verify.c b/source4/heimdal/lib/gssapi/mech/gss_verify.c index f11cac7d2e..d82ceee984 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_verify.c +++ b/source4/heimdal/lib/gssapi/mech/gss_verify.c @@ -27,9 +27,9 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_verify.c 17700 2006-06-28 09:00:26Z lha $"); +RCSID("$Id: gss_verify.c 23025 2008-04-17 10:01:57Z lha $"); -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gss_verify(OM_uint32 *minor_status, gss_ctx_id_t context_handle, gss_buffer_t message_buffer, diff --git a/source4/heimdal/lib/gssapi/mech/gss_verify_mic.c b/source4/heimdal/lib/gssapi/mech/gss_verify_mic.c index 118f50735f..c58c63ac0f 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_verify_mic.c +++ b/source4/heimdal/lib/gssapi/mech/gss_verify_mic.c @@ -27,9 +27,9 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_verify_mic.c 19965 2007-01-17 16:23:47Z lha $"); +RCSID("$Id: gss_verify_mic.c 23025 2008-04-17 10:01:57Z lha $"); -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gss_verify_mic(OM_uint32 *minor_status, const gss_ctx_id_t context_handle, const gss_buffer_t message_buffer, diff --git a/source4/heimdal/lib/gssapi/mech/gss_wrap.c b/source4/heimdal/lib/gssapi/mech/gss_wrap.c index 0eb9dfbc6d..f6b5077d0e 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_wrap.c +++ b/source4/heimdal/lib/gssapi/mech/gss_wrap.c @@ -27,9 +27,9 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_wrap.c 19965 2007-01-17 16:23:47Z lha $"); +RCSID("$Id: gss_wrap.c 23025 2008-04-17 10:01:57Z lha $"); -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gss_wrap(OM_uint32 *minor_status, const gss_ctx_id_t context_handle, int conf_req_flag, diff --git a/source4/heimdal/lib/gssapi/mech/gss_wrap_size_limit.c b/source4/heimdal/lib/gssapi/mech/gss_wrap_size_limit.c index 35b3ad723d..14f373dada 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_wrap_size_limit.c +++ b/source4/heimdal/lib/gssapi/mech/gss_wrap_size_limit.c @@ -27,9 +27,9 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_wrap_size_limit.c 19965 2007-01-17 16:23:47Z lha $"); +RCSID("$Id: gss_wrap_size_limit.c 23025 2008-04-17 10:01:57Z lha $"); -OM_uint32 +OM_uint32 GSSAPI_LIB_FUNCTION gss_wrap_size_limit(OM_uint32 *minor_status, const gss_ctx_id_t context_handle, int conf_req_flag, diff --git a/source4/heimdal/lib/gssapi/spnego/accept_sec_context.c b/source4/heimdal/lib/gssapi/spnego/accept_sec_context.c index df25b0f4bf..6b618092fe 100644 --- a/source4/heimdal/lib/gssapi/spnego/accept_sec_context.c +++ b/source4/heimdal/lib/gssapi/spnego/accept_sec_context.c @@ -33,7 +33,7 @@ #include "spnego/spnego_locl.h" -RCSID("$Id: accept_sec_context.c 22600 2008-02-21 12:46:24Z lha $"); +RCSID("$Id: accept_sec_context.c 23158 2008-05-02 09:45:28Z lha $"); static OM_uint32 send_reject (OM_uint32 *minor_status, @@ -376,6 +376,9 @@ select_mech(OM_uint32 *minor_status, MechType *mechType, int verify_p, char mechbuf[64]; size_t mech_len; gss_OID_desc oid; + gss_OID oidp; + gss_OID_set mechs; + int i; OM_uint32 ret, junk; ret = der_put_oid ((unsigned char *)mechbuf + sizeof(mechbuf) - 1, @@ -396,27 +399,29 @@ select_mech(OM_uint32 *minor_status, MechType *mechType, int verify_p, *minor_status = 0; /* Translate broken MS Kebreros OID */ - if (gss_oid_equal(&oid, &_gss_spnego_mskrb_mechanism_oid_desc)) { - gssapi_mech_interface mech; + if (gss_oid_equal(&oid, &_gss_spnego_mskrb_mechanism_oid_desc)) + oidp = &_gss_spnego_krb5_mechanism_oid_desc; + else + oidp = &oid; - mech = __gss_get_mechanism(&_gss_spnego_krb5_mechanism_oid_desc); - if (mech == NULL) - return GSS_S_BAD_MECH; - ret = gss_duplicate_oid(minor_status, - &_gss_spnego_mskrb_mechanism_oid_desc, - mech_p); - } else { - gssapi_mech_interface mech; + ret = gss_indicate_mechs(&junk, &mechs); + if (ret) + return (ret); - mech = __gss_get_mechanism(&oid); - if (mech == NULL) - return GSS_S_BAD_MECH; + for (i = 0; i < mechs->count; i++) + if (gss_oid_equal(&mechs->elements[i], oidp)) + break; - ret = gss_duplicate_oid(minor_status, - &mech->gm_mech_oid, - mech_p); + if (i == mechs->count) { + gss_release_oid_set(&junk, &mechs); + return GSS_S_BAD_MECH; } + gss_release_oid_set(&junk, &mechs); + + ret = gss_duplicate_oid(minor_status, + &oid, /* possibly this should be oidp */ + mech_p); if (verify_p) { gss_name_t name = GSS_C_NO_NAME; @@ -635,9 +640,6 @@ acceptor_start if (ctx->mech_src_name != GSS_C_NO_NAME) gss_release_name(&junk, &ctx->mech_src_name); - if (ctx->delegated_cred_id != GSS_C_NO_CREDENTIAL) - _gss_spnego_release_cred(&junk, &ctx->delegated_cred_id); - ret = gss_accept_sec_context(minor_status, &ctx->negotiated_ctx_id, mech_cred, @@ -649,19 +651,20 @@ acceptor_start &ctx->mech_flags, &ctx->mech_time_rec, &mech_delegated_cred); + + if (mech_delegated_cred && delegated_cred_handle) { + _gss_spnego_alloc_cred(&junk, + mech_delegated_cred, + delegated_cred_handle); + } else if (mech_delegated_cred != GSS_C_NO_CREDENTIAL) + gss_release_cred(&junk, &mech_delegated_cred); + if (ret == GSS_S_COMPLETE || ret == GSS_S_CONTINUE_NEEDED) { ctx->preferred_mech_type = preferred_mech_type; ctx->negotiated_mech_type = preferred_mech_type; if (ret == GSS_S_COMPLETE) ctx->open = 1; - if (mech_delegated_cred && delegated_cred_handle) - ret = _gss_spnego_alloc_cred(&junk, - mech_delegated_cred, - delegated_cred_handle); - else - gss_release_cred(&junk, &mech_delegated_cred); - ret = acceptor_complete(minor_status, ctx, &get_mic, @@ -740,10 +743,6 @@ out: *src_name = (gss_name_t)name; } } - if (delegated_cred_handle != NULL) { - *delegated_cred_handle = ctx->delegated_cred_id; - ctx->delegated_cred_id = GSS_C_NO_CREDENTIAL; - } } if (mech_type != NULL) @@ -780,7 +779,7 @@ acceptor_continue gss_cred_id_t *delegated_cred_handle ) { - OM_uint32 ret, ret2, minor; + OM_uint32 ret, ret2, minor, junk; NegotiationToken nt; size_t nt_len; NegTokenResp *na; @@ -836,27 +835,16 @@ acceptor_continue if (mech_input_token != GSS_C_NO_BUFFER) { gss_cred_id_t mech_cred; - gss_cred_id_t mech_delegated_cred; - gss_cred_id_t *mech_delegated_cred_p; + gss_cred_id_t mech_delegated_cred = GSS_C_NO_CREDENTIAL; if (acceptor_cred != NULL) mech_cred = acceptor_cred->negotiated_cred_id; else mech_cred = GSS_C_NO_CREDENTIAL; - if (delegated_cred_handle != NULL) { - mech_delegated_cred = GSS_C_NO_CREDENTIAL; - mech_delegated_cred_p = &mech_delegated_cred; - } else { - mech_delegated_cred_p = NULL; - } - if (ctx->mech_src_name != GSS_C_NO_NAME) gss_release_name(&minor, &ctx->mech_src_name); - if (ctx->delegated_cred_id != GSS_C_NO_CREDENTIAL) - _gss_spnego_release_cred(&minor, &ctx->delegated_cred_id); - ret = gss_accept_sec_context(&minor, &ctx->negotiated_ctx_id, mech_cred, @@ -867,16 +855,16 @@ acceptor_continue &obuf, &ctx->mech_flags, &ctx->mech_time_rec, - mech_delegated_cred_p); + &mech_delegated_cred); + + if (mech_delegated_cred && delegated_cred_handle) { + _gss_spnego_alloc_cred(&junk, + mech_delegated_cred, + delegated_cred_handle); + } else if (mech_delegated_cred != GSS_C_NO_CREDENTIAL) + gss_release_cred(&junk, &mech_delegated_cred); + if (ret == GSS_S_COMPLETE || ret == GSS_S_CONTINUE_NEEDED) { - if (mech_delegated_cred_p != NULL && - mech_delegated_cred != GSS_C_NO_CREDENTIAL) { - ret2 = _gss_spnego_alloc_cred(minor_status, - mech_delegated_cred, - &ctx->delegated_cred_id); - if (ret2 != GSS_S_COMPLETE) - ret = ret2; - } mech_output_token = &obuf; } if (ret != GSS_S_COMPLETE && ret != GSS_S_CONTINUE_NEEDED) { @@ -958,10 +946,6 @@ acceptor_continue *src_name = (gss_name_t)name; } } - if (delegated_cred_handle != NULL) { - *delegated_cred_handle = ctx->delegated_cred_id; - ctx->delegated_cred_id = GSS_C_NO_CREDENTIAL; - } } if (mech_type != NULL) diff --git a/source4/heimdal/lib/gssapi/spnego/compat.c b/source4/heimdal/lib/gssapi/spnego/compat.c index 287f4f760e..36de854784 100644 --- a/source4/heimdal/lib/gssapi/spnego/compat.c +++ b/source4/heimdal/lib/gssapi/spnego/compat.c @@ -32,7 +32,7 @@ #include "spnego/spnego_locl.h" -RCSID("$Id: compat.c 21866 2007-08-08 11:31:29Z lha $"); +RCSID("$Id: compat.c 22688 2008-03-16 11:33:58Z lha $"); /* * Apparently Microsoft got the OID wrong, and used @@ -76,7 +76,6 @@ OM_uint32 _gss_spnego_alloc_sec_context (OM_uint32 * minor_status, ctx->mech_flags = 0; ctx->mech_time_rec = 0; ctx->mech_src_name = GSS_C_NO_NAME; - ctx->delegated_cred_id = GSS_C_NO_CREDENTIAL; ctx->open = 0; ctx->local = 0; @@ -124,8 +123,6 @@ OM_uint32 _gss_spnego_internal_delete_sec_context if (ctx->initiator_mech_types.val != NULL) free_MechTypeList(&ctx->initiator_mech_types); - _gss_spnego_release_cred(&minor, &ctx->delegated_cred_id); - gss_release_oid(&minor, &ctx->preferred_mech_type); ctx->negotiated_mech_type = GSS_C_NO_OID; diff --git a/source4/heimdal/lib/gssapi/spnego/context_stubs.c b/source4/heimdal/lib/gssapi/spnego/context_stubs.c index 0169017ee5..6f1c3eb4b6 100644 --- a/source4/heimdal/lib/gssapi/spnego/context_stubs.c +++ b/source4/heimdal/lib/gssapi/spnego/context_stubs.c @@ -32,7 +32,7 @@ #include "spnego/spnego_locl.h" -RCSID("$Id: context_stubs.c 22604 2008-02-21 21:12:48Z lha $"); +RCSID("$Id: context_stubs.c 22688 2008-03-16 11:33:58Z lha $"); static OM_uint32 spnego_supported_mechs(OM_uint32 *minor_status, gss_OID_set *mechs) @@ -907,7 +907,7 @@ OM_uint32 _gss_spnego_set_sec_context_option return GSS_S_NO_CONTEXT; } - ctx = (gssspnego_ctx)context_handle; + ctx = (gssspnego_ctx)*context_handle; if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) { return GSS_S_NO_CONTEXT; @@ -919,3 +919,31 @@ OM_uint32 _gss_spnego_set_sec_context_option value); } + +OM_uint32 +_gss_spnego_pseudo_random(OM_uint32 *minor_status, + gss_ctx_id_t context_handle, + int prf_key, + const gss_buffer_t prf_in, + ssize_t desired_output_len, + gss_buffer_t prf_out) +{ + gssspnego_ctx ctx; + + *minor_status = 0; + + if (context_handle == GSS_C_NO_CONTEXT) + return GSS_S_NO_CONTEXT; + + ctx = (gssspnego_ctx)context_handle; + + if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) + return GSS_S_NO_CONTEXT; + + return gss_pseudo_random(minor_status, + ctx->negotiated_ctx_id, + prf_key, + prf_in, + desired_output_len, + prf_out); +} diff --git a/source4/heimdal/lib/gssapi/spnego/cred_stubs.c b/source4/heimdal/lib/gssapi/spnego/cred_stubs.c index 2362e99019..d87d7d618e 100644 --- a/source4/heimdal/lib/gssapi/spnego/cred_stubs.c +++ b/source4/heimdal/lib/gssapi/spnego/cred_stubs.c @@ -32,7 +32,7 @@ #include "spnego/spnego_locl.h" -RCSID("$Id: cred_stubs.c 20619 2007-05-08 13:43:45Z lha $"); +RCSID("$Id: cred_stubs.c 22688 2008-03-16 11:33:58Z lha $"); OM_uint32 _gss_spnego_release_cred(OM_uint32 *minor_status, gss_cred_id_t *cred_handle) @@ -334,3 +334,23 @@ OM_uint32 _gss_spnego_inquire_cred_by_oid return ret; } +OM_uint32 +_gss_spnego_set_cred_option (OM_uint32 *minor_status, + gss_cred_id_t *cred_handle, + const gss_OID object, + const gss_buffer_t value) +{ + gssspnego_cred cred; + + if (cred_handle == NULL || *cred_handle == GSS_C_NO_CREDENTIAL) { + *minor_status = 0; + return GSS_S_NO_CRED; + } + + cred = (gssspnego_cred)*cred_handle; + return gss_set_cred_option(minor_status, + &cred->negotiated_cred_id, + object, + value); +} + diff --git a/source4/heimdal/lib/gssapi/spnego/external.c b/source4/heimdal/lib/gssapi/spnego/external.c index 6c9a03a3b0..317d358707 100644 --- a/source4/heimdal/lib/gssapi/spnego/external.c +++ b/source4/heimdal/lib/gssapi/spnego/external.c @@ -33,7 +33,7 @@ #include "spnego/spnego_locl.h" #include <gssapi_mech.h> -RCSID("$Id: external.c 22600 2008-02-21 12:46:24Z lha $"); +RCSID("$Id: external.c 22688 2008-03-16 11:33:58Z lha $"); /* * RFC2478, SPNEGO: @@ -57,8 +57,8 @@ static gssapi_mech_interface_desc spnego_mech = { _gss_spnego_verify_mic, _gss_spnego_wrap, _gss_spnego_unwrap, - NULL, - NULL, + NULL, /* gm_display_status */ + NULL, /* gm_indicate_mechs */ _gss_spnego_compare_name, _gss_spnego_display_name, _gss_spnego_import_name, @@ -74,7 +74,12 @@ static gssapi_mech_interface_desc spnego_mech = { _gss_spnego_inquire_names_for_mech, _gss_spnego_inquire_mechs_for_name, _gss_spnego_canonicalize_name, - _gss_spnego_duplicate_name + _gss_spnego_duplicate_name, + _gss_spnego_inquire_sec_context_by_oid, + _gss_spnego_inquire_cred_by_oid, + _gss_spnego_set_sec_context_option, + _gss_spnego_set_cred_option, + _gss_spnego_pseudo_random }; gssapi_mech_interface diff --git a/source4/heimdal/lib/gssapi/spnego/spnego-private.h b/source4/heimdal/lib/gssapi/spnego/spnego-private.h index 69f4d8423d..3b20d737b7 100644 --- a/source4/heimdal/lib/gssapi/spnego/spnego-private.h +++ b/source4/heimdal/lib/gssapi/spnego/spnego-private.h @@ -225,6 +225,15 @@ _gss_spnego_process_context_token ( const gss_buffer_t token_buffer ); OM_uint32 +_gss_spnego_pseudo_random ( + OM_uint32 */*minor_status*/, + gss_ctx_id_t /*context_handle*/, + int /*prf_key*/, + const gss_buffer_t /*prf_in*/, + ssize_t /*desired_output_len*/, + gss_buffer_t /*prf_out*/); + +OM_uint32 _gss_spnego_release_cred ( OM_uint32 */*minor_status*/, gss_cred_id_t */*cred_handle*/); @@ -251,6 +260,13 @@ _gss_spnego_seal ( gss_buffer_t output_message_buffer ); OM_uint32 +_gss_spnego_set_cred_option ( + OM_uint32 */*minor_status*/, + gss_cred_id_t */*cred_handle*/, + const gss_OID /*object*/, + const gss_buffer_t /*value*/); + +OM_uint32 _gss_spnego_set_sec_context_option ( OM_uint32 * /*minor_status*/, gss_ctx_id_t * /*context_handle*/, diff --git a/source4/heimdal/lib/gssapi/spnego/spnego_locl.h b/source4/heimdal/lib/gssapi/spnego/spnego_locl.h index 44b24688e1..6eb808efbc 100644 --- a/source4/heimdal/lib/gssapi/spnego/spnego_locl.h +++ b/source4/heimdal/lib/gssapi/spnego/spnego_locl.h @@ -30,7 +30,7 @@ * SUCH DAMAGE. */ -/* $Id: spnego_locl.h 19411 2006-12-18 15:42:03Z lha $ */ +/* $Id: spnego_locl.h 23161 2008-05-05 09:56:20Z lha $ */ #ifndef SPNEGO_LOCL_H #define SPNEGO_LOCL_H @@ -86,7 +86,6 @@ typedef struct { OM_uint32 mech_flags; OM_uint32 mech_time_rec; gss_name_t mech_src_name; - gss_cred_id_t delegated_cred_id; unsigned int open : 1; unsigned int local : 1; unsigned int require_mic : 1; diff --git a/source4/heimdal/lib/hcrypto/aes.c b/source4/heimdal/lib/hcrypto/aes.c index a36459a457..a36459a457 100755..100644 --- a/source4/heimdal/lib/hcrypto/aes.c +++ b/source4/heimdal/lib/hcrypto/aes.c diff --git a/source4/heimdal/lib/hcrypto/aes.h b/source4/heimdal/lib/hcrypto/aes.h index e91d8e73e1..eeba5c9e51 100755..100644 --- a/source4/heimdal/lib/hcrypto/aes.h +++ b/source4/heimdal/lib/hcrypto/aes.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: aes.h 17450 2006-05-05 11:11:43Z lha $ */ +/* $Id: aes.h 22958 2008-04-11 11:33:22Z lha $ */ #ifndef HEIM_AES_H #define HEIM_AES_H 1 @@ -58,6 +58,10 @@ typedef struct aes_key { int rounds; } AES_KEY; +#ifdef __cplusplus +extern "C" { +#endif + int AES_set_encrypt_key(const unsigned char *, const int, AES_KEY *); int AES_set_decrypt_key(const unsigned char *, const int, AES_KEY *); @@ -68,4 +72,8 @@ void AES_cbc_encrypt(const unsigned char *, unsigned char *, const unsigned long, const AES_KEY *, unsigned char *, int); +#ifdef __cplusplus +} +#endif + #endif /* HEIM_AES_H */ diff --git a/source4/heimdal/lib/hcrypto/bn.c b/source4/heimdal/lib/hcrypto/bn.c index 6076478bbb..1f8c1d5471 100644 --- a/source4/heimdal/lib/hcrypto/bn.c +++ b/source4/heimdal/lib/hcrypto/bn.c @@ -35,7 +35,7 @@ #include <config.h> #endif -RCSID("$Id: bn.c 22261 2007-12-09 06:24:18Z lha $"); +RCSID("$Id: bn.c 22850 2008-04-07 18:49:01Z lha $"); #include <stdio.h> #include <stdlib.h> @@ -297,13 +297,13 @@ BN_set_word(BIGNUM *bn, unsigned long num) for (num2 = num, i = 0; num2 > 0; i++) num2 = num2 >> 8; - len = i - 1; + len = i; for (; i > 0; i--) { p[i - 1] = (num & 0xff); num = num >> 8; } - bn = BN_bin2bn(p, len + 1, bn); + bn = BN_bin2bn(p, len, bn); return bn != NULL; } diff --git a/source4/heimdal/lib/hcrypto/camellia-ntt.c b/source4/heimdal/lib/hcrypto/camellia-ntt.c index c32c406baa..80fc49aef9 100644 --- a/source4/heimdal/lib/hcrypto/camellia-ntt.c +++ b/source4/heimdal/lib/hcrypto/camellia-ntt.c @@ -23,14 +23,12 @@ * http://info.isl.ntt.co.jp/crypt/eng/camellia/specifications.html */ + #include <string.h> #include <stdlib.h> -#include "camellia.h" - -/* u32 must be 32bit word */ -typedef unsigned int u32; -typedef unsigned char u8; +#include <krb5-types.h> +#include "camellia-ntt.h" /* key constants */ @@ -444,7 +442,7 @@ static const u32 camellia_sp4404[256] = { #define subl(x) subL[(x)] #define subr(x) subR[(x)] -void camellia_setup128(const unsigned char *key, u32 *subkey) +static void camellia_setup128(const unsigned char *key, u32 *subkey) { u32 kll, klr, krl, krr; u32 il, ir, t0, t1, w0, w1; @@ -655,7 +653,7 @@ void camellia_setup128(const unsigned char *key, u32 *subkey) return; } -void camellia_setup256(const unsigned char *key, u32 *subkey) +static void camellia_setup256(const unsigned char *key, u32 *subkey) { u32 kll,klr,krl,krr; /* left half of key */ u32 krll,krlr,krrl,krrr; /* right half of key */ @@ -941,7 +939,7 @@ void camellia_setup256(const unsigned char *key, u32 *subkey) return; } -void camellia_setup192(const unsigned char *key, u32 *subkey) +static void camellia_setup192(const unsigned char *key, u32 *subkey) { unsigned char kk[32]; u32 krll, krlr, krrl,krrr; @@ -963,7 +961,7 @@ void camellia_setup192(const unsigned char *key, u32 *subkey) * * "io" must be 4byte aligned and big-endian data. */ -void camellia_encrypt128(const u32 *subkey, u32 *io) +static void camellia_encrypt128(const u32 *subkey, u32 *io) { u32 il, ir, t0, t1; @@ -1053,7 +1051,7 @@ void camellia_encrypt128(const u32 *subkey, u32 *io) return; } -void camellia_decrypt128(const u32 *subkey, u32 *io) +static void camellia_decrypt128(const u32 *subkey, u32 *io) { u32 il,ir,t0,t1; /* temporary valiables */ @@ -1146,7 +1144,7 @@ void camellia_decrypt128(const u32 *subkey, u32 *io) /** * stuff for 192 and 256bit encryption/decryption */ -void camellia_encrypt256(const u32 *subkey, u32 *io) +static void camellia_encrypt256(const u32 *subkey, u32 *io) { u32 il,ir,t0,t1; /* temporary valiables */ @@ -1260,7 +1258,7 @@ void camellia_encrypt256(const u32 *subkey, u32 *io) return; } -void camellia_decrypt256(const u32 *subkey, u32 *io) +static void camellia_decrypt256(const u32 *subkey, u32 *io) { u32 il,ir,t0,t1; /* temporary valiables */ diff --git a/source4/heimdal/lib/hcrypto/camellia-ntt.h b/source4/heimdal/lib/hcrypto/camellia-ntt.h index 740ed8bfd9..8356e3b31e 100644 --- a/source4/heimdal/lib/hcrypto/camellia-ntt.h +++ b/source4/heimdal/lib/hcrypto/camellia-ntt.h @@ -29,7 +29,11 @@ extern "C" { #define CAMELLIA_TABLE_BYTE_LEN 272 #define CAMELLIA_TABLE_WORD_LEN (CAMELLIA_TABLE_BYTE_LEN / 4) -typedef unsigned int KEY_TABLE_TYPE[CAMELLIA_TABLE_WORD_LEN]; +/* u32 must be 32bit word */ +typedef uint32_t u32; +typedef unsigned char u8; + +typedef u32 KEY_TABLE_TYPE[CAMELLIA_TABLE_WORD_LEN]; void Camellia_Ekeygen(const int keyBitLength, diff --git a/source4/heimdal/lib/hcrypto/camellia.h b/source4/heimdal/lib/hcrypto/camellia.h index 3b21934b66..f736f88b1e 100644 --- a/source4/heimdal/lib/hcrypto/camellia.h +++ b/source4/heimdal/lib/hcrypto/camellia.h @@ -36,9 +36,6 @@ #ifndef HEIM_CAMELLIA_H #define HEIM_CAMELLIA_H 1 -#include <krb5-types.h> -#include "camellia-ntt.h" - /* symbol renaming */ #define CAMELLIA_set_key hc_CAMELLIA_set_encrypt_key #define CAMELLIA_encrypt hc_CAMELLIA_encrypt @@ -50,14 +47,15 @@ */ #define CAMELLIA_BLOCK_SIZE 16 -#define CAMELLIA_MAXNR 14 +#define CAMELLIA_TABLE_BYTE_LEN 272 +#define CAMELLIA_TABLE_WORD_LEN (CAMELLIA_TABLE_BYTE_LEN / 4) #define CAMELLIA_ENCRYPT 1 #define CAMELLIA_DECRYPT 0 typedef struct camellia_key { unsigned int bits; - KEY_TABLE_TYPE key; + uint32_t key[CAMELLIA_TABLE_WORD_LEN]; } CAMELLIA_KEY; int CAMELLIA_set_key(const unsigned char *, const int, CAMELLIA_KEY *); diff --git a/source4/heimdal/lib/hcrypto/des.c b/source4/heimdal/lib/hcrypto/des.c index a4444a8a7c..9e533dd708 100644 --- a/source4/heimdal/lib/hcrypto/des.c +++ b/source4/heimdal/lib/hcrypto/des.c @@ -31,7 +31,46 @@ * SUCH DAMAGE. */ -/* +/** + * @page page_des DES - Data Encryption Standard crypto interface + * + * See the library functions here: @ref hcrypto_des + * + * DES was created by IBM, modififed by NSA and then adopted by NBS + * (now NIST) and published ad FIPS PUB 46 (updated by FIPS 46-1). + * + * Since the 19th May 2005 DES was withdrawn by NIST and should no + * longer be used. See @ref page_evp for replacement encryption + * algorithms and interfaces. + * + * Read more the iteresting history of DES on Wikipedia + * http://www.wikipedia.org/wiki/Data_Encryption_Standard . + * + * @section des_keygen DES key generation + * + * To generate a DES key safely you have to use the code-snippet + * below. This is because the DES_random_key() can fail with an + * abort() in case of and failure to start the random generator. + * + * There is a replacement function DES_new_random_key(), however that + * function does not exists in OpenSSL. + * + * @code + * DES_cblock key; + * do { + * if (RAND_rand(&key, sizeof(key)) != 1) + * goto failure; + * DES_set_odd_parity(key); + * } while (DES_is_weak_key(&key)); + * @endcode + * + * @section des_impl DES implementation history + * + * There was no complete BSD licensed, fast, GPL compatible + * implementation of DES, so Love wrote the part that was missing, + * fast key schedule setup and adapted the interface to the orignal + * libdes. + * * The document that got me started for real was "Efficient * Implementation of the Data Encryption Standard" by Dag Arne Osvik. * I never got to the PC1 transformation was working, instead I used @@ -45,9 +84,11 @@ #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$Id: des.c 17211 2006-04-24 14:26:19Z lha $"); +RCSID("$Id: des.c 23117 2008-04-28 10:29:36Z lha $"); #endif +#define HC_DEPRECATED + #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -70,17 +111,39 @@ static void FP(uint32_t [2]); x = ( ((x)<<(2)) & 0xffffffc) | ((x) >> 26); \ } -/* +/** + * Set the parity of the key block, used to generate a des key from a + * random key. See @ref des_keygen. * + * @param key key to fixup the parity for. + * @ingroup hcrypto_des */ -int +void DES_set_odd_parity(DES_cblock *key) { - int i; + unsigned int i; for (i = 0; i < DES_CBLOCK_LEN; i++) (*key)[i] = odd_parity[(*key)[i]]; - return 0; +} + +/** + * Check if the key have correct parity. + * + * @param key key to check the parity. + * @return 1 on success, 0 on failure. + * @ingroup hcrypto_des + */ + +int HC_DEPRECATED +DES_check_key_parity(DES_cblock *key) +{ + unsigned int i; + + for (i = 0; i < DES_CBLOCK_LEN; i++) + if ((*key)[i] != odd_parity[(*key)[i]]) + return 0; + return 1; } /* @@ -107,6 +170,16 @@ static DES_cblock weak_keys[] = { {0xFE,0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1} }; +/** + * Checks if the key is any of the weaks keys that makes DES attacks + * trival. + * + * @param key key to check. + * + * @return 1 if the key is weak, 0 otherwise. + * @ingroup hcrypto_des + */ + int DES_is_weak_key(DES_cblock *key) { @@ -119,13 +192,38 @@ DES_is_weak_key(DES_cblock *key) return 0; } +/** + * Setup a des key schedule from a key. Deprecated function, use + * DES_set_key_unchecked() or DES_set_key_checked() instead. + * + * @param key a key to initialize the key schedule with. + * @param ks a key schedule to initialize. + * + * @return 0 on success + * @ingroup hcrypto_des + */ -/* +int HC_DEPRECATED +DES_set_key(DES_cblock *key, DES_key_schedule *ks) +{ + return DES_set_key_checked(key, ks); +} + +/** + * Setup a des key schedule from a key. The key is no longer needed + * after this transaction and can cleared. * + * Does NOT check that the key is weak for or have wrong parity. + * + * @param key a key to initialize the key schedule with. + * @param ks a key schedule to initialize. + * + * @return 0 on success + * @ingroup hcrypto_des */ int -DES_set_key(DES_cblock *key, DES_key_schedule *ks) +DES_set_key_unchecked(DES_cblock *key, DES_key_schedule *ks) { uint32_t t1, t2; uint32_t c, d; @@ -184,28 +282,46 @@ DES_set_key(DES_cblock *key, DES_key_schedule *ks) return 0; } -/* +/** + * Just like DES_set_key_unchecked() except checking that the key is + * not weak for or have correct parity. + * + * @param key a key to initialize the key schedule with. + * @param ks a key schedule to initialize. * + * @return 0 on success, -1 on invalid parity, -2 on weak key. + * @ingroup hcrypto_des */ int DES_set_key_checked(DES_cblock *key, DES_key_schedule *ks) { + if (!DES_check_key_parity(key)) { + memset(ks, 0, sizeof(*ks)); + return -1; + } if (DES_is_weak_key(key)) { memset(ks, 0, sizeof(*ks)); - return 1; + return -2; } - return DES_set_key(key, ks); + return DES_set_key_unchecked(key, ks); } -/* - * Compatibility function for eay libdes +/** + * Compatibility function for eay libdes, works just like + * DES_set_key_checked(). + * + * @param key a key to initialize the key schedule with. + * @param ks a key schedule to initialize. + * + * @return 0 on success, -1 on invalid parity, -2 on weak key. + * @ingroup hcrypto_des */ int DES_key_sched(DES_cblock *key, DES_key_schedule *ks) { - return DES_set_key(key, ks); + return DES_set_key_checked(key, ks); } /* @@ -238,39 +354,63 @@ store(const uint32_t v[2], unsigned char *b) b[7] = (v[1] >> 0) & 0xff; } -/* +/** + * Encrypt/decrypt a block using DES. Also called ECB mode + * + * @param u data to encrypt + * @param ks key schedule to use + * @param encp if non zero, encrypt. if zero, decrypt. * + * @ingroup hcrypto_des */ void -DES_encrypt(uint32_t u[2], DES_key_schedule *ks, int forward_encrypt) +DES_encrypt(uint32_t u[2], DES_key_schedule *ks, int encp) { IP(u); - desx(u, ks, forward_encrypt); + desx(u, ks, encp); FP(u); } -/* +/** + * Encrypt/decrypt a block using DES. * + * @param input data to encrypt + * @param output data to encrypt + * @param ks key schedule to use + * @param encp if non zero, encrypt. if zero, decrypt. + * + * @ingroup hcrypto_des */ void DES_ecb_encrypt(DES_cblock *input, DES_cblock *output, - DES_key_schedule *ks, int forward_encrypt) + DES_key_schedule *ks, int encp) { uint32_t u[2]; load(*input, u); - DES_encrypt(u, ks, forward_encrypt); + DES_encrypt(u, ks, encp); store(u, *output); } -/* +/** + * Encrypt/decrypt a block using DES in Chain Block Cipher mode (cbc). * + * The IV must always be diffrent for diffrent input data blocks. + * + * @param in data to encrypt + * @param out data to encrypt + * @param length length of data + * @param ks key schedule to use + * @param iv initial vector to use + * @param encp if non zero, encrypt. if zero, decrypt. + * + * @ingroup hcrypto_des */ void DES_cbc_encrypt(const void *in, void *out, long length, - DES_key_schedule *ks, DES_cblock *iv, int forward_encrypt) + DES_key_schedule *ks, DES_cblock *iv, int encp) { const unsigned char *input = in; unsigned char *output = out; @@ -279,7 +419,7 @@ DES_cbc_encrypt(const void *in, void *out, long length, load(*iv, uiv); - if (forward_encrypt) { + if (encp) { while (length >= DES_CBLOCK_LEN) { load(input, u); u[0] ^= uiv[0]; u[1] ^= uiv[1]; @@ -327,13 +467,26 @@ DES_cbc_encrypt(const void *in, void *out, long length, uiv[0] = 0; u[0] = 0; uiv[1] = 0; u[1] = 0; } -/* +/** + * Encrypt/decrypt a block using DES in Propagating Cipher Block + * Chaining mode. This mode is only used for Kerberos 4, and it should + * stay that way. + * + * The IV must always be diffrent for diffrent input data blocks. * + * @param in data to encrypt + * @param out data to encrypt + * @param length length of data + * @param ks key schedule to use + * @param iv initial vector to use + * @param encp if non zero, encrypt. if zero, decrypt. + * + * @ingroup hcrypto_des */ void DES_pcbc_encrypt(const void *in, void *out, long length, - DES_key_schedule *ks, DES_cblock *iv, int forward_encrypt) + DES_key_schedule *ks, DES_cblock *iv, int encp) { const unsigned char *input = in; unsigned char *output = out; @@ -342,7 +495,7 @@ DES_pcbc_encrypt(const void *in, void *out, long length, load(*iv, uiv); - if (forward_encrypt) { + if (encp) { uint32_t t[2]; while (length >= DES_CBLOCK_LEN) { load(input, u); @@ -397,10 +550,10 @@ DES_pcbc_encrypt(const void *in, void *out, long length, static void _des3_encrypt(uint32_t u[2], DES_key_schedule *ks1, DES_key_schedule *ks2, - DES_key_schedule *ks3, int forward_encrypt) + DES_key_schedule *ks3, int encp) { IP(u); - if (forward_encrypt) { + if (encp) { desx(u, ks1, 1); /* IP + FP cancel out each other */ desx(u, ks2, 0); desx(u, ks3, 1); @@ -412,8 +565,18 @@ _des3_encrypt(uint32_t u[2], DES_key_schedule *ks1, DES_key_schedule *ks2, FP(u); } -/* +/** + * Encrypt/decrypt a block using triple DES using EDE mode, + * encrypt/decrypt/encrypt. + * + * @param input data to encrypt + * @param output data to encrypt + * @param ks1 key schedule to use + * @param ks2 key schedule to use + * @param ks3 key schedule to use + * @param encp if non zero, encrypt. if zero, decrypt. * + * @ingroup hcrypto_des */ void @@ -422,24 +585,37 @@ DES_ecb3_encrypt(DES_cblock *input, DES_key_schedule *ks1, DES_key_schedule *ks2, DES_key_schedule *ks3, - int forward_encrypt) + int encp) { uint32_t u[2]; load(*input, u); - _des3_encrypt(u, ks1, ks2, ks3, forward_encrypt); + _des3_encrypt(u, ks1, ks2, ks3, encp); store(u, *output); return; } -/* +/** + * Encrypt/decrypt using Triple DES in Chain Block Cipher mode (cbc). + * + * The IV must always be diffrent for diffrent input data blocks. * + * @param in data to encrypt + * @param out data to encrypt + * @param length length of data + * @param ks1 key schedule to use + * @param ks2 key schedule to use + * @param ks3 key schedule to use + * @param iv initial vector to use + * @param encp if non zero, encrypt. if zero, decrypt. + * + * @ingroup hcrypto_des */ void DES_ede3_cbc_encrypt(const void *in, void *out, long length, DES_key_schedule *ks1, DES_key_schedule *ks2, DES_key_schedule *ks3, - DES_cblock *iv, int forward_encrypt) + DES_cblock *iv, int encp) { const unsigned char *input = in; unsigned char *output = out; @@ -448,7 +624,7 @@ DES_ede3_cbc_encrypt(const void *in, void *out, load(*iv, uiv); - if (forward_encrypt) { + if (encp) { while (length >= DES_CBLOCK_LEN) { load(input, u); u[0] ^= uiv[0]; u[1] ^= uiv[1]; @@ -497,14 +673,27 @@ DES_ede3_cbc_encrypt(const void *in, void *out, uiv[0] = 0; u[0] = 0; uiv[1] = 0; u[1] = 0; } -/* +/** + * Encrypt/decrypt using DES in cipher feedback mode with 64 bit + * feedback. + * + * The IV must always be diffrent for diffrent input data blocks. + * + * @param in data to encrypt + * @param out data to encrypt + * @param length length of data + * @param ks key schedule to use + * @param iv initial vector to use + * @param num offset into in cipher block encryption/decryption stop last time. + * @param encp if non zero, encrypt. if zero, decrypt. * + * @ingroup hcrypto_des */ void DES_cfb64_encrypt(const void *in, void *out, long length, DES_key_schedule *ks, DES_cblock *iv, - int *num, int forward_encrypt) + int *num, int encp) { const unsigned char *input = in; unsigned char *output = out; @@ -515,7 +704,7 @@ DES_cfb64_encrypt(const void *in, void *out, assert(*num >= 0 && *num < DES_CBLOCK_LEN); - if (forward_encrypt) { + if (encp) { int i = *num; while (length > 0) { @@ -562,8 +751,19 @@ DES_cfb64_encrypt(const void *in, void *out, } } -/* +/** + * Crete a checksum using DES in CBC encryption mode. This mode is + * only used for Kerberos 4, and it should stay that way. + * + * The IV must always be diffrent for diffrent input data blocks. + * + * @param in data to checksum + * @param output the checksum + * @param length length of data + * @param ks key schedule to use + * @param iv initial vector to use * + * @ingroup hcrypto_des */ uint32_t @@ -616,6 +816,16 @@ bitswap8(unsigned char b) return r; } +/** + * Convert a string to a DES key. Use something like + * PKCS5_PBKDF2_HMAC_SHA1() to create key from passwords. + * + * @param str The string to convert to a key + * @param key the resulting key + * + * @ingroup hcrypto_des + */ + void DES_string_to_key(const char *str, DES_cblock *key) { @@ -646,8 +856,16 @@ DES_string_to_key(const char *str, DES_cblock *key) k[7] ^= 0xF0; } -/* +/** + * Read password from prompt and create a DES key. Internal uses + * DES_string_to_key(). Really, go use a really string2key function + * like PKCS5_PBKDF2_HMAC_SHA1(). + * + * @param key key to convert to + * @param prompt prompt to display user + * @param verify prompt twice. * + * @return 1 on success, non 1 on failure. */ int @@ -657,7 +875,7 @@ DES_read_password(DES_cblock *key, char *prompt, int verify) int ret; ret = UI_UTIL_read_pw_string(buf, sizeof(buf) - 1, prompt, verify); - if (ret == 0) + if (ret == 1) DES_string_to_key(buf, key); return ret; } @@ -892,7 +1110,7 @@ FP(uint32_t v[2]) } static void -desx(uint32_t block[2], DES_key_schedule *ks, int forward_encrypt) +desx(uint32_t block[2], DES_key_schedule *ks, int encp) { uint32_t *keys; uint32_t fval, work, right, left; @@ -901,7 +1119,7 @@ desx(uint32_t block[2], DES_key_schedule *ks, int forward_encrypt) left = block[0]; right = block[1]; - if (forward_encrypt) { + if (encp) { keys = &ks->ks[0]; for( round = 0; round < 8; round++ ) { diff --git a/source4/heimdal/lib/hcrypto/des.h b/source4/heimdal/lib/hcrypto/des.h index ac8deb8ab8..3c52f59e28 100644 --- a/source4/heimdal/lib/hcrypto/des.h +++ b/source4/heimdal/lib/hcrypto/des.h @@ -31,36 +31,38 @@ * SUCH DAMAGE. */ -/* $Id: des.h 16480 2006-01-08 21:47:29Z lha $ */ +/* $Id: des.h 23148 2008-04-29 05:53:27Z biorn $ */ #ifndef _DESperate_H #define _DESperate_H 1 /* symbol renaming */ -#define DES_set_odd_parity hc_DES_set_odd_parity +#define _DES_ipfp_test _hc_DES_ipfp_test +#define DES_cbc_cksum hc_DES_cbc_cksum +#define DES_cbc_encrypt hc_DES_cbc_encrypt +#define DES_cfb64_encrypt hc_DES_cfb64_encrypt +#define DES_check_key_parity hc_DES_check_key_parity +#define DES_ecb3_encrypt hc_DES_ecb3_encrypt +#define DES_ecb_encrypt hc_DES_ecb_encrypt +#define DES_ede3_cbc_encrypt hc_DES_ede3_cbc_encrypt +#define DES_encrypt hc_DES_encrypt +#define DES_generate_random_block hc_DES_generate_random_block +#define DES_init_random_number_generator hc_DES_init_random_number_generator #define DES_is_weak_key hc_DES_is_weak_key #define DES_key_sched hc_DES_key_sched +#define DES_new_random_key hc_DES_new_random_key +#define DES_pcbc_encrypt hc_DES_pcbc_encrypt +#define DES_rand_data hc_DES_rand_data +#define DES_random_key hc_DES_random_key +#define DES_read_password hc_DES_read_password #define DES_set_key hc_DES_set_key #define DES_set_key_checked hc_DES_set_key_checked +#define DES_set_key_unchecked hc_DES_set_key_unchecked #define DES_set_key_sched hc_DES_set_key_sched -#define DES_new_random_key hc_DES_new_random_key -#define DES_string_to_key hc_DES_string_to_key -#define DES_read_password hc_DES_read_password -#define DES_rand_data hc_DES_rand_data +#define DES_set_odd_parity hc_DES_set_odd_parity #define DES_set_random_generator_seed hc_DES_set_random_generator_seed -#define DES_generate_random_block hc_DES_generate_random_block #define DES_set_sequence_number hc_DES_set_sequence_number -#define DES_init_random_number_generator hc_DES_init_random_number_generator -#define DES_random_key hc_DES_random_key -#define DES_encrypt hc_DES_encrypt -#define DES_ecb_encrypt hc_DES_ecb_encrypt -#define DES_ecb3_encrypt hc_DES_ecb3_encrypt -#define DES_pcbc_encrypt hc_DES_pcbc_encrypt -#define DES_cbc_encrypt hc_DES_cbc_encrypt -#define DES_cbc_cksum hc_DES_cbc_cksum -#define DES_ede3_cbc_encrypt hc_DES_ede3_cbc_encrypt -#define DES_cfb64_encrypt hc_DES_cfb64_encrypt -#define _DES_ipfp_test _hc_DES_ipfp_test +#define DES_string_to_key hc_DES_string_to_key /* * @@ -82,21 +84,35 @@ typedef struct DES_key_schedule * */ -int DES_set_odd_parity(DES_cblock *); +#if !defined(__GNUC__) && !defined(__attribute__) +#define __attribute__(x) +#endif + +#ifndef HC_DEPRECATED +#define HC_DEPRECATED __attribute__((deprecated)) +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +void DES_set_odd_parity(DES_cblock *); +int DES_check_key_parity(DES_cblock *); int DES_is_weak_key(DES_cblock *); -int DES_set_key(DES_cblock *, DES_key_schedule *); +int HC_DEPRECATED DES_set_key(DES_cblock *, DES_key_schedule *); int DES_set_key_checked(DES_cblock *, DES_key_schedule *); +int DES_set_key_unchecked(DES_cblock *, DES_key_schedule *); int DES_key_sched(DES_cblock *, DES_key_schedule *); -int DES_new_random_key(DES_cblock *); void DES_string_to_key(const char *, DES_cblock *); int DES_read_password(DES_cblock *, char *, int); -void DES_rand_data(void *, int); -void DES_set_random_generator_seed(DES_cblock *); -void DES_generate_random_block(DES_cblock *); -void DES_set_sequence_number(void *); -void DES_init_random_number_generator(DES_cblock *); -void DES_random_key(DES_cblock *); +void HC_DEPRECATED DES_rand_data(void *, int); +void HC_DEPRECATED DES_set_random_generator_seed(DES_cblock *); +void HC_DEPRECATED DES_generate_random_block(DES_cblock *); +void HC_DEPRECATED DES_set_sequence_number(void *); +void HC_DEPRECATED DES_init_random_number_generator(DES_cblock *); +void HC_DEPRECATED DES_random_key(DES_cblock *); +int HC_DEPRECATED DES_new_random_key(DES_cblock *); void DES_encrypt(uint32_t [2], DES_key_schedule *, int); @@ -110,8 +126,8 @@ void DES_cbc_encrypt(const void *, void *, long, void DES_ede3_cbc_encrypt(const void *, void *, long, DES_key_schedule *, DES_key_schedule *, DES_key_schedule *, DES_cblock *, int); -void DES_cfb64_encrypt(const void *, void *, long, - DES_key_schedule *, DES_cblock *, int *, int); +void DES_cfb64_encrypt(const void *, void *, long, + DES_key_schedule *, DES_cblock *, int *, int); uint32_t DES_cbc_cksum(const void *, DES_cblock *, @@ -120,5 +136,9 @@ uint32_t DES_cbc_cksum(const void *, DES_cblock *, void _DES_ipfp_test(void); +#ifdef __cplusplus +} +#endif + #endif /* _DESperate_H */ diff --git a/source4/heimdal/lib/hcrypto/evp.c b/source4/heimdal/lib/hcrypto/evp.c index 788000b054..b4fb8a7f23 100644 --- a/source4/heimdal/lib/hcrypto/evp.c +++ b/source4/heimdal/lib/hcrypto/evp.c @@ -35,7 +35,9 @@ #include <config.h> #endif -RCSID("$Id: evp.c 22379 2007-12-29 11:13:26Z lha $"); +RCSID("$Id: evp.c 23144 2008-04-29 05:47:16Z lha $"); + +#define HC_DEPRECATED #include <sys/types.h> #include <stdio.h> @@ -79,6 +81,13 @@ struct hc_evp_md { evp_md_cleanup cleanup; }; +struct hc_EVP_MD_CTX { + const EVP_MD *md; + ENGINE *engine; + void *ptr; +}; + + /** * Return the output size of the message digest function. * @@ -135,7 +144,7 @@ EVP_MD_CTX_create(void) * @ingroup hcrypto_evp */ -void +void HC_DEPRECATED EVP_MD_CTX_init(EVP_MD_CTX *ctx) { memset(ctx, 0, sizeof(*ctx)); @@ -166,7 +175,7 @@ EVP_MD_CTX_destroy(EVP_MD_CTX *ctx) * @ingroup hcrypto_evp */ -int +int HC_DEPRECATED EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx) { if (ctx->md && ctx->md->cleanup) @@ -508,7 +517,6 @@ EVP_md_null(void) } #if 0 -void EVP_MD_CTX_init(EVP_MD_CTX *ctx); int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type); int EVP_DigestFinal(EVP_MD_CTX *ctx,unsigned char *md,unsigned int *s); int EVP_SignFinal(EVP_MD_CTX *, void *, size_t *, EVP_PKEY *); @@ -1050,10 +1058,19 @@ des_ede3_cbc_init(EVP_CIPHER_CTX *ctx, int encp) { struct des_ede3_cbc *k = ctx->cipher_data; + DES_cblock deskey; + + memcpy(&deskey, key, sizeof(deskey)); + DES_set_odd_parity(&deskey); + DES_set_key_unchecked(&deskey, &k->ks[0]); + + memcpy(&deskey, key + 8, sizeof(deskey)); + DES_set_odd_parity(&deskey); + DES_set_key_unchecked(&deskey, &k->ks[1]); - DES_key_sched((DES_cblock *)(key), &k->ks[0]); - DES_key_sched((DES_cblock *)(key + 8), &k->ks[1]); - DES_key_sched((DES_cblock *)(key + 16), &k->ks[2]); + memcpy(&deskey, key + 16, sizeof(deskey)); + DES_set_odd_parity(&deskey); + DES_set_key_unchecked(&deskey, &k->ks[2]); return 1; } diff --git a/source4/heimdal/lib/hcrypto/evp.h b/source4/heimdal/lib/hcrypto/evp.h index 4910ca01b8..c8f8f80f80 100644 --- a/source4/heimdal/lib/hcrypto/evp.h +++ b/source4/heimdal/lib/hcrypto/evp.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: evp.h 21687 2007-07-24 16:29:05Z lha $ */ +/* $Id: evp.h 23141 2008-04-29 05:47:04Z lha $ */ #ifndef HEIM_EVP_H #define HEIM_EVP_H 1 @@ -155,11 +155,17 @@ struct hc_CIPHER_CTX { unsigned char final[EVP_MAX_BLOCK_LENGTH]; }; -struct hc_EVP_MD_CTX { - const EVP_MD *md; - ENGINE *engine; - void *ptr; -}; +#if !defined(__GNUC__) && !defined(__attribute__) +#define __attribute__(x) +#endif + +#ifndef HC_DEPRECATED +#define HC_DEPRECATED __attribute__((deprecated)) +#endif + +#ifdef __cplusplus +extern "C" { +#endif /* * Avaible crypto algs @@ -201,9 +207,9 @@ size_t EVP_MD_CTX_block_size(EVP_MD_CTX *); EVP_MD_CTX * EVP_MD_CTX_create(void); -void EVP_MD_CTX_init(EVP_MD_CTX *); +void HC_DEPRECATED EVP_MD_CTX_init(EVP_MD_CTX *); void EVP_MD_CTX_destroy(EVP_MD_CTX *); -int EVP_MD_CTX_cleanup(EVP_MD_CTX *); +int HC_DEPRECATED EVP_MD_CTX_cleanup(EVP_MD_CTX *); int EVP_DigestInit_ex(EVP_MD_CTX *, const EVP_MD *, ENGINE *); int EVP_DigestUpdate(EVP_MD_CTX *,const void *, size_t); @@ -258,4 +264,8 @@ void OpenSSL_add_all_algorithms(void); void OpenSSL_add_all_algorithms_conf(void); void OpenSSL_add_all_algorithms_noconf(void); +#ifdef __cplusplus +} +#endif + #endif /* HEIM_EVP_H */ diff --git a/source4/heimdal/lib/hcrypto/imath/LICENSE b/source4/heimdal/lib/hcrypto/imath/LICENSE index cecfb11404..53dd364c2b 100644 --- a/source4/heimdal/lib/hcrypto/imath/LICENSE +++ b/source4/heimdal/lib/hcrypto/imath/LICENSE @@ -1,4 +1,4 @@ -IMath is Copyright 2002-2006 Michael J. Fromberger +IMath is Copyright 2002-2007 Michael J. Fromberger You may use it subject to the following Licensing Terms: Permission is hereby granted, free of charge, to any person obtaining diff --git a/source4/heimdal/lib/hcrypto/pkcs12.c b/source4/heimdal/lib/hcrypto/pkcs12.c index b43fe571d6..fcf04a73c1 100644 --- a/source4/heimdal/lib/hcrypto/pkcs12.c +++ b/source4/heimdal/lib/hcrypto/pkcs12.c @@ -35,7 +35,7 @@ #include <config.h> #endif -RCSID("$Id: pkcs12.c 21155 2007-06-18 21:59:44Z lha $"); +RCSID("$Id: pkcs12.c 23137 2008-04-29 05:46:48Z lha $"); #include <stdio.h> #include <stdlib.h> @@ -55,19 +55,24 @@ PKCS12_key_gen(const void *key, size_t keylen, unsigned char *v, *I, hash[EVP_MAX_MD_SIZE]; unsigned int size, size_I = 0; unsigned char idc = id; - EVP_MD_CTX ctx; + EVP_MD_CTX *ctx; unsigned char *outp = out; int i, vlen; - EVP_MD_CTX_init(&ctx); + ctx = EVP_MD_CTX_create(); + if (ctx == NULL) + return 0; vlen = EVP_MD_block_size(md); v = malloc(vlen + 1); - if (v == NULL) + if (v == NULL) { + EVP_MD_CTX_destroy(ctx); return 0; + } I = calloc(1, vlen * 2); if (I == NULL) { + EVP_MD_CTX_destroy(ctx); free(v); return 0; } @@ -93,15 +98,16 @@ PKCS12_key_gen(const void *key, size_t keylen, while (1) { BIGNUM *bnB, *bnOne; - if (!EVP_DigestInit_ex(&ctx, md, NULL)) { + if (!EVP_DigestInit_ex(ctx, md, NULL)) { + EVP_MD_CTX_destroy(ctx); free(I); free(v); return 0; } for (i = 0; i < vlen; i++) - EVP_DigestUpdate(&ctx, &idc, 1); - EVP_DigestUpdate(&ctx, I, size_I); - EVP_DigestFinal_ex(&ctx, hash, &size); + EVP_DigestUpdate(ctx, &idc, 1); + EVP_DigestUpdate(ctx, I, size_I); + EVP_DigestFinal_ex(ctx, hash, &size); for (i = 1; i < iteration; i++) EVP_Digest(hash, size, hash, &size, md, NULL); @@ -145,7 +151,7 @@ PKCS12_key_gen(const void *key, size_t keylen, size_I = vlen * 2; } - EVP_MD_CTX_cleanup(&ctx); + EVP_MD_CTX_destroy(ctx); free(I); free(v); diff --git a/source4/heimdal/lib/hcrypto/pkcs5.c b/source4/heimdal/lib/hcrypto/pkcs5.c index 85b8713cba..8a8f948abb 100644 --- a/source4/heimdal/lib/hcrypto/pkcs5.c +++ b/source4/heimdal/lib/hcrypto/pkcs5.c @@ -35,7 +35,7 @@ #include <config.h> #endif -RCSID("$Id: pkcs5.c 17445 2006-05-05 10:37:46Z lha $"); +RCSID("$Id: pkcs5.c 23059 2008-04-18 13:04:08Z lha $"); #ifdef KRB5 #include <krb5-types.h> @@ -49,6 +49,22 @@ RCSID("$Id: pkcs5.c 17445 2006-05-05 10:37:46Z lha $"); #include <roken.h> +/** + * As descriped in PKCS5, convert a password, salt, and iteration counter into a crypto key. + * + * @param password Password. + * @param password_len Length of password. + * @param salt Salt + * @param salt_len Length of salt. + * @param iter iteration counter. + * @param keylen the output key length. + * @param key the output key. + * + * @return 1 on success, non 1 on failure. + * + * @ingroup hcrypto_misc + */ + int PKCS5_PBKDF2_HMAC_SHA1(const void * password, size_t password_len, const void * salt, size_t salt_len, diff --git a/source4/heimdal/lib/hcrypto/rand-egd.c b/source4/heimdal/lib/hcrypto/rand-egd.c index 497a3ab5f8..c1f306bcc3 100644 --- a/source4/heimdal/lib/hcrypto/rand-egd.c +++ b/source4/heimdal/lib/hcrypto/rand-egd.c @@ -35,7 +35,7 @@ #include <config.h> #endif -RCSID("$Id: rand-egd.c 21156 2007-06-18 22:00:59Z lha $"); +RCSID("$Id: rand-egd.c 23461 2008-07-27 12:14:20Z lha $"); #include <sys/types.h> #ifdef HAVE_SYS_UN_H @@ -76,6 +76,8 @@ connect_egd(const char *path) if (fd < 0) return -1; + rk_cloexec(fd); + if (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) != 0) { close(fd); return -1; diff --git a/source4/heimdal/lib/hcrypto/rand-fortuna.c b/source4/heimdal/lib/hcrypto/rand-fortuna.c index 1d47ed49cc..da59a433b1 100644 --- a/source4/heimdal/lib/hcrypto/rand-fortuna.c +++ b/source4/heimdal/lib/hcrypto/rand-fortuna.c @@ -33,7 +33,7 @@ #include <config.h> #endif -RCSID("$Id: rand-fortuna.c 21196 2007-06-20 05:08:58Z lha $"); +RCSID("$Id: rand-fortuna.c 23463 2008-07-27 12:15:06Z lha $"); #include <stdio.h> #include <stdlib.h> @@ -118,6 +118,7 @@ struct fortuna_state unsigned pool0_bytes; unsigned rnd_pos; int tricks_done; + pid_t pid; }; typedef struct fortuna_state FState; @@ -175,6 +176,7 @@ init_state(FState * st) memset(st, 0, sizeof(*st)); for (i = 0; i < NUM_POOLS; i++) md_init(&st->pool[i]); + st->pid = getpid(); } /* @@ -276,6 +278,9 @@ reseed(FState * st) /* add old key into mix too */ md_update(&key_md, st->key, BLOCK); + /* add pid to make output diverse after fork() */ + md_update(&key_md, (const unsigned char *)&st->pid, sizeof(st->pid)); + /* now we have new key */ md_result(&key_md, st->key); @@ -384,6 +389,7 @@ extract_data(FState * st, unsigned count, unsigned char *dst) { unsigned n; unsigned block_nr = 0; + pid_t pid = getpid(); /* Should we reseed? */ if (st->pool0_bytes >= POOL0_FILL || st->reseed_count == 0) @@ -394,6 +400,12 @@ extract_data(FState * st, unsigned count, unsigned char *dst) if (!st->tricks_done) startup_tricks(st); + /* If we forked, force a reseed again */ + if (pid != st->pid) { + st->pid = pid; + reseed(st); + } + while (count > 0) { /* produce bytes */ @@ -493,6 +505,7 @@ fortuna_reseed(void) fd = open("/etc/shadow", O_RDONLY, 0); if (fd >= 0) { ssize_t n; + rk_cloexec(fd); /* add_entropy will hash the buf */ while ((n = read(fd, (char *)u.shad, sizeof(u.shad))) > 0) add_entropy(&main_state, u.shad, sizeof(u.shad)); diff --git a/source4/heimdal/lib/hcrypto/rand-unix.c b/source4/heimdal/lib/hcrypto/rand-unix.c index 354492fb3d..5fb099d724 100644 --- a/source4/heimdal/lib/hcrypto/rand-unix.c +++ b/source4/heimdal/lib/hcrypto/rand-unix.c @@ -35,7 +35,7 @@ #include <config.h> #endif -RCSID("$Id: rand-unix.c 20028 2007-01-21 09:54:56Z lha $"); +RCSID("$Id: rand-unix.c 23462 2008-07-27 12:14:42Z lha $"); #include <stdio.h> #include <stdlib.h> @@ -63,8 +63,10 @@ get_device_fd(int flags) for(p = rnd_devices; *p; p++) { int fd = open(*p, flags | O_NDELAY); - if(fd >= 0) + if(fd >= 0) { + rk_cloexec(fd); return fd; + } } return -1; } diff --git a/source4/heimdal/lib/hcrypto/rand.c b/source4/heimdal/lib/hcrypto/rand.c index 79dd39eb76..1561f2ad39 100644 --- a/source4/heimdal/lib/hcrypto/rand.c +++ b/source4/heimdal/lib/hcrypto/rand.c @@ -35,7 +35,7 @@ #include <config.h> #endif -RCSID("$Id: rand.c 22199 2007-12-07 13:43:25Z lha $"); +RCSID("$Id: rand.c 23464 2008-07-27 12:15:21Z lha $"); #include <stdio.h> #include <stdlib.h> @@ -48,8 +48,14 @@ RCSID("$Id: rand.c 22199 2007-12-07 13:43:25Z lha $"); #define O_BINARY 0 #endif +/** + * @page page_rand RAND - random number + * + * See the library functions here: @ref hcrypto_rand + */ const static RAND_METHOD *selected_meth = NULL; +static ENGINE *selected_engine = NULL; static void init_method(void) @@ -59,6 +65,16 @@ init_method(void) selected_meth = &hc_rand_fortuna_method; } +/** + * Seed that random number generator. Secret material can securely be + * feed into the function, they will never be returned. + * + * @param indata seed data + * @param size length seed data + * + * @ingroup hcrypto_rand + */ + void RAND_seed(const void *indata, size_t size) { @@ -66,6 +82,16 @@ RAND_seed(const void *indata, size_t size) (*selected_meth->seed)(indata, size); } +/** + * Get a random block from the random generator, can be used for key material. + * + * @param outdata random data + * @param size length random data + * + * @return 1 on success, 0 on failure. + * + * @ingroup hcrypto_rand + */ int RAND_bytes(void *outdata, size_t size) { @@ -73,13 +99,39 @@ RAND_bytes(void *outdata, size_t size) return (*selected_meth->bytes)(outdata, size); } +/** + * Reset and free memory used by the random generator. + * + * @ingroup hcrypto_rand + */ + void RAND_cleanup(void) { - init_method(); - (*selected_meth->cleanup)(); + const RAND_METHOD *meth = selected_meth; + ENGINE *engine = selected_engine; + + selected_meth = NULL; + selected_engine = NULL; + + if (meth) + (*meth->cleanup)(); + if (engine) + ENGINE_finish(engine); } +/** + * Seed that random number generator. Secret material can securely be + * feed into the function, they will never be returned. + * + * @param indata the input data. + * @param size size of in data. + * @param entropi entropi in data. + * + * + * @ingroup hcrypto_rand + */ + void RAND_add(const void *indata, size_t size, double entropi) { @@ -87,6 +139,17 @@ RAND_add(const void *indata, size_t size, double entropi) (*selected_meth->add)(indata, size, entropi); } +/** + * Get a random block from the random generator, should NOT be used for key material. + * + * @param outdata random data + * @param size length random data + * + * @return 1 on success, 0 on failure. + * + * @ingroup hcrypto_rand + */ + int RAND_pseudo_bytes(void *outdata, size_t size) { @@ -94,6 +157,14 @@ RAND_pseudo_bytes(void *outdata, size_t size) return (*selected_meth->pseudorand)(outdata, size); } +/** + * Return status of the random generator + * + * @return 1 if the random generator can deliver random data. + * + * @ingroup hcrypto_rand + */ + int RAND_status(void) { @@ -101,27 +172,92 @@ RAND_status(void) return (*selected_meth->status)(); } +/** + * Set the default random method. + * + * @param meth set the new default method. + * + * @return 1 on success. + * + * @ingroup hcrypto_rand + */ + int RAND_set_rand_method(const RAND_METHOD *meth) { + const RAND_METHOD *old = selected_meth; selected_meth = meth; + if (old) + (*old->cleanup)(); + if (selected_engine) { + ENGINE_finish(selected_engine); + selected_engine = NULL; + } return 1; } +/** + * Get the default random method. + * + * @ingroup hcrypto_rand + */ + const RAND_METHOD * RAND_get_rand_method(void) { + init_method(); return selected_meth; } +/** + * Set the default random method from engine. + * + * @param engine use engine, if NULL is passed it, old method and engine is cleared. + * + * @return 1 on success, 0 on failure. + * + * @ingroup hcrypto_rand + */ + int RAND_set_rand_engine(ENGINE *engine) { + const RAND_METHOD *meth, *old = selected_meth; + + if (engine) { + ENGINE_up_ref(engine); + meth = ENGINE_get_RAND(engine); + if (meth == NULL) { + ENGINE_finish(engine); + return 0; + } + } else { + meth = NULL; + } + + if (old) + (*old->cleanup)(); + + if (selected_engine) + ENGINE_finish(selected_engine); + + selected_engine = engine; + selected_meth = meth; + return 1; } #define RAND_FILE_SIZE 1024 +/** + * Load a a file and feed it into RAND_seed(). + * + * @param filename name of file to read. + * @param size minimum size to read. + * + * @ingroup hcrypto_rand + */ + int RAND_load_file(const char *filename, size_t size) { @@ -133,7 +269,7 @@ RAND_load_file(const char *filename, size_t size) fd = open(filename, O_RDONLY | O_BINARY, 0600); if (fd < 0) return 0; - + rk_cloexec(fd); len = 0; while(len < size) { slen = read(fd, buf, sizeof(buf)); @@ -147,6 +283,15 @@ RAND_load_file(const char *filename, size_t size) return len ? 1 : 0; } +/** + * Write of random numbers to a file to store for later initiation with RAND_load_file(). + * + * @param filename name of file to write. + * + * @return 1 on success and non-one on failure. + * @ingroup hcrypto_rand + */ + int RAND_write_file(const char *filename) { @@ -157,6 +302,7 @@ RAND_write_file(const char *filename) fd = open(filename, O_WRONLY | O_CREAT | O_BINARY, 0600); if (fd < 0) return 0; + rk_cloexec(fd); len = 0; while(len < RAND_FILE_SIZE) { @@ -175,6 +321,18 @@ RAND_write_file(const char *filename) return res; } +/** + * Return the default random state filename for a user to use for + * RAND_load_file(), and RAND_write_file(). + * + * @param filename buffer to hold file name. + * @param size size of buffer filename. + * + * @return the buffer filename or NULL on failure. + * + * @ingroup hcrypto_rand + */ + const char * RAND_file_name(char *filename, size_t size) { diff --git a/source4/heimdal/lib/hcrypto/rc2.c b/source4/heimdal/lib/hcrypto/rc2.c index 63992be9a9..63992be9a9 100755..100644 --- a/source4/heimdal/lib/hcrypto/rc2.c +++ b/source4/heimdal/lib/hcrypto/rc2.c diff --git a/source4/heimdal/lib/hcrypto/rc2.h b/source4/heimdal/lib/hcrypto/rc2.h index 5a2dd2d705..5a2dd2d705 100755..100644 --- a/source4/heimdal/lib/hcrypto/rc2.h +++ b/source4/heimdal/lib/hcrypto/rc2.h diff --git a/source4/heimdal/lib/hcrypto/rc4.c b/source4/heimdal/lib/hcrypto/rc4.c index edaf37ddc4..edaf37ddc4 100755..100644 --- a/source4/heimdal/lib/hcrypto/rc4.c +++ b/source4/heimdal/lib/hcrypto/rc4.c diff --git a/source4/heimdal/lib/hcrypto/rijndael-alg-fst.c b/source4/heimdal/lib/hcrypto/rijndael-alg-fst.c index c6330d27e4..c6330d27e4 100755..100644 --- a/source4/heimdal/lib/hcrypto/rijndael-alg-fst.c +++ b/source4/heimdal/lib/hcrypto/rijndael-alg-fst.c diff --git a/source4/heimdal/lib/hcrypto/rijndael-alg-fst.h b/source4/heimdal/lib/hcrypto/rijndael-alg-fst.h index 7e2e1935fd..7e2e1935fd 100755..100644 --- a/source4/heimdal/lib/hcrypto/rijndael-alg-fst.h +++ b/source4/heimdal/lib/hcrypto/rijndael-alg-fst.h diff --git a/source4/heimdal/lib/hcrypto/rnd_keys.c b/source4/heimdal/lib/hcrypto/rnd_keys.c index a035b890b8..0fd64af3b5 100644 --- a/source4/heimdal/lib/hcrypto/rnd_keys.c +++ b/source4/heimdal/lib/hcrypto/rnd_keys.c @@ -34,476 +34,109 @@ #ifdef HAVE_CONFIG_H #include "config.h" -RCSID("$Id: rnd_keys.c 17445 2006-05-05 10:37:46Z lha $"); +RCSID("$Id: rnd_keys.c 23093 2008-04-27 18:49:51Z lha $"); #endif +#define HC_DEPRECATED + #ifdef KRB5 #include <krb5-types.h> #endif #include <des.h> +#include <rand.h> #include <stdlib.h> -#include <string.h> - -#ifdef TIME_WITH_SYS_TIME -#include <sys/time.h> -#include <time.h> -#elif defined(HAVE_SYS_TIME_H) -#include <sys/time.h> -#else -#include <time.h> -#endif - -#ifdef HAVE_SYS_TYPES_H -#include <sys/types.h> -#endif - -#ifdef HAVE_UNISTD_H -#include <unistd.h> -#endif -#ifdef HAVE_IO_H -#include <io.h> -#endif - -#ifdef HAVE_SIGNAL_H -#include <signal.h> -#endif -#ifdef HAVE_FCNTL_H -#include <fcntl.h> -#endif - -/* - * Generate "random" data by checksumming a file. - * - * Returns -1 if there were any problems with permissions or I/O - * errors. - */ -static -int -sumFile (const char *name, int len, void *res) -{ - uint32_t sum[2] = { 0, 0 }; - uint32_t buf[1024*2]; - int fd, i; - - fd = open (name, 0); - if (fd < 0) - return -1; - - while (len > 0) - { - int n = read(fd, buf, sizeof(buf)); - if (n < 0) - { - close(fd); - return n; - } - for (i = 0; i < (n/sizeof(buf[0])); i++) - { - sum[0] += buf[i]; - i++; - sum[1] += buf[i]; - } - len -= n; - } - close (fd); - memcpy (res, &sum, sizeof(sum)); - return 0; -} - -#if 0 -static -int -md5sumFile (const char *name, int len, int32_t sum[4]) -{ - int32_t buf[1024*2]; - int fd, cnt; - struct md5 md5; - - fd = open (name, 0); - if (fd < 0) - return -1; - - md5_init(&md5); - while (len > 0) - { - int n = read(fd, buf, sizeof(buf)); - if (n < 0) - { - close(fd); - return n; - } - md5_update(&md5, buf, n); - len -= n; - } - md5_finito(&md5, (unsigned char *)sum); - close (fd); - return 0; -} -#endif - -/* - * Create a sequence of random 64 bit blocks. - * The sequence is indexed with a long long and - * based on an initial des key used as a seed. - */ -static DES_key_schedule sequence_seed; -static uint32_t sequence_index[2]; - -/* - * Random number generator based on ideas from truerand in cryptolib - * as described on page 424 in Applied Cryptography 2 ed. by Bruce - * Schneier. - */ - -static volatile int counter; -static volatile unsigned char *gdata; /* Global data */ -static volatile int igdata; /* Index into global data */ -static int gsize; -#if !defined(WIN32) && !defined(__EMX__) && !defined(__OS2__) && !defined(__CYGWIN32__) -/* Visual C++ 4.0 (Windows95/NT) */ +#undef __attribute__ +#define __attribute__(X) -static -RETSIGTYPE -sigALRM(int sig) -{ - if (igdata < gsize) - gdata[igdata++] ^= counter & 0xff; - -#ifndef HAVE_SIGACTION - signal(SIGALRM, sigALRM); /* Reinstall SysV signal handler */ -#endif - SIGRETURN(0); -} - -#endif - -#if !defined(HAVE_RANDOM) && defined(HAVE_RAND) -#ifndef srandom -#define srandom srand -#endif -#ifndef random -#define random rand -#endif -#endif - -#if !defined(HAVE_SETITIMER) || defined(WIN32) || defined(__EMX__) || defined(__OS2__) || defined(__CYGWIN32__) -static void -des_not_rand_data(unsigned char *data, int size) -{ - int i; - - srandom (time (NULL)); - - for(i = 0; i < size; ++i) - data[i] ^= random() % 0x100; -} -#endif - -#if !defined(WIN32) && !defined(__EMX__) && !defined(__OS2__) && !defined(__CYGWIN32__) - -#ifndef HAVE_SETITIMER -static void -pacemaker(struct timeval *tv) -{ - fd_set fds; - pid_t pid; - pid = getppid(); - while(1){ - FD_ZERO(&fds); - FD_SET(0, &fds); - select(1, &fds, NULL, NULL, tv); - kill(pid, SIGALRM); - } -} -#endif - -#ifdef HAVE_SIGACTION -/* XXX ugly hack, should perhaps use function from roken */ -static RETSIGTYPE -(*fake_signal(int sig, RETSIGTYPE (*f)(int)))(int) -{ - struct sigaction sa, osa; - sa.sa_handler = f; - sa.sa_flags = 0; - sigemptyset(&sa.sa_mask); - sigaction(sig, &sa, &osa); - return osa.sa_handler; -} -#define signal(S, F) fake_signal((S), (F)) -#endif - -/* - * Generate size bytes of "random" data using timed interrupts. - * It takes about 40ms/byte random data. - * It's not neccessary to be root to run it. - */ -void +void HC_DEPRECATED DES_rand_data(void *outdata, int size) { - unsigned char *data = outdata; - struct itimerval tv, otv; - RETSIGTYPE (*osa)(int); - int i, j; -#ifndef HAVE_SETITIMER - RETSIGTYPE (*ochld)(int); - pid_t pid; -#endif - const char *rnd_devices[] = {"/dev/random", - "/dev/srandom", - "/dev/urandom", - "/dev/arandom", - NULL}; - const char **p; - - for(p = rnd_devices; *p; p++) { - int fd = open(*p, O_RDONLY | O_NDELAY); - - if(fd >= 0 && read(fd, data, size) == size) { - close(fd); - return; - } - close(fd); - } - - /* Paranoia? Initialize data from /dev/mem if we can read it. */ - if (size >= 8) - sumFile("/dev/mem", (1024*1024*2), data); - - gdata = data; - gsize = size; - igdata = 0; - - osa = signal(SIGALRM, sigALRM); - - /* Start timer */ - tv.it_value.tv_sec = 0; - tv.it_value.tv_usec = 10 * 1000; /* 10 ms */ - tv.it_interval = tv.it_value; -#ifdef HAVE_SETITIMER - setitimer(ITIMER_REAL, &tv, &otv); -#else - ochld = signal(SIGCHLD, SIG_IGN); - pid = fork(); - if(pid == -1){ - signal(SIGCHLD, ochld != SIG_ERR ? ochld : SIG_DFL); - des_not_rand_data(data, size); - return; - } - if(pid == 0) - pacemaker(&tv.it_interval); -#endif - - for(i = 0; i < 4; i++) { - for (igdata = 0; igdata < size;) /* igdata++ in sigALRM */ - counter++; - for (j = 0; j < size; j++) /* Only use 2 bits each lap */ - gdata[j] = (gdata[j]>>2) | (gdata[j]<<6); - } -#ifdef HAVE_SETITIMER - setitimer(ITIMER_REAL, &otv, 0); -#else - kill(pid, SIGKILL); - while(waitpid(pid, NULL, 0) != pid); - signal(SIGCHLD, ochld != SIG_ERR ? ochld : SIG_DFL); -#endif - signal(SIGALRM, osa != SIG_ERR ? osa : SIG_DFL); -} -#else -void -DES_rand_data(unsigned char *p, int s) -{ - des_not_rand_data (p, s); + RAND_bytes(outdata, size); } -#endif -void +void HC_DEPRECATED DES_generate_random_block(DES_cblock *block) { - DES_rand_data((unsigned char *)block, sizeof(*block)); + RAND_bytes(block, sizeof(*block)); } #define DES_rand_data_key hc_DES_rand_data_key -void +void HC_DEPRECATED DES_rand_data_key(DES_cblock *key); /* - * Generate a "random" DES key. + * Generate a random DES key. */ -void -DES_rand_data_key(DES_cblock *key) -{ - unsigned char data[8]; - DES_key_schedule sched; - do { - DES_rand_data(data, sizeof(data)); - DES_rand_data((unsigned char*)key, sizeof(DES_cblock)); - DES_set_odd_parity(key); - DES_set_key(key, &sched); - DES_ecb_encrypt(&data, key, &sched, DES_ENCRYPT); - memset(&data, 0, sizeof(data)); - memset(&sched, 0, sizeof(sched)); - DES_set_odd_parity(key); - } while(DES_is_weak_key(key)); -} -/* - * Generate "random" data by checksumming /dev/mem - * - * It's neccessary to be root to run it. Returns -1 if there were any - * problems with permissions. - */ - -#define DES_mem_rand8 hc_DES_mem_rand8 - -int -DES_mem_rand8(unsigned char *data); - -int -DES_mem_rand8(unsigned char *data) -{ - return 1; -} - -/* - * In case the generator does not get initialized use this as fallback. - */ -static int initialized; - -static void -do_initialize(void) +void HC_DEPRECATED +DES_rand_data_key(DES_cblock *key) { - DES_cblock default_seed; - do { - DES_generate_random_block(&default_seed); - DES_set_odd_parity(&default_seed); - } while (DES_is_weak_key(&default_seed)); - DES_init_random_number_generator(&default_seed); + DES_new_random_key(key); } -#define zero_long_long(ll) do { ll[0] = ll[1] = 0; } while (0) - -#define incr_long_long(ll) do { if (++ll[0] == 0) ++ll[1]; } while (0) - -#define set_sequence_number(ll) \ -memcpy((char *)sequence_index, (ll), sizeof(sequence_index)); - -/* - * Set the sequnce number to this value (a long long). - */ -void +void HC_DEPRECATED DES_set_sequence_number(void *ll) { - set_sequence_number(ll); } -/* - * Set the generator seed and reset the sequence number to 0. - */ -void +void HC_DEPRECATED DES_set_random_generator_seed(DES_cblock *seed) { - DES_set_key(seed, &sequence_seed); - zero_long_long(sequence_index); - initialized = 1; + RAND_seed(seed, sizeof(*seed)); } -/* - * Generate a sequence of random des keys - * using the random block sequence, fixup - * parity and skip weak keys. +/** + * Generate a random des key using a random block, fixup parity and + * skip weak keys. + * + * @param key is set to a random key. + * + * @return 0 on success, non zero on random number generator failure. + * + * @ingroup hcrypto_des */ -int + +int HC_DEPRECATED DES_new_random_key(DES_cblock *key) { - if (!initialized) - do_initialize(); - do { - DES_ecb_encrypt((DES_cblock *) sequence_index, - key, - &sequence_seed, - DES_ENCRYPT); - incr_long_long(sequence_index); - /* random key must have odd parity and not be weak */ + if (RAND_bytes(key, sizeof(*key)) != 1) + return 1; DES_set_odd_parity(key); - } while (DES_is_weak_key(key)); + } while(DES_is_weak_key(key)); + return(0); } -/* - * des_init_random_number_generator: +/** + * Seed the random number generator. Deprecated, use @ref page_rand * - * Initialize the sequence of random 64 bit blocks. The input seed - * can be a secret key since it should be well hidden and is also not - * kept. + * @param seed a seed to seed that random number generate with. * + * @ingroup hcrypto_des */ -void -DES_init_random_number_generator(DES_cblock *seed) -{ - struct timeval now; - DES_cblock uniq; - DES_cblock new_key; - gettimeofday(&now, (struct timezone *)0); - DES_generate_random_block(&uniq); - - /* Pick a unique random key from the shared sequence. */ - DES_set_random_generator_seed(seed); - set_sequence_number((unsigned char *)&uniq); - DES_new_random_key(&new_key); - - /* Select a new nonshared sequence, */ - DES_set_random_generator_seed(&new_key); - - /* and use the current time to pick a key for the new sequence. */ - set_sequence_number((unsigned char *)&now); - DES_new_random_key(&new_key); - DES_set_random_generator_seed(&new_key); -} - -/* This is for backwards compatibility. */ -void -DES_random_key(DES_cblock *ret) +void HC_DEPRECATED +DES_init_random_number_generator(DES_cblock *seed) { - DES_new_random_key(ret); + RAND_seed(seed, sizeof(*seed)); } -#ifdef TESTRUN -int -main() -{ - unsigned char data[8]; - int i; - - while (1) - { - if (sumFile("/dev/mem", (1024*1024*8), data) != 0) - { perror("sumFile"); exit(1); } - for (i = 0; i < 8; i++) - printf("%02x", data[i]); - printf("\n"); - } -} -#endif +/** + * Generate a random key, deprecated since it doesn't return an error + * code, use DES_new_random_key(). + * + * @param key is set to a random key. + * + * @ingroup hcrypto_des + */ -#ifdef TESTRUN2 -int -main() +void HC_DEPRECATED +DES_random_key(DES_cblock *key) { - DES_cblock data; - int i; - - while (1) - { - do_initialize(); - DES_random_key(data); - for (i = 0; i < 8; i++) - printf("%02x", data[i]); - printf("\n"); - } + if (DES_new_random_key(key)) + abort(); } -#endif diff --git a/source4/heimdal/lib/hcrypto/ui.c b/source4/heimdal/lib/hcrypto/ui.c index 3e651998b5..8c3ea1fa15 100644 --- a/source4/heimdal/lib/hcrypto/ui.c +++ b/source4/heimdal/lib/hcrypto/ui.c @@ -33,7 +33,7 @@ #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$Id: ui.c 18158 2006-09-22 15:45:57Z lha $"); +RCSID("$Id: ui.c 23466 2008-07-27 12:16:15Z lha $"); #endif #include <stdio.h> @@ -84,7 +84,9 @@ read_string(const char *preprompt, const char *prompt, if (sigaction(i, &sa, &sigs[i]) == 0) oksigs[i] = 1; - if((tty = fopen("/dev/tty", "r")) == NULL) + if((tty = fopen("/dev/tty", "r")) != NULL) + rk_cloexec_file(tty); + else tty = stdin; fprintf(stderr, "%s%s", preprompt, prompt); @@ -116,7 +118,7 @@ read_string(const char *preprompt, const char *prompt, *p = 0; if(echo == 0){ - printf("\n"); + fprintf(stderr, "\n"); tcsetattr(fileno(tty), TCSANOW, &t_old); } diff --git a/source4/heimdal/lib/hdb/db.c b/source4/heimdal/lib/hdb/db.c index 870f0431cf..cb28226431 100644 --- a/source4/heimdal/lib/hdb/db.c +++ b/source4/heimdal/lib/hdb/db.c @@ -33,7 +33,7 @@ #include "hdb_locl.h" -RCSID("$Id: db.c 20215 2007-02-09 21:59:53Z lha $"); +RCSID("$Id: db.c 23316 2008-06-23 04:32:32Z lha $"); #if HAVE_DB1 @@ -68,8 +68,8 @@ DB_lock(krb5_context context, HDB *db, int operation) DB *d = (DB*)db->hdb_db; int fd = (*d->fd)(d); if(fd < 0) { - krb5_set_error_string(context, - "Can't lock database: %s", db->hdb_name); + krb5_set_error_message(context, HDB_ERR_CANT_LOCK_DB, + "Can't lock database: %s", db->hdb_name); return HDB_ERR_CANT_LOCK_DB; } return hdb_lock(fd, operation); @@ -81,8 +81,8 @@ DB_unlock(krb5_context context, HDB *db) DB *d = (DB*)db->hdb_db; int fd = (*d->fd)(d); if(fd < 0) { - krb5_set_error_string(context, - "Can't unlock database: %s", db->hdb_name); + krb5_set_error_message(context, HDB_ERR_CANT_LOCK_DB, + "Can't unlock database: %s", db->hdb_name); return HDB_ERR_CANT_LOCK_DB; } return hdb_unlock(fd); @@ -100,15 +100,15 @@ DB_seq(krb5_context context, HDB *db, code = db->hdb_lock(context, db, HDB_RLOCK); if(code == -1) { - krb5_set_error_string(context, "Database %s in use", db->hdb_name); + krb5_set_error_message(context, HDB_ERR_DB_INUSE, "Database %s in use", db->hdb_name); return HDB_ERR_DB_INUSE; } code = (*d->seq)(d, &key, &value, flag); db->hdb_unlock(context, db); /* XXX check value */ if(code == -1) { code = errno; - krb5_set_error_string(context, "Database %s seq error: %s", - db->hdb_name, strerror(code)); + krb5_set_error_message(context, code, "Database %s seq error: %s", + db->hdb_name, strerror(code)); return code; } if(code == 1) { @@ -131,8 +131,8 @@ DB_seq(krb5_context context, HDB *db, if (code == 0 && entry->entry.principal == NULL) { entry->entry.principal = malloc(sizeof(*entry->entry.principal)); if (entry->entry.principal == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); code = ENOMEM; + krb5_set_error_message(context, code, "malloc: out of memory"); hdb_free_entry (context, entry); } else { hdb_key2principal(context, &key_data, entry->entry.principal); @@ -190,8 +190,8 @@ DB__get(krb5_context context, HDB *db, krb5_data key, krb5_data *reply) db->hdb_unlock(context, db); if(code < 0) { code = errno; - krb5_set_error_string(context, "Database %s get error: %s", - db->hdb_name, strerror(code)); + krb5_set_error_message(context, code, "Database %s get error: %s", + db->hdb_name, strerror(code)); return code; } if(code == 1) { @@ -222,8 +222,8 @@ DB__put(krb5_context context, HDB *db, int replace, db->hdb_unlock(context, db); if(code < 0) { code = errno; - krb5_set_error_string(context, "Database %s put error: %s", - db->hdb_name, strerror(code)); + krb5_set_error_message(context, code, "Database %s put error: %s", + db->hdb_name, strerror(code)); return code; } if(code == 1) { @@ -248,8 +248,8 @@ DB__del(krb5_context context, HDB *db, krb5_data key) db->hdb_unlock(context, db); if(code == 1) { code = errno; - krb5_set_error_string(context, "Database %s put error: %s", - db->hdb_name, strerror(code)); + krb5_set_error_message(context, code, "Database %s put error: %s", + db->hdb_name, strerror(code)); return code; } if(code < 0) @@ -265,7 +265,7 @@ DB_open(krb5_context context, HDB *db, int flags, mode_t mode) asprintf(&fn, "%s.db", db->hdb_name); if (fn == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } db->hdb_db = dbopen(fn, flags, mode, DB_BTREE, NULL); @@ -275,7 +275,7 @@ DB_open(krb5_context context, HDB *db, int flags, mode_t mode) db->hdb_db = dbopen(db->hdb_name, flags, mode, DB_BTREE, NULL); if(db->hdb_db == NULL) { ret = errno; - krb5_set_error_string(context, "dbopen (%s): %s", + krb5_set_error_message(context, ret, "dbopen (%s): %s", db->hdb_name, strerror(ret)); return ret; } @@ -289,7 +289,7 @@ DB_open(krb5_context context, HDB *db, int flags, mode_t mode) } if (ret) { DB_close(context, db); - krb5_set_error_string(context, "hdb_open: failed %s database %s", + krb5_set_error_message(context, ret, "hdb_open: failed %s database %s", (flags & O_ACCMODE) == O_RDONLY ? "checking format of" : "initialize", db->hdb_name); @@ -303,16 +303,16 @@ hdb_db_create(krb5_context context, HDB **db, { *db = calloc(1, sizeof(**db)); if (*db == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } (*db)->hdb_db = NULL; (*db)->hdb_name = strdup(filename); if ((*db)->hdb_name == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); free(*db); *db = NULL; + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } (*db)->hdb_master_key_set = 0; diff --git a/source4/heimdal/lib/hdb/dbinfo.c b/source4/heimdal/lib/hdb/dbinfo.c index d43e31b39a..e99f72050d 100644 --- a/source4/heimdal/lib/hdb/dbinfo.c +++ b/source4/heimdal/lib/hdb/dbinfo.c @@ -33,7 +33,7 @@ #include "hdb_locl.h" -RCSID("$Id: dbinfo.c 22306 2007-12-14 12:22:38Z lha $"); +RCSID("$Id: dbinfo.c 23316 2008-06-23 04:32:32Z lha $"); struct hdb_dbinfo { char *label; @@ -63,7 +63,7 @@ get_dbinfo(krb5_context context, di = calloc(1, sizeof(*di)); if (di == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } di->label = strdup(label); diff --git a/source4/heimdal/lib/hdb/ext.c b/source4/heimdal/lib/hdb/ext.c index 5f60999946..30e15efb27 100644 --- a/source4/heimdal/lib/hdb/ext.c +++ b/source4/heimdal/lib/hdb/ext.c @@ -34,7 +34,7 @@ #include "hdb_locl.h" #include <der.h> -RCSID("$Id: ext.c 21113 2007-06-18 12:59:32Z lha $"); +RCSID("$Id: ext.c 23316 2008-06-23 04:32:32Z lha $"); krb5_error_code hdb_entry_check_mandatory(krb5_context context, const hdb_entry *ent) @@ -53,8 +53,9 @@ hdb_entry_check_mandatory(krb5_context context, const hdb_entry *ent) choice_HDB_extension_data_asn1_ellipsis) continue; if (ent->extensions->val[i].mandatory) { - krb5_set_error_string(context, "Principal have unknown " - "mandatory extension"); + krb5_set_error_message(context, HDB_ERR_MANDATORY_OPTION, + "Principal have unknown " + "mandatory extension"); return HDB_ERR_MANDATORY_OPTION; } } @@ -95,7 +96,7 @@ hdb_replace_extension(krb5_context context, if (entry->extensions == NULL) { entry->extensions = calloc(1, sizeof(*entry->extensions)); if (entry->extensions == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } } else if (ext->data.element != choice_HDB_extension_data_asn1_ellipsis) { @@ -120,8 +121,8 @@ hdb_replace_extension(krb5_context context, &replace_class, &replace_type, &replace_tag, &size); if (ret) { - krb5_set_error_string(context, "hdb: failed to decode " - "replacement hdb extention"); + krb5_set_error_message(context, ret, "hdb: failed to decode " + "replacement hdb extention"); return ret; } @@ -136,8 +137,8 @@ hdb_replace_extension(krb5_context context, &list_class, &list_type, &list_tag, &size); if (ret) { - krb5_set_error_string(context, "hdb: failed to decode " - "present hdb extention"); + krb5_set_error_message(context, ret, "hdb: failed to decode " + "present hdb extention"); return ret; } @@ -153,15 +154,15 @@ hdb_replace_extension(krb5_context context, free_HDB_extension(ext2); ret = copy_HDB_extension(ext, ext2); if (ret) - krb5_set_error_string(context, "hdb: failed to copy replacement " - "hdb extention"); + krb5_set_error_message(context, ret, "hdb: failed to copy replacement " + "hdb extention"); return ret; } es = realloc(entry->extensions->val, (entry->extensions->len+1)*sizeof(entry->extensions->val[0])); if (es == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } entry->extensions->val = es; @@ -171,7 +172,7 @@ hdb_replace_extension(krb5_context context, if (ret == 0) entry->extensions->len++; else - krb5_set_error_string(context, "hdb: failed to copy new extension"); + krb5_set_error_message(context, ret, "hdb: failed to copy new extension"); return ret; } @@ -283,8 +284,9 @@ hdb_entry_get_password(krb5_context context, HDB *db, db->hdb_master_key); if (key == NULL) { - krb5_set_error_string(context, "master key %d missing", - *ext->data.u.password.mkvno); + krb5_set_error_message(context, HDB_ERR_NO_MKEY, + "master key %d missing", + *ext->data.u.password.mkvno); return HDB_ERR_NO_MKEY; } @@ -302,7 +304,7 @@ hdb_entry_get_password(krb5_context context, HDB *db, str = pw.data; if (str[pw.length - 1] != '\0') { - krb5_set_error_string(context, "password malformated"); + krb5_set_error_message(context, EINVAL, "password malformated"); return EINVAL; } @@ -310,7 +312,7 @@ hdb_entry_get_password(krb5_context context, HDB *db, der_free_octet_string(&pw); if (*p == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } return 0; @@ -318,7 +320,7 @@ hdb_entry_get_password(krb5_context context, HDB *db, ret = krb5_unparse_name(context, entry->principal, &str); if (ret == 0) { - krb5_set_error_string(context, "no password attributefor %s", str); + krb5_set_error_message(context, ENOENT, "no password attributefor %s", str); free(str); } else krb5_clear_error_string(context); @@ -341,8 +343,9 @@ hdb_entry_set_password(krb5_context context, HDB *db, key = _hdb_find_master_key(NULL, db->hdb_master_key); if (key == NULL) { - krb5_set_error_string(context, "hdb_entry_set_password: " - "failed to find masterkey"); + krb5_set_error_message(context, HDB_ERR_NO_MKEY, + "hdb_entry_set_password: " + "failed to find masterkey"); return HDB_ERR_NO_MKEY; } @@ -356,7 +359,7 @@ hdb_entry_set_password(krb5_context context, HDB *db, malloc(sizeof(*ext.data.u.password.mkvno)); if (ext.data.u.password.mkvno == NULL) { free_HDB_extension(&ext); - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } *ext.data.u.password.mkvno = _hdb_mkey_version(key); @@ -367,7 +370,7 @@ hdb_entry_set_password(krb5_context context, HDB *db, ret = krb5_data_copy(&ext.data.u.password.password, p, strlen(p) + 1); if (ret) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); free_HDB_extension(&ext); return ret; } diff --git a/source4/heimdal/lib/hdb/hdb.c b/source4/heimdal/lib/hdb/hdb.c index f0731ed98e..3da980a81f 100644 --- a/source4/heimdal/lib/hdb/hdb.c +++ b/source4/heimdal/lib/hdb/hdb.c @@ -33,7 +33,7 @@ #include "hdb_locl.h" -RCSID("$Id: hdb.c 20214 2007-02-09 21:51:10Z lha $"); +RCSID("$Id: hdb.c 23316 2008-06-23 04:32:32Z lha $"); #ifdef HAVE_DLFCN_H #include <dlfcn.h> @@ -88,7 +88,8 @@ hdb_next_enctype2key(krb5_context context, return 0; } } - krb5_set_error_string(context, "No next enctype %d for hdb-entry", + krb5_set_error_message(context, KRB5_PROG_ETYPE_NOSUPP, + "No next enctype %d for hdb-entry", (int)enctype); return KRB5_PROG_ETYPE_NOSUPP; /* XXX */ } @@ -381,7 +382,7 @@ hdb_list_builtin(krb5_context context, char **list) len += 1; buf = malloc(len); if (buf == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } buf[0] = '\0'; diff --git a/source4/heimdal/lib/hdb/keys.c b/source4/heimdal/lib/hdb/keys.c index 60a58677fe..e689ae1020 100644 --- a/source4/heimdal/lib/hdb/keys.c +++ b/source4/heimdal/lib/hdb/keys.c @@ -33,7 +33,7 @@ #include "hdb_locl.h" -RCSID("$Id: keys.c 22071 2007-11-14 20:04:50Z lha $"); +RCSID("$Id: keys.c 23316 2008-06-23 04:32:32Z lha $"); /* * free all the memory used by (len, keys) @@ -153,7 +153,7 @@ parse_key_set(krb5_context context, const char *key, v4 compat, and a cell name for afs compat */ salt->saltvalue.data = strdup(buf[i]); if (salt->saltvalue.data == NULL) { - krb5_set_error_string(context, "out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } salt->saltvalue.length = strlen(buf[i]); @@ -161,7 +161,7 @@ parse_key_set(krb5_context context, const char *key, } if(enctypes == NULL || salt->salttype == 0) { - krb5_set_error_string(context, "bad value for default_keys `%s'", key); + krb5_set_error_message(context, EINVAL, "bad value for default_keys `%s'", key); return EINVAL; } @@ -173,8 +173,9 @@ parse_key_set(krb5_context context, const char *key, krb5_realm *realm = krb5_princ_realm(context, principal); salt->saltvalue.data = strdup(*realm); if(salt->saltvalue.data == NULL) { - krb5_set_error_string(context, "out of memory while " - "parsing salt specifiers"); + krb5_set_error_message(context, ENOMEM, + "out of memory while " + "parsing salt specifiers"); return ENOMEM; } strlwr(salt->saltvalue.data); @@ -185,7 +186,7 @@ parse_key_set(krb5_context context, const char *key, *ret_enctypes = malloc(sizeof(enctypes[0]) * num_enctypes); if (*ret_enctypes == NULL) { krb5_free_salt(context, *salt); - krb5_set_error_string(context, "out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } memcpy(*ret_enctypes, enctypes, sizeof(enctypes[0]) * num_enctypes); diff --git a/source4/heimdal/lib/hdb/keytab.c b/source4/heimdal/lib/hdb/keytab.c index 5c867daf20..dc4ccf7678 100644 --- a/source4/heimdal/lib/hdb/keytab.c +++ b/source4/heimdal/lib/hdb/keytab.c @@ -35,7 +35,7 @@ /* keytab backend for HDB databases */ -RCSID("$Id: keytab.c 18380 2006-10-09 12:36:40Z lha $"); +RCSID("$Id: keytab.c 23316 2008-06-23 04:32:32Z lha $"); struct hdb_data { char *dbname; @@ -55,7 +55,7 @@ hdb_resolve(krb5_context context, const char *name, krb5_keytab id) d = malloc(sizeof(*d)); if(d == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } db = name; @@ -67,7 +67,7 @@ hdb_resolve(krb5_context context, const char *name, krb5_keytab id) d->dbname = strdup(name); if(d->dbname == NULL) { free(d); - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } } @@ -79,7 +79,7 @@ hdb_resolve(krb5_context context, const char *name, krb5_keytab id) d->dbname = malloc(mkey - db + 1); if(d->dbname == NULL) { free(d); - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } memmove(d->dbname, db, mkey - db); @@ -89,7 +89,7 @@ hdb_resolve(krb5_context context, const char *name, krb5_keytab id) if(d->mkey == NULL) { free(d->dbname); free(d); - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } } diff --git a/source4/heimdal/lib/hdb/mkey.c b/source4/heimdal/lib/hdb/mkey.c index 05cf71c593..04cb423889 100644 --- a/source4/heimdal/lib/hdb/mkey.c +++ b/source4/heimdal/lib/hdb/mkey.c @@ -36,7 +36,7 @@ #define O_BINARY 0 #endif -RCSID("$Id: mkey.c 21745 2007-07-31 16:11:25Z lha $"); +RCSID("$Id: mkey.c 23316 2008-06-23 04:32:32Z lha $"); struct hdb_master_key_data { krb5_keytab_entry keytab; @@ -67,7 +67,7 @@ hdb_process_master_key(krb5_context context, *mkey = calloc(1, sizeof(**mkey)); if(*mkey == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } (*mkey)->keytab.vno = kvno; @@ -159,8 +159,8 @@ read_master_mit(krb5_context context, const char *filename, fd = open(filename, O_RDONLY | O_BINARY); if(fd < 0) { int save_errno = errno; - krb5_set_error_string(context, "failed to open %s: %s", filename, - strerror(save_errno)); + krb5_set_error_message(context, save_errno, "failed to open %s: %s", + filename, strerror(save_errno)); return save_errno; } sp = krb5_storage_from_fd(fd); @@ -176,9 +176,9 @@ read_master_mit(krb5_context context, const char *filename, #else ret = krb5_ret_int16(sp, &enctype); if((htons(enctype) & 0xff00) == 0x3000) { - krb5_set_error_string(context, "unknown keytype in %s: %#x, expected %#x", - filename, htons(enctype), 0x3000); ret = HEIM_ERR_BAD_MKEY; + krb5_set_error_message(context, ret, "unknown keytype in %s: %#x, expected %#x", + filename, htons(enctype), 0x3000); goto out; } key.keytype = enctype; @@ -209,7 +209,7 @@ read_master_encryptionkey(krb5_context context, const char *filename, fd = open(filename, O_RDONLY | O_BINARY); if(fd < 0) { int save_errno = errno; - krb5_set_error_string(context, "failed to open %s: %s", + krb5_set_error_message(context, save_errno, "failed to open %s: %s", filename, strerror(save_errno)); return save_errno; } @@ -218,7 +218,7 @@ read_master_encryptionkey(krb5_context context, const char *filename, close(fd); if(len < 0) { int save_errno = errno; - krb5_set_error_string(context, "error reading %s: %s", + krb5_set_error_message(context, save_errno, "error reading %s: %s", filename, strerror(save_errno)); return save_errno; } @@ -255,8 +255,8 @@ read_master_krb4(krb5_context context, const char *filename, fd = open(filename, O_RDONLY | O_BINARY); if(fd < 0) { int save_errno = errno; - krb5_set_error_string(context, "failed to open %s: %s", - filename, strerror(save_errno)); + krb5_set_error_message(context, save_errno, "failed to open %s: %s", + filename, strerror(save_errno)); return save_errno; } @@ -264,12 +264,13 @@ read_master_krb4(krb5_context context, const char *filename, close(fd); if(len < 0) { int save_errno = errno; - krb5_set_error_string(context, "error reading %s: %s", - filename, strerror(save_errno)); + krb5_set_error_message(context, save_errno, "error reading %s: %s", + filename, strerror(save_errno)); return save_errno; } if(len != 8) { - krb5_set_error_string(context, "bad contents of %s", filename); + krb5_set_error_message(context, HEIM_ERR_EOF, + "bad contents of %s", filename); return HEIM_ERR_EOF; /* XXX file might be too large */ } @@ -303,14 +304,14 @@ hdb_read_master_key(krb5_context context, const char *filename, f = fopen(filename, "r"); if(f == NULL) { int save_errno = errno; - krb5_set_error_string(context, "failed to open %s: %s", - filename, strerror(save_errno)); + krb5_set_error_message(context, save_errno, "failed to open %s: %s", + filename, strerror(save_errno)); return save_errno; } if(fread(buf, 1, 2, f) != 2) { - krb5_set_error_string(context, "end of file reading %s", filename); fclose(f); + krb5_set_error_message(context, HEIM_ERR_EOF, "end of file reading %s", filename); return HEIM_ERR_EOF; } diff --git a/source4/heimdal/lib/hdb/ndbm.c b/source4/heimdal/lib/hdb/ndbm.c index 6575b8a417..e1e8aacf87 100644 --- a/source4/heimdal/lib/hdb/ndbm.c +++ b/source4/heimdal/lib/hdb/ndbm.c @@ -33,7 +33,7 @@ #include "hdb_locl.h" -RCSID("$Id: ndbm.c 16395 2005-12-13 11:54:10Z lha $"); +RCSID("$Id: ndbm.c 23316 2008-06-23 04:32:32Z lha $"); #if HAVE_NDBM @@ -110,9 +110,9 @@ NDBM_seq(krb5_context context, HDB *db, if (ret == 0 && entry->entry.principal == NULL) { entry->entry.principal = malloc (sizeof(*entry->entry.principal)); if (entry->entry.principal == NULL) { - ret = ENOMEM; hdb_free_entry (context, entry); - krb5_set_error_string(context, "malloc: out of memory"); + ret = ENOMEM; + krb5_set_error_message(context, ret, "malloc: out of memory"); } else { hdb_key2principal (context, &key_data, entry->entry.principal); } @@ -152,15 +152,15 @@ NDBM_rename(krb5_context context, HDB *db, const char *new_name) asprintf(&new_lock, "%s.lock", new_name); if(new_lock == NULL) { db->hdb_unlock(context, db); - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } lock_fd = open(new_lock, O_RDWR | O_CREAT, 0600); if(lock_fd < 0) { ret = errno; db->hdb_unlock(context, db); - krb5_set_error_string(context, "open(%s): %s", new_lock, - strerror(ret)); + krb5_set_error_message(context, ret, "open(%s): %s", new_lock, + strerror(ret)); free(new_lock); return ret; } @@ -188,7 +188,7 @@ NDBM_rename(krb5_context context, HDB *db, const char *new_name) if(ret) { ret = errno; close(lock_fd); - krb5_set_error_string(context, "rename: %s", strerror(ret)); + krb5_set_error_message(context, ret, "rename: %s", strerror(ret)); return ret; } @@ -284,13 +284,13 @@ NDBM_open(krb5_context context, HDB *db, int flags, mode_t mode) char *lock_file; if(d == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } asprintf(&lock_file, "%s.lock", (char*)db->hdb_name); if(lock_file == NULL) { free(d); - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } d->db = dbm_open((char*)db->hdb_name, flags, mode); @@ -298,8 +298,8 @@ NDBM_open(krb5_context context, HDB *db, int flags, mode_t mode) ret = errno; free(d); free(lock_file); - krb5_set_error_string(context, "dbm_open(%s): %s", db->hdb_name, - strerror(ret)); + krb5_set_error_message(context, ret, "dbm_open(%s): %s", db->hdb_name, + strerror(ret)); return ret; } d->lock_fd = open(lock_file, O_RDWR | O_CREAT, 0600); @@ -307,8 +307,8 @@ NDBM_open(krb5_context context, HDB *db, int flags, mode_t mode) ret = errno; dbm_close(d->db); free(d); - krb5_set_error_string(context, "open(%s): %s", lock_file, - strerror(ret)); + krb5_set_error_message(context, ret, "open(%s): %s", lock_file, + strerror(ret)); free(lock_file); return ret; } @@ -322,10 +322,10 @@ NDBM_open(krb5_context context, HDB *db, int flags, mode_t mode) return 0; if (ret) { NDBM_close(context, db); - krb5_set_error_string(context, "hdb_open: failed %s database %s", - (flags & O_ACCMODE) == O_RDONLY ? - "checking format of" : "initialize", - db->hdb_name); + krb5_set_error_message(context, ret, "hdb_open: failed %s database %s", + (flags & O_ACCMODE) == O_RDONLY ? + "checking format of" : "initialize", + db->hdb_name); } return ret; } @@ -336,16 +336,16 @@ hdb_ndbm_create(krb5_context context, HDB **db, { *db = calloc(1, sizeof(**db)); if (*db == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } (*db)->hdb_db = NULL; (*db)->hdb_name = strdup(filename); if ((*db)->hdb_name == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); free(*db); *db = NULL; + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } (*db)->hdb_master_key_set = 0; diff --git a/source4/heimdal/lib/hx509/ca.c b/source4/heimdal/lib/hx509/ca.c index 40260700b3..55374321ea 100644 --- a/source4/heimdal/lib/hx509/ca.c +++ b/source4/heimdal/lib/hx509/ca.c @@ -33,7 +33,7 @@ #include "hx_locl.h" #include <pkinit_asn1.h> -RCSID("$Id: ca.c 22456 2008-01-15 20:22:53Z lha $"); +RCSID("$Id: ca.c 22995 2008-04-15 19:31:29Z lha $"); /** * @page page_ca Hx509 CA functions @@ -1225,7 +1225,7 @@ ca_sign(hx509_context context, { BasicConstraints bc; int aCA = 1; - uint32_t path; + unsigned int path; memset(&bc, 0, sizeof(bc)); diff --git a/source4/heimdal/lib/hx509/cert.c b/source4/heimdal/lib/hx509/cert.c index 09c85bc084..3194526e34 100644 --- a/source4/heimdal/lib/hx509/cert.c +++ b/source4/heimdal/lib/hx509/cert.c @@ -32,7 +32,7 @@ */ #include "hx_locl.h" -RCSID("$Id: cert.c 22583 2008-02-11 20:46:21Z lha $"); +RCSID("$Id: cert.c 23457 2008-07-27 12:12:56Z lha $"); #include "crypto-headers.h" #include <rtbl.h> @@ -138,7 +138,7 @@ hx509_context_init(hx509_context *context) /** * Selects if the hx509_revoke_verify() function is going to require - * the existans of a revokation method (OSCP, CRL) or not. Note that + * the existans of a revokation method (OCSP, CRL) or not. Note that * hx509_verify_path(), hx509_cms_verify_signed(), and other function * call hx509_revoke_verify(). * @@ -485,6 +485,12 @@ hx509_verify_set_time(hx509_verify_ctx ctx, time_t t) ctx->time_now = t; } +time_t +_hx509_verify_get_time(hx509_verify_ctx ctx) +{ + return ctx->time_now; +} + /** * Set the maximum depth of the certificate chain that the path * builder is going to try. @@ -2355,7 +2361,7 @@ hx509_verify_hostname(hx509_context context, } while (1); { - Name *name = &cert->data->tbsCertificate.subject; + const Name *name = &cert->data->tbsCertificate.subject; /* match if first component is a CN= */ if (name->u.rdnSequence.len > 0 @@ -2491,8 +2497,16 @@ hx509_cert_get_friendly_name(hx509_cert cert) a = hx509_cert_get_attribute(cert, oid_id_pkcs_9_at_friendlyName()); if (a == NULL) { - /* XXX use subject name ? */ - return NULL; + hx509_name name; + + ret = hx509_cert_get_subject(cert, &name); + if (ret) + return NULL; + ret = hx509_name_to_string(name, &cert->friendlyname); + hx509_name_free(&name); + if (ret) + return NULL; + return cert->friendlyname; } ret = decode_PKCS9_friendlyName(a->data.data, a->data.length, &n, &sz); @@ -2548,6 +2562,7 @@ hx509_query_alloc(hx509_context context, hx509_query **q) return 0; } + /** * Set match options for the hx509 query controller. * @@ -2697,6 +2712,25 @@ hx509_query_match_eku(hx509_query *q, const heim_oid *eku) return 0; } +int +hx509_query_match_expr(hx509_context context, hx509_query *q, const char *expr) +{ + if (q->expr) { + _hx509_expr_free(q->expr); + q->expr = NULL; + } + + if (expr == NULL) { + q->match &= ~HX509_QUERY_MATCH_EXPR; + } else { + q->expr = _hx509_expr_parse(expr); + if (q->expr) + q->match |= HX509_QUERY_MATCH_EXPR; + } + + return 0; +} + /** * Set the query controller to match using a specific match function. * @@ -2753,6 +2787,9 @@ hx509_query_free(hx509_context context, hx509_query *q) } if (q->friendlyname) free(q->friendlyname); + if (q->expr) + _hx509_expr_free(q->expr); + memset(q, 0, sizeof(*q)); free(q); } @@ -2890,6 +2927,19 @@ _hx509_query_match_cert(hx509_context context, const hx509_query *q, hx509_cert hx509_cert_check_eku(context, cert, q->eku, 0)) return 0; + if ((q->match & HX509_QUERY_MATCH_EXPR)) { + hx509_env env = NULL; + + ret = _hx509_cert_to_env(context, cert, &env); + if (ret) + return 0; + + ret = _hx509_expr_eval(context, env, q->expr); + hx509_env_free(&env); + if (ret == 0) + return 0; + } + if (q->match & ~HX509_QUERY_MASK) return 0; @@ -2922,6 +2972,7 @@ _hx509_query_statistic(hx509_context context, int type, const hx509_query *q) f = fopen(context->querystat, "a"); if (f == NULL) return; + rk_cloexec_file(f); fprintf(f, "%d %d\n", type, q->match); fclose(f); } @@ -2992,6 +3043,7 @@ hx509_query_unparse_stats(hx509_context context, int printtype, FILE *out) context->querystat, strerror(errno)); return; } + rk_cloexec_file(f); for (i = 0; i < sizeof(stats)/sizeof(stats[0]); i++) { stats[i].index = i; @@ -3206,3 +3258,103 @@ hx509_xfree(void *ptr) { free(ptr); } + +/** + * + */ + +int +_hx509_cert_to_env(hx509_context context, hx509_cert cert, hx509_env *env) +{ + ExtKeyUsage eku; + hx509_name name; + char *buf; + int ret; + hx509_env envcert = NULL; + + *env = NULL; + + /* version */ + asprintf(&buf, "%d", _hx509_cert_get_version(_hx509_get_cert(cert))); + ret = hx509_env_add(context, &envcert, "version", buf); + free(buf); + if (ret) + goto out; + + /* subject */ + ret = hx509_cert_get_subject(cert, &name); + if (ret) + goto out; + + ret = hx509_name_to_string(name, &buf); + if (ret) { + hx509_name_free(&name); + goto out; + } + + ret = hx509_env_add(context, &envcert, "subject", buf); + hx509_name_free(&name); + if (ret) + goto out; + + /* issuer */ + ret = hx509_cert_get_issuer(cert, &name); + if (ret) + goto out; + + ret = hx509_name_to_string(name, &buf); + hx509_name_free(&name); + if (ret) + goto out; + + ret = hx509_env_add(context, &envcert, "issuer", buf); + hx509_xfree(buf); + if (ret) + goto out; + + /* eku */ + + ret = _hx509_cert_get_eku(context, cert, &eku); + if (ret == HX509_EXTENSION_NOT_FOUND) + ; + else if (ret != 0) + goto out; + else { + int i; + hx509_env enveku = NULL; + + for (i = 0; i < eku.len; i++) { + + ret = der_print_heim_oid(&eku.val[i], '.', &buf); + if (ret) { + free_ExtKeyUsage(&eku); + hx509_env_free(&enveku); + goto out; + } + ret = hx509_env_add(context, &enveku, buf, "oid-name-here"); + free(buf); + if (ret) { + free_ExtKeyUsage(&eku); + hx509_env_free(&enveku); + goto out; + } + } + free_ExtKeyUsage(&eku); + + ret = hx509_env_add_binding(context, &envcert, "eku", enveku); + if (ret) { + hx509_env_free(&enveku); + goto out; + } + } + + ret = hx509_env_add_binding(context, env, "certificate", envcert); + if (ret) + goto out; + + return 0; + +out: + hx509_env_free(&envcert); + return ret; +} diff --git a/source4/heimdal/lib/hx509/cms.c b/source4/heimdal/lib/hx509/cms.c index 80bcaac6c9..69e7730f3c 100644 --- a/source4/heimdal/lib/hx509/cms.c +++ b/source4/heimdal/lib/hx509/cms.c @@ -32,7 +32,7 @@ */ #include "hx_locl.h" -RCSID("$Id: cms.c 22327 2007-12-15 04:49:37Z lha $"); +RCSID("$Id: cms.c 23268 2008-06-23 03:23:47Z lha $"); /** * @page page_cms CMS/PKCS7 message functions. @@ -260,6 +260,7 @@ static int find_CMSIdentifier(hx509_context context, CMSIdentifier *client, hx509_certs certs, + time_t time_now, hx509_cert *signer_cert, int match) { @@ -292,7 +293,10 @@ find_CMSIdentifier(hx509_context context, q.match |= match; q.match |= HX509_QUERY_MATCH_TIME; - q.timenow = time(NULL); + if (time_now) + q.timenow = time_now; + else + q.timenow = time(NULL); ret = hx509_certs_find(context, certs, &q, &cert); if (ret == HX509_CERT_NOT_FOUND) { @@ -333,6 +337,7 @@ find_CMSIdentifier(hx509_context context, * @param length length of the data that data point to. * @param encryptedContent in case of detached signature, this * contains the actual encrypted data, othersize its should be NULL. + * @param time_now set the current time, if zero the library uses now as the date. * @param contentType output type oid, should be freed with der_free_oid(). * @param content the data, free with der_free_octet_string(). * @@ -346,6 +351,7 @@ hx509_cms_unenvelope(hx509_context context, const void *data, size_t length, const heim_octet_string *encryptedContent, + time_t time_now, heim_oid *contentType, heim_octet_string *content) { @@ -407,7 +413,8 @@ hx509_cms_unenvelope(hx509_context context, ri = &ed.recipientInfos.val[i]; - ret = find_CMSIdentifier(context, &ri->rid, certs, &cert, + ret = find_CMSIdentifier(context, &ri->rid, certs, + time_now, &cert, HX509_QUERY_PRIVATE_KEY|findflags); if (ret) continue; @@ -831,7 +838,8 @@ hx509_cms_verify_signed(hx509_context context, continue; } - ret = find_CMSIdentifier(context, &signer_info->sid, certs, &cert, + ret = find_CMSIdentifier(context, &signer_info->sid, certs, + _hx509_verify_get_time(ctx), &cert, HX509_QUERY_KU_DIGITALSIGNATURE); if (ret) continue; diff --git a/source4/heimdal/lib/hx509/crypto.c b/source4/heimdal/lib/hx509/crypto.c index e0f00ad7b4..9334a4a847 100644 --- a/source4/heimdal/lib/hx509/crypto.c +++ b/source4/heimdal/lib/hx509/crypto.c @@ -32,7 +32,7 @@ */ #include "hx_locl.h" -RCSID("$Id: crypto.c 22435 2008-01-14 20:53:56Z lha $"); +RCSID("$Id: crypto.c 22855 2008-04-07 18:49:24Z lha $"); struct hx509_crypto; @@ -1592,11 +1592,11 @@ _hx509_private_key_init(hx509_private_key *key, hx509_private_key _hx509_private_key_ref(hx509_private_key key) { - if (key->ref <= 0) - _hx509_abort("refcount <= 0"); - key->ref++; if (key->ref == 0) - _hx509_abort("refcount == 0"); + _hx509_abort("key refcount <= 0 on ref"); + key->ref++; + if (key->ref == UINT_MAX) + _hx509_abort("key refcount == UINT_MAX on ref"); return key; } @@ -1612,8 +1612,8 @@ _hx509_private_key_free(hx509_private_key *key) if (key == NULL || *key == NULL) return 0; - if ((*key)->ref <= 0) - _hx509_abort("refcount <= 0"); + if ((*key)->ref == 0) + _hx509_abort("key refcount == 0 on free"); if (--(*key)->ref > 0) return 0; diff --git a/source4/heimdal/lib/hx509/env.c b/source4/heimdal/lib/hx509/env.c index f868c22488..a124e6ea1c 100644 --- a/source4/heimdal/lib/hx509/env.c +++ b/source4/heimdal/lib/hx509/env.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 Kungliga Tekniska Högskolan + * Copyright (c) 2007 - 2008 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -32,7 +32,7 @@ */ #include "hx_locl.h" -RCSID("$Id: env.c 22349 2007-12-26 19:32:49Z lha $"); +RCSID("$Id: env.c 22677 2008-03-13 17:35:49Z lha $"); /** * @page page_env Hx509 enviroment functions @@ -40,19 +40,13 @@ RCSID("$Id: env.c 22349 2007-12-26 19:32:49Z lha $"); * See the library functions here: @ref hx509_env */ -struct hx509_env { - struct { - char *key; - char *value; - } *val; - size_t len; -}; - /** - * Allocate a new hx509_env container object. + * Add a new key/value pair to the hx509_env. * * @param context A hx509 context. - * @param env return a hx509_env structure, free with hx509_env_free(). + * @param env enviroment to add the enviroment variable too. + * @param key key to add + * @param value value to add * * @return An hx509 error code, see hx509_get_error_string(). * @@ -60,23 +54,50 @@ struct hx509_env { */ int -hx509_env_init(hx509_context context, hx509_env *env) +hx509_env_add(hx509_context context, hx509_env *env, + const char *key, const char *value) { - *env = calloc(1, sizeof(**env)); - if (*env == NULL) { + hx509_env n; + + n = malloc(sizeof(*n)); + if (n == NULL) { hx509_set_error_string(context, 0, ENOMEM, "out of memory"); return ENOMEM; } + + n->type = env_string; + n->next = NULL; + n->name = strdup(key); + if (n->name == NULL) { + free(n); + return ENOMEM; + } + n->u.string = strdup(value); + if (n->u.string == NULL) { + free(n->name); + free(n); + return ENOMEM; + } + + /* add to tail */ + if (*env) { + hx509_env e = *env; + while (e->next) + e = e->next; + e->next = n; + } else + *env = n; + return 0; } /** - * Add a new key/value pair to the hx509_env. + * Add a new key/binding pair to the hx509_env. * * @param context A hx509 context. * @param env enviroment to add the enviroment variable too. * @param key key to add - * @param value value to add + * @param list binding list to add * * @return An hx509 error code, see hx509_get_error_string(). * @@ -84,34 +105,41 @@ hx509_env_init(hx509_context context, hx509_env *env) */ int -hx509_env_add(hx509_context context, hx509_env env, - const char *key, const char *value) +hx509_env_add_binding(hx509_context context, hx509_env *env, + const char *key, hx509_env list) { - void *ptr; + hx509_env n; - ptr = realloc(env->val, sizeof(env->val[0]) * (env->len + 1)); - if (ptr == NULL) { + n = malloc(sizeof(*n)); + if (n == NULL) { hx509_set_error_string(context, 0, ENOMEM, "out of memory"); return ENOMEM; } - env->val = ptr; - env->val[env->len].key = strdup(key); - if (env->val[env->len].key == NULL) { - hx509_set_error_string(context, 0, ENOMEM, "out of memory"); - return ENOMEM; - } - env->val[env->len].value = strdup(value); - if (env->val[env->len].value == NULL) { - free(env->val[env->len].key); - hx509_set_error_string(context, 0, ENOMEM, "out of memory"); + + n->type = env_list; + n->next = NULL; + n->name = strdup(key); + if (n->name == NULL) { + free(n); return ENOMEM; } - env->len++; + n->u.list = list; + + /* add to tail */ + if (*env) { + hx509_env e = *env; + while (e->next) + e = e->next; + e->next = n; + } else + *env = n; + return 0; } + /** - * Search the hx509_env for a key. + * Search the hx509_env for a length based key. * * @param context A hx509 context. * @param env enviroment to add the enviroment variable too. @@ -127,17 +155,81 @@ const char * hx509_env_lfind(hx509_context context, hx509_env env, const char *key, size_t len) { - size_t i; + while(env) { + if (strncmp(key, env->name ,len) == 0 + && env->name[len] == '\0' && env->type == env_string) + return env->u.string; + env = env->next; + } + return NULL; +} - for (i = 0; i < env->len; i++) { - char *s = env->val[i].key; - if (strncmp(key, s, len) == 0 && s[len] == '\0') - return env->val[i].value; +/** + * Search the hx509_env for a key. + * + * @param context A hx509 context. + * @param env enviroment to add the enviroment variable too. + * @param key key to search for. + * + * @return the value if the key is found, NULL otherwise. + * + * @ingroup hx509_env + */ + +const char * +hx509_env_find(hx509_context context, hx509_env env, const char *key) +{ + while(env) { + if (strcmp(key, env->name) == 0 && env->type == env_string) + return env->u.string; + env = env->next; } return NULL; } /** + * Search the hx509_env for a binding. + * + * @param context A hx509 context. + * @param env enviroment to add the enviroment variable too. + * @param key key to search for. + * + * @return the binding if the key is found, NULL if not found. + * + * @ingroup hx509_env + */ + +hx509_env +hx509_env_find_binding(hx509_context context, + hx509_env env, + const char *key) +{ + while(env) { + if (strcmp(key, env->name) == 0 && env->type == env_list) + return env->u.list; + env = env->next; + } + return NULL; +} + +static void +env_free(hx509_env b) +{ + while(b) { + hx509_env next = b->next; + + if (b->type == env_string) + free(b->u.string); + else if (b->type == env_list) + env_free(b->u.list); + + free(b->name); + free(b); + b = next; + } +} + +/** * Free an hx509_env enviroment context. * * @param env the enviroment to free. @@ -148,14 +240,7 @@ hx509_env_lfind(hx509_context context, hx509_env env, void hx509_env_free(hx509_env *env) { - size_t i; - - for (i = 0; i < (*env)->len; i++) { - free((*env)->val[i].key); - free((*env)->val[i].value); - } - free((*env)->val); - free(*env); + if (*env) + env_free(*env); *env = NULL; } - diff --git a/source4/heimdal/lib/hx509/file.c b/source4/heimdal/lib/hx509/file.c index b076b74f44..c8f0e9a642 100644 --- a/source4/heimdal/lib/hx509/file.c +++ b/source4/heimdal/lib/hx509/file.c @@ -35,13 +35,13 @@ RCSID("$ID$"); int -_hx509_map_file_os(const char *fn, heim_octet_string *os, struct stat *rsb) +_hx509_map_file_os(const char *fn, heim_octet_string *os) { size_t length; void *data; int ret; - ret = _hx509_map_file(fn, &data, &length, rsb); + ret = rk_undumpdata(fn, &data, &length); os->data = data; os->length = length; @@ -52,86 +52,13 @@ _hx509_map_file_os(const char *fn, heim_octet_string *os, struct stat *rsb) void _hx509_unmap_file_os(heim_octet_string *os) { - _hx509_unmap_file(os->data, os->length); -} - -int -_hx509_map_file(const char *fn, void **data, size_t *length, struct stat *rsb) -{ - struct stat sb; - size_t len; - ssize_t l; - int ret; - void *d; - int fd; - - *data = NULL; - *length = 0; - - fd = open(fn, O_RDONLY); - if (fd < 0) - return errno; - - if (fstat(fd, &sb) < 0) { - ret = errno; - close(fd); - return ret; - } - - len = sb.st_size; - - d = malloc(len); - if (d == NULL) { - close(fd); - return ENOMEM; - } - - l = read(fd, d, len); - close(fd); - if (l < 0 || l != len) { - free(d); - return EINVAL; - } - - if (rsb) - *rsb = sb; - *data = d; - *length = len; - return 0; -} - -void -_hx509_unmap_file(void *data, size_t len) -{ - free(data); + rk_xfree(os->data); } int _hx509_write_file(const char *fn, const void *data, size_t length) { - ssize_t sz; - const unsigned char *p = data; - int fd; - - fd = open(fn, O_WRONLY|O_TRUNC|O_CREAT, 0644); - if (fd < 0) - return errno; - - do { - sz = write(fd, p, length); - if (sz < 0) { - int saved_errno = errno; - close(fd); - return saved_errno; - } - if (sz == 0) - break; - length -= sz; - } while (length > 0); - - if (close(fd) == -1) - return errno; - + rk_dumpdata(fn, data, length); return 0; } diff --git a/source4/heimdal/lib/hx509/hx509-private.h b/source4/heimdal/lib/hx509/hx509-private.h index be36c07421..de1fcfa7e6 100644 --- a/source4/heimdal/lib/hx509/hx509-private.h +++ b/source4/heimdal/lib/hx509/hx509-private.h @@ -98,6 +98,12 @@ _hx509_cert_set_release ( void */*ctx*/); int +_hx509_cert_to_env ( + hx509_context /*context*/, + hx509_cert /*cert*/, + hx509_env */*env*/); + +int _hx509_certs_keys_add ( hx509_context /*context*/, hx509_certs /*certs*/, @@ -182,6 +188,18 @@ _hx509_create_signature_bitstring ( heim_bit_string */*sig*/); int +_hx509_expr_eval ( + hx509_context /*context*/, + hx509_env /*env*/, + struct hx_expr */*expr*/); + +void +_hx509_expr_free (struct hx_expr */*expr*/); + +struct hx_expr * +_hx509_expr_parse (const char */*buf*/); + +int _hx509_find_extension_subject_key_id ( const Certificate */*issuer*/, SubjectKeyIdentifier */*si*/); @@ -253,18 +271,16 @@ _hx509_lock_get_passwords (hx509_lock /*lock*/); hx509_certs _hx509_lock_unlock_certs (hx509_lock /*lock*/); -int -_hx509_map_file ( - const char */*fn*/, - void **/*data*/, - size_t */*length*/, - struct stat */*rsb*/); +struct hx_expr * +_hx509_make_expr ( + enum hx_expr_op /*op*/, + void */*arg1*/, + void */*arg2*/); int _hx509_map_file_os ( const char */*fn*/, - heim_octet_string */*os*/, - struct stat */*rsb*/); + heim_octet_string */*os*/); int _hx509_match_keys ( @@ -486,6 +502,9 @@ _hx509_request_to_pkcs10 ( hx509_revoke_ctx _hx509_revoke_ref (hx509_revoke_ctx /*ctx*/); +void +_hx509_sel_yyerror (char */*s*/); + int _hx509_set_cert_attribute ( hx509_context /*context*/, @@ -494,11 +513,6 @@ _hx509_set_cert_attribute ( const heim_octet_string */*attr*/); void -_hx509_unmap_file ( - void */*data*/, - size_t /*len*/); - -void _hx509_unmap_file_os (heim_octet_string */*os*/); int @@ -506,6 +520,9 @@ _hx509_unparse_Name ( const Name */*aname*/, char **/*str*/); +time_t +_hx509_verify_get_time (hx509_verify_ctx /*ctx*/); + int _hx509_verify_signature ( hx509_context /*context*/, diff --git a/source4/heimdal/lib/hx509/hx509-protos.h b/source4/heimdal/lib/hx509/hx509-protos.h index 3e297424cc..f8e6bc19a4 100644 --- a/source4/heimdal/lib/hx509/hx509-protos.h +++ b/source4/heimdal/lib/hx509/hx509-protos.h @@ -8,11 +8,13 @@ extern "C" { #endif -#ifndef HX509_LIB_FUNCTION +#ifndef HX509_LIB #if defined(_WIN32) -#define HX509_LIB_FUNCTION _stdcall +#define HX509_LIB_FUNCTION _stdcall __declspec(dllimport) +#define HX509_LIB_VARIABLE __declspec(dllimport) #else #define HX509_LIB_FUNCTION +#define HX509_LIB_VARIABLE #endif #endif @@ -396,6 +398,7 @@ hx509_cms_unenvelope ( const void */*data*/, size_t /*length*/, const heim_octet_string */*encryptedContent*/, + time_t /*time_now*/, heim_oid */*contentType*/, heim_octet_string */*content*/); @@ -564,17 +567,31 @@ hx509_crypto_set_random_key ( int hx509_env_add ( hx509_context /*context*/, - hx509_env /*env*/, + hx509_env */*env*/, const char */*key*/, const char */*value*/); -void -hx509_env_free (hx509_env */*env*/); - int -hx509_env_init ( +hx509_env_add_binding ( hx509_context /*context*/, - hx509_env */*env*/); + hx509_env */*env*/, + const char */*key*/, + hx509_env /*list*/); + +const char * +hx509_env_find ( + hx509_context /*context*/, + hx509_env /*env*/, + const char */*key*/); + +hx509_env +hx509_env_find_binding ( + hx509_context /*context*/, + hx509_env /*env*/, + const char */*key*/); + +void +hx509_env_free (hx509_env */*env*/); const char * hx509_env_lfind ( @@ -826,6 +843,12 @@ hx509_query_match_eku ( const heim_oid */*eku*/); int +hx509_query_match_expr ( + hx509_context /*context*/, + hx509_query */*q*/, + const char */*expr*/); + +int hx509_query_match_friendly_name ( hx509_query */*q*/, const char */*name*/); @@ -1047,6 +1070,9 @@ hx509_verify_signature ( void hx509_xfree (void */*ptr*/); +int +yywrap (void); + #ifdef __cplusplus } #endif diff --git a/source4/heimdal/lib/hx509/hx509.h b/source4/heimdal/lib/hx509/hx509.h index be02f63474..d2a6b06e0c 100644 --- a/source4/heimdal/lib/hx509/hx509.h +++ b/source4/heimdal/lib/hx509/hx509.h @@ -31,7 +31,13 @@ * SUCH DAMAGE. */ -/* $Id: hx509.h 22464 2008-01-16 14:24:50Z lha $ */ +/* $Id: hx509.h 22908 2008-04-08 08:16:32Z lha $ */ + +#ifndef HEIMDAL_HX509_H +#define HEIMDAL_HX509_H 1 + +#include <heim_asn1.h> +#include <rfc2459_asn1.h> typedef struct hx509_cert_attribute_data *hx509_cert_attribute; typedef struct hx509_cert_data *hx509_cert; @@ -50,7 +56,7 @@ typedef struct hx509_request_data *hx509_request; typedef struct hx509_error_data *hx509_error; typedef struct hx509_peer_info *hx509_peer_info; typedef struct hx509_ca_tbs *hx509_ca_tbs; -typedef struct hx509_env *hx509_env; +typedef struct hx509_env_data *hx509_env; typedef struct hx509_crl *hx509_crl; typedef void (*hx509_vprint_func)(void *, const char *, va_list); @@ -146,3 +152,6 @@ typedef enum { } hx509_hostname_type; #include <hx509-protos.h> +#include <hx509_err.h> + +#endif /* HEIMDAL_HX509_H */ diff --git a/source4/heimdal/lib/hx509/hx_locl.h b/source4/heimdal/lib/hx509/hx_locl.h index 6d89167bfc..d2db3354c7 100644 --- a/source4/heimdal/lib/hx509/hx_locl.h +++ b/source4/heimdal/lib/hx509/hx_locl.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: hx_locl.h 22538 2008-01-27 13:05:47Z lha $ */ +/* $Id: hx_locl.h 23189 2008-05-23 15:04:27Z lha $ */ #ifdef HAVE_CONFIG_H #include <config.h> @@ -45,6 +45,8 @@ #include <assert.h> #include <stdarg.h> #include <err.h> +#include <limits.h> + #include <getarg.h> #include <base64.h> #include <hex.h> @@ -80,6 +82,8 @@ typedef void (*_hx509_cert_release_func)(struct hx509_cert_data *, void *); typedef struct hx509_private_key_ops hx509_private_key_ops; +#include "sel.h" + #include <hx509-private.h> #include <hx509_err.h> @@ -129,7 +133,8 @@ struct hx509_query_data { #define HX509_QUERY_MATCH_KEY_HASH_SHA1 0x100000 #define HX509_QUERY_MATCH_TIME 0x200000 #define HX509_QUERY_MATCH_EKU 0x400000 -#define HX509_QUERY_MASK 0x7fffff +#define HX509_QUERY_MATCH_EXPR 0x800000 +#define HX509_QUERY_MASK 0xffffff Certificate *subject; Certificate *certificate; heim_integer *serial; @@ -144,6 +149,7 @@ struct hx509_query_data { heim_octet_string *keyhash_sha1; time_t timenow; heim_oid *eku; + struct hx_expr *expr; }; struct hx509_keyset_ops { @@ -188,6 +194,18 @@ struct hx509_context_data { /* _hx509_calculate_path flag field */ #define HX509_CALCULATE_PATH_NO_ANCHOR 1 +/* environment */ +struct hx509_env_data { + enum { env_string, env_list } type; + char *name; + struct hx509_env_data *next; + union { + char *string; + struct hx509_env_data *list; + } u; +}; + + extern const AlgorithmIdentifier * _hx509_crypto_default_sig_alg; extern const AlgorithmIdentifier * _hx509_crypto_default_digest_alg; extern const AlgorithmIdentifier * _hx509_crypto_default_secret_alg; diff --git a/source4/heimdal/lib/hx509/keyset.c b/source4/heimdal/lib/hx509/keyset.c index 2fcff7b03b..1fceb849ec 100644 --- a/source4/heimdal/lib/hx509/keyset.c +++ b/source4/heimdal/lib/hx509/keyset.c @@ -32,7 +32,7 @@ */ #include "hx_locl.h" -RCSID("$Id: keyset.c 22466 2008-01-16 14:26:35Z lha $"); +RCSID("$Id: keyset.c 22851 2008-04-07 18:49:07Z lha $"); /** * @page page_keyset Certificate store operations @@ -59,7 +59,7 @@ RCSID("$Id: keyset.c 22466 2008-01-16 14:26:35Z lha $"); */ struct hx509_certs_data { - int ref; + unsigned int ref; struct hx509_keyset_ops *ops; void *ops_data; }; @@ -203,11 +203,11 @@ _hx509_certs_ref(hx509_certs certs) { if (certs == NULL) return NULL; - if (certs->ref <= 0) - _hx509_abort("certs refcount <= 0"); - certs->ref++; if (certs->ref == 0) - _hx509_abort("certs refcount == 0"); + _hx509_abort("certs refcount == 0 on ref"); + if (certs->ref == UINT_MAX) + _hx509_abort("certs refcount == UINT_MAX on ref"); + certs->ref++; return certs; } @@ -223,8 +223,8 @@ void hx509_certs_free(hx509_certs *certs) { if (*certs) { - if ((*certs)->ref <= 0) - _hx509_abort("refcount <= 0"); + if ((*certs)->ref == 0) + _hx509_abort("cert refcount == 0 on free"); if (--(*certs)->ref > 0) return; diff --git a/source4/heimdal/lib/hx509/ks_dir.c b/source4/heimdal/lib/hx509/ks_dir.c index a0bc875e5b..0dabc78c52 100644 --- a/source4/heimdal/lib/hx509/ks_dir.c +++ b/source4/heimdal/lib/hx509/ks_dir.c @@ -32,7 +32,7 @@ */ #include "hx_locl.h" -RCSID("$Id: ks_dir.c 19778 2007-01-09 10:52:13Z lha $"); +RCSID("$Id: ks_dir.c 23460 2008-07-27 12:14:03Z lha $"); #include <dirent.h> /* @@ -116,6 +116,7 @@ dir_iter_start(hx509_context context, free(d); return errno; } + rk_cloexec(dirfd(d->dir)); d->certs = NULL; d->iter = NULL; diff --git a/source4/heimdal/lib/hx509/ks_file.c b/source4/heimdal/lib/hx509/ks_file.c index 87b97af401..25ceb1c64f 100644 --- a/source4/heimdal/lib/hx509/ks_file.c +++ b/source4/heimdal/lib/hx509/ks_file.c @@ -32,7 +32,7 @@ */ #include "hx_locl.h" -RCSID("$Id: ks_file.c 22465 2008-01-16 14:25:24Z lha $"); +RCSID("$Id: ks_file.c 23459 2008-07-27 12:13:31Z lha $"); typedef enum { USE_PEM, USE_DER } outformat; @@ -391,6 +391,7 @@ file_init_common(hx509_context context, p, strerror(errno)); goto out; } + rk_cloexec_file(f); ret = hx509_pem_read(context, f, pem_func, &pem_ctx); fclose(f); @@ -401,7 +402,7 @@ file_init_common(hx509_context context, void *ptr; int i; - ret = _hx509_map_file(p, &ptr, &length, NULL); + ret = rk_undumpdata(p, &ptr, &length); if (ret) { hx509_clear_error_string(context); goto out; @@ -412,7 +413,7 @@ file_init_common(hx509_context context, if (ret == 0) break; } - _hx509_unmap_file(ptr, length); + rk_xfree(ptr); if (ret) goto out; } @@ -525,6 +526,7 @@ file_store(hx509_context context, "Failed to open file %s for writing"); return ENOENT; } + rk_cloexec_file(sc.f); sc.format = f->format; ret = hx509_certs_iter(context, f->certs, store_func, &sc); diff --git a/source4/heimdal/lib/hx509/ks_p11.c b/source4/heimdal/lib/hx509/ks_p11.c index 0d7c312c72..bf46e6604e 100644 --- a/source4/heimdal/lib/hx509/ks_p11.c +++ b/source4/heimdal/lib/hx509/ks_p11.c @@ -32,7 +32,7 @@ */ #include "hx_locl.h" -RCSID("$Id: ks_p11.c 22071 2007-11-14 20:04:50Z lha $"); +RCSID("$Id: ks_p11.c 22899 2008-04-07 18:52:36Z lha $"); #ifdef HAVE_DLFCN_H #include <dlfcn.h> #endif @@ -65,7 +65,7 @@ struct p11_module { void *dl_handle; CK_FUNCTION_LIST_PTR funcs; CK_ULONG num_slots; - unsigned int refcount; + unsigned int ref; struct p11_slot *slot; }; @@ -309,7 +309,8 @@ p11_init_slot(hx509_context context, CK_SESSION_HANDLE session; CK_SLOT_INFO slot_info; CK_TOKEN_INFO token_info; - int ret, i; + size_t i; + int ret; slot->certs = NULL; slot->id = id; @@ -640,9 +641,11 @@ collect_private_key(hx509_context context, p11rsa->slot = slot; p11rsa->private_key = object; - p->refcount++; - if (p->refcount == 0) - _hx509_abort("pkcs11 refcount to high"); + if (p->ref == 0) + _hx509_abort("pkcs11 ref == 0 on alloc"); + p->ref++; + if (p->ref == UINT_MAX) + _hx509_abort("pkcs11 ref == UINT_MAX on alloc"); RSA_set_method(rsa, &p11_rsa_pkcs1_method); ret = RSA_set_app_data(rsa, p11rsa); @@ -695,9 +698,11 @@ collect_cert(hx509_context context, if (ret) return ret; - p->refcount++; - if (p->refcount == 0) - _hx509_abort("pkcs11 refcount to high"); + if (p->ref == 0) + _hx509_abort("pkcs11 ref == 0 on alloc"); + p->ref++; + if (p->ref == UINT_MAX) + _hx509_abort("pkcs11 ref to high"); _hx509_cert_set_release(cert, p11_cert_release, p); @@ -808,7 +813,7 @@ p11_init(hx509_context context, return ENOMEM; } - p->refcount = 1; + p->ref = 1; str = strchr(list, ','); if (str) @@ -934,9 +939,9 @@ p11_release_module(struct p11_module *p) { int i; - if (p->refcount == 0) - _hx509_abort("pkcs11 refcount to low"); - if (--p->refcount > 0) + if (p->ref == 0) + _hx509_abort("pkcs11 ref to low"); + if (--p->ref > 0) return; for (i = 0; i < p->num_slots; i++) { diff --git a/source4/heimdal/lib/hx509/ks_p12.c b/source4/heimdal/lib/hx509/ks_p12.c index 12756e6c07..3ab824a330 100644 --- a/source4/heimdal/lib/hx509/ks_p12.c +++ b/source4/heimdal/lib/hx509/ks_p12.c @@ -32,7 +32,7 @@ */ #include "hx_locl.h" -RCSID("$Id: ks_p12.c 21146 2007-06-18 21:37:25Z lha $"); +RCSID("$Id: ks_p12.c 23413 2008-07-26 18:34:53Z lha $"); struct ks_pkcs12 { hx509_certs certs; @@ -276,6 +276,7 @@ envelopedData_parser(hx509_context context, 0, data, length, NULL, + 0, &contentType, &content); if (ret) { @@ -361,14 +362,14 @@ p12_init(hx509_context context, goto out; } - ret = _hx509_map_file(residue, &buf, &len, NULL); + ret = rk_undumpdata(residue, &buf, &len); if (ret) { hx509_clear_error_string(context); goto out; } ret = decode_PKCS12_PFX(buf, len, &pfx, NULL); - _hx509_unmap_file(buf, len); + rk_xfree(buf); if (ret) { hx509_set_error_string(context, 0, ret, "Failed to decode the PFX in %s", residue); diff --git a/source4/heimdal/lib/hx509/name.c b/source4/heimdal/lib/hx509/name.c index 3f0806ddc0..ccc33a3e55 100644 --- a/source4/heimdal/lib/hx509/name.c +++ b/source4/heimdal/lib/hx509/name.c @@ -33,7 +33,7 @@ #include "hx_locl.h" #include <wind.h> -RCSID("$Id: name.c 22583 2008-02-11 20:46:21Z lha $"); +RCSID("$Id: name.c 22677 2008-03-13 17:35:49Z lha $"); /** * @page page_name PKIX/X.509 Names @@ -897,7 +897,7 @@ hx509_name_is_null_p(const hx509_name name) * @param name the name to print * @param str an allocated string returns the name in string form * - * @return An hx509 error code, see krb5_get_error_string(). + * @return An hx509 error code, see hx509_get_error_string(). * * @ingroup hx509_name */ diff --git a/source4/heimdal/lib/hx509/req.c b/source4/heimdal/lib/hx509/req.c index d7a85e1cec..f374044ca6 100644 --- a/source4/heimdal/lib/hx509/req.c +++ b/source4/heimdal/lib/hx509/req.c @@ -33,7 +33,7 @@ #include "hx_locl.h" #include <pkcs10_asn1.h> -RCSID("$Id: req.c 21344 2007-06-26 14:22:34Z lha $"); +RCSID("$Id: req.c 23413 2008-07-26 18:34:53Z lha $"); struct hx509_request_data { hx509_name name; @@ -257,14 +257,14 @@ _hx509_request_parse(hx509_context context, /* XXX PEM request */ - ret = _hx509_map_file(path, &p, &len, NULL); + ret = rk_undumpdata(path, &p, &len); if (ret) { hx509_set_error_string(context, 0, ret, "Failed to map file %s", path); return ret; } ret = decode_CertificationRequest(p, len, &r, &size); - _hx509_unmap_file(p, len); + rk_xfree(p); if (ret) { hx509_set_error_string(context, 0, ret, "Failed to decode %s", path); return ret; diff --git a/source4/heimdal/lib/hx509/revoke.c b/source4/heimdal/lib/hx509/revoke.c index 2010f945f0..8325c4723d 100644 --- a/source4/heimdal/lib/hx509/revoke.c +++ b/source4/heimdal/lib/hx509/revoke.c @@ -50,7 +50,7 @@ */ #include "hx_locl.h" -RCSID("$Id: revoke.c 22583 2008-02-11 20:46:21Z lha $"); +RCSID("$Id: revoke.c 23413 2008-07-26 18:34:53Z lha $"); struct revoke_crl { char *path; @@ -70,7 +70,7 @@ struct revoke_ocsp { struct hx509_revoke_ctx_data { - unsigned ref; + unsigned int ref; struct { struct revoke_crl *val; size_t len; @@ -113,11 +113,11 @@ _hx509_revoke_ref(hx509_revoke_ctx ctx) { if (ctx == NULL) return NULL; - if (ctx->ref <= 0) - _hx509_abort("revoke ctx refcount <= 0"); - ctx->ref++; if (ctx->ref == 0) - _hx509_abort("revoke ctx refcount == 0"); + _hx509_abort("revoke ctx refcount == 0 on ref"); + ctx->ref++; + if (ctx->ref == UINT_MAX) + _hx509_abort("revoke ctx refcount == UINT_MAX on ref"); return ctx; } @@ -146,8 +146,8 @@ hx509_revoke_free(hx509_revoke_ctx *ctx) if (ctx == NULL || *ctx == NULL) return; - if ((*ctx)->ref <= 0) - _hx509_abort("revoke ctx refcount <= 0 on free"); + if ((*ctx)->ref == 0) + _hx509_abort("revoke ctx refcount == 0 on free"); if (--(*ctx)->ref > 0) return; @@ -218,7 +218,7 @@ verify_ocsp(hx509_context context, ret = _hx509_cert_is_parent_cmp(s, p, 0); if (ret != 0) { ret = HX509_PARENT_NOT_CA; - hx509_set_error_string(context, 0, ret, "Revoke OSCP signer is " + hx509_set_error_string(context, 0, ret, "Revoke OCSP signer is " "doesn't have CA as signer certificate"); goto out; } @@ -230,7 +230,7 @@ verify_ocsp(hx509_context context, &s->signatureValue); if (ret) { hx509_set_error_string(context, HX509_ERROR_APPEND, ret, - "OSCP signer signature invalid"); + "OCSP signer signature invalid"); goto out; } @@ -247,7 +247,7 @@ verify_ocsp(hx509_context context, &ocsp->ocsp.signature); if (ret) { hx509_set_error_string(context, HX509_ERROR_APPEND, ret, - "OSCP signature invalid"); + "OCSP signature invalid"); goto out; } @@ -333,12 +333,16 @@ load_ocsp(hx509_context context, struct revoke_ocsp *ocsp) void *data; int ret; - ret = _hx509_map_file(ocsp->path, &data, &length, &sb); + ret = rk_undumpdata(ocsp->path, &data, &length); if (ret) return ret; + ret = stat(ocsp->path, &sb); + if (ret) + return errno; + ret = parse_ocsp_basic(data, length, &basic); - _hx509_unmap_file(data, length); + rk_xfree(data); if (ret) { hx509_set_error_string(context, 0, ret, "Failed to parse OCSP response"); @@ -567,14 +571,18 @@ load_crl(const char *path, time_t *t, CRLCertificateList *crl) memset(crl, 0, sizeof(*crl)); - ret = _hx509_map_file(path, &data, &length, &sb); + ret = rk_undumpdata(path, &data, &length); if (ret) return ret; + ret = stat(path, &sb); + if (ret) + return errno; + *t = sb.st_mtime; ret = decode_CRLCertificateList(data, length, crl, &size); - _hx509_unmap_file(data, length); + rk_xfree(data); if (ret) return ret; diff --git a/source4/heimdal/lib/hx509/sel-gram.c b/source4/heimdal/lib/hx509/sel-gram.c new file mode 100644 index 0000000000..905384da55 --- /dev/null +++ b/source4/heimdal/lib/hx509/sel-gram.c @@ -0,0 +1,1714 @@ +/* A Bison parser, made by GNU Bison 2.3. */ + +/* Skeleton implementation for Bison's Yacc-like parsers in C + + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 + Free Software Foundation, Inc. + + 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 2, 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, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +/* C LALR(1) parser skeleton written by Richard Stallman, by + simplifying the original so-called "semantic" parser. */ + +/* All symbols defined below should begin with yy or YY, to avoid + infringing on user name space. This should be done even for local + variables, as they might otherwise be expanded by user macros. + There are some unavoidable exceptions within include files to + define necessary library symbols; they are noted "INFRINGES ON + USER NAME SPACE" below. */ + +/* Identify Bison output. */ +#define YYBISON 1 + +/* Bison version. */ +#define YYBISON_VERSION "2.3" + +/* Skeleton name. */ +#define YYSKELETON_NAME "yacc.c" + +/* Pure parsers. */ +#define YYPURE 0 + +/* Using locations. */ +#define YYLSP_NEEDED 0 + + + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + kw_TRUE = 258, + kw_FALSE = 259, + kw_AND = 260, + kw_OR = 261, + kw_IN = 262, + kw_TAILMATCH = 263, + NUMBER = 264, + STRING = 265, + IDENTIFIER = 266 + }; +#endif +/* Tokens. */ +#define kw_TRUE 258 +#define kw_FALSE 259 +#define kw_AND 260 +#define kw_OR 261 +#define kw_IN 262 +#define kw_TAILMATCH 263 +#define NUMBER 264 +#define STRING 265 +#define IDENTIFIER 266 + + + + +/* Copy the first part of user declarations. */ +#line 34 "heimdal/lib/hx509/sel-gram.y" + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <stdio.h> +#include <stdlib.h> +#include <hx_locl.h> + +RCSID("$Id$"); + + + +/* Enabling traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif + +/* Enabling verbose error messages. */ +#ifdef YYERROR_VERBOSE +# undef YYERROR_VERBOSE +# define YYERROR_VERBOSE 1 +#else +# define YYERROR_VERBOSE 0 +#endif + +/* Enabling the token table. */ +#ifndef YYTOKEN_TABLE +# define YYTOKEN_TABLE 0 +#endif + +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +typedef union YYSTYPE +#line 46 "heimdal/lib/hx509/sel-gram.y" +{ + char *string; + struct hx_expr *expr; +} +/* Line 187 of yacc.c. */ +#line 135 "heimdal/lib/hx509/sel-gram.y" + YYSTYPE; +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +# define YYSTYPE_IS_DECLARED 1 +# define YYSTYPE_IS_TRIVIAL 1 +#endif + + + +/* Copy the second part of user declarations. */ + + +/* Line 216 of yacc.c. */ +#line 148 "heimdal/lib/hx509/sel-gram.y" + +#ifdef short +# undef short +#endif + +#ifdef YYTYPE_UINT8 +typedef YYTYPE_UINT8 yytype_uint8; +#else +typedef unsigned char yytype_uint8; +#endif + +#ifdef YYTYPE_INT8 +typedef YYTYPE_INT8 yytype_int8; +#elif (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +typedef signed char yytype_int8; +#else +typedef short int yytype_int8; +#endif + +#ifdef YYTYPE_UINT16 +typedef YYTYPE_UINT16 yytype_uint16; +#else +typedef unsigned short int yytype_uint16; +#endif + +#ifdef YYTYPE_INT16 +typedef YYTYPE_INT16 yytype_int16; +#else +typedef short int yytype_int16; +#endif + +#ifndef YYSIZE_T +# ifdef __SIZE_TYPE__ +# define YYSIZE_T __SIZE_TYPE__ +# elif defined size_t +# define YYSIZE_T size_t +# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +# include <stddef.h> /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# else +# define YYSIZE_T unsigned int +# endif +#endif + +#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) + +#ifndef YY_ +# if YYENABLE_NLS +# if ENABLE_NLS +# include <libintl.h> /* INFRINGES ON USER NAME SPACE */ +# define YY_(msgid) dgettext ("bison-runtime", msgid) +# endif +# endif +# ifndef YY_ +# define YY_(msgid) msgid +# endif +#endif + +/* Suppress unused-variable warnings by "using" E. */ +#if ! defined lint || defined __GNUC__ +# define YYUSE(e) ((void) (e)) +#else +# define YYUSE(e) /* empty */ +#endif + +/* Identity function, used to suppress warnings about constant conditions. */ +#ifndef lint +# define YYID(n) (n) +#else +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static int +YYID (int i) +#else +static int +YYID (i) + int i; +#endif +{ + return i; +} +#endif + +#if ! defined yyoverflow || YYERROR_VERBOSE + +/* The parser invokes alloca or malloc; define the necessary symbols. */ + +# ifdef YYSTACK_USE_ALLOCA +# if YYSTACK_USE_ALLOCA +# ifdef __GNUC__ +# define YYSTACK_ALLOC __builtin_alloca +# elif defined __BUILTIN_VA_ARG_INCR +# include <alloca.h> /* INFRINGES ON USER NAME SPACE */ +# elif defined _AIX +# define YYSTACK_ALLOC __alloca +# elif defined _MSC_VER +# include <malloc.h> /* INFRINGES ON USER NAME SPACE */ +# define alloca _alloca +# else +# define YYSTACK_ALLOC alloca +# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ +# ifndef _STDLIB_H +# define _STDLIB_H 1 +# endif +# endif +# endif +# endif +# endif + +# ifdef YYSTACK_ALLOC + /* Pacify GCC's `empty if-body' warning. */ +# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) +# ifndef YYSTACK_ALLOC_MAXIMUM + /* The OS might guarantee only one guard page at the bottom of the stack, + and a page size can be as small as 4096 bytes. So we cannot safely + invoke alloca (N) if N exceeds 4096. Use a slightly smaller number + to allow for a few compiler-allocated temporary stack slots. */ +# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ +# endif +# else +# define YYSTACK_ALLOC YYMALLOC +# define YYSTACK_FREE YYFREE +# ifndef YYSTACK_ALLOC_MAXIMUM +# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM +# endif +# if (defined __cplusplus && ! defined _STDLIB_H \ + && ! ((defined YYMALLOC || defined malloc) \ + && (defined YYFREE || defined free))) +# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ +# ifndef _STDLIB_H +# define _STDLIB_H 1 +# endif +# endif +# ifndef YYMALLOC +# define YYMALLOC malloc +# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# ifndef YYFREE +# define YYFREE free +# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +void free (void *); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# endif +#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ + + +#if (! defined yyoverflow \ + && (! defined __cplusplus \ + || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) + +/* A type that is properly aligned for any stack member. */ +union yyalloc +{ + yytype_int16 yyss; + YYSTYPE yyvs; + }; + +/* The size of the maximum gap between one aligned stack and the next. */ +# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) + +/* The size of an array large to enough to hold all stacks, each with + N elements. */ +# define YYSTACK_BYTES(N) \ + ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ + + YYSTACK_GAP_MAXIMUM) + +/* Copy COUNT objects from FROM to TO. The source and destination do + not overlap. */ +# ifndef YYCOPY +# if defined __GNUC__ && 1 < __GNUC__ +# define YYCOPY(To, From, Count) \ + __builtin_memcpy (To, From, (Count) * sizeof (*(From))) +# else +# define YYCOPY(To, From, Count) \ + do \ + { \ + YYSIZE_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (To)[yyi] = (From)[yyi]; \ + } \ + while (YYID (0)) +# endif +# endif + +/* Relocate STACK from its old location to the new one. The + local variables YYSIZE and YYSTACKSIZE give the old and new number of + elements in the stack, and YYPTR gives the new location of the + stack. Advance YYPTR to a properly aligned location for the next + stack. */ +# define YYSTACK_RELOCATE(Stack) \ + do \ + { \ + YYSIZE_T yynewbytes; \ + YYCOPY (&yyptr->Stack, Stack, yysize); \ + Stack = &yyptr->Stack; \ + yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / sizeof (*yyptr); \ + } \ + while (YYID (0)) + +#endif + +/* YYFINAL -- State number of the termination state. */ +#define YYFINAL 21 +/* YYLAST -- Last index in YYTABLE. */ +#define YYLAST 50 + +/* YYNTOKENS -- Number of terminals. */ +#define YYNTOKENS 21 +/* YYNNTS -- Number of nonterminals. */ +#define YYNNTS 11 +/* YYNRULES -- Number of rules. */ +#define YYNRULES 26 +/* YYNRULES -- Number of states. */ +#define YYNSTATES 50 + +/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ +#define YYUNDEFTOK 2 +#define YYMAXUTOK 266 + +#define YYTRANSLATE(YYX) \ + ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) + +/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ +static const yytype_uint8 yytranslate[] = +{ + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 12, 2, 2, 2, 17, 2, 2, + 13, 14, 2, 2, 15, 2, 20, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 16, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 18, 2, 19, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11 +}; + +#if YYDEBUG +/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in + YYRHS. */ +static const yytype_uint8 yyprhs[] = +{ + 0, 0, 3, 5, 7, 9, 12, 16, 20, 24, + 26, 28, 32, 37, 42, 46, 52, 56, 58, 60, + 62, 64, 66, 68, 73, 78, 82 +}; + +/* YYRHS -- A `-1'-separated list of the rules' RHS. */ +static const yytype_int8 yyrhs[] = +{ + 22, 0, -1, 23, -1, 3, -1, 4, -1, 12, + 23, -1, 23, 5, 23, -1, 23, 6, 23, -1, + 13, 23, 14, -1, 25, -1, 26, -1, 26, 15, + 24, -1, 26, 16, 16, 26, -1, 26, 12, 16, + 26, -1, 26, 8, 26, -1, 26, 7, 13, 24, + 14, -1, 26, 7, 30, -1, 27, -1, 28, -1, + 29, -1, 30, -1, 9, -1, 10, -1, 11, 13, + 24, 14, -1, 17, 18, 31, 19, -1, 11, 20, + 31, -1, 11, -1 +}; + +/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ +static const yytype_uint8 yyrline[] = +{ + 0, 74, 74, 76, 77, 78, 79, 80, 81, 82, + 85, 86, 89, 90, 91, 92, 93, 96, 97, 98, + 99, 102, 103, 105, 108, 111, 113 +}; +#endif + +#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE +/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. + First, the terminals, then, starting at YYNTOKENS, nonterminals. */ +static const char *const yytname[] = +{ + "$end", "error", "$undefined", "kw_TRUE", "kw_FALSE", "kw_AND", "kw_OR", + "kw_IN", "kw_TAILMATCH", "NUMBER", "STRING", "IDENTIFIER", "'!'", "'('", + "')'", "','", "'='", "'%'", "'{'", "'}'", "'.'", "$accept", "start", + "expr", "words", "comp", "word", "number", "string", "function", + "variable", "variables", 0 +}; +#endif + +# ifdef YYPRINT +/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to + token YYLEX-NUM. */ +static const yytype_uint16 yytoknum[] = +{ + 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 33, 40, 41, 44, 61, 37, 123, 125, + 46 +}; +# endif + +/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +static const yytype_uint8 yyr1[] = +{ + 0, 21, 22, 23, 23, 23, 23, 23, 23, 23, + 24, 24, 25, 25, 25, 25, 25, 26, 26, 26, + 26, 27, 28, 29, 30, 31, 31 +}; + +/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ +static const yytype_uint8 yyr2[] = +{ + 0, 2, 1, 1, 1, 2, 3, 3, 3, 1, + 1, 3, 4, 4, 3, 5, 3, 1, 1, 1, + 1, 1, 1, 4, 4, 3, 1 +}; + +/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state + STATE-NUM when YYTABLE doesn't specify something else to do. Zero + means the default is an error. */ +static const yytype_uint8 yydefact[] = +{ + 0, 3, 4, 21, 22, 0, 0, 0, 0, 0, + 2, 9, 0, 17, 18, 19, 20, 0, 5, 0, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 10, + 8, 26, 0, 6, 7, 0, 16, 14, 0, 0, + 23, 0, 0, 24, 0, 13, 12, 11, 25, 15 +}; + +/* YYDEFGOTO[NTERM-NUM]. */ +static const yytype_int8 yydefgoto[] = +{ + -1, 9, 10, 28, 11, 12, 13, 14, 15, 16, + 32 +}; + +/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ +#define YYPACT_NINF -31 +static const yytype_int8 yypact[] = +{ + 22, -31, -31, -31, -31, -1, 22, 22, -11, 27, + 11, -31, -6, -31, -31, -31, -31, 19, 11, 9, + 26, -31, 22, 22, -4, 19, 24, 25, 28, 23, + -31, 29, 31, 11, 11, 19, -31, -31, 19, 19, + -31, 19, 26, -31, 30, -31, -31, -31, -31, -31 +}; + +/* YYPGOTO[NTERM-NUM]. */ +static const yytype_int8 yypgoto[] = +{ + -31, -31, -3, -30, -31, -17, -31, -31, -31, 21, + 1 +}; + +/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If + positive, shift that token. If negative, reduce the rule which + number is the opposite. If zero, do what YYDEFACT says. + If YYTABLE_NINF, syntax error. */ +#define YYTABLE_NINF -1 +static const yytype_uint8 yytable[] = +{ + 29, 24, 25, 18, 19, 44, 26, 20, 37, 35, + 27, 47, 17, 8, 22, 23, 22, 23, 29, 33, + 34, 45, 46, 30, 29, 1, 2, 21, 3, 4, + 5, 3, 4, 5, 6, 7, 8, 31, 41, 8, + 38, 39, 40, 48, 49, 36, 0, 0, 0, 42, + 43 +}; + +static const yytype_int8 yycheck[] = +{ + 17, 7, 8, 6, 7, 35, 12, 18, 25, 13, + 16, 41, 13, 17, 5, 6, 5, 6, 35, 22, + 23, 38, 39, 14, 41, 3, 4, 0, 9, 10, + 11, 9, 10, 11, 12, 13, 17, 11, 15, 17, + 16, 16, 14, 42, 14, 24, -1, -1, -1, 20, + 19 +}; + +/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing + symbol of state STATE-NUM. */ +static const yytype_uint8 yystos[] = +{ + 0, 3, 4, 9, 10, 11, 12, 13, 17, 22, + 23, 25, 26, 27, 28, 29, 30, 13, 23, 23, + 18, 0, 5, 6, 7, 8, 12, 16, 24, 26, + 14, 11, 31, 23, 23, 13, 30, 26, 16, 16, + 14, 15, 20, 19, 24, 26, 26, 24, 31, 14 +}; + +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) +#define YYEMPTY (-2) +#define YYEOF 0 + +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrorlab + + +/* Like YYERROR except do call yyerror. This remains here temporarily + to ease the transition to the new meaning of YYERROR, for GCC. + Once GCC version 2 has supplanted version 1, this can go. */ + +#define YYFAIL goto yyerrlab + +#define YYRECOVERING() (!!yyerrstatus) + +#define YYBACKUP(Token, Value) \ +do \ + if (yychar == YYEMPTY && yylen == 1) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + yytoken = YYTRANSLATE (yychar); \ + YYPOPSTACK (1); \ + goto yybackup; \ + } \ + else \ + { \ + yyerror (YY_("syntax error: cannot back up")); \ + YYERROR; \ + } \ +while (YYID (0)) + + +#define YYTERROR 1 +#define YYERRCODE 256 + + +/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. + If N is 0, then set CURRENT to the empty location which ends + the previous symbol: RHS[0] (always defined). */ + +#define YYRHSLOC(Rhs, K) ((Rhs)[K]) +#ifndef YYLLOC_DEFAULT +# define YYLLOC_DEFAULT(Current, Rhs, N) \ + do \ + if (YYID (N)) \ + { \ + (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ + (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ + (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ + (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ + } \ + else \ + { \ + (Current).first_line = (Current).last_line = \ + YYRHSLOC (Rhs, 0).last_line; \ + (Current).first_column = (Current).last_column = \ + YYRHSLOC (Rhs, 0).last_column; \ + } \ + while (YYID (0)) +#endif + + +/* YY_LOCATION_PRINT -- Print the location on the stream. + This macro was not mandated originally: define only if we know + we won't break user code: when these are the locations we know. */ + +#ifndef YY_LOCATION_PRINT +# if YYLTYPE_IS_TRIVIAL +# define YY_LOCATION_PRINT(File, Loc) \ + fprintf (File, "%d.%d-%d.%d", \ + (Loc).first_line, (Loc).first_column, \ + (Loc).last_line, (Loc).last_column) +# else +# define YY_LOCATION_PRINT(File, Loc) ((void) 0) +# endif +#endif + + +/* YYLEX -- calling `yylex' with the right arguments. */ + +#ifdef YYLEX_PARAM +# define YYLEX yylex (YYLEX_PARAM) +#else +# define YYLEX yylex () +#endif + +/* Enable debugging if requested. */ +#if YYDEBUG + +# ifndef YYFPRINTF +# include <stdio.h> /* INFRINGES ON USER NAME SPACE */ +# define YYFPRINTF fprintf +# endif + +# define YYDPRINTF(Args) \ +do { \ + if (yydebug) \ + YYFPRINTF Args; \ +} while (YYID (0)) + +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ +do { \ + if (yydebug) \ + { \ + YYFPRINTF (stderr, "%s ", Title); \ + yy_symbol_print (stderr, \ + Type, Value); \ + YYFPRINTF (stderr, "\n"); \ + } \ +} while (YYID (0)) + + +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +/*ARGSUSED*/ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) +#else +static void +yy_symbol_value_print (yyoutput, yytype, yyvaluep) + FILE *yyoutput; + int yytype; + YYSTYPE const * const yyvaluep; +#endif +{ + if (!yyvaluep) + return; +# ifdef YYPRINT + if (yytype < YYNTOKENS) + YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); +# else + YYUSE (yyoutput); +# endif + switch (yytype) + { + default: + break; + } +} + + +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) +#else +static void +yy_symbol_print (yyoutput, yytype, yyvaluep) + FILE *yyoutput; + int yytype; + YYSTYPE const * const yyvaluep; +#endif +{ + if (yytype < YYNTOKENS) + YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); + else + YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); + + yy_symbol_value_print (yyoutput, yytype, yyvaluep); + YYFPRINTF (yyoutput, ")"); +} + +/*------------------------------------------------------------------. +| yy_stack_print -- Print the state stack from its BOTTOM up to its | +| TOP (included). | +`------------------------------------------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_stack_print (yytype_int16 *bottom, yytype_int16 *top) +#else +static void +yy_stack_print (bottom, top) + yytype_int16 *bottom; + yytype_int16 *top; +#endif +{ + YYFPRINTF (stderr, "Stack now"); + for (; bottom <= top; ++bottom) + YYFPRINTF (stderr, " %d", *bottom); + YYFPRINTF (stderr, "\n"); +} + +# define YY_STACK_PRINT(Bottom, Top) \ +do { \ + if (yydebug) \ + yy_stack_print ((Bottom), (Top)); \ +} while (YYID (0)) + + +/*------------------------------------------------. +| Report that the YYRULE is going to be reduced. | +`------------------------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_reduce_print (YYSTYPE *yyvsp, int yyrule) +#else +static void +yy_reduce_print (yyvsp, yyrule) + YYSTYPE *yyvsp; + int yyrule; +#endif +{ + int yynrhs = yyr2[yyrule]; + int yyi; + unsigned long int yylno = yyrline[yyrule]; + YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", + yyrule - 1, yylno); + /* The symbols being reduced. */ + for (yyi = 0; yyi < yynrhs; yyi++) + { + fprintf (stderr, " $%d = ", yyi + 1); + yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], + &(yyvsp[(yyi + 1) - (yynrhs)]) + ); + fprintf (stderr, "\n"); + } +} + +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug) \ + yy_reduce_print (yyvsp, Rule); \ +} while (YYID (0)) + +/* Nonzero means print parse trace. It is left uninitialized so that + multiple parsers can coexist. */ +int yydebug; +#else /* !YYDEBUG */ +# define YYDPRINTF(Args) +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) +# define YY_STACK_PRINT(Bottom, Top) +# define YY_REDUCE_PRINT(Rule) +#endif /* !YYDEBUG */ + + +/* YYINITDEPTH -- initial size of the parser's stacks. */ +#ifndef YYINITDEPTH +# define YYINITDEPTH 200 +#endif + +/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only + if the built-in stack extension method is used). + + Do not make this value too large; the results are undefined if + YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) + evaluated with infinite-precision integer arithmetic. */ + +#ifndef YYMAXDEPTH +# define YYMAXDEPTH 10000 +#endif + + + +#if YYERROR_VERBOSE + +# ifndef yystrlen +# if defined __GLIBC__ && defined _STRING_H +# define yystrlen strlen +# else +/* Return the length of YYSTR. */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static YYSIZE_T +yystrlen (const char *yystr) +#else +static YYSIZE_T +yystrlen (yystr) + const char *yystr; +#endif +{ + YYSIZE_T yylen; + for (yylen = 0; yystr[yylen]; yylen++) + continue; + return yylen; +} +# endif +# endif + +# ifndef yystpcpy +# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE +# define yystpcpy stpcpy +# else +/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in + YYDEST. */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static char * +yystpcpy (char *yydest, const char *yysrc) +#else +static char * +yystpcpy (yydest, yysrc) + char *yydest; + const char *yysrc; +#endif +{ + char *yyd = yydest; + const char *yys = yysrc; + + while ((*yyd++ = *yys++) != '\0') + continue; + + return yyd - 1; +} +# endif +# endif + +# ifndef yytnamerr +/* Copy to YYRES the contents of YYSTR after stripping away unnecessary + quotes and backslashes, so that it's suitable for yyerror. The + heuristic is that double-quoting is unnecessary unless the string + contains an apostrophe, a comma, or backslash (other than + backslash-backslash). YYSTR is taken from yytname. If YYRES is + null, do not copy; instead, return the length of what the result + would have been. */ +static YYSIZE_T +yytnamerr (char *yyres, const char *yystr) +{ + if (*yystr == '"') + { + YYSIZE_T yyn = 0; + char const *yyp = yystr; + + for (;;) + switch (*++yyp) + { + case '\'': + case ',': + goto do_not_strip_quotes; + + case '\\': + if (*++yyp != '\\') + goto do_not_strip_quotes; + /* Fall through. */ + default: + if (yyres) + yyres[yyn] = *yyp; + yyn++; + break; + + case '"': + if (yyres) + yyres[yyn] = '\0'; + return yyn; + } + do_not_strip_quotes: ; + } + + if (! yyres) + return yystrlen (yystr); + + return yystpcpy (yyres, yystr) - yyres; +} +# endif + +/* Copy into YYRESULT an error message about the unexpected token + YYCHAR while in state YYSTATE. Return the number of bytes copied, + including the terminating null byte. If YYRESULT is null, do not + copy anything; just return the number of bytes that would be + copied. As a special case, return 0 if an ordinary "syntax error" + message will do. Return YYSIZE_MAXIMUM if overflow occurs during + size calculation. */ +static YYSIZE_T +yysyntax_error (char *yyresult, int yystate, int yychar) +{ + int yyn = yypact[yystate]; + + if (! (YYPACT_NINF < yyn && yyn <= YYLAST)) + return 0; + else + { + int yytype = YYTRANSLATE (yychar); + YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]); + YYSIZE_T yysize = yysize0; + YYSIZE_T yysize1; + int yysize_overflow = 0; + enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; + char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; + int yyx; + +# if 0 + /* This is so xgettext sees the translatable formats that are + constructed on the fly. */ + YY_("syntax error, unexpected %s"); + YY_("syntax error, unexpected %s, expecting %s"); + YY_("syntax error, unexpected %s, expecting %s or %s"); + YY_("syntax error, unexpected %s, expecting %s or %s or %s"); + YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"); +# endif + char *yyfmt; + char const *yyf; + static char const yyunexpected[] = "syntax error, unexpected %s"; + static char const yyexpecting[] = ", expecting %s"; + static char const yyor[] = " or %s"; + char yyformat[sizeof yyunexpected + + sizeof yyexpecting - 1 + + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2) + * (sizeof yyor - 1))]; + char const *yyprefix = yyexpecting; + + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. */ + int yyxbegin = yyn < 0 ? -yyn : 0; + + /* Stay within bounds of both yycheck and yytname. */ + int yychecklim = YYLAST - yyn + 1; + int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; + int yycount = 1; + + yyarg[0] = yytname[yytype]; + yyfmt = yystpcpy (yyformat, yyunexpected); + + for (yyx = yyxbegin; yyx < yyxend; ++yyx) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) + { + if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) + { + yycount = 1; + yysize = yysize0; + yyformat[sizeof yyunexpected - 1] = '\0'; + break; + } + yyarg[yycount++] = yytname[yyx]; + yysize1 = yysize + yytnamerr (0, yytname[yyx]); + yysize_overflow |= (yysize1 < yysize); + yysize = yysize1; + yyfmt = yystpcpy (yyfmt, yyprefix); + yyprefix = yyor; + } + + yyf = YY_(yyformat); + yysize1 = yysize + yystrlen (yyf); + yysize_overflow |= (yysize1 < yysize); + yysize = yysize1; + + if (yysize_overflow) + return YYSIZE_MAXIMUM; + + if (yyresult) + { + /* Avoid sprintf, as that infringes on the user's name space. + Don't have undefined behavior even if the translation + produced a string with the wrong number of "%s"s. */ + char *yyp = yyresult; + int yyi = 0; + while ((*yyp = *yyf) != '\0') + { + if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) + { + yyp += yytnamerr (yyp, yyarg[yyi++]); + yyf += 2; + } + else + { + yyp++; + yyf++; + } + } + } + return yysize; + } +} +#endif /* YYERROR_VERBOSE */ + + +/*-----------------------------------------------. +| Release the memory associated to this symbol. | +`-----------------------------------------------*/ + +/*ARGSUSED*/ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) +#else +static void +yydestruct (yymsg, yytype, yyvaluep) + const char *yymsg; + int yytype; + YYSTYPE *yyvaluep; +#endif +{ + YYUSE (yyvaluep); + + if (!yymsg) + yymsg = "Deleting"; + YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); + + switch (yytype) + { + + default: + break; + } +} + + +/* Prevent warnings from -Wmissing-prototypes. */ + +#ifdef YYPARSE_PARAM +#if defined __STDC__ || defined __cplusplus +int yyparse (void *YYPARSE_PARAM); +#else +int yyparse (); +#endif +#else /* ! YYPARSE_PARAM */ +#if defined __STDC__ || defined __cplusplus +int yyparse (void); +#else +int yyparse (); +#endif +#endif /* ! YYPARSE_PARAM */ + + + +/* The look-ahead symbol. */ +int yychar; + +/* The semantic value of the look-ahead symbol. */ +YYSTYPE yylval; + +/* Number of syntax errors so far. */ +int yynerrs; + + + +/*----------. +| yyparse. | +`----------*/ + +#ifdef YYPARSE_PARAM +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +int +yyparse (void *YYPARSE_PARAM) +#else +int +yyparse (YYPARSE_PARAM) + void *YYPARSE_PARAM; +#endif +#else /* ! YYPARSE_PARAM */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +int +yyparse (void) +#else +int +yyparse () + +#endif +#endif +{ + + int yystate; + int yyn; + int yyresult; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus; + /* Look-ahead token as an internal (translated) token number. */ + int yytoken = 0; +#if YYERROR_VERBOSE + /* Buffer for error messages, and its allocated size. */ + char yymsgbuf[128]; + char *yymsg = yymsgbuf; + YYSIZE_T yymsg_alloc = sizeof yymsgbuf; +#endif + + /* Three stacks and their tools: + `yyss': related to states, + `yyvs': related to semantic values, + `yyls': related to locations. + + Refer to the stacks thru separate pointers, to allow yyoverflow + to reallocate them elsewhere. */ + + /* The state stack. */ + yytype_int16 yyssa[YYINITDEPTH]; + yytype_int16 *yyss = yyssa; + yytype_int16 *yyssp; + + /* The semantic value stack. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs = yyvsa; + YYSTYPE *yyvsp; + + + +#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) + + YYSIZE_T yystacksize = YYINITDEPTH; + + /* The variables used to return semantic value and location from the + action routines. */ + YYSTYPE yyval; + + + /* The number of symbols on the RHS of the reduced rule. + Keep to zero when no symbol should be popped. */ + int yylen = 0; + + YYDPRINTF ((stderr, "Starting parse\n")); + + yystate = 0; + yyerrstatus = 0; + yynerrs = 0; + yychar = YYEMPTY; /* Cause a token to be read. */ + + /* Initialize stack pointers. + Waste one element of value and location stack + so that they stay on the same level as the state stack. + The wasted elements are never initialized. */ + + yyssp = yyss; + yyvsp = yyvs; + + goto yysetstate; + +/*------------------------------------------------------------. +| yynewstate -- Push a new state, which is found in yystate. | +`------------------------------------------------------------*/ + yynewstate: + /* In all cases, when you get here, the value and location stacks + have just been pushed. So pushing a state here evens the stacks. */ + yyssp++; + + yysetstate: + *yyssp = yystate; + + if (yyss + yystacksize - 1 <= yyssp) + { + /* Get the current used size of the three stacks, in elements. */ + YYSIZE_T yysize = yyssp - yyss + 1; + +#ifdef yyoverflow + { + /* Give user a chance to reallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ + YYSTYPE *yyvs1 = yyvs; + yytype_int16 *yyss1 = yyss; + + + /* Each stack pointer address is followed by the size of the + data in use in that stack, in bytes. This used to be a + conditional around just the two extra args, but that might + be undefined if yyoverflow is a macro. */ + yyoverflow (YY_("memory exhausted"), + &yyss1, yysize * sizeof (*yyssp), + &yyvs1, yysize * sizeof (*yyvsp), + + &yystacksize); + + yyss = yyss1; + yyvs = yyvs1; + } +#else /* no yyoverflow */ +# ifndef YYSTACK_RELOCATE + goto yyexhaustedlab; +# else + /* Extend the stack our own way. */ + if (YYMAXDEPTH <= yystacksize) + goto yyexhaustedlab; + yystacksize *= 2; + if (YYMAXDEPTH < yystacksize) + yystacksize = YYMAXDEPTH; + + { + yytype_int16 *yyss1 = yyss; + union yyalloc *yyptr = + (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); + if (! yyptr) + goto yyexhaustedlab; + YYSTACK_RELOCATE (yyss); + YYSTACK_RELOCATE (yyvs); + +# undef YYSTACK_RELOCATE + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); + } +# endif +#endif /* no yyoverflow */ + + yyssp = yyss + yysize - 1; + yyvsp = yyvs + yysize - 1; + + + YYDPRINTF ((stderr, "Stack size increased to %lu\n", + (unsigned long int) yystacksize)); + + if (yyss + yystacksize - 1 <= yyssp) + YYABORT; + } + + YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + + goto yybackup; + +/*-----------. +| yybackup. | +`-----------*/ +yybackup: + + /* Do appropriate processing given the current state. Read a + look-ahead token if we need one and don't already have one. */ + + /* First try to decide what to do without reference to look-ahead token. */ + yyn = yypact[yystate]; + if (yyn == YYPACT_NINF) + goto yydefault; + + /* Not known => get a look-ahead token if don't already have one. */ + + /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */ + if (yychar == YYEMPTY) + { + YYDPRINTF ((stderr, "Reading a token: ")); + yychar = YYLEX; + } + + if (yychar <= YYEOF) + { + yychar = yytoken = YYEOF; + YYDPRINTF ((stderr, "Now at end of input.\n")); + } + else + { + yytoken = YYTRANSLATE (yychar); + YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); + } + + /* If the proper action on seeing token YYTOKEN is to reduce or to + detect an error, take that action. */ + yyn += yytoken; + if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) + goto yydefault; + yyn = yytable[yyn]; + if (yyn <= 0) + { + if (yyn == 0 || yyn == YYTABLE_NINF) + goto yyerrlab; + yyn = -yyn; + goto yyreduce; + } + + if (yyn == YYFINAL) + YYACCEPT; + + /* Count tokens shifted since error; after three, turn off error + status. */ + if (yyerrstatus) + yyerrstatus--; + + /* Shift the look-ahead token. */ + YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); + + /* Discard the shifted token unless it is eof. */ + if (yychar != YYEOF) + yychar = YYEMPTY; + + yystate = yyn; + *++yyvsp = yylval; + + goto yynewstate; + + +/*-----------------------------------------------------------. +| yydefault -- do the default action for the current state. | +`-----------------------------------------------------------*/ +yydefault: + yyn = yydefact[yystate]; + if (yyn == 0) + goto yyerrlab; + goto yyreduce; + + +/*-----------------------------. +| yyreduce -- Do a reduction. | +`-----------------------------*/ +yyreduce: + /* yyn is the number of a rule to reduce with. */ + yylen = yyr2[yyn]; + + /* If YYLEN is nonzero, implement the default value of the action: + `$$ = $1'. + + Otherwise, the following line sets YYVAL to garbage. + This behavior is undocumented and Bison + users should not rely upon it. Assigning to YYVAL + unconditionally makes the parser a bit smaller, and it avoids a + GCC warning that YYVAL may be used uninitialized. */ + yyval = yyvsp[1-yylen]; + + + YY_REDUCE_PRINT (yyn); + switch (yyn) + { + case 2: +#line 74 "heimdal/lib/hx509/sel-gram.y" + { _hx509_expr_input.expr = (yyvsp[(1) - (1)].expr); } + break; + + case 3: +#line 76 "heimdal/lib/hx509/sel-gram.y" + { (yyval.expr) = _hx509_make_expr(op_TRUE, NULL, NULL); } + break; + + case 4: +#line 77 "heimdal/lib/hx509/sel-gram.y" + { (yyval.expr) = _hx509_make_expr(op_FALSE, NULL, NULL); } + break; + + case 5: +#line 78 "heimdal/lib/hx509/sel-gram.y" + { (yyval.expr) = _hx509_make_expr(op_NOT, (yyvsp[(2) - (2)].expr), NULL); } + break; + + case 6: +#line 79 "heimdal/lib/hx509/sel-gram.y" + { (yyval.expr) = _hx509_make_expr(op_AND, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); } + break; + + case 7: +#line 80 "heimdal/lib/hx509/sel-gram.y" + { (yyval.expr) = _hx509_make_expr(op_OR, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); } + break; + + case 8: +#line 81 "heimdal/lib/hx509/sel-gram.y" + { (yyval.expr) = (yyvsp[(2) - (3)].expr); } + break; + + case 9: +#line 82 "heimdal/lib/hx509/sel-gram.y" + { (yyval.expr) = _hx509_make_expr(op_COMP, (yyvsp[(1) - (1)].expr), NULL); } + break; + + case 10: +#line 85 "heimdal/lib/hx509/sel-gram.y" + { (yyval.expr) = _hx509_make_expr(expr_WORDS, (yyvsp[(1) - (1)].expr), NULL); } + break; + + case 11: +#line 86 "heimdal/lib/hx509/sel-gram.y" + { (yyval.expr) = _hx509_make_expr(expr_WORDS, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); } + break; + + case 12: +#line 89 "heimdal/lib/hx509/sel-gram.y" + { (yyval.expr) = _hx509_make_expr(comp_EQ, (yyvsp[(1) - (4)].expr), (yyvsp[(4) - (4)].expr)); } + break; + + case 13: +#line 90 "heimdal/lib/hx509/sel-gram.y" + { (yyval.expr) = _hx509_make_expr(comp_NE, (yyvsp[(1) - (4)].expr), (yyvsp[(4) - (4)].expr)); } + break; + + case 14: +#line 91 "heimdal/lib/hx509/sel-gram.y" + { (yyval.expr) = _hx509_make_expr(comp_TAILEQ, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); } + break; + + case 15: +#line 92 "heimdal/lib/hx509/sel-gram.y" + { (yyval.expr) = _hx509_make_expr(comp_IN, (yyvsp[(1) - (5)].expr), (yyvsp[(4) - (5)].expr)); } + break; + + case 16: +#line 93 "heimdal/lib/hx509/sel-gram.y" + { (yyval.expr) = _hx509_make_expr(comp_IN, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); } + break; + + case 17: +#line 96 "heimdal/lib/hx509/sel-gram.y" + { (yyval.expr) = (yyvsp[(1) - (1)].expr); } + break; + + case 18: +#line 97 "heimdal/lib/hx509/sel-gram.y" + { (yyval.expr) = (yyvsp[(1) - (1)].expr); } + break; + + case 19: +#line 98 "heimdal/lib/hx509/sel-gram.y" + { (yyval.expr) = (yyvsp[(1) - (1)].expr); } + break; + + case 20: +#line 99 "heimdal/lib/hx509/sel-gram.y" + { (yyval.expr) = (yyvsp[(1) - (1)].expr); } + break; + + case 21: +#line 102 "heimdal/lib/hx509/sel-gram.y" + { (yyval.expr) = _hx509_make_expr(expr_NUMBER, (yyvsp[(1) - (1)].string), NULL); } + break; + + case 22: +#line 103 "heimdal/lib/hx509/sel-gram.y" + { (yyval.expr) = _hx509_make_expr(expr_STRING, (yyvsp[(1) - (1)].string), NULL); } + break; + + case 23: +#line 105 "heimdal/lib/hx509/sel-gram.y" + { + (yyval.expr) = _hx509_make_expr(expr_FUNCTION, (yyvsp[(1) - (4)].string), (yyvsp[(3) - (4)].expr)); } + break; + + case 24: +#line 108 "heimdal/lib/hx509/sel-gram.y" + { (yyval.expr) = (yyvsp[(3) - (4)].expr); } + break; + + case 25: +#line 111 "heimdal/lib/hx509/sel-gram.y" + { + (yyval.expr) = _hx509_make_expr(expr_VAR, (yyvsp[(1) - (3)].string), (yyvsp[(3) - (3)].expr)); } + break; + + case 26: +#line 113 "heimdal/lib/hx509/sel-gram.y" + { + (yyval.expr) = _hx509_make_expr(expr_VAR, (yyvsp[(1) - (1)].string), NULL); } + break; + + +/* Line 1267 of yacc.c. */ +#line 1501 "heimdal/lib/hx509/sel-gram.y" + default: break; + } + YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); + + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + + *++yyvsp = yyval; + + + /* Now `shift' the result of the reduction. Determine what state + that goes to, based on the state we popped back to and the rule + number reduced by. */ + + yyn = yyr1[yyn]; + + yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; + if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) + yystate = yytable[yystate]; + else + yystate = yydefgoto[yyn - YYNTOKENS]; + + goto yynewstate; + + +/*------------------------------------. +| yyerrlab -- here on detecting error | +`------------------------------------*/ +yyerrlab: + /* If not already recovering from an error, report this error. */ + if (!yyerrstatus) + { + ++yynerrs; +#if ! YYERROR_VERBOSE + yyerror (YY_("syntax error")); +#else + { + YYSIZE_T yysize = yysyntax_error (0, yystate, yychar); + if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM) + { + YYSIZE_T yyalloc = 2 * yysize; + if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM)) + yyalloc = YYSTACK_ALLOC_MAXIMUM; + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); + yymsg = (char *) YYSTACK_ALLOC (yyalloc); + if (yymsg) + yymsg_alloc = yyalloc; + else + { + yymsg = yymsgbuf; + yymsg_alloc = sizeof yymsgbuf; + } + } + + if (0 < yysize && yysize <= yymsg_alloc) + { + (void) yysyntax_error (yymsg, yystate, yychar); + yyerror (yymsg); + } + else + { + yyerror (YY_("syntax error")); + if (yysize != 0) + goto yyexhaustedlab; + } + } +#endif + } + + + + if (yyerrstatus == 3) + { + /* If just tried and failed to reuse look-ahead token after an + error, discard it. */ + + if (yychar <= YYEOF) + { + /* Return failure if at end of input. */ + if (yychar == YYEOF) + YYABORT; + } + else + { + yydestruct ("Error: discarding", + yytoken, &yylval); + yychar = YYEMPTY; + } + } + + /* Else will try to reuse look-ahead token after shifting the error + token. */ + goto yyerrlab1; + + +/*---------------------------------------------------. +| yyerrorlab -- error raised explicitly by YYERROR. | +`---------------------------------------------------*/ +yyerrorlab: + + /* Pacify compilers like GCC when the user code never invokes + YYERROR and the label yyerrorlab therefore never appears in user + code. */ + if (/*CONSTCOND*/ 0) + goto yyerrorlab; + + /* Do not reclaim the symbols of the rule which action triggered + this YYERROR. */ + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + yystate = *yyssp; + goto yyerrlab1; + + +/*-------------------------------------------------------------. +| yyerrlab1 -- common code for both syntax error and YYERROR. | +`-------------------------------------------------------------*/ +yyerrlab1: + yyerrstatus = 3; /* Each real token shifted decrements this. */ + + for (;;) + { + yyn = yypact[yystate]; + if (yyn != YYPACT_NINF) + { + yyn += YYTERROR; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) + { + yyn = yytable[yyn]; + if (0 < yyn) + break; + } + } + + /* Pop the current state because it cannot handle the error token. */ + if (yyssp == yyss) + YYABORT; + + + yydestruct ("Error: popping", + yystos[yystate], yyvsp); + YYPOPSTACK (1); + yystate = *yyssp; + YY_STACK_PRINT (yyss, yyssp); + } + + if (yyn == YYFINAL) + YYACCEPT; + + *++yyvsp = yylval; + + + /* Shift the error token. */ + YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); + + yystate = yyn; + goto yynewstate; + + +/*-------------------------------------. +| yyacceptlab -- YYACCEPT comes here. | +`-------------------------------------*/ +yyacceptlab: + yyresult = 0; + goto yyreturn; + +/*-----------------------------------. +| yyabortlab -- YYABORT comes here. | +`-----------------------------------*/ +yyabortlab: + yyresult = 1; + goto yyreturn; + +#ifndef yyoverflow +/*-------------------------------------------------. +| yyexhaustedlab -- memory exhaustion comes here. | +`-------------------------------------------------*/ +yyexhaustedlab: + yyerror (YY_("memory exhausted")); + yyresult = 2; + /* Fall through. */ +#endif + +yyreturn: + if (yychar != YYEOF && yychar != YYEMPTY) + yydestruct ("Cleanup: discarding lookahead", + yytoken, &yylval); + /* Do not reclaim the symbols of the rule which action triggered + this YYABORT or YYACCEPT. */ + YYPOPSTACK (yylen); + YY_STACK_PRINT (yyss, yyssp); + while (yyssp != yyss) + { + yydestruct ("Cleanup: popping", + yystos[*yyssp], yyvsp); + YYPOPSTACK (1); + } +#ifndef yyoverflow + if (yyss != yyssa) + YYSTACK_FREE (yyss); +#endif +#if YYERROR_VERBOSE + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); +#endif + /* Make sure YYID is used. */ + return YYID (yyresult); +} + + + diff --git a/source4/heimdal/lib/hx509/sel-gram.h b/source4/heimdal/lib/hx509/sel-gram.h new file mode 100644 index 0000000000..bb4a64d1c7 --- /dev/null +++ b/source4/heimdal/lib/hx509/sel-gram.h @@ -0,0 +1,83 @@ +/* A Bison parser, made by GNU Bison 2.3. */ + +/* Skeleton interface for Bison's Yacc-like parsers in C + + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 + Free Software Foundation, Inc. + + 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 2, 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, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + kw_TRUE = 258, + kw_FALSE = 259, + kw_AND = 260, + kw_OR = 261, + kw_IN = 262, + kw_TAILMATCH = 263, + NUMBER = 264, + STRING = 265, + IDENTIFIER = 266 + }; +#endif +/* Tokens. */ +#define kw_TRUE 258 +#define kw_FALSE 259 +#define kw_AND 260 +#define kw_OR 261 +#define kw_IN 262 +#define kw_TAILMATCH 263 +#define NUMBER 264 +#define STRING 265 +#define IDENTIFIER 266 + + + + +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +typedef union YYSTYPE +#line 46 "heimdal/lib/hx509/sel-gram.y" +{ + char *string; + struct hx_expr *expr; +} +/* Line 1489 of yacc.c. */ +#line 76 "heimdal/lib/hx509/sel-gram.y" + YYSTYPE; +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +# define YYSTYPE_IS_DECLARED 1 +# define YYSTYPE_IS_TRIVIAL 1 +#endif + +extern YYSTYPE yylval; + diff --git a/source4/heimdal/lib/hx509/sel-gram.y b/source4/heimdal/lib/hx509/sel-gram.y new file mode 100644 index 0000000000..ca34a1975f --- /dev/null +++ b/source4/heimdal/lib/hx509/sel-gram.y @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2008 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +%{ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <stdio.h> +#include <stdlib.h> +#include <hx_locl.h> + +RCSID("$Id$"); + +%} + +%union { + char *string; + struct hx_expr *expr; +} + +%token kw_TRUE +%token kw_FALSE +%token kw_AND +%token kw_OR +%token kw_IN +%token kw_TAILMATCH + +%type <expr> expr +%type <expr> comp +%type <expr> word words +%type <expr> number +%type <expr> string +%type <expr> function +%type <expr> variable variables + +%token <string> NUMBER +%token <string> STRING +%token <string> IDENTIFIER + +%start start + +%% + +start: expr { _hx509_expr_input.expr = $1; } + +expr : kw_TRUE { $$ = _hx509_make_expr(op_TRUE, NULL, NULL); } + | kw_FALSE { $$ = _hx509_make_expr(op_FALSE, NULL, NULL); } + | '!' expr { $$ = _hx509_make_expr(op_NOT, $2, NULL); } + | expr kw_AND expr { $$ = _hx509_make_expr(op_AND, $1, $3); } + | expr kw_OR expr { $$ = _hx509_make_expr(op_OR, $1, $3); } + | '(' expr ')' { $$ = $2; } + | comp { $$ = _hx509_make_expr(op_COMP, $1, NULL); } + ; + +words : word { $$ = _hx509_make_expr(expr_WORDS, $1, NULL); } + | word ',' words { $$ = _hx509_make_expr(expr_WORDS, $1, $3); } + ; + +comp : word '=' '=' word { $$ = _hx509_make_expr(comp_EQ, $1, $4); } + | word '!' '=' word { $$ = _hx509_make_expr(comp_NE, $1, $4); } + | word kw_TAILMATCH word { $$ = _hx509_make_expr(comp_TAILEQ, $1, $3); } + | word kw_IN '(' words ')' { $$ = _hx509_make_expr(comp_IN, $1, $4); } + | word kw_IN variable { $$ = _hx509_make_expr(comp_IN, $1, $3); } + ; + +word : number { $$ = $1; } + | string { $$ = $1; } + | function { $$ = $1; } + | variable { $$ = $1; } + ; + +number : NUMBER { $$ = _hx509_make_expr(expr_NUMBER, $1, NULL); }; +string : STRING { $$ = _hx509_make_expr(expr_STRING, $1, NULL); }; + +function: IDENTIFIER '(' words ')' { + $$ = _hx509_make_expr(expr_FUNCTION, $1, $3); } + ; +variable: '%' '{' variables '}' { $$ = $3; } + ; + +variables: IDENTIFIER '.' variables { + $$ = _hx509_make_expr(expr_VAR, $1, $3); } + | IDENTIFIER { + $$ = _hx509_make_expr(expr_VAR, $1, NULL); } + ; diff --git a/source4/heimdal/lib/hx509/sel-lex.c b/source4/heimdal/lib/hx509/sel-lex.c new file mode 100644 index 0000000000..8dcb374c1f --- /dev/null +++ b/source4/heimdal/lib/hx509/sel-lex.c @@ -0,0 +1,1899 @@ +#include "config.h" + +#line 3 "heimdal/lib/hx509/sel-lex.c" + +#define YY_INT_ALIGNED short int + +/* A lexical scanner generated by flex */ + +#define FLEX_SCANNER +#define YY_FLEX_MAJOR_VERSION 2 +#define YY_FLEX_MINOR_VERSION 5 +#define YY_FLEX_SUBMINOR_VERSION 34 +#if YY_FLEX_SUBMINOR_VERSION > 0 +#define FLEX_BETA +#endif + +/* First, we deal with platform-specific or compiler-specific issues. */ + +/* begin standard C headers. */ +#include <stdio.h> +#include <string.h> +#include <errno.h> +#include <stdlib.h> + +/* end standard C headers. */ + +/* flex integer type definitions */ + +#ifndef FLEXINT_H +#define FLEXINT_H + +/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */ + +#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + +/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, + * if you want the limit (max/min) macros for int types. + */ +#ifndef __STDC_LIMIT_MACROS +#define __STDC_LIMIT_MACROS 1 +#endif + +#include <inttypes.h> +typedef int8_t flex_int8_t; +typedef uint8_t flex_uint8_t; +typedef int16_t flex_int16_t; +typedef uint16_t flex_uint16_t; +typedef int32_t flex_int32_t; +typedef uint32_t flex_uint32_t; +#else +typedef signed char flex_int8_t; +typedef short int flex_int16_t; +typedef int flex_int32_t; +typedef unsigned char flex_uint8_t; +typedef unsigned short int flex_uint16_t; +typedef unsigned int flex_uint32_t; +#endif /* ! C99 */ + +/* Limits of integral types. */ +#ifndef INT8_MIN +#define INT8_MIN (-128) +#endif +#ifndef INT16_MIN +#define INT16_MIN (-32767-1) +#endif +#ifndef INT32_MIN +#define INT32_MIN (-2147483647-1) +#endif +#ifndef INT8_MAX +#define INT8_MAX (127) +#endif +#ifndef INT16_MAX +#define INT16_MAX (32767) +#endif +#ifndef INT32_MAX +#define INT32_MAX (2147483647) +#endif +#ifndef UINT8_MAX +#define UINT8_MAX (255U) +#endif +#ifndef UINT16_MAX +#define UINT16_MAX (65535U) +#endif +#ifndef UINT32_MAX +#define UINT32_MAX (4294967295U) +#endif + +#endif /* ! FLEXINT_H */ + +#ifdef __cplusplus + +/* The "const" storage-class-modifier is valid. */ +#define YY_USE_CONST + +#else /* ! __cplusplus */ + +/* C99 requires __STDC__ to be defined as 1. */ +#if defined (__STDC__) + +#define YY_USE_CONST + +#endif /* defined (__STDC__) */ +#endif /* ! __cplusplus */ + +#ifdef YY_USE_CONST +#define yyconst const +#else +#define yyconst +#endif + +/* Returned upon end-of-file. */ +#define YY_NULL 0 + +/* Promotes a possibly negative, possibly signed char to an unsigned + * integer for use as an array index. If the signed char is negative, + * we want to instead treat it as an 8-bit unsigned char, hence the + * double cast. + */ +#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) + +/* Enter a start condition. This macro really ought to take a parameter, + * but we do it the disgusting crufty way forced on us by the ()-less + * definition of BEGIN. + */ +#define BEGIN (yy_start) = 1 + 2 * + +/* Translate the current start state into a value that can be later handed + * to BEGIN to return to the state. The YYSTATE alias is for lex + * compatibility. + */ +#define YY_START (((yy_start) - 1) / 2) +#define YYSTATE YY_START + +/* Action number for EOF rule of a given start state. */ +#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) + +/* Special action meaning "start processing a new file". */ +#define YY_NEW_FILE yyrestart(yyin ) + +#define YY_END_OF_BUFFER_CHAR 0 + +/* Size of default input buffer. */ +#ifndef YY_BUF_SIZE +#define YY_BUF_SIZE 16384 +#endif + +/* The state buf must be large enough to hold one state per character in the main buffer. + */ +#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) + +#ifndef YY_TYPEDEF_YY_BUFFER_STATE +#define YY_TYPEDEF_YY_BUFFER_STATE +typedef struct yy_buffer_state *YY_BUFFER_STATE; +#endif + +extern int yyleng; + +extern FILE *yyin, *yyout; + +#define EOB_ACT_CONTINUE_SCAN 0 +#define EOB_ACT_END_OF_FILE 1 +#define EOB_ACT_LAST_MATCH 2 + + #define YY_LESS_LINENO(n) + +/* Return all but the first "n" matched characters back to the input stream. */ +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + *yy_cp = (yy_hold_char); \ + YY_RESTORE_YY_MORE_OFFSET \ + (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ + YY_DO_BEFORE_ACTION; /* set up yytext again */ \ + } \ + while ( 0 ) + +#define unput(c) yyunput( c, (yytext_ptr) ) + +/* The following is because we cannot portably get our hands on size_t + * (without autoconf's help, which isn't available because we want + * flex-generated scanners to compile on their own). + * Given that the standard has decreed that size_t exists since 1989, + * I guess we can afford to depend on it. Manoj. + */ + +#ifndef YY_TYPEDEF_YY_SIZE_T +#define YY_TYPEDEF_YY_SIZE_T +typedef size_t yy_size_t; +#endif + +#ifndef YY_STRUCT_YY_BUFFER_STATE +#define YY_STRUCT_YY_BUFFER_STATE +struct yy_buffer_state + { + FILE *yy_input_file; + + char *yy_ch_buf; /* input buffer */ + char *yy_buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + yy_size_t yy_buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ + int yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to + * delete it. + */ + int yy_is_our_buffer; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int yy_is_interactive; + + /* Whether we're considered to be at the beginning of a line. + * If so, '^' rules will be active on the next match, otherwise + * not. + */ + int yy_at_bol; + + int yy_bs_lineno; /**< The line count. */ + int yy_bs_column; /**< The column count. */ + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int yy_fill_buffer; + + int yy_buffer_status; + +#define YY_BUFFER_NEW 0 +#define YY_BUFFER_NORMAL 1 + /* When an EOF's been seen but there's still some text to process + * then we mark the buffer as YY_EOF_PENDING, to indicate that we + * shouldn't try reading from the input source any more. We might + * still have a bunch of tokens to match, though, because of + * possible backing-up. + * + * When we actually see the EOF, we change the status to "new" + * (via yyrestart()), so that the user can continue scanning by + * just pointing yyin at a new input file. + */ +#define YY_BUFFER_EOF_PENDING 2 + + }; +#endif /* !YY_STRUCT_YY_BUFFER_STATE */ + +/* Stack of input buffers. */ +static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */ +static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */ +static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */ + +/* We provide macros for accessing buffer states in case in the + * future we want to put the buffer states in a more general + * "scanner state". + * + * Returns the top of the stack, or NULL. + */ +#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ + ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ + : NULL) + +/* Same as previous macro, but useful when we know that the buffer stack is not + * NULL or when we need an lvalue. For internal use only. + */ +#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] + +/* yy_hold_char holds the character lost when yytext is formed. */ +static char yy_hold_char; +static int yy_n_chars; /* number of characters read into yy_ch_buf */ +int yyleng; + +/* Points to current character in buffer. */ +static char *yy_c_buf_p = (char *) 0; +static int yy_init = 0; /* whether we need to initialize */ +static int yy_start = 0; /* start state number */ + +/* Flag which is used to allow yywrap()'s to do buffer switches + * instead of setting up a fresh yyin. A bit of a hack ... + */ +static int yy_did_buffer_switch_on_eof; + +void yyrestart (FILE *input_file ); +void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ); +YY_BUFFER_STATE yy_create_buffer (FILE *file,int size ); +void yy_delete_buffer (YY_BUFFER_STATE b ); +void yy_flush_buffer (YY_BUFFER_STATE b ); +void yypush_buffer_state (YY_BUFFER_STATE new_buffer ); +void yypop_buffer_state (void ); + +static void yyensure_buffer_stack (void ); +static void yy_load_buffer_state (void ); +static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file ); + +#define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER ) + +YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size ); +YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str ); +YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len ); + +void *yyalloc (yy_size_t ); +void *yyrealloc (void *,yy_size_t ); +void yyfree (void * ); + +#define yy_new_buffer yy_create_buffer + +#define yy_set_interactive(is_interactive) \ + { \ + if ( ! YY_CURRENT_BUFFER ){ \ + yyensure_buffer_stack (); \ + YY_CURRENT_BUFFER_LVALUE = \ + yy_create_buffer(yyin,YY_BUF_SIZE ); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ + } + +#define yy_set_bol(at_bol) \ + { \ + if ( ! YY_CURRENT_BUFFER ){\ + yyensure_buffer_stack (); \ + YY_CURRENT_BUFFER_LVALUE = \ + yy_create_buffer(yyin,YY_BUF_SIZE ); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ + } + +#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) + +/* Begin user sect3 */ + +typedef unsigned char YY_CHAR; + +FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0; + +typedef int yy_state_type; + +extern int yylineno; + +int yylineno = 1; + +extern char *yytext; +#define yytext_ptr yytext + +static yy_state_type yy_get_previous_state (void ); +static yy_state_type yy_try_NUL_trans (yy_state_type current_state ); +static int yy_get_next_buffer (void ); +static void yy_fatal_error (yyconst char msg[] ); + +/* Done after the current pattern has been matched and before the + * corresponding action - sets up yytext. + */ +#define YY_DO_BEFORE_ACTION \ + (yytext_ptr) = yy_bp; \ + yyleng = (size_t) (yy_cp - yy_bp); \ + (yy_hold_char) = *yy_cp; \ + *yy_cp = '\0'; \ + (yy_c_buf_p) = yy_cp; + +#define YY_NUM_RULES 12 +#define YY_END_OF_BUFFER 13 +/* This struct is not used in this scanner, + but its presence is necessary. */ +struct yy_trans_info + { + flex_int32_t yy_verify; + flex_int32_t yy_nxt; + }; +static yyconst flex_int16_t yy_accept[36] = + { 0, + 0, 0, 13, 12, 11, 9, 10, 8, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 5, 4, 7, + 7, 3, 7, 7, 7, 7, 7, 1, 2, 7, + 7, 7, 7, 6, 0 + } ; + +static yyconst flex_int32_t yy_ec[256] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 4, 5, 1, 1, 4, 1, 1, 4, + 4, 1, 1, 4, 6, 4, 1, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 1, 1, 1, + 4, 1, 1, 1, 7, 8, 9, 10, 11, 12, + 8, 13, 14, 8, 8, 15, 16, 17, 18, 8, + 8, 19, 20, 21, 22, 8, 8, 8, 8, 8, + 1, 1, 1, 1, 6, 1, 8, 8, 8, 8, + + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 4, 1, 4, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1 + } ; + +static yyconst flex_int32_t yy_meta[23] = + { 0, + 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2 + } ; + +static yyconst flex_int16_t yy_base[37] = + { 0, + 0, 0, 43, 44, 44, 44, 44, 44, 25, 0, + 34, 23, 20, 16, 0, 28, 22, 0, 0, 22, + 12, 0, 13, 17, 20, 19, 13, 0, 0, 21, + 6, 17, 12, 0, 44, 22 + } ; + +static yyconst flex_int16_t yy_def[37] = + { 0, + 35, 1, 35, 35, 35, 35, 35, 35, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 0, 35 + } ; + +static yyconst flex_int16_t yy_nxt[67] = + { 0, + 4, 5, 6, 7, 8, 4, 9, 10, 10, 10, + 10, 11, 10, 12, 10, 10, 10, 13, 10, 10, + 14, 10, 20, 15, 34, 33, 32, 31, 30, 29, + 28, 27, 26, 25, 21, 24, 23, 22, 19, 18, + 17, 16, 35, 3, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35 + } ; + +static yyconst flex_int16_t yy_chk[67] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 14, 36, 33, 32, 31, 30, 27, 26, + 25, 24, 23, 21, 14, 20, 17, 16, 13, 12, + 11, 9, 3, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35 + } ; + +static yy_state_type yy_last_accepting_state; +static char *yy_last_accepting_cpos; + +extern int yy_flex_debug; +int yy_flex_debug = 0; + +/* The intent behind this definition is that it'll catch + * any uses of REJECT which flex missed. + */ +#define REJECT reject_used_but_not_detected +#define yymore() yymore_used_but_not_detected +#define YY_MORE_ADJ 0 +#define YY_RESTORE_YY_MORE_OFFSET +char *yytext; +#line 1 "sel-lex.l" +#line 2 "sel-lex.l" +/* + * Copyright (c) 2004, 2008 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* $Id$ */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#undef ECHO + +#include <stdio.h> +#include <string.h> +#include <stdarg.h> +#include <stdlib.h> +#include "sel.h" +#include "sel-gram.h" +unsigned lineno = 1; + +static char * handle_string(void); +static int lex_input(char *, int); + +struct hx_expr_input _hx509_expr_input; + +#define YY_NO_UNPUT 1 + +#undef YY_INPUT +#define YY_INPUT(buf,res,maxsize) (res = lex_input(buf, maxsize)) + +#undef ECHO + +#line 541 "heimdal/lib/hx509/sel-lex.c" + +#define INITIAL 0 + +#ifndef YY_NO_UNISTD_H +/* Special case for "unistd.h", since it is non-ANSI. We include it way + * down here because we want the user's section 1 to have been scanned first. + * The user has a chance to override it with an option. + */ +#include <unistd.h> +#endif + +#ifndef YY_EXTRA_TYPE +#define YY_EXTRA_TYPE void * +#endif + +static int yy_init_globals (void ); + +/* Macros after this point can all be overridden by user definitions in + * section 1. + */ + +#ifndef YY_SKIP_YYWRAP +#ifdef __cplusplus +extern "C" int yywrap (void ); +#else +extern int yywrap (void ); +#endif +#endif + + static void yyunput (int c,char *buf_ptr ); + +#ifndef yytext_ptr +static void yy_flex_strncpy (char *,yyconst char *,int ); +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (yyconst char * ); +#endif + +#ifndef YY_NO_INPUT + +#ifdef __cplusplus +static int yyinput (void ); +#else +static int input (void ); +#endif + +#endif + +/* Amount of stuff to slurp up with each read. */ +#ifndef YY_READ_BUF_SIZE +#define YY_READ_BUF_SIZE 8192 +#endif + +/* Copy whatever the last rule matched to the standard output. */ +#ifndef ECHO +/* This used to be an fputs(), but since the string might contain NUL's, + * we now use fwrite(). + */ +#define ECHO fwrite( yytext, yyleng, 1, yyout ) +#endif + +/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, + * is returned in "result". + */ +#ifndef YY_INPUT +#define YY_INPUT(buf,result,max_size) \ + if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ + { \ + int c = '*'; \ + int n; \ + for ( n = 0; n < max_size && \ + (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ + buf[n] = (char) c; \ + if ( c == '\n' ) \ + buf[n++] = (char) c; \ + if ( c == EOF && ferror( yyin ) ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + result = n; \ + } \ + else \ + { \ + errno=0; \ + while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \ + { \ + if( errno != EINTR) \ + { \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + break; \ + } \ + errno=0; \ + clearerr(yyin); \ + } \ + }\ +\ + +#endif + +/* No semi-colon after return; correct usage is to write "yyterminate();" - + * we don't want an extra ';' after the "return" because that will cause + * some compilers to complain about unreachable statements. + */ +#ifndef yyterminate +#define yyterminate() return YY_NULL +#endif + +/* Number of entries by which start-condition stack grows. */ +#ifndef YY_START_STACK_INCR +#define YY_START_STACK_INCR 25 +#endif + +/* Report a fatal error. */ +#ifndef YY_FATAL_ERROR +#define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) +#endif + +/* end tables serialization structures and prototypes */ + +/* Default declaration of generated scanner - a define so the user can + * easily add parameters. + */ +#ifndef YY_DECL +#define YY_DECL_IS_OURS 1 + +extern int yylex (void); + +#define YY_DECL int yylex (void) +#endif /* !YY_DECL */ + +/* Code executed at the beginning of each rule, after yytext and yyleng + * have been set up. + */ +#ifndef YY_USER_ACTION +#define YY_USER_ACTION +#endif + +/* Code executed at the end of each rule. */ +#ifndef YY_BREAK +#define YY_BREAK break; +#endif + +#define YY_RULE_SETUP \ + YY_USER_ACTION + +/** The main scanner function which does all the work. + */ +YY_DECL +{ + register yy_state_type yy_current_state; + register char *yy_cp, *yy_bp; + register int yy_act; + +#line 64 "sel-lex.l" + + +#line 697 "heimdal/lib/hx509/sel-lex.c" + + if ( !(yy_init) ) + { + (yy_init) = 1; + +#ifdef YY_USER_INIT + YY_USER_INIT; +#endif + + if ( ! (yy_start) ) + (yy_start) = 1; /* first start state */ + + if ( ! yyin ) + yyin = stdin; + + if ( ! yyout ) + yyout = stdout; + + if ( ! YY_CURRENT_BUFFER ) { + yyensure_buffer_stack (); + YY_CURRENT_BUFFER_LVALUE = + yy_create_buffer(yyin,YY_BUF_SIZE ); + } + + yy_load_buffer_state( ); + } + + while ( 1 ) /* loops until end-of-file is reached */ + { + yy_cp = (yy_c_buf_p); + + /* Support of yytext. */ + *yy_cp = (yy_hold_char); + + /* yy_bp points to the position in yy_ch_buf of the start of + * the current run. + */ + yy_bp = yy_cp; + + yy_current_state = (yy_start); +yy_match: + do + { + register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 36 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + ++yy_cp; + } + while ( yy_base[yy_current_state] != 44 ); + +yy_find_action: + yy_act = yy_accept[yy_current_state]; + if ( yy_act == 0 ) + { /* have to back up */ + yy_cp = (yy_last_accepting_cpos); + yy_current_state = (yy_last_accepting_state); + yy_act = yy_accept[yy_current_state]; + } + + YY_DO_BEFORE_ACTION; + +do_action: /* This label is used only to access EOF actions. */ + + switch ( yy_act ) + { /* beginning of action switch */ + case 0: /* must back up */ + /* undo the effects of YY_DO_BEFORE_ACTION */ + *yy_cp = (yy_hold_char); + yy_cp = (yy_last_accepting_cpos); + yy_current_state = (yy_last_accepting_state); + goto yy_find_action; + +case 1: +YY_RULE_SETUP +#line 66 "sel-lex.l" +{ return kw_TRUE; } + YY_BREAK +case 2: +YY_RULE_SETUP +#line 67 "sel-lex.l" +{ return kw_FALSE; } + YY_BREAK +case 3: +YY_RULE_SETUP +#line 68 "sel-lex.l" +{ return kw_AND; } + YY_BREAK +case 4: +YY_RULE_SETUP +#line 69 "sel-lex.l" +{ return kw_OR; } + YY_BREAK +case 5: +YY_RULE_SETUP +#line 70 "sel-lex.l" +{ return kw_IN; } + YY_BREAK +case 6: +YY_RULE_SETUP +#line 71 "sel-lex.l" +{ return kw_TAILMATCH; } + YY_BREAK +case 7: +YY_RULE_SETUP +#line 73 "sel-lex.l" +{ + yylval.string = strdup ((const char *)yytext); + return IDENTIFIER; + } + YY_BREAK +case 8: +YY_RULE_SETUP +#line 77 "sel-lex.l" +{ yylval.string = handle_string(); return STRING; } + YY_BREAK +case 9: +/* rule 9 can match eol */ +YY_RULE_SETUP +#line 78 "sel-lex.l" +{ ++lineno; } + YY_BREAK +case 10: +YY_RULE_SETUP +#line 79 "sel-lex.l" +{ return *yytext; } + YY_BREAK +case 11: +YY_RULE_SETUP +#line 80 "sel-lex.l" +; + YY_BREAK +case 12: +YY_RULE_SETUP +#line 81 "sel-lex.l" +ECHO; + YY_BREAK +#line 844 "heimdal/lib/hx509/sel-lex.c" +case YY_STATE_EOF(INITIAL): + yyterminate(); + + case YY_END_OF_BUFFER: + { + /* Amount of text matched not including the EOB char. */ + int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; + + /* Undo the effects of YY_DO_BEFORE_ACTION. */ + *yy_cp = (yy_hold_char); + YY_RESTORE_YY_MORE_OFFSET + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) + { + /* We're scanning a new file or input source. It's + * possible that this happened because the user + * just pointed yyin at a new source and called + * yylex(). If so, then we have to assure + * consistency between YY_CURRENT_BUFFER and our + * globals. Here is the right place to do so, because + * this is the first action (other than possibly a + * back-up) that will match for the new input source. + */ + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; + } + + /* Note that here we test for yy_c_buf_p "<=" to the position + * of the first EOB in the buffer, since yy_c_buf_p will + * already have been incremented past the NUL character + * (since all states make transitions on EOB to the + * end-of-buffer state). Contrast this with the test + * in input(). + */ + if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) + { /* This was really a NUL. */ + yy_state_type yy_next_state; + + (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( ); + + /* Okay, we're now positioned to make the NUL + * transition. We couldn't have + * yy_get_previous_state() go ahead and do it + * for us because it doesn't know how to deal + * with the possibility of jamming (and we don't + * want to build jamming into it because then it + * will run more slowly). + */ + + yy_next_state = yy_try_NUL_trans( yy_current_state ); + + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + + if ( yy_next_state ) + { + /* Consume the NUL. */ + yy_cp = ++(yy_c_buf_p); + yy_current_state = yy_next_state; + goto yy_match; + } + + else + { + yy_cp = (yy_c_buf_p); + goto yy_find_action; + } + } + + else switch ( yy_get_next_buffer( ) ) + { + case EOB_ACT_END_OF_FILE: + { + (yy_did_buffer_switch_on_eof) = 0; + + if ( yywrap( ) ) + { + /* Note: because we've taken care in + * yy_get_next_buffer() to have set up + * yytext, we can now set up + * yy_c_buf_p so that if some total + * hoser (like flex itself) wants to + * call the scanner after we return the + * YY_NULL, it'll still work - another + * YY_NULL will get returned. + */ + (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; + + yy_act = YY_STATE_EOF(YY_START); + goto do_action; + } + + else + { + if ( ! (yy_did_buffer_switch_on_eof) ) + YY_NEW_FILE; + } + break; + } + + case EOB_ACT_CONTINUE_SCAN: + (yy_c_buf_p) = + (yytext_ptr) + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( ); + + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + goto yy_match; + + case EOB_ACT_LAST_MATCH: + (yy_c_buf_p) = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; + + yy_current_state = yy_get_previous_state( ); + + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + goto yy_find_action; + } + break; + } + + default: + YY_FATAL_ERROR( + "fatal flex scanner internal error--no action found" ); + } /* end of action switch */ + } /* end of scanning one token */ +} /* end of yylex */ + +/* yy_get_next_buffer - try to read in a new buffer + * + * Returns a code representing an action: + * EOB_ACT_LAST_MATCH - + * EOB_ACT_CONTINUE_SCAN - continue scanning from current position + * EOB_ACT_END_OF_FILE - end of file + */ +static int yy_get_next_buffer (void) +{ + register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; + register char *source = (yytext_ptr); + register int number_to_move, i; + int ret_val; + + if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) + YY_FATAL_ERROR( + "fatal flex scanner internal error--end of buffer missed" ); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) + { /* Don't try to fill the buffer, so this is an EOF. */ + if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) + { + /* We matched a single character, the EOB, so + * treat this as a final EOF. + */ + return EOB_ACT_END_OF_FILE; + } + + else + { + /* We matched some text prior to the EOB, first + * process it. + */ + return EOB_ACT_LAST_MATCH; + } + } + + /* Try to read more data. */ + + /* First move last chars to start of buffer. */ + number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1; + + for ( i = 0; i < number_to_move; ++i ) + *(dest++) = *(source++); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) + /* don't do the read, it's not guaranteed to return an EOF, + * just force an EOF + */ + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; + + else + { + int num_to_read = + YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; + + while ( num_to_read <= 0 ) + { /* Not enough room in the buffer - grow it. */ + + /* just a shorter name for the current buffer */ + YY_BUFFER_STATE b = YY_CURRENT_BUFFER; + + int yy_c_buf_p_offset = + (int) ((yy_c_buf_p) - b->yy_ch_buf); + + if ( b->yy_is_our_buffer ) + { + int new_size = b->yy_buf_size * 2; + + if ( new_size <= 0 ) + b->yy_buf_size += b->yy_buf_size / 8; + else + b->yy_buf_size *= 2; + + b->yy_ch_buf = (char *) + /* Include room in for 2 EOB chars. */ + yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ); + } + else + /* Can't grow it, we don't own it. */ + b->yy_ch_buf = 0; + + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( + "fatal error - scanner input buffer overflow" ); + + (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; + + num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - + number_to_move - 1; + + } + + if ( num_to_read > YY_READ_BUF_SIZE ) + num_to_read = YY_READ_BUF_SIZE; + + /* Read in more data. */ + YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), + (yy_n_chars), (size_t) num_to_read ); + + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + if ( (yy_n_chars) == 0 ) + { + if ( number_to_move == YY_MORE_ADJ ) + { + ret_val = EOB_ACT_END_OF_FILE; + yyrestart(yyin ); + } + + else + { + ret_val = EOB_ACT_LAST_MATCH; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = + YY_BUFFER_EOF_PENDING; + } + } + + else + ret_val = EOB_ACT_CONTINUE_SCAN; + + if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { + /* Extend the array by 50%, plus the number we really need. */ + yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ); + if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); + } + + (yy_n_chars) += number_to_move; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; + + (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; + + return ret_val; +} + +/* yy_get_previous_state - get the state just before the EOB char was reached */ + + static yy_state_type yy_get_previous_state (void) +{ + register yy_state_type yy_current_state; + register char *yy_cp; + + yy_current_state = (yy_start); + + for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) + { + register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 36 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + } + + return yy_current_state; +} + +/* yy_try_NUL_trans - try to make a transition on the NUL character + * + * synopsis + * next_state = yy_try_NUL_trans( current_state ); + */ + static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state ) +{ + register int yy_is_jam; + register char *yy_cp = (yy_c_buf_p); + + register YY_CHAR yy_c = 1; + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 36 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + yy_is_jam = (yy_current_state == 35); + + return yy_is_jam ? 0 : yy_current_state; +} + + static void yyunput (int c, register char * yy_bp ) +{ + register char *yy_cp; + + yy_cp = (yy_c_buf_p); + + /* undo effects of setting up yytext */ + *yy_cp = (yy_hold_char); + + if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) + { /* need to shift things up to make room */ + /* +2 for EOB chars. */ + register int number_to_move = (yy_n_chars) + 2; + register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ + YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; + register char *source = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; + + while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) + *--dest = *--source; + + yy_cp += (int) (dest - source); + yy_bp += (int) (dest - source); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size; + + if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) + YY_FATAL_ERROR( "flex scanner push-back overflow" ); + } + + *--yy_cp = (char) c; + + (yytext_ptr) = yy_bp; + (yy_hold_char) = *yy_cp; + (yy_c_buf_p) = yy_cp; +} + +#ifndef YY_NO_INPUT +#ifdef __cplusplus + static int yyinput (void) +#else + static int input (void) +#endif + +{ + int c; + + *(yy_c_buf_p) = (yy_hold_char); + + if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) + { + /* yy_c_buf_p now points to the character we want to return. + * If this occurs *before* the EOB characters, then it's a + * valid NUL; if not, then we've hit the end of the buffer. + */ + if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) + /* This was really a NUL. */ + *(yy_c_buf_p) = '\0'; + + else + { /* need more input */ + int offset = (yy_c_buf_p) - (yytext_ptr); + ++(yy_c_buf_p); + + switch ( yy_get_next_buffer( ) ) + { + case EOB_ACT_LAST_MATCH: + /* This happens because yy_g_n_b() + * sees that we've accumulated a + * token and flags that we need to + * try matching the token before + * proceeding. But for input(), + * there's no matching to consider. + * So convert the EOB_ACT_LAST_MATCH + * to EOB_ACT_END_OF_FILE. + */ + + /* Reset buffer status. */ + yyrestart(yyin ); + + /*FALLTHROUGH*/ + + case EOB_ACT_END_OF_FILE: + { + if ( yywrap( ) ) + return EOF; + + if ( ! (yy_did_buffer_switch_on_eof) ) + YY_NEW_FILE; +#ifdef __cplusplus + return yyinput(); +#else + return input(); +#endif + } + + case EOB_ACT_CONTINUE_SCAN: + (yy_c_buf_p) = (yytext_ptr) + offset; + break; + } + } + } + + c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ + *(yy_c_buf_p) = '\0'; /* preserve yytext */ + (yy_hold_char) = *++(yy_c_buf_p); + + return c; +} +#endif /* ifndef YY_NO_INPUT */ + +/** Immediately switch to a different input stream. + * @param input_file A readable stream. + * + * @note This function does not reset the start condition to @c INITIAL . + */ + void yyrestart (FILE * input_file ) +{ + + if ( ! YY_CURRENT_BUFFER ){ + yyensure_buffer_stack (); + YY_CURRENT_BUFFER_LVALUE = + yy_create_buffer(yyin,YY_BUF_SIZE ); + } + + yy_init_buffer(YY_CURRENT_BUFFER,input_file ); + yy_load_buffer_state( ); +} + +/** Switch to a different input buffer. + * @param new_buffer The new input buffer. + * + */ + void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ) +{ + + /* TODO. We should be able to replace this entire function body + * with + * yypop_buffer_state(); + * yypush_buffer_state(new_buffer); + */ + yyensure_buffer_stack (); + if ( YY_CURRENT_BUFFER == new_buffer ) + return; + + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + YY_CURRENT_BUFFER_LVALUE = new_buffer; + yy_load_buffer_state( ); + + /* We don't actually know whether we did this switch during + * EOF (yywrap()) processing, but the only time this flag + * is looked at is after yywrap() is called, so it's safe + * to go ahead and always set it. + */ + (yy_did_buffer_switch_on_eof) = 1; +} + +static void yy_load_buffer_state (void) +{ + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; + yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; + (yy_hold_char) = *(yy_c_buf_p); +} + +/** Allocate and initialize an input buffer state. + * @param file A readable stream. + * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. + * + * @return the allocated buffer state. + */ + YY_BUFFER_STATE yy_create_buffer (FILE * file, int size ) +{ + YY_BUFFER_STATE b; + + b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_buf_size = size; + + /* yy_ch_buf has to be 2 characters longer than the size given because + * we need to put in 2 end-of-buffer characters. + */ + b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2 ); + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_is_our_buffer = 1; + + yy_init_buffer(b,file ); + + return b; +} + +/** Destroy the buffer. + * @param b a buffer created with yy_create_buffer() + * + */ + void yy_delete_buffer (YY_BUFFER_STATE b ) +{ + + if ( ! b ) + return; + + if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ + YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; + + if ( b->yy_is_our_buffer ) + yyfree((void *) b->yy_ch_buf ); + + yyfree((void *) b ); +} + +#ifndef __cplusplus +extern int isatty (int ); +#endif /* __cplusplus */ + +/* Initializes or reinitializes a buffer. + * This function is sometimes called more than once on the same buffer, + * such as during a yyrestart() or at EOF. + */ + static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file ) + +{ + int oerrno = errno; + + yy_flush_buffer(b ); + + b->yy_input_file = file; + b->yy_fill_buffer = 1; + + /* If b is the current buffer, then yy_init_buffer was _probably_ + * called from yyrestart() or through yy_get_next_buffer. + * In that case, we don't want to reset the lineno or column. + */ + if (b != YY_CURRENT_BUFFER){ + b->yy_bs_lineno = 1; + b->yy_bs_column = 0; + } + + b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; + + errno = oerrno; +} + +/** Discard all buffered characters. On the next scan, YY_INPUT will be called. + * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. + * + */ + void yy_flush_buffer (YY_BUFFER_STATE b ) +{ + if ( ! b ) + return; + + b->yy_n_chars = 0; + + /* We always need two end-of-buffer characters. The first causes + * a transition to the end-of-buffer state. The second causes + * a jam in that state. + */ + b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; + b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; + + b->yy_buf_pos = &b->yy_ch_buf[0]; + + b->yy_at_bol = 1; + b->yy_buffer_status = YY_BUFFER_NEW; + + if ( b == YY_CURRENT_BUFFER ) + yy_load_buffer_state( ); +} + +/** Pushes the new state onto the stack. The new state becomes + * the current state. This function will allocate the stack + * if necessary. + * @param new_buffer The new state. + * + */ +void yypush_buffer_state (YY_BUFFER_STATE new_buffer ) +{ + if (new_buffer == NULL) + return; + + yyensure_buffer_stack(); + + /* This block is copied from yy_switch_to_buffer. */ + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + /* Only push if top exists. Otherwise, replace top. */ + if (YY_CURRENT_BUFFER) + (yy_buffer_stack_top)++; + YY_CURRENT_BUFFER_LVALUE = new_buffer; + + /* copied from yy_switch_to_buffer. */ + yy_load_buffer_state( ); + (yy_did_buffer_switch_on_eof) = 1; +} + +/** Removes and deletes the top of the stack, if present. + * The next element becomes the new top. + * + */ +void yypop_buffer_state (void) +{ + if (!YY_CURRENT_BUFFER) + return; + + yy_delete_buffer(YY_CURRENT_BUFFER ); + YY_CURRENT_BUFFER_LVALUE = NULL; + if ((yy_buffer_stack_top) > 0) + --(yy_buffer_stack_top); + + if (YY_CURRENT_BUFFER) { + yy_load_buffer_state( ); + (yy_did_buffer_switch_on_eof) = 1; + } +} + +/* Allocates the stack if it does not exist. + * Guarantees space for at least one push. + */ +static void yyensure_buffer_stack (void) +{ + int num_to_alloc; + + if (!(yy_buffer_stack)) { + + /* First allocation is just for 2 elements, since we don't know if this + * scanner will even need a stack. We use 2 instead of 1 to avoid an + * immediate realloc on the next call. + */ + num_to_alloc = 1; + (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc + (num_to_alloc * sizeof(struct yy_buffer_state*) + ); + if ( ! (yy_buffer_stack) ) + YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); + + memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); + + (yy_buffer_stack_max) = num_to_alloc; + (yy_buffer_stack_top) = 0; + return; + } + + if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ + + /* Increase the buffer to prepare for a possible push. */ + int grow_size = 8 /* arbitrary grow size */; + + num_to_alloc = (yy_buffer_stack_max) + grow_size; + (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc + ((yy_buffer_stack), + num_to_alloc * sizeof(struct yy_buffer_state*) + ); + if ( ! (yy_buffer_stack) ) + YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); + + /* zero only the new slots.*/ + memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); + (yy_buffer_stack_max) = num_to_alloc; + } +} + +/** Setup the input buffer state to scan directly from a user-specified character buffer. + * @param base the character buffer + * @param size the size in bytes of the character buffer + * + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size ) +{ + YY_BUFFER_STATE b; + + if ( size < 2 || + base[size-2] != YY_END_OF_BUFFER_CHAR || + base[size-1] != YY_END_OF_BUFFER_CHAR ) + /* They forgot to leave room for the EOB's. */ + return 0; + + b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); + + b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ + b->yy_buf_pos = b->yy_ch_buf = base; + b->yy_is_our_buffer = 0; + b->yy_input_file = 0; + b->yy_n_chars = b->yy_buf_size; + b->yy_is_interactive = 0; + b->yy_at_bol = 1; + b->yy_fill_buffer = 0; + b->yy_buffer_status = YY_BUFFER_NEW; + + yy_switch_to_buffer(b ); + + return b; +} + +/** Setup the input buffer state to scan a string. The next call to yylex() will + * scan from a @e copy of @a str. + * @param yystr a NUL-terminated string to scan + * + * @return the newly allocated buffer state object. + * @note If you want to scan bytes that may contain NUL values, then use + * yy_scan_bytes() instead. + */ +YY_BUFFER_STATE yy_scan_string (yyconst char * yystr ) +{ + + return yy_scan_bytes(yystr,strlen(yystr) ); +} + +/** Setup the input buffer state to scan the given bytes. The next call to yylex() will + * scan from a @e copy of @a bytes. + * @param bytes the byte buffer to scan + * @param len the number of bytes in the buffer pointed to by @a bytes. + * + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, int _yybytes_len ) +{ + YY_BUFFER_STATE b; + char *buf; + yy_size_t n; + int i; + + /* Get memory for full buffer, including space for trailing EOB's. */ + n = _yybytes_len + 2; + buf = (char *) yyalloc(n ); + if ( ! buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); + + for ( i = 0; i < _yybytes_len; ++i ) + buf[i] = yybytes[i]; + + buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; + + b = yy_scan_buffer(buf,n ); + if ( ! b ) + YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); + + /* It's okay to grow etc. this buffer, and we should throw it + * away when we're done. + */ + b->yy_is_our_buffer = 1; + + return b; +} + +#ifndef YY_EXIT_FAILURE +#define YY_EXIT_FAILURE 2 +#endif + +static void yy_fatal_error (yyconst char* msg ) +{ + (void) fprintf( stderr, "%s\n", msg ); + exit( YY_EXIT_FAILURE ); +} + +/* Redefine yyless() so it works in section 3 code. */ + +#undef yyless +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + yytext[yyleng] = (yy_hold_char); \ + (yy_c_buf_p) = yytext + yyless_macro_arg; \ + (yy_hold_char) = *(yy_c_buf_p); \ + *(yy_c_buf_p) = '\0'; \ + yyleng = yyless_macro_arg; \ + } \ + while ( 0 ) + +/* Accessor methods (get/set functions) to struct members. */ + +/** Get the current line number. + * + */ +int yyget_lineno (void) +{ + + return yylineno; +} + +/** Get the input stream. + * + */ +FILE *yyget_in (void) +{ + return yyin; +} + +/** Get the output stream. + * + */ +FILE *yyget_out (void) +{ + return yyout; +} + +/** Get the length of the current token. + * + */ +int yyget_leng (void) +{ + return yyleng; +} + +/** Get the current token. + * + */ + +char *yyget_text (void) +{ + return yytext; +} + +/** Set the current line number. + * @param line_number + * + */ +void yyset_lineno (int line_number ) +{ + + yylineno = line_number; +} + +/** Set the input stream. This does not discard the current + * input buffer. + * @param in_str A readable stream. + * + * @see yy_switch_to_buffer + */ +void yyset_in (FILE * in_str ) +{ + yyin = in_str ; +} + +void yyset_out (FILE * out_str ) +{ + yyout = out_str ; +} + +int yyget_debug (void) +{ + return yy_flex_debug; +} + +void yyset_debug (int bdebug ) +{ + yy_flex_debug = bdebug ; +} + +static int yy_init_globals (void) +{ + /* Initialization is the same as for the non-reentrant scanner. + * This function is called from yylex_destroy(), so don't allocate here. + */ + + (yy_buffer_stack) = 0; + (yy_buffer_stack_top) = 0; + (yy_buffer_stack_max) = 0; + (yy_c_buf_p) = (char *) 0; + (yy_init) = 0; + (yy_start) = 0; + +/* Defined in main.c */ +#ifdef YY_STDINIT + yyin = stdin; + yyout = stdout; +#else + yyin = (FILE *) 0; + yyout = (FILE *) 0; +#endif + + /* For future reference: Set errno on error, since we are called by + * yylex_init() + */ + return 0; +} + +/* yylex_destroy is for both reentrant and non-reentrant scanners. */ +int yylex_destroy (void) +{ + + /* Pop the buffer stack, destroying each element. */ + while(YY_CURRENT_BUFFER){ + yy_delete_buffer(YY_CURRENT_BUFFER ); + YY_CURRENT_BUFFER_LVALUE = NULL; + yypop_buffer_state(); + } + + /* Destroy the stack itself. */ + yyfree((yy_buffer_stack) ); + (yy_buffer_stack) = NULL; + + /* Reset the globals. This is important in a non-reentrant scanner so the next time + * yylex() is called, initialization will occur. */ + yy_init_globals( ); + + return 0; +} + +/* + * Internal utility routines. + */ + +#ifndef yytext_ptr +static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) +{ + register int i; + for ( i = 0; i < n; ++i ) + s1[i] = s2[i]; +} +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (yyconst char * s ) +{ + register int n; + for ( n = 0; s[n]; ++n ) + ; + + return n; +} +#endif + +void *yyalloc (yy_size_t size ) +{ + return (void *) malloc( size ); +} + +void *yyrealloc (void * ptr, yy_size_t size ) +{ + /* The cast to (char *) in the following accommodates both + * implementations that use char* generic pointers, and those + * that use void* generic pointers. It works with the latter + * because both ANSI C and C++ allow castless assignment from + * any pointer type to void*, and deal with argument conversions + * as though doing an assignment. + */ + return (void *) realloc( (char *) ptr, size ); +} + +void yyfree (void * ptr ) +{ + free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ +} + +#define YYTABLES_NAME "yytables" + +#line 81 "sel-lex.l" + + + +static char * +handle_string(void) +{ + char x[1024]; + int i = 0; + int c; + int quote = 0; + while((c = input()) != EOF){ + if(quote) { + x[i++] = '\\'; + x[i++] = c; + quote = 0; + continue; + } + if(c == '\n'){ + _hx509_sel_yyerror("unterminated string"); + lineno++; + break; + } + if(c == '\\'){ + quote++; + continue; + } + if(c == '\"') + break; + x[i++] = c; + } + x[i] = '\0'; + return strdup(x); +} + +int +yywrap () +{ + return 1; +} + +static int +lex_input(char *buf, int max_size) +{ + int n; + + n = _hx509_expr_input.length - _hx509_expr_input.offset; + if (max_size < n) + n = max_size; + if (n <= 0) + return YY_NULL; + + memcpy(buf, _hx509_expr_input.buf + _hx509_expr_input.offset, n); + _hx509_expr_input.offset += n; + + return n; +} + diff --git a/source4/heimdal/lib/hx509/sel-lex.l b/source4/heimdal/lib/hx509/sel-lex.l new file mode 100644 index 0000000000..53944897f9 --- /dev/null +++ b/source4/heimdal/lib/hx509/sel-lex.l @@ -0,0 +1,135 @@ +%{ +/* + * Copyright (c) 2004, 2008 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* $Id$ */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#undef ECHO + +#include <stdio.h> +#include <string.h> +#include <stdarg.h> +#include <stdlib.h> +#include "sel.h" +#include "sel-gram.h" +unsigned lineno = 1; + +static char * handle_string(void); +static int lex_input(char *, int); + +struct hx_expr_input _hx509_expr_input; + +#define YY_NO_UNPUT 1 + +#undef YY_INPUT +#define YY_INPUT(buf,res,maxsize) (res = lex_input(buf, maxsize)) + +#undef ECHO + +%} +%% + +TRUE { return kw_TRUE; } +FALSE { return kw_FALSE; } +AND { return kw_AND; } +OR { return kw_OR; } +IN { return kw_IN; } +TAILMATCH { return kw_TAILMATCH; } + +[A-Za-z][-A-Za-z0-9_]* { + yylval.string = strdup ((const char *)yytext); + return IDENTIFIER; + } +"\"" { yylval.string = handle_string(); return STRING; } +\n { ++lineno; } +[,.!={}()%] { return *yytext; } +[ \t] ; +%% + +static char * +handle_string(void) +{ + char x[1024]; + int i = 0; + int c; + int quote = 0; + while((c = input()) != EOF){ + if(quote) { + x[i++] = '\\'; + x[i++] = c; + quote = 0; + continue; + } + if(c == '\n'){ + _hx509_sel_yyerror("unterminated string"); + lineno++; + break; + } + if(c == '\\'){ + quote++; + continue; + } + if(c == '\"') + break; + x[i++] = c; + } + x[i] = '\0'; + return strdup(x); +} + +int +yywrap () +{ + return 1; +} + +static int +lex_input(char *buf, int max_size) +{ + int n; + + n = _hx509_expr_input.length - _hx509_expr_input.offset; + if (max_size < n) + n = max_size; + if (n <= 0) + return YY_NULL; + + memcpy(buf, _hx509_expr_input.buf + _hx509_expr_input.offset, n); + _hx509_expr_input.offset += n; + + return n; +} diff --git a/source4/heimdal/lib/hx509/sel.c b/source4/heimdal/lib/hx509/sel.c new file mode 100644 index 0000000000..0e68f8ba5d --- /dev/null +++ b/source4/heimdal/lib/hx509/sel.c @@ -0,0 +1,232 @@ +/* + * Copyright (c) 2008 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 "hx_locl.h" + +struct hx_expr * +_hx509_make_expr(enum hx_expr_op op, void *arg1, void *arg2) +{ + struct hx_expr *expr; + + expr = malloc(sizeof(*expr)); + if (expr == NULL) + return NULL; + expr->op = op; + expr->arg1 = arg1; + expr->arg2 = arg2; + + return expr; +} + +static const char * +eval_word(hx509_context context, hx509_env env, struct hx_expr *word) +{ + switch (word->op) { + case expr_STRING: + return word->arg1; + case expr_VAR: + if (word->arg2 == NULL) + return hx509_env_find(context, env, word->arg1); + + env = hx509_env_find_binding(context, env, word->arg1); + if (env == NULL) + return NULL; + + return eval_word(context, env, word->arg2); + default: + return NULL; + } +} + +static hx509_env +find_variable(hx509_context context, hx509_env env, struct hx_expr *word) +{ + assert(word->op == expr_VAR); + + if (word->arg2 == NULL) + return hx509_env_find_binding(context, env, word->arg1); + + env = hx509_env_find_binding(context, env, word->arg1); + if (env == NULL) + return NULL; + return find_variable(context, env, word->arg2); +} + +static int +eval_comp(hx509_context context, hx509_env env, struct hx_expr *expr) +{ + switch (expr->op) { + case comp_NE: + case comp_EQ: + case comp_TAILEQ: { + const char *s1, *s2; + int ret; + + s1 = eval_word(context, env, expr->arg1); + s2 = eval_word(context, env, expr->arg2); + + if (s1 == NULL || s2 == NULL) + return FALSE; + + if (expr->op == comp_TAILEQ) { + size_t len1 = strlen(s1); + size_t len2 = strlen(s2); + + if (len1 < len2) + return 0; + ret = strcmp(s1 + (len1 - len2), s2) == 0; + } else { + ret = strcmp(s1, s2) == 0; + if (expr->op == comp_NE) + ret = !ret; + } + return ret; + } + case comp_IN: { + struct hx_expr *subexpr; + const char *w, *s1; + + w = eval_word(context, env, expr->arg1); + + subexpr = expr->arg2; + + if (subexpr->op == expr_WORDS) { + while (subexpr) { + s1 = eval_word(context, env, subexpr->arg1); + if (strcmp(w, s1) == 0) + return TRUE; + subexpr = subexpr->arg2; + } + } else if (subexpr->op == expr_VAR) { + hx509_env subenv; + + subenv = find_variable(context, env, subexpr); + if (subenv == NULL) + return FALSE; + + while (subenv) { + if (subenv->type != env_string) + continue; + if (strcmp(w, subenv->name) == 0) + return TRUE; + if (strcmp(w, subenv->u.string) == 0) + return TRUE; + subenv = subenv->next; + } + + } else + _hx509_abort("hx509 eval IN unknown op: %d", (int)subexpr->op); + + return FALSE; + } + default: + _hx509_abort("hx509 eval expr with unknown op: %d", (int)expr->op); + } + return FALSE; +} + +int +_hx509_expr_eval(hx509_context context, hx509_env env, struct hx_expr *expr) +{ + switch (expr->op) { + case op_TRUE: + return 1; + case op_FALSE: + return 0; + case op_NOT: + return ! _hx509_expr_eval(context, env, expr->arg1); + case op_AND: + return _hx509_expr_eval(context, env, expr->arg1) && + _hx509_expr_eval(context, env, expr->arg2); + case op_OR: + return _hx509_expr_eval(context, env, expr->arg1) || + _hx509_expr_eval(context, env, expr->arg2); + case op_COMP: + return eval_comp(context, env, expr->arg1); + default: + _hx509_abort("hx509 eval expr with unknown op: %d", (int)expr->op); + } +} + +void +_hx509_expr_free(struct hx_expr *expr) +{ + switch (expr->op) { + case expr_STRING: + case expr_NUMBER: + free(expr->arg1); + break; + case expr_WORDS: + case expr_FUNCTION: + case expr_VAR: + free(expr->arg1); + if (expr->arg2) + _hx509_expr_free(expr->arg2); + break; + default: + if (expr->arg1) + _hx509_expr_free(expr->arg1); + if (expr->arg2) + _hx509_expr_free(expr->arg2); + break; + } + free(expr); +} + +struct hx_expr * +_hx509_expr_parse(const char *buf) +{ + _hx509_expr_input.buf = buf; + _hx509_expr_input.length = strlen(buf); + _hx509_expr_input.offset = 0; + _hx509_expr_input.expr = NULL; + + if (_hx509_expr_input.error) { + free(_hx509_expr_input.error); + _hx509_expr_input.error = NULL; + } + + yyparse(); + + return _hx509_expr_input.expr; +} + +void +_hx509_sel_yyerror (char *s) +{ + if (_hx509_expr_input.error) + free(_hx509_expr_input.error); + + _hx509_expr_input.error = strdup(s); +} + diff --git a/source4/heimdal/lib/hx509/sel.h b/source4/heimdal/lib/hx509/sel.h new file mode 100644 index 0000000000..ce6c3636bc --- /dev/null +++ b/source4/heimdal/lib/hx509/sel.h @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2008 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. + */ + +enum hx_expr_op { + op_TRUE, + op_FALSE, + op_NOT, + op_AND, + op_OR, + op_COMP, + + comp_EQ, + comp_NE, + comp_IN, + comp_TAILEQ, + + expr_NUMBER, + expr_STRING, + expr_FUNCTION, + expr_VAR, + expr_WORDS +}; + +struct hx_expr { + enum hx_expr_op op; + void *arg1; + void *arg2; +}; + +struct hx_expr_input { + const char *buf; + size_t length; + size_t offset; + struct hx_expr *expr; + char *error; +}; + +extern struct hx_expr_input _hx509_expr_input; + +#define yyparse _hx509_sel_yyparse +#define yylex _hx509_sel_yylex +#define yyerror _hx509_sel_yyerror +#define yylval _hx509_sel_yylval +#define yychar _hx509_sel_yychar +#define yydebug _hx509_sel_yydebug +#define yynerrs _hx509_sel_yynerrs +#define yywrap _hx509_sel_yywrap + +int _hx509_sel_yyparse(void); +int _hx509_sel_yylex(void); +void _hx509_sel_yyerror(char *); + diff --git a/source4/heimdal/lib/hx509/test_name.c b/source4/heimdal/lib/hx509/test_name.c index 2c6dd516cb..6dcf542d01 100644 --- a/source4/heimdal/lib/hx509/test_name.c +++ b/source4/heimdal/lib/hx509/test_name.c @@ -32,7 +32,7 @@ */ #include "hx_locl.h" -RCSID("$Id: test_name.c 19882 2007-01-13 01:02:57Z lha $"); +RCSID("$Id: test_name.c 22677 2008-03-13 17:35:49Z lha $"); static int test_name(hx509_context context, const char *name) @@ -72,13 +72,12 @@ test_name_fail(hx509_context context, const char *name) static int test_expand(hx509_context context, const char *name, const char *expected) { - hx509_env env; + hx509_env env = NULL; hx509_name n; char *s; int ret; - hx509_env_init(context, &env); - hx509_env_add(context, env, "uid", "lha"); + hx509_env_add(context, &env, "uid", "lha"); ret = hx509_parse_name(context, name, &n); if (ret) diff --git a/source4/heimdal/lib/krb5/acache.c b/source4/heimdal/lib/krb5/acache.c index 775239cf6d..8dd8687005 100644 --- a/source4/heimdal/lib/krb5/acache.c +++ b/source4/heimdal/lib/krb5/acache.c @@ -37,7 +37,7 @@ #include <dlfcn.h> #endif -RCSID("$Id: acache.c 22669 2008-03-09 23:39:25Z lha $"); +RCSID("$Id: acache.c 23316 2008-06-23 04:32:32Z lha $"); /* XXX should we fetch these for each open ? */ static HEIMDAL_MUTEX acc_mutex = HEIMDAL_MUTEX_INITIALIZER; @@ -68,6 +68,7 @@ static const struct { { ccIteratorEnd, KRB5_CC_END }, { ccErrNoMem, KRB5_CC_NOMEM }, { ccErrServerUnavailable, KRB5_CC_NOSUPP }, + { ccErrInvalidCCache, KRB5_CC_BADNAME }, { ccNoError, 0 } }; @@ -114,15 +115,17 @@ init_ccapi(krb5_context context) cc_handle = dlopen(lib, RTLD_LAZY); if (cc_handle == NULL) { HEIMDAL_MUTEX_unlock(&acc_mutex); - krb5_set_error_string(context, "Failed to load %s", lib); + krb5_set_error_message(context, KRB5_CC_NOSUPP, + "Failed to load %s", lib); return KRB5_CC_NOSUPP; } init_func = (cc_initialize_func)dlsym(cc_handle, "cc_initialize"); HEIMDAL_MUTEX_unlock(&acc_mutex); if (init_func == NULL) { - krb5_set_error_string(context, "Failed to find cc_initialize" - "in %s: %s", lib, dlerror()); + krb5_set_error_message(context, KRB5_CC_NOSUPP, + "Failed to find cc_initialize" + "in %s: %s", lib, dlerror()); dlclose(cc_handle); return KRB5_CC_NOSUPP; } @@ -130,7 +133,7 @@ init_ccapi(krb5_context context) return 0; #else HEIMDAL_MUTEX_unlock(&acc_mutex); - krb5_set_error_string(context, "no support for shared object"); + krb5_set_error_message(context, KRB5_CC_NOSUPP, "no support for shared object"); return KRB5_CC_NOSUPP; #endif } @@ -141,7 +144,7 @@ make_cred_from_ccred(krb5_context context, krb5_creds *cred) { krb5_error_code ret; - int i; + unsigned int i; memset(cred, 0, sizeof(*cred)); @@ -255,7 +258,7 @@ make_cred_from_ccred(krb5_context context, nomem: ret = ENOMEM; - krb5_set_error_string(context, "malloc - out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); fail: krb5_free_cred_contents(context, cred); @@ -584,8 +587,10 @@ acc_close(krb5_context context, free(a->cache_name); a->cache_name = NULL; } - (*a->context->func->release)(a->context); - a->context = NULL; + if (a->context) { + (*a->context->func->release)(a->context); + a->context = NULL; + } krb5_data_free(&id->data); return 0; } @@ -620,7 +625,8 @@ acc_store_cred(krb5_context context, cc_int32 error; if (a->ccache == NULL) { - krb5_set_error_string(context, "No API credential found"); + krb5_set_error_message(context, KRB5_CC_NOTFOUND, + "No API credential found"); return KRB5_CC_NOTFOUND; } @@ -653,7 +659,8 @@ acc_get_principal(krb5_context context, cc_string_t name; if (a->ccache == NULL) { - krb5_set_error_string(context, "No API credential found"); + krb5_set_error_message(context, KRB5_CC_NOTFOUND, + "No API credential found"); return KRB5_CC_NOTFOUND; } @@ -679,7 +686,8 @@ acc_get_first (krb5_context context, int32_t error; if (a->ccache == NULL) { - krb5_set_error_string(context, "No API credential found"); + krb5_set_error_message(context, KRB5_CC_NOTFOUND, + "No API credential found"); return KRB5_CC_NOTFOUND; } @@ -744,7 +752,8 @@ acc_remove_cred(krb5_context context, char *client, *server; if (a->ccache == NULL) { - krb5_set_error_string(context, "No API credential found"); + krb5_set_error_message(context, KRB5_CC_NOTFOUND, + "No API credential found"); return KRB5_CC_NOTFOUND; } @@ -796,8 +805,8 @@ acc_remove_cred(krb5_context context, (*iter->func->release)(iter); if (ret) - krb5_set_error_string(context, "Can't find credential %s in cache", - server); + krb5_set_error_message(context, ret, + "Can't find credential %s in cache", server); free(server); free(client); @@ -812,7 +821,7 @@ acc_set_flags(krb5_context context, return 0; } -static krb5_error_code +static int acc_get_version(krb5_context context, krb5_ccache id) { @@ -837,7 +846,7 @@ acc_get_cache_first(krb5_context context, krb5_cc_cursor *cursor) iter = calloc(1, sizeof(*iter)); if (iter == NULL) { - krb5_set_error_string(context, "malloc - out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } @@ -940,7 +949,7 @@ acc_move(krb5_context context, krb5_ccache from, krb5_ccache to) } static krb5_error_code -acc_default_name(krb5_context context, char **str) +acc_get_default_name(krb5_context context, char **str) { krb5_error_code ret; cc_context_t cc; @@ -966,12 +975,30 @@ acc_default_name(krb5_context context, char **str) (*cc->func->release)(cc); if (*str == NULL) { - krb5_set_error_string(context, "out of memory"); + krb5_set_error_message(context, ENOMEM, "out of memory"); return ENOMEM; } return 0; } +static krb5_error_code +acc_set_default(krb5_context context, krb5_ccache id) +{ + krb5_acc *a = ACACHE(id); + cc_int32 error; + + if (a->ccache == NULL) { + krb5_set_error_message(context, KRB5_CC_NOTFOUND, + "No API credential found"); + return KRB5_CC_NOTFOUND; + } + + error = (*a->ccache->func->set_default)(a->ccache); + if (error) + return translate_cc_error(context, error); + + return 0; +} /** * Variable containing the API based credential cache implemention. @@ -979,7 +1006,8 @@ acc_default_name(krb5_context context, char **str) * @ingroup krb5_ccache */ -const krb5_cc_ops krb5_acc_ops = { +KRB5_LIB_VARIABLE const krb5_cc_ops krb5_acc_ops = { + KRB5_CC_OPS_VERSION, "API", acc_get_name, acc_resolve, @@ -1000,5 +1028,6 @@ const krb5_cc_ops krb5_acc_ops = { acc_get_cache_next, acc_end_cache_get, acc_move, - acc_default_name + acc_get_default_name, + acc_set_default }; diff --git a/source4/heimdal/lib/krb5/addr_families.c b/source4/heimdal/lib/krb5/addr_families.c index f364f5974d..40abd874cc 100644 --- a/source4/heimdal/lib/krb5/addr_families.c +++ b/source4/heimdal/lib/krb5/addr_families.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: addr_families.c 22039 2007-11-10 11:47:35Z lha $"); +RCSID("$Id: addr_families.c 23316 2008-06-23 04:32:32Z lha $"); struct addr_operations { int af; @@ -202,7 +202,8 @@ ipv4_mask_boundary(krb5_context context, const krb5_address *inaddr, uint32_t l, h, m = 0xffffffff; if (len > 32) { - krb5_set_error_string(context, "IPv4 prefix too large (%ld)", len); + krb5_set_error_message(context, KRB5_PROG_ATYPE_NOSUPP, + "IPv4 prefix too large (%ld)", len); return KRB5_PROG_ATYPE_NOSUPP; } m = m << (32 - len); @@ -395,12 +396,14 @@ ipv6_mask_boundary(krb5_context context, const krb5_address *inaddr, int i, sub_len; if (len > 128) { - krb5_set_error_string(context, "IPv6 prefix too large (%ld)", len); + krb5_set_error_message(context, KRB5_PROG_ATYPE_NOSUPP, + "IPv6 prefix too large (%ld)", len); return KRB5_PROG_ATYPE_NOSUPP; } if (inaddr->address.length != sizeof(addr)) { - krb5_set_error_string(context, "IPv6 addr bad length"); + krb5_set_error_message(context, KRB5_PROG_ATYPE_NOSUPP, + "IPv6 addr bad length"); return KRB5_PROG_ATYPE_NOSUPP; } @@ -786,8 +789,9 @@ krb5_sockaddr2address (krb5_context context, { struct addr_operations *a = find_af(sa->sa_family); if (a == NULL) { - krb5_set_error_string (context, "Address family %d not supported", - sa->sa_family); + krb5_set_error_message (context, KRB5_PROG_ATYPE_NOSUPP, + "Address family %d not supported", + sa->sa_family); return KRB5_PROG_ATYPE_NOSUPP; } return (*a->sockaddr2addr)(sa, addr); @@ -813,8 +817,9 @@ krb5_sockaddr2port (krb5_context context, { struct addr_operations *a = find_af(sa->sa_family); if (a == NULL) { - krb5_set_error_string (context, "Address family %d not supported", - sa->sa_family); + krb5_set_error_message (context, KRB5_PROG_ATYPE_NOSUPP, + "Address family %d not supported", + sa->sa_family); return KRB5_PROG_ATYPE_NOSUPP; } return (*a->sockaddr2port)(sa, port); @@ -851,14 +856,16 @@ krb5_addr2sockaddr (krb5_context context, struct addr_operations *a = find_atype(addr->addr_type); if (a == NULL) { - krb5_set_error_string (context, "Address type %d not supported", - addr->addr_type); + krb5_set_error_message (context, KRB5_PROG_ATYPE_NOSUPP, + "Address type %d not supported", + addr->addr_type); return KRB5_PROG_ATYPE_NOSUPP; } if (a->addr2sockaddr == NULL) { - krb5_set_error_string (context, - "Can't convert address type %d to sockaddr", - addr->addr_type); + krb5_set_error_message (context, + KRB5_PROG_ATYPE_NOSUPP, + "Can't convert address type %d to sockaddr", + addr->addr_type); return KRB5_PROG_ATYPE_NOSUPP; } (*a->addr2sockaddr)(addr, sa, sa_size, port); @@ -935,7 +942,8 @@ krb5_h_addr2sockaddr (krb5_context context, { struct addr_operations *a = find_af(af); if (a == NULL) { - krb5_set_error_string (context, "Address family %d not supported", af); + krb5_set_error_message (context, KRB5_PROG_ATYPE_NOSUPP, + "Address family %d not supported", af); return KRB5_PROG_ATYPE_NOSUPP; } (*a->h_addr2sockaddr)(addr, sa, sa_size, port); @@ -963,7 +971,8 @@ krb5_h_addr2addr (krb5_context context, { struct addr_operations *a = find_af(af); if (a == NULL) { - krb5_set_error_string (context, "Address family %d not supported", af); + krb5_set_error_message (context, KRB5_PROG_ATYPE_NOSUPP, + "Address family %d not supported", af); return KRB5_PROG_ATYPE_NOSUPP; } return (*a->h_addr2addr)(haddr, addr); @@ -996,7 +1005,8 @@ krb5_anyaddr (krb5_context context, struct addr_operations *a = find_af (af); if (a == NULL) { - krb5_set_error_string (context, "Address family %d not supported", af); + krb5_set_error_message (context, KRB5_PROG_ATYPE_NOSUPP, + "Address family %d not supported", af); return KRB5_PROG_ATYPE_NOSUPP; } @@ -1089,7 +1099,8 @@ krb5_parse_address(krb5_context context, if((*at[i].parse_addr)(context, string, &addr) == 0) { ALLOC_SEQ(addresses, 1); if (addresses->val == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, + "malloc: out of memory"); return ENOMEM; } addresses->val[0] = addr; @@ -1100,9 +1111,12 @@ krb5_parse_address(krb5_context context, error = getaddrinfo (string, NULL, NULL, &ai); if (error) { + krb5_error_code ret2; save_errno = errno; - krb5_set_error_string (context, "%s: %s", string, gai_strerror(error)); - return krb5_eai_to_heim_errno(error, save_errno); + ret2 = krb5_eai_to_heim_errno(error, save_errno); + krb5_set_error_message (context, ret2, "%s: %s", + string, gai_strerror(error)); + return ret2; } n = 0; @@ -1111,7 +1125,8 @@ krb5_parse_address(krb5_context context, ALLOC_SEQ(addresses, n); if (addresses->val == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, + "malloc: out of memory"); freeaddrinfo(ai); return ENOMEM; } @@ -1154,15 +1169,17 @@ krb5_address_order(krb5_context context, struct addr_operations *a; a = find_atype(addr1->addr_type); if(a == NULL) { - krb5_set_error_string (context, "Address family %d not supported", - addr1->addr_type); + krb5_set_error_message (context, KRB5_PROG_ATYPE_NOSUPP, + "Address family %d not supported", + addr1->addr_type); return KRB5_PROG_ATYPE_NOSUPP; } if(a->order_addr != NULL) return (*a->order_addr)(context, addr1, addr2); a = find_atype(addr2->addr_type); if(a == NULL) { - krb5_set_error_string (context, "Address family %d not supported", + krb5_set_error_message (context, KRB5_PROG_ATYPE_NOSUPP, + "Address family %d not supported", addr2->addr_type); return KRB5_PROG_ATYPE_NOSUPP; } @@ -1349,7 +1366,8 @@ krb5_append_addresses(krb5_context context, if(source->len > 0) { tmp = realloc(dest->val, (dest->len + source->len) * sizeof(*tmp)); if(tmp == NULL) { - krb5_set_error_string(context, "realloc: out of memory"); + krb5_set_error_message (context, ENOMEM, + "realloc: out of memory"); return ENOMEM; } dest->val = tmp; @@ -1391,13 +1409,15 @@ krb5_make_addrport (krb5_context context, *res = malloc (sizeof(**res)); if (*res == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message (context, ENOMEM, + "malloc: out of memory"); return ENOMEM; } (*res)->addr_type = KRB5_ADDRESS_ADDRPORT; ret = krb5_data_alloc (&(*res)->address, len); if (ret) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message (context, ret, + "malloc: out of memory"); free (*res); *res = NULL; return ret; @@ -1457,7 +1477,8 @@ krb5_address_prefixlen_boundary(krb5_context context, struct addr_operations *a = find_atype (inaddr->addr_type); if(a != NULL && a->mask_boundary != NULL) return (*a->mask_boundary)(context, inaddr, prefixlen, low, high); - krb5_set_error_string(context, "Address family %d doesn't support " + krb5_set_error_message(context, KRB5_PROG_ATYPE_NOSUPP, + "Address family %d doesn't support " "address mask operation", inaddr->addr_type); return KRB5_PROG_ATYPE_NOSUPP; } diff --git a/source4/heimdal/lib/krb5/auth_context.c b/source4/heimdal/lib/krb5/auth_context.c index 323f17a245..e4fb50e5b8 100644 --- a/source4/heimdal/lib/krb5/auth_context.c +++ b/source4/heimdal/lib/krb5/auth_context.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: auth_context.c 21745 2007-07-31 16:11:25Z lha $"); +RCSID("$Id: auth_context.c 23273 2008-06-23 03:25:00Z lha $"); krb5_error_code KRB5_LIB_FUNCTION krb5_auth_con_init(krb5_context context, @@ -43,13 +43,13 @@ krb5_auth_con_init(krb5_context context, ALLOC(p, 1); if(!p) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } memset(p, 0, sizeof(*p)); ALLOC(p->authenticator, 1); if (!p->authenticator) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); free(p); return ENOMEM; } @@ -174,7 +174,8 @@ krb5_auth_con_genaddrs(krb5_context context, len = sizeof(ss_local); if(getsockname(fd, local, &len) < 0) { ret = errno; - krb5_set_error_string (context, "getsockname: %s", + krb5_set_error_message(context, ret, + "getsockname: %s", strerror(ret)); goto out; } @@ -191,7 +192,8 @@ krb5_auth_con_genaddrs(krb5_context context, len = sizeof(ss_remote); if(getpeername(fd, remote, &len) < 0) { ret = errno; - krb5_set_error_string (context, "getpeername: %s", strerror(ret)); + krb5_set_error_message(context, ret, + "getpeername: %s", strerror(ret)); goto out; } ret = krb5_sockaddr2address (context, remote, &remote_k_address); @@ -239,7 +241,7 @@ krb5_auth_con_getaddrs(krb5_context context, krb5_free_address (context, *local_addr); *local_addr = malloc (sizeof(**local_addr)); if (*local_addr == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } krb5_copy_address(context, @@ -250,7 +252,7 @@ krb5_auth_con_getaddrs(krb5_context context, krb5_free_address (context, *remote_addr); *remote_addr = malloc (sizeof(**remote_addr)); if (*remote_addr == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); krb5_free_address (context, *local_addr); *local_addr = NULL; return ENOMEM; @@ -450,7 +452,7 @@ krb5_auth_con_getauthenticator(krb5_context context, { *authenticator = malloc(sizeof(**authenticator)); if (*authenticator == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } diff --git a/source4/heimdal/lib/krb5/build_auth.c b/source4/heimdal/lib/krb5/build_auth.c index f8739c044d..fe3a5f523c 100644 --- a/source4/heimdal/lib/krb5/build_auth.c +++ b/source4/heimdal/lib/krb5/build_auth.c @@ -33,7 +33,7 @@ #include <krb5_locl.h> -RCSID("$Id: build_auth.c 17033 2006-04-10 08:53:21Z lha $"); +RCSID("$Id: build_auth.c 23273 2008-06-23 03:25:00Z lha $"); static krb5_error_code make_etypelist(krb5_context context, @@ -62,7 +62,7 @@ make_etypelist(krb5_context context, ALLOC_SEQ(&ad, 1); if (ad.val == NULL) { free(buf); - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } @@ -81,14 +81,14 @@ make_etypelist(krb5_context context, ALLOC(*auth_data, 1); if (*auth_data == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } ALLOC_SEQ(*auth_data, 1); if ((*auth_data)->val == NULL) { free(buf); - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } @@ -118,7 +118,7 @@ krb5_build_authenticator (krb5_context context, auth = calloc(1, sizeof(*auth)); if (auth == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } diff --git a/source4/heimdal/lib/krb5/cache.c b/source4/heimdal/lib/krb5/cache.c index 5db6d2b2cf..34bfb4a350 100644 --- a/source4/heimdal/lib/krb5/cache.c +++ b/source4/heimdal/lib/krb5/cache.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: cache.c 22127 2007-12-04 00:54:37Z lha $"); +RCSID("$Id: cache.c 23417 2008-07-26 18:36:33Z lha $"); /** * Add a new ccache type with operations `ops', overwriting any @@ -59,9 +59,10 @@ krb5_cc_register(krb5_context context, for(i = 0; i < context->num_cc_ops && context->cc_ops[i].prefix; i++) { if(strcmp(context->cc_ops[i].prefix, ops->prefix) == 0) { if(!override) { - krb5_set_error_string(context, - "ccache type %s already exists", - ops->prefix); + krb5_set_error_message(context, + KRB5_CC_TYPE_EXISTS, + "ccache type %s already exists", + ops->prefix); return KRB5_CC_TYPE_EXISTS; } break; @@ -72,7 +73,8 @@ krb5_cc_register(krb5_context context, (context->num_cc_ops + 1) * sizeof(*context->cc_ops)); if(o == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, KRB5_CC_NOMEM, + "malloc: out of memory"); return KRB5_CC_NOMEM; } context->num_cc_ops++; @@ -98,7 +100,7 @@ _krb5_cc_allocate(krb5_context context, p = malloc (sizeof(*p)); if(p == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, KRB5_CC_NOMEM, "malloc: out of memory"); return KRB5_CC_NOMEM; } p->ops = ops; @@ -166,7 +168,8 @@ krb5_cc_resolve(krb5_context context, if (strchr (name, ':') == NULL) return allocate_ccache (context, &krb5_fcc_ops, name, id); else { - krb5_set_error_string(context, "unknown ccache type %s", name); + krb5_set_error_message(context, KRB5_CC_UNKNOWN_TYPE, + "unknown ccache type %s", name); return KRB5_CC_UNKNOWN_TYPE; } } @@ -204,16 +207,14 @@ krb5_error_code KRB5_LIB_FUNCTION krb5_cc_new_unique(krb5_context context, const char *type, const char *hint, krb5_ccache *id) { - const krb5_cc_ops *ops = KRB5_DEFAULT_CCTYPE; + const krb5_cc_ops *ops; krb5_error_code ret; - if (type) { - ops = krb5_cc_get_prefix_ops(context, type); - if (ops == NULL) { - krb5_set_error_string(context, - "Credential cache type %s is unknown", type); - return KRB5_CC_UNKNOWN_TYPE; - } + ops = krb5_cc_get_prefix_ops(context, type); + if (ops == NULL) { + krb5_set_error_message(context, KRB5_CC_UNKNOWN_TYPE, + "Credential cache type %s is unknown", type); + return KRB5_CC_UNKNOWN_TYPE; } ret = _krb5_cc_allocate(context, ops, id); @@ -270,18 +271,20 @@ krb5_cc_get_full_name(krb5_context context, type = krb5_cc_get_type(context, id); if (type == NULL) { - krb5_set_error_string(context, "cache have no name of type"); + krb5_set_error_message(context, KRB5_CC_UNKNOWN_TYPE, + "cache have no name of type"); return KRB5_CC_UNKNOWN_TYPE; } name = krb5_cc_get_name(context, id); if (name == NULL) { - krb5_set_error_string(context, "cache of type %s have no name", type); + krb5_set_error_message(context, KRB5_CC_BADNAME, + "cache of type %s have no name", type); return KRB5_CC_BADNAME; } if (asprintf(str, "%s:%s", type, name) == -1) { - krb5_set_error_string(context, "malloc - out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); *str = NULL; return ENOMEM; } @@ -327,7 +330,8 @@ _krb5_expand_default_cc_name(krb5_context context, const char *str, char **res) if (tmp2 == NULL) { free(*res); *res = NULL; - krb5_set_error_string(context, "variable missing }"); + krb5_set_error_message(context, KRB5_CONFIG_BADFORMAT, + "variable missing }"); return KRB5_CONFIG_BADFORMAT; } if (strncasecmp(tmp, "%{uid}", 6) == 0) @@ -337,10 +341,11 @@ _krb5_expand_default_cc_name(krb5_context context, const char *str, char **res) else { free(*res); *res = NULL; - krb5_set_error_string(context, - "expand default cache unknown " - "variable \"%.*s\"", - (int)(tmp2 - tmp) - 2, tmp + 2); + krb5_set_error_message(context, + KRB5_CONFIG_BADFORMAT, + "expand default cache unknown " + "variable \"%.*s\"", + (int)(tmp2 - tmp) - 2, tmp + 2); return KRB5_CONFIG_BADFORMAT; } str = tmp2 + 1; @@ -351,7 +356,7 @@ _krb5_expand_default_cc_name(krb5_context context, const char *str, char **res) if (append == NULL) { free(*res); *res = NULL; - krb5_set_error_string(context, "malloc - out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } @@ -361,7 +366,8 @@ _krb5_expand_default_cc_name(krb5_context context, const char *str, char **res) free(append); free(*res); *res = NULL; - krb5_set_error_string(context, "malloc - out of memory"); + krb5_set_error_message(context, ENOMEM, + "malloc: out of memory"); return ENOMEM; } *res = tmp; @@ -406,11 +412,29 @@ environment_changed(krb5_context context) } /** - * Set the default cc name for `context' to `name'. + * Switch the default default credential cache for a specific + * credcache type (and name for some implementations). + * + * @return Returns 0 or an error code. * * @ingroup krb5_ccache */ +krb5_error_code +krb5_cc_switch(krb5_context context, krb5_ccache id) +{ + + if (id->ops->set_default == NULL) + return 0; + + return (*id->ops->set_default)(context, id); +} + +/** + * Set the default cc name for `context' to `name'. + * + * @ingroup krb5_ccache + */ krb5_error_code KRB5_LIB_FUNCTION krb5_cc_set_default_name(krb5_context context, const char *name) @@ -440,7 +464,19 @@ krb5_cc_set_default_name(krb5_context context, const char *name) } if (e == NULL) { const krb5_cc_ops *ops = KRB5_DEFAULT_CCTYPE; - ret = (*ops->default_name)(context, &p); + e = krb5_config_get_string(context, NULL, "libdefaults", + "default_cc_type", NULL); + if (e) { + ops = krb5_cc_get_prefix_ops(context, e); + if (ops == NULL) { + krb5_set_error_message(context, + KRB5_CC_UNKNOWN_TYPE, + "Credential cache type %s " + "is unknown", e); + return KRB5_CC_UNKNOWN_TYPE; + } + } + ret = (*ops->get_default_name)(context, &p); if (ret) return ret; } @@ -452,7 +488,7 @@ krb5_cc_set_default_name(krb5_context context, const char *name) } if (p == NULL) { - krb5_set_error_string(context, "malloc - out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } @@ -499,7 +535,7 @@ krb5_cc_default(krb5_context context, const char *p = krb5_cc_default_name(context); if (p == NULL) { - krb5_set_error_string(context, "malloc - out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } return krb5_cc_resolve(context, p, id); @@ -728,9 +764,10 @@ krb5_cc_remove_cred(krb5_context context, krb5_creds *cred) { if(id->ops->remove_cred == NULL) { - krb5_set_error_string(context, - "ccache %s does not support remove_cred", - id->ops->prefix); + krb5_set_error_message(context, + EACCES, + "ccache %s does not support remove_cred", + id->ops->prefix); return EACCES; /* XXX */ } return (*id->ops->remove_cred)(context, id, which, cred); @@ -846,10 +883,12 @@ krb5_cc_clear_mcred(krb5_creds *mcred) /** * Get the cc ops that is registered in `context' to handle the - * `prefix'. `prefix' can be a complete credential cache name or a + * prefix. prefix can be a complete credential cache name or a * prefix, the function will only use part up to the first colon (:) - * if there is one. - * Returns NULL if ops not found. + * if there is one. If prefix the argument is NULL, the default ccache + * implemtation is returned. + + * @return Returns NULL if ops not found. * * @ingroup krb5_ccache */ @@ -861,12 +900,14 @@ krb5_cc_get_prefix_ops(krb5_context context, const char *prefix) char *p, *p1; int i; + if (prefix == NULL) + return KRB5_DEFAULT_CCTYPE; if (prefix[0] == '/') return &krb5_fcc_ops; p = strdup(prefix); if (p == NULL) { - krb5_set_error_string(context, "malloc - out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return NULL; } p1 = strchr(p, ':'); @@ -911,20 +952,22 @@ krb5_cc_cache_get_first (krb5_context context, ops = krb5_cc_get_prefix_ops(context, type); if (ops == NULL) { - krb5_set_error_string(context, "Unknown type \"%s\" when iterating " - "trying to iterate the credential caches", type); + krb5_set_error_message(context, KRB5_CC_UNKNOWN_TYPE, + "Unknown type \"%s\" when iterating " + "trying to iterate the credential caches", type); return KRB5_CC_UNKNOWN_TYPE; } if (ops->get_cache_first == NULL) { - krb5_set_error_string(context, "Credential cache type %s doesn't support " - "iterations over caches", ops->prefix); + krb5_set_error_message(context, KRB5_CC_NOSUPP, + "Credential cache type %s doesn't support " + "iterations over caches", ops->prefix); return KRB5_CC_NOSUPP; } *cursor = calloc(1, sizeof(**cursor)); if (*cursor == NULL) { - krb5_set_error_string(context, "malloc - out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } @@ -1028,8 +1071,10 @@ krb5_cc_cache_match (krb5_context context, krb5_unparse_name(context, client, &str); - krb5_set_error_string(context, "Principal %s not found in a " - "credential cache", str ? str : "<out of memory>"); + krb5_set_error_message(context, KRB5_CC_NOTFOUND, + "Principal %s not found in a " + "credential cache", + str ? str : "<out of memory>"); if (str) free(str); return KRB5_CC_NOTFOUND; @@ -1059,8 +1104,9 @@ krb5_cc_move(krb5_context context, krb5_ccache from, krb5_ccache to) krb5_error_code ret; if (strcmp(from->ops->prefix, to->ops->prefix) != 0) { - krb5_set_error_string(context, "Moving credentials between diffrent " - "types not yet supported"); + krb5_set_error_message(context, KRB5_CC_NOSUPP, + "Moving credentials between diffrent " + "types not yet supported"); return KRB5_CC_NOSUPP; } @@ -1071,3 +1117,123 @@ krb5_cc_move(krb5_context context, krb5_ccache from, krb5_ccache to) } return ret; } + +#define KRB5_CONF_NAME "@krb5_ccache_conf_data" + +static krb5_error_code +build_conf_principals(krb5_context context, krb5_ccache id, + krb5_const_principal principal, + const char *name, krb5_creds *cred) +{ + krb5_principal client; + krb5_error_code ret; + char *pname = NULL; + + memset(cred, 0, sizeof(*cred)); + + ret = krb5_cc_get_principal(context, id, &client); + if (ret) + return ret; + + if (principal) { + ret = krb5_unparse_name(context, principal, &pname); + if (ret) + return ret; + } + + ret = krb5_make_principal(context, &cred->server, + krb5_principal_get_realm(context, client), + KRB5_CONF_NAME, name, pname, NULL); + free(pname); + if (ret) { + krb5_free_principal(context, client); + return ret; + } + ret = krb5_copy_principal(context, client, &cred->client); + krb5_free_principal(context, client); + return ret; +} + +/** + * Store some configuration for the credential cache in the cache. + * Existing configuration under the same name is over-written. + * + * @param context a Keberos context + * @param id the credential cache to store the data for + * @param principal configuration for a specific principal, if + * NULL, global for the whole cache. + * @param name name under which the configuraion is stored. + * @param data data to store + */ + +krb5_error_code KRB5_LIB_FUNCTION +krb5_cc_set_config(krb5_context context, krb5_ccache id, + krb5_const_principal principal, + const char *name, krb5_data *data) +{ + krb5_error_code ret; + krb5_creds cred; + + ret = build_conf_principals(context, id, principal, name, &cred); + if (ret) + goto out; + + /* Remove old configuration */ + ret = krb5_cc_remove_cred(context, id, 0, &cred); + if (ret) + goto out; + + /* not that anyone care when this expire */ + cred.times.authtime = time(NULL); + cred.times.endtime = cred.times.authtime + 3600 * 24 * 30; + + ret = krb5_data_copy(&cred.ticket, data->data, data->length); + if (ret) + goto out; + + ret = krb5_cc_store_cred(context, id, &cred); + +out: + krb5_free_cred_contents (context, &cred); + return ret; +} + +/** + * Get some configuration for the credential cache in the cache. + * + * @param context a Keberos context + * @param id the credential cache to store the data for + * @param principal configuration for a specific principal, if + * NULL, global for the whole cache. + * @param name name under which the configuraion is stored. + * @param data data to fetched, free with krb5_data_free() + */ + + +krb5_error_code KRB5_LIB_FUNCTION +krb5_cc_get_config(krb5_context context, krb5_ccache id, + krb5_const_principal principal, + const char *name, krb5_data *data) +{ + krb5_creds mcred, cred; + krb5_error_code ret; + + memset(&cred, 0, sizeof(cred)); + krb5_data_zero(data); + + ret = build_conf_principals(context, id, principal, name, &mcred); + if (ret) + goto out; + + ret = krb5_cc_retrieve_cred(context, id, 0, &mcred, &cred); + if (ret) + goto out; + + ret = krb5_data_copy(data, cred.ticket.data, cred.ticket.length); + +out: + krb5_free_cred_contents (context, &cred); + krb5_free_cred_contents (context, &mcred); + return ret; +} + diff --git a/source4/heimdal/lib/krb5/changepw.c b/source4/heimdal/lib/krb5/changepw.c index 703cf43eb6..ac1a2d312e 100644 --- a/source4/heimdal/lib/krb5/changepw.c +++ b/source4/heimdal/lib/krb5/changepw.c @@ -33,7 +33,11 @@ #include <krb5_locl.h> -RCSID("$Id: changepw.c 21505 2007-07-12 12:28:38Z lha $"); +RCSID("$Id: changepw.c 23445 2008-07-27 12:08:03Z lha $"); + +#undef __attribute__ +#define __attribute__(X) + static void str2data (krb5_data *d, @@ -141,7 +145,8 @@ chgpw_send_request (krb5_context context, if (sendmsg (sock, &msghdr, 0) < 0) { ret = errno; - krb5_set_error_string(context, "sendmsg %s: %s", host, strerror(ret)); + krb5_set_error_message(context, ret, "sendmsg %s: %s", + host, strerror(ret)); } krb5_data_free (&krb_priv_data); @@ -250,7 +255,8 @@ setpw_send_request (krb5_context context, if (sendmsg (sock, &msghdr, 0) < 0) { ret = errno; - krb5_set_error_string(context, "sendmsg %s: %s", host, strerror(ret)); + krb5_set_error_message(context, ret, "sendmsg %s: %s", + host, strerror(ret)); } krb5_data_free (&krb_priv_data); @@ -286,11 +292,12 @@ process_reply (krb5_context context, 0, NULL, NULL); if (ret < 0) { save_errno = errno; - krb5_set_error_string(context, "recvfrom %s: %s", - host, strerror(save_errno)); + krb5_set_error_message(context, save_errno, + "recvfrom %s: %s", + host, strerror(save_errno)); return save_errno; } else if (ret == 0) { - krb5_set_error_string(context, "recvfrom timeout %s", host); + krb5_set_error_message(context, 1,"recvfrom timeout %s", host); return 1; } len += ret; @@ -304,16 +311,18 @@ process_reply (krb5_context context, break; } if (len == sizeof(reply)) { - krb5_set_error_string(context, "message too large from %s", - host); + krb5_set_error_message(context, ENOMEM, + "message too large from %s", + host); return ENOMEM; } } else { ret = recvfrom (sock, reply, sizeof(reply), 0, NULL, NULL); if (ret < 0) { save_errno = errno; - krb5_set_error_string(context, "recvfrom %s: %s", - host, strerror(save_errno)); + krb5_set_error_message(context, save_errno, + "recvfrom %s: %s", + host, strerror(save_errno)); return save_errno; } len = ret; @@ -522,7 +531,7 @@ change_password_loop (krb5_context context, krb5_krbhst_handle handle = NULL; krb5_krbhst_info *hi; int sock; - int i; + unsigned int i; int done = 0; krb5_realm realm; @@ -571,6 +580,7 @@ change_password_loop (krb5_context context, sock = socket (a->ai_family, a->ai_socktype, a->ai_protocol); if (sock < 0) continue; + rk_cloexec(sock); ret = connect(sock, a->ai_addr, a->ai_addrlen); if (ret < 0) { @@ -607,8 +617,9 @@ change_password_loop (krb5_context context, } if (sock >= FD_SETSIZE) { - krb5_set_error_string(context, "fd %d too large", sock); ret = ERANGE; + krb5_set_error_message(context, ret, + "fd %d too large", sock); close (sock); goto out; } @@ -647,24 +658,32 @@ change_password_loop (krb5_context context, out: krb5_krbhst_free (context, handle); krb5_auth_con_free (context, auth_context); - if (done) - return 0; - else { - if (ret == KRB5_KDC_UNREACH) { - krb5_set_error_string(context, - "unable to reach any changepw server " - " in realm %s", realm); - *result_code = KRB5_KPASSWD_HARDERROR; - } - return ret; + + if (ret == KRB5_KDC_UNREACH) { + krb5_set_error_message(context, + ret, + "unable to reach any changepw server " + " in realm %s", realm); + *result_code = KRB5_KPASSWD_HARDERROR; } + return ret; } +#ifndef HEIMDAL_SMALLER -/* - * change the password using the credentials in `creds' (for the - * principal indicated in them) to `newpw', storing the result of - * the operation in `result_*' and an error code or 0. +/** + * krb5_change_password() is deprecated, use krb5_set_password(). + * + * @param context a Keberos context + * @param creds + * @param newpw + * @param result_code + * @param result_code_string + * @param result_string + * + * @return On sucess password is changed. + + * @ingroup @krb5_deprecated */ krb5_error_code KRB5_LIB_FUNCTION @@ -674,6 +693,7 @@ krb5_change_password (krb5_context context, int *result_code, krb5_data *result_code_string, krb5_data *result_string) + __attribute__((deprecated)) { struct kpwd_proc *p = find_chpw_proto("change password"); @@ -688,9 +708,24 @@ krb5_change_password (krb5_context context, result_code, result_code_string, result_string, p); } +#endif /* HEIMDAL_SMALLER */ -/* +/** + * Change passwrod using creds. + * + * @param context a Keberos context + * @param creds The initial kadmin/passwd for the principal or an admin principal + * @param newpw The new password to set + * @param targprinc if unset, the default principal is used. + * @param result_code Result code, KRB5_KPASSWD_SUCCESS is when password is changed. + * @param result_code_string binary message from the server, contains + * at least the result_code. + * @param result_string A message from the kpasswd service or the + * library in human printable form. The string is NUL terminated. * + * @return On sucess and *result_code is KRB5_KPASSWD_SUCCESS, the password is changed. + + * @ingroup @krb5 */ krb5_error_code KRB5_LIB_FUNCTION @@ -707,8 +742,8 @@ krb5_set_password(krb5_context context, int i; *result_code = KRB5_KPASSWD_MALFORMED; - result_code_string->data = result_string->data = NULL; - result_code_string->length = result_string->length = 0; + krb5_data_zero(result_code_string); + krb5_data_zero(result_string); if (targprinc == NULL) { ret = krb5_get_default_principal(context, &principal); @@ -732,6 +767,8 @@ krb5_set_password(krb5_context context, return ret; } +#ifndef HEIMDAL_SMALLER + /* * */ @@ -797,6 +834,8 @@ krb5_set_password_using_ccache(krb5_context context, return ret; } +#endif /* !HEIMDAL_SMALLER */ + /* * */ diff --git a/source4/heimdal/lib/krb5/config_file.c b/source4/heimdal/lib/krb5/config_file.c index ac5eba39dc..bf3c432397 100644 --- a/source4/heimdal/lib/krb5/config_file.c +++ b/source4/heimdal/lib/krb5/config_file.c @@ -32,7 +32,7 @@ */ #include "krb5_locl.h" -RCSID("$Id: config_file.c 19213 2006-12-04 23:36:36Z lha $"); +RCSID("$Id: config_file.c 23280 2008-06-23 03:26:18Z lha $"); #ifndef HAVE_NETINFO @@ -295,7 +295,8 @@ krb5_config_parse_string_multi(krb5_context context, ret = krb5_config_parse_debug (&f, res, &lineno, &str); if (ret) { - krb5_set_error_string (context, "%s:%u: %s", "<constant>", lineno, str); + krb5_set_error_message (context, ret, "%s:%u: %s", + "<constant>", lineno, str); return ret; } return 0; @@ -314,14 +315,15 @@ krb5_config_parse_file_multi (krb5_context context, f.s = NULL; if(f.f == NULL) { ret = errno; - krb5_set_error_string (context, "open %s: %s", fname, strerror(ret)); + krb5_set_error_message (context, ret, "open %s: %s", + fname, strerror(ret)); return ret; } ret = krb5_config_parse_debug (&f, res, &lineno, &str); fclose(f.f); if (ret) { - krb5_set_error_string (context, "%s:%u: %s", fname, lineno, str); + krb5_set_error_message (context, ret, "%s:%u: %s", fname, lineno, str); return ret; } return 0; diff --git a/source4/heimdal/lib/krb5/constants.c b/source4/heimdal/lib/krb5/constants.c index 5188a1d3a8..8fffb0f402 100644 --- a/source4/heimdal/lib/krb5/constants.c +++ b/source4/heimdal/lib/krb5/constants.c @@ -33,11 +33,11 @@ #include "krb5_locl.h" -RCSID("$Id: constants.c 14253 2004-09-23 07:57:37Z joda $"); +RCSID("$Id: constants.c 23026 2008-04-17 10:02:03Z lha $"); -const char *krb5_config_file = +KRB5_LIB_VARIABLE const char *krb5_config_file = #ifdef __APPLE__ "/Library/Preferences/edu.mit.Kerberos:" #endif SYSCONFDIR "/krb5.conf:/etc/krb5.conf"; -const char *krb5_defkeyname = KEYTAB_DEFAULT; +KRB5_LIB_VARIABLE const char *krb5_defkeyname = KEYTAB_DEFAULT; diff --git a/source4/heimdal/lib/krb5/context.c b/source4/heimdal/lib/krb5/context.c index 256783310e..543dba396d 100644 --- a/source4/heimdal/lib/krb5/context.c +++ b/source4/heimdal/lib/krb5/context.c @@ -34,7 +34,7 @@ #include "krb5_locl.h" #include <com_err.h> -RCSID("$Id: context.c 22293 2007-12-14 05:25:59Z lha $"); +RCSID("$Id: context.c 23420 2008-07-26 18:37:48Z lha $"); #define INIT_FIELD(C, T, E, D, F) \ (C)->E = krb5_config_get_ ## T ## _default ((C), NULL, (D), \ @@ -68,7 +68,7 @@ set_etypes (krb5_context context, etypes = malloc((i+1) * sizeof(*etypes)); if (etypes == NULL) { krb5_config_free_strings (etypes_str); - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message (context, ENOMEM, "malloc: out of memory"); return ENOMEM; } for(j = 0, k = 0; j < i; j++) { @@ -246,6 +246,9 @@ krb5_init_context(krb5_context *context) krb5_cc_register(p, &krb5_acc_ops, TRUE); krb5_cc_register(p, &krb5_fcc_ops, TRUE); krb5_cc_register(p, &krb5_mcc_ops, TRUE); +#if 0 + krb5_cc_register(p, &krb5_scc_ops, TRUE); +#endif #ifdef HAVE_KCM krb5_cc_register(p, &krb5_kcm_ops, TRUE); #endif @@ -257,8 +260,6 @@ krb5_init_context(krb5_context *context) krb5_kt_register (p, &krb5_javakt_ops); krb5_kt_register (p, &krb5_mkt_ops); krb5_kt_register (p, &krb5_akf_ops); - krb5_kt_register (p, &krb4_fkt_ops); - krb5_kt_register (p, &krb5_srvtab_fkt_ops); krb5_kt_register (p, &krb5_any_ops); out: @@ -552,7 +553,7 @@ default_etypes(krb5_context context, krb5_enctype **etype) ep = realloc(e, (n + 2) * sizeof(*e)); if (ep == NULL) { free(e); - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message (context, ENOMEM, "malloc: out of memory"); return ENOMEM; } e = ep; @@ -594,7 +595,7 @@ krb5_set_default_in_tkt_etypes(krb5_context context, ++i; ALLOC(p, i); if(!p) { - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message (context, ENOMEM, "malloc: out of memory"); return ENOMEM; } memmove(p, etypes, i * sizeof(krb5_enctype)); @@ -623,26 +624,26 @@ krb5_error_code KRB5_LIB_FUNCTION krb5_get_default_in_tkt_etypes(krb5_context context, krb5_enctype **etypes) { - krb5_enctype *p; - int i; - krb5_error_code ret; - - if(context->etypes) { - for(i = 0; context->etypes[i]; i++); - ++i; - ALLOC(p, i); - if(!p) { - krb5_set_error_string (context, "malloc: out of memory"); - return ENOMEM; + krb5_enctype *p; + int i; + krb5_error_code ret; + + if(context->etypes) { + for(i = 0; context->etypes[i]; i++); + ++i; + ALLOC(p, i); + if(!p) { + krb5_set_error_message (context, ENOMEM, "malloc: out of memory"); + return ENOMEM; + } + memmove(p, context->etypes, i * sizeof(krb5_enctype)); + } else { + ret = default_etypes(context, &p); + if (ret) + return ret; } - memmove(p, context->etypes, i * sizeof(krb5_enctype)); - } else { - ret = default_etypes(context, &p); - if (ret) - return ret; - } - *etypes = p; - return 0; + *etypes = p; + return 0; } /** @@ -776,7 +777,7 @@ krb5_set_extra_addresses(krb5_context context, const krb5_addresses *addresses) if(context->extra_addresses == NULL) { context->extra_addresses = malloc(sizeof(*context->extra_addresses)); if(context->extra_addresses == NULL) { - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message (context, ENOMEM, "malloc: out of memory"); return ENOMEM; } } @@ -858,7 +859,7 @@ krb5_set_ignore_addresses(krb5_context context, const krb5_addresses *addresses) if(context->ignore_addresses == NULL) { context->ignore_addresses = malloc(sizeof(*context->ignore_addresses)); if(context->ignore_addresses == NULL) { - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message (context, ENOMEM, "malloc: out of memory"); return ENOMEM; } } @@ -986,7 +987,7 @@ krb5_get_dns_canonicalize_hostname (krb5_context context) * @param sec seconds part of offset. * @param usec micro seconds part of offset. * - * @return return non zero if the library uses DNS to canonicalize hostnames. + * @return returns zero * * @ingroup krb5 */ @@ -1002,6 +1003,27 @@ krb5_get_kdc_sec_offset (krb5_context context, int32_t *sec, int32_t *usec) } /** + * Set current offset in time to the KDC. + * + * @param context Kerberos 5 context. + * @param sec seconds part of offset. + * @param usec micro seconds part of offset. + * + * @return returns zero + * + * @ingroup krb5 + */ + +krb5_error_code KRB5_LIB_FUNCTION +krb5_set_kdc_sec_offset (krb5_context context, int32_t sec, int32_t usec) +{ + context->kdc_sec_offset = sec; + if (usec >= 0) + context->kdc_usec_offset = usec; + return 0; +} + +/** * Get max time skew allowed. * * @param context Kerberos 5 context. diff --git a/source4/heimdal/lib/krb5/convert_creds.c b/source4/heimdal/lib/krb5/convert_creds.c index b2af0187ea..07943efb28 100644 --- a/source4/heimdal/lib/krb5/convert_creds.c +++ b/source4/heimdal/lib/krb5/convert_creds.c @@ -32,7 +32,7 @@ */ #include "krb5_locl.h" -RCSID("$Id: convert_creds.c 22050 2007-11-11 11:20:46Z lha $"); +RCSID("$Id: convert_creds.c 23280 2008-06-23 03:26:18Z lha $"); #include "krb5-v4compat.h" @@ -97,7 +97,7 @@ krb524_convert_creds_kdc(krb5_context context, sp = krb5_storage_from_mem(reply.data, reply.length); if(sp == NULL) { ret = ENOMEM; - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message (context, ENOMEM, "malloc: out of memory"); goto out2; } krb5_ret_int32(sp, &tmp); @@ -132,8 +132,8 @@ krb524_convert_creds_kdc(krb5_context context, goto out; memcpy(v4creds->session, v5_creds->session.keyvalue.data, 8); } else { - krb5_set_error_string(context, "converting credentials: %s", - krb5_get_err_text(context, ret)); + krb5_set_error_message (context, ret, "converting credentials: %s", + krb5_get_err_text(context, ret)); } out: krb5_storage_free(sp); diff --git a/source4/heimdal/lib/krb5/copy_host_realm.c b/source4/heimdal/lib/krb5/copy_host_realm.c index 8c4f39b4ac..cbe333850c 100644 --- a/source4/heimdal/lib/krb5/copy_host_realm.c +++ b/source4/heimdal/lib/krb5/copy_host_realm.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: copy_host_realm.c 22057 2007-11-11 15:13:13Z lha $"); +RCSID("$Id: copy_host_realm.c 23280 2008-06-23 03:26:18Z lha $"); /** * Copy the list of realms from `from' to `to'. @@ -53,24 +53,23 @@ krb5_copy_host_realm(krb5_context context, const krb5_realm *from, krb5_realm **to) { - int n, i; + unsigned int n, i; const krb5_realm *p; - for (n = 0, p = from; *p != NULL; ++p) + for (n = 1, p = from; *p != NULL; ++p) ++n; - ++n; - *to = malloc (n * sizeof(**to)); + + *to = calloc (n, sizeof(**to)); if (*to == NULL) { - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message (context, ENOMEM, "malloc: out of memory"); return ENOMEM; } - for (i = 0; i < n; ++i) - (*to)[i] = NULL; + for (i = 0, p = from; *p != NULL; ++p, ++i) { (*to)[i] = strdup(*p); if ((*to)[i] == NULL) { krb5_free_host_realm (context, *to); - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message (context, ENOMEM, "malloc: out of memory"); return ENOMEM; } } diff --git a/source4/heimdal/lib/krb5/crc.c b/source4/heimdal/lib/krb5/crc.c index 072c29d689..e8ddecf7ba 100644 --- a/source4/heimdal/lib/krb5/crc.c +++ b/source4/heimdal/lib/krb5/crc.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: crc.c 17442 2006-05-05 09:31:15Z lha $"); +RCSID("$Id: crc.c 22862 2008-04-07 18:49:55Z lha $"); static u_long table[256]; @@ -44,7 +44,7 @@ _krb5_crc_init_table(void) { static int flag = 0; unsigned long crc, poly; - int i, j; + unsigned int i, j; if(flag) return; poly = CRC_GEN; diff --git a/source4/heimdal/lib/krb5/creds.c b/source4/heimdal/lib/krb5/creds.c index 17ef46dfa3..938ec294a4 100644 --- a/source4/heimdal/lib/krb5/creds.c +++ b/source4/heimdal/lib/krb5/creds.c @@ -33,11 +33,13 @@ #include "krb5_locl.h" -RCSID("$Id: creds.c 22062 2007-11-11 15:41:50Z lha $"); +RCSID("$Id: creds.c 23280 2008-06-23 03:26:18Z lha $"); #undef __attribute__ #define __attribute__(X) +#ifndef HEIMDAL_SMALLER + /* keep this for compatibility with older code */ krb5_error_code KRB5_LIB_FUNCTION __attribute__((deprecated)) krb5_free_creds_contents (krb5_context context, krb5_creds *c) @@ -45,6 +47,8 @@ krb5_free_creds_contents (krb5_context context, krb5_creds *c) return krb5_free_cred_contents (context, c); } +#endif /* HEIMDAL_SMALLER */ + /** * Free content of krb5_creds. * @@ -152,7 +156,7 @@ krb5_copy_creds (krb5_context context, c = malloc (sizeof (*c)); if (c == NULL) { - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message (context, ENOMEM, "malloc: out of memory"); return ENOMEM; } memset (c, 0, sizeof(*c)); diff --git a/source4/heimdal/lib/krb5/crypto.c b/source4/heimdal/lib/krb5/crypto.c index 2e63490946..e91cb9391a 100644 --- a/source4/heimdal/lib/krb5/crypto.c +++ b/source4/heimdal/lib/krb5/crypto.c @@ -32,7 +32,8 @@ */ #include "krb5_locl.h" -RCSID("$Id: crypto.c 22200 2007-12-07 13:48:01Z lha $"); +RCSID("$Id: crypto.c 23454 2008-07-27 12:11:44Z lha $"); +#include <pkinit_asn1.h> #undef CRYPTO_DEBUG #ifdef CRYPTO_DEBUG @@ -111,7 +112,6 @@ struct checksum_type { struct encryption_type { krb5_enctype type; const char *name; - heim_oid *oid; size_t blocksize; size_t padsize; size_t confoundersize; @@ -178,7 +178,7 @@ static void krb5_DES_schedule(krb5_context context, struct key_data *key) { - DES_set_key(key->key->keyvalue.data, key->schedule->data); + DES_set_key_unchecked(key->key->keyvalue.data, key->schedule->data); } #ifdef ENABLE_AFS_STRING_TO_KEY @@ -245,12 +245,12 @@ krb5_DES_AFS3_Transarc_string_to_key (krb5_data pw, memcpy(&ivec, "kerberos", 8); memcpy(&temp_key, "kerberos", 8); DES_set_odd_parity (&temp_key); - DES_set_key (&temp_key, &schedule); + DES_set_key_unchecked (&temp_key, &schedule); DES_cbc_cksum ((void*)password, &ivec, passlen, &schedule, &ivec); memcpy(&temp_key, &ivec, 8); DES_set_odd_parity (&temp_key); - DES_set_key (&temp_key, &schedule); + DES_set_key_unchecked (&temp_key, &schedule); DES_cbc_cksum ((void*)password, key, passlen, &schedule, &ivec); memset(&schedule, 0, sizeof(schedule)); memset(&temp_key, 0, sizeof(temp_key)); @@ -305,7 +305,7 @@ DES_string_to_key_int(unsigned char *data, size_t length, DES_cblock *key) DES_set_odd_parity(key); if(DES_is_weak_key(key)) (*key)[7] ^= 0xF0; - DES_set_key(key, &schedule); + DES_set_key_unchecked(key, &schedule); DES_cbc_cksum((void*)data, key, length, &schedule, key); memset(&schedule, 0, sizeof(schedule)); DES_set_odd_parity(key); @@ -338,7 +338,7 @@ krb5_DES_string_to_key(krb5_context context, len = password.length + salt.saltvalue.length; s = malloc(len); if(len > 0 && s == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message (context, ENOMEM, "malloc: out of memory"); return ENOMEM; } memcpy(s, password.data, password.length); @@ -390,9 +390,9 @@ DES3_schedule(krb5_context context, { DES_cblock *k = key->key->keyvalue.data; DES_key_schedule *s = key->schedule->data; - DES_set_key(&k[0], &s[0]); - DES_set_key(&k[1], &s[1]); - DES_set_key(&k[2], &s[2]); + DES_set_key_unchecked(&k[0], &s[0]); + DES_set_key_unchecked(&k[1], &s[1]); + DES_set_key_unchecked(&k[2], &s[2]); } /* @@ -430,7 +430,7 @@ DES3_string_to_key(krb5_context context, len = password.length + salt.saltvalue.length; str = malloc(len); if(len != 0 && str == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message (context, ENOMEM, "malloc: out of memory"); return ENOMEM; } memcpy(str, password.data, password.length); @@ -444,7 +444,7 @@ DES3_string_to_key(krb5_context context, if (ret) { memset(str, 0, len); free(str); - krb5_set_error_string(context, "out of memory"); + krb5_set_error_message (context, ret, "malloc: out of memory"); return ret; } @@ -453,7 +453,7 @@ DES3_string_to_key(krb5_context context, DES_set_odd_parity(keys + i); if(DES_is_weak_key(keys + i)) xor(keys + i, (const unsigned char*)"\0\0\0\0\0\0\0\xf0"); - DES_set_key(keys + i, &s[i]); + DES_set_key_unchecked(keys + i, &s[i]); } memset(&ivec, 0, sizeof(ivec)); DES_ede3_cbc_encrypt(tmp, @@ -491,7 +491,7 @@ DES3_string_to_key_derived(krb5_context context, s = malloc(len); if(len != 0 && s == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message (context, ENOMEM, "malloc: out of memory"); return ENOMEM; } memcpy(s, password.data, password.length); @@ -560,35 +560,49 @@ ARCFOUR_string_to_key(krb5_context context, krb5_data opaque, krb5_keyblock *key) { - char *s, *p; - size_t len; - int i; - MD4_CTX m; krb5_error_code ret; + uint16_t *s; + size_t len, i; + MD4_CTX m; - len = 2 * password.length; - s = malloc (len); + ret = wind_utf8ucs2_length(password.data, &len); + if (ret) { + krb5_set_error_message (context, ret, "Password not an UCS2 string"); + return ret; + } + + s = malloc (len * sizeof(s[0])); if (len != 0 && s == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); - ret = ENOMEM; - goto out; + krb5_set_error_message (context, ENOMEM, "malloc: out of memory"); + return ENOMEM; } - for (p = s, i = 0; i < password.length; ++i) { - *p++ = ((char *)password.data)[i]; - *p++ = 0; + + ret = wind_utf8ucs2(password.data, s, &len); + if (ret) { + krb5_set_error_message (context, ret, "Password not an UCS2 string"); + goto out; } + + /* LE encoding */ MD4_Init (&m); - MD4_Update (&m, s, len); + for (i = 0; i < len; i++) { + unsigned char p; + p = (s[i] & 0xff); + MD4_Update (&m, &p, 1); + p = (s[i] >> 8) & 0xff; + MD4_Update (&m, &p, 1); + } + key->keytype = enctype; ret = krb5_data_alloc (&key->keyvalue, 16); if (ret) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message (context, ENOMEM, "malloc: out of memory"); goto out; } MD4_Final (key->keyvalue.data, &m); - memset (s, 0, len); ret = 0; out: + memset (s, 0, len); free (s); return ret; } @@ -628,13 +642,13 @@ AES_string_to_key(krb5_context context, kd.schedule = NULL; ALLOC(kd.key, 1); if(kd.key == NULL) { - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message (context, ENOMEM, "malloc: out of memory"); return ENOMEM; } kd.key->keytype = enctype; ret = krb5_data_alloc(&kd.key->keyvalue, et->keytype->size); if (ret) { - krb5_set_error_string(context, "Failed to allocate pkcs5 key"); + krb5_set_error_message (context, ret, "malloc: out of memory"); return ret; } @@ -644,7 +658,8 @@ AES_string_to_key(krb5_context context, et->keytype->size, kd.key->keyvalue.data); if (ret != 1) { free_key_data(context, &kd); - krb5_set_error_string(context, "Error calculating s2k"); + krb5_set_error_message(context, KRB5_PROG_KEYTYPE_NOSUPP, + "Error calculating s2k"); return KRB5_PROG_KEYTYPE_NOSUPP; } @@ -847,21 +862,24 @@ krb5_salttype_to_string (krb5_context context, e = _find_enctype (etype); if (e == NULL) { - krb5_set_error_string(context, "encryption type %d not supported", - etype); + krb5_set_error_message(context, KRB5_PROG_ETYPE_NOSUPP, + "encryption type %d not supported", + etype); return KRB5_PROG_ETYPE_NOSUPP; } for (st = e->keytype->string_to_key; st && st->type; st++) { if (st->type == stype) { *string = strdup (st->name); if (*string == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message (context, ENOMEM, + "malloc: out of memory"); return ENOMEM; } return 0; } } - krb5_set_error_string(context, "salttype %d not supported", stype); + krb5_set_error_message (context, HEIM_ERR_SALTTYPE_NOSUPP, + "salttype %d not supported", stype); return HEIM_ERR_SALTTYPE_NOSUPP; } @@ -876,8 +894,9 @@ krb5_string_to_salttype (krb5_context context, e = _find_enctype (etype); if (e == NULL) { - krb5_set_error_string(context, "encryption type %d not supported", - etype); + krb5_set_error_message(context, KRB5_PROG_ETYPE_NOSUPP, + "encryption type %d not supported", + etype); return KRB5_PROG_ETYPE_NOSUPP; } for (st = e->keytype->string_to_key; st && st->type; st++) { @@ -886,7 +905,8 @@ krb5_string_to_salttype (krb5_context context, return 0; } } - krb5_set_error_string(context, "salttype %s not supported", string); + krb5_set_error_message(context, HEIM_ERR_SALTTYPE_NOSUPP, + "salttype %s not supported", string); return HEIM_ERR_SALTTYPE_NOSUPP; } @@ -988,16 +1008,18 @@ krb5_string_to_key_data_salt_opaque (krb5_context context, struct encryption_type *et =_find_enctype(enctype); struct salt_type *st; if(et == NULL) { - krb5_set_error_string(context, "encryption type %d not supported", - enctype); + krb5_set_error_message(context, KRB5_PROG_ETYPE_NOSUPP, + "encryption type %d not supported", + enctype); return KRB5_PROG_ETYPE_NOSUPP; } for(st = et->keytype->string_to_key; st && st->type; st++) if(st->type == salt.salttype) return (*st->string_to_key)(context, enctype, password, salt, opaque, key); - krb5_set_error_string(context, "salt type %d not supported", - salt.salttype); + krb5_set_error_message(context, HEIM_ERR_SALTTYPE_NOSUPP, + "salt type %d not supported", + salt.salttype); return HEIM_ERR_SALTTYPE_NOSUPP; } @@ -1042,12 +1064,13 @@ krb5_keytype_to_string(krb5_context context, { struct key_type *kt = _find_keytype(keytype); if(kt == NULL) { - krb5_set_error_string(context, "key type %d not supported", keytype); + krb5_set_error_message(context, KRB5_PROG_KEYTYPE_NOSUPP, + "key type %d not supported", keytype); return KRB5_PROG_KEYTYPE_NOSUPP; } *string = strdup(kt->name); if(*string == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } return 0; @@ -1058,13 +1081,24 @@ krb5_string_to_keytype(krb5_context context, const char *string, krb5_keytype *keytype) { + char *end; int i; + for(i = 0; i < num_keytypes; i++) if(strcasecmp(keytypes[i]->name, string) == 0){ *keytype = keytypes[i]->type; return 0; } - krb5_set_error_string(context, "key type %s not supported", string); + + /* check if the enctype is a number */ + *keytype = strtol(string, &end, 0); + if(*end == '\0' && *keytype != 0) { + if (krb5_enctype_valid(context, *keytype) == 0) + return 0; + } + + krb5_set_error_message(context, KRB5_PROG_KEYTYPE_NOSUPP, + "key type %s not supported", string); return KRB5_PROG_KEYTYPE_NOSUPP; } @@ -1075,8 +1109,9 @@ krb5_enctype_keysize(krb5_context context, { struct encryption_type *et = _find_enctype(type); if(et == NULL) { - krb5_set_error_string(context, "encryption type %d not supported", - type); + krb5_set_error_message(context, KRB5_PROG_ETYPE_NOSUPP, + "encryption type %d not supported", + type); return KRB5_PROG_ETYPE_NOSUPP; } *keysize = et->keytype->size; @@ -1090,7 +1125,8 @@ krb5_enctype_keybits(krb5_context context, { struct encryption_type *et = _find_enctype(type); if(et == NULL) { - krb5_set_error_string(context, "encryption type %d not supported", + krb5_set_error_message(context, KRB5_PROG_ETYPE_NOSUPP, + "encryption type %d not supported", type); return KRB5_PROG_ETYPE_NOSUPP; } @@ -1106,8 +1142,9 @@ krb5_generate_random_keyblock(krb5_context context, krb5_error_code ret; struct encryption_type *et = _find_enctype(type); if(et == NULL) { - krb5_set_error_string(context, "encryption type %d not supported", - type); + krb5_set_error_message(context, KRB5_PROG_ETYPE_NOSUPP, + "encryption type %d not supported", + type); return KRB5_PROG_ETYPE_NOSUPP; } ret = krb5_data_alloc(&key->keyvalue, et->keytype->size); @@ -1136,7 +1173,7 @@ _key_schedule(krb5_context context, return 0; ALLOC(key->schedule, 1); if(key->schedule == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } ret = krb5_data_alloc(key->schedule, kt->schedule_size); @@ -1481,8 +1518,9 @@ krb5_hmac(krb5_context context, krb5_error_code ret; if (c == NULL) { - krb5_set_error_string (context, "checksum type %d not supported", - cktype); + krb5_set_error_message (context, KRB5_PROG_SUMTYPE_NOSUPP, + "checksum type %d not supported", + cktype); return KRB5_PROG_SUMTYPE_NOSUPP; } @@ -1797,7 +1835,7 @@ get_checksum_key(krb5_context context, *key = _new_derived_key(crypto, 0xff/* KRB5_KU_RFC1510_VARIANT */); if(*key == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } ret = krb5_copy_keyblock(context, crypto->key.key, &(*key)->key); @@ -1832,9 +1870,10 @@ create_checksum (krb5_context context, } keyed_checksum = (ct->flags & F_KEYED) != 0; if(keyed_checksum && crypto == NULL) { - krb5_set_error_string (context, "Checksum type %s is keyed " - "but no crypto context (key) was passed in", - ct->name); + krb5_set_error_message (context, KRB5_PROG_SUMTYPE_NOSUPP, + "Checksum type %s is keyed " + "but no crypto context (key) was passed in", + ct->name); return KRB5_PROG_SUMTYPE_NOSUPP; /* XXX */ } if(keyed_checksum) { @@ -1880,8 +1919,9 @@ krb5_create_checksum(krb5_context context, } if(ct == NULL) { - krb5_set_error_string (context, "checksum type %d not supported", - type); + krb5_set_error_message (context, KRB5_PROG_SUMTYPE_NOSUPP, + "checksum type %d not supported", + type); return KRB5_PROG_SUMTYPE_NOSUPP; } @@ -1911,7 +1951,8 @@ verify_checksum(krb5_context context, ct = _find_checksum(cksum->cksumtype); if (ct == NULL || (ct->flags & F_DISABLED)) { - krb5_set_error_string (context, "checksum type %d not supported", + krb5_set_error_message (context, KRB5_PROG_SUMTYPE_NOSUPP, + "checksum type %d not supported", cksum->cksumtype); return KRB5_PROG_SUMTYPE_NOSUPP; } @@ -1921,9 +1962,10 @@ verify_checksum(krb5_context context, } keyed_checksum = (ct->flags & F_KEYED) != 0; if(keyed_checksum && crypto == NULL) { - krb5_set_error_string (context, "Checksum type %s is keyed " - "but no crypto context (key) was passed in", - ct->name); + krb5_set_error_message (context, KRB5_PROG_SUMTYPE_NOSUPP, + "Checksum type %s is keyed " + "but no crypto context (key) was passed in", + ct->name); return KRB5_PROG_SUMTYPE_NOSUPP; /* XXX */ } if(keyed_checksum) @@ -1963,8 +2005,9 @@ krb5_verify_checksum(krb5_context context, ct = _find_checksum(cksum->cksumtype); if(ct == NULL) { - krb5_set_error_string (context, "checksum type %d not supported", - cksum->cksumtype); + krb5_set_error_message (context, KRB5_PROG_SUMTYPE_NOSUPP, + "checksum type %d not supported", + cksum->cksumtype); return KRB5_PROG_SUMTYPE_NOSUPP; } @@ -1992,7 +2035,8 @@ krb5_crypto_get_checksum_type(krb5_context context, } if (ct == NULL) { - krb5_set_error_string (context, "checksum type not found"); + krb5_set_error_message (context, KRB5_PROG_SUMTYPE_NOSUPP, + "checksum type not found"); return KRB5_PROG_SUMTYPE_NOSUPP; } @@ -2009,8 +2053,9 @@ krb5_checksumsize(krb5_context context, { struct checksum_type *ct = _find_checksum(type); if(ct == NULL) { - krb5_set_error_string (context, "checksum type %d not supported", - type); + krb5_set_error_message (context, KRB5_PROG_SUMTYPE_NOSUPP, + "checksum type %d not supported", + type); return KRB5_PROG_SUMTYPE_NOSUPP; } *size = ct->checksumsize; @@ -2024,8 +2069,9 @@ krb5_checksum_is_keyed(krb5_context context, struct checksum_type *ct = _find_checksum(type); if(ct == NULL) { if (context) - krb5_set_error_string (context, "checksum type %d not supported", - type); + krb5_set_error_message (context, KRB5_PROG_SUMTYPE_NOSUPP, + "checksum type %d not supported", + type); return KRB5_PROG_SUMTYPE_NOSUPP; } return ct->flags & F_KEYED; @@ -2038,8 +2084,9 @@ krb5_checksum_is_collision_proof(krb5_context context, struct checksum_type *ct = _find_checksum(type); if(ct == NULL) { if (context) - krb5_set_error_string (context, "checksum type %d not supported", - type); + krb5_set_error_message (context, KRB5_PROG_SUMTYPE_NOSUPP, + "checksum type %d not supported", + type); return KRB5_PROG_SUMTYPE_NOSUPP; } return ct->flags & F_CPROOF; @@ -2052,8 +2099,9 @@ krb5_checksum_disable(krb5_context context, struct checksum_type *ct = _find_checksum(type); if(ct == NULL) { if (context) - krb5_set_error_string (context, "checksum type %d not supported", - type); + krb5_set_error_message (context, KRB5_PROG_SUMTYPE_NOSUPP, + "checksum type %d not supported", + type); return KRB5_PROG_SUMTYPE_NOSUPP; } ct->flags |= F_DISABLED; @@ -2478,7 +2526,7 @@ AES_PRF(krb5_context context, result.cksumtype = ct->type; ret = krb5_data_alloc(&result.checksum, ct->checksumsize); if (ret) { - krb5_set_error_string(context, "out memory"); + krb5_set_error_message(context, ret, "out memory"); return ret; } @@ -2519,7 +2567,6 @@ AES_PRF(krb5_context context, static struct encryption_type enctype_null = { ETYPE_NULL, "null", - NULL, 1, 1, 0, @@ -2534,7 +2581,6 @@ static struct encryption_type enctype_null = { static struct encryption_type enctype_des_cbc_crc = { ETYPE_DES_CBC_CRC, "des-cbc-crc", - NULL, 8, 8, 8, @@ -2549,7 +2595,6 @@ static struct encryption_type enctype_des_cbc_crc = { static struct encryption_type enctype_des_cbc_md4 = { ETYPE_DES_CBC_MD4, "des-cbc-md4", - NULL, 8, 8, 8, @@ -2564,7 +2609,6 @@ static struct encryption_type enctype_des_cbc_md4 = { static struct encryption_type enctype_des_cbc_md5 = { ETYPE_DES_CBC_MD5, "des-cbc-md5", - NULL, 8, 8, 8, @@ -2579,7 +2623,6 @@ static struct encryption_type enctype_des_cbc_md5 = { static struct encryption_type enctype_arcfour_hmac_md5 = { ETYPE_ARCFOUR_HMAC_MD5, "arcfour-hmac-md5", - NULL, 1, 1, 8, @@ -2594,7 +2637,6 @@ static struct encryption_type enctype_arcfour_hmac_md5 = { static struct encryption_type enctype_des3_cbc_md5 = { ETYPE_DES3_CBC_MD5, "des3-cbc-md5", - NULL, 8, 8, 8, @@ -2609,7 +2651,6 @@ static struct encryption_type enctype_des3_cbc_md5 = { static struct encryption_type enctype_des3_cbc_sha1 = { ETYPE_DES3_CBC_SHA1, "des3-cbc-sha1", - NULL, 8, 8, 8, @@ -2624,7 +2665,6 @@ static struct encryption_type enctype_des3_cbc_sha1 = { static struct encryption_type enctype_old_des3_cbc_sha1 = { ETYPE_OLD_DES3_CBC_SHA1, "old-des3-cbc-sha1", - NULL, 8, 8, 8, @@ -2639,7 +2679,6 @@ static struct encryption_type enctype_old_des3_cbc_sha1 = { static struct encryption_type enctype_aes128_cts_hmac_sha1 = { ETYPE_AES128_CTS_HMAC_SHA1_96, "aes128-cts-hmac-sha1-96", - NULL, 16, 1, 16, @@ -2654,7 +2693,6 @@ static struct encryption_type enctype_aes128_cts_hmac_sha1 = { static struct encryption_type enctype_aes256_cts_hmac_sha1 = { ETYPE_AES256_CTS_HMAC_SHA1_96, "aes256-cts-hmac-sha1-96", - NULL, 16, 1, 16, @@ -2669,7 +2707,6 @@ static struct encryption_type enctype_aes256_cts_hmac_sha1 = { static struct encryption_type enctype_des_cbc_none = { ETYPE_DES_CBC_NONE, "des-cbc-none", - NULL, 8, 8, 0, @@ -2684,7 +2721,6 @@ static struct encryption_type enctype_des_cbc_none = { static struct encryption_type enctype_des_cfb64_none = { ETYPE_DES_CFB64_NONE, "des-cfb64-none", - NULL, 1, 1, 0, @@ -2699,7 +2735,6 @@ static struct encryption_type enctype_des_cfb64_none = { static struct encryption_type enctype_des_pcbc_none = { ETYPE_DES_PCBC_NONE, "des-pcbc-none", - NULL, 8, 8, 0, @@ -2714,7 +2749,6 @@ static struct encryption_type enctype_des_pcbc_none = { static struct encryption_type enctype_des3_cbc_none = { ETYPE_DES3_CBC_NONE, "des3-cbc-none", - NULL, 8, 8, 0, @@ -2766,14 +2800,15 @@ krb5_enctype_to_string(krb5_context context, struct encryption_type *e; e = _find_enctype(etype); if(e == NULL) { - krb5_set_error_string (context, "encryption type %d not supported", - etype); + krb5_set_error_message (context, KRB5_PROG_ETYPE_NOSUPP, + "encryption type %d not supported", + etype); *string = NULL; return KRB5_PROG_ETYPE_NOSUPP; } *string = strdup(e->name); if(*string == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } return 0; @@ -2790,43 +2825,9 @@ krb5_string_to_enctype(krb5_context context, *etype = etypes[i]->type; return 0; } - krb5_set_error_string (context, "encryption type %s not supported", - string); - return KRB5_PROG_ETYPE_NOSUPP; -} - -krb5_error_code KRB5_LIB_FUNCTION -_krb5_enctype_to_oid(krb5_context context, - krb5_enctype etype, - heim_oid *oid) -{ - struct encryption_type *et = _find_enctype(etype); - if(et == NULL) { - krb5_set_error_string (context, "encryption type %d not supported", - etype); - return KRB5_PROG_ETYPE_NOSUPP; - } - if(et->oid == NULL) { - krb5_set_error_string (context, "%s have not oid", et->name); - return KRB5_PROG_ETYPE_NOSUPP; - } - krb5_clear_error_string(context); - return der_copy_oid(et->oid, oid); -} - -krb5_error_code KRB5_LIB_FUNCTION -_krb5_oid_to_enctype(krb5_context context, - const heim_oid *oid, - krb5_enctype *etype) -{ - int i; - for(i = 0; i < num_etypes; i++) { - if(etypes[i]->oid && der_heim_oid_cmp(etypes[i]->oid, oid) == 0) { - *etype = etypes[i]->type; - return 0; - } - } - krb5_set_error_string(context, "enctype for oid not supported"); + krb5_set_error_message (context, KRB5_PROG_ETYPE_NOSUPP, + "encryption type %s not supported", + string); return KRB5_PROG_ETYPE_NOSUPP; } @@ -2837,7 +2838,8 @@ krb5_enctype_to_keytype(krb5_context context, { struct encryption_type *e = _find_enctype(etype); if(e == NULL) { - krb5_set_error_string (context, "encryption type %d not supported", + krb5_set_error_message (context, KRB5_PROG_ETYPE_NOSUPP, + "encryption type %d not supported", etype); return KRB5_PROG_ETYPE_NOSUPP; } @@ -2845,21 +2847,6 @@ krb5_enctype_to_keytype(krb5_context context, return 0; } -#if 0 -krb5_error_code KRB5_LIB_FUNCTION -krb5_keytype_to_enctype(krb5_context context, - krb5_keytype keytype, - krb5_enctype *etype) -{ - struct key_type *kt = _find_keytype(keytype); - krb5_warnx(context, "krb5_keytype_to_enctype(%u)", keytype); - if(kt == NULL) - return KRB5_PROG_KEYTYPE_NOSUPP; - *etype = kt->best_etype; - return 0; -} -#endif - krb5_error_code KRB5_LIB_FUNCTION krb5_keytype_to_enctypes (krb5_context context, krb5_keytype keytype, @@ -2877,7 +2864,7 @@ krb5_keytype_to_enctypes (krb5_context context, } ret = malloc(n * sizeof(*ret)); if (ret == NULL && n != 0) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } n = 0; @@ -2902,7 +2889,7 @@ krb5_keytype_to_enctypes_default (krb5_context context, unsigned *len, krb5_enctype **val) { - int i, n; + unsigned int i, n; krb5_enctype *ret; if (keytype != KEYTYPE_DES || context->etypes_des == NULL) @@ -2912,7 +2899,7 @@ krb5_keytype_to_enctypes_default (krb5_context context, ; ret = malloc (n * sizeof(*ret)); if (ret == NULL && n != 0) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } for (i = 0; i < n; ++i) @@ -2928,13 +2915,15 @@ krb5_enctype_valid(krb5_context context, { struct encryption_type *e = _find_enctype(etype); if(e == NULL) { - krb5_set_error_string (context, "encryption type %d not supported", - etype); + krb5_set_error_message (context, KRB5_PROG_ETYPE_NOSUPP, + "encryption type %d not supported", + etype); return KRB5_PROG_ETYPE_NOSUPP; } if (e->flags & F_DISABLED) { - krb5_set_error_string (context, "encryption type %s is disabled", - e->name); + krb5_set_error_message (context, KRB5_PROG_ETYPE_NOSUPP, + "encryption type %s is disabled", + e->name); return KRB5_PROG_ETYPE_NOSUPP; } return 0; @@ -2946,13 +2935,15 @@ krb5_cksumtype_valid(krb5_context context, { struct checksum_type *c = _find_checksum(ctype); if (c == NULL) { - krb5_set_error_string (context, "checksum type %d not supported", - ctype); + krb5_set_error_message (context, KRB5_PROG_SUMTYPE_NOSUPP, + "checksum type %d not supported", + ctype); return KRB5_PROG_SUMTYPE_NOSUPP; } if (c->flags & F_DISABLED) { - krb5_set_error_string (context, "checksum type %s is disabled", - c->name); + krb5_set_error_message (context, KRB5_PROG_SUMTYPE_NOSUPP, + "checksum type %s is disabled", + c->name); return KRB5_PROG_SUMTYPE_NOSUPP; } return 0; @@ -3010,7 +3001,7 @@ encrypt_internal_derived(krb5_context context, total_sz = block_sz + checksum_sz; p = calloc(1, total_sz); if(p == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } @@ -3077,7 +3068,7 @@ encrypt_internal(krb5_context context, block_sz = (sz + et->padsize - 1) &~ (et->padsize - 1); /* pad */ p = calloc(1, block_sz); if(p == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } @@ -3142,7 +3133,7 @@ encrypt_internal_special(krb5_context context, tmp = malloc (sz); if (tmp == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } p = tmp; @@ -3181,8 +3172,9 @@ decrypt_internal_derived(krb5_context context, checksum_sz = CHECKSUMSIZE(et->keyed_checksum); if (len < checksum_sz + et->confoundersize) { - krb5_set_error_string(context, "Encrypted data shorter then " - "checksum + confunder"); + krb5_set_error_message(context, KRB5_BAD_MSIZE, + "Encrypted data shorter then " + "checksum + confunder"); return KRB5_BAD_MSIZE; } @@ -3193,7 +3185,7 @@ decrypt_internal_derived(krb5_context context, p = malloc(len); if(len != 0 && p == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } memcpy(p, data, len); @@ -3238,7 +3230,7 @@ decrypt_internal_derived(krb5_context context, result->data = realloc(p, l); if(result->data == NULL && l != 0) { free(p); - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } result->length = l; @@ -3267,7 +3259,7 @@ decrypt_internal(krb5_context context, checksum_sz = CHECKSUMSIZE(et->checksum); p = malloc(len); if(len != 0 && p == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } memcpy(p, data, len); @@ -3303,7 +3295,7 @@ decrypt_internal(krb5_context context, result->data = realloc(p, l); if(result->data == NULL && l != 0) { free(p); - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } result->length = l; @@ -3332,7 +3324,7 @@ decrypt_internal_special(krb5_context context, p = malloc (len); if (p == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } memcpy(p, data, len); @@ -3347,7 +3339,7 @@ decrypt_internal_special(krb5_context context, result->data = realloc(p, sz); if(result->data == NULL && sz != 0) { free(p); - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } result->length = sz; @@ -3463,6 +3455,7 @@ seed_something(void) fd = open(seedfile, O_RDONLY); if (fd >= 0) { ssize_t ret; + rk_cloexec(fd); ret = read(fd, buf, sizeof(buf)); if (ret > 0) RAND_add(buf, ret, 0.0); @@ -3547,13 +3540,13 @@ derive_key(krb5_context context, nblocks = (kt->bits + et->blocksize * 8 - 1) / (et->blocksize * 8); k = malloc(nblocks * et->blocksize); if(k == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } ret = _krb5_n_fold(constant, len, k, et->blocksize); if (ret) { free(k); - krb5_set_error_string(context, "out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); return ret; } for(i = 0; i < nblocks; i++) { @@ -3570,7 +3563,7 @@ derive_key(krb5_context context, size_t res_len = (kt->bits + 7) / 8; if(len != 0 && c == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } memcpy(c, constant, len); @@ -3578,13 +3571,13 @@ derive_key(krb5_context context, k = malloc(res_len); if(res_len != 0 && k == NULL) { free(c); - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } ret = _krb5_n_fold(c, len, k, res_len); if (ret) { free(k); - krb5_set_error_string(context, "out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); return ret; } free(c); @@ -3600,10 +3593,10 @@ derive_key(krb5_context context, memcpy(key->key->keyvalue.data, k, key->key->keyvalue.length); break; default: - krb5_set_error_string(context, - "derive_key() called with unknown keytype (%u)", - kt->type); ret = KRB5_CRYPTO_INTERNAL; + krb5_set_error_message(context, ret, + "derive_key() called with unknown keytype (%u)", + kt->type); break; } if (key->schedule) { @@ -3645,8 +3638,9 @@ krb5_derive_key(krb5_context context, et = _find_enctype (etype); if (et == NULL) { - krb5_set_error_string(context, "encryption type %d not supported", - etype); + krb5_set_error_message(context, KRB5_PROG_ETYPE_NOSUPP, + "encryption type %d not supported", + etype); return KRB5_PROG_ETYPE_NOSUPP; } @@ -3679,7 +3673,7 @@ _get_derived_key(krb5_context context, } d = _new_derived_key(crypto, usage); if(d == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } krb5_copy_keyblock(context, crypto->key.key, &d->key); @@ -3699,7 +3693,7 @@ krb5_crypto_init(krb5_context context, krb5_error_code ret; ALLOC(*crypto, 1); if(*crypto == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } if(etype == ETYPE_NULL) @@ -3708,14 +3702,16 @@ krb5_crypto_init(krb5_context context, if((*crypto)->et == NULL || ((*crypto)->et->flags & F_DISABLED)) { free(*crypto); *crypto = NULL; - krb5_set_error_string (context, "encryption type %d not supported", - etype); + krb5_set_error_message (context, KRB5_PROG_ETYPE_NOSUPP, + "encryption type %d not supported", + etype); return KRB5_PROG_ETYPE_NOSUPP; } if((*crypto)->et->keytype->size != key->keyvalue.length) { free(*crypto); *crypto = NULL; - krb5_set_error_string (context, "encryption key has bad length"); + krb5_set_error_message (context, KRB5_BAD_KEYSIZE, + "encryption key has bad length"); return KRB5_BAD_KEYSIZE; } ret = krb5_copy_keyblock(context, key, &(*crypto)->key.key); @@ -3803,8 +3799,9 @@ krb5_enctype_disable(krb5_context context, struct encryption_type *et = _find_enctype(enctype); if(et == NULL) { if (context) - krb5_set_error_string (context, "encryption type %d not supported", - enctype); + krb5_set_error_message (context, KRB5_PROG_ETYPE_NOSUPP, + "encryption type %d not supported", + enctype); return KRB5_PROG_ETYPE_NOSUPP; } et->flags |= F_DISABLED; @@ -3825,15 +3822,17 @@ krb5_string_to_key_derived(krb5_context context, u_char *tmp; if(et == NULL) { - krb5_set_error_string (context, "encryption type %d not supported", - etype); + krb5_set_error_message (context, KRB5_PROG_ETYPE_NOSUPP, + "encryption type %d not supported", + etype); return KRB5_PROG_ETYPE_NOSUPP; } keylen = et->keytype->bits / 8; ALLOC(kd.key, 1); if(kd.key == NULL) { - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message (context, ENOMEM, + "malloc: out of memory"); return ENOMEM; } ret = krb5_data_alloc(&kd.key->keyvalue, et->keytype->size); @@ -3845,13 +3844,13 @@ krb5_string_to_key_derived(krb5_context context, tmp = malloc (keylen); if(tmp == NULL) { krb5_free_keyblock(context, kd.key); - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message (context, ENOMEM, "malloc: out of memory"); return ENOMEM; } ret = _krb5_n_fold(str, len, tmp, keylen); if (ret) { free(tmp); - krb5_set_error_string(context, "out of memory"); + krb5_set_error_message (context, ENOMEM, "malloc: out of memory"); return ret; } kd.schedule = NULL; @@ -3970,14 +3969,16 @@ krb5_random_to_key(krb5_context context, krb5_error_code ret; struct encryption_type *et = _find_enctype(type); if(et == NULL) { - krb5_set_error_string(context, "encryption type %d not supported", - type); + krb5_set_error_message(context, KRB5_PROG_ETYPE_NOSUPP, + "encryption type %d not supported", + type); return KRB5_PROG_ETYPE_NOSUPP; } if ((et->keytype->bits + 7) / 8 > size) { - krb5_set_error_string(context, "encryption key %s needs %d bytes " - "of random to make an encryption key out of it", - et->name, (int)et->keytype->size); + krb5_set_error_message(context, KRB5_PROG_ETYPE_NOSUPP, + "encryption key %s needs %d bytes " + "of random to make an encryption key out of it", + et->name, (int)et->keytype->size); return KRB5_PROG_ETYPE_NOSUPP; } ret = krb5_data_alloc(&key->keyvalue, et->keytype->size); @@ -4009,15 +4010,16 @@ _krb5_pk_octetstring2key(krb5_context context, unsigned char shaoutput[20]; if(et == NULL) { - krb5_set_error_string(context, "encryption type %d not supported", - type); + krb5_set_error_message(context, KRB5_PROG_ETYPE_NOSUPP, + "encryption type %d not supported", + type); return KRB5_PROG_ETYPE_NOSUPP; } keylen = (et->keytype->bits + 7) / 8; keydata = malloc(keylen); if (keydata == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } @@ -4050,6 +4052,182 @@ _krb5_pk_octetstring2key(krb5_context context, return ret; } +static krb5_error_code +encode_uvinfo(krb5_context context, krb5_const_principal p, krb5_data *data) +{ + KRB5PrincipalName pn; + krb5_error_code ret; + size_t size; + + pn.principalName = p->name; + pn.realm = p->realm; + + ASN1_MALLOC_ENCODE(KRB5PrincipalName, data->data, data->length, + &pn, &size, ret); + if (ret) { + krb5_data_zero(data); + krb5_set_error_message(context, ret, + "Failed to encode KRB5PrincipalName"); + return ret; + } + if (data->length != size) + krb5_abortx(context, "asn1 compiler internal error"); + return 0; +} + +static krb5_error_code +encode_otherinfo(krb5_context context, + const AlgorithmIdentifier *ai, + krb5_const_principal client, + krb5_const_principal server, + krb5_enctype enctype, + const krb5_data *as_req, + const krb5_data *pk_as_rep, + const Ticket *ticket, + krb5_data *other) +{ + PkinitSP80056AOtherInfo otherinfo; + PkinitSuppPubInfo pubinfo; + krb5_error_code ret; + krb5_data pub; + size_t size; + + krb5_data_zero(other); + memset(&otherinfo, 0, sizeof(otherinfo)); + memset(&pubinfo, 0, sizeof(pubinfo)); + + pubinfo.enctype = enctype; + pubinfo.as_REQ = *as_req; + pubinfo.pk_as_rep = *pk_as_rep; + pubinfo.ticket = *ticket; + ASN1_MALLOC_ENCODE(PkinitSuppPubInfo, pub.data, pub.length, + &pubinfo, &size, ret); + if (ret) { + krb5_set_error_message(context, ret, "out of memory"); + return ret; + } + if (pub.length != size) + krb5_abortx(context, "asn1 compiler internal error"); + + ret = encode_uvinfo(context, client, &otherinfo.partyUInfo); + if (ret) { + free(pub.data); + return ret; + } + ret = encode_uvinfo(context, server, &otherinfo.partyVInfo); + if (ret) { + free(otherinfo.partyUInfo.data); + free(pub.data); + return ret; + } + + otherinfo.algorithmID = *ai; + otherinfo.suppPubInfo = &pub; + + ASN1_MALLOC_ENCODE(PkinitSP80056AOtherInfo, other->data, other->length, + &otherinfo, &size, ret); + free(otherinfo.partyUInfo.data); + free(otherinfo.partyVInfo.data); + free(pub.data); + if (ret) { + krb5_set_error_message(context, ret, "out of memory"); + return ret; + } + if (other->length != size) + krb5_abortx(context, "asn1 compiler internal error"); + + return 0; +} + +krb5_error_code +_krb5_pk_kdf(krb5_context context, + const struct AlgorithmIdentifier *ai, + const void *dhdata, + size_t dhsize, + krb5_const_principal client, + krb5_const_principal server, + krb5_enctype enctype, + const krb5_data *as_req, + const krb5_data *pk_as_rep, + const Ticket *ticket, + krb5_keyblock *key) +{ + struct encryption_type *et; + krb5_error_code ret; + krb5_data other; + size_t keylen, offset; + uint32_t counter; + unsigned char *keydata; + unsigned char shaoutput[20]; + + if (der_heim_oid_cmp(oid_id_pkinit_kdf_ah_sha1(), &ai->algorithm) != 0) { + krb5_set_error_message(context, KRB5_PROG_ETYPE_NOSUPP, + "kdf not supported"); + return KRB5_PROG_ETYPE_NOSUPP; + } + if (ai->parameters != NULL && + (ai->parameters->length != 2 || + memcmp(ai->parameters->data, "\x05\x00", 2) != 0)) + { + krb5_set_error_message(context, KRB5_PROG_ETYPE_NOSUPP, + "kdf params not NULL or the NULL-type"); + return KRB5_PROG_ETYPE_NOSUPP; + } + + et = _find_enctype(enctype); + if(et == NULL) { + krb5_set_error_message(context, KRB5_PROG_ETYPE_NOSUPP, + "encryption type %d not supported", + enctype); + return KRB5_PROG_ETYPE_NOSUPP; + } + keylen = (et->keytype->bits + 7) / 8; + + keydata = malloc(keylen); + if (keydata == NULL) { + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); + return ENOMEM; + } + + ret = encode_otherinfo(context, ai, client, server, + enctype, as_req, pk_as_rep, ticket, &other); + if (ret) { + free(keydata); + return ret; + } + + offset = 0; + counter = 1; + do { + unsigned char cdata[4]; + SHA_CTX m; + + SHA1_Init(&m); + _krb5_put_int(cdata, counter, 4); + SHA1_Update(&m, cdata, 4); + SHA1_Update(&m, dhdata, dhsize); + SHA1_Update(&m, other.data, other.length); + SHA1_Final(shaoutput, &m); + + memcpy((unsigned char *)keydata + offset, + shaoutput, + min(keylen - offset, sizeof(shaoutput))); + + offset += sizeof(shaoutput); + counter++; + } while(offset < keylen); + memset(shaoutput, 0, sizeof(shaoutput)); + + free(other.data); + + ret = krb5_random_to_key(context, enctype, keydata, keylen, key); + memset(keydata, 0, sizeof(keylen)); + free(keydata); + + return ret; +} + + krb5_error_code KRB5_LIB_FUNCTION krb5_crypto_prf_length(krb5_context context, krb5_enctype type, @@ -4058,8 +4236,9 @@ krb5_crypto_prf_length(krb5_context context, struct encryption_type *et = _find_enctype(type); if(et == NULL || et->prf_length == 0) { - krb5_set_error_string(context, "encryption type %d not supported", - type); + krb5_set_error_message(context, KRB5_PROG_ETYPE_NOSUPP, + "encryption type %d not supported", + type); return KRB5_PROG_ETYPE_NOSUPP; } @@ -4078,8 +4257,9 @@ krb5_crypto_prf(krb5_context context, krb5_data_zero(output); if(et->prf == NULL) { - krb5_set_error_string(context, "kerberos prf for %s not supported", - et->name); + krb5_set_error_message(context, KRB5_PROG_ETYPE_NOSUPP, + "kerberos prf for %s not supported", + et->name); return KRB5_PROG_ETYPE_NOSUPP; } diff --git a/source4/heimdal/lib/krb5/data.c b/source4/heimdal/lib/krb5/data.c index eda1a8b259..2b78bfb32b 100644 --- a/source4/heimdal/lib/krb5/data.c +++ b/source4/heimdal/lib/krb5/data.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: data.c 22064 2007-11-11 16:28:14Z lha $"); +RCSID("$Id: data.c 23280 2008-06-23 03:26:18Z lha $"); /** * Reset the (potentially uninitalized) krb5_data structure. @@ -192,7 +192,7 @@ krb5_copy_data(krb5_context context, krb5_error_code ret; ALLOC(*outdata, 1); if(*outdata == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } ret = der_copy_octet_string(indata, *outdata); diff --git a/source4/heimdal/lib/krb5/error_string.c b/source4/heimdal/lib/krb5/error_string.c index ff6e98a3dc..6679b76749 100644 --- a/source4/heimdal/lib/krb5/error_string.c +++ b/source4/heimdal/lib/krb5/error_string.c @@ -33,59 +33,71 @@ #include "krb5_locl.h" -RCSID("$Id: error_string.c 22142 2007-12-04 16:56:02Z lha $"); +RCSID("$Id: error_string.c 23274 2008-06-23 03:25:08Z lha $"); #undef __attribute__ #define __attribute__(X) void KRB5_LIB_FUNCTION -krb5_free_error_string(krb5_context context, char *str) -{ - HEIMDAL_MUTEX_lock(context->mutex); - if (str != context->error_buf) - free(str); - HEIMDAL_MUTEX_unlock(context->mutex); -} - -void KRB5_LIB_FUNCTION krb5_clear_error_string(krb5_context context) { HEIMDAL_MUTEX_lock(context->mutex); - if (context->error_string != NULL - && context->error_string != context->error_buf) + if (context->error_string) free(context->error_string); + context->error_code = 0; context->error_string = NULL; HEIMDAL_MUTEX_unlock(context->mutex); } -krb5_error_code KRB5_LIB_FUNCTION -krb5_set_error_string(krb5_context context, const char *fmt, ...) - __attribute__((format (printf, 2, 3))) +/** + * Set the context full error string for a specific error code. + * + * @param context Kerberos 5 context + * @param ret The error code + * @param fmt Error string for the error code + * @param ... printf(3) style parameters. + * + * @ingroup krb5_error + */ + +void KRB5_LIB_FUNCTION +krb5_set_error_message(krb5_context context, krb5_error_code ret, + const char *fmt, ...) + __attribute__ ((format (printf, 3, 4))) { - krb5_error_code ret; va_list ap; va_start(ap, fmt); - ret = krb5_vset_error_string (context, fmt, ap); + krb5_vset_error_message (context, ret, fmt, ap); va_end(ap); - return ret; } -krb5_error_code KRB5_LIB_FUNCTION -krb5_vset_error_string(krb5_context context, const char *fmt, va_list args) - __attribute__ ((format (printf, 2, 0))) +/** + * Set the context full error string for a specific error code. + * + * @param context Kerberos 5 context + * @param ret The error code + * @param fmt Error string for the error code + * @param args printf(3) style parameters. + * + * @ingroup krb5_error + */ + + +void KRB5_LIB_FUNCTION +krb5_vset_error_message (krb5_context context, krb5_error_code ret, + const char *fmt, va_list args) + __attribute__ ((format (printf, 3, 0))) { + krb5_clear_error_string(context); HEIMDAL_MUTEX_lock(context->mutex); + context->error_code = ret; vasprintf(&context->error_string, fmt, args); - if(context->error_string == NULL) { - vsnprintf (context->error_buf, sizeof(context->error_buf), fmt, args); - context->error_string = context->error_buf; - } HEIMDAL_MUTEX_unlock(context->mutex); - return 0; } + /** * Return the error message in context. On error or no error string, * the function returns NULL. @@ -93,7 +105,7 @@ krb5_vset_error_string(krb5_context context, const char *fmt, va_list args) * @param context Kerberos 5 context * * @return an error string, needs to be freed with - * krb5_free_error_string(). The functions return NULL on error. + * krb5_free_error_message(). The functions return NULL on error. * * @ingroup krb5_error */ @@ -121,35 +133,99 @@ krb5_have_error_string(krb5_context context) } /** - * Return the error message for `code' in context. On error the - * function returns NULL. + * Return the error message for `code' in context. On memory + * allocation error the function returns NULL. * * @param context Kerberos 5 context * @param code Error code related to the error * * @return an error string, needs to be freed with - * krb5_free_error_string(). The functions return NULL on error. + * krb5_free_error_message(). The functions return NULL on error. * * @ingroup krb5_error */ -char * KRB5_LIB_FUNCTION +const char * KRB5_LIB_FUNCTION krb5_get_error_message(krb5_context context, krb5_error_code code) { const char *cstr; char *str; - str = krb5_get_error_string(context); - if (str) - return str; + HEIMDAL_MUTEX_lock(context->mutex); + if (context->error_string && + (code == context->error_code || context->error_code == 0)) + { + str = strdup(context->error_string); + if (str) { + HEIMDAL_MUTEX_unlock(context->mutex); + return str; + } + } + HEIMDAL_MUTEX_unlock(context->mutex); cstr = krb5_get_err_text(context, code); if (cstr) return strdup(cstr); - if (asprintf(&str, "<unknown error: %d>", code) == -1) + if (asprintf(&str, "<unknown error: %d>", (int)code) == -1) return NULL; return str; } + +/** + * Free the error message returned by krb5_get_error_message(). + * + * @param context Kerberos context + * @param msg error message to free, returned byg + * krb5_get_error_message(). + * + * @ingroup krb5_error + */ + +void KRB5_LIB_FUNCTION +krb5_free_error_message(krb5_context context, const char *msg) +{ + free(rk_UNCONST(msg)); +} + +#ifndef HEIMDAL_SMALLER + +/** + * Free the error message returned by krb5_get_error_string(), + * deprecated, use krb5_free_error_message(). + * + * @param context Kerberos context + * @param msg error message to free + * + * @ingroup krb5_error + */ + +void KRB5_LIB_FUNCTION __attribute__((deprecated)) +krb5_free_error_string(krb5_context context, char *str) +{ + krb5_free_error_message(context, str); +} + +krb5_error_code KRB5_LIB_FUNCTION +krb5_set_error_string(krb5_context context, const char *fmt, ...) + __attribute__((format (printf, 2, 3))) __attribute__((deprecated)) +{ + va_list ap; + + va_start(ap, fmt); + krb5_vset_error_message (context, 0, fmt, ap); + va_end(ap); + return 0; +} + +krb5_error_code KRB5_LIB_FUNCTION +krb5_vset_error_string(krb5_context context, const char *fmt, va_list args) + __attribute__ ((format (printf, 2, 0))) __attribute__((deprecated)) +{ + krb5_vset_error_message(context, 0, fmt, args); + return 0; +} + +#endif /* !HEIMDAL_SMALLER */ diff --git a/source4/heimdal/lib/krb5/expand_hostname.c b/source4/heimdal/lib/krb5/expand_hostname.c index 28e39afb42..d06d576432 100644 --- a/source4/heimdal/lib/krb5/expand_hostname.c +++ b/source4/heimdal/lib/krb5/expand_hostname.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: expand_hostname.c 22229 2007-12-08 21:40:59Z lha $"); +RCSID("$Id: expand_hostname.c 23280 2008-06-23 03:26:18Z lha $"); static krb5_error_code copy_hostname(krb5_context context, @@ -42,7 +42,7 @@ copy_hostname(krb5_context context, { *new_hostname = strdup (orig_hostname); if (*new_hostname == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } strlwr (*new_hostname); @@ -76,7 +76,8 @@ krb5_expand_hostname (krb5_context context, *new_hostname = strdup (a->ai_canonname); freeaddrinfo (ai); if (*new_hostname == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, + "malloc: out of memory"); return ENOMEM; } else { return 0; diff --git a/source4/heimdal/lib/krb5/fcache.c b/source4/heimdal/lib/krb5/fcache.c index 484df059ab..8951bdb24e 100644 --- a/source4/heimdal/lib/krb5/fcache.c +++ b/source4/heimdal/lib/krb5/fcache.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: fcache.c 22517 2008-01-24 11:45:51Z lha $"); +RCSID("$Id: fcache.c 23444 2008-07-27 12:07:47Z lha $"); typedef struct krb5_fcache{ char *filename; @@ -93,12 +93,12 @@ _krb5_xlock(krb5_context context, int fd, krb5_boolean exclusive, ret = 0; break; case EAGAIN: - krb5_set_error_string(context, "timed out locking cache file %s", - filename); + krb5_set_error_message(context, ret, "timed out locking cache file %s", + filename); break; default: - krb5_set_error_string(context, "error locking cache file %s: %s", - filename, strerror(ret)); + krb5_set_error_message(context, ret, "error locking cache file %s: %s", + filename, strerror(ret)); break; } return ret; @@ -127,14 +127,40 @@ _krb5_xunlock(krb5_context context, int fd) ret = 0; break; default: - krb5_set_error_string(context, - "Failed to unlock file: %s", strerror(ret)); + krb5_set_error_message(context, ret, + "Failed to unlock file: %s", + strerror(ret)); break; } return ret; } static krb5_error_code +write_storage(krb5_context context, krb5_storage *sp, int fd) +{ + krb5_error_code ret; + krb5_data data; + ssize_t sret; + + ret = krb5_storage_to_data(sp, &data); + if (ret) { + krb5_set_error_message(context, ret, "malloc: out of memory"); + return ret; + } + sret = write(fd, data.data, data.length); + ret = (sret != data.length); + krb5_data_free(&data); + if (ret) { + ret = errno; + krb5_set_error_message(context, ret, + "Failed to write FILE credential data"); + return ret; + } + return 0; +} + + +static krb5_error_code fcc_lock(krb5_context context, krb5_ccache id, int fd, krb5_boolean exclusive) { @@ -153,13 +179,15 @@ fcc_resolve(krb5_context context, krb5_ccache *id, const char *res) krb5_fcache *f; f = malloc(sizeof(*f)); if(f == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, KRB5_CC_NOMEM, + "malloc: out of memory"); return KRB5_CC_NOMEM; } f->filename = strdup(res); if(f->filename == NULL){ free(f); - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, KRB5_CC_NOMEM, + "malloc: out of memory"); return KRB5_CC_NOMEM; } f->version = 0; @@ -203,7 +231,7 @@ scrub_file (int fd) */ static krb5_error_code -erase_file(const char *filename) +erase_file(krb5_context context, const char *filename) { int fd; struct stat sb1, sb2; @@ -220,12 +248,20 @@ erase_file(const char *filename) else return errno; } + rk_cloexec(fd); + ret = _krb5_xlock(context, fd, 1, filename); + if (ret) { + close(fd); + return ret; + } if (unlink(filename) < 0) { + _krb5_xunlock(context, fd); close (fd); return errno; } ret = fstat (fd, &sb2); if (ret < 0) { + _krb5_xunlock(context, fd); close (fd); return errno; } @@ -233,6 +269,7 @@ erase_file(const char *filename) /* check if someone was playing with symlinks */ if (sb1.st_dev != sb2.st_dev || sb1.st_ino != sb2.st_ino) { + _krb5_xunlock(context, fd); close (fd); return EPERM; } @@ -240,11 +277,18 @@ erase_file(const char *filename) /* there are still hard links to this file */ if (sb2.st_nlink != 0) { + _krb5_xunlock(context, fd); close (fd); return 0; } ret = scrub_file (fd); + if (ret) { + _krb5_xunlock(context, fd); + close(fd); + return ret; + } + ret = _krb5_xunlock(context, fd); close (fd); return ret; } @@ -258,19 +302,21 @@ fcc_gen_new(krb5_context context, krb5_ccache *id) f = malloc(sizeof(*f)); if(f == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, KRB5_CC_NOMEM, + "malloc: out of memory"); return KRB5_CC_NOMEM; } asprintf (&file, "%sXXXXXX", KRB5_DEFAULT_CCFILE_ROOT); if(file == NULL) { free(f); - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, KRB5_CC_NOMEM, + "malloc: out of memory"); return KRB5_CC_NOMEM; } fd = mkstemp(file); if(fd < 0) { int ret = errno; - krb5_set_error_string(context, "mkstemp %s", file); + krb5_set_error_message(context, ret, "mkstemp %s", file); free(f); free(file); return ret; @@ -323,11 +369,12 @@ fcc_open(krb5_context context, fd = open(filename, flags, mode); if(fd < 0) { ret = errno; - krb5_set_error_string(context, "open(%s): %s", filename, - strerror(ret)); + krb5_set_error_message(context, ret, "open(%s): %s", filename, + strerror(ret)); return ret; } - + rk_cloexec(fd); + if((ret = fcc_lock(context, id, fd, exclusive)) != 0) { close(fd); return ret; @@ -353,7 +400,7 @@ fcc_initialize(krb5_context context, return ret; { krb5_storage *sp; - sp = krb5_storage_from_fd(fd); + sp = krb5_storage_emem(); krb5_storage_set_eof_code(sp, KRB5_CC_END); if(context->fcache_vno != 0) f->version = context->fcache_vno; @@ -376,14 +423,16 @@ fcc_initialize(krb5_context context, } ret |= krb5_store_principal(sp, primary_principal); + ret |= write_storage(context, sp, fd); + krb5_storage_free(sp); } fcc_unlock(context, fd); if (close(fd) < 0) if (ret == 0) { ret = errno; - krb5_set_error_string (context, "close %s: %s", - FILENAME(id), strerror(ret)); + krb5_set_error_message (context, ret, "close %s: %s", + FILENAME(id), strerror(ret)); } return ret; } @@ -401,7 +450,7 @@ static krb5_error_code fcc_destroy(krb5_context context, krb5_ccache id) { - erase_file(FILENAME(id)); + erase_file(context, FILENAME(id)); return 0; } @@ -418,7 +467,8 @@ fcc_store_cred(krb5_context context, return ret; { krb5_storage *sp; - sp = krb5_storage_from_fd(fd); + + sp = krb5_storage_emem(); krb5_storage_set_eof_code(sp, KRB5_CC_END); storage_set_flags(context, sp, FCACHE(id)->version); if (!krb5_config_get_bool_default(context, NULL, TRUE, @@ -427,15 +477,18 @@ fcc_store_cred(krb5_context context, NULL)) krb5_storage_set_flags(sp, KRB5_STORAGE_CREDS_FLAGS_WRONG_BITORDER); ret = krb5_store_creds(sp, creds); + if (ret == 0) + ret = write_storage(context, sp, fd); krb5_storage_free(sp); } fcc_unlock(context, fd); - if (close(fd) < 0) + if (close(fd) < 0) { if (ret == 0) { ret = errno; - krb5_set_error_string (context, "close %s: %s", - FILENAME(id), strerror(ret)); + krb5_set_error_message (context, ret, "close %s: %s", + FILENAME(id), strerror(ret)); } + } return ret; } @@ -464,25 +517,27 @@ init_fcc (krb5_context context, ret = krb5_ret_int8(sp, &pvno); if(ret != 0) { if(ret == KRB5_CC_END) { - krb5_set_error_string(context, "Empty credential cache file: %s", - FILENAME(id)); ret = ENOENT; + krb5_set_error_message(context, ret, + "Empty credential cache file: %s", + FILENAME(id)); } else - krb5_set_error_string(context, "Error reading pvno in " - "cache file: %s", FILENAME(id)); + krb5_set_error_message(context, ret, "Error reading pvno in " + "cache file: %s", FILENAME(id)); goto out; } if(pvno != 5) { - krb5_set_error_string(context, "Bad version number in credential " - "cache file: %s", FILENAME(id)); ret = KRB5_CCACHE_BADVNO; + krb5_set_error_message(context, ret, "Bad version number in " + "credential cache file: %s", + FILENAME(id)); goto out; } ret = krb5_ret_int8(sp, &tag); /* should not be host byte order */ if(ret != 0) { - krb5_set_error_string(context, "Error reading tag in " - "cache file: %s", FILENAME(id)); ret = KRB5_CC_FORMAT; + krb5_set_error_message(context, ret, "Error reading tag in " + "cache file: %s", FILENAME(id)); goto out; } FCACHE(id)->version = tag; @@ -494,8 +549,9 @@ init_fcc (krb5_context context, ret = krb5_ret_int16 (sp, &length); if(ret) { ret = KRB5_CC_FORMAT; - krb5_set_error_string(context, "Error reading tag length in " - "cache file: %s", FILENAME(id)); + krb5_set_error_message(context, ret, + "Error reading tag length in " + "cache file: %s", FILENAME(id)); goto out; } while(length > 0) { @@ -505,32 +561,32 @@ init_fcc (krb5_context context, ret = krb5_ret_int16 (sp, &dtag); if(ret) { - krb5_set_error_string(context, "Error reading dtag in " - "cache file: %s", FILENAME(id)); ret = KRB5_CC_FORMAT; + krb5_set_error_message(context, ret, "Error reading dtag in " + "cache file: %s", FILENAME(id)); goto out; } ret = krb5_ret_int16 (sp, &data_len); if(ret) { - krb5_set_error_string(context, "Error reading dlength in " - "cache file: %s", FILENAME(id)); ret = KRB5_CC_FORMAT; + krb5_set_error_message(context, ret, "Error reading dlength in " + "cache file: %s", FILENAME(id)); goto out; } switch (dtag) { case FCC_TAG_DELTATIME : ret = krb5_ret_int32 (sp, &context->kdc_sec_offset); if(ret) { - krb5_set_error_string(context, "Error reading kdc_sec in " - "cache file: %s", FILENAME(id)); ret = KRB5_CC_FORMAT; + krb5_set_error_message(context, ret, "Error reading kdc_sec in " + "cache file: %s", FILENAME(id)); goto out; } ret = krb5_ret_int32 (sp, &context->kdc_usec_offset); if(ret) { - krb5_set_error_string(context, "Error reading kdc_usec in " - "cache file: %s", FILENAME(id)); ret = KRB5_CC_FORMAT; + krb5_set_error_message(context, ret, "Error reading kdc_usec in " + "cache file: %s", FILENAME(id)); goto out; } break; @@ -538,10 +594,11 @@ init_fcc (krb5_context context, for (i = 0; i < data_len; ++i) { ret = krb5_ret_int8 (sp, &dummy); if(ret) { - krb5_set_error_string(context, "Error reading unknown " - "tag in cache file: %s", - FILENAME(id)); ret = KRB5_CC_FORMAT; + krb5_set_error_message(context, ret, + "Error reading unknown " + "tag in cache file: %s", + FILENAME(id)); goto out; } } @@ -557,9 +614,9 @@ init_fcc (krb5_context context, break; default : ret = KRB5_CCACHE_BADVNO; - krb5_set_error_string(context, "Unknown version number (%d) in " - "credential cache file: %s", - (int)tag, FILENAME(id)); + krb5_set_error_message(context, ret, "Unknown version number (%d) in " + "credential cache file: %s", + (int)tag, FILENAME(id)); goto out; } *ret_sp = sp; @@ -610,7 +667,7 @@ fcc_get_first (krb5_context context, *cursor = malloc(sizeof(struct fcc_cursor)); if (*cursor == NULL) { - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } memset(*cursor, 0, sizeof(struct fcc_cursor)); @@ -670,7 +727,7 @@ fcc_remove_cred(krb5_context context, krb5_creds *cred) { krb5_error_code ret; - krb5_ccache copy; + krb5_ccache copy, newfile; ret = krb5_cc_gen_new(context, &krb5_mcc_ops, ©); if (ret) @@ -688,12 +745,20 @@ fcc_remove_cred(krb5_context context, return ret; } - fcc_destroy(context, id); + ret = krb5_cc_gen_new(context, &krb5_fcc_ops, &newfile); + if (ret) { + krb5_cc_destroy(context, copy); + return ret; + } - ret = krb5_cc_copy_cache(context, copy, id); + ret = krb5_cc_copy_cache(context, copy, newfile); krb5_cc_destroy(context, copy); + if (ret) { + krb5_cc_destroy(context, newfile); + return ret; + } - return ret; + return krb5_cc_move(context, newfile, id); } static krb5_error_code @@ -704,7 +769,7 @@ fcc_set_flags(krb5_context context, return 0; /* XXX */ } -static krb5_error_code +static int fcc_get_version(krb5_context context, krb5_ccache id) { @@ -722,7 +787,7 @@ fcc_get_cache_first(krb5_context context, krb5_cc_cursor *cursor) iter = calloc(1, sizeof(*iter)); if (iter == NULL) { - krb5_set_error_string(context, "malloc - out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } iter->first = 1; @@ -775,10 +840,10 @@ fcc_move(krb5_context context, krb5_ccache from, krb5_ccache to) ret = rename(FILENAME(from), FILENAME(to)); if (ret && errno != EXDEV) { ret = errno; - krb5_set_error_string(context, - "Rename of file from %s to %s failed: %s", - FILENAME(from), FILENAME(to), - strerror(ret)); + krb5_set_error_message(context, ret, + "Rename of file from %s to %s failed: %s", + FILENAME(from), FILENAME(to), + strerror(ret)); return ret; } else if (ret && errno == EXDEV) { /* make a copy and delete the orignal */ @@ -801,21 +866,19 @@ fcc_move(krb5_context context, krb5_ccache from, krb5_ccache to) sz2 = write(fd2, buf, sz1); if (sz1 != sz2) { ret = EIO; - krb5_set_error_string(context, - "Failed to write data from one file " - "credential cache to the other"); + krb5_set_error_message(context, ret, + "Failed to write data from one file " + "credential cache to the other"); goto out2; } } if (sz1 < 0) { ret = EIO; - krb5_set_error_string(context, - "Failed to read data from one file " - "credential cache to the other"); + krb5_set_error_message(context, ret, + "Failed to read data from one file " + "credential cache to the other"); goto out2; } - erase_file(FILENAME(from)); - out2: fcc_unlock(context, fd2); close(fd2); @@ -824,8 +887,10 @@ fcc_move(krb5_context context, krb5_ccache from, krb5_ccache to) fcc_unlock(context, fd1); close(fd1); + erase_file(context, FILENAME(from)); + if (ret) { - erase_file(FILENAME(to)); + erase_file(context, FILENAME(to)); return ret; } } @@ -856,7 +921,8 @@ fcc_default_name(krb5_context context, char **str) * @ingroup krb5_ccache */ -const krb5_cc_ops krb5_fcc_ops = { +KRB5_LIB_VARIABLE const krb5_cc_ops krb5_fcc_ops = { + KRB5_CC_OPS_VERSION, "FILE", fcc_get_name, fcc_resolve, diff --git a/source4/heimdal/lib/krb5/generate_subkey.c b/source4/heimdal/lib/krb5/generate_subkey.c index fb99cbbf3f..fb7efbcd29 100644 --- a/source4/heimdal/lib/krb5/generate_subkey.c +++ b/source4/heimdal/lib/krb5/generate_subkey.c @@ -33,7 +33,7 @@ #include <krb5_locl.h> -RCSID("$Id: generate_subkey.c 14455 2005-01-05 02:39:21Z lukeh $"); +RCSID("$Id: generate_subkey.c 23280 2008-06-23 03:26:18Z lha $"); krb5_error_code KRB5_LIB_FUNCTION krb5_generate_subkey(krb5_context context, @@ -53,7 +53,7 @@ krb5_generate_subkey_extended(krb5_context context, ALLOC(*subkey, 1); if (*subkey == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } diff --git a/source4/heimdal/lib/krb5/get_cred.c b/source4/heimdal/lib/krb5/get_cred.c index fc78945c63..268550b229 100644 --- a/source4/heimdal/lib/krb5/get_cred.c +++ b/source4/heimdal/lib/krb5/get_cred.c @@ -1,39 +1,39 @@ /* - * Copyright (c) 1997 - 2007 Kungliga Tekniska Högskolan - * (Royal Institute of Technology, Stockholm, Sweden). - * All rights reserved. + * Copyright (c) 1997 - 2008 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: + * 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. + * 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. + * 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. + * 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. + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. */ #include <krb5_locl.h> -RCSID("$Id: get_cred.c 22530 2008-01-27 11:48:16Z lha $"); +RCSID("$Id: get_cred.c 23280 2008-06-23 03:26:18Z lha $"); /* * Take the `body' and encode it into `padata' using the credentials @@ -41,12 +41,11 @@ RCSID("$Id: get_cred.c 22530 2008-01-27 11:48:16Z lha $"); */ static krb5_error_code -make_pa_tgs_req(krb5_context context, +make_pa_tgs_req(krb5_context context, krb5_auth_context ac, KDC_REQ_BODY *body, PA_DATA *padata, - krb5_creds *creds, - krb5_key_usage usage) + krb5_creds *creds) { u_char *buf; size_t buf_size; @@ -65,8 +64,7 @@ make_pa_tgs_req(krb5_context context, ret = _krb5_mk_req_internal(context, &ac, 0, &in_data, creds, &padata->padata_value, KRB5_KU_TGS_REQ_AUTH_CKSUM, - usage - /* KRB5_KU_TGS_REQ_AUTH */); + KRB5_KU_TGS_REQ_AUTH); out: free (buf); if(ret) @@ -101,7 +99,7 @@ set_auth_data (krb5_context context, ALLOC(req_body->enc_authorization_data, 1); if (req_body->enc_authorization_data == NULL) { free (buf); - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } ret = krb5_crypto_init(context, key, 0, &crypto); @@ -111,9 +109,9 @@ set_auth_data (krb5_context context, req_body->enc_authorization_data = NULL; return ret; } - krb5_encrypt_EncryptedData(context, + krb5_encrypt_EncryptedData(context, crypto, - KRB5_KU_TGS_REQ_AUTH_DAT_SUBKEY, + KRB5_KU_TGS_REQ_AUTH_DAT_SUBKEY, /* KRB5_KU_TGS_REQ_AUTH_DAT_SESSION? */ buf, len, @@ -125,7 +123,7 @@ set_auth_data (krb5_context context, req_body->enc_authorization_data = NULL; } return 0; -} +} /* * Create a tgs-req in `t' with `addresses', `flags', `second_ticket' @@ -144,8 +142,7 @@ init_tgs_req (krb5_context context, unsigned nonce, const METHOD_DATA *padata, krb5_keyblock **subkey, - TGS_REQ *t, - krb5_key_usage usage) + TGS_REQ *t) { krb5_error_code ret = 0; @@ -156,14 +153,14 @@ init_tgs_req (krb5_context context, ALLOC_SEQ(&t->req_body.etype, 1); if(t->req_body.etype.val == NULL) { ret = ENOMEM; - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); goto fail; } t->req_body.etype.val[0] = in_creds->session.keytype; } else { - ret = krb5_init_etype(context, - &t->req_body.etype.len, - &t->req_body.etype.val, + ret = krb5_init_etype(context, + &t->req_body.etype.len, + &t->req_body.etype.val, NULL); } if (ret) @@ -176,7 +173,7 @@ init_tgs_req (krb5_context context, ALLOC(t->req_body.sname, 1); if (t->req_body.sname == NULL) { ret = ENOMEM; - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); goto fail; } @@ -192,39 +189,39 @@ init_tgs_req (krb5_context context, ALLOC(t->req_body.till, 1); if(t->req_body.till == NULL){ ret = ENOMEM; - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); goto fail; } *t->req_body.till = in_creds->times.endtime; - + t->req_body.nonce = nonce; if(second_ticket){ ALLOC(t->req_body.additional_tickets, 1); if (t->req_body.additional_tickets == NULL) { ret = ENOMEM; - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); goto fail; } ALLOC_SEQ(t->req_body.additional_tickets, 1); if (t->req_body.additional_tickets->val == NULL) { ret = ENOMEM; - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); goto fail; } - ret = copy_Ticket(second_ticket, t->req_body.additional_tickets->val); + ret = copy_Ticket(second_ticket, t->req_body.additional_tickets->val); if (ret) goto fail; } ALLOC(t->padata, 1); if (t->padata == NULL) { ret = ENOMEM; - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); goto fail; } ALLOC_SEQ(t->padata, 1 + padata->len); if (t->padata->val == NULL) { ret = ENOMEM; - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); goto fail; } { @@ -232,7 +229,7 @@ init_tgs_req (krb5_context context, for (i = 0; i < padata->len; i++) { ret = copy_PA_DATA(&padata->val[i], &t->padata->val[i + 1]); if (ret) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); goto fail; } } @@ -278,10 +275,9 @@ init_tgs_req (krb5_context context, ret = make_pa_tgs_req(context, ac, - &t->req_body, + &t->req_body, &t->padata->val[0], - krbtgt, - usage); + krbtgt); if(ret) { if (key) krb5_free_keyblock (context, key); @@ -315,7 +311,7 @@ _krb5_get_krbtgt(krb5_context context, if (ret) return ret; - ret = krb5_make_principal(context, + ret = krb5_make_principal(context, &tmp_cred.server, realm, KRB5_TGS_NAME, @@ -349,7 +345,7 @@ decrypt_tkt_with_subkey (krb5_context context, krb5_data data; size_t size; krb5_crypto crypto; - + ret = krb5_crypto_init(context, key, 0, &crypto); if (ret) return ret; @@ -373,33 +369,32 @@ decrypt_tkt_with_subkey (krb5_context context, } if (ret) return ret; - + ret = krb5_decode_EncASRepPart(context, data.data, data.length, - &dec_rep->enc_part, + &dec_rep->enc_part, &size); if (ret) ret = krb5_decode_EncTGSRepPart(context, data.data, data.length, - &dec_rep->enc_part, + &dec_rep->enc_part, &size); krb5_data_free (&data); return ret; } static krb5_error_code -get_cred_kdc_usage(krb5_context context, - krb5_ccache id, - krb5_kdc_flags flags, - krb5_addresses *addresses, - krb5_creds *in_creds, - krb5_creds *krbtgt, - krb5_principal impersonate_principal, - Ticket *second_ticket, - krb5_creds *out_creds, - krb5_key_usage usage) +get_cred_kdc(krb5_context context, + krb5_ccache id, + krb5_kdc_flags flags, + krb5_addresses *addresses, + krb5_creds *in_creds, + krb5_creds *krbtgt, + krb5_principal impersonate_principal, + Ticket *second_ticket, + krb5_creds *out_creds) { TGS_REQ req; krb5_data enc; @@ -412,7 +407,7 @@ get_cred_kdc_usage(krb5_context context, size_t len; Ticket second_ticket_data; METHOD_DATA padata; - + krb5_data_zero(&resp); krb5_data_zero(&enc); padata.val = NULL; @@ -420,10 +415,10 @@ get_cred_kdc_usage(krb5_context context, krb5_generate_random_block(&nonce, sizeof(nonce)); nonce &= 0xffffffff; - + if(flags.b.enc_tkt_in_skey && second_ticket == NULL){ - ret = decode_Ticket(in_creds->second_ticket.data, - in_creds->second_ticket.length, + ret = decode_Ticket(in_creds->second_ticket.data, + in_creds->second_ticket.length, &second_ticket_data, &len); if(ret) return ret; @@ -460,7 +455,7 @@ get_cred_kdc_usage(krb5_context context, KRB5_KU_OTHER_CKSUM, 0, data.data, - data.length, + data.length, &self.cksum); krb5_crypto_destroy(context, crypto); krb5_data_free(&data); @@ -491,14 +486,13 @@ get_cred_kdc_usage(krb5_context context, krbtgt, nonce, &padata, - &subkey, - &req, - usage); + &subkey, + &req); if (ret) goto out; ASN1_MALLOC_ENCODE(TGS_REQ, enc.data, enc.length, &req, &len, ret); - if (ret) + if (ret) goto out; if(enc.length != len) krb5_abortx(context, "internal error in ASN.1 encoder"); @@ -526,20 +520,26 @@ get_cred_kdc_usage(krb5_context context, goto out; memset(&rep, 0, sizeof(rep)); - if(decode_TGS_REP(resp.data, resp.length, &rep.kdc_rep, &len) == 0){ - ret = krb5_copy_principal(context, - in_creds->client, + if(decode_TGS_REP(resp.data, resp.length, &rep.kdc_rep, &len) == 0) { + unsigned eflags = 0; + + ret = krb5_copy_principal(context, + in_creds->client, &out_creds->client); if(ret) - goto out; - ret = krb5_copy_principal(context, - in_creds->server, + goto out2; + ret = krb5_copy_principal(context, + in_creds->server, &out_creds->server); if(ret) - goto out; + goto out2; /* this should go someplace else */ out_creds->times.endtime = in_creds->times.endtime; + /* XXX should do better testing */ + if (flags.b.constrained_delegation || impersonate_principal) + eflags |= EXTRACT_TICKET_ALLOW_CNAME_MISMATCH; + ret = _krb5_extract_ticket(context, &rep, out_creds, @@ -548,10 +548,10 @@ get_cred_kdc_usage(krb5_context context, KRB5_KU_TGS_REP_ENC_PART_SESSION, &krbtgt->addresses, nonce, - EXTRACT_TICKET_ALLOW_CNAME_MISMATCH| - EXTRACT_TICKET_ALLOW_SERVER_MISMATCH, + eflags, decrypt_tkt_with_subkey, subkey); + out2: krb5_free_kdc_rep(context, &rep); } else if(krb5_rd_error(context, &resp, &error) == 0) { ret = krb5_error_from_rd_error(context, &error, in_creds); @@ -575,52 +575,50 @@ out: free(subkey); } return ret; - + } +/* + * same as above, just get local addresses first if the krbtgt have + * them and the realm is not addressless + */ + static krb5_error_code -get_cred_kdc(krb5_context context, - krb5_ccache id, - krb5_kdc_flags flags, - krb5_addresses *addresses, - krb5_creds *in_creds, - krb5_creds *krbtgt, - krb5_principal impersonate_principal, - Ticket *second_ticket, - krb5_creds *out_creds) +get_cred_kdc_address(krb5_context context, + krb5_ccache id, + krb5_kdc_flags flags, + krb5_addresses *addrs, + krb5_creds *in_creds, + krb5_creds *krbtgt, + krb5_principal impersonate_principal, + Ticket *second_ticket, + krb5_creds *out_creds) { krb5_error_code ret; + krb5_addresses addresses = { 0, NULL }; - ret = get_cred_kdc_usage(context, id, flags, addresses, in_creds, - krbtgt, impersonate_principal, second_ticket, - out_creds, KRB5_KU_TGS_REQ_AUTH); - if (ret == KRB5KRB_AP_ERR_BAD_INTEGRITY) { - krb5_clear_error_string (context); - ret = get_cred_kdc_usage(context, id, flags, addresses, in_creds, - krbtgt, impersonate_principal, second_ticket, - out_creds, KRB5_KU_AP_REQ_AUTH); - } - return ret; -} + /* + * Inherit the address-ness of the krbtgt if the address is not + * specified. + */ -/* same as above, just get local addresses first */ + if (addrs == NULL && krbtgt->addresses.len != 0) { + krb5_boolean noaddr; -static krb5_error_code -get_cred_kdc_la(krb5_context context, krb5_ccache id, krb5_kdc_flags flags, - krb5_creds *in_creds, krb5_creds *krbtgt, - krb5_principal impersonate_principal, Ticket *second_ticket, - krb5_creds *out_creds) -{ - krb5_error_code ret; - krb5_addresses addresses, *addrs = &addresses; - - krb5_get_all_client_addrs(context, &addresses); - /* XXX this sucks. */ - if(addresses.len == 0) - addrs = NULL; - ret = get_cred_kdc(context, id, flags, addrs, - in_creds, krbtgt, impersonate_principal, second_ticket, - out_creds); + krb5_appdefault_boolean(context, NULL, krbtgt->server->realm, + "no-addresses", FALSE, &noaddr); + + if (!noaddr) { + krb5_get_all_client_addrs(context, &addresses); + /* XXX this sucks. */ + addrs = &addresses; + if(addresses.len == 0) + addrs = NULL; + } + } + ret = get_cred_kdc(context, id, flags, addrs, in_creds, + krbtgt, impersonate_principal, + second_ticket, out_creds); krb5_free_addresses(context, &addresses); return ret; } @@ -640,7 +638,7 @@ krb5_get_kdc_cred(krb5_context context, *out_creds = calloc(1, sizeof(**out_creds)); if(*out_creds == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } ret = _krb5_get_krbtgt (context, @@ -651,7 +649,7 @@ krb5_get_kdc_cred(krb5_context context, free(*out_creds); return ret; } - ret = get_cred_kdc(context, id, flags, addresses, + ret = get_cred_kdc(context, id, flags, addresses, in_creds, krbtgt, NULL, NULL, *out_creds); krb5_free_creds (context, krbtgt); if(ret) @@ -659,8 +657,8 @@ krb5_get_kdc_cred(krb5_context context, return ret; } -static void -not_found(krb5_context context, krb5_const_principal p) +static int +not_found(krb5_context context, krb5_const_principal p, krb5_error_code code) { krb5_error_code ret; char *str; @@ -668,10 +666,11 @@ not_found(krb5_context context, krb5_const_principal p) ret = krb5_unparse_name(context, p, &str); if(ret) { krb5_clear_error_string(context); - return; + return code; } - krb5_set_error_string(context, "Matching credential (%s) not found", str); + krb5_set_error_message(context, code, "Matching credential (%s) not found", str); free(str); + return code; } static krb5_error_code @@ -686,24 +685,23 @@ find_cred(krb5_context context, krb5_cc_clear_mcred(&mcreds); mcreds.server = server; - ret = krb5_cc_retrieve_cred(context, id, KRB5_TC_DONT_MATCH_REALM, + ret = krb5_cc_retrieve_cred(context, id, KRB5_TC_DONT_MATCH_REALM, &mcreds, out_creds); if(ret == 0) return 0; while(tgts && *tgts){ - if(krb5_compare_creds(context, KRB5_TC_DONT_MATCH_REALM, + if(krb5_compare_creds(context, KRB5_TC_DONT_MATCH_REALM, &mcreds, *tgts)){ ret = krb5_copy_creds_contents(context, *tgts, out_creds); return ret; } tgts++; } - not_found(context, server); - return KRB5_CC_NOTFOUND; + return not_found(context, server, KRB5_CC_NOTFOUND); } static krb5_error_code -add_cred(krb5_context context, krb5_creds ***tgts, krb5_creds *tkt) +add_cred(krb5_context context, krb5_creds const *tkt, krb5_creds ***tgts) { int i; krb5_error_code ret; @@ -712,7 +710,7 @@ add_cred(krb5_context context, krb5_creds ***tgts, krb5_creds *tkt) for(i = 0; tmp && tmp[i]; i++); /* XXX */ tmp = realloc(tmp, (i+2)*sizeof(*tmp)); if(tmp == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } *tgts = tmp; @@ -737,14 +735,14 @@ get_cred(server) */ static krb5_error_code -get_cred_from_kdc_flags(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) +get_cred_kdc_capath(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; krb5_creds *tgt, tmp_creds; @@ -759,7 +757,7 @@ get_cred_from_kdc_flags(krb5_context context, if(ret) return ret; - try_realm = krb5_config_get_string(context, NULL, "capaths", + try_realm = krb5_config_get_string(context, NULL, "capaths", client_realm, server_realm, NULL); if (try_realm == NULL) try_realm = client_realm; @@ -768,7 +766,7 @@ get_cred_from_kdc_flags(krb5_context context, &tmp_creds.server, try_realm, KRB5_TGS_NAME, - server_realm, + server_realm, NULL); if(ret){ krb5_free_principal(context, tmp_creds.client); @@ -776,32 +774,20 @@ get_cred_from_kdc_flags(krb5_context context, } { krb5_creds tgts; - /* XXX try krb5_cc_retrieve_cred first? */ - ret = find_cred(context, ccache, tmp_creds.server, + + ret = find_cred(context, ccache, tmp_creds.server, *ret_tgts, &tgts); if(ret == 0){ *out_creds = calloc(1, sizeof(**out_creds)); if(*out_creds == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); ret = ENOMEM; + krb5_set_error_message(context, ret, "malloc: out of memory"); } else { - krb5_boolean noaddr; - - krb5_appdefault_boolean(context, NULL, tgts.server->realm, - "no-addresses", FALSE, &noaddr); - - if (noaddr) - ret = get_cred_kdc(context, ccache, flags, NULL, - in_creds, &tgts, - impersonate_principal, - second_ticket, - *out_creds); - else - ret = get_cred_kdc_la(context, ccache, flags, - in_creds, &tgts, - impersonate_principal, - second_ticket, - *out_creds); + ret = get_cred_kdc_address(context, ccache, flags, NULL, + in_creds, &tgts, + impersonate_principal, + second_ticket, + *out_creds); if (ret) { free (*out_creds); *out_creds = NULL; @@ -813,22 +799,21 @@ get_cred_from_kdc_flags(krb5_context context, return ret; } } - if(krb5_realm_compare(context, in_creds->client, in_creds->server)) { - not_found(context, in_creds->server); - return KRB5_CC_NOTFOUND; - } + if(krb5_realm_compare(context, in_creds->client, in_creds->server)) + return not_found(context, in_creds->server, KRB5_CC_NOTFOUND); + /* XXX this can loop forever */ while(1){ heim_general_string tgt_inst; - ret = get_cred_from_kdc_flags(context, flags, ccache, &tmp_creds, - NULL, NULL, &tgt, ret_tgts); + ret = get_cred_kdc_capath(context, flags, ccache, &tmp_creds, + NULL, NULL, &tgt, ret_tgts); if(ret) { krb5_free_principal(context, tmp_creds.server); krb5_free_principal(context, tmp_creds.client); return ret; } - ret = add_cred(context, ret_tgts, tgt); + ret = add_cred(context, tgt, ret_tgts); if(ret) { krb5_free_principal(context, tmp_creds.server); krb5_free_principal(context, tmp_creds.client); @@ -838,7 +823,7 @@ get_cred_from_kdc_flags(krb5_context context, if(strcmp(tgt_inst, server_realm) == 0) break; krb5_free_principal(context, tmp_creds.server); - ret = krb5_make_principal(context, &tmp_creds.server, + ret = krb5_make_principal(context, &tmp_creds.server, tgt_inst, KRB5_TGS_NAME, server_realm, NULL); if(ret) { krb5_free_principal(context, tmp_creds.server); @@ -857,22 +842,12 @@ get_cred_from_kdc_flags(krb5_context context, krb5_free_principal(context, tmp_creds.client); *out_creds = calloc(1, sizeof(**out_creds)); if(*out_creds == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); ret = ENOMEM; + krb5_set_error_message(context, ret, "malloc: out of memory"); } else { - krb5_boolean noaddr; - - krb5_appdefault_boolean(context, NULL, tgt->server->realm, - "no-addresses", KRB5_ADDRESSLESS_DEFAULT, - &noaddr); - if (noaddr) - ret = get_cred_kdc (context, ccache, flags, NULL, - in_creds, tgt, NULL, NULL, - *out_creds); - else - ret = get_cred_kdc_la(context, ccache, flags, - in_creds, tgt, NULL, NULL, - *out_creds); + ret = get_cred_kdc_address (context, ccache, flags, NULL, + in_creds, tgt, impersonate_principal, + second_ticket, *out_creds); if (ret) { free (*out_creds); *out_creds = NULL; @@ -882,6 +857,185 @@ get_cred_from_kdc_flags(krb5_context context, return ret; } +static krb5_error_code +get_cred_kdc_referral(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_const_realm client_realm; + krb5_error_code ret; + krb5_creds tgt, referral, ticket; + int loop = 0; + + memset(&tgt, 0, sizeof(tgt)); + memset(&ticket, 0, sizeof(ticket)); + + flags.b.canonicalize = 1; + + *out_creds = NULL; + + client_realm = krb5_principal_get_realm(context, in_creds->client); + + /* find tgt for the clients base realm */ + { + krb5_principal tgtname; + + ret = krb5_make_principal(context, &tgtname, + client_realm, + KRB5_TGS_NAME, + client_realm, + NULL); + if(ret) + return ret; + + ret = find_cred(context, ccache, tgtname, *ret_tgts, &tgt); + krb5_free_principal(context, tgtname); + if (ret) + return ret; + } + + referral = *in_creds; + ret = krb5_copy_principal(context, in_creds->server, &referral.server); + if (ret) { + krb5_free_cred_contents(context, &tgt); + return ret; + } + ret = krb5_principal_set_realm(context, referral.server, client_realm); + if (ret) { + krb5_free_cred_contents(context, &tgt); + krb5_free_principal(context, referral.server); + return ret; + } + + while (loop++ < 17) { + krb5_creds **tickets; + krb5_creds mcreds; + char *referral_realm; + + /* Use cache if we are not doing impersonation or contrainte deleg */ + if (impersonate_principal == NULL || flags.b.constrained_delegation) { + krb5_cc_clear_mcred(&mcreds); + mcreds.server = referral.server; + ret = krb5_cc_retrieve_cred(context, ccache, 0, &mcreds, &ticket); + } else + ret = EINVAL; + + if (ret) { + ret = get_cred_kdc_address (context, ccache, flags, NULL, + &referral, &tgt, impersonate_principal, + second_ticket, &ticket); + if (ret) + goto out; + } + + /* Did we get the right ticket ? */ + if (krb5_principal_compare_any_realm(context, + referral.server, + ticket.server)) + break; + + if (ticket.server->name.name_string.len != 2 && + strcmp(ticket.server->name.name_string.val[0], KRB5_TGS_NAME) != 0) + { + krb5_set_error_message(context, KRB5KRB_AP_ERR_NOT_US, + "Got back an non krbtgt ticket referrals"); + krb5_free_cred_contents(context, &ticket); + return KRB5KRB_AP_ERR_NOT_US; + } + + referral_realm = ticket.server->name.name_string.val[1]; + + /* check that there are no referrals loops */ + tickets = *ret_tgts; + + krb5_cc_clear_mcred(&mcreds); + mcreds.server = ticket.server; + + while(tickets && *tickets){ + if(krb5_compare_creds(context, + KRB5_TC_DONT_MATCH_REALM, + &mcreds, + *tickets)) + { + krb5_set_error_message(context, KRB5_GET_IN_TKT_LOOP, + "Referral from %s loops back to realm %s", + tgt.server->realm, + referral_realm); + krb5_free_cred_contents(context, &ticket); + return KRB5_GET_IN_TKT_LOOP; + } + tickets++; + } + + ret = add_cred(context, &ticket, ret_tgts); + if (ret) { + krb5_free_cred_contents(context, &ticket); + goto out; + } + + /* try realm in the referral */ + ret = krb5_principal_set_realm(context, + referral.server, + referral_realm); + krb5_free_cred_contents(context, &tgt); + tgt = ticket; + memset(&ticket, 0, sizeof(ticket)); + if (ret) + goto out; + } + + ret = krb5_copy_creds(context, &ticket, out_creds); + +out: + krb5_free_principal(context, referral.server); + krb5_free_cred_contents(context, &tgt); + return ret; +} + + +/* + * Glue function between referrals version and old client chasing + * 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 ret; + + ret = get_cred_kdc_referral(context, + flags, + ccache, + in_creds, + impersonate_principal, + second_ticket, + out_creds, + ret_tgts); + if (ret == 0 || flags.b.canonicalize) + return ret; + return get_cred_kdc_capath(context, + flags, + ccache, + in_creds, + impersonate_principal, + second_ticket, + out_creds, + ret_tgts); +} + + krb5_error_code KRB5_LIB_FUNCTION krb5_get_cred_from_kdc_opt(krb5_context context, krb5_ccache ccache, @@ -892,9 +1046,9 @@ krb5_get_cred_from_kdc_opt(krb5_context context, { krb5_kdc_flags f; f.i = flags; - return get_cred_from_kdc_flags(context, f, ccache, - in_creds, NULL, NULL, - out_creds, ret_tgts); + return get_cred_kdc_any(context, f, ccache, + in_creds, NULL, NULL, + out_creds, ret_tgts); } krb5_error_code KRB5_LIB_FUNCTION @@ -904,10 +1058,10 @@ krb5_get_cred_from_kdc(krb5_context context, krb5_creds **out_creds, krb5_creds ***ret_tgts) { - return krb5_get_cred_from_kdc_opt(context, ccache, + 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, @@ -921,18 +1075,18 @@ krb5_get_credentials_with_flags(krb5_context context, krb5_creds **tgts; krb5_creds *res_creds; int i; - + *out_creds = NULL; res_creds = calloc(1, sizeof(*res_creds)); if (res_creds == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } if (in_creds->session.keytype) options |= KRB5_TC_MATCH_KEYTYPE; - /* + /* * If we got a credential, check if credential is expired before * returning it. */ @@ -941,7 +1095,7 @@ krb5_get_credentials_with_flags(krb5_context context, in_creds->session.keytype ? KRB5_TC_MATCH_KEYTYPE : 0, in_creds, res_creds); - /* + /* * If we got a credential, check if credential is expired before * returning it, but only if KRB5_GC_EXPIRED_OK is not set. */ @@ -953,7 +1107,7 @@ krb5_get_credentials_with_flags(krb5_context context, *out_creds = res_creds; return 0; } - + krb5_timeofday(context, &timeret); if(res_creds->times.endtime > timeret) { *out_creds = res_creds; @@ -967,18 +1121,17 @@ krb5_get_credentials_with_flags(krb5_context context, return ret; } free(res_creds); - if(options & KRB5_GC_CACHED) { - not_found(context, in_creds->server); - return KRB5_CC_NOTFOUND; - } + if(options & KRB5_GC_CACHED) + return not_found(context, in_creds->server, KRB5_CC_NOTFOUND); + if(options & KRB5_GC_USER_USER) flags.b.enc_tkt_in_skey = 1; if (flags.b.enc_tkt_in_skey) options |= KRB5_GC_NO_STORE; tgts = NULL; - ret = get_cred_from_kdc_flags(context, flags, ccache, - in_creds, NULL, NULL, out_creds, &tgts); + ret = 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]); @@ -1015,7 +1168,7 @@ krb5_get_creds_opt_alloc(krb5_context context, krb5_get_creds_opt *opt) { *opt = calloc(1, sizeof(**opt)); if (*opt == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } return 0; @@ -1079,14 +1232,14 @@ krb5_get_creds_opt_set_ticket(krb5_context context, opt->ticket = malloc(sizeof(*ticket)); if (opt->ticket == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } ret = copy_Ticket(ticket, opt->ticket); if (ret) { free(opt->ticket); opt->ticket = NULL; - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); return ret; } } @@ -1109,7 +1262,7 @@ krb5_get_creds(krb5_context context, krb5_creds **tgts; krb5_creds *res_creds; int i; - + memset(&in_creds, 0, sizeof(in_creds)); in_creds.server = rk_UNCONST(inprinc); @@ -1124,7 +1277,7 @@ krb5_get_creds(krb5_context context, res_creds = calloc(1, sizeof(*res_creds)); if (res_creds == NULL) { krb5_free_principal(context, in_creds.client); - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } @@ -1133,7 +1286,7 @@ krb5_get_creds(krb5_context context, options |= KRB5_TC_MATCH_KEYTYPE; } - /* + /* * If we got a credential, check if credential is expired before * returning it. */ @@ -1141,7 +1294,7 @@ krb5_get_creds(krb5_context context, ccache, opt->enctype ? KRB5_TC_MATCH_KEYTYPE : 0, &in_creds, res_creds); - /* + /* * If we got a credential, check if credential is expired before * returning it, but only if KRB5_GC_EXPIRED_OK is not set. */ @@ -1154,7 +1307,7 @@ krb5_get_creds(krb5_context context, krb5_free_principal(context, in_creds.client); return 0; } - + krb5_timeofday(context, &timeret); if(res_creds->times.endtime > timeret) { *out_creds = res_creds; @@ -1171,9 +1324,8 @@ krb5_get_creds(krb5_context context, } free(res_creds); if(options & KRB5_GC_CACHED) { - not_found(context, in_creds.server); krb5_free_principal(context, in_creds.client); - return KRB5_CC_NOTFOUND; + return not_found(context, in_creds.server, KRB5_CC_NOTFOUND); } if(options & KRB5_GC_USER_USER) { flags.b.enc_tkt_in_skey = 1; @@ -1187,11 +1339,13 @@ krb5_get_creds(krb5_context context, flags.b.request_anonymous = 1; /* XXX ARGH confusion */ flags.b.constrained_delegation = 1; } + if (options & KRB5_GC_CANONICALIZE) + flags.b.canonicalize = 1; tgts = NULL; - ret = get_cred_from_kdc_flags(context, flags, ccache, - &in_creds, opt->self, opt->ticket, - out_creds, &tgts); + ret = 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/get_default_principal.c b/source4/heimdal/lib/krb5/get_default_principal.c index 83fb2b0fa9..5a7a7829fc 100644 --- a/source4/heimdal/lib/krb5/get_default_principal.c +++ b/source4/heimdal/lib/krb5/get_default_principal.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: get_default_principal.c 14870 2005-04-20 20:53:29Z lha $"); +RCSID("$Id: get_default_principal.c 23280 2008-06-23 03:26:18Z lha $"); /* * Try to find out what's a reasonable default principal. @@ -85,8 +85,8 @@ _krb5_get_default_principal_local (krb5_context context, user = getlogin(); } if(user == NULL) { - krb5_set_error_string(context, - "unable to figure out current principal"); + krb5_set_error_message(context, ENOTTY, + "unable to figure out current principal"); return ENOTTY; /* XXX */ } ret = krb5_make_principal(context, princ, NULL, user, NULL); diff --git a/source4/heimdal/lib/krb5/get_default_realm.c b/source4/heimdal/lib/krb5/get_default_realm.c index 09c8577b26..1c996031e8 100644 --- a/source4/heimdal/lib/krb5/get_default_realm.c +++ b/source4/heimdal/lib/krb5/get_default_realm.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: get_default_realm.c 13863 2004-05-25 21:46:46Z lha $"); +RCSID("$Id: get_default_realm.c 23280 2008-06-23 03:26:18Z lha $"); /* * Return a NULL-terminated list of default realms in `realms'. @@ -76,7 +76,7 @@ krb5_get_default_realm(krb5_context context, res = strdup (context->default_realms[0]); if (res == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } *realm = res; diff --git a/source4/heimdal/lib/krb5/get_for_creds.c b/source4/heimdal/lib/krb5/get_for_creds.c index cb8b7c8641..a8aac950ec 100644 --- a/source4/heimdal/lib/krb5/get_for_creds.c +++ b/source4/heimdal/lib/krb5/get_for_creds.c @@ -33,7 +33,7 @@ #include <krb5_locl.h> -RCSID("$Id: get_for_creds.c 22504 2008-01-21 15:49:58Z lha $"); +RCSID("$Id: get_for_creds.c 23316 2008-06-23 04:32:32Z lha $"); static krb5_error_code add_addrs(krb5_context context, @@ -51,8 +51,8 @@ add_addrs(krb5_context context, tmp = realloc(addr->val, (addr->len + n) * sizeof(*addr->val)); if (tmp == NULL && (addr->len + n) != 0) { - krb5_set_error_string(context, "malloc: out of memory"); ret = ENOMEM; + krb5_set_error_message(context, ret, "malloc: out of memory"); goto fail; } addr->val = tmp; @@ -207,7 +207,6 @@ krb5_get_forwarded_creds (krb5_context context, krb5_kdc_flags kdc_flags; krb5_crypto crypto; struct addrinfo *ai; - int save_errno; krb5_creds *ticket; paddrs = NULL; @@ -238,10 +237,10 @@ krb5_get_forwarded_creds (krb5_context context, ret = getaddrinfo (hostname, NULL, NULL, &ai); if (ret) { - save_errno = errno; - krb5_set_error_string(context, "resolving %s: %s", + krb5_error_code ret2 = krb5_eai_to_heim_errno(ret, errno); + krb5_set_error_message(context, ret2, "resolving %s: %s", hostname, gai_strerror(ret)); - return krb5_eai_to_heim_errno(ret, save_errno); + return ret2; } ret = add_addrs (context, &addrs, ai); @@ -269,7 +268,7 @@ krb5_get_forwarded_creds (krb5_context context, ALLOC_SEQ(&cred.tickets, 1); if (cred.tickets.val == NULL) { ret = ENOMEM; - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); goto out2; } ret = decode_Ticket(out_creds->ticket.data, @@ -282,7 +281,7 @@ krb5_get_forwarded_creds (krb5_context context, ALLOC_SEQ(&enc_krb_cred_part.ticket_info, 1); if (enc_krb_cred_part.ticket_info.val == NULL) { ret = ENOMEM; - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); goto out4; } @@ -295,14 +294,14 @@ krb5_get_forwarded_creds (krb5_context context, ALLOC(enc_krb_cred_part.timestamp, 1); if (enc_krb_cred_part.timestamp == NULL) { ret = ENOMEM; - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); goto out4; } *enc_krb_cred_part.timestamp = sec; ALLOC(enc_krb_cred_part.usec, 1); if (enc_krb_cred_part.usec == NULL) { ret = ENOMEM; - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); goto out4; } *enc_krb_cred_part.usec = usec; @@ -346,7 +345,7 @@ krb5_get_forwarded_creds (krb5_context context, ALLOC(enc_krb_cred_part.r_address, 1); if (enc_krb_cred_part.r_address == NULL) { ret = ENOMEM; - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); goto out4; } diff --git a/source4/heimdal/lib/krb5/get_host_realm.c b/source4/heimdal/lib/krb5/get_host_realm.c index d709e4b38d..f4c875b347 100644 --- a/source4/heimdal/lib/krb5/get_host_realm.c +++ b/source4/heimdal/lib/krb5/get_host_realm.c @@ -34,7 +34,7 @@ #include "krb5_locl.h" #include <resolve.h> -RCSID("$Id: get_host_realm.c 18541 2006-10-17 19:28:36Z lha $"); +RCSID("$Id: get_host_realm.c 23316 2008-06-23 04:32:32Z lha $"); /* To automagically find the correct realm of a host (without * [domain_realm] in krb5.conf) add a text record for your domain with @@ -55,7 +55,7 @@ copy_txt_to_realms (struct resource_record *head, krb5_realm **realms) { struct resource_record *rr; - int n, i; + unsigned int n, i; for(n = 0, rr = head; rr; rr = rr->next) if (rr->type == T_TXT) @@ -192,21 +192,22 @@ _krb5_get_host_realm_int (krb5_context context, p++; *realms = malloc(2 * sizeof(krb5_realm)); if (*realms == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } (*realms)[0] = strdup(p); if((*realms)[0] == NULL) { free(*realms); - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } strupr((*realms)[0]); (*realms)[1] = NULL; return 0; } - krb5_set_error_string(context, "unable to find realm of host %s", host); + krb5_set_error_message(context, KRB5_ERR_HOST_REALM_UNKNOWN, + "unable to find realm of host %s", host); return KRB5_ERR_HOST_REALM_UNKNOWN; } @@ -248,8 +249,9 @@ krb5_get_host_realm(krb5_context context, */ ret = krb5_get_default_realms(context, realms); if (ret) { - krb5_set_error_string(context, "Unable to find realm of host %s", - host); + krb5_set_error_message(context, KRB5_ERR_HOST_REALM_UNKNOWN, + "Unable to find realm of host %s", + host); return KRB5_ERR_HOST_REALM_UNKNOWN; } } diff --git a/source4/heimdal/lib/krb5/get_in_tkt.c b/source4/heimdal/lib/krb5/get_in_tkt.c index a9ed3857d0..8bdc8c0eb2 100644 --- a/source4/heimdal/lib/krb5/get_in_tkt.c +++ b/source4/heimdal/lib/krb5/get_in_tkt.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997 - 2002 Kungliga Tekniska Högskolan + * Copyright (c) 1997 - 2008 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: get_in_tkt.c 20226 2007-02-16 03:31:50Z lha $"); +RCSID("$Id: get_in_tkt.c 23316 2008-06-23 04:32:32Z lha $"); krb5_error_code KRB5_LIB_FUNCTION krb5_init_etype (krb5_context context, @@ -41,7 +41,7 @@ krb5_init_etype (krb5_context context, krb5_enctype **val, const krb5_enctype *etypes) { - int i; + unsigned int i; krb5_error_code ret; krb5_enctype *tmp = NULL; @@ -60,7 +60,7 @@ krb5_init_etype (krb5_context context, *val = malloc(i * sizeof(**val)); if (i != 0 && *val == NULL) { ret = ENOMEM; - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); goto cleanup; } memmove (*val, @@ -72,6 +72,225 @@ cleanup: return ret; } +static krb5_error_code +check_server_referral(krb5_context context, + krb5_kdc_rep *rep, + unsigned flags, + krb5_const_principal requested, + krb5_const_principal returned, + const krb5_keyblock const * key) +{ + krb5_error_code ret; + PA_ServerReferralData ref; + krb5_crypto session; + EncryptedData ed; + size_t len; + krb5_data data; + PA_DATA *pa; + int i = 0, cmp; + + if (rep->kdc_rep.padata == NULL) + goto noreferral; + + pa = krb5_find_padata(rep->kdc_rep.padata->val, + rep->kdc_rep.padata->len, + KRB5_PADATA_SERVER_REFERRAL, &i); + if (pa == NULL) + goto noreferral; + + memset(&ed, 0, sizeof(ed)); + memset(&ref, 0, sizeof(ref)); + + ret = decode_EncryptedData(pa->padata_value.data, + pa->padata_value.length, + &ed, &len); + if (ret) + return ret; + if (len != pa->padata_value.length) { + free_EncryptedData(&ed); + krb5_set_error_message(context, KRB5KRB_AP_ERR_MODIFIED, "Referral EncryptedData wrong"); + return KRB5KRB_AP_ERR_MODIFIED; + } + + ret = krb5_crypto_init(context, key, 0, &session); + if (ret) { + free_EncryptedData(&ed); + return ret; + } + + ret = krb5_decrypt_EncryptedData(context, session, + KRB5_KU_PA_SERVER_REFERRAL, + &ed, &data); + free_EncryptedData(&ed); + krb5_crypto_destroy(context, session); + if (ret) + return ret; + + ret = decode_PA_ServerReferralData(data.data, data.length, &ref, &len); + if (ret) { + krb5_data_free(&data); + return ret; + } + krb5_data_free(&data); + + if (strcmp(requested->realm, returned->realm) != 0) { + free_PA_ServerReferralData(&ref); + krb5_set_error_message(context, KRB5KRB_AP_ERR_MODIFIED, + "server ref realm mismatch"); + return KRB5KRB_AP_ERR_MODIFIED; + } + + if (returned->name.name_string.len == 2 && + strcmp(returned->name.name_string.val[0], KRB5_TGS_NAME) == 0) + { + const char *realm = returned->name.name_string.val[1]; + + if (ref.referred_realm == NULL + || strcmp(*ref.referred_realm, realm) != 0) + { + free_PA_ServerReferralData(&ref); + krb5_set_error_message(context, KRB5KRB_AP_ERR_MODIFIED, + "tgt returned with wrong ref"); + return KRB5KRB_AP_ERR_MODIFIED; + } + } else if (krb5_principal_compare(context, returned, requested) == 0) { + free_PA_ServerReferralData(&ref); + krb5_set_error_message(context, KRB5KRB_AP_ERR_MODIFIED, + "req princ no same as returned"); + return KRB5KRB_AP_ERR_MODIFIED; + } + + if (ref.requested_principal_name) { + cmp = _krb5_principal_compare_PrincipalName(context, + requested, + ref.requested_principal_name); + if (!cmp) { + free_PA_ServerReferralData(&ref); + krb5_set_error_message(context, KRB5KRB_AP_ERR_MODIFIED, + "compare requested failed"); + return KRB5KRB_AP_ERR_MODIFIED; + } + } else if (flags & EXTRACT_TICKET_AS_REQ) { + free_PA_ServerReferralData(&ref); + krb5_set_error_message(context, KRB5KRB_AP_ERR_MODIFIED, + "Requested principal missing on AS-REQ"); + return KRB5KRB_AP_ERR_MODIFIED; + } + + free_PA_ServerReferralData(&ref); + + return ret; +noreferral: + if (krb5_principal_compare(context, requested, returned) == FALSE) { + krb5_set_error_message(context, KRB5KRB_AP_ERR_MODIFIED, + "Not same server principal returned " + "as requested"); + return KRB5KRB_AP_ERR_MODIFIED; + } + return 0; +} + + +/* + * Verify referral data + */ + + +static krb5_error_code +check_client_referral(krb5_context context, + krb5_kdc_rep *rep, + krb5_const_principal requested, + krb5_const_principal mapped, + krb5_keyblock const * key) +{ + krb5_error_code ret; + PA_ClientCanonicalized canon; + krb5_crypto crypto; + krb5_data data; + PA_DATA *pa; + size_t len; + int i = 0; + + if (rep->kdc_rep.padata == NULL) + goto noreferral; + + pa = krb5_find_padata(rep->kdc_rep.padata->val, + rep->kdc_rep.padata->len, + KRB5_PADATA_CLIENT_CANONICALIZED, &i); + if (pa == NULL) + goto noreferral; + + ret = decode_PA_ClientCanonicalized(pa->padata_value.data, + pa->padata_value.length, + &canon, &len); + if (ret) { + krb5_set_error_message(context, ret, "Failed to decode " + "PA_ClientCanonicalized"); + return ret; + } + + ASN1_MALLOC_ENCODE(PA_ClientCanonicalizedNames, data.data, data.length, + &canon.names, &len, ret); + if (ret) { + free_PA_ClientCanonicalized(&canon); + return ret; + } + if (data.length != len) + krb5_abortx(context, "internal asn.1 error"); + + ret = krb5_crypto_init(context, key, 0, &crypto); + if (ret) { + free(data.data); + free_PA_ClientCanonicalized(&canon); + return ret; + } + + ret = krb5_verify_checksum(context, crypto, KRB5_KU_CANONICALIZED_NAMES, + data.data, data.length, + &canon.canon_checksum); + krb5_crypto_destroy(context, crypto); + free(data.data); + if (ret) { + krb5_set_error_message(context, ret, "Failed to verify " + "client canonicalized data"); + free_PA_ClientCanonicalized(&canon); + return ret; + } + + if (!_krb5_principal_compare_PrincipalName(context, + requested, + &canon.names.requested_name)) + { + free_PA_ClientCanonicalized(&canon); + krb5_set_error_message(context, KRB5_PRINC_NOMATCH, + "Requested name doesn't match" + " in client referral"); + return KRB5_PRINC_NOMATCH; + } + if (!_krb5_principal_compare_PrincipalName(context, + mapped, + &canon.names.mapped_name)) + { + free_PA_ClientCanonicalized(&canon); + krb5_set_error_message(context, KRB5_PRINC_NOMATCH, + "Mapped name doesn't match" + " in client referral"); + return KRB5_PRINC_NOMATCH; + } + + return 0; + +noreferral: + if (krb5_principal_compare(context, requested, mapped) == FALSE) { + krb5_set_error_message(context, KRB5KRB_AP_ERR_MODIFIED, + "Not same client principal returned " + "as requested"); + return KRB5KRB_AP_ERR_MODIFIED; + } + return 0; +} + + static krb5_error_code decrypt_tkt (krb5_context context, @@ -117,9 +336,9 @@ decrypt_tkt (krb5_context context, } int -_krb5_extract_ticket(krb5_context context, - krb5_kdc_rep *rep, - krb5_creds *creds, +_krb5_extract_ticket(krb5_context context, + krb5_kdc_rep *rep, + krb5_creds *creds, krb5_keyblock *key, krb5_const_pointer keyseed, krb5_key_usage key_usage, @@ -131,83 +350,86 @@ _krb5_extract_ticket(krb5_context context, { krb5_error_code ret; krb5_principal tmp_principal; - int tmp; size_t len; time_t tmp_time; krb5_timestamp sec_now; -/* - * HACK: - * this is really a ugly hack, to support using the Netbios Domain Name - * as realm against windows KDC's, they always return the full realm - * based on the DNS Name. - */ -flags |= EXTRACT_TICKET_ALLOW_SERVER_MISMATCH; -flags |=EXTRACT_TICKET_ALLOW_CNAME_MISMATCH ; + /* decrypt */ + + if (decrypt_proc == NULL) + decrypt_proc = decrypt_tkt; + + ret = (*decrypt_proc)(context, key, key_usage, decryptarg, rep); + if (ret) + goto out; + + /* save session key */ + + creds->session.keyvalue.length = 0; + creds->session.keyvalue.data = NULL; + creds->session.keytype = rep->enc_part.key.keytype; + ret = krb5_data_copy (&creds->session.keyvalue, + rep->enc_part.key.keyvalue.data, + rep->enc_part.key.keyvalue.length); + if (ret) { + krb5_clear_error_string(context); + goto out; + } + + /* + * HACK: + * this is really a ugly hack, to support using the Netbios Domain Name + * as realm against windows KDC's, they always return the full realm + * based on the DNS Name. + */ + flags |= EXTRACT_TICKET_ALLOW_SERVER_MISMATCH; + flags |=EXTRACT_TICKET_ALLOW_CNAME_MISMATCH ; + - ret = _krb5_principalname2krb5_principal (context, + /* compare client and save */ + ret = _krb5_principalname2krb5_principal (context, &tmp_principal, rep->kdc_rep.cname, rep->kdc_rep.crealm); if (ret) goto out; - /* compare client */ - - if((flags & EXTRACT_TICKET_ALLOW_CNAME_MISMATCH) == 0){ - tmp = krb5_principal_compare (context, tmp_principal, creds->client); - if (!tmp) { + /* check client referral and save principal */ + /* anonymous here ? */ + if((flags & EXTRACT_TICKET_ALLOW_CNAME_MISMATCH) == 0) { + ret = check_client_referral(context, rep, + creds->client, + tmp_principal, + &creds->session); + if (ret) { krb5_free_principal (context, tmp_principal); - krb5_clear_error_string (context); - ret = KRB5KRB_AP_ERR_MODIFIED; goto out; } } - krb5_free_principal (context, creds->client); creds->client = tmp_principal; - /* extract ticket */ - ASN1_MALLOC_ENCODE(Ticket, creds->ticket.data, creds->ticket.length, - &rep->kdc_rep.ticket, &len, ret); - if(ret) - goto out; - if (creds->ticket.length != len) - krb5_abortx(context, "internal error in ASN.1 encoder"); - creds->second_ticket.length = 0; - creds->second_ticket.data = NULL; - - /* compare server */ - + /* check server referral and save principal */ ret = _krb5_principalname2krb5_principal (context, &tmp_principal, rep->kdc_rep.ticket.sname, rep->kdc_rep.ticket.realm); if (ret) goto out; - if(flags & EXTRACT_TICKET_ALLOW_SERVER_MISMATCH){ - krb5_free_principal(context, creds->server); - creds->server = tmp_principal; - tmp_principal = NULL; - } else { - tmp = krb5_principal_compare (context, tmp_principal, - creds->server); - krb5_free_principal (context, tmp_principal); - if (!tmp) { - ret = KRB5KRB_AP_ERR_MODIFIED; - krb5_clear_error_string (context); + if((flags & EXTRACT_TICKET_ALLOW_SERVER_MISMATCH) == 0){ + ret = check_server_referral(context, + rep, + flags, + creds->server, + tmp_principal, + &creds->session); + if (ret) { + krb5_free_principal (context, tmp_principal); goto out; } } - - /* decrypt */ - - if (decrypt_proc == NULL) - decrypt_proc = decrypt_tkt; - - ret = (*decrypt_proc)(context, key, key_usage, decryptarg, rep); - if (ret) - goto out; + krb5_free_principal(context, creds->server); + creds->server = tmp_principal; /* verify names */ if(flags & EXTRACT_TICKET_MATCH_REALM){ @@ -227,7 +449,7 @@ flags |=EXTRACT_TICKET_ALLOW_CNAME_MISMATCH ; if (nonce != rep->enc_part.nonce) { ret = KRB5KRB_AP_ERR_MODIFIED; - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } @@ -254,7 +476,7 @@ flags |=EXTRACT_TICKET_ALLOW_CNAME_MISMATCH ; if (creds->times.starttime == 0 && abs(tmp_time - sec_now) > context->max_skew) { ret = KRB5KRB_AP_ERR_SKEW; - krb5_set_error_string (context, + krb5_set_error_message (context, ret, "time skew (%d) larger than max (%d)", abs(tmp_time - sec_now), (int)context->max_skew); @@ -307,12 +529,17 @@ flags |=EXTRACT_TICKET_ALLOW_CNAME_MISMATCH ; creds->authdata.len = 0; creds->authdata.val = NULL; - creds->session.keyvalue.length = 0; - creds->session.keyvalue.data = NULL; - creds->session.keytype = rep->enc_part.key.keytype; - ret = krb5_data_copy (&creds->session.keyvalue, - rep->enc_part.key.keyvalue.data, - rep->enc_part.key.keyvalue.length); + + /* extract ticket */ + ASN1_MALLOC_ENCODE(Ticket, creds->ticket.data, creds->ticket.length, + &rep->kdc_rep.ticket, &len, ret); + if(ret) + goto out; + if (creds->ticket.length != len) + krb5_abortx(context, "internal error in ASN.1 encoder"); + creds->second_ticket.length = 0; + creds->second_ticket.data = NULL; + out: memset (rep->enc_part.key.keyvalue.data, 0, @@ -402,7 +629,7 @@ add_padata(krb5_context context, } pa2 = realloc (md->val, (md->len + netypes) * sizeof(*md->val)); if (pa2 == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } md->val = pa2; @@ -449,13 +676,13 @@ init_as_req (krb5_context context, a->req_body.cname = malloc(sizeof(*a->req_body.cname)); if (a->req_body.cname == NULL) { ret = ENOMEM; - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); goto fail; } a->req_body.sname = malloc(sizeof(*a->req_body.sname)); if (a->req_body.sname == NULL) { ret = ENOMEM; - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); goto fail; } ret = _krb5_principal2principalname (a->req_body.cname, creds->client); @@ -472,7 +699,7 @@ init_as_req (krb5_context context, a->req_body.from = malloc(sizeof(*a->req_body.from)); if (a->req_body.from == NULL) { ret = ENOMEM; - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); goto fail; } *a->req_body.from = creds->times.starttime; @@ -485,7 +712,7 @@ init_as_req (krb5_context context, a->req_body.rtime = malloc(sizeof(*a->req_body.rtime)); if (a->req_body.rtime == NULL) { ret = ENOMEM; - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); goto fail; } *a->req_body.rtime = creds->times.renew_till; @@ -508,7 +735,7 @@ init_as_req (krb5_context context, a->req_body.addresses = malloc(sizeof(*a->req_body.addresses)); if (a->req_body.addresses == NULL) { ret = ENOMEM; - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); goto fail; } @@ -533,7 +760,7 @@ init_as_req (krb5_context context, ALLOC(a->padata, 1); if(a->padata == NULL) { ret = ENOMEM; - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); goto fail; } a->padata->val = NULL; @@ -572,7 +799,7 @@ init_as_req (krb5_context context, ALLOC(a->padata, 1); if (a->padata == NULL) { ret = ENOMEM; - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); goto fail; } a->padata->len = 0; @@ -590,9 +817,9 @@ init_as_req (krb5_context context, key_proc, keyseed, a->req_body.etype.val, a->req_body.etype.len, &salt); } else { - krb5_set_error_string (context, "pre-auth type %d not supported", - *ptypes); ret = KRB5_PREAUTH_BAD_TYPE; + krb5_set_error_message (context, ret, "pre-auth type %d not supported", + *ptypes); goto fail; } return 0; diff --git a/source4/heimdal/lib/krb5/init_creds.c b/source4/heimdal/lib/krb5/init_creds.c index a59c903bd9..74c9ff78e5 100644 --- a/source4/heimdal/lib/krb5/init_creds.c +++ b/source4/heimdal/lib/krb5/init_creds.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: init_creds.c 21711 2007-07-27 14:22:02Z lha $"); +RCSID("$Id: init_creds.c 23316 2008-06-23 04:32:32Z lha $"); void KRB5_LIB_FUNCTION krb5_get_init_creds_opt_init(krb5_get_init_creds_opt *opt) @@ -52,13 +52,13 @@ krb5_get_init_creds_opt_alloc(krb5_context context, *opt = NULL; o = calloc(1, sizeof(*o)); if (o == NULL) { - krb5_set_error_string(context, "out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } krb5_get_init_creds_opt_init(o); o->opt_private = calloc(1, sizeof(*o->opt_private)); if (o->opt_private == NULL) { - krb5_set_error_string(context, "out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); free(o); return ENOMEM; } @@ -77,7 +77,7 @@ _krb5_get_init_creds_opt_copy(krb5_context context, *out = NULL; opt = calloc(1, sizeof(*opt)); if (opt == NULL) { - krb5_set_error_string(context, "out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } if (in) @@ -85,7 +85,7 @@ _krb5_get_init_creds_opt_copy(krb5_context context, if(opt->opt_private == NULL) { opt->opt_private = calloc(1, sizeof(*opt->opt_private)); if (opt->opt_private == NULL) { - krb5_set_error_string(context, "out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); free(opt); return ENOMEM; } @@ -327,7 +327,7 @@ require_ext_opt(krb5_context context, const char *type) { if (opt->opt_private == NULL) { - krb5_set_error_string(context, "%s on non extendable opt", type); + krb5_set_error_message(context, EINVAL, "%s on non extendable opt", type); return EINVAL; } return 0; @@ -381,7 +381,7 @@ krb5_get_init_creds_opt_get_error(krb5_context context, *error = malloc(sizeof(**error)); if (*error == NULL) { - krb5_set_error_string(context, "malloc - out memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } diff --git a/source4/heimdal/lib/krb5/init_creds_pw.c b/source4/heimdal/lib/krb5/init_creds_pw.c index 441adff8fd..e3098b0a92 100644 --- a/source4/heimdal/lib/krb5/init_creds_pw.c +++ b/source4/heimdal/lib/krb5/init_creds_pw.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: init_creds_pw.c 21931 2007-08-27 14:11:55Z lha $"); +RCSID("$Id: init_creds_pw.c 23316 2008-06-23 04:32:32Z lha $"); typedef struct krb5_get_init_creds_ctx { KDCOptions flags; @@ -165,14 +165,10 @@ init_cred (krb5_context context, } if (in_tkt_service) { - krb5_realm server_realm; - ret = krb5_parse_name (context, in_tkt_service, &cred->server); if (ret) goto out; - server_realm = strdup (client_realm); - free (*krb5_princ_realm(context, cred->server)); - krb5_princ_set_realm (context, cred->server, &server_realm); + krb5_principal_set_realm (context, cred->server, client_realm); } else { ret = krb5_make_principal(context, &cred->server, client_realm, KRB5_TGS_NAME, client_realm, @@ -340,7 +336,7 @@ get_init_creds_common(krb5_context context, etypes = malloc((options->etype_list_length + 1) * sizeof(krb5_enctype)); if (etypes == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } memcpy (etypes, options->etype_list, @@ -352,7 +348,7 @@ get_init_creds_common(krb5_context context, pre_auth_types = malloc((options->preauth_list_length + 1) * sizeof(krb5_preauthtype)); if (pre_auth_types == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } memcpy (pre_auth_types, options->preauth_list, @@ -445,12 +441,13 @@ change_password (krb5_context context, memset (buf2, 0, sizeof(buf2)); } - ret = krb5_change_password (context, - &cpw_cred, - buf1, - &result_code, - &result_code_string, - &result_string); + ret = krb5_set_password (context, + &cpw_cred, + buf1, + client, + &result_code, + &result_code_string, + &result_string); if (ret) goto out; asprintf (&p, "%s: %.*s\n", @@ -464,8 +461,8 @@ change_password (krb5_context context, strlcpy (newpw, buf1, newpw_sz); ret = 0; } else { - krb5_set_error_string (context, "failed changing password"); ret = ENOTTY; + krb5_set_error_message(context, ret, "failed changing password"); } out: @@ -507,8 +504,8 @@ krb5_get_init_creds_keytab(krb5_context context, a = malloc (sizeof(*a)); if (a == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); ret = ENOMEM; + krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } a->principal = ctx.cred.client; @@ -560,13 +557,13 @@ init_creds_init_as_req (krb5_context context, a->req_body.cname = malloc(sizeof(*a->req_body.cname)); if (a->req_body.cname == NULL) { ret = ENOMEM; - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); goto fail; } a->req_body.sname = malloc(sizeof(*a->req_body.sname)); if (a->req_body.sname == NULL) { ret = ENOMEM; - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); goto fail; } @@ -585,7 +582,7 @@ init_creds_init_as_req (krb5_context context, a->req_body.from = malloc(sizeof(*a->req_body.from)); if (a->req_body.from == NULL) { ret = ENOMEM; - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); goto fail; } *a->req_body.from = creds->times.starttime; @@ -598,7 +595,7 @@ init_creds_init_as_req (krb5_context context, a->req_body.rtime = malloc(sizeof(*a->req_body.rtime)); if (a->req_body.rtime == NULL) { ret = ENOMEM; - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); goto fail; } *a->req_body.rtime = creds->times.renew_till; @@ -621,7 +618,7 @@ init_creds_init_as_req (krb5_context context, a->req_body.addresses = malloc(sizeof(*a->req_body.addresses)); if (a->req_body.addresses == NULL) { ret = ENOMEM; - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); goto fail; } @@ -1036,7 +1033,7 @@ pa_data_to_md_pkinit(krb5_context context, ctx->pk_nonce, md); #else - krb5_set_error_string(context, "no support for PKINIT compiled in"); + krb5_set_error_message(context, EINVAL, "no support for PKINIT compiled in"); return EINVAL; #endif } @@ -1093,7 +1090,7 @@ process_pa_data_to_md(krb5_context context, ALLOC(*out_md, 1); if (*out_md == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } (*out_md)->len = 0; @@ -1191,15 +1188,15 @@ process_pa_data_to_key(krb5_context context, pa, key); #else - krb5_set_error_string(context, "no support for PKINIT compiled in"); ret = EINVAL; + krb5_set_error_message(context, ret, "no support for PKINIT compiled in"); #endif } else if (ctx->password) ret = pa_data_to_key_plain(context, creds->client, ctx, paid.salt, paid.s2kparams, etype, key); else { - krb5_set_error_string(context, "No usable pa data type"); ret = EINVAL; + krb5_set_error_message(context, ret, "No usable pa data type"); } free_paid(context, &paid); @@ -1325,8 +1322,8 @@ init_cred_loop(krb5_context context, &md, NULL); if (ret) - krb5_set_error_string(context, - "failed to decode METHOD DATA"); + krb5_set_error_message(context, ret, + "failed to decode METHOD DATA"); } else { /* XXX guess what the server want here add add md */ } @@ -1348,15 +1345,16 @@ init_cred_loop(krb5_context context, { krb5_keyblock *key = NULL; - unsigned flags = 0; + unsigned flags = EXTRACT_TICKET_AS_REQ; if (ctx->flags.request_anonymous) flags |= EXTRACT_TICKET_ALLOW_SERVER_MISMATCH; if (ctx->flags.canonicalize) { - flags |= EXTRACT_TICKET_ALLOW_CNAME_MISMATCH; flags |= EXTRACT_TICKET_ALLOW_SERVER_MISMATCH; flags |= EXTRACT_TICKET_MATCH_REALM; } + if (ctx->ic_flags & KRB5_INIT_CREDS_NO_C_CANON_CHECK) + flags |= EXTRACT_TICKET_ALLOW_CNAME_MISMATCH; ret = process_pa_data_to_key(context, ctx, creds, &ctx->as_req, &rep, hi, &key); @@ -1376,60 +1374,6 @@ init_cred_loop(krb5_context context, NULL); krb5_free_keyblock(context, key); } - /* - * Verify referral data - */ - if ((ctx->ic_flags & KRB5_INIT_CREDS_CANONICALIZE) && - (ctx->ic_flags & KRB5_INIT_CREDS_NO_C_CANON_CHECK) == 0) - { - PA_ClientCanonicalized canon; - krb5_crypto crypto; - krb5_data data; - PA_DATA *pa; - size_t len; - - pa = find_pa_data(rep.kdc_rep.padata, KRB5_PADATA_CLIENT_CANONICALIZED); - if (pa == NULL) { - ret = EINVAL; - krb5_set_error_string(context, "Client canonicalizion not signed"); - goto out; - } - - ret = decode_PA_ClientCanonicalized(pa->padata_value.data, - pa->padata_value.length, - &canon, &len); - if (ret) { - krb5_set_error_string(context, "Failed to decode " - "PA_ClientCanonicalized"); - goto out; - } - - ASN1_MALLOC_ENCODE(PA_ClientCanonicalizedNames, data.data, data.length, - &canon.names, &len, ret); - if (ret) - goto out; - if (data.length != len) - krb5_abortx(context, "internal asn.1 error"); - - ret = krb5_crypto_init(context, &creds->session, 0, &crypto); - if (ret) { - free(data.data); - free_PA_ClientCanonicalized(&canon); - goto out; - } - - ret = krb5_verify_checksum(context, crypto, KRB5_KU_CANONICALIZED_NAMES, - data.data, data.length, - &canon.canon_checksum); - krb5_crypto_destroy(context, crypto); - free(data.data); - free_PA_ClientCanonicalized(&canon); - if (ret) { - krb5_set_error_string(context, "Failed to verify " - "client canonicalized data"); - goto out; - } - } out: if (stctx) krb5_sendto_ctx_free(context, stctx); diff --git a/source4/heimdal/lib/krb5/kcm.c b/source4/heimdal/lib/krb5/kcm.c index 8afaa6ea80..0c91fbb3a0 100644 --- a/source4/heimdal/lib/krb5/kcm.c +++ b/source4/heimdal/lib/krb5/kcm.c @@ -43,7 +43,7 @@ #include "kcm.h" -RCSID("$Id: kcm.c 22108 2007-12-03 17:23:53Z lha $"); +RCSID("$Id: kcm.c 23446 2008-07-27 12:08:37Z lha $"); typedef struct krb5_kcmcache { char *name; @@ -56,7 +56,8 @@ typedef struct krb5_kcmcache { #define KCMCURSOR(C) (*(uint32_t *)(C)) static krb5_error_code -try_door(krb5_context context, const krb5_kcmcache *k, +try_door(krb5_context context, + krb5_kcmcache *k, krb5_data *request_data, krb5_data *response_data) { @@ -70,6 +71,7 @@ try_door(krb5_context context, const krb5_kcmcache *k, fd = open(k->door_path, O_RDWR); if (fd < 0) return KRB5_CC_IO; + rk_cloexec(fd); arg.data_ptr = request_data->data; arg.data_size = request_data->length; @@ -95,7 +97,8 @@ try_door(krb5_context context, const krb5_kcmcache *k, } static krb5_error_code -try_unix_socket(krb5_context context, const krb5_kcmcache *k, +try_unix_socket(krb5_context context, + krb5_kcmcache *k, krb5_data *request_data, krb5_data *response_data) { @@ -105,7 +108,8 @@ try_unix_socket(krb5_context context, const krb5_kcmcache *k, fd = socket(AF_UNIX, SOCK_STREAM, 0); if (fd < 0) return KRB5_CC_IO; - + rk_cloexec(fd); + if (connect(fd, rk_UNCONST(&k->path), sizeof(k->path)) != 0) { close(fd); return KRB5_CC_IO; @@ -136,7 +140,7 @@ kcm_send_request(krb5_context context, return KRB5_CC_NOMEM; } - ret = KRB5_CC_IO; + ret = KRB5_CC_NOSUPP; for (i = 0; i < context->max_retries; i++) { ret = try_door(context, k, &request_data, response_data); @@ -151,7 +155,7 @@ kcm_send_request(krb5_context context, if (ret) { krb5_clear_error_string(context); - ret = KRB5_CC_IO; + ret = KRB5_CC_NOSUPP; } return ret; @@ -169,7 +173,7 @@ kcm_storage_request(krb5_context context, sp = krb5_storage_emem(); if (sp == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, KRB5_CC_NOMEM, "malloc: out of memory"); return KRB5_CC_NOMEM; } @@ -187,7 +191,7 @@ kcm_storage_request(krb5_context context, *storage_p = sp; fail: if (ret) { - krb5_set_error_string(context, "Failed to encode request"); + krb5_set_error_message(context, ret, "Failed to encode request"); krb5_storage_free(sp); } @@ -202,7 +206,7 @@ kcm_alloc(krb5_context context, const char *name, krb5_ccache *id) k = malloc(sizeof(*k)); if (k == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, KRB5_CC_NOMEM, "malloc: out of memory"); return KRB5_CC_NOMEM; } @@ -210,7 +214,7 @@ kcm_alloc(krb5_context context, const char *name, krb5_ccache *id) k->name = strdup(name); if (k->name == NULL) { free(k); - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, KRB5_CC_NOMEM, "malloc: out of memory"); return KRB5_CC_NOMEM; } } else @@ -822,7 +826,7 @@ kcm_set_flags(krb5_context context, return ret; } -static krb5_error_code +static int kcm_get_version(krb5_context context, krb5_ccache id) { @@ -832,8 +836,30 @@ kcm_get_version(krb5_context context, static krb5_error_code kcm_move(krb5_context context, krb5_ccache from, krb5_ccache to) { - krb5_set_error_string(context, "kcm_move not implemented"); - return EINVAL; + krb5_error_code ret; + krb5_kcmcache *oldk = KCMCACHE(from); + krb5_kcmcache *newk = KCMCACHE(to); + krb5_storage *request; + + ret = kcm_storage_request(context, KCM_OP_MOVE_CACHE, &request); + if (ret) + return ret; + + ret = krb5_store_stringz(request, oldk->name); + if (ret) { + krb5_storage_free(request); + return ret; + } + + ret = krb5_store_stringz(request, newk->name); + if (ret) { + krb5_storage_free(request); + return ret; + } + ret = kcm_call(context, oldk, request, NULL, NULL); + + krb5_storage_free(request); + return ret; } static krb5_error_code @@ -850,7 +876,8 @@ kcm_default_name(krb5_context context, char **str) * @ingroup krb5_ccache */ -const krb5_cc_ops krb5_kcm_ops = { +KRB5_LIB_VARIABLE const krb5_cc_ops krb5_kcm_ops = { + KRB5_CC_OPS_VERSION, "KCM", kcm_get_name, kcm_resolve, @@ -1118,5 +1145,4 @@ _krb5_kcm_get_ticket(krb5_context context, return ret; } - #endif /* HAVE_KCM */ diff --git a/source4/heimdal/lib/krb5/keyblock.c b/source4/heimdal/lib/krb5/keyblock.c index ff4f972e57..fa19e1e726 100644 --- a/source4/heimdal/lib/krb5/keyblock.c +++ b/source4/heimdal/lib/krb5/keyblock.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: keyblock.c 15167 2005-05-18 04:21:57Z lha $"); +RCSID("$Id: keyblock.c 23316 2008-06-23 04:32:32Z lha $"); void KRB5_LIB_FUNCTION krb5_keyblock_zero(krb5_keyblock *keyblock) @@ -81,7 +81,7 @@ krb5_copy_keyblock (krb5_context context, k = malloc (sizeof(*k)); if (k == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } *to = k; @@ -116,15 +116,16 @@ krb5_keyblock_init(krb5_context context, return ret; if (len != size) { - krb5_set_error_string(context, "Encryption key %d is %lu bytes " - "long, %lu was passed in", - type, (unsigned long)len, (unsigned long)size); + krb5_set_error_message(context, KRB5_PROG_ETYPE_NOSUPP, + "Encryption key %d is %lu bytes " + "long, %lu was passed in", + type, (unsigned long)len, (unsigned long)size); return KRB5_PROG_ETYPE_NOSUPP; } ret = krb5_data_copy(&key->keyvalue, data, len); if(ret) { - krb5_set_error_string(context, "malloc failed: %lu", - (unsigned long)len); + krb5_set_error_message(context, ret, "malloc failed: %lu", + (unsigned long)len); return ret; } key->keytype = type; diff --git a/source4/heimdal/lib/krb5/keytab.c b/source4/heimdal/lib/krb5/keytab.c index 79a3f20e79..09e130d850 100644 --- a/source4/heimdal/lib/krb5/keytab.c +++ b/source4/heimdal/lib/krb5/keytab.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: keytab.c 22532 2008-01-27 11:59:18Z lha $"); +RCSID("$Id: keytab.c 23316 2008-06-23 04:32:32Z lha $"); /* * Register a new keytab in `ops' @@ -47,14 +47,15 @@ krb5_kt_register(krb5_context context, struct krb5_keytab_data *tmp; if (strlen(ops->prefix) > KRB5_KT_PREFIX_MAX_LEN - 1) { - krb5_set_error_string(context, "krb5_kt_register; prefix too long"); + krb5_set_error_message(context, KRB5_KT_BADNAME, + "krb5_kt_register; prefix too long"); return KRB5_KT_BADNAME; } tmp = realloc(context->kt_types, (context->num_kt_types + 1) * sizeof(*context->kt_types)); if(tmp == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } memcpy(&tmp[context->num_kt_types], ops, @@ -97,14 +98,15 @@ krb5_kt_resolve(krb5_context context, break; } if(i == context->num_kt_types) { - krb5_set_error_string(context, "unknown keytab type %.*s", - (int)type_len, type); + krb5_set_error_message(context, KRB5_KT_UNKNOWN_TYPE, + "unknown keytab type %.*s", + (int)type_len, type); return KRB5_KT_UNKNOWN_TYPE; } k = malloc (sizeof(*k)); if (k == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } memcpy(k, &context->kt_types[i], sizeof(*k)); @@ -265,7 +267,7 @@ krb5_kt_get_full_name(krb5_context context, return ret; if (asprintf(str, "%s:%s", type, name) == -1) { - krb5_set_error_string(context, "malloc - out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); *str = NULL; return ENOMEM; } @@ -377,12 +379,12 @@ krb5_kt_get_entry(krb5_context context, else kvno_str[0] = '\0'; - krb5_set_error_string (context, - "Failed to find %s%s in keytab %s (%s)", - princ, - kvno_str, - kt_name ? kt_name : "unknown keytab", - enctype_str ? enctype_str : "unknown enctype"); + krb5_set_error_message (context, KRB5_KT_NOTFOUND, + "Failed to find %s%s in keytab %s (%s)", + princ, + kvno_str, + kt_name ? kt_name : "unknown keytab", + enctype_str ? enctype_str : "unknown enctype"); free(kt_name); free(enctype_str); return KRB5_KT_NOTFOUND; @@ -443,9 +445,9 @@ krb5_kt_start_seq_get(krb5_context context, krb5_kt_cursor *cursor) { if(id->start_seq_get == NULL) { - krb5_set_error_string(context, - "start_seq_get is not supported in the %s " - " keytab", id->prefix); + krb5_set_error_message(context, HEIM_ERR_OPNOTSUPP, + "start_seq_get is not supported in the %s " + " keytab", id->prefix); return HEIM_ERR_OPNOTSUPP; } return (*id->start_seq_get)(context, id, cursor); @@ -464,9 +466,9 @@ krb5_kt_next_entry(krb5_context context, krb5_kt_cursor *cursor) { if(id->next_entry == NULL) { - krb5_set_error_string(context, - "next_entry is not supported in the %s " - " keytab", id->prefix); + krb5_set_error_message(context, HEIM_ERR_OPNOTSUPP, + "next_entry is not supported in the %s " + " keytab", id->prefix); return HEIM_ERR_OPNOTSUPP; } return (*id->next_entry)(context, id, entry, cursor); @@ -482,9 +484,9 @@ krb5_kt_end_seq_get(krb5_context context, krb5_kt_cursor *cursor) { if(id->end_seq_get == NULL) { - krb5_set_error_string(context, - "end_seq_get is not supported in the %s " - " keytab", id->prefix); + krb5_set_error_message(context, HEIM_ERR_OPNOTSUPP, + "end_seq_get is not supported in the %s " + " keytab", id->prefix); return HEIM_ERR_OPNOTSUPP; } return (*id->end_seq_get)(context, id, cursor); @@ -501,8 +503,9 @@ krb5_kt_add_entry(krb5_context context, krb5_keytab_entry *entry) { if(id->add == NULL) { - krb5_set_error_string(context, "Add is not supported in the %s keytab", - id->prefix); + krb5_set_error_message(context, KRB5_KT_NOWRITE, + "Add is not supported in the %s keytab", + id->prefix); return KRB5_KT_NOWRITE; } entry->timestamp = time(NULL); @@ -520,9 +523,9 @@ krb5_kt_remove_entry(krb5_context context, krb5_keytab_entry *entry) { if(id->remove == NULL) { - krb5_set_error_string(context, - "Remove is not supported in the %s keytab", - id->prefix); + krb5_set_error_message(context, KRB5_KT_NOWRITE, + "Remove is not supported in the %s keytab", + id->prefix); return KRB5_KT_NOWRITE; } return (*id->remove)(context, id, entry); diff --git a/source4/heimdal/lib/krb5/keytab_any.c b/source4/heimdal/lib/krb5/keytab_any.c index 54272d4845..9e93191045 100644 --- a/source4/heimdal/lib/krb5/keytab_any.c +++ b/source4/heimdal/lib/krb5/keytab_any.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: keytab_any.c 17035 2006-04-10 09:20:13Z lha $"); +RCSID("$Id: keytab_any.c 23316 2008-06-23 04:32:32Z lha $"); struct any_data { krb5_keytab kt; @@ -72,8 +72,8 @@ any_resolve(krb5_context context, const char *name, krb5_keytab id) a0 = a; a->name = strdup(buf); if (a->name == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); ret = ENOMEM; + krb5_set_error_message(context, ret, "malloc: out of memory"); goto fail; } } else @@ -87,7 +87,7 @@ any_resolve(krb5_context context, const char *name, krb5_keytab id) prev = a; } if (a0 == NULL) { - krb5_set_error_string(context, "empty ANY: keytab"); + krb5_set_error_message(context, ENOENT, "empty ANY: keytab"); return ENOENT; } id->data = a0; @@ -134,7 +134,7 @@ any_start_seq_get(krb5_context context, c->data = malloc (sizeof(struct any_cursor_extra_data)); if(c->data == NULL){ - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } ed = (struct any_cursor_extra_data *)c->data; @@ -206,8 +206,8 @@ any_add_entry(krb5_context context, while(a != NULL) { ret = krb5_kt_add_entry(context, a->kt, entry); if(ret != 0 && ret != KRB5_KT_NOWRITE) { - krb5_set_error_string(context, "failed to add entry to %s", - a->name); + krb5_set_error_message(context, ret, "failed to add entry to %s", + a->name); return ret; } a = a->next; @@ -229,8 +229,9 @@ any_remove_entry(krb5_context context, found++; else { if(ret != KRB5_KT_NOWRITE && ret != KRB5_KT_NOTFOUND) { - krb5_set_error_string(context, "failed to remove entry from %s", - a->name); + krb5_set_error_message(context, ret, + "Failed to remove keytab entry from %s", + a->name); return ret; } } diff --git a/source4/heimdal/lib/krb5/keytab_file.c b/source4/heimdal/lib/krb5/keytab_file.c index be195d96c2..e830ab3412 100644 --- a/source4/heimdal/lib/krb5/keytab_file.c +++ b/source4/heimdal/lib/krb5/keytab_file.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997 - 2005 Kungliga Tekniska Högskolan + * Copyright (c) 1997 - 2008 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: keytab_file.c 22532 2008-01-27 11:59:18Z lha $"); +RCSID("$Id: keytab_file.c 23469 2008-07-27 12:17:12Z lha $"); #define KRB5_KT_VNO_1 1 #define KRB5_KT_VNO_2 2 @@ -62,7 +62,7 @@ krb5_kt_ret_data(krb5_context context, data->length = size; data->data = malloc(size); if (data->data == NULL) { - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } ret = krb5_storage_read(sp, data->data, size); @@ -83,7 +83,7 @@ krb5_kt_ret_string(krb5_context context, return ret; *data = malloc(size + 1); if (*data == NULL) { - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } ret = krb5_storage_read(sp, *data, size); @@ -168,22 +168,22 @@ krb5_kt_ret_principal(krb5_context context, ALLOC(p, 1); if(p == NULL) { - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } ret = krb5_ret_int16(sp, &len); if(ret) { - krb5_set_error_string(context, - "Failed decoding length of keytab principal"); + krb5_set_error_message(context, ret, + "Failed decoding length of keytab principal"); goto out; } if(krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_WRONG_NUM_COMPONENTS)) len--; if (len < 0) { - krb5_set_error_string(context, - "Keytab principal contains invalid length"); ret = KRB5_KT_END; + krb5_set_error_message(context, ret, + "Keytab principal contains invalid length"); goto out; } ret = krb5_kt_ret_string(context, sp, &p->realm); @@ -191,8 +191,8 @@ krb5_kt_ret_principal(krb5_context context, goto out; p->name.name_string.val = calloc(len, sizeof(*p->name.name_string.val)); if(p->name.name_string.val == NULL) { - krb5_set_error_string (context, "malloc: out of memory"); ret = ENOMEM; + krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } p->name.name_string.len = len; @@ -253,13 +253,13 @@ fkt_resolve(krb5_context context, const char *name, krb5_keytab id) d = malloc(sizeof(*d)); if(d == NULL) { - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } d->filename = strdup(name); if(d->filename == NULL) { free(d); - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } d->flags = 0; @@ -334,10 +334,11 @@ fkt_start_seq_get_int(krb5_context context, c->fd = open (d->filename, flags); if (c->fd < 0) { ret = errno; - krb5_set_error_string(context, "keytab %s open failed: %s", - d->filename, strerror(ret)); + krb5_set_error_message(context, ret, "keytab %s open failed: %s", + d->filename, strerror(ret)); return ret; } + rk_cloexec(c->fd); ret = _krb5_xlock(context, c->fd, exclusive, d->filename); if (ret) { close(c->fd); @@ -347,7 +348,7 @@ fkt_start_seq_get_int(krb5_context context, if (c->sp == NULL) { _krb5_xunlock(context, c->fd); close(c->fd); - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } krb5_storage_set_eof_code(c->sp, KRB5_KT_END); @@ -492,10 +493,12 @@ fkt_add_entry(krb5_context context, fd = open (d->filename, O_RDWR | O_CREAT | O_EXCL | O_BINARY, 0600); if (fd < 0) { ret = errno; - krb5_set_error_string(context, "open(%s): %s", d->filename, - strerror(ret)); + krb5_set_error_message(context, ret, "open(%s): %s", d->filename, + strerror(ret)); return ret; } + rk_cloexec(fd); + ret = _krb5_xlock(context, fd, 1, d->filename); if (ret) { close(fd); @@ -510,6 +513,9 @@ fkt_add_entry(krb5_context context, storage_set_flags(context, sp, id->version); } else { int8_t pvno, tag; + + rk_cloexec(fd); + ret = _krb5_xlock(context, fd, 1, d->filename); if (ret) { close(fd); @@ -523,22 +529,22 @@ fkt_add_entry(krb5_context context, properly */ ret = fkt_setup_keytab(context, id, sp); if(ret) { - krb5_set_error_string(context, "%s: keytab is corrupted: %s", - d->filename, strerror(ret)); + krb5_set_error_message(context, ret, "%s: keytab is corrupted: %s", + d->filename, strerror(ret)); goto out; } storage_set_flags(context, sp, id->version); } else { if(pvno != 5) { ret = KRB5_KEYTAB_BADVNO; - krb5_set_error_string(context, "%s: %s", - d->filename, strerror(ret)); + krb5_set_error_message(context, ret, "%s: %s", + d->filename, strerror(ret)); goto out; } ret = krb5_ret_int8 (sp, &tag); if (ret) { - krb5_set_error_string(context, "%s: reading tag: %s", - d->filename, strerror(ret)); + krb5_set_error_message(context, ret, "%s: reading tag: %s", + d->filename, strerror(ret)); goto out; } id->version = tag; @@ -551,7 +557,7 @@ fkt_add_entry(krb5_context context, emem = krb5_storage_emem(); if(emem == NULL) { ret = ENOMEM; - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } ret = krb5_kt_store_principal(context, emem, entry->principal); diff --git a/source4/heimdal/lib/krb5/keytab_keyfile.c b/source4/heimdal/lib/krb5/keytab_keyfile.c index aa612add09..7e14cbd329 100644 --- a/source4/heimdal/lib/krb5/keytab_keyfile.c +++ b/source4/heimdal/lib/krb5/keytab_keyfile.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: keytab_keyfile.c 22532 2008-01-27 11:59:18Z lha $"); +RCSID("$Id: keytab_keyfile.c 23316 2008-06-23 04:32:32Z lha $"); /* afs keyfile operations --------------------------------------- */ @@ -52,7 +52,7 @@ RCSID("$Id: keytab_keyfile.c 22532 2008-01-27 11:59:18Z lha $"); #define AFS_SERVERMAGICKRBCONF "/usr/afs/etc/krb.conf" struct akf_data { - int num_entries; + uint32_t num_entries; char *filename; char *cell; char *realm; @@ -72,13 +72,13 @@ get_cell_and_realm (krb5_context context, struct akf_data *d) f = fopen (AFS_SERVERTHISCELL, "r"); if (f == NULL) { ret = errno; - krb5_set_error_string (context, "open %s: %s", AFS_SERVERTHISCELL, - strerror(ret)); + krb5_set_error_message (context, ret, "open %s: %s", AFS_SERVERTHISCELL, + strerror(ret)); return ret; } if (fgets (buf, sizeof(buf), f) == NULL) { fclose (f); - krb5_set_error_string (context, "no cell in %s", AFS_SERVERTHISCELL); + krb5_set_error_message (context, EINVAL, "no cell in %s", AFS_SERVERTHISCELL); return EINVAL; } buf[strcspn(buf, "\n")] = '\0'; @@ -86,7 +86,7 @@ get_cell_and_realm (krb5_context context, struct akf_data *d) d->cell = strdup (buf); if (d->cell == NULL) { - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } @@ -96,8 +96,8 @@ get_cell_and_realm (krb5_context context, struct akf_data *d) free (d->cell); d->cell = NULL; fclose (f); - krb5_set_error_string (context, "no realm in %s", - AFS_SERVERMAGICKRBCONF); + krb5_set_error_message (context, EINVAL, "no realm in %s", + AFS_SERVERMAGICKRBCONF); return EINVAL; } buf[strcspn(buf, "\n")] = '\0'; @@ -111,7 +111,7 @@ get_cell_and_realm (krb5_context context, struct akf_data *d) if (d->realm == NULL) { free (d->cell); d->cell = NULL; - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } return 0; @@ -128,7 +128,7 @@ akf_resolve(krb5_context context, const char *name, krb5_keytab id) struct akf_data *d = malloc(sizeof (struct akf_data)); if (d == NULL) { - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } @@ -143,7 +143,7 @@ akf_resolve(krb5_context context, const char *name, krb5_keytab id) free (d->cell); free (d->realm); free (d); - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } id->data = d; @@ -197,13 +197,13 @@ akf_start_seq_get(krb5_context context, c->fd = open (d->filename, O_RDONLY|O_BINARY, 0600); if (c->fd < 0) { ret = errno; - krb5_set_error_string(context, "keytab afs keyfil open %s failed: %s", - d->filename, strerror(ret)); + krb5_set_error_message(context, ret, "keytab afs keyfil open %s failed: %s", + d->filename, strerror(ret)); return ret; } c->sp = krb5_storage_from_fd(c->fd); - ret = krb5_ret_int32(c->sp, &d->num_entries); + ret = krb5_ret_uint32(c->sp, &d->num_entries); if(ret) { krb5_storage_free(c->sp); close(c->fd); @@ -250,7 +250,7 @@ akf_next_entry(krb5_context context, entry->keyblock.keyvalue.data = malloc (8); if (entry->keyblock.keyvalue.data == NULL) { krb5_free_principal (context, entry->principal); - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); ret = ENOMEM; goto out; } @@ -307,8 +307,8 @@ akf_add_entry(krb5_context context, O_RDWR | O_BINARY | O_CREAT | O_EXCL, 0600); if (fd < 0) { ret = errno; - krb5_set_error_string(context, "open(%s): %s", d->filename, - strerror(ret)); + krb5_set_error_message(context, ret, "open(%s): %s", d->filename, + strerror(ret)); return ret; } created = 1; @@ -317,7 +317,7 @@ akf_add_entry(krb5_context context, sp = krb5_storage_from_fd(fd); if(sp == NULL) { close(fd); - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } if (created) @@ -327,7 +327,7 @@ akf_add_entry(krb5_context context, ret = errno; krb5_storage_free(sp); close(fd); - krb5_set_error_string (context, "seek: %s", strerror(ret)); + krb5_set_error_message(context, ret, "seek: %s", strerror(ret)); return ret; } @@ -350,11 +350,12 @@ akf_add_entry(krb5_context context, for (i = 0; i < len; i++) { ret = krb5_ret_int32(sp, &kvno); if (ret) { - krb5_set_error_string (context, "Failed to get kvno "); + krb5_set_error_message (context, ret, "Failed to get kvno "); goto out; } if(krb5_storage_seek(sp, 8, SEEK_CUR) < 0) { - krb5_set_error_string (context, "seek: %s", strerror(ret)); + ret = errno; + krb5_set_error_message (context, ret, "seek: %s", strerror(ret)); goto out; } if (kvno == entry->vno) { @@ -368,25 +369,26 @@ akf_add_entry(krb5_context context, if(krb5_storage_seek(sp, 0, SEEK_SET) < 0) { ret = errno; - krb5_set_error_string (context, "seek: %s", strerror(ret)); + krb5_set_error_message (context, ret, "seek: %s", strerror(ret)); goto out; } ret = krb5_store_int32(sp, len); if(ret) { - krb5_set_error_string(context, "keytab keyfile failed new length"); + ret = errno; + krb5_set_error_message (context, ret, "keytab keyfile failed new length"); return ret; } if(krb5_storage_seek(sp, (len - 1) * (8 + 4), SEEK_CUR) < 0) { ret = errno; - krb5_set_error_string (context, "seek to end: %s", strerror(ret)); + krb5_set_error_message (context, ret, "seek to end: %s", strerror(ret)); goto out; } ret = krb5_store_int32(sp, entry->vno); if(ret) { - krb5_set_error_string(context, "keytab keyfile failed store kvno"); + krb5_set_error_message(context, ret, "keytab keyfile failed store kvno"); goto out; } ret = krb5_storage_write(sp, entry->keyblock.keyvalue.data, @@ -396,7 +398,7 @@ akf_add_entry(krb5_context context, ret = errno; else ret = ENOTTY; - krb5_set_error_string(context, "keytab keyfile failed to add key"); + krb5_set_error_message(context, ret, "keytab keyfile failed to add key"); goto out; } ret = 0; diff --git a/source4/heimdal/lib/krb5/keytab_memory.c b/source4/heimdal/lib/krb5/keytab_memory.c index 0ad8720c3f..eabee7c693 100644 --- a/source4/heimdal/lib/krb5/keytab_memory.c +++ b/source4/heimdal/lib/krb5/keytab_memory.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: keytab_memory.c 16352 2005-12-05 18:39:46Z lha $"); +RCSID("$Id: keytab_memory.c 23293 2008-06-23 03:28:22Z lha $"); /* memory operations -------------------------------------------- */ @@ -75,14 +75,14 @@ mkt_resolve(krb5_context context, const char *name, krb5_keytab id) d = calloc(1, sizeof(*d)); if(d == NULL) { HEIMDAL_MUTEX_unlock(&mkt_mutex); - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } d->name = strdup(name); if (d->name == NULL) { HEIMDAL_MUTEX_unlock(&mkt_mutex); free(d); - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } d->entries = NULL; @@ -176,7 +176,7 @@ mkt_add_entry(krb5_context context, krb5_keytab_entry *tmp; tmp = realloc(d->entries, (d->num_entries + 1) * sizeof(*d->entries)); if(tmp == NULL) { - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } d->entries = tmp; diff --git a/source4/heimdal/lib/krb5/krb5-private.h b/source4/heimdal/lib/krb5/krb5-private.h index 7e04446fe0..867d08e3e5 100644 --- a/source4/heimdal/lib/krb5/krb5-private.h +++ b/source4/heimdal/lib/krb5/krb5-private.h @@ -38,12 +38,6 @@ _krb5_dh_group_ok ( struct krb5_dh_moduli **/*moduli*/, char **/*name*/); -krb5_error_code KRB5_LIB_FUNCTION -_krb5_enctype_to_oid ( - krb5_context /*context*/, - krb5_enctype /*etype*/, - heim_oid */*oid*/); - krb5_error_code _krb5_expand_default_cc_name ( krb5_context /*context*/, @@ -283,12 +277,6 @@ _krb5_n_fold ( void */*key*/, size_t /*size*/); -krb5_error_code KRB5_LIB_FUNCTION -_krb5_oid_to_enctype ( - krb5_context /*context*/, - const heim_oid */*oid*/, - krb5_enctype */*etype*/); - krb5_error_code _krb5_pac_sign ( krb5_context /*context*/, @@ -321,6 +309,20 @@ _krb5_pk_allow_proxy_certificate ( void KRB5_LIB_FUNCTION _krb5_pk_cert_free (struct krb5_pk_cert */*cert*/); +krb5_error_code +_krb5_pk_kdf ( + krb5_context /*context*/, + const struct AlgorithmIdentifier */*ai*/, + const void */*dhdata*/, + size_t /*dhsize*/, + krb5_const_principal /*client*/, + krb5_const_principal /*server*/, + krb5_enctype /*enctype*/, + const krb5_data */*as_req*/, + const krb5_data */*pk_as_rep*/, + const Ticket */*ticket*/, + krb5_keyblock */*key*/); + krb5_error_code KRB5_LIB_FUNCTION _krb5_pk_load_id ( krb5_context /*context*/, @@ -401,6 +403,12 @@ _krb5_principal2principalname ( PrincipalName */*p*/, const krb5_principal /*from*/); +krb5_boolean KRB5_LIB_FUNCTION +_krb5_principal_compare_PrincipalName ( + krb5_context /*context*/, + krb5_const_principal /*princ1*/, + PrincipalName */*princ2*/); + krb5_error_code KRB5_LIB_FUNCTION _krb5_principalname2krb5_principal ( krb5_context /*context*/, diff --git a/source4/heimdal/lib/krb5/krb5-protos.h b/source4/heimdal/lib/krb5/krb5-protos.h index 647d8886b7..ead66565e7 100644 --- a/source4/heimdal/lib/krb5/krb5-protos.h +++ b/source4/heimdal/lib/krb5/krb5-protos.h @@ -12,11 +12,13 @@ extern "C" { #endif -#ifndef KRB5_LIB_FUNCTION +#ifndef KRB5_LIB #if defined(_WIN32) -#define KRB5_LIB_FUNCTION _stdcall +#define KRB5_LIB_FUNCTION _stdcall __declspec(dllimport) +#define KRB5_LIB_VARIABLE __declspec(dllimport) #else #define KRB5_LIB_FUNCTION +#define KRB5_LIB_VARIABLE #endif #endif @@ -628,6 +630,14 @@ krb5_cc_gen_new ( krb5_ccache */*id*/); krb5_error_code KRB5_LIB_FUNCTION +krb5_cc_get_config ( + krb5_context /*context*/, + krb5_ccache /*id*/, + krb5_const_principal /*principal*/, + const char */*name*/, + krb5_data */*data*/); + +krb5_error_code KRB5_LIB_FUNCTION krb5_cc_get_full_name ( krb5_context /*context*/, krb5_ccache /*id*/, @@ -727,6 +737,14 @@ krb5_cc_retrieve_cred ( krb5_creds */*creds*/); krb5_error_code KRB5_LIB_FUNCTION +krb5_cc_set_config ( + krb5_context /*context*/, + krb5_ccache /*id*/, + krb5_const_principal /*principal*/, + const char */*name*/, + krb5_data */*data*/); + +krb5_error_code KRB5_LIB_FUNCTION krb5_cc_set_default_name ( krb5_context /*context*/, const char */*name*/); @@ -749,6 +767,11 @@ krb5_cc_store_cred ( krb5_ccache /*id*/, krb5_creds */*creds*/); +krb5_error_code +krb5_cc_switch ( + krb5_context /*context*/, + krb5_ccache /*id*/); + krb5_error_code KRB5_LIB_FUNCTION krb5_change_password ( krb5_context /*context*/, @@ -756,7 +779,8 @@ krb5_change_password ( const char */*newpw*/, int */*result_code*/, krb5_data */*result_code_string*/, - krb5_data */*result_string*/); + krb5_data */*result_string*/) + __attribute__((deprecated)); krb5_error_code KRB5_LIB_FUNCTION krb5_check_transited ( @@ -764,14 +788,14 @@ krb5_check_transited ( krb5_const_realm /*client_realm*/, krb5_const_realm /*server_realm*/, krb5_realm */*realms*/, - int /*num_realms*/, + unsigned int /*num_realms*/, int */*bad_realm*/); krb5_error_code KRB5_LIB_FUNCTION krb5_check_transited_realms ( krb5_context /*context*/, const char *const */*realms*/, - int /*num_realms*/, + unsigned int /*num_realms*/, int */*bad_realm*/); krb5_error_code KRB5_LIB_FUNCTION @@ -1462,14 +1486,14 @@ krb5_domain_x500_decode ( krb5_context /*context*/, krb5_data /*tr*/, char ***/*realms*/, - int */*num_realms*/, + unsigned int */*num_realms*/, const char */*client_realm*/, const char */*server_realm*/); krb5_error_code KRB5_LIB_FUNCTION krb5_domain_x500_encode ( char **/*realms*/, - int /*num_realms*/, + unsigned int /*num_realms*/, krb5_data */*encoding*/); krb5_error_code KRB5_LIB_FUNCTION @@ -1731,9 +1755,9 @@ krb5_free_error_contents ( krb5_error */*error*/); void KRB5_LIB_FUNCTION -krb5_free_error_string ( +krb5_free_error_message ( krb5_context /*context*/, - char */*str*/); + const char */*msg*/); krb5_error_code KRB5_LIB_FUNCTION krb5_free_host_realm ( @@ -1939,7 +1963,7 @@ krb5_get_err_text ( krb5_context /*context*/, krb5_error_code /*code*/); -char * KRB5_LIB_FUNCTION +const char * KRB5_LIB_FUNCTION krb5_get_error_message ( krb5_context /*context*/, krb5_error_code /*code*/); @@ -2969,6 +2993,12 @@ krb5_principal_match ( krb5_const_principal /*princ*/, krb5_const_principal /*pattern*/); +krb5_error_code KRB5_LIB_FUNCTION +krb5_principal_set_realm ( + krb5_context /*context*/, + krb5_principal /*principal*/, + krb5_const_realm /*realm*/); + void KRB5_LIB_FUNCTION krb5_principal_set_type ( krb5_context /*context*/, @@ -3450,12 +3480,20 @@ krb5_set_dns_canonicalize_hostname ( krb5_context /*context*/, krb5_boolean /*flag*/); +void KRB5_LIB_FUNCTION +krb5_set_error_message ( + krb5_context /*context*/, + krb5_error_code /*ret*/, + const char */*fmt*/, + ...) + __attribute__ ((format (printf, 3, 4))); + krb5_error_code KRB5_LIB_FUNCTION krb5_set_error_string ( krb5_context /*context*/, const char */*fmt*/, - ...) - __attribute__((format (printf, 2, 3))); + ...) __attribute__((format (printf, 2, 3))) + __attribute__((deprecated)); krb5_error_code KRB5_LIB_FUNCTION krb5_set_extra_addresses ( @@ -3472,6 +3510,12 @@ krb5_set_ignore_addresses ( krb5_context /*context*/, const krb5_addresses */*addresses*/); +krb5_error_code KRB5_LIB_FUNCTION +krb5_set_kdc_sec_offset ( + krb5_context /*context*/, + int32_t /*sec*/, + int32_t /*usec*/); + void KRB5_LIB_FUNCTION krb5_set_max_time_skew ( krb5_context /*context*/, @@ -4047,12 +4091,20 @@ krb5_vlog_msg ( va_list /*ap*/) __attribute__((format (printf, 5, 0))); +void KRB5_LIB_FUNCTION +krb5_vset_error_message ( + krb5_context /*context*/, + krb5_error_code /*ret*/, + const char */*fmt*/, + va_list /*args*/) + __attribute__ ((format (printf, 3, 0))); + krb5_error_code KRB5_LIB_FUNCTION krb5_vset_error_string ( krb5_context /*context*/, const char */*fmt*/, - va_list /*args*/) - __attribute__ ((format (printf, 2, 0))); + va_list args) __attribute__ ((format (printf, 2, 0))) + __attribute__((deprecated)); krb5_error_code KRB5_LIB_FUNCTION krb5_vwarn ( @@ -4107,6 +4159,9 @@ krb5_write_safe_message ( krb5_error_code KRB5_LIB_FUNCTION krb5_xfree (void */*ptr*/); +void KRB5_LIB_FUNCTION + __attribute__((deprecated)) krb5_free_error_string(krb5_context context, char *str); + #ifdef __cplusplus } #endif diff --git a/source4/heimdal/lib/krb5/krb5.h b/source4/heimdal/lib/krb5/krb5.h index 571eb6192a..b1e2781d52 100644 --- a/source4/heimdal/lib/krb5/krb5.h +++ b/source4/heimdal/lib/krb5/krb5.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: krb5.h 22100 2007-12-03 17:15:00Z lha $ */ +/* $Id: krb5.h 23026 2008-04-17 10:02:03Z lha $ */ #ifndef __KRB5_H__ #define __KRB5_H__ @@ -363,6 +363,7 @@ typedef union { #define KRB5_GC_FORWARDABLE (1U << 4) #define KRB5_GC_NO_TRANSIT_CHECK (1U << 5) #define KRB5_GC_CONSTRAINED_DELEGATION (1U << 6) +#define KRB5_GC_CANONICALIZE (1U << 7) /* constants for compare_creds (and cc_retrieve_cred) */ #define KRB5_TC_DONT_MATCH_REALM (1U << 31) @@ -395,7 +396,10 @@ typedef struct krb5_creds { typedef struct krb5_cc_cache_cursor_data *krb5_cc_cache_cursor; +#define KRB5_CC_OPS_VERSION 1 + typedef struct krb5_cc_ops { + int version; const char *prefix; const char* (*get_name)(krb5_context, krb5_ccache); krb5_error_code (*resolve)(krb5_context, krb5_ccache *, const char *); @@ -419,7 +423,8 @@ typedef struct krb5_cc_ops { krb5_error_code (*get_cache_next)(krb5_context, krb5_cc_cursor, krb5_ccache *); krb5_error_code (*end_cache_get)(krb5_context, krb5_cc_cursor); krb5_error_code (*move)(krb5_context, krb5_ccache, krb5_ccache); - krb5_error_code (*default_name)(krb5_context, char **); + krb5_error_code (*get_default_name)(krb5_context, char **); + krb5_error_code (*set_default)(krb5_context, krb5_ccache); } krb5_cc_ops; struct krb5_log_facility; @@ -589,11 +594,6 @@ typedef EncAPRepPart krb5_ap_rep_enc_part; #define KRB5_DIGEST_NAME ("digest") -/* variables */ - -extern const char *krb5_config_file; -extern const char *krb5_defkeyname; - typedef enum { KRB5_PROMPT_TYPE_PASSWORD = 0x1, KRB5_PROMPT_TYPE_NEW_PASSWORD = 0x2, @@ -681,20 +681,6 @@ typedef struct krb5_verify_opt { #define KRB5_VERIFY_LREALMS 1 #define KRB5_VERIFY_NO_ADDRESSES 2 -extern const krb5_cc_ops krb5_acc_ops; -extern const krb5_cc_ops krb5_fcc_ops; -extern const krb5_cc_ops krb5_mcc_ops; -extern const krb5_cc_ops krb5_kcm_ops; - -extern const krb5_kt_ops krb5_fkt_ops; -extern const krb5_kt_ops krb5_wrfkt_ops; -extern const krb5_kt_ops krb5_javakt_ops; -extern const krb5_kt_ops krb5_mkt_ops; -extern const krb5_kt_ops krb5_akf_ops; -extern const krb5_kt_ops krb4_fkt_ops; -extern const krb5_kt_ops krb5_srvtab_fkt_ops; -extern const krb5_kt_ops krb5_any_ops; - #define KRB5_KPASSWD_VERS_CHANGEPW 1 #define KRB5_KPASSWD_VERS_SETPW 0xff80 @@ -739,6 +725,7 @@ enum { typedef krb5_error_code (*krb5_send_to_kdc_func)(krb5_context, void *, krb5_krbhst_info *, + time_t timeout, const krb5_data *, krb5_data *); @@ -776,5 +763,26 @@ struct sockaddr; #include <krb5-protos.h> +/* variables */ + +extern KRB5_LIB_VARIABLE const char *krb5_config_file; +extern KRB5_LIB_VARIABLE const char *krb5_defkeyname; + + +extern KRB5_LIB_VARIABLE const krb5_cc_ops krb5_acc_ops; +extern KRB5_LIB_VARIABLE const krb5_cc_ops krb5_fcc_ops; +extern KRB5_LIB_VARIABLE const krb5_cc_ops krb5_mcc_ops; +extern KRB5_LIB_VARIABLE const krb5_cc_ops krb5_kcm_ops; +extern KRB5_LIB_VARIABLE const krb5_cc_ops krb5_scc_ops; + +extern KRB5_LIB_VARIABLE const krb5_kt_ops krb5_fkt_ops; +extern KRB5_LIB_VARIABLE const krb5_kt_ops krb5_wrfkt_ops; +extern KRB5_LIB_VARIABLE const krb5_kt_ops krb5_javakt_ops; +extern KRB5_LIB_VARIABLE const krb5_kt_ops krb5_mkt_ops; +extern KRB5_LIB_VARIABLE const krb5_kt_ops krb5_akf_ops; +extern KRB5_LIB_VARIABLE const krb5_kt_ops krb4_fkt_ops; +extern KRB5_LIB_VARIABLE const krb5_kt_ops krb5_srvtab_fkt_ops; +extern KRB5_LIB_VARIABLE const krb5_kt_ops krb5_any_ops; + #endif /* __KRB5_H__ */ diff --git a/source4/heimdal/lib/krb5/krb5_err.et b/source4/heimdal/lib/krb5/krb5_err.et index 6714401e45..8e49ffcc4a 100644 --- a/source4/heimdal/lib/krb5/krb5_err.et +++ b/source4/heimdal/lib/krb5/krb5_err.et @@ -3,7 +3,7 @@ # # This might look like a com_err file, but is not # -id "$Id: krb5_err.et 21050 2007-06-12 02:00:40Z lha $" +id "$Id: krb5_err.et 23354 2008-07-15 11:23:34Z lha $" error_table krb5 @@ -110,7 +110,7 @@ error_code PUBLIC_KEY_ENCRYPTION_NOT_SUPPORTED, "Public key encryption not suppo index 128 prefix -error_code KRB5_ERR_RCSID, "$Id: krb5_err.et 21050 2007-06-12 02:00:40Z lha $" +error_code KRB5_ERR_RCSID, "$Id: krb5_err.et 23354 2008-07-15 11:23:34Z lha $" error_code KRB5_LIBOS_BADLOCKFLAG, "Invalid flag for file lock mode" error_code KRB5_LIBOS_CANTREADPWD, "Cannot read password" @@ -262,5 +262,7 @@ error_code KRB5_ERR_BAD_S2K_PARAMS, "Invalid key generation parameters from KDC" error_code KRB5_ERR_NO_SERVICE, "Service not available" error_code KRB5_CC_NOSUPP, "Credential cache function not supported" error_code KRB5_DELTAT_BADFORMAT, "Invalid format of Kerberos lifetime or clock skew string" +error_code KRB5_PLUGIN_NO_HANDLE, "Supplied data not handled by this plugin" +error_code KRB5_PLUGIN_OP_NOTSUPP, "Plugin does not support the operaton" end diff --git a/source4/heimdal/lib/krb5/krb5_locl.h b/source4/heimdal/lib/krb5/krb5_locl.h index 8b7c41cc80..aaabd4541b 100644 --- a/source4/heimdal/lib/krb5/krb5_locl.h +++ b/source4/heimdal/lib/krb5/krb5_locl.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: krb5_locl.h 22226 2007-12-08 21:31:53Z lha $ */ +/* $Id: krb5_locl.h 23324 2008-06-26 03:54:45Z lha $ */ #ifndef __KRB5_LOCL_H__ #define __KRB5_LOCL_H__ @@ -131,6 +131,8 @@ struct sockaddr_dl; #include <parse_time.h> #include <base64.h> +#include <wind.h> + #include "crypto-headers.h" @@ -142,6 +144,7 @@ struct send_to_kdc; struct krb5_pk_identity; struct krb5_pk_cert; struct ContentInfo; +struct AlgorithmIdentifier; typedef struct krb5_pk_init_ctx_data *krb5_pk_init_ctx; struct krb5_dh_moduli; @@ -154,7 +157,7 @@ struct _krb5_krb_auth_data; #include <krb5_err.h> #include <asn1_err.h> #ifdef PKINIT -#include <hx509_err.h> +#include <hx509.h> #endif #include <krb5-private.h> @@ -164,7 +167,7 @@ struct _krb5_krb_auth_data; #define ALLOC_SEQ(X, N) do { (X)->len = (N); ALLOC((X)->val, (N)); } while(0) /* should this be public? */ -#define KEYTAB_DEFAULT "ANY:FILE:" SYSCONFDIR "/krb5.keytab,krb4:" SYSCONFDIR "/srvtab" +#define KEYTAB_DEFAULT "FILE:" SYSCONFDIR "/krb5.keytab" #define KEYTAB_DEFAULT_MODIFY "FILE:" SYSCONFDIR "/krb5.keytab" #define MODULI_FILE SYSCONFDIR "/krb5.moduli" @@ -227,7 +230,7 @@ typedef struct krb5_context_data { struct krb5_keytab_data *kt_types; /* registered keytab types */ const char *date_fmt; char *error_string; - char error_buf[256]; + krb5_error_code error_code; krb5_addresses *ignore_addresses; char *default_cc_name; char *default_cc_name_env; @@ -247,6 +250,7 @@ typedef struct krb5_context_data { #define EXTRACT_TICKET_ALLOW_CNAME_MISMATCH 1 #define EXTRACT_TICKET_ALLOW_SERVER_MISMATCH 2 #define EXTRACT_TICKET_MATCH_REALM 4 +#define EXTRACT_TICKET_AS_REQ 8 /* * Configurable options @@ -264,4 +268,22 @@ typedef struct krb5_context_data { #define KRB5_ADDRESSLESS_DEFAULT TRUE #endif +#ifdef PKINIT + +struct krb5_pk_identity { + hx509_context hx509ctx; + hx509_verify_ctx verify_ctx; + hx509_certs certs; + hx509_certs anchors; + hx509_certs certpool; + hx509_revoke_ctx revokectx; +}; + +enum krb5_pk_type { + PKINIT_WIN2K = 1, + PKINIT_27 = 2 +}; + +#endif /* PKINIT */ + #endif /* __KRB5_LOCL_H__ */ diff --git a/source4/heimdal/lib/krb5/krbhst.c b/source4/heimdal/lib/krb5/krbhst.c index 094fd4f9c6..3514a026b7 100644 --- a/source4/heimdal/lib/krb5/krbhst.c +++ b/source4/heimdal/lib/krb5/krbhst.c @@ -35,7 +35,7 @@ #include <resolve.h> #include "locate_plugin.h" -RCSID("$Id: krbhst.c 21457 2007-07-10 12:53:25Z lha $"); +RCSID("$Id: krbhst.c 23447 2008-07-27 12:09:05Z lha $"); static int string_to_proto(const char *string) @@ -72,7 +72,8 @@ srv_find_realm(krb5_context context, krb5_krbhst_info ***res, int *count, proto_num = string_to_proto(proto); if(proto_num < 0) { - krb5_set_error_string(context, "unknown protocol `%s'", proto); + krb5_set_error_message(context, EINVAL, + "unknown protocol `%s'", proto); return EINVAL; } @@ -96,7 +97,7 @@ srv_find_realm(krb5_context context, krb5_krbhst_info ***res, int *count, *res = malloc(num_srv * sizeof(**res)); if(*res == NULL) { dns_free_data(r); - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } @@ -247,7 +248,7 @@ _krb5_krbhost_info_move(krb5_context context, /* trailing NUL is included in structure */ *to = calloc(1, sizeof(**to) + hostnamelen); if(*to == NULL) { - krb5_set_error_string(context, "malloc - out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } @@ -522,7 +523,8 @@ plugin_get_hosts(krb5_context context, struct krb5_plugin *list = NULL, *e; krb5_error_code ret; - ret = _krb5_plugin_find(context, PLUGIN_TYPE_DATA, "resolve", &list); + ret = _krb5_plugin_find(context, PLUGIN_TYPE_DATA, + KRB5_PLUGIN_LOCATE, &list); if(ret != 0 || list == NULL) return; @@ -539,8 +541,9 @@ plugin_get_hosts(krb5_context context, (*service->init)(context, &ctx); ret = (*service->lookup)(ctx, type, kd->realm, 0, 0, add_locate, kd); (*service->fini)(ctx); - if (ret) { - krb5_set_error_string(context, "Plugin failed to lookup"); + if (ret && ret != KRB5_PLUGIN_NO_HANDLE) { + krb5_set_error_message(context, ret, + "Locate plugin failed to lookup: %d", ret); break; } } @@ -832,7 +835,7 @@ krb5_krbhst_init_flags(krb5_context context, def_port = ntohs(krb5_getportbyname (context, "krb524", "udp", 4444)); break; default: - krb5_set_error_string(context, "unknown krbhst type (%u)", type); + krb5_set_error_message(context, ENOTTY, "unknown krbhst type (%u)", type); return ENOTTY; } if((kd = common_init(context, realm, flags)) == NULL) @@ -920,7 +923,8 @@ gethostlist(krb5_context context, const char *realm, while(krb5_krbhst_next(context, handle, &hostinfo) == 0) nhost++; if(nhost == 0) { - krb5_set_error_string(context, "No KDC found for realm %s", realm); + krb5_set_error_message(context, KRB5_KDC_UNREACH, + "No KDC found for realm %s", realm); return KRB5_KDC_UNREACH; } *hostlist = calloc(nhost + 1, sizeof(**hostlist)); diff --git a/source4/heimdal/lib/krb5/locate_plugin.h b/source4/heimdal/lib/krb5/locate_plugin.h index 251712c894..a342617d38 100644 --- a/source4/heimdal/lib/krb5/locate_plugin.h +++ b/source4/heimdal/lib/krb5/locate_plugin.h @@ -31,13 +31,15 @@ * SUCH DAMAGE. */ -/* $Id: locate_plugin.h 18998 2006-11-12 19:00:03Z lha $ */ +/* $Id: locate_plugin.h 23351 2008-07-15 11:22:39Z lha $ */ #ifndef HEIMDAL_KRB5_LOCATE_PLUGIN_H #define HEIMDAL_KRB5_LOCATE_PLUGIN_H 1 #include <krb5.h> +#define KRB5_PLUGIN_LOCATE "resolve" + enum locate_service_type { locate_service_kdc = 1, locate_service_master_kdc, diff --git a/source4/heimdal/lib/krb5/log.c b/source4/heimdal/lib/krb5/log.c index c04f50fd9a..721e3691ca 100644 --- a/source4/heimdal/lib/krb5/log.c +++ b/source4/heimdal/lib/krb5/log.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: log.c 19088 2006-11-21 08:08:46Z lha $"); +RCSID("$Id: log.c 23443 2008-07-27 12:07:25Z lha $"); struct facility { int min; @@ -121,13 +121,13 @@ krb5_initlog(krb5_context context, { krb5_log_facility *f = calloc(1, sizeof(*f)); if(f == NULL) { - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } f->program = strdup(program); if(f->program == NULL){ free(f); - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } *fac = f; @@ -145,7 +145,7 @@ krb5_addlog_func(krb5_context context, { struct facility *fp = log_realloc(fac); if(fp == NULL) { - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } fp->min = min; @@ -187,7 +187,7 @@ open_syslog(krb5_context context, int i; if(sd == NULL) { - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } i = find_value(sev, syslogvals); @@ -242,7 +242,7 @@ open_file(krb5_context context, krb5_log_facility *fac, int min, int max, { struct file_data *fd = malloc(sizeof(*fd)); if(fd == NULL) { - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } fd->filename = filename; @@ -277,7 +277,8 @@ krb5_addlog_dest(krb5_context context, krb5_log_facility *f, const char *orig) if(n){ p = strchr(p, '/'); if(p == NULL) { - krb5_set_error_string (context, "failed to parse \"%s\"", orig); + krb5_set_error_message(context, HEIM_ERR_LOG_PARSE, + "failed to parse \"%s\"", orig); return HEIM_ERR_LOG_PARSE; } p++; @@ -292,7 +293,7 @@ krb5_addlog_dest(krb5_context context, krb5_log_facility *f, const char *orig) int keep_open = 0; fn = strdup(p + 5); if(fn == NULL) { - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } if(p[4] == '='){ @@ -300,16 +301,17 @@ krb5_addlog_dest(krb5_context context, krb5_log_facility *f, const char *orig) O_TRUNC | O_APPEND, 0666); if(i < 0) { ret = errno; - krb5_set_error_string (context, "open(%s): %s", fn, + krb5_set_error_message(context, ret, "open(%s): %s", fn, strerror(ret)); free(fn); return ret; } + rk_cloexec(i); file = fdopen(i, "a"); if(file == NULL){ ret = errno; close(i); - krb5_set_error_string (context, "fdopen(%s): %s", fn, + krb5_set_error_message(context, ret, "fdopen(%s): %s", fn, strerror(ret)); free(fn); return ret; @@ -333,8 +335,8 @@ krb5_addlog_dest(krb5_context context, krb5_log_facility *f, const char *orig) strlcpy(facility, "AUTH", sizeof(facility)); ret = open_syslog(context, f, min, max, severity, facility); }else{ - krb5_set_error_string (context, "unknown log type: %s", p); ret = HEIM_ERR_LOG_PARSE; /* XXX */ + krb5_set_error_message (context, ret, "unknown log type: %s", p); } return ret; } diff --git a/source4/heimdal/lib/krb5/mcache.c b/source4/heimdal/lib/krb5/mcache.c index 01bcb09d3b..682f9f6abd 100644 --- a/source4/heimdal/lib/krb5/mcache.c +++ b/source4/heimdal/lib/krb5/mcache.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: mcache.c 22107 2007-12-03 17:22:51Z lha $"); +RCSID("$Id: mcache.c 23316 2008-06-23 04:32:32Z lha $"); typedef struct krb5_mcache { char *name; @@ -119,7 +119,7 @@ mcc_resolve(krb5_context context, krb5_ccache *id, const char *res) m = mcc_alloc(res); if (m == NULL) { - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, KRB5_CC_NOMEM, "malloc: out of memory"); return KRB5_CC_NOMEM; } @@ -138,7 +138,7 @@ mcc_gen_new(krb5_context context, krb5_ccache *id) m = mcc_alloc(NULL); if (m == NULL) { - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, KRB5_CC_NOMEM, "malloc: out of memory"); return KRB5_CC_NOMEM; } @@ -237,7 +237,7 @@ mcc_store_cred(krb5_context context, l = malloc (sizeof(*l)); if (l == NULL) { - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, KRB5_CC_NOMEM, "malloc: out of memory"); return KRB5_CC_NOMEM; } l->next = m->creds; @@ -348,7 +348,7 @@ mcc_get_cache_first(krb5_context context, krb5_cc_cursor *cursor) iter = calloc(1, sizeof(*iter)); if (iter == NULL) { - krb5_set_error_string(context, "malloc - out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } @@ -439,7 +439,7 @@ mcc_default_name(krb5_context context, char **str) { *str = strdup("MEMORY:"); if (*str == NULL) { - krb5_set_error_string(context, "out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } return 0; @@ -452,7 +452,8 @@ mcc_default_name(krb5_context context, char **str) * @ingroup krb5_ccache */ -const krb5_cc_ops krb5_mcc_ops = { +KRB5_LIB_VARIABLE const krb5_cc_ops krb5_mcc_ops = { + KRB5_CC_OPS_VERSION, "MEMORY", mcc_get_name, mcc_resolve, diff --git a/source4/heimdal/lib/krb5/mk_priv.c b/source4/heimdal/lib/krb5/mk_priv.c index 87e429af8c..3b4b6e30b7 100644 --- a/source4/heimdal/lib/krb5/mk_priv.c +++ b/source4/heimdal/lib/krb5/mk_priv.c @@ -33,7 +33,7 @@ #include <krb5_locl.h> -RCSID("$Id: mk_priv.c 16680 2006-02-01 12:39:26Z lha $"); +RCSID("$Id: mk_priv.c 23297 2008-06-23 03:28:53Z lha $"); krb5_error_code KRB5_LIB_FUNCTION @@ -138,7 +138,7 @@ krb5_mk_priv(krb5_context context, ret = krb5_data_copy(outbuf, buf + buf_size - len, len); if (ret) { - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); free(buf); return ENOMEM; } diff --git a/source4/heimdal/lib/krb5/mk_rep.c b/source4/heimdal/lib/krb5/mk_rep.c index 570a837201..069df42e26 100644 --- a/source4/heimdal/lib/krb5/mk_rep.c +++ b/source4/heimdal/lib/krb5/mk_rep.c @@ -33,7 +33,7 @@ #include <krb5_locl.h> -RCSID("$Id: mk_rep.c 13863 2004-05-25 21:46:46Z lha $"); +RCSID("$Id: mk_rep.c 23316 2008-06-23 04:32:32Z lha $"); krb5_error_code KRB5_LIB_FUNCTION krb5_mk_rep(krb5_context context, @@ -61,18 +61,18 @@ krb5_mk_rep(krb5_context context, auth_context, auth_context->keyblock); if(ret) { - krb5_set_error_string (context, - "krb5_mk_rep: generating subkey"); free_EncAPRepPart(&body); + krb5_set_error_message(context, ret, + "krb5_mk_rep: generating subkey"); return ret; } } ret = krb5_copy_keyblock(context, auth_context->local_subkey, &body.subkey); if (ret) { - krb5_set_error_string (context, - "krb5_copy_keyblock: out of memory"); free_EncAPRepPart(&body); + krb5_set_error_message(context, ENOMEM, + "krb5_copy_keyblock: out of memory"); return ENOMEM; } } else @@ -84,7 +84,7 @@ krb5_mk_rep(krb5_context context, &auth_context->local_seqnumber); ALLOC(body.seq_number, 1); if (body.seq_number == NULL) { - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); free_EncAPRepPart(&body); return ENOMEM; } diff --git a/source4/heimdal/lib/krb5/n-fold.c b/source4/heimdal/lib/krb5/n-fold.c index 53528cfd1f..287f8cf64f 100644 --- a/source4/heimdal/lib/krb5/n-fold.c +++ b/source4/heimdal/lib/krb5/n-fold.c @@ -32,7 +32,7 @@ #include "krb5_locl.h" -RCSID("$Id: n-fold.c 22190 2007-12-06 16:24:22Z lha $"); +RCSID("$Id: n-fold.c 22923 2008-04-08 14:51:33Z lha $"); static krb5_error_code rr13(unsigned char *buf, size_t len) diff --git a/source4/heimdal/lib/krb5/pac.c b/source4/heimdal/lib/krb5/pac.c index 0b44ca1da3..fbc754efda 100644 --- a/source4/heimdal/lib/krb5/pac.c +++ b/source4/heimdal/lib/krb5/pac.c @@ -34,7 +34,7 @@ #include "krb5_locl.h" #include <wind.h> -RCSID("$Id: pac.c 22562 2008-02-03 17:38:35Z lha $"); +RCSID("$Id: pac.c 23316 2008-06-23 04:32:32Z lha $"); struct PAC_INFO_BUFFER { uint32_t type; @@ -93,14 +93,14 @@ krb5_pac_parse(krb5_context context, const void *ptr, size_t len, p = calloc(1, sizeof(*p)); if (p == NULL) { ret = ENOMEM; - krb5_set_error_string(context, "out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } sp = krb5_storage_from_readonly_mem(ptr, len); if (sp == NULL) { ret = ENOMEM; - krb5_set_error_string(context, "out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } krb5_storage_set_flags(sp, KRB5_STORAGE_BYTEORDER_LE); @@ -108,21 +108,21 @@ krb5_pac_parse(krb5_context context, const void *ptr, size_t len, CHECK(ret, krb5_ret_uint32(sp, &tmp), out); CHECK(ret, krb5_ret_uint32(sp, &tmp2), out); if (tmp < 1) { - krb5_set_error_string(context, "PAC have too few buffer"); ret = EINVAL; /* Too few buffers */ + krb5_set_error_message(context, ret, "PAC have too few buffer"); goto out; } if (tmp2 != 0) { - krb5_set_error_string(context, "PAC have wrong version"); ret = EINVAL; /* Wrong version */ + krb5_set_error_message(context, ret, "PAC have wrong version"); goto out; } p->pac = calloc(1, sizeof(*p->pac) + (sizeof(p->pac->buffers[0]) * (tmp - 1))); if (p->pac == NULL) { - krb5_set_error_string(context, "out of memory"); ret = ENOMEM; + krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } @@ -143,51 +143,52 @@ krb5_pac_parse(krb5_context context, const void *ptr, size_t len, /* consistency checks */ if (p->pac->buffers[i].offset_lo & (PAC_ALIGNMENT - 1)) { - krb5_set_error_string(context, "PAC out of allignment"); ret = EINVAL; + krb5_set_error_message(context, ret, "PAC out of allignment"); goto out; } if (p->pac->buffers[i].offset_hi) { - krb5_set_error_string(context, "PAC high offset set"); ret = EINVAL; + krb5_set_error_message(context, ret, "PAC high offset set"); goto out; } if (p->pac->buffers[i].offset_lo > len) { - krb5_set_error_string(context, "PAC offset off end"); ret = EINVAL; + krb5_set_error_message(context, ret, "PAC offset off end"); goto out; } if (p->pac->buffers[i].offset_lo < header_end) { - krb5_set_error_string(context, "PAC offset inside header: %d %d", - p->pac->buffers[i].offset_lo, header_end); ret = EINVAL; + krb5_set_error_message(context, ret, "PAC offset inside header: %lu %lu", + (unsigned long)p->pac->buffers[i].offset_lo, + (unsigned long)header_end); goto out; } if (p->pac->buffers[i].buffersize > len - p->pac->buffers[i].offset_lo){ - krb5_set_error_string(context, "PAC length off end"); ret = EINVAL; + krb5_set_error_message(context, ret, "PAC length off end"); goto out; } /* let save pointer to data we need later */ if (p->pac->buffers[i].type == PAC_SERVER_CHECKSUM) { if (p->server_checksum) { - krb5_set_error_string(context, "PAC have two server checksums"); ret = EINVAL; + krb5_set_error_message(context, ret, "PAC have two server checksums"); goto out; } p->server_checksum = &p->pac->buffers[i]; } else if (p->pac->buffers[i].type == PAC_PRIVSVR_CHECKSUM) { if (p->privsvr_checksum) { - krb5_set_error_string(context, "PAC have two KDC checksums"); ret = EINVAL; + krb5_set_error_message(context, ret, "PAC have two KDC checksums"); goto out; } p->privsvr_checksum = &p->pac->buffers[i]; } else if (p->pac->buffers[i].type == PAC_LOGON_NAME) { if (p->logon_name) { - krb5_set_error_string(context, "PAC have two logon names"); ret = EINVAL; + krb5_set_error_message(context, ret, "PAC have two logon names"); goto out; } p->logon_name = &p->pac->buffers[i]; @@ -224,14 +225,14 @@ krb5_pac_init(krb5_context context, krb5_pac *pac) p = calloc(1, sizeof(*p)); if (p == NULL) { - krb5_set_error_string(context, "out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } p->pac = calloc(1, sizeof(*p->pac)); if (p->pac == NULL) { free(p); - krb5_set_error_string(context, "out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } @@ -239,7 +240,7 @@ krb5_pac_init(krb5_context context, krb5_pac *pac) if (ret) { free (p->pac); free(p); - krb5_set_error_string(context, "out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); return ret; } @@ -262,7 +263,7 @@ krb5_pac_add_buffer(krb5_context context, krb5_pac p, ptr = realloc(p->pac, sizeof(*p->pac) + (sizeof(p->pac->buffers[0]) * len)); if (ptr == NULL) { - krb5_set_error_string(context, "out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } p->pac = ptr; @@ -280,7 +281,7 @@ krb5_pac_add_buffer(krb5_context context, krb5_pac p, old_end = p->data.length; len = p->data.length + data->length + PAC_INFO_BUFFER_SIZE; if (len < p->data.length) { - krb5_set_error_string(context, "integer overrun"); + krb5_set_error_message(context, EINVAL, "integer overrun"); return EINVAL; } @@ -289,7 +290,7 @@ krb5_pac_add_buffer(krb5_context context, krb5_pac p, ret = krb5_data_realloc(&p->data, len); if (ret) { - krb5_set_error_string(context, "out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); return ret; } @@ -330,7 +331,7 @@ krb5_pac_get_buffer(krb5_context context, krb5_pac p, if (type == PAC_PRIVSVR_CHECKSUM || type == PAC_SERVER_CHECKSUM) { ret = krb5_data_alloc(data, 16); if (ret) { - krb5_set_error_string(context, "out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); return ret; } memset(data->data, 0, data->length); @@ -346,13 +347,13 @@ krb5_pac_get_buffer(krb5_context context, krb5_pac p, ret = krb5_data_copy(data, (unsigned char *)p->data.data + offset, len); if (ret) { - krb5_set_error_string(context, "Out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); return ret; } return 0; } - krb5_set_error_string(context, "No PAC buffer of type %lu was found", - (unsigned long)type); + krb5_set_error_message(context, ENOENT, "No PAC buffer of type %lu was found", + (unsigned long)type); return ENOENT; } @@ -371,7 +372,7 @@ krb5_pac_get_types(krb5_context context, *types = calloc(p->pac->numbuffers, sizeof(*types)); if (*types == NULL) { *len = 0; - krb5_set_error_string(context, "out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } for (i = 0; i < p->pac->numbuffers; i++) @@ -415,7 +416,7 @@ verify_checksum(krb5_context context, sp = krb5_storage_from_mem((char *)data->data + sig->offset_lo, sig->buffersize); if (sp == NULL) { - krb5_set_error_string(context, "out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } krb5_storage_set_flags(sp, KRB5_STORAGE_BYTEORDER_LE); @@ -426,21 +427,21 @@ verify_checksum(krb5_context context, sig->buffersize - krb5_storage_seek(sp, 0, SEEK_CUR); cksum.checksum.data = malloc(cksum.checksum.length); if (cksum.checksum.data == NULL) { - krb5_set_error_string(context, "out of memory"); ret = ENOMEM; + krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } ret = krb5_storage_read(sp, cksum.checksum.data, cksum.checksum.length); if (ret != cksum.checksum.length) { - krb5_set_error_string(context, "PAC checksum missing checksum"); ret = EINVAL; + krb5_set_error_message(context, ret, "PAC checksum missing checksum"); goto out; } if (!krb5_checksum_is_keyed(context, cksum.cksumtype)) { - krb5_set_error_string (context, "Checksum type %d not keyed", - cksum.cksumtype); ret = EINVAL; + krb5_set_error_message(context, ret, "Checksum type %d not keyed", + cksum.cksumtype); goto out; } @@ -487,7 +488,7 @@ create_checksum(krb5_context context, return ret; if (cksum.checksum.length != siglen) { - krb5_set_error_string(context, "pac checksum wrong length"); + krb5_set_error_message(context, EINVAL, "pac checksum wrong length"); free_Checksum(&cksum); return EINVAL; } @@ -530,7 +531,7 @@ verify_logonname(krb5_context context, sp = krb5_storage_from_readonly_mem((const char *)data->data + logon_name->offset_lo, logon_name->buffersize); if (sp == NULL) { - krb5_set_error_string(context, "Out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } @@ -545,27 +546,27 @@ verify_logonname(krb5_context context, t2 = ((uint64_t)time2 << 32) | time1; if (t1 != t2) { krb5_storage_free(sp); - krb5_set_error_string(context, "PAC timestamp mismatch"); + krb5_set_error_message(context, EINVAL, "PAC timestamp mismatch"); return EINVAL; } } CHECK(ret, krb5_ret_uint16(sp, &len), out); if (len == 0) { krb5_storage_free(sp); - krb5_set_error_string(context, "PAC logon name length missing"); + krb5_set_error_message(context, EINVAL, "PAC logon name length missing"); return EINVAL; } s = malloc(len); if (s == NULL) { krb5_storage_free(sp); - krb5_set_error_string(context, "Out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } ret = krb5_storage_read(sp, s, len); if (ret != len) { krb5_storage_free(sp); - krb5_set_error_string(context, "Failed to read PAC logon name"); + krb5_set_error_message(context, EINVAL, "Failed to read PAC logon name"); return EINVAL; } krb5_storage_free(sp); @@ -577,33 +578,33 @@ verify_logonname(krb5_context context, ucs2 = malloc(sizeof(ucs2[0]) * ucs2len); if (ucs2 == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } ret = wind_ucs2read(s, len, &flags, ucs2, &ucs2len); free(s); if (ret) { free(ucs2); - krb5_set_error_string(context, "Failed to convert string to UCS-2"); + krb5_set_error_message(context, ret, "Failed to convert string to UCS-2"); return ret; } ret = wind_ucs2utf8_length(ucs2, ucs2len, &u8len); if (ret) { free(ucs2); - krb5_set_error_string(context, "Failed to count length of UCS-2 string"); + krb5_set_error_message(context, ret, "Failed to count length of UCS-2 string"); return ret; } u8len += 1; /* Add space for NUL */ s = malloc(u8len); if (s == NULL) { free(ucs2); - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } ret = wind_ucs2utf8(ucs2, ucs2len, s, &u8len); free(ucs2); if (ret) { - krb5_set_error_string(context, "Failed to convert to UTF-8"); + krb5_set_error_message(context, ret, "Failed to convert to UTF-8"); return ret; } } @@ -613,8 +614,8 @@ verify_logonname(krb5_context context, return ret; if (krb5_principal_compare_any_realm(context, principal, p2) != TRUE) { - krb5_set_error_string(context, "PAC logon name mismatch"); ret = EINVAL; + krb5_set_error_message(context, ret, "PAC logon name mismatch"); } krb5_free_principal(context, p2); return ret; @@ -644,7 +645,7 @@ build_logon_name(krb5_context context, sp = krb5_storage_emem(); if (sp == NULL) { - krb5_set_error_string(context, "out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } krb5_storage_set_flags(sp, KRB5_STORAGE_BYTEORDER_LE); @@ -710,15 +711,15 @@ krb5_pac_verify(krb5_context context, krb5_error_code ret; if (pac->server_checksum == NULL) { - krb5_set_error_string(context, "PAC missing server checksum"); + krb5_set_error_message(context, EINVAL, "PAC missing server checksum"); return EINVAL; } if (pac->privsvr_checksum == NULL) { - krb5_set_error_string(context, "PAC missing kdc checksum"); + krb5_set_error_message(context, EINVAL, "PAC missing kdc checksum"); return EINVAL; } if (pac->logon_name == NULL) { - krb5_set_error_string(context, "PAC missing logon name"); + krb5_set_error_message(context, EINVAL, "PAC missing logon name"); return EINVAL; } @@ -795,7 +796,7 @@ fill_zeros(krb5_context context, krb5_storage *sp, size_t len) l = sizeof(zeros); sret = krb5_storage_write(sp, zeros, l); if (sret <= 0) { - krb5_set_error_string(context, "out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } len -= sret; @@ -823,7 +824,7 @@ pac_checksum(krb5_context context, return ret; if (krb5_checksum_is_keyed(context, cktype) == FALSE) { - krb5_set_error_string(context, "PAC checksum type is not keyed"); + krb5_set_error_message(context, EINVAL, "PAC checksum type is not keyed"); return EINVAL; } @@ -868,7 +869,7 @@ _krb5_pac_sign(krb5_context context, ptr = realloc(p->pac, sizeof(*p->pac) + (sizeof(p->pac->buffers[0]) * (p->pac->numbuffers + num - 1))); if (ptr == NULL) { - krb5_set_error_string(context, "out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } p->pac = ptr; @@ -906,7 +907,7 @@ _krb5_pac_sign(krb5_context context, /* Encode PAC */ sp = krb5_storage_emem(); if (sp == NULL) { - krb5_set_error_string(context, "out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } krb5_storage_set_flags(sp, KRB5_STORAGE_BYTEORDER_LE); @@ -914,7 +915,7 @@ _krb5_pac_sign(krb5_context context, spdata = krb5_storage_emem(); if (spdata == NULL) { krb5_storage_free(sp); - krb5_set_error_string(context, "out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } krb5_storage_set_flags(spdata, KRB5_STORAGE_BYTEORDER_LE); @@ -953,8 +954,8 @@ _krb5_pac_sign(krb5_context context, sret = krb5_storage_write(spdata, ptr, len); if (sret != len) { - krb5_set_error_string(context, "out of memory"); ret = ENOMEM; + krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } /* XXX if not aligned, fill_zeros */ @@ -985,21 +986,21 @@ _krb5_pac_sign(krb5_context context, /* export PAC */ ret = krb5_storage_to_data(spdata, &d); if (ret) { - krb5_set_error_string(context, "out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } ret = krb5_storage_write(sp, d.data, d.length); if (ret != d.length) { krb5_data_free(&d); - krb5_set_error_string(context, "out of memory"); ret = ENOMEM; + krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } krb5_data_free(&d); ret = krb5_storage_to_data(sp, &d); if (ret) { - krb5_set_error_string(context, "out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } diff --git a/source4/heimdal/lib/krb5/padata.c b/source4/heimdal/lib/krb5/padata.c index b2b70f52e7..9dc3fe69a5 100644 --- a/source4/heimdal/lib/krb5/padata.c +++ b/source4/heimdal/lib/krb5/padata.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: padata.c 15469 2005-06-17 04:28:35Z lha $"); +RCSID("$Id: padata.c 23300 2008-06-23 03:29:22Z lha $"); PA_DATA * krb5_find_padata(PA_DATA *val, unsigned len, int type, int *idx) @@ -52,7 +52,7 @@ krb5_padata_add(krb5_context context, METHOD_DATA *md, pa = realloc (md->val, (md->len + 1) * sizeof(*md->val)); if (pa == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } md->val = pa; diff --git a/source4/heimdal/lib/krb5/pkinit.c b/source4/heimdal/lib/krb5/pkinit.c index 4a585bff07..1e82971c6e 100755 --- a/source4/heimdal/lib/krb5/pkinit.c +++ b/source4/heimdal/lib/krb5/pkinit.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: pkinit.c 22673 2008-03-10 15:00:05Z lha $"); +RCSID("$Id: pkinit.c 23450 2008-07-27 12:10:10Z lha $"); struct krb5_dh_moduli { char *name; @@ -45,8 +45,6 @@ struct krb5_dh_moduli { #ifdef PKINIT -#include <heim_asn1.h> -#include <rfc2459_asn1.h> #include <cms_asn1.h> #include <pkcs8_asn1.h> #include <pkcs9_asn1.h> @@ -56,22 +54,6 @@ struct krb5_dh_moduli { #include <der.h> -#include <hx509.h> - -enum { - COMPAT_WIN2K = 1, - COMPAT_IETF = 2 -}; - -struct krb5_pk_identity { - hx509_context hx509ctx; - hx509_verify_ctx verify_ctx; - hx509_certs certs; - hx509_certs anchors; - hx509_certs certpool; - hx509_revoke_ctx revokectx; -}; - struct krb5_pk_cert { hx509_cert cert; }; @@ -82,7 +64,7 @@ struct krb5_pk_init_ctx_data { krb5_data *clientDHNonce; struct krb5_dh_moduli **m; hx509_peer_info peer; - int type; + enum krb5_pk_type type; unsigned int require_binding:1; unsigned int require_eku:1; unsigned int require_krbtgt_otherName:1; @@ -91,11 +73,11 @@ struct krb5_pk_init_ctx_data { }; static void -_krb5_pk_copy_error(krb5_context context, - hx509_context hx509ctx, - int hxret, - const char *fmt, - ...) +pk_copy_error(krb5_context context, + hx509_context hx509ctx, + int hxret, + const char *fmt, + ...) __attribute__ ((format (printf, 4, 5))); /* @@ -132,7 +114,7 @@ integer_to_BN(krb5_context context, const char *field, const heim_integer *f) bn = BN_bin2bn((const unsigned char *)f->data, f->length, NULL); if (bn == NULL) { - krb5_set_error_string(context, "PKINIT: parsing BN failed %s", field); + krb5_set_error_message(context, ENOMEM, "PKINIT: parsing BN failed %s", field); return NULL; } BN_set_negative(bn, f->negative); @@ -167,16 +149,16 @@ find_cert(krb5_context context, struct krb5_pk_identity *id, for (i = 0; i < sizeof(cf)/sizeof(cf[0]); i++) { ret = hx509_query_match_eku(q, cf[i].oid); if (ret) { - _krb5_pk_copy_error(context, id->hx509ctx, ret, - "Failed setting %s OID", cf[i].type); + pk_copy_error(context, id->hx509ctx, ret, + "Failed setting %s OID", cf[i].type); return ret; } ret = hx509_certs_find(id->hx509ctx, id->certs, q, cert); if (ret == 0) break; - _krb5_pk_copy_error(context, id->hx509ctx, ret, - "Failed cert for finding %s OID", cf[i].type); + pk_copy_error(context, id->hx509ctx, ret, + "Failed cert for finding %s OID", cf[i].type); } return ret; } @@ -196,8 +178,8 @@ create_signature(krb5_context context, ret = hx509_query_alloc(id->hx509ctx, &q); if (ret) { - _krb5_pk_copy_error(context, id->hx509ctx, ret, - "Allocate query to find signing certificate"); + pk_copy_error(context, id->hx509ctx, ret, + "Allocate query to find signing certificate"); return ret; } @@ -222,8 +204,8 @@ create_signature(krb5_context context, sd_data); hx509_cert_free(cert); if (ret) { - _krb5_pk_copy_error(context, id->hx509ctx, ret, - "Create CMS signedData"); + pk_copy_error(context, id->hx509ctx, ret, + "Create CMS signedData"); return ret; } @@ -374,7 +356,7 @@ build_auth_pack(krb5_context context, ALLOC(a->pkAuthenticator.paChecksum, 1); if (a->pkAuthenticator.paChecksum == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } @@ -524,7 +506,7 @@ pk_mk_padata(krb5_context context, krb5_data_zero(&sd_buf); memset(&content_info, 0, sizeof(content_info)); - if (ctx->type == COMPAT_WIN2K) { + if (ctx->type == PKINIT_WIN2K) { AuthPack_Win2k ap; krb5_timestamp sec; int32_t usec; @@ -554,14 +536,15 @@ pk_mk_padata(krb5_context context, &ap, &size, ret); free_AuthPack_Win2k(&ap); if (ret) { - krb5_set_error_string(context, "AuthPack_Win2k: %d", ret); + krb5_set_error_message(context, ret, "AuthPack_Win2k: %d", + (int)ret); goto out; } if (buf.length != size) krb5_abortx(context, "internal ASN1 encoder error"); oid = oid_id_pkcs7_data(); - } else if (ctx->type == COMPAT_IETF) { + } else if (ctx->type == PKINIT_27) { AuthPack ap; memset(&ap, 0, sizeof(ap)); @@ -575,7 +558,7 @@ pk_mk_padata(krb5_context context, ASN1_MALLOC_ENCODE(AuthPack, buf.data, buf.length, &ap, &size, ret); free_AuthPack(&ap); if (ret) { - krb5_set_error_string(context, "AuthPack: %d", ret); + krb5_set_error_message(context, ret, "AuthPack: %d", (int)ret); goto out; } if (buf.length != size) @@ -594,12 +577,12 @@ pk_mk_padata(krb5_context context, ret = hx509_cms_wrap_ContentInfo(oid_id_pkcs7_signedData(), &sd_buf, &buf); krb5_data_free(&sd_buf); if (ret) { - krb5_set_error_string(context, - "ContentInfo wrapping of signedData failed"); + krb5_set_error_message(context, ret, + "ContentInfo wrapping of signedData failed"); goto out; } - if (ctx->type == COMPAT_WIN2K) { + if (ctx->type == PKINIT_WIN2K) { PA_PK_AS_REQ_Win2k winreq; pa_type = KRB5_PADATA_PK_AS_REQ_WIN; @@ -612,7 +595,7 @@ pk_mk_padata(krb5_context context, &winreq, &size, ret); free_PA_PK_AS_REQ_Win2k(&winreq); - } else if (ctx->type == COMPAT_IETF) { + } else if (ctx->type == PKINIT_27) { PA_PK_AS_REQ req; pa_type = KRB5_PADATA_PK_AS_REQ; @@ -624,14 +607,15 @@ pk_mk_padata(krb5_context context, req.trustedCertifiers = calloc(1, sizeof(*req.trustedCertifiers)); if (req.trustedCertifiers == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + ret = ENOMEM; + krb5_set_error_message(context, ret, "malloc: out of memory"); free_PA_PK_AS_REQ(&req); goto out; } ret = build_edi(context, ctx->id->hx509ctx, ctx->id->anchors, req.trustedCertifiers); if (ret) { - krb5_set_error_string(context, "pk-init: failed to build trustedCertifiers"); + krb5_set_error_message(context, ret, "pk-init: failed to build trustedCertifiers"); free_PA_PK_AS_REQ(&req); goto out; } @@ -646,7 +630,7 @@ pk_mk_padata(krb5_context context, } else krb5_abortx(context, "internal pkinit error"); if (ret) { - krb5_set_error_string(context, "PA-PK-AS-REQ %d", ret); + krb5_set_error_message(context, ret, "PA-PK-AS-REQ %d", (int)ret); goto out; } if (buf.length != size) @@ -656,10 +640,10 @@ pk_mk_padata(krb5_context context, if (ret) free(buf.data); - if (ret == 0 && ctx->type == COMPAT_WIN2K) + if (ret == 0 && ctx->type == PKINIT_WIN2K) krb5_padata_add(context, md, KRB5_PADATA_PK_AS_09_BINDING, NULL, 0); -out: + out: free_ContentInfo(&content_info); return ret; @@ -691,9 +675,9 @@ _krb5_pk_mk_padata(krb5_context context, req_body->realm, "pkinit_win2k_require_binding", NULL); - ctx->type = COMPAT_WIN2K; + ctx->type = PKINIT_WIN2K; } else - ctx->type = COMPAT_IETF; + ctx->type = PKINIT_27; ctx->require_eku = krb5_config_get_bool_default(context, NULL, @@ -753,8 +737,8 @@ _krb5_pk_verify_sign(krb5_context context, content, &signer_certs); if (ret) { - _krb5_pk_copy_error(context, id->hx509ctx, ret, - "CMS verify signed failed"); + pk_copy_error(context, id->hx509ctx, ret, + "CMS verify signed failed"); return ret; } @@ -767,12 +751,12 @@ _krb5_pk_verify_sign(krb5_context context, ret = hx509_get_one_cert(id->hx509ctx, signer_certs, &(*signer)->cert); if (ret) { - _krb5_pk_copy_error(context, id->hx509ctx, ret, - "Failed to get on of the signer certs"); + pk_copy_error(context, id->hx509ctx, ret, + "Failed to get on of the signer certs"); goto out; } -out: + out: hx509_certs_free(&signer_certs); if (ret) { if (*signer) { @@ -800,29 +784,28 @@ get_reply_key_win(krb5_context context, &key_pack, &size); if (ret) { - krb5_set_error_string(context, "PKINIT decoding reply key failed"); + krb5_set_error_message(context, ret, "PKINIT decoding reply key failed"); free_ReplyKeyPack_Win2k(&key_pack); return ret; } if (key_pack.nonce != nonce) { - krb5_set_error_string(context, "PKINIT enckey nonce is wrong"); + krb5_set_error_message(context, ret, "PKINIT enckey nonce is wrong"); free_ReplyKeyPack_Win2k(&key_pack); return KRB5KRB_AP_ERR_MODIFIED; } *key = malloc (sizeof (**key)); if (*key == NULL) { - krb5_set_error_string(context, "PKINIT failed allocating reply key"); free_ReplyKeyPack_Win2k(&key_pack); - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } ret = copy_EncryptionKey(&key_pack.replyKey, *key); free_ReplyKeyPack_Win2k(&key_pack); if (ret) { - krb5_set_error_string(context, "PKINIT failed copying reply key"); + krb5_set_error_message(context, ret, "PKINIT failed copying reply key"); free(*key); *key = NULL; } @@ -845,7 +828,7 @@ get_reply_key(krb5_context context, &key_pack, &size); if (ret) { - krb5_set_error_string(context, "PKINIT decoding reply key failed"); + krb5_set_error_message(context, ret, "PKINIT decoding reply key failed"); free_ReplyKeyPack(&key_pack); return ret; } @@ -876,16 +859,15 @@ get_reply_key(krb5_context context, *key = malloc (sizeof (**key)); if (*key == NULL) { - krb5_set_error_string(context, "PKINIT failed allocating reply key"); free_ReplyKeyPack(&key_pack); - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } ret = copy_EncryptionKey(&key_pack.replyKey, *key); free_ReplyKeyPack(&key_pack); if (ret) { - krb5_set_error_string(context, "PKINIT failed copying reply key"); + krb5_set_error_message(context, ret, "PKINIT failed copying reply key"); free(*key); *key = NULL; } @@ -907,7 +889,7 @@ pk_verify_host(krb5_context context, ret = hx509_cert_check_eku(ctx->id->hx509ctx, host->cert, oid_id_pkkdcekuoid(), 0); if (ret) { - krb5_set_error_string(context, "No PK-INIT KDC EKU in kdc certificate"); + krb5_set_error_message(context, ret, "No PK-INIT KDC EKU in kdc certificate"); return ret; } } @@ -920,8 +902,8 @@ pk_verify_host(krb5_context context, oid_id_pkinit_san(), &list); if (ret) { - krb5_set_error_string(context, "Failed to find the PK-INIT " - "subjectAltName in the KDC certificate"); + krb5_set_error_message(context, ret, "Failed to find the PK-INIT " + "subjectAltName in the KDC certificate"); return ret; } @@ -934,8 +916,8 @@ pk_verify_host(krb5_context context, &r, NULL); if (ret) { - krb5_set_error_string(context, "Failed to decode the PK-INIT " - "subjectAltName in the KDC certificate"); + krb5_set_error_message(context, ret, "Failed to decode the PK-INIT " + "subjectAltName in the KDC certificate"); break; } @@ -944,11 +926,11 @@ pk_verify_host(krb5_context context, strcmp(r.principalName.name_string.val[0], KRB5_TGS_NAME) != 0 || strcmp(r.principalName.name_string.val[1], realm) != 0 || strcmp(r.realm, realm) != 0) - { - krb5_set_error_string(context, "KDC have wrong realm name in " - "the certificate"); - ret = KRB5_KDC_ERR_INVALID_CERTIFICATE; - } + { + ret = KRB5_KDC_ERR_INVALID_CERTIFICATE; + krb5_set_error_message(context, ret, "KDC have wrong realm name in " + "the certificate"); + } free_KRB5PrincipalName(&r); if (ret) @@ -967,8 +949,8 @@ pk_verify_host(krb5_context context, hi->ai->ai_addr, hi->ai->ai_addrlen); if (ret) - krb5_set_error_string(context, "Address mismatch in " - "the KDC certificate"); + krb5_set_error_message(context, ret, "Address mismatch in " + "the KDC certificate"); } return ret; } @@ -993,7 +975,7 @@ pk_rd_pa_reply_enckey(krb5_context context, heim_oid contentType = { 0, NULL }; if (der_heim_oid_cmp(oid_id_pkcs7_envelopedData(), dataType)) { - krb5_set_error_string(context, "PKINIT: Invalid content type"); + krb5_set_error_message(context, EINVAL, "PKINIT: Invalid content type"); return EINVAL; } @@ -1003,11 +985,12 @@ pk_rd_pa_reply_enckey(krb5_context context, indata->data, indata->length, NULL, + 0, &contentType, &content); if (ret) { - _krb5_pk_copy_error(context, ctx->id->hx509ctx, ret, - "Failed to unenvelope CMS data in PK-INIT reply"); + pk_copy_error(context, ctx->id->hx509ctx, ret, + "Failed to unenvelope CMS data in PK-INIT reply"); return ret; } der_free_oid(&contentType); @@ -1031,14 +1014,14 @@ pk_rd_pa_reply_enckey(krb5_context context, #endif /* win2k uses ContentInfo */ - if (type == COMPAT_WIN2K) { + if (type == PKINIT_WIN2K) { heim_oid type; heim_octet_string out; ret = hx509_cms_unwrap_ContentInfo(&content, &type, &out, NULL); if (der_heim_oid_cmp(&type, oid_id_pkcs7_signedData())) { ret = EINVAL; /* XXX */ - krb5_set_error_string(context, "PKINIT: Invalid content type"); + krb5_set_error_message(context, ret, "PKINIT: Invalid content type"); der_free_oid(&type); der_free_octet_string(&out); goto out; @@ -1048,7 +1031,7 @@ pk_rd_pa_reply_enckey(krb5_context context, ret = krb5_data_copy(&content, out.data, out.length); der_free_octet_string(&out); if (ret) { - krb5_set_error_string(context, "PKINIT: out of memory"); + krb5_set_error_message(context, ret, "PKINIT: out of memory"); goto out; } } @@ -1070,28 +1053,28 @@ pk_rd_pa_reply_enckey(krb5_context context, } #if 0 - if (type == COMPAT_WIN2K) { + if (type == PKINIT_WIN2K) { if (der_heim_oid_cmp(&contentType, oid_id_pkcs7_data()) != 0) { - krb5_set_error_string(context, "PKINIT: reply key, wrong oid"); ret = KRB5KRB_AP_ERR_MSG_TYPE; + krb5_set_error_message(context, ret, "PKINIT: reply key, wrong oid"); goto out; } } else { if (der_heim_oid_cmp(&contentType, oid_id_pkrkeydata()) != 0) { - krb5_set_error_string(context, "PKINIT: reply key, wrong oid"); ret = KRB5KRB_AP_ERR_MSG_TYPE; + krb5_set_error_message(context, ret, "PKINIT: reply key, wrong oid"); goto out; } } #endif switch(type) { - case COMPAT_WIN2K: + case PKINIT_WIN2K: ret = get_reply_key(context, &content, req_buffer, key); if (ret != 0 && ctx->require_binding == 0) ret = get_reply_key_win(context, &content, nonce, key); break; - case COMPAT_IETF: + case PKINIT_27: ret = get_reply_key(context, &content, req_buffer, key); break; } @@ -1137,7 +1120,7 @@ pk_rd_pa_reply_dh(krb5_context context, memset(&kdc_dh_info, 0, sizeof(kdc_dh_info)); if (der_heim_oid_cmp(oid_id_pkcs7_signedData(), dataType)) { - krb5_set_error_string(context, "PKINIT: Invalid content type"); + krb5_set_error_message(context, EINVAL, "PKINIT: Invalid content type"); return EINVAL; } @@ -1157,8 +1140,8 @@ pk_rd_pa_reply_dh(krb5_context context, goto out; if (der_heim_oid_cmp(&contentType, oid_id_pkdhkeydata())) { - krb5_set_error_string(context, "pkinit - dh reply contains wrong oid"); ret = KRB5KRB_AP_ERR_MSG_TYPE; + krb5_set_error_message(context, ret, "pkinit - dh reply contains wrong oid"); goto out; } @@ -1168,35 +1151,35 @@ pk_rd_pa_reply_dh(krb5_context context, &size); if (ret) { - krb5_set_error_string(context, "pkinit - " - "failed to decode KDC DH Key Info"); + krb5_set_error_message(context, ret, "pkinit - " + "failed to decode KDC DH Key Info"); goto out; } if (kdc_dh_info.nonce != nonce) { - krb5_set_error_string(context, "PKINIT: DH nonce is wrong"); ret = KRB5KRB_AP_ERR_MODIFIED; + krb5_set_error_message(context, ret, "PKINIT: DH nonce is wrong"); goto out; } if (kdc_dh_info.dhKeyExpiration) { if (k_n == NULL) { - krb5_set_error_string(context, "pkinit; got key expiration " - "without server nonce"); ret = KRB5KRB_ERR_GENERIC; + krb5_set_error_message(context, ret, "pkinit; got key expiration " + "without server nonce"); goto out; } if (c_n == NULL) { - krb5_set_error_string(context, "pkinit; got DH reuse but no " - "client nonce"); ret = KRB5KRB_ERR_GENERIC; + krb5_set_error_message(context, ret, "pkinit; got DH reuse but no " + "client nonce"); goto out; } } else { if (k_n) { - krb5_set_error_string(context, "pkinit: got server nonce " - "without key expiration"); ret = KRB5KRB_ERR_GENERIC; + krb5_set_error_message(context, ret, "pkinit: got server nonce " + "without key expiration"); goto out; } c_n = NULL; @@ -1210,15 +1193,15 @@ pk_rd_pa_reply_dh(krb5_context context, DHPublicKey k; ret = decode_DHPublicKey(p, size, &k, NULL); if (ret) { - krb5_set_error_string(context, "pkinit: can't decode " - "without key expiration"); + krb5_set_error_message(context, ret, "pkinit: can't decode " + "without key expiration"); goto out; } kdc_dh_pubkey = integer_to_BN(context, "DHPublicKey", &k); free_DHPublicKey(&k); if (kdc_dh_pubkey == NULL) { - ret = KRB5KRB_ERR_GENERIC; + ret = ENOMEM; goto out; } } @@ -1230,8 +1213,8 @@ pk_rd_pa_reply_dh(krb5_context context, dh_gen_key = malloc(size); if (dh_gen_key == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); ret = ENOMEM; + krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } memset(dh_gen_key, 0, size - dh_gen_keylen); @@ -1239,16 +1222,16 @@ pk_rd_pa_reply_dh(krb5_context context, dh_gen_keylen = DH_compute_key(dh_gen_key + (size - dh_gen_keylen), kdc_dh_pubkey, ctx->dh); if (dh_gen_keylen == -1) { - krb5_set_error_string(context, - "PKINIT: Can't compute Diffie-Hellman key"); ret = KRB5KRB_ERR_GENERIC; + krb5_set_error_message(context, ret, + "PKINIT: Can't compute Diffie-Hellman key"); goto out; } *key = malloc (sizeof (**key)); if (*key == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); ret = ENOMEM; + krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } @@ -1258,8 +1241,8 @@ pk_rd_pa_reply_dh(krb5_context context, c_n, k_n, *key); if (ret) { - krb5_set_error_string(context, - "PKINIT: can't create key from DH key"); + krb5_set_error_message(context, ret, + "PKINIT: can't create key from DH key"); free(*key); *key = NULL; goto out; @@ -1298,13 +1281,13 @@ _krb5_pk_rd_pa_reply(krb5_context context, size_t size; /* Check for IETF PK-INIT first */ - if (ctx->type == COMPAT_IETF) { + if (ctx->type == PKINIT_27) { PA_PK_AS_REP rep; heim_octet_string os, data; heim_oid oid; if (pa->padata_type != KRB5_PADATA_PK_AS_REP) { - krb5_set_error_string(context, "PKINIT: wrong padata recv"); + krb5_set_error_message(context, EINVAL, "PKINIT: wrong padata recv"); return EINVAL; } @@ -1313,7 +1296,7 @@ _krb5_pk_rd_pa_reply(krb5_context context, &rep, &size); if (ret) { - krb5_set_error_string(context, "Failed to decode pkinit AS rep"); + krb5_set_error_message(context, ret, "Failed to decode pkinit AS rep"); return ret; } @@ -1326,15 +1309,15 @@ _krb5_pk_rd_pa_reply(krb5_context context, break; default: free_PA_PK_AS_REP(&rep); - krb5_set_error_string(context, "PKINIT: -27 reply " - "invalid content type"); + krb5_set_error_message(context, EINVAL, "PKINIT: -27 reply " + "invalid content type"); return EINVAL; } ret = hx509_cms_unwrap_ContentInfo(&os, &oid, &data, NULL); if (ret) { free_PA_PK_AS_REP(&rep); - krb5_set_error_string(context, "PKINIT: failed to unwrap CI"); + krb5_set_error_message(context, ret, "PKINIT: failed to unwrap CI"); return ret; } @@ -1346,7 +1329,7 @@ _krb5_pk_rd_pa_reply(krb5_context context, nonce, pa, key); break; case choice_PA_PK_AS_REP_encKeyPack: - ret = pk_rd_pa_reply_enckey(context, COMPAT_IETF, &data, &oid, realm, + ret = pk_rd_pa_reply_enckey(context, PKINIT_27, &data, &oid, realm, ctx, etype, hi, nonce, req_buffer, pa, key); break; default: @@ -1356,14 +1339,14 @@ _krb5_pk_rd_pa_reply(krb5_context context, der_free_oid(&oid); free_PA_PK_AS_REP(&rep); - } else if (ctx->type == COMPAT_WIN2K) { + } else if (ctx->type == PKINIT_WIN2K) { PA_PK_AS_REP_Win2k w2krep; /* Check for Windows encoding of the AS-REP pa data */ #if 0 /* should this be ? */ if (pa->padata_type != KRB5_PADATA_PK_AS_REP) { - krb5_set_error_string(context, "PKINIT: wrong padata recv"); + krb5_set_error_message(context, EINVAL, "PKINIT: wrong padata recv"); return EINVAL; } #endif @@ -1375,8 +1358,8 @@ _krb5_pk_rd_pa_reply(krb5_context context, &w2krep, &size); if (ret) { - krb5_set_error_string(context, "PKINIT: Failed decoding windows " - "pkinit reply %d", ret); + krb5_set_error_message(context, ret, "PKINIT: Failed decoding windows " + "pkinit reply %d", (int)ret); return ret; } @@ -1391,11 +1374,11 @@ _krb5_pk_rd_pa_reply(krb5_context context, &oid, &data, NULL); free_PA_PK_AS_REP_Win2k(&w2krep); if (ret) { - krb5_set_error_string(context, "PKINIT: failed to unwrap CI"); + krb5_set_error_message(context, ret, "PKINIT: failed to unwrap CI"); return ret; } - ret = pk_rd_pa_reply_enckey(context, COMPAT_WIN2K, &data, &oid, realm, + ret = pk_rd_pa_reply_enckey(context, PKINIT_WIN2K, &data, &oid, realm, ctx, etype, hi, nonce, req_buffer, pa, key); der_free_octet_string(&data); der_free_oid(&oid); @@ -1404,15 +1387,15 @@ _krb5_pk_rd_pa_reply(krb5_context context, } default: free_PA_PK_AS_REP_Win2k(&w2krep); - krb5_set_error_string(context, "PKINIT: win2k reply invalid " - "content type"); ret = EINVAL; + krb5_set_error_message(context, ret, "PKINIT: win2k reply invalid " + "content type"); break; } } else { - krb5_set_error_string(context, "PKINIT: unknown reply type"); ret = EINVAL; + krb5_set_error_message(context, ret, "PKINIT: unknown reply type"); } return ret; @@ -1486,13 +1469,14 @@ _krb5_pk_load_id(krb5_context context, *ret_id = NULL; if (anchor_id == NULL) { - krb5_set_error_string(context, "PKINIT: No anchor given"); + krb5_set_error_message(context, HEIM_PKINIT_NO_VALID_CA, + "PKINIT: No anchor given"); return HEIM_PKINIT_NO_VALID_CA; } if (user_id == NULL) { - krb5_set_error_string(context, - "PKINIT: No user certificate given"); + krb5_set_error_message(context, HEIM_PKINIT_NO_PRIVATE_KEY, + "PKINIT: No user certificate given"); return HEIM_PKINIT_NO_PRIVATE_KEY; } @@ -1500,7 +1484,7 @@ _krb5_pk_load_id(krb5_context context, id = calloc(1, sizeof(*id)); if (id == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } @@ -1524,23 +1508,23 @@ _krb5_pk_load_id(krb5_context context, ret = hx509_certs_init(id->hx509ctx, user_id, 0, lock, &id->certs); if (ret) { - _krb5_pk_copy_error(context, id->hx509ctx, ret, - "Failed to init cert certs"); + pk_copy_error(context, id->hx509ctx, ret, + "Failed to init cert certs"); goto out; } ret = hx509_certs_init(id->hx509ctx, anchor_id, 0, NULL, &id->anchors); if (ret) { - _krb5_pk_copy_error(context, id->hx509ctx, ret, - "Failed to init anchors"); + pk_copy_error(context, id->hx509ctx, ret, + "Failed to init anchors"); goto out; } ret = hx509_certs_init(id->hx509ctx, "MEMORY:pkinit-cert-chain", 0, NULL, &id->certpool); if (ret) { - _krb5_pk_copy_error(context, id->hx509ctx, ret, - "Failed to init chain"); + pk_copy_error(context, id->hx509ctx, ret, + "Failed to init chain"); goto out; } @@ -1548,9 +1532,9 @@ _krb5_pk_load_id(krb5_context context, ret = hx509_certs_append(id->hx509ctx, id->certpool, NULL, *chain_list); if (ret) { - _krb5_pk_copy_error(context, id->hx509ctx, ret, - "Failed to laod chain %s", - *chain_list); + pk_copy_error(context, id->hx509ctx, ret, + "Failed to laod chain %s", + *chain_list); goto out; } chain_list++; @@ -1559,8 +1543,8 @@ _krb5_pk_load_id(krb5_context context, if (revoke_list) { ret = hx509_revoke_init(id->hx509ctx, &id->revokectx); if (ret) { - _krb5_pk_copy_error(context, id->hx509ctx, ret, - "Failed init revoke list"); + pk_copy_error(context, id->hx509ctx, ret, + "Failed init revoke list"); goto out; } @@ -1569,8 +1553,8 @@ _krb5_pk_load_id(krb5_context context, id->revokectx, *revoke_list); if (ret) { - _krb5_pk_copy_error(context, id->hx509ctx, ret, - "Failed load revoke list"); + pk_copy_error(context, id->hx509ctx, ret, + "Failed load revoke list"); goto out; } revoke_list++; @@ -1580,15 +1564,15 @@ _krb5_pk_load_id(krb5_context context, ret = hx509_verify_init_ctx(id->hx509ctx, &id->verify_ctx); if (ret) { - _krb5_pk_copy_error(context, id->hx509ctx, ret, - "Failed init verify context"); + pk_copy_error(context, id->hx509ctx, ret, + "Failed init verify context"); goto out; } hx509_verify_attach_anchors(id->verify_ctx, id->anchors); hx509_verify_attach_revoke(id->verify_ctx, id->revokectx); -out: + out: if (ret) { hx509_verify_destroy_ctx(id->verify_ctx); hx509_certs_free(&id->certs); @@ -1622,10 +1606,10 @@ select_dh_group(krb5_context context, DH *dh, unsigned long bits, break; } if (moduli[i] == NULL) { - krb5_set_error_string(context, - "Did not find a DH group parameter " - "matching requirement of %lu bits", - bits); + krb5_set_error_message(context, EINVAL, + "Did not find a DH group parameter " + "matching requirement of %lu bits", + bits); return EINVAL; } m = moduli[i]; @@ -1644,6 +1628,39 @@ select_dh_group(krb5_context context, DH *dh, unsigned long bits, return 0; } +/* + * + */ + +static void +pk_copy_error(krb5_context context, + hx509_context hx509ctx, + int hxret, + const char *fmt, + ...) +{ + va_list va; + char *s, *f; + + va_start(va, fmt); + vasprintf(&f, fmt, va); + va_end(va); + if (f == NULL) { + krb5_clear_error_string(context); + return; + } + + s = hx509_get_error_string(hx509ctx, hxret); + if (s == NULL) { + krb5_clear_error_string(context); + free(f); + return; + } + krb5_set_error_message(context, hxret, "%s: %s", f, s); + free(s); + free(f); +} + #endif /* PKINIT */ static int @@ -1654,15 +1671,15 @@ parse_integer(krb5_context context, char **p, const char *file, int lineno, char *p1; p1 = strsep(p, " \t"); if (p1 == NULL) { - krb5_set_error_string(context, "moduli file %s missing %s on line %d", - file, name, lineno); + krb5_set_error_message(context, EINVAL, "moduli file %s missing %s on line %d", + file, name, lineno); return EINVAL; } ret = der_parse_hex_heim_integer(p1, integer); if (ret) { - krb5_set_error_string(context, "moduli file %s failed parsing %s " - "on line %d", - file, name, lineno); + krb5_set_error_message(context, ret, "moduli file %s failed parsing %s " + "on line %d", + file, name, lineno); return ret; } @@ -1684,7 +1701,7 @@ _krb5_parse_moduli_line(krb5_context context, m1 = calloc(1, sizeof(*m1)); if (m1 == NULL) { - krb5_set_error_string(context, "malloc - out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } @@ -1696,28 +1713,28 @@ _krb5_parse_moduli_line(krb5_context context, p1 = strsep(&p, " \t"); if (p1 == NULL) { - krb5_set_error_string(context, "moduli file %s missing name " - "on line %d", file, lineno); + krb5_set_error_message(context, ret, "moduli file %s missing name " + "on line %d", file, lineno); goto out; } m1->name = strdup(p1); if (p1 == NULL) { - krb5_set_error_string(context, "malloc - out of memeory"); ret = ENOMEM; + krb5_set_error_message(context, ret, "malloc - out of memeory"); goto out; } p1 = strsep(&p, " \t"); if (p1 == NULL) { - krb5_set_error_string(context, "moduli file %s missing bits on line %d", - file, lineno); + krb5_set_error_message(context, ret, "moduli file %s missing bits on line %d", + file, lineno); goto out; } m1->bits = atoi(p1); if (m1->bits == 0) { - krb5_set_error_string(context, "moduli file %s have un-parsable " - "bits on line %d", file, lineno); + krb5_set_error_message(context, ret, "moduli file %s have un-parsable " + "bits on line %d", file, lineno); goto out; } @@ -1734,7 +1751,7 @@ _krb5_parse_moduli_line(krb5_context context, *m = m1; return 0; -out: + out: free(m1->name); der_free_heim_integer(&m1->p); der_free_heim_integer(&m1->g); @@ -1826,7 +1843,7 @@ _krb5_parse_moduli(krb5_context context, const char *file, m = calloc(1, sizeof(m[0]) * 3); if (m == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } @@ -1855,6 +1872,7 @@ _krb5_parse_moduli(krb5_context context, const char *file, *moduli = m; return 0; } + rk_cloexec_file(f); while(fgets(buf, sizeof(buf), f) != NULL) { struct krb5_dh_moduli *element; @@ -1864,8 +1882,8 @@ _krb5_parse_moduli(krb5_context context, const char *file, m2 = realloc(m, (n + 2) * sizeof(m[0])); if (m2 == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); _krb5_free_moduli(m); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } m = m2; @@ -1903,19 +1921,23 @@ _krb5_dh_group_ok(krb5_context context, unsigned long bits, if (der_heim_integer_cmp(&moduli[i]->g, g) == 0 && der_heim_integer_cmp(&moduli[i]->p, p) == 0 && (q == NULL || der_heim_integer_cmp(&moduli[i]->q, q) == 0)) - { - if (bits && bits > moduli[i]->bits) { - krb5_set_error_string(context, "PKINIT: DH group parameter %s " - "no accepted, not enough bits generated", - moduli[i]->name); - return KRB5_KDC_ERR_DH_KEY_PARAMETERS_NOT_ACCEPTED; + { + if (bits && bits > moduli[i]->bits) { + krb5_set_error_message(context, + KRB5_KDC_ERR_DH_KEY_PARAMETERS_NOT_ACCEPTED, + "PKINIT: DH group parameter %s " + "no accepted, not enough bits generated", + moduli[i]->name); + return KRB5_KDC_ERR_DH_KEY_PARAMETERS_NOT_ACCEPTED; + } + if (name) + *name = strdup(moduli[i]->name); + return 0; } - if (name) - *name = strdup(moduli[i]->name); - return 0; - } } - krb5_set_error_string(context, "PKINIT: DH group parameter no ok"); + krb5_set_error_message(context, + KRB5_KDC_ERR_DH_KEY_PARAMETERS_NOT_ACCEPTED, + "PKINIT: DH group parameter no ok"); return KRB5_KDC_ERR_DH_KEY_PARAMETERS_NOT_ACCEPTED; } @@ -1930,7 +1952,7 @@ _krb5_get_init_creds_opt_free_pkinit(krb5_get_init_creds_opt *opt) ctx = opt->opt_private->pk_init_ctx; if (ctx->dh) DH_free(ctx->dh); - ctx->dh = NULL; + ctx->dh = NULL; if (ctx->id) { hx509_verify_destroy_ctx(ctx->id->verify_ctx); hx509_certs_free(&ctx->id->certs); @@ -1970,14 +1992,14 @@ krb5_get_init_creds_opt_set_pkinit(krb5_context context, char *anchors = NULL; if (opt->opt_private == NULL) { - krb5_set_error_string(context, "PKINIT: on non extendable opt"); + krb5_set_error_message(context, EINVAL, "PKINIT: on non extendable opt"); return EINVAL; } opt->opt_private->pk_init_ctx = calloc(1, sizeof(*opt->opt_private->pk_init_ctx)); if (opt->opt_private->pk_init_ctx == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } opt->opt_private->pk_init_ctx->dh = NULL; @@ -2047,8 +2069,8 @@ krb5_get_init_creds_opt_set_pkinit(krb5_context context, opt->opt_private->pk_init_ctx->dh = DH_new(); if (opt->opt_private->pk_init_ctx->dh == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); _krb5_get_init_creds_opt_free_pkinit(opt); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } @@ -2061,48 +2083,15 @@ krb5_get_init_creds_opt_set_pkinit(krb5_context context, } if (DH_generate_key(opt->opt_private->pk_init_ctx->dh) != 1) { - krb5_set_error_string(context, "pkinit: failed to generate DH key"); _krb5_get_init_creds_opt_free_pkinit(opt); + krb5_set_error_message(context, ENOMEM, "pkinit: failed to generate DH key"); return ENOMEM; } } return 0; #else - krb5_set_error_string(context, "no support for PKINIT compiled in"); + krb5_set_error_message(context, EINVAL, "no support for PKINIT compiled in"); return EINVAL; #endif } - -/* - * - */ - -static void -_krb5_pk_copy_error(krb5_context context, - hx509_context hx509ctx, - int hxret, - const char *fmt, - ...) -{ - va_list va; - char *s, *f; - - va_start(va, fmt); - vasprintf(&f, fmt, va); - va_end(va); - if (f == NULL) { - krb5_clear_error_string(context); - return; - } - - s = hx509_get_error_string(hx509ctx, hxret); - if (s == NULL) { - krb5_clear_error_string(context); - free(f); - return; - } - krb5_set_error_string(context, "%s: %s", f, s); - free(s); - free(f); -} diff --git a/source4/heimdal/lib/krb5/plugin.c b/source4/heimdal/lib/krb5/plugin.c index bae28496aa..8dda27fa59 100644 --- a/source4/heimdal/lib/krb5/plugin.c +++ b/source4/heimdal/lib/krb5/plugin.c @@ -32,7 +32,7 @@ */ #include "krb5_locl.h" -RCSID("$Id: plugin.c 22033 2007-11-10 10:39:47Z lha $"); +RCSID("$Id: plugin.c 23451 2008-07-27 12:10:30Z lha $"); #ifdef HAVE_DLFCN_H #include <dlfcn.h> #endif @@ -87,7 +87,7 @@ loadlib(krb5_context context, { *e = calloc(1, sizeof(**e)); if (*e == NULL) { - krb5_set_error_string(context, "out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } @@ -99,8 +99,8 @@ loadlib(krb5_context context, if ((*e)->dsohandle == NULL) { free(*e); *e = NULL; - krb5_set_error_string(context, "Failed to load %s: %s", - lib, dlerror()); + krb5_set_error_message(context, ENOMEM, "Failed to load %s: %s", + lib, dlerror()); return ENOMEM; } @@ -139,14 +139,14 @@ krb5_plugin_register(krb5_context context, e = calloc(1, sizeof(*e)); if (e == NULL) { - krb5_set_error_string(context, "out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } e->type = type; e->name = strdup(name); if (e->name == NULL) { free(e); - krb5_set_error_string(context, "out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } e->symbol = symbol; @@ -185,8 +185,8 @@ _krb5_plugin_find(krb5_context context, e = calloc(1, sizeof(*e)); if (e == NULL) { HEIMDAL_MUTEX_unlock(&plugin_mutex); - krb5_set_error_string(context, "out of memory"); ret = ENOMEM; + krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } e->symbol = p->symbol; @@ -210,12 +210,13 @@ _krb5_plugin_find(krb5_context context, d = opendir(*di); if (d == NULL) continue; + rk_cloexec(dirfd(d)); while ((entry = readdir(d)) != NULL) { asprintf(&path, "%s/%s", *di, entry->d_name); if (path == NULL) { - krb5_set_error_string(context, "out of memory"); ret = ENOMEM; + krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } ret = loadlib(context, type, name, path, &e); @@ -233,7 +234,7 @@ _krb5_plugin_find(krb5_context context, #endif /* HAVE_DLOPEN */ if (*list == NULL) { - krb5_set_error_string(context, "Did not find a plugin for %s", name); + krb5_set_error_message(context, ENOENT, "Did not find a plugin for %s", name); return ENOENT; } diff --git a/source4/heimdal/lib/krb5/principal.c b/source4/heimdal/lib/krb5/principal.c index cdad477115..0d6d72dbcf 100644 --- a/source4/heimdal/lib/krb5/principal.c +++ b/source4/heimdal/lib/krb5/principal.c @@ -57,7 +57,7 @@ host/admin@H5L.ORG #include <fnmatch.h> #include "resolve.h" -RCSID("$Id: principal.c 22549 2008-01-29 09:37:25Z lha $"); +RCSID("$Id: principal.c 23316 2008-06-23 04:32:32Z lha $"); #define princ_num_comp(P) ((P)->name.name_string.len) #define princ_type(P) ((P)->name.name_type) @@ -149,8 +149,9 @@ krb5_parse_name_flags(krb5_context context, #define RFLAGS (KRB5_PRINCIPAL_PARSE_NO_REALM|KRB5_PRINCIPAL_PARSE_MUST_REALM) if ((flags & RFLAGS) == RFLAGS) { - krb5_set_error_string(context, "Can't require both realm and " - "no realm at the same time"); + krb5_set_error_message(context, KRB5_ERR_NO_SERVICE, + "Can't require both realm and " + "no realm at the same time"); return KRB5_ERR_NO_SERVICE; } #undef RFLAGS @@ -163,7 +164,7 @@ krb5_parse_name_flags(krb5_context context, for(p = name; *p; p++){ if(*p=='\\'){ if(!p[1]) { - krb5_set_error_string (context, + krb5_set_error_message(context, KRB5_PARSE_MALFORMED, "trailing \\ in principal name"); return KRB5_PARSE_MALFORMED; } @@ -176,7 +177,7 @@ krb5_parse_name_flags(krb5_context context, } comp = calloc(ncomp, sizeof(*comp)); if (comp == NULL) { - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } @@ -184,7 +185,7 @@ krb5_parse_name_flags(krb5_context context, p = start = q = s = strdup(name); if (start == NULL) { free (comp); - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } while(*p){ @@ -200,9 +201,9 @@ krb5_parse_name_flags(krb5_context context, else if(c == '0') c = '\0'; else if(c == '\0') { - krb5_set_error_string (context, - "trailing \\ in principal name"); ret = KRB5_PARSE_MALFORMED; + krb5_set_error_message(context, ret, + "trailing \\ in principal name"); goto exit; } }else if(enterprise && first_at) { @@ -210,15 +211,15 @@ krb5_parse_name_flags(krb5_context context, first_at = 0; }else if((c == '/' && !enterprise) || c == '@'){ if(got_realm){ - krb5_set_error_string (context, - "part after realm in principal name"); ret = KRB5_PARSE_MALFORMED; + krb5_set_error_message(context, ret, + "part after realm in principal name"); goto exit; }else{ comp[n] = malloc(q - start + 1); if (comp[n] == NULL) { - krb5_set_error_string (context, "malloc: out of memory"); ret = ENOMEM; + krb5_set_error_message(context, ret, "malloc: out of memory"); goto exit; } memcpy(comp[n], start, q - start); @@ -231,33 +232,33 @@ krb5_parse_name_flags(krb5_context context, continue; } if(got_realm && (c == ':' || c == '/' || c == '\0')) { - krb5_set_error_string (context, - "part after realm in principal name"); ret = KRB5_PARSE_MALFORMED; + krb5_set_error_message(context, ret, + "part after realm in principal name"); goto exit; } *q++ = c; } if(got_realm){ if (flags & KRB5_PRINCIPAL_PARSE_NO_REALM) { - krb5_set_error_string (context, "realm found in 'short' principal " - "expected to be without one"); ret = KRB5_PARSE_MALFORMED; + krb5_set_error_message(context, ret, "realm found in 'short' principal " + "expected to be without one"); goto exit; } realm = malloc(q - start + 1); if (realm == NULL) { - krb5_set_error_string (context, "malloc: out of memory"); ret = ENOMEM; + krb5_set_error_message(context, ret, "malloc: out of memory"); goto exit; } memcpy(realm, start, q - start); realm[q - start] = 0; }else{ if (flags & KRB5_PRINCIPAL_PARSE_MUST_REALM) { - krb5_set_error_string (context, "realm NOT found in principal " - "expected to be with one"); ret = KRB5_PARSE_MALFORMED; + krb5_set_error_message(context, ret, "realm NOT found in principal " + "expected to be with one"); goto exit; } else if (flags & KRB5_PRINCIPAL_PARSE_NO_REALM) { realm = NULL; @@ -269,8 +270,8 @@ krb5_parse_name_flags(krb5_context context, comp[n] = malloc(q - start + 1); if (comp[n] == NULL) { - krb5_set_error_string (context, "malloc: out of memory"); ret = ENOMEM; + krb5_set_error_message(context, ret, "malloc: out of memory"); goto exit; } memcpy(comp[n], start, q - start); @@ -279,8 +280,8 @@ krb5_parse_name_flags(krb5_context context, } *principal = malloc(sizeof(**principal)); if (*principal == NULL) { - krb5_set_error_string (context, "malloc: out of memory"); ret = ENOMEM; + krb5_set_error_message(context, ret, "malloc: out of memory"); goto exit; } if (enterprise) @@ -350,7 +351,8 @@ unparse_name_fixed(krb5_context context, int display = (flags & KRB5_PRINCIPAL_UNPARSE_DISPLAY) != 0; if (!no_realm && princ_realm(principal) == NULL) { - krb5_set_error_string(context, "Realm missing from principal, " + krb5_set_error_message(context, ERANGE, + "Realm missing from principal, " "can't unparse"); return ERANGE; } @@ -360,7 +362,7 @@ unparse_name_fixed(krb5_context context, add_char(name, idx, len, '/'); idx = quote_string(princ_ncomp(principal, i), name, idx, len, display); if(idx == len) { - krb5_set_error_string(context, "Out of space printing principal"); + krb5_set_error_message(context, ERANGE, "Out of space printing principal"); return ERANGE; } } @@ -379,8 +381,8 @@ unparse_name_fixed(krb5_context context, add_char(name, idx, len, '@'); idx = quote_string(princ_realm(principal), name, idx, len, display); if(idx == len) { - krb5_set_error_string(context, - "Out of space printing realm of principal"); + krb5_set_error_message(context, ERANGE, + "Out of space printing realm of principal"); return ERANGE; } } @@ -446,7 +448,7 @@ unparse_name(krb5_context context, len++; /* '\0' */ *name = malloc(len); if(*name == NULL) { - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } ret = unparse_name_fixed(context, principal, *name, len, flags); @@ -511,6 +513,22 @@ krb5_princ_set_realm(krb5_context context, princ_realm(principal) = *realm; } +krb5_error_code KRB5_LIB_FUNCTION +krb5_principal_set_realm(krb5_context context, + krb5_principal principal, + krb5_const_realm realm) +{ + if (princ_realm(principal)) + free(princ_realm(principal)); + + princ_realm(principal) = strdup(realm); + if (princ_realm(principal) == NULL) { + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); + return ENOMEM; + } + return 0; +} + krb5_error_code KRB5_LIB_FUNCTION krb5_build_principal(krb5_context context, @@ -537,13 +555,13 @@ append_component(krb5_context context, krb5_principal p, tmp = realloc(princ_comp(p), (len + 1) * sizeof(*tmp)); if(tmp == NULL) { - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } princ_comp(p) = tmp; princ_ncomp(p, len) = malloc(comp_len + 1); if (princ_ncomp(p, len) == NULL) { - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } memcpy (princ_ncomp(p, len), comp, comp_len); @@ -591,7 +609,7 @@ build_principal(krb5_context context, p = calloc(1, sizeof(*p)); if (p == NULL) { - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } princ_type(p) = KRB5_NT_PRINCIPAL; @@ -599,7 +617,7 @@ build_principal(krb5_context context, princ_realm(p) = strdup(realm); if(p->realm == NULL){ free(p); - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } @@ -675,12 +693,12 @@ krb5_copy_principal(krb5_context context, { krb5_principal p = malloc(sizeof(*p)); if (p == NULL) { - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } if(copy_Principal(inprinc, p)) { free(p); - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } *outprinc = p; @@ -706,6 +724,22 @@ krb5_principal_compare_any_realm(krb5_context context, return TRUE; } +krb5_boolean KRB5_LIB_FUNCTION +_krb5_principal_compare_PrincipalName(krb5_context context, + krb5_const_principal princ1, + PrincipalName *princ2) +{ + int i; + if (princ_num_comp(princ1) != princ2->name_string.len) + return FALSE; + for(i = 0; i < princ_num_comp(princ1); i++){ + if(strcmp(princ_ncomp(princ1, i), princ2->name_string.val[i]) != 0) + return FALSE; + } + return TRUE; +} + + /* * return TRUE iff princ1 == princ2 */ @@ -909,7 +943,7 @@ krb5_425_conv_principal_ext2(krb5_context context, #endif if (passed) { if (inst == NULL) { - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } strlwr(inst); @@ -1160,7 +1194,7 @@ krb5_524_conv_principal(krb5_context context, i = principal->name.name_string.val[1]; break; default: - krb5_set_error_string (context, + krb5_set_error_message(context, KRB5_PARSE_MALFORMED, "cannot convert a %d component principal", principal->name.name_string.len); return KRB5_PARSE_MALFORMED; @@ -1186,17 +1220,17 @@ krb5_524_conv_principal(krb5_context context, } if (strlcpy (name, n, aname_sz) >= aname_sz) { - krb5_set_error_string (context, + krb5_set_error_message(context, KRB5_PARSE_MALFORMED, "too long name component to convert"); return KRB5_PARSE_MALFORMED; } if (strlcpy (instance, i, aname_sz) >= aname_sz) { - krb5_set_error_string (context, + krb5_set_error_message(context, KRB5_PARSE_MALFORMED, "too long instance component to convert"); return KRB5_PARSE_MALFORMED; } if (strlcpy (realm, r, aname_sz) >= aname_sz) { - krb5_set_error_string (context, + krb5_set_error_message(context, KRB5_PARSE_MALFORMED, "too long realm component to convert"); return KRB5_PARSE_MALFORMED; } @@ -1219,8 +1253,9 @@ krb5_sname_to_principal (krb5_context context, char **realms, *host = NULL; if(type != KRB5_NT_SRV_HST && type != KRB5_NT_UNKNOWN) { - krb5_set_error_string (context, "unsupported name type %d", - type); + krb5_set_error_message(context, KRB5_SNAME_UNSUPP_NAMETYPE, + "unsupported name type %d", + (int)type); return KRB5_SNAME_UNSUPP_NAMETYPE; } if(hostname == NULL) { @@ -1280,6 +1315,7 @@ krb5_parse_nametype(krb5_context context, const char *str, int32_t *nametype) return 0; } } - krb5_set_error_string(context, "Failed to find name type %s", str); + krb5_set_error_message(context, KRB5_PARSE_MALFORMED, + "Failed to find name type %s", str); return KRB5_PARSE_MALFORMED; } diff --git a/source4/heimdal/lib/krb5/rd_cred.c b/source4/heimdal/lib/krb5/rd_cred.c index c3f732201f..26aa3f2d79 100644 --- a/source4/heimdal/lib/krb5/rd_cred.c +++ b/source4/heimdal/lib/krb5/rd_cred.c @@ -33,7 +33,7 @@ #include <krb5_locl.h> -RCSID("$Id: rd_cred.c 20304 2007-04-11 11:15:05Z lha $"); +RCSID("$Id: rd_cred.c 23316 2008-06-23 04:32:32Z lha $"); static krb5_error_code compare_addrs(krb5_context context, @@ -49,7 +49,8 @@ compare_addrs(krb5_context context, krb5_print_address (a, a_str, sizeof(a_str), &len); krb5_print_address (b, b_str, sizeof(b_str), &len); - krb5_set_error_string(context, "%s: %s != %s", message, b_str, a_str); + krb5_set_error_message(context, KRB5KRB_AP_ERR_BADADDR, + "%s: %s != %s", message, b_str, a_str); return KRB5KRB_AP_ERR_BADADDR; } @@ -244,7 +245,7 @@ krb5_rd_cred(krb5_context context, if (*ret_creds == NULL) { ret = ENOMEM; - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } @@ -255,7 +256,7 @@ krb5_rd_cred(krb5_context context, creds = calloc(1, sizeof(*creds)); if(creds == NULL) { ret = ENOMEM; - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } diff --git a/source4/heimdal/lib/krb5/rd_error.c b/source4/heimdal/lib/krb5/rd_error.c index e7646467af..9e50af539a 100644 --- a/source4/heimdal/lib/krb5/rd_error.c +++ b/source4/heimdal/lib/krb5/rd_error.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: rd_error.c 21057 2007-06-12 17:22:31Z lha $"); +RCSID("$Id: rd_error.c 23316 2008-06-23 04:32:32Z lha $"); krb5_error_code KRB5_LIB_FUNCTION krb5_rd_error(krb5_context context, @@ -78,7 +78,7 @@ krb5_error_from_rd_error(krb5_context context, ret = error->error_code; if (error->e_text != NULL) { - krb5_set_error_string(context, "%s", *error->e_text); + krb5_set_error_message(context, ret, "%s", *error->e_text); } else { char clientname[256], servername[256]; @@ -91,28 +91,28 @@ krb5_error_from_rd_error(krb5_context context, switch (ret) { case KRB5KDC_ERR_NAME_EXP : - krb5_set_error_string(context, "Client %s%s%s expired", - creds ? "(" : "", - creds ? clientname : "", - creds ? ")" : ""); + krb5_set_error_message(context, ret, "Client %s%s%s expired", + creds ? "(" : "", + creds ? clientname : "", + creds ? ")" : ""); break; case KRB5KDC_ERR_SERVICE_EXP : - krb5_set_error_string(context, "Server %s%s%s expired", - creds ? "(" : "", - creds ? servername : "", - creds ? ")" : ""); + krb5_set_error_message(context, ret, "Server %s%s%s expired", + creds ? "(" : "", + creds ? servername : "", + creds ? ")" : ""); break; case KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN : - krb5_set_error_string(context, "Client %s%s%s unknown", - creds ? "(" : "", - creds ? clientname : "", - creds ? ")" : ""); + krb5_set_error_message(context, ret, "Client %s%s%s unknown", + creds ? "(" : "", + creds ? clientname : "", + creds ? ")" : ""); break; case KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN : - krb5_set_error_string(context, "Server %s%s%s unknown", - creds ? "(" : "", - creds ? servername : "", - creds ? ")" : ""); + krb5_set_error_message(context, ret, "Server %s%s%s unknown", + creds ? "(" : "", + creds ? servername : "", + creds ? ")" : ""); break; default : krb5_clear_error_string(context); diff --git a/source4/heimdal/lib/krb5/rd_rep.c b/source4/heimdal/lib/krb5/rd_rep.c index 8c9b7bb441..0e6e3d09af 100644 --- a/source4/heimdal/lib/krb5/rd_rep.c +++ b/source4/heimdal/lib/krb5/rd_rep.c @@ -33,7 +33,7 @@ #include <krb5_locl.h> -RCSID("$Id: rd_rep.c 17890 2006-08-21 09:19:22Z lha $"); +RCSID("$Id: rd_rep.c 23304 2008-06-23 03:29:56Z lha $"); krb5_error_code KRB5_LIB_FUNCTION krb5_rd_rep(krb5_context context, @@ -79,7 +79,7 @@ krb5_rd_rep(krb5_context context, *repl = malloc(sizeof(**repl)); if (*repl == NULL) { ret = ENOMEM; - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } ret = krb5_decode_EncAPRepPart(context, diff --git a/source4/heimdal/lib/krb5/rd_req.c b/source4/heimdal/lib/krb5/rd_req.c index 0f33b97164..ddf1f69ae4 100644 --- a/source4/heimdal/lib/krb5/rd_req.c +++ b/source4/heimdal/lib/krb5/rd_req.c @@ -33,7 +33,7 @@ #include <krb5_locl.h> -RCSID("$Id: rd_req.c 22235 2007-12-08 21:52:07Z lha $"); +RCSID("$Id: rd_req.c 23415 2008-07-26 18:35:44Z lha $"); static krb5_error_code decrypt_tkt_enc_part (krb5_context context, @@ -133,7 +133,7 @@ static krb5_error_code check_transited(krb5_context context, Ticket *ticket, EncTicketPart *enc) { char **realms; - int num_realms; + unsigned int num_realms; krb5_error_code ret; /* @@ -389,11 +389,6 @@ krb5_verify_ap_req2(krb5_context context, t->ticket.crealm); if (ret) goto out; - /* save key */ - - ret = krb5_copy_keyblock(context, &t->ticket.key, &ac->keyblock); - if (ret) goto out; - ret = decrypt_authenticator (context, &t->ticket.key, &ap_req->authenticator, @@ -479,6 +474,10 @@ krb5_verify_ap_req2(krb5_context context, } } + /* save key */ + ret = krb5_copy_keyblock(context, &t->ticket.key, &ac->keyblock); + if (ret) goto out; + if (ap_req_options) { *ap_req_options = 0; if (ac->keytype != ETYPE_NULL) @@ -533,7 +532,7 @@ krb5_rd_req_in_ctx_alloc(krb5_context context, krb5_rd_req_in_ctx *ctx) { *ctx = calloc(1, sizeof(**ctx)); if (*ctx == NULL) { - krb5_set_error_string(context, "out of memory"); + krb5_set_error_message(context, ENOMEM, "out of memory"); return ENOMEM; } (*ctx)->check_pac = (context->flags & KRB5_CTX_F_CHECK_PAC) ? 1 : 0; @@ -616,7 +615,7 @@ _krb5_rd_req_out_ctx_alloc(krb5_context context, krb5_rd_req_out_ctx *ctx) { *ctx = calloc(1, sizeof(**ctx)); if (*ctx == NULL) { - krb5_set_error_string(context, "out of memory"); + krb5_set_error_message(context, ENOMEM, "out of memory"); return ENOMEM; } return 0; @@ -805,9 +804,9 @@ krb5_rd_req_ctx(krb5_context context, } if (ap_req.ap_options.use_session_key && (*auth_context)->keyblock == NULL) { - krb5_set_error_string(context, "krb5_rd_req: user to user auth " - "without session key given"); ret = KRB5KRB_AP_ERR_NOKEY; + krb5_set_error_message(context, ret, "krb5_rd_req: user to user auth " + "without session key given"); goto out; } diff --git a/source4/heimdal/lib/krb5/replay.c b/source4/heimdal/lib/krb5/replay.c index 12894d96a9..7639bfa2ce 100644 --- a/source4/heimdal/lib/krb5/replay.c +++ b/source4/heimdal/lib/krb5/replay.c @@ -34,7 +34,7 @@ #include "krb5_locl.h" #include <vis.h> -RCSID("$Id: replay.c 17047 2006-04-10 17:13:49Z lha $"); +RCSID("$Id: replay.c 23467 2008-07-27 12:16:37Z lha $"); struct krb5_rcache_data { char *name; @@ -47,7 +47,7 @@ krb5_rc_resolve(krb5_context context, { id->name = strdup(name); if(id->name == NULL) { - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, KRB5_RC_MALLOC, "malloc: out of memory"); return KRB5_RC_MALLOC; } return 0; @@ -60,13 +60,14 @@ krb5_rc_resolve_type(krb5_context context, { *id = NULL; if(strcmp(type, "FILE")) { - krb5_set_error_string (context, "replay cache type %s not supported", - type); + krb5_set_error_message (context, KRB5_RC_TYPE_NOTFOUND, + "replay cache type %s not supported", + type); return KRB5_RC_TYPE_NOTFOUND; } *id = calloc(1, sizeof(**id)); if(*id == NULL) { - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, KRB5_RC_MALLOC, "malloc: out of memory"); return KRB5_RC_MALLOC; } return 0; @@ -82,7 +83,8 @@ krb5_rc_resolve_full(krb5_context context, *id = NULL; if(strncmp(string_name, "FILE:", 5)) { - krb5_set_error_string (context, "replay cache type %s not supported", + krb5_set_error_message(context, KRB5_RC_TYPE_NOTFOUND, + "replay cache type %s not supported", string_name); return KRB5_RC_TYPE_NOTFOUND; } @@ -132,7 +134,7 @@ krb5_rc_initialize(krb5_context context, if(f == NULL) { ret = errno; - krb5_set_error_string (context, "open(%s): %s", id->name, + krb5_set_error_message(context, ret, "open(%s): %s", id->name, strerror(ret)); return ret; } @@ -157,7 +159,7 @@ krb5_rc_destroy(krb5_context context, if(remove(id->name) < 0) { ret = errno; - krb5_set_error_string (context, "remove(%s): %s", id->name, + krb5_set_error_message(context, ret, "remove(%s): %s", id->name, strerror(ret)); return ret; } @@ -204,10 +206,11 @@ krb5_rc_store(krb5_context context, f = fopen(id->name, "r"); if(f == NULL) { ret = errno; - krb5_set_error_string (context, "open(%s): %s", id->name, + krb5_set_error_message(context, ret, "open(%s): %s", id->name, strerror(ret)); return ret; } + rk_cloexec_file(f); fread(&tmp, sizeof(ent), 1, f); t = ent.stamp - tmp.stamp; while(fread(&tmp, sizeof(ent), 1, f)){ @@ -222,13 +225,15 @@ krb5_rc_store(krb5_context context, if(ferror(f)){ ret = errno; fclose(f); - krb5_set_error_string (context, "%s: %s", id->name, strerror(ret)); + krb5_set_error_message(context, ret, "%s: %s", + id->name, strerror(ret)); return ret; } fclose(f); f = fopen(id->name, "a"); if(f == NULL) { - krb5_set_error_string (context, "open(%s): %s", id->name, + krb5_set_error_message(context, KRB5_RC_IO_UNKNOWN, + "open(%s): %s", id->name, strerror(errno)); return KRB5_RC_IO_UNKNOWN; } @@ -288,7 +293,7 @@ krb5_get_server_rcache(krb5_context context, char *name; if(tmp == NULL) { - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } strvisx(tmp, piece->data, piece->length, VIS_WHITE | VIS_OCTAL); @@ -299,7 +304,7 @@ krb5_get_server_rcache(krb5_context context, #endif free(tmp); if(name == NULL) { - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } diff --git a/source4/heimdal/lib/krb5/send_to_kdc.c b/source4/heimdal/lib/krb5/send_to_kdc.c index 2582a615c0..1ddb5afd1f 100644 --- a/source4/heimdal/lib/krb5/send_to_kdc.c +++ b/source4/heimdal/lib/krb5/send_to_kdc.c @@ -32,8 +32,9 @@ */ #include "krb5_locl.h" +#include "send_to_kdc_plugin.h" -RCSID("$Id: send_to_kdc.c 21934 2007-08-27 14:21:04Z lha $"); +RCSID("$Id: send_to_kdc.c 23448 2008-07-27 12:09:22Z lha $"); struct send_to_kdc { krb5_send_to_kdc_func func; @@ -290,6 +291,7 @@ send_via_proxy (krb5_context context, s = socket (a->ai_family, a->ai_socktype, a->ai_protocol); if (s < 0) continue; + rk_cloexec(s); if (connect (s, a->ai_addr, a->ai_addrlen) < 0) { close (s); continue; @@ -316,6 +318,46 @@ send_via_proxy (krb5_context context, return 1; } +static krb5_error_code +send_via_plugin(krb5_context context, + krb5_krbhst_info *hi, + time_t timeout, + const krb5_data *send_data, + krb5_data *receive) +{ + struct krb5_plugin *list = NULL, *e; + krb5_error_code ret; + + ret = _krb5_plugin_find(context, PLUGIN_TYPE_DATA, KRB5_PLUGIN_SEND_TO_KDC, &list); + if(ret != 0 || list == NULL) + return KRB5_PLUGIN_NO_HANDLE; + + for (e = list; e != NULL; e = _krb5_plugin_get_next(e)) { + krb5plugin_send_to_kdc_ftable *service; + void *ctx; + + service = _krb5_plugin_get_symbol(e); + if (service->minor_version != 0) + continue; + + (*service->init)(context, &ctx); + ret = (*service->send_to_kdc)(context, ctx, hi, + timeout, send_data, receive); + (*service->fini)(ctx); + if (ret == 0) + break; + if (ret != KRB5_PLUGIN_NO_HANDLE) { + krb5_set_error_message(context, ret, + "Plugin %s failed to lookup with error: %d", + KRB5_PLUGIN_SEND_TO_KDC, ret); + break; + } + } + _krb5_plugin_free(list); + return KRB5_PLUGIN_NO_HANDLE; +} + + /* * Send the data `send' to one host from `handle` and get back the reply * in `receive'. @@ -343,12 +385,19 @@ krb5_sendto (krb5_context context, struct send_to_kdc *s = context->send_to_kdc; ret = (*s->func)(context, s->data, - hi, send_data, receive); + hi, context->kdc_timeout, send_data, receive); if (ret == 0 && receive->length != 0) goto out; continue; } + ret = send_via_plugin(context, hi, context->kdc_timeout, + send_data, receive); + if (ret == 0 && receive->length != 0) + goto out; + else if (ret != KRB5_PLUGIN_NO_HANDLE) + continue; + if(hi->proto == KRB5_KRBHST_HTTP && context->http_proxy) { if (send_via_proxy (context, hi, send_data, receive) == 0) { ret = 0; @@ -365,6 +414,7 @@ krb5_sendto (krb5_context context, fd = socket (a->ai_family, a->ai_socktype, a->ai_protocol); if (fd < 0) continue; + rk_cloexec(fd); if (connect (fd, a->ai_addr, a->ai_addrlen) < 0) { close (fd); continue; @@ -439,7 +489,7 @@ krb5_set_send_to_kdc_func(krb5_context context, context->send_to_kdc = malloc(sizeof(*context->send_to_kdc)); if (context->send_to_kdc == NULL) { - krb5_set_error_string(context, "Out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } @@ -460,7 +510,7 @@ krb5_sendto_ctx_alloc(krb5_context context, krb5_sendto_ctx *ctx) { *ctx = calloc(1, sizeof(**ctx)); if (*ctx == NULL) { - krb5_set_error_string(context, "out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } return 0; @@ -566,8 +616,8 @@ krb5_sendto_context(krb5_context context, if (handle) krb5_krbhst_free(context, handle); if (ret == KRB5_KDC_UNREACH) - krb5_set_error_string(context, - "unable to reach any KDC in realm %s", realm); + krb5_set_error_message(context, ret, + "unable to reach any KDC in realm %s", realm); if (ret) krb5_data_free(receive); if (freectx) diff --git a/source4/heimdal/lib/krb5/send_to_kdc_plugin.h b/source4/heimdal/lib/krb5/send_to_kdc_plugin.h new file mode 100644 index 0000000000..e0c2979e28 --- /dev/null +++ b/source4/heimdal/lib/krb5/send_to_kdc_plugin.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2008 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* $Id$ */ + +#ifndef HEIMDAL_KRB5_SEND_TO_KDC_PLUGIN_H +#define HEIMDAL_KRB5_SEND_TO_KDC_PLUGIN_H 1 + +#include <krb5.h> + +#define KRB5_PLUGIN_SEND_TO_KDC "send_to_kdc" + +typedef krb5_error_code +(*krb5plugin_send_to_kdc_func)(krb5_context, + void *, + krb5_krbhst_info *, + time_t timeout, + const krb5_data *, + krb5_data *); + +typedef struct krb5plugin_send_to_kdc_ftable { + int minor_version; + krb5_error_code (*init)(krb5_context, void **); + void (*fini)(void *); + krb5plugin_send_to_kdc_func send_to_kdc; +} krb5plugin_send_to_kdc_ftable; + +#endif /* HEIMDAL_KRB5_SEND_TO_KDC_PLUGIN_H */ diff --git a/source4/heimdal/lib/krb5/set_default_realm.c b/source4/heimdal/lib/krb5/set_default_realm.c index 98040bc2e9..55abf2ea7d 100644 --- a/source4/heimdal/lib/krb5/set_default_realm.c +++ b/source4/heimdal/lib/krb5/set_default_realm.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: set_default_realm.c 13863 2004-05-25 21:46:46Z lha $"); +RCSID("$Id: set_default_realm.c 23309 2008-06-23 03:30:41Z lha $"); /* * Convert the simple string `s' into a NULL-terminated and freshly allocated @@ -46,13 +46,13 @@ string_to_list (krb5_context context, const char *s, krb5_realm **list) *list = malloc (2 * sizeof(**list)); if (*list == NULL) { - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } (*list)[0] = strdup (s); if ((*list)[0] == NULL) { free (*list); - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } (*list)[1] = NULL; diff --git a/source4/heimdal/lib/krb5/ticket.c b/source4/heimdal/lib/krb5/ticket.c index 7eb4d32fad..5eff64e12d 100644 --- a/source4/heimdal/lib/krb5/ticket.c +++ b/source4/heimdal/lib/krb5/ticket.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: ticket.c 19544 2006-12-28 20:49:18Z lha $"); +RCSID("$Id: ticket.c 23310 2008-06-23 03:30:49Z lha $"); krb5_error_code KRB5_LIB_FUNCTION krb5_free_ticket(krb5_context context, @@ -57,7 +57,7 @@ krb5_copy_ticket(krb5_context context, *to = NULL; tmp = malloc(sizeof(*tmp)); if(tmp == NULL) { - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } if((ret = copy_EncTicketPart(&from->ticket, &tmp->ticket))){ @@ -118,9 +118,10 @@ find_type_in_ad(krb5_context context, int i; if (level > 9) { - krb5_set_error_string(context, "Authorization data nested deeper " - "then %d levels, stop searching", level); ret = ENOENT; /* XXX */ + krb5_set_error_message(context, ret, + "Authorization data nested deeper " + "then %d levels, stop searching", level); goto out; } @@ -133,7 +134,7 @@ find_type_in_ad(krb5_context context, if (!*found && ad->val[i].ad_type == type) { ret = der_copy_octet_string(&ad->val[i].ad_data, data); if (ret) { - krb5_set_error_string(context, "malloc - out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } *found = TRUE; @@ -147,8 +148,8 @@ find_type_in_ad(krb5_context context, &child, NULL); if (ret) { - krb5_set_error_string(context, "Failed to decode " - "IF_RELEVANT with %d", ret); + krb5_set_error_message(context, ret, "Failed to decode " + "IF_RELEVANT with %d", (int)ret); goto out; } ret = find_type_in_ad(context, type, data, found, FALSE, @@ -167,8 +168,8 @@ find_type_in_ad(krb5_context context, &child, NULL); if (ret) { - krb5_set_error_string(context, "Failed to decode " - "AD_KDCIssued with %d", ret); + krb5_set_error_message(context, ret, "Failed to decode " + "AD_KDCIssued with %d", ret); goto out; } if (failp) { @@ -211,17 +212,17 @@ find_type_in_ad(krb5_context context, case KRB5_AUTHDATA_AND_OR: if (!failp) break; - krb5_set_error_string(context, "Authorization data contains " - "AND-OR element that is unknown to the " - "application"); ret = ENOENT; /* XXX */ + krb5_set_error_message(context, ret, "Authorization data contains " + "AND-OR element that is unknown to the " + "application"); goto out; default: if (!failp) break; - krb5_set_error_string(context, "Authorization data contains " - "unknown type (%d) ", ad->val[i].ad_type); ret = ENOENT; /* XXX */ + krb5_set_error_message(context, ret, "Authorization data contains " + "unknown type (%d) ", ad->val[i].ad_type); goto out; } } @@ -255,7 +256,8 @@ krb5_ticket_get_authorization_data_type(krb5_context context, ad = ticket->ticket.authorization_data; if (ticket->ticket.authorization_data == NULL) { - krb5_set_error_string(context, "Ticket have not authorization data"); + krb5_set_error_message(context, ENOENT, + "Ticket have not authorization data"); return ENOENT; /* XXX */ } @@ -264,8 +266,8 @@ krb5_ticket_get_authorization_data_type(krb5_context context, if (ret) return ret; if (!found) { - krb5_set_error_string(context, "Ticket have not authorization " - "data of type %d", type); + krb5_set_error_message(context, ENOENT, "Ticket have not " + "authorization data of type %d", type); return ENOENT; /* XXX */ } return 0; diff --git a/source4/heimdal/lib/krb5/time.c b/source4/heimdal/lib/krb5/time.c index 4cd992d48f..46f88a86cd 100644 --- a/source4/heimdal/lib/krb5/time.c +++ b/source4/heimdal/lib/krb5/time.c @@ -33,12 +33,20 @@ #include "krb5_locl.h" -RCSID("$Id: time.c 14308 2004-10-13 17:57:11Z lha $"); +RCSID("$Id: time.c 23260 2008-06-21 15:22:37Z lha $"); -/* +/** * Set the absolute time that the caller knows the kdc has so the * kerberos library can calculate the relative diffrence beteen the * KDC time and local system time. + * + * @param context Keberos 5 context. + * @param sec The applications new of "now" in seconds + * @param usec The applications new of "now" in micro seconds + + * @return Kerberos 5 error code, see krb5_get_error_message(). + * + * @ingroup krb5 */ krb5_error_code KRB5_LIB_FUNCTION @@ -51,12 +59,21 @@ krb5_set_real_time (krb5_context context, gettimeofday(&tv, NULL); context->kdc_sec_offset = sec - tv.tv_sec; - context->kdc_usec_offset = usec - tv.tv_usec; - if (context->kdc_usec_offset < 0) { - context->kdc_sec_offset--; - context->kdc_usec_offset += 1000000; - } + /** + * If the caller passes in a negative usec, its assumed to be + * unknown and the function will use the current time usec. + */ + if (usec >= 0) { + context->kdc_usec_offset = usec - tv.tv_usec; + + if (context->kdc_usec_offset < 0) { + context->kdc_sec_offset--; + context->kdc_usec_offset += 1000000; + } + } else + context->kdc_usec_offset = tv.tv_usec; + return 0; } diff --git a/source4/heimdal/lib/krb5/transited.c b/source4/heimdal/lib/krb5/transited.c index 9b67ecc04f..58b00a4b7a 100644 --- a/source4/heimdal/lib/krb5/transited.c +++ b/source4/heimdal/lib/krb5/transited.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: transited.c 21745 2007-07-31 16:11:25Z lha $"); +RCSID("$Id: transited.c 23316 2008-06-23 04:32:32Z lha $"); /* this is an attempt at one of the most horrible `compression' schemes that has ever been invented; it's so amazingly brain-dead @@ -88,7 +88,7 @@ make_path(krb5_context context, struct tr_realm *r, break; tmp = calloc(1, sizeof(*tmp)); if(tmp == NULL){ - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } tmp->next = path; @@ -96,7 +96,7 @@ make_path(krb5_context context, struct tr_realm *r, path->realm = strdup(p); if(path->realm == NULL){ r->next = path; /* XXX */ - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM;; } } @@ -112,7 +112,7 @@ make_path(krb5_context context, struct tr_realm *r, break; tmp = calloc(1, sizeof(*tmp)); if(tmp == NULL){ - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } tmp->next = path; @@ -120,7 +120,7 @@ make_path(krb5_context context, struct tr_realm *r, path->realm = malloc(p - from + 1); if(path->realm == NULL){ r->next = path; /* XXX */ - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } memcpy(path->realm, from, p - from); @@ -186,7 +186,7 @@ expand_realms(krb5_context context, tmp = realloc(r->realm, len); if(tmp == NULL){ free_realms(realms); - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } r->realm = tmp; @@ -200,7 +200,7 @@ expand_realms(krb5_context context, tmp = malloc(len); if(tmp == NULL){ free_realms(realms); - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } strlcpy(tmp, prev_realm, len); @@ -286,7 +286,7 @@ decode_realms(krb5_context context, if(tr[i] == ','){ tmp = malloc(tr + i - start + 1); if(tmp == NULL){ - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } memcpy(tmp, start, tr + i - start); @@ -294,7 +294,7 @@ decode_realms(krb5_context context, r = make_realm(tmp); if(r == NULL){ free_realms(*realms); - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } *realms = append_realm(*realms, r); @@ -304,7 +304,7 @@ decode_realms(krb5_context context, tmp = malloc(tr + i - start + 1); if(tmp == NULL){ free(*realms); - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } memcpy(tmp, start, tr + i - start); @@ -312,7 +312,7 @@ decode_realms(krb5_context context, r = make_realm(tmp); if(r == NULL){ free_realms(*realms); - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } *realms = append_realm(*realms, r); @@ -323,7 +323,7 @@ decode_realms(krb5_context context, krb5_error_code KRB5_LIB_FUNCTION krb5_domain_x500_decode(krb5_context context, - krb5_data tr, char ***realms, int *num_realms, + krb5_data tr, char ***realms, unsigned int *num_realms, const char *client_realm, const char *server_realm) { struct tr_realm *r = NULL; @@ -385,11 +385,12 @@ krb5_domain_x500_decode(krb5_context context, } krb5_error_code KRB5_LIB_FUNCTION -krb5_domain_x500_encode(char **realms, int num_realms, krb5_data *encoding) +krb5_domain_x500_encode(char **realms, unsigned int num_realms, + krb5_data *encoding) { char *s = NULL; int len = 0; - int i; + unsigned int i; krb5_data_zero(encoding); if (num_realms == 0) return 0; @@ -420,7 +421,7 @@ krb5_check_transited(krb5_context context, krb5_const_realm client_realm, krb5_const_realm server_realm, krb5_realm *realms, - int num_realms, + unsigned int num_realms, int *bad_realm) { char **tr_realms; @@ -442,8 +443,9 @@ krb5_check_transited(krb5_context context, } if(p == NULL || *p == NULL) { krb5_config_free_strings(tr_realms); - krb5_set_error_string (context, "no transit through realm %s", - realms[i]); + krb5_set_error_message (context, KRB5KRB_AP_ERR_ILL_CR_TKT, + "no transit through realm %s", + realms[i]); if(bad_realm) *bad_realm = i; return KRB5KRB_AP_ERR_ILL_CR_TKT; @@ -456,7 +458,7 @@ krb5_check_transited(krb5_context context, krb5_error_code KRB5_LIB_FUNCTION krb5_check_transited_realms(krb5_context context, const char *const *realms, - int num_realms, + unsigned int num_realms, int *bad_realm) { int i; @@ -472,9 +474,9 @@ krb5_check_transited_realms(krb5_context context, char **p; for(p = bad_realms; *p; p++) if(strcmp(*p, realms[i]) == 0) { - krb5_set_error_string (context, "no transit through realm %s", - *p); ret = KRB5KRB_AP_ERR_ILL_CR_TKT; + krb5_set_error_message (context, ret, + "no transit through realm %s", *p); if(bad_realm) *bad_realm = i; break; diff --git a/source4/heimdal/lib/krb5/v4_glue.c b/source4/heimdal/lib/krb5/v4_glue.c index 37b1e35dd1..55570c44dd 100644 --- a/source4/heimdal/lib/krb5/v4_glue.c +++ b/source4/heimdal/lib/krb5/v4_glue.c @@ -32,7 +32,7 @@ */ #include "krb5_locl.h" -RCSID("$Id: v4_glue.c 22071 2007-11-14 20:04:50Z lha $"); +RCSID("$Id: v4_glue.c 23452 2008-07-27 12:10:54Z lha $"); #include "krb5-v4compat.h" @@ -147,7 +147,7 @@ write_v4_cc(krb5_context context, const char *tkfile, ret = get_krb4_cc_name(tkfile, &path); if (ret) { - krb5_set_error_string(context, + krb5_set_error_message(context, ret, "krb5_krb_tf_setup: failed getting " "the krb4 credentials cache name"); return ret; @@ -156,15 +156,16 @@ write_v4_cc(krb5_context context, const char *tkfile, fd = open(path, O_WRONLY|O_CREAT, 0600); if (fd < 0) { ret = errno; - krb5_set_error_string(context, + krb5_set_error_message(context, ret, "krb5_krb_tf_setup: error opening file %s", path); free(path); return ret; } + rk_cloexec(fd); if (fstat(fd, &sb) != 0 || !S_ISREG(sb.st_mode)) { - krb5_set_error_string(context, + krb5_set_error_message(context, ret, "krb5_krb_tf_setup: tktfile %s is not a file", path); free(path); @@ -179,9 +180,9 @@ write_v4_cc(krb5_context context, const char *tkfile, break; } if (i == KRB5_TF_LCK_RETRY_COUNT) { - krb5_set_error_string(context, - "krb5_krb_tf_setup: failed to lock %s", - path); + krb5_set_error_message(context, KRB5_FCC_PERM, + "krb5_krb_tf_setup: failed to lock %s", + path); free(path); close(fd); return KRB5_FCC_PERM; @@ -191,9 +192,9 @@ write_v4_cc(krb5_context context, const char *tkfile, ret = ftruncate(fd, 0); if (ret < 0) { flock(fd, LOCK_UN); - krb5_set_error_string(context, - "krb5_krb_tf_setup: failed to truncate %s", - path); + krb5_set_error_message(context, KRB5_FCC_PERM, + "krb5_krb_tf_setup: failed to truncate %s", + path); free(path); close(fd); return KRB5_FCC_PERM; @@ -291,7 +292,7 @@ _krb5_krb_dest_tkt(krb5_context context, const char *tkfile) ret = get_krb4_cc_name(tkfile, &path); if (ret) { - krb5_set_error_string(context, + krb5_set_error_message(context, ret, "krb5_krb_tf_setup: failed getting " "the krb4 credentials cache name"); return ret; @@ -299,7 +300,7 @@ _krb5_krb_dest_tkt(krb5_context context, const char *tkfile) if (unlink(path) < 0) { ret = errno; - krb5_set_error_string(context, + krb5_set_error_message(context, ret, "krb5_krb_dest_tkt failed removing the cache " "with error %s", strerror(ret)); } @@ -421,7 +422,7 @@ _krb5_krb_create_ticket(krb5_context context, sp = krb5_storage_emem(); if (sp == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } krb5_storage_set_byteorder(sp, KRB5_STORAGE_BYTEORDER_BE); @@ -448,7 +449,7 @@ _krb5_krb_create_ticket(krb5_context context, error: krb5_storage_free(sp); if (ret) - krb5_set_error_string(context, "Failed to encode kerberos 4 ticket"); + krb5_set_error_message(context, ret, "Failed to encode kerberos 4 ticket"); return ret; } @@ -477,7 +478,7 @@ _krb5_krb_create_ciph(krb5_context context, sp = krb5_storage_emem(); if (sp == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } krb5_storage_set_byteorder(sp, KRB5_STORAGE_BYTEORDER_BE); @@ -507,7 +508,7 @@ _krb5_krb_create_ciph(krb5_context context, error: krb5_storage_free(sp); if (ret) - krb5_set_error_string(context, "Failed to encode kerberos 4 ticket"); + krb5_set_error_message(context, ret, "Failed to encode kerberos 4 ticket"); return ret; } @@ -535,7 +536,7 @@ _krb5_krb_create_auth_reply(krb5_context context, sp = krb5_storage_emem(); if (sp == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } krb5_storage_set_byteorder(sp, KRB5_STORAGE_BYTEORDER_BE); @@ -559,7 +560,7 @@ _krb5_krb_create_auth_reply(krb5_context context, error: krb5_storage_free(sp); if (ret) - krb5_set_error_string(context, "Failed to encode kerberos 4 ticket"); + krb5_set_error_message(context, ret, "Failed to encode kerberos 4 ticket"); return ret; } @@ -590,7 +591,7 @@ _krb5_krb_cr_err_reply(krb5_context context, sp = krb5_storage_emem(); if (sp == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } krb5_storage_set_byteorder(sp, KRB5_STORAGE_BYTEORDER_BE); @@ -610,7 +611,7 @@ _krb5_krb_cr_err_reply(krb5_context context, error: krb5_storage_free(sp); if (ret) - krb5_set_error_string(context, "Failed to encode kerberos 4 error"); + krb5_set_error_message(context, ret, "Failed to encode kerberos 4 error"); return 0; } @@ -661,7 +662,7 @@ _krb5_krb_decomp_ticket(krb5_context context, sp = krb5_storage_from_data(&ticket); if (sp == NULL) { krb5_data_free(&ticket); - krb5_set_error_string(context, "alloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "alloc: out of memory"); return ENOMEM; } @@ -720,7 +721,7 @@ _krb5_krb_decomp_ticket(krb5_context context, *sinstance = NULL; } _krb5_krb_free_auth_data(context, ad); - krb5_set_error_string(context, "Failed to decode v4 ticket"); + krb5_set_error_message(context, ret, "Failed to decode v4 ticket"); } return ret; } @@ -769,7 +770,7 @@ _krb5_krb_rd_req(krb5_context context, sp = krb5_storage_from_data(authent); if (sp == NULL) { - krb5_set_error_string(context, "alloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "alloc: out of memory"); return ENOMEM; } @@ -777,19 +778,19 @@ _krb5_krb_rd_req(krb5_context context, ret = krb5_ret_int8(sp, &pvno); if (ret) { - krb5_set_error_string(context, "Failed reading v4 pvno"); + krb5_set_error_message(context, ret, "Failed reading v4 pvno"); goto error; } if (pvno != KRB_PROT_VERSION) { ret = KRB4ET_RD_AP_VERSION; - krb5_set_error_string(context, "Failed v4 pvno not 4"); + krb5_set_error_message(context, ret, "Failed v4 pvno not 4"); goto error; } ret = krb5_ret_int8(sp, &type); if (ret) { - krb5_set_error_string(context, "Failed readin v4 type"); + krb5_set_error_message(context, ret, "Failed readin v4 type"); goto error; } @@ -798,7 +799,7 @@ _krb5_krb_rd_req(krb5_context context, if(type != AUTH_MSG_APPL_REQUEST && type != AUTH_MSG_APPL_REQUEST_MUTUAL) { ret = KRB4ET_RD_AP_MSG_TYPE; - krb5_set_error_string(context, "Not a valid v4 request type"); + krb5_set_error_message(context, ret, "Not a valid v4 request type"); goto error; } @@ -811,7 +812,7 @@ _krb5_krb_rd_req(krb5_context context, size = krb5_storage_read(sp, ticket.data, ticket.length); if (size != ticket.length) { ret = KRB4ET_INTK_PROT; - krb5_set_error_string(context, "Failed reading v4 ticket"); + krb5_set_error_message(context, ret, "Failed reading v4 ticket"); goto error; } @@ -826,7 +827,7 @@ _krb5_krb_rd_req(krb5_context context, size = krb5_storage_read(sp, eaut.data, eaut.length); if (size != eaut.length) { ret = KRB4ET_INTK_PROT; - krb5_set_error_string(context, "Failed reading v4 authenticator"); + krb5_set_error_message(context, ret, "Failed reading v4 authenticator"); goto error; } @@ -840,7 +841,7 @@ _krb5_krb_rd_req(krb5_context context, sp = krb5_storage_from_data(&aut); if (sp == NULL) { ret = ENOMEM; - krb5_set_error_string(context, "alloc: out of memory"); + krb5_set_error_message(context, ret, "alloc: out of memory"); goto error; } @@ -860,14 +861,14 @@ _krb5_krb_rd_req(krb5_context context, if (strcmp(ad->pname, r_name) != 0 || strcmp(ad->pinst, r_instance) != 0 || strcmp(ad->prealm, r_realm) != 0) { - krb5_set_error_string(context, "v4 principal mismatch"); ret = KRB4ET_RD_AP_INCON; + krb5_set_error_message(context, ret, "v4 principal mismatch"); goto error; } if (from_addr && ad->address && from_addr != ad->address) { - krb5_set_error_string(context, "v4 bad address in ticket"); ret = KRB4ET_RD_AP_BADD; + krb5_set_error_message(context, ret, "v4 bad address in ticket"); goto error; } @@ -875,7 +876,7 @@ _krb5_krb_rd_req(krb5_context context, delta_t = abs((int)(tv.tv_sec - r_time_sec)); if (delta_t > CLOCK_SKEW) { ret = KRB4ET_RD_AP_TIME; - krb5_set_error_string(context, "v4 clock skew"); + krb5_set_error_message(context, ret, "v4 clock skew"); goto error; } @@ -885,13 +886,13 @@ _krb5_krb_rd_req(krb5_context context, if ((tkt_age < 0) && (-tkt_age > CLOCK_SKEW)) { ret = KRB4ET_RD_AP_NYV; - krb5_set_error_string(context, "v4 clock skew for expiration"); + krb5_set_error_message(context, ret, "v4 clock skew for expiration"); goto error; } if (tv.tv_sec > _krb5_krb_life_to_time(ad->time_sec, ad->life)) { ret = KRB4ET_RD_AP_EXP; - krb5_set_error_string(context, "v4 ticket expired"); + krb5_set_error_message(context, ret, "v4 ticket expired"); goto error; } diff --git a/source4/heimdal/lib/krb5/warn.c b/source4/heimdal/lib/krb5/warn.c index 85f143b8b4..97a6cc9e0a 100644 --- a/source4/heimdal/lib/krb5/warn.c +++ b/source4/heimdal/lib/krb5/warn.c @@ -34,7 +34,7 @@ #include "krb5_locl.h" #include <err.h> -RCSID("$Id: warn.c 19086 2006-11-21 08:06:40Z lha $"); +RCSID("$Id: warn.c 23206 2008-05-29 02:13:41Z lha $"); static krb5_error_code _warnerr(krb5_context context, int do_errtext, krb5_error_code code, int level, const char *fmt, va_list ap) @@ -47,7 +47,7 @@ _warnerr(krb5_context context, int do_errtext, char xfmt[7] = ""; const char *args[2], **arg; char *msg = NULL; - char *err_str = NULL; + const char *err_str = NULL; args[0] = args[1] = NULL; arg = args; @@ -65,7 +65,7 @@ _warnerr(krb5_context context, int do_errtext, strlcat(xfmt, "%s", sizeof(xfmt)); - err_str = krb5_get_error_string(context); + err_str = krb5_get_error_message(context, code); if (err_str != NULL) { *arg++ = err_str; } else { @@ -82,7 +82,7 @@ _warnerr(krb5_context context, int do_errtext, else warnx(xfmt, args[0], args[1]); free(msg); - free(err_str); + krb5_free_error_message(context, err_str); return 0; } diff --git a/source4/heimdal/lib/ntlm/ntlm.c b/source4/heimdal/lib/ntlm/ntlm.c index f3dccfaca1..d3309824b5 100644 --- a/source4/heimdal/lib/ntlm/ntlm.c +++ b/source4/heimdal/lib/ntlm/ntlm.c @@ -33,7 +33,7 @@ #include <config.h> -RCSID("$Id: ntlm.c 22370 2007-12-28 16:12:01Z lha $"); +RCSID("$Id: ntlm.c 23169 2008-05-22 02:52:07Z lha $"); #include <stdio.h> #include <stdlib.h> @@ -68,7 +68,7 @@ RCSID("$Id: ntlm.c 22370 2007-12-28 16:12:01Z lha $"); * Heimdal to implement and GSS-API mechanism. There is also support * in the KDC to do remote digest authenticiation, this to allow * services to authenticate users w/o direct access to the users ntlm - * hashes (same as Kerberos arcfour enctype hashes). + * hashes (same as Kerberos arcfour enctype keys). * * More information about the NTLM protocol can found here * http://davenport.sourceforge.net/ntlm.html . @@ -876,7 +876,7 @@ splitandenc(unsigned char *hash, ((unsigned char*)key)[7] = (hash[6] << 1); DES_set_odd_parity(&key); - DES_set_key(&key, &sched); + DES_set_key_unchecked(&key, &sched); DES_ecb_encrypt((DES_cblock *)challange, (DES_cblock *)answer, &sched, 1); memset(&sched, 0, sizeof(sched)); memset(key, 0, sizeof(key)); diff --git a/source4/heimdal/lib/roken/dumpdata.c b/source4/heimdal/lib/roken/dumpdata.c index c445bfa361..81fd127296 100644 --- a/source4/heimdal/lib/roken/dumpdata.c +++ b/source4/heimdal/lib/roken/dumpdata.c @@ -33,7 +33,7 @@ #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$Id: dumpdata.c 21005 2007-06-08 01:54:35Z lha $"); +RCSID("$Id: dumpdata.c 23412 2008-07-26 18:34:23Z lha $"); #endif #include <unistd.h> @@ -55,3 +55,45 @@ rk_dumpdata (const char *filename, const void *buf, size_t size) net_write(fd, buf, size); close(fd); } + +/* + * Read all data from a filename, care about errors. + */ + +int ROKEN_LIB_FUNCTION +rk_undumpdata(const char *filename, void **buf, size_t *size) +{ + struct stat sb; + int fd, ret; + ssize_t sret; + + *buf = NULL; + + fd = open(filename, O_RDONLY, 0); + if (fd < 0) + return errno; + if (fstat(fd, &sb) != 0){ + ret = errno; + goto out; + } + *buf = malloc(sb.st_size); + if (*buf == NULL) { + ret = ENOMEM; + goto out; + } + *size = sb.st_size; + + sret = net_read(fd, *buf, *size); + if (sret < 0) + ret = errno; + else if (sret != *size) { + ret = EINVAL; + free(*buf); + *buf = NULL; + } else + ret = 0; + + out: + close(fd); + return ret; +} diff --git a/source4/heimdal/lib/roken/err.hin b/source4/heimdal/lib/roken/err.hin index fcae879279..2f1232d3e7 100644 --- a/source4/heimdal/lib/roken/err.hin +++ b/source4/heimdal/lib/roken/err.hin @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: err.hin,v 1.18 2005/04/12 11:28:38 lha Exp $ */ +/* $Id: err.hin 14773 2005-04-12 11:29:18Z lha $ */ #ifndef __ERR_H__ #define __ERR_H__ diff --git a/source4/heimdal/lib/roken/resolve.c b/source4/heimdal/lib/roken/resolve.c index a8778fda57..bf064e8aae 100644 --- a/source4/heimdal/lib/roken/resolve.c +++ b/source4/heimdal/lib/roken/resolve.c @@ -45,7 +45,7 @@ #include <assert.h> -RCSID("$Id: resolve.c 19869 2007-01-12 16:03:14Z lha $"); +RCSID("$Id: resolve.c 22873 2008-04-07 18:50:39Z lha $"); #ifdef _AIX /* AIX have broken res_nsearch() in 5.1 (5.0 also ?) */ #undef HAVE_RES_NSEARCH @@ -128,7 +128,8 @@ parse_record(const unsigned char *data, const unsigned char *end_data, const unsigned char **pp, struct resource_record **ret_rr) { struct resource_record *rr; - int type, class, ttl, size; + int type, class, ttl; + unsigned size; int status; char host[MAXDNAME]; const unsigned char *p = *pp; diff --git a/source4/heimdal/lib/roken/roken-common.h b/source4/heimdal/lib/roken/roken-common.h index b835e880a2..f943202c45 100644 --- a/source4/heimdal/lib/roken/roken-common.h +++ b/source4/heimdal/lib/roken/roken-common.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: roken-common.h 20867 2007-06-03 21:00:45Z lha $ */ +/* $Id: roken-common.h 23468 2008-07-27 12:16:56Z lha $ */ #ifndef __ROKEN_COMMON_H__ #define __ROKEN_COMMON_H__ @@ -400,6 +400,19 @@ rk_strpoolfree(struct rk_strpool *); void ROKEN_LIB_FUNCTION rk_dumpdata (const char *, const void *, size_t); +int ROKEN_LIB_FUNCTION +rk_undumpdata (const char *, void **, size_t *); + +void ROKEN_LIB_FUNCTION +rk_xfree (void *); + +void ROKEN_LIB_FUNCTION +rk_cloexec(int); + +void ROKEN_LIB_FUNCTION +rk_cloexec_file(FILE *); + + ROKEN_CPP_END #endif /* __ROKEN_COMMON_H__ */ diff --git a/source4/heimdal/lib/roken/roken.h.in b/source4/heimdal/lib/roken/roken.h.in index 82473d7053..cf2ee9ed7b 100644 --- a/source4/heimdal/lib/roken/roken.h.in +++ b/source4/heimdal/lib/roken/roken.h.in @@ -32,7 +32,7 @@ * SUCH DAMAGE. */ -/* $Id: roken.h.in,v 1.182 2006/10/19 16:35:16 lha Exp $ */ +/* $Id: roken.h.in 18612 2006-10-19 16:35:16Z lha $ */ #include <stdio.h> #include <stdlib.h> diff --git a/source4/heimdal/lib/roken/vis.hin b/source4/heimdal/lib/roken/vis.hin index b7a6f3ceff..224870b00a 100644 --- a/source4/heimdal/lib/roken/vis.hin +++ b/source4/heimdal/lib/roken/vis.hin @@ -1,5 +1,5 @@ /* $NetBSD: vis.h,v 1.11 1999/11/25 16:55:50 wennmach Exp $ */ -/* $Id: vis.hin,v 1.7 2006/12/15 11:53:09 lha Exp $ */ +/* $Id: vis.hin 19341 2006-12-15 11:53:09Z lha $ */ /*- * Copyright (c) 1990, 1993 diff --git a/source4/heimdal/lib/wind/stringprep.c b/source4/heimdal/lib/wind/stringprep.c index 0beba76384..7c28fdae1f 100644 --- a/source4/heimdal/lib/wind/stringprep.c +++ b/source4/heimdal/lib/wind/stringprep.c @@ -36,10 +36,10 @@ #endif #include "windlocl.h" #include <stdlib.h> -#include <strings.h> +#include <string.h> #include <errno.h> -RCSID("$Id: stringprep.c 22593 2008-02-12 11:58:01Z lha $"); +RCSID("$Id: stringprep.c 23063 2008-04-21 11:18:04Z lha $"); /** * Process a input UCS4 string according a string-prep profile. diff --git a/source4/heimdal/lib/wind/utf8.c b/source4/heimdal/lib/wind/utf8.c index c49e80522e..544e0fe00d 100644 --- a/source4/heimdal/lib/wind/utf8.c +++ b/source4/heimdal/lib/wind/utf8.c @@ -36,7 +36,68 @@ #endif #include "windlocl.h" -RCSID("$Id: utf8.c 22572 2008-02-05 20:22:39Z lha $"); +RCSID("$Id: utf8.c 23246 2008-06-01 22:29:04Z lha $"); + +static int +utf8toutf32(const unsigned char **pp, uint32_t *out) +{ + const unsigned char *p = *pp; + unsigned c = *p; + + if (c & 0x80) { + if ((c & 0xE0) == 0xC0) { + const unsigned c2 = *++p; + if ((c2 & 0xC0) == 0x80) { + *out = ((c & 0x1F) << 6) + | (c2 & 0x3F); + } else { + return WIND_ERR_INVALID_UTF8; + } + } else if ((c & 0xF0) == 0xE0) { + const unsigned c2 = *++p; + if ((c2 & 0xC0) == 0x80) { + const unsigned c3 = *++p; + if ((c3 & 0xC0) == 0x80) { + *out = ((c & 0x0F) << 12) + | ((c2 & 0x3F) << 6) + | (c3 & 0x3F); + } else { + return WIND_ERR_INVALID_UTF8; + } + } else { + return WIND_ERR_INVALID_UTF8; + } + } else if ((c & 0xF8) == 0xF0) { + const unsigned c2 = *++p; + if ((c2 & 0xC0) == 0x80) { + const unsigned c3 = *++p; + if ((c3 & 0xC0) == 0x80) { + const unsigned c4 = *++p; + if ((c4 & 0xC0) == 0x80) { + *out = ((c & 0x07) << 18) + | ((c2 & 0x3F) << 12) + | ((c3 & 0x3F) << 6) + | (c4 & 0x3F); + } else { + return WIND_ERR_INVALID_UTF8; + } + } else { + return WIND_ERR_INVALID_UTF8; + } + } else { + return WIND_ERR_INVALID_UTF8; + } + } else { + return WIND_ERR_INVALID_UTF8; + } + } else { + *out = c; + } + + *pp = p; + + return 0; +} /** * Convert an UTF-8 string to an UCS4 string. @@ -59,60 +120,15 @@ wind_utf8ucs4(const char *in, uint32_t *out, size_t *out_len) { const unsigned char *p; size_t o = 0; + int ret; for (p = (const unsigned char *)in; *p != '\0'; ++p) { - unsigned c = *p; uint32_t u; - if (c & 0x80) { - if ((c & 0xE0) == 0xC0) { - const unsigned c2 = *++p; - if ((c2 & 0xC0) == 0x80) { - u = ((c & 0x1F) << 6) - | (c2 & 0x3F); - } else { - return WIND_ERR_INVALID_UTF8; - } - } else if ((c & 0xF0) == 0xE0) { - const unsigned c2 = *++p; - if ((c2 & 0xC0) == 0x80) { - const unsigned c3 = *++p; - if ((c3 & 0xC0) == 0x80) { - u = ((c & 0x0F) << 12) - | ((c2 & 0x3F) << 6) - | (c3 & 0x3F); - } else { - return WIND_ERR_INVALID_UTF8; - } - } else { - return WIND_ERR_INVALID_UTF8; - } - } else if ((c & 0xF8) == 0xF0) { - const unsigned c2 = *++p; - if ((c2 & 0xC0) == 0x80) { - const unsigned c3 = *++p; - if ((c3 & 0xC0) == 0x80) { - const unsigned c4 = *++p; - if ((c4 & 0xC0) == 0x80) { - u = ((c & 0x07) << 18) - | ((c2 & 0x3F) << 12) - | ((c3 & 0x3F) << 6) - | (c4 & 0x3F); - } else { - return WIND_ERR_INVALID_UTF8; - } - } else { - return WIND_ERR_INVALID_UTF8; - } - } else { - return WIND_ERR_INVALID_UTF8; - } - } else { - return WIND_ERR_INVALID_UTF8; - } - } else { - u = c; - } + ret = utf8toutf32(&p, &u); + if (ret) + return ret; + if (out) { if (o >= *out_len) return WIND_ERR_OVERRUN; @@ -365,6 +381,67 @@ wind_ucs2write(const uint16_t *in, size_t in_len, unsigned int *flags, /** + * Convert an UTF-8 string to an UCS2 string. + * + * @param in an UTF-8 string to convert. + * @param out the resulting UCS2 strint, must be at least + * wind_utf8ucs2_length() long. If out is NULL, the function will + * calculate the needed space for the out variable (just like + * wind_utf8ucs2_length()). + * @param out_len before processing out_len should be the length of + * the out variable, after processing it will be the length of the out + * string. + * + * @return returns 0 on success, an wind error code otherwise + * @ingroup wind + */ + +int +wind_utf8ucs2(const char *in, uint16_t *out, size_t *out_len) +{ + const unsigned char *p; + size_t o = 0; + int ret; + + for (p = (const unsigned char *)in; *p != '\0'; ++p) { + uint32_t u; + + ret = utf8toutf32(&p, &u); + if (ret) + return ret; + + if (u & 0xffff0000) + return WIND_ERR_NOT_UTF16; + + if (out) { + if (o >= *out_len) + return WIND_ERR_OVERRUN; + out[o] = u; + } + o++; + } + *out_len = o; + return 0; +} + +/** + * Calculate the length of from converting a UTF-8 string to a UCS2 + * string. + * + * @param in an UTF-8 string to convert. + * @param out_len the length of the resulting UCS4 string. + * + * @return returns 0 on success, an wind error code otherwise + * @ingroup wind + */ + +int +wind_utf8ucs2_length(const char *in, size_t *out_len) +{ + return wind_utf8ucs2(in, NULL, out_len); +} + +/** * Convert an UCS2 string to a UTF-8 string. * * @param in an UCS2 string to convert. diff --git a/source4/heimdal/lib/wind/wind.h b/source4/heimdal/lib/wind/wind.h index 6921b619f5..3120e87da5 100644 --- a/source4/heimdal/lib/wind/wind.h +++ b/source4/heimdal/lib/wind/wind.h @@ -31,13 +31,13 @@ * SUCH DAMAGE. */ -/* $Id: wind.h 22595 2008-02-12 11:59:05Z lha $ */ +/* $Id: wind.h 23233 2008-06-01 22:25:25Z lha $ */ #ifndef _WIND_H_ #define _WIND_H_ #include <stddef.h> -#include <stdint.h> +#include <krb5-types.h> #include <wind_err.h> @@ -58,9 +58,9 @@ typedef unsigned int wind_profile_flags; #define WIND_RW_BE 2 #define WIND_RW_BOM 4 -int wind_stringprep(const unsigned *in, size_t in_len, - unsigned *out, size_t *out_len, - wind_profile_flags flags); +int wind_stringprep(const uint32_t *, size_t, + uint32_t *, size_t *, + wind_profile_flags); int wind_profile(const char *, wind_profile_flags *); int wind_punycode_label_toascii(const uint32_t *, size_t, @@ -72,6 +72,9 @@ int wind_utf8ucs4_length(const char *, size_t *); int wind_ucs4utf8(const uint32_t *, size_t, char *, size_t *); int wind_ucs4utf8_length(const uint32_t *, size_t, size_t *); +int wind_utf8ucs2(const char *, uint16_t *, size_t *); +int wind_utf8ucs2_length(const char *, size_t *); + int wind_ucs2utf8(const uint16_t *, size_t, char *, size_t *); int wind_ucs2utf8_length(const uint16_t *, size_t, size_t *); diff --git a/source4/heimdal/lib/wind/wind_err.et b/source4/heimdal/lib/wind/wind_err.et index 025c402790..65bdff992f 100644 --- a/source4/heimdal/lib/wind/wind_err.et +++ b/source4/heimdal/lib/wind/wind_err.et @@ -3,7 +3,7 @@ # # This might look like a com_err file, but is not # -id "$Id: wind_err.et 22559 2008-02-03 16:35:07Z lha $" +id "$Id: wind_err.et 23233 2008-06-01 22:25:25Z lha $" error_table wind @@ -18,5 +18,6 @@ error_code INVALID_UTF8, "Invalid UTF-8 combination in string" error_code INVALID_UTF16, "Invalid UTF-16 combination in string" error_code INVALID_UTF32, "Invalid UTF-32 combination in string" error_code NO_BOM, "No byte order mark (BOM) in string" +error_code NOT_UTF16, "Code can't be represented as UTF-16" end diff --git a/source4/heimdal/lib/wind/windlocl.h b/source4/heimdal/lib/wind/windlocl.h index 02e8c46481..009a4ae94a 100644 --- a/source4/heimdal/lib/wind/windlocl.h +++ b/source4/heimdal/lib/wind/windlocl.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: windlocl.h 22582 2008-02-11 20:43:50Z lha $ */ +/* $Id: windlocl.h 23187 2008-05-23 15:04:07Z lha $ */ #ifndef _WINDLOCL_H_ #define _WINDLOCL_H_ @@ -40,6 +40,8 @@ #include <config.h> #endif +#include <krb5-types.h> + #include "wind.h" #include "wind_err.h" |