summaryrefslogtreecommitdiff
path: root/source4
diff options
context:
space:
mode:
Diffstat (limited to 'source4')
-rw-r--r--source4/Makefile4
-rw-r--r--source4/auth/credentials/credentials_krb5.c12
-rw-r--r--source4/auth/gensec/gensec_gssapi.c2
-rw-r--r--source4/auth/kerberos/krb5_init_context.c5
-rw-r--r--source4/auth/kerberos/krb5_init_context.h1
-rw-r--r--source4/auth/ntlm/auth_server.c14
-rw-r--r--source4/auth/ntlmssp/ntlmssp_server.c6
-rw-r--r--source4/build/m4/env.m43
-rwxr-xr-xsource4/build/make/lex_compile.sh13
-rwxr-xr-xsource4/build/make/yacc_compile.sh4
-rw-r--r--source4/dsdb/samdb/ldb_modules/schema_fsmo.c1
-rw-r--r--source4/dsdb/schema/schema_init.c5
-rw-r--r--source4/heimdal/README23
-rw-r--r--source4/heimdal/cf/check-var.m43
-rw-r--r--source4/heimdal/cf/find-func-no-libs.m42
-rw-r--r--source4/heimdal/cf/find-func-no-libs2.m42
-rw-r--r--source4/heimdal/cf/find-func.m42
-rw-r--r--source4/heimdal/cf/resolv.m42
-rw-r--r--source4/heimdal/kdc/default_config.c4
-rw-r--r--source4/heimdal/kdc/digest.c200
-rw-r--r--source4/heimdal/kdc/kaserver.c8
-rw-r--r--source4/heimdal/kdc/kerberos5.c14
-rw-r--r--source4/heimdal/kdc/krb5tgs.c639
-rw-r--r--source4/heimdal/kdc/kx509.c36
-rw-r--r--source4/heimdal/kdc/misc.c11
-rwxr-xr-xsource4/heimdal/kdc/pkinit.c146
-rw-r--r--source4/heimdal/kdc/process.c9
-rw-r--r--source4/heimdal/kdc/windc.c6
-rw-r--r--source4/heimdal/kdc/windc_plugin.h4
-rw-r--r--source4/heimdal/kuser/kinit.c61
-rw-r--r--source4/heimdal/lib/asn1/der.h2
-rw-r--r--source4/heimdal/lib/asn1/der_free.c2
-rw-r--r--source4/heimdal/lib/asn1/gen.c17
-rw-r--r--source4/heimdal/lib/asn1/k5.asn124
-rw-r--r--source4/heimdal/lib/asn1/lex.c73
-rw-r--r--source4/heimdal/lib/asn1/lex.l2
-rw-r--r--source4/heimdal/lib/asn1/pkinit.asn113
-rw-r--r--source4/heimdal/lib/asn1/test.gen2
-rw-r--r--source4/heimdal/lib/com_err/lex.c73
-rw-r--r--source4/heimdal/lib/com_err/lex.l2
-rw-r--r--source4/heimdal/lib/gssapi/gssapi/gssapi.h137
-rw-r--r--source4/heimdal/lib/gssapi/gssapi/gssapi_krb5.h95
-rw-r--r--source4/heimdal/lib/gssapi/gssapi/gssapi_spnego.h4
-rw-r--r--source4/heimdal/lib/gssapi/krb5/accept_sec_context.c75
-rw-r--r--source4/heimdal/lib/gssapi/krb5/delete_sec_context.c4
-rw-r--r--source4/heimdal/lib/gssapi/krb5/display_status.c4
-rw-r--r--source4/heimdal/lib/gssapi/krb5/external.c177
-rw-r--r--source4/heimdal/lib/gssapi/krb5/get_mic.c6
-rw-r--r--source4/heimdal/lib/gssapi/krb5/gsskrb5_locl.h11
-rw-r--r--source4/heimdal/lib/gssapi/krb5/import_sec_context.c8
-rw-r--r--source4/heimdal/lib/gssapi/krb5/init_sec_context.c272
-rw-r--r--source4/heimdal/lib/gssapi/krb5/set_cred_option.c2
-rw-r--r--source4/heimdal/lib/gssapi/krb5/set_sec_context_option.c61
-rw-r--r--source4/heimdal/lib/gssapi/krb5/unwrap.c8
-rw-r--r--source4/heimdal/lib/gssapi/krb5/verify_mic.c6
-rw-r--r--source4/heimdal/lib/gssapi/krb5/wrap.c14
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_acquire_cred.c4
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_add_cred.c4
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_add_oid_set_member.c4
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_buffer_set.c8
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_canonicalize_name.c4
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_compare_name.c4
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_context_time.c4
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_create_empty_oid_set.c4
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_decapsulate_token.c4
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_delete_sec_context.c4
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_display_name.c4
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_display_status.c4
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_encapsulate_token.c4
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_export_name.c4
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_export_sec_context.c4
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_get_mic.c4
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_import_name.c4
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_import_sec_context.c4
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_indicate_mechs.c4
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_init_sec_context.c4
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_inquire_context.c4
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_inquire_cred.c4
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_inquire_cred_by_mech.c4
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_inquire_cred_by_oid.c4
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_inquire_mechs_for_name.c4
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_inquire_names_for_mech.c4
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_inquire_sec_context_by_oid.c4
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_krb5.c91
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_mech_switch.c7
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_oid_equal.c4
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_oid_to_str.c4
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_process_context_token.c4
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_pseudo_random.c69
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_release_buffer.c4
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_release_cred.c4
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_release_name.c4
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_release_oid.c4
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_release_oid_set.c4
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_seal.c4
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_set_cred_option.c4
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_set_sec_context_option.c4
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_sign.c4
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_test_oid_set_member.c4
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_unseal.c4
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_unwrap.c4
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_verify.c4
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_verify_mic.c4
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_wrap.c4
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_wrap_size_limit.c4
-rw-r--r--source4/heimdal/lib/gssapi/spnego/accept_sec_context.c98
-rw-r--r--source4/heimdal/lib/gssapi/spnego/compat.c5
-rw-r--r--source4/heimdal/lib/gssapi/spnego/context_stubs.c32
-rw-r--r--source4/heimdal/lib/gssapi/spnego/cred_stubs.c22
-rw-r--r--source4/heimdal/lib/gssapi/spnego/external.c13
-rw-r--r--source4/heimdal/lib/gssapi/spnego/spnego-private.h16
-rw-r--r--source4/heimdal/lib/gssapi/spnego/spnego_locl.h3
-rw-r--r--[-rwxr-xr-x]source4/heimdal/lib/hcrypto/aes.c0
-rw-r--r--[-rwxr-xr-x]source4/heimdal/lib/hcrypto/aes.h10
-rw-r--r--source4/heimdal/lib/hcrypto/bn.c6
-rw-r--r--source4/heimdal/lib/hcrypto/camellia-ntt.c22
-rw-r--r--source4/heimdal/lib/hcrypto/camellia-ntt.h6
-rw-r--r--source4/heimdal/lib/hcrypto/camellia.h8
-rw-r--r--source4/heimdal/lib/hcrypto/des.c302
-rw-r--r--source4/heimdal/lib/hcrypto/des.h78
-rw-r--r--source4/heimdal/lib/hcrypto/evp.c31
-rw-r--r--source4/heimdal/lib/hcrypto/evp.h26
-rw-r--r--source4/heimdal/lib/hcrypto/imath/LICENSE2
-rw-r--r--source4/heimdal/lib/hcrypto/pkcs12.c24
-rw-r--r--source4/heimdal/lib/hcrypto/pkcs5.c18
-rw-r--r--source4/heimdal/lib/hcrypto/rand-egd.c4
-rw-r--r--source4/heimdal/lib/hcrypto/rand-fortuna.c15
-rw-r--r--source4/heimdal/lib/hcrypto/rand-unix.c6
-rw-r--r--source4/heimdal/lib/hcrypto/rand.c166
-rw-r--r--[-rwxr-xr-x]source4/heimdal/lib/hcrypto/rc2.c0
-rw-r--r--[-rwxr-xr-x]source4/heimdal/lib/hcrypto/rc2.h0
-rw-r--r--[-rwxr-xr-x]source4/heimdal/lib/hcrypto/rc4.c0
-rw-r--r--[-rwxr-xr-x]source4/heimdal/lib/hcrypto/rijndael-alg-fst.c0
-rw-r--r--[-rwxr-xr-x]source4/heimdal/lib/hcrypto/rijndael-alg-fst.h0
-rw-r--r--source4/heimdal/lib/hcrypto/rnd_keys.c471
-rw-r--r--source4/heimdal/lib/hcrypto/ui.c8
-rw-r--r--source4/heimdal/lib/hdb/db.c40
-rw-r--r--source4/heimdal/lib/hdb/dbinfo.c4
-rw-r--r--source4/heimdal/lib/hdb/ext.c45
-rw-r--r--source4/heimdal/lib/hdb/hdb.c7
-rw-r--r--source4/heimdal/lib/hdb/keys.c13
-rw-r--r--source4/heimdal/lib/hdb/keytab.c10
-rw-r--r--source4/heimdal/lib/hdb/mkey.c33
-rw-r--r--source4/heimdal/lib/hdb/ndbm.c38
-rw-r--r--source4/heimdal/lib/hx509/ca.c4
-rw-r--r--source4/heimdal/lib/hx509/cert.c162
-rw-r--r--source4/heimdal/lib/hx509/cms.c16
-rw-r--r--source4/heimdal/lib/hx509/crypto.c14
-rw-r--r--source4/heimdal/lib/hx509/env.c181
-rw-r--r--source4/heimdal/lib/hx509/file.c81
-rw-r--r--source4/heimdal/lib/hx509/hx509-private.h43
-rw-r--r--source4/heimdal/lib/hx509/hx509-protos.h42
-rw-r--r--source4/heimdal/lib/hx509/hx509.h13
-rw-r--r--source4/heimdal/lib/hx509/hx_locl.h22
-rw-r--r--source4/heimdal/lib/hx509/keyset.c16
-rw-r--r--source4/heimdal/lib/hx509/ks_dir.c3
-rw-r--r--source4/heimdal/lib/hx509/ks_file.c8
-rw-r--r--source4/heimdal/lib/hx509/ks_p11.c31
-rw-r--r--source4/heimdal/lib/hx509/ks_p12.c7
-rw-r--r--source4/heimdal/lib/hx509/name.c4
-rw-r--r--source4/heimdal/lib/hx509/req.c6
-rw-r--r--source4/heimdal/lib/hx509/revoke.c38
-rw-r--r--source4/heimdal/lib/hx509/sel-gram.c1714
-rw-r--r--source4/heimdal/lib/hx509/sel-gram.h83
-rw-r--r--source4/heimdal/lib/hx509/sel-gram.y115
-rw-r--r--source4/heimdal/lib/hx509/sel-lex.c1899
-rw-r--r--source4/heimdal/lib/hx509/sel-lex.l135
-rw-r--r--source4/heimdal/lib/hx509/sel.c232
-rw-r--r--source4/heimdal/lib/hx509/sel.h82
-rw-r--r--source4/heimdal/lib/hx509/test_name.c7
-rw-r--r--source4/heimdal/lib/krb5/acache.c71
-rw-r--r--source4/heimdal/lib/krb5/addr_families.c75
-rw-r--r--source4/heimdal/lib/krb5/auth_context.c18
-rw-r--r--source4/heimdal/lib/krb5/build_auth.c10
-rw-r--r--source4/heimdal/lib/krb5/cache.c256
-rw-r--r--source4/heimdal/lib/krb5/changepw.c97
-rw-r--r--source4/heimdal/lib/krb5/config_file.c10
-rw-r--r--source4/heimdal/lib/krb5/constants.c6
-rw-r--r--source4/heimdal/lib/krb5/context.c78
-rw-r--r--source4/heimdal/lib/krb5/convert_creds.c8
-rw-r--r--source4/heimdal/lib/krb5/copy_host_realm.c17
-rw-r--r--source4/heimdal/lib/krb5/crc.c4
-rw-r--r--source4/heimdal/lib/krb5/creds.c8
-rw-r--r--source4/heimdal/lib/krb5/crypto.c584
-rw-r--r--source4/heimdal/lib/krb5/data.c4
-rw-r--r--source4/heimdal/lib/krb5/error_string.c146
-rw-r--r--source4/heimdal/lib/krb5/expand_hostname.c7
-rw-r--r--source4/heimdal/lib/krb5/fcache.c204
-rw-r--r--source4/heimdal/lib/krb5/generate_subkey.c4
-rw-r--r--source4/heimdal/lib/krb5/get_cred.c588
-rw-r--r--source4/heimdal/lib/krb5/get_default_principal.c6
-rw-r--r--source4/heimdal/lib/krb5/get_default_realm.c4
-rw-r--r--source4/heimdal/lib/krb5/get_for_creds.c21
-rw-r--r--source4/heimdal/lib/krb5/get_host_realm.c16
-rw-r--r--source4/heimdal/lib/krb5/get_in_tkt.c377
-rw-r--r--source4/heimdal/lib/krb5/init_creds.c14
-rw-r--r--source4/heimdal/lib/krb5/init_creds_pw.c110
-rw-r--r--source4/heimdal/lib/krb5/kcm.c56
-rw-r--r--source4/heimdal/lib/krb5/keyblock.c15
-rw-r--r--source4/heimdal/lib/krb5/keytab.c57
-rw-r--r--source4/heimdal/lib/krb5/keytab_any.c17
-rw-r--r--source4/heimdal/lib/krb5/keytab_file.c54
-rw-r--r--source4/heimdal/lib/krb5/keytab_keyfile.c54
-rw-r--r--source4/heimdal/lib/krb5/keytab_memory.c8
-rw-r--r--source4/heimdal/lib/krb5/krb5-private.h32
-rw-r--r--source4/heimdal/lib/krb5/krb5-protos.h83
-rw-r--r--source4/heimdal/lib/krb5/krb5.h50
-rw-r--r--source4/heimdal/lib/krb5/krb5_err.et6
-rw-r--r--source4/heimdal/lib/krb5/krb5_locl.h30
-rw-r--r--source4/heimdal/lib/krb5/krbhst.c22
-rw-r--r--source4/heimdal/lib/krb5/locate_plugin.h4
-rw-r--r--source4/heimdal/lib/krb5/log.c24
-rw-r--r--source4/heimdal/lib/krb5/mcache.c15
-rw-r--r--source4/heimdal/lib/krb5/mk_priv.c4
-rw-r--r--source4/heimdal/lib/krb5/mk_rep.c12
-rw-r--r--source4/heimdal/lib/krb5/n-fold.c2
-rw-r--r--source4/heimdal/lib/krb5/pac.c113
-rw-r--r--source4/heimdal/lib/krb5/padata.c4
-rwxr-xr-xsource4/heimdal/lib/krb5/pkinit.c415
-rw-r--r--source4/heimdal/lib/krb5/plugin.c19
-rw-r--r--source4/heimdal/lib/krb5/principal.c114
-rw-r--r--source4/heimdal/lib/krb5/rd_cred.c9
-rw-r--r--source4/heimdal/lib/krb5/rd_error.c36
-rw-r--r--source4/heimdal/lib/krb5/rd_rep.c4
-rw-r--r--source4/heimdal/lib/krb5/rd_req.c21
-rw-r--r--source4/heimdal/lib/krb5/replay.c31
-rw-r--r--source4/heimdal/lib/krb5/send_to_kdc.c62
-rw-r--r--source4/heimdal/lib/krb5/send_to_kdc_plugin.h58
-rw-r--r--source4/heimdal/lib/krb5/set_default_realm.c6
-rw-r--r--source4/heimdal/lib/krb5/ticket.c36
-rw-r--r--source4/heimdal/lib/krb5/time.c31
-rw-r--r--source4/heimdal/lib/krb5/transited.c42
-rw-r--r--source4/heimdal/lib/krb5/v4_glue.c71
-rw-r--r--source4/heimdal/lib/krb5/warn.c8
-rw-r--r--source4/heimdal/lib/ntlm/ntlm.c6
-rw-r--r--source4/heimdal/lib/roken/cloexec.c60
-rw-r--r--source4/heimdal/lib/roken/dumpdata.c44
-rw-r--r--source4/heimdal/lib/roken/err.hin2
-rw-r--r--source4/heimdal/lib/roken/resolve.c5
-rw-r--r--source4/heimdal/lib/roken/roken-common.h15
-rw-r--r--source4/heimdal/lib/roken/roken.h.in2
-rw-r--r--source4/heimdal/lib/roken/vis.hin2
-rw-r--r--source4/heimdal/lib/roken/xfree.c47
-rw-r--r--source4/heimdal/lib/wind/stringprep.c4
-rw-r--r--source4/heimdal/lib/wind/utf8.c179
-rw-r--r--source4/heimdal/lib/wind/wind.h13
-rw-r--r--source4/heimdal/lib/wind/wind_err.et3
-rw-r--r--source4/heimdal/lib/wind/windlocl.h4
-rwxr-xr-xsource4/heimdal_build/asn1_deps.pl1
-rwxr-xr-xsource4/heimdal_build/et_deps.pl1
-rw-r--r--source4/heimdal_build/internal.m45
-rw-r--r--source4/heimdal_build/internal.mk41
-rw-r--r--source4/heimdal_build/krb5/windc_plugin.h1
-rw-r--r--source4/kdc/config.mk6
-rw-r--r--source4/kdc/kdc.h6
-rw-r--r--source4/kdc/kpasswdd.c6
-rw-r--r--source4/libcli/smb2/connect.c8
-rw-r--r--source4/libcli/smb2/logoff.c2
-rw-r--r--source4/libcli/smb2/session.c10
-rw-r--r--source4/libcli/smb2/signing.c9
-rw-r--r--source4/libcli/smb2/smb2.h9
-rw-r--r--source4/libcli/smb2/transport.c6
-rw-r--r--source4/librpc/idl/drsblobs.idl97
-rw-r--r--source4/main.mk1
-rw-r--r--source4/rpc_server/dcerpc_server.c1
-rw-r--r--source4/scripting/python/samba/provision.py36
-rw-r--r--source4/smb_server/smb2/negprot.c2
-rw-r--r--source4/smb_server/smb2/receive.c21
-rw-r--r--source4/smb_server/smb2/sesssetup.c34
-rw-r--r--source4/smb_server/smb_server.h7
-rw-r--r--source4/static_deps.mk27
-rw-r--r--source4/torture/rpc/dssync.c42
-rw-r--r--source4/torture/rpc/lsa.c7
-rw-r--r--source4/torture/smb2/connect.c11
274 files changed, 10633 insertions, 3749 deletions
diff --git a/source4/Makefile b/source4/Makefile
index fba06ccfa9..b0aa009edd 100644
--- a/source4/Makefile
+++ b/source4/Makefile
@@ -10,8 +10,6 @@ include mkconfig.mk
pidldir := $(srcdir)/pidl
-VPATH = $(builddir):$(srcdir):$(srcdir)/heimdal_build:$(heimdalsrcdir)/lib/asn1:$(heimdalsrcdir)/lib/krb5:$(heimdalsrcdir)/lib/gssapi:$(heimdalsrcdir)/lib/hdb:$(heimdalsrcdir)/lib/roken:$(heimdalsrcdir)/lib/des
-
BASEDIR = $(prefix)
TORTUREDIR = $(libdir)/torture
SWATDIR = $(datadir)/swat
@@ -138,7 +136,7 @@ libraries:: $(STATIC_LIBS) $(SHARED_LIBS)
modules:: $(PLUGINS)
headers:: $(PUBLIC_HEADERS) $(DEFAULT_HEADERS)
manpages:: $(MANPAGES)
-all:: showflags $(ALL_PREDEP) bin/asn1_compile bin/compile_et binaries modules pythonmods libraries headers
+all:: showflags $(ALL_PREDEP) binaries modules pythonmods libraries headers
everything:: all
LD_LIBPATH_OVERRIDE = $(LIB_PATH_VAR)=$(builddir)/bin/shared
diff --git a/source4/auth/credentials/credentials_krb5.c b/source4/auth/credentials/credentials_krb5.c
index c4c58398c3..1a2d5faddd 100644
--- a/source4/auth/credentials/credentials_krb5.c
+++ b/source4/auth/credentials/credentials_krb5.c
@@ -392,7 +392,17 @@ _PUBLIC_ int cli_credentials_get_client_gss_creds(struct cli_credentials *cred,
return ret;
}
- /* transfer the enctypes from the smb_krb5_context to the gssapi layer */
+ /*
+ * transfer the enctypes from the smb_krb5_context to the gssapi layer
+ *
+ * We use 'our' smb_krb5_context to do the AS-REQ and it is possible
+ * to configure the enctypes via the krb5.conf.
+ *
+ * And the gss_init_sec_context() creates it's own krb5_context and
+ * the TGS-REQ had all enctypes in it and only the ones configured
+ * and used for the AS-REQ, so it wasn't possible to disable the usage
+ * of AES keys.
+ */
min_stat = krb5_get_default_in_tkt_etypes(ccache->smb_krb5_context->krb5_context,
&etypes);
if (min_stat == 0) {
diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c
index 205d8a0f9b..bb44c75901 100644
--- a/source4/auth/gensec/gensec_gssapi.c
+++ b/source4/auth/gensec/gensec_gssapi.c
@@ -24,7 +24,6 @@
#include "includes.h"
#include "lib/events/events.h"
#include "system/kerberos.h"
-#include "heimdal/lib/gssapi/gssapi/gssapi.h"
#include "auth/kerberos/kerberos.h"
#include "librpc/gen_ndr/krb5pac.h"
#include "auth/auth.h"
@@ -37,6 +36,7 @@
#include "auth/gensec/gensec_proto.h"
#include "param/param.h"
#include "auth/session_proto.h"
+#include <gssapi/gssapi.h>
enum gensec_gssapi_sasl_state
{
diff --git a/source4/auth/kerberos/krb5_init_context.c b/source4/auth/kerberos/krb5_init_context.c
index a455fda398..82e42a4560 100644
--- a/source4/auth/kerberos/krb5_init_context.c
+++ b/source4/auth/kerberos/krb5_init_context.c
@@ -22,13 +22,11 @@
#include "includes.h"
#include "system/kerberos.h"
-#include "heimdal/lib/krb5/krb5_locl.h"
#include "auth/kerberos/kerberos.h"
#include "lib/socket/socket.h"
#include "lib/stream/packet.h"
#include "system/network.h"
#include "lib/events/events.h"
-#include "roken.h"
#include "param/param.h"
#include "libcli/resolve/resolve.h"
@@ -208,6 +206,7 @@ static void smb_krb5_socket_handler(struct event_context *ev, struct fd_event *f
krb5_error_code smb_krb5_send_and_recv_func(krb5_context context,
void *data,
krb5_krbhst_info *hi,
+ time_t timeout,
const krb5_data *send_buf,
krb5_data *recv_buf)
{
@@ -298,7 +297,7 @@ krb5_error_code smb_krb5_send_and_recv_func(krb5_context context,
socket_set_flags(smb_krb5->sock, SOCKET_FLAG_NOCLOSE);
event_add_timed(ev, smb_krb5,
- timeval_current_ofs(context->kdc_timeout, 0),
+ timeval_current_ofs(timeout, 0),
smb_krb5_request_timeout, smb_krb5);
diff --git a/source4/auth/kerberos/krb5_init_context.h b/source4/auth/kerberos/krb5_init_context.h
index 44771f2aec..815e9a639d 100644
--- a/source4/auth/kerberos/krb5_init_context.h
+++ b/source4/auth/kerberos/krb5_init_context.h
@@ -32,5 +32,6 @@ void smb_krb5_free_context(struct smb_krb5_context *smb_krb5_context);
krb5_error_code smb_krb5_send_and_recv_func(krb5_context context,
void *data,
krb5_krbhst_info *hi,
+ time_t timeout,
const krb5_data *send_buf,
krb5_data *recv_buf);
diff --git a/source4/auth/ntlm/auth_server.c b/source4/auth/ntlm/auth_server.c
index f154cf0425..bb8773e75e 100644
--- a/source4/auth/ntlm/auth_server.c
+++ b/source4/auth/ntlm/auth_server.c
@@ -70,7 +70,11 @@ static NTSTATUS server_get_challenge(struct auth_method_context *ctx, TALLOC_CTX
io.in.called_name = strupper_talloc(mem_ctx, io.in.dest_host);
/* We don't want to get as far as the session setup */
- io.in.credentials = NULL;
+ io.in.credentials = cli_credentials_init_anon(mem_ctx);
+ cli_credentials_set_workstation(io.in.credentials,
+ lp_netbios_name(ctx->auth_ctx->lp_ctx),
+ CRED_SPECIFIED);
+
io.in.service = NULL;
io.in.workgroup = ""; /* only used with SPNEGO, disabled above */
@@ -79,10 +83,10 @@ static NTSTATUS server_get_challenge(struct auth_method_context *ctx, TALLOC_CTX
status = smb_composite_connect(&io, mem_ctx, lp_resolve_context(ctx->auth_ctx->lp_ctx),
ctx->auth_ctx->event_ctx);
- if (!NT_STATUS_IS_OK(status)) {
- *_blob = io.out.tree->session->transport->negotiate.secblob;
- ctx->private_data = talloc_steal(ctx, io.out.tree->session);
- }
+ NT_STATUS_NOT_OK_RETURN(status);
+
+ *_blob = io.out.tree->session->transport->negotiate.secblob;
+ ctx->private_data = talloc_steal(ctx, io.out.tree->session);
return NT_STATUS_OK;
}
diff --git a/source4/auth/ntlmssp/ntlmssp_server.c b/source4/auth/ntlmssp/ntlmssp_server.c
index dfc5940d99..838596ee98 100644
--- a/source4/auth/ntlmssp/ntlmssp_server.c
+++ b/source4/auth/ntlmssp/ntlmssp_server.c
@@ -157,6 +157,10 @@ NTSTATUS ntlmssp_server_negotiate(struct gensec_security *gensec_security,
/* Ask our caller what challenge they would like in the packet */
cryptkey = gensec_ntlmssp_state->get_challenge(gensec_ntlmssp_state);
+ if (!cryptkey) {
+ DEBUG(1, ("ntlmssp_server_negotiate: backend doesn't give a challenge\n"));
+ return NT_STATUS_INTERNAL_ERROR;
+ }
/* Check if we may set the challenge */
if (!gensec_ntlmssp_state->may_set_challenge(gensec_ntlmssp_state)) {
@@ -614,6 +618,8 @@ static const uint8_t *auth_ntlmssp_get_challenge(const struct gensec_ntlmssp_sta
status = auth_get_challenge(gensec_ntlmssp_state->auth_context, &chal);
if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(1, ("auth_ntlmssp_get_challenge: failed to get challenge: %s\n",
+ nt_errstr(status)));
return NULL;
}
diff --git a/source4/build/m4/env.m4 b/source4/build/m4/env.m4
index 9510a8ee0d..6c040b9bab 100644
--- a/source4/build/m4/env.m4
+++ b/source4/build/m4/env.m4
@@ -16,6 +16,9 @@ export builddir;
AC_SUBST(datarootdir)
+AC_SUBST(VPATH)
+VPATH="\$(builddir):\$(srcdir)"
+
SMB_VERSION_STRING=`cat ${srcdir}/version.h | grep 'SAMBA_VERSION_OFFICIAL_STRING' | cut -d '"' -f2`
echo "SAMBA VERSION: ${SMB_VERSION_STRING}"
diff --git a/source4/build/make/lex_compile.sh b/source4/build/make/lex_compile.sh
index 9bba7257b1..d05056d100 100755
--- a/source4/build/make/lex_compile.sh
+++ b/source4/build/make/lex_compile.sh
@@ -31,20 +31,29 @@ if [ -r $DEST ]; then
fi
fi
TOP=`pwd`
+echo "info: running $LEX $ARGS $file"
if cd $dir && $LEX $ARGS $file; then
- if [ -r $base.yy.c ];then
+ if [ -r lex.yy.c ];then
# we must guarantee that config.h comes first
+ echo "info: move lex.yy.c to $base.c"
+ echo "#include \"config.h\"" > $base.c
+ sed -e "s|lex\.yy\.c|$DEST|" lex.yy.c >> $base.c
+ rm -f $base.yy.c
+ elif [ -r $base.yy.c ];then
+ # we must guarantee that config.h comes first
+ echo "info: move $base.yy.c to $base.c"
echo "#include \"config.h\"" > $base.c
sed -e "s|$base\.yy\.c|$DEST|" $base.yy.c >> $base.c
rm -f $base.yy.c
elif [ -r $base.c ];then
# we must guarantee that config.h comes first
+ echo "info: add #include \"config.h\" to $base.c"
mv $base.c $base.c.tmp
echo "#include \"config.h\"" > $base.c
sed -e "s|$base\.yy\.c|$DEST|" $base.c.tmp >> $base.c
rm -f $base.c.tmp
elif [ ! -r base.c ]; then
- echo "$base.c nor $base.yy.c generated."
+ echo "$base.c nor $base.yy.c nor lex.yy.c generated."
exit 1
fi
fi
diff --git a/source4/build/make/yacc_compile.sh b/source4/build/make/yacc_compile.sh
index a56a51da0a..ac4afea3f6 100755
--- a/source4/build/make/yacc_compile.sh
+++ b/source4/build/make/yacc_compile.sh
@@ -29,10 +29,12 @@ if [ -r $DEST ]; then
fi
fi
TOP=`pwd`
+echo "info: running $YACC -d $file"
if cd $dir && $YACC -d $file; then
if [ -r y.tab.h -a -r y.tab.c ];then
- #echo "info: move files"
+ echo "info: move y.tab.h to $base.h"
sed -e "/^#/!b" -e "s|y\.tab\.h|$SRC|" -e "s|\"$base.y|\"$SRC|" y.tab.h > $base.h
+ echo "info: move y.tab.c to $base.c"
sed -e "s|y\.tab\.c|$SRC|" -e "s|\"$base.y|\"$SRC|" y.tab.c > $base.c
rm -f y.tab.c y.tab.h
elif [ ! -r $base.h -a ! -r $base.c]; then
diff --git a/source4/dsdb/samdb/ldb_modules/schema_fsmo.c b/source4/dsdb/samdb/ldb_modules/schema_fsmo.c
index 2acc5c0af4..87ada855d3 100644
--- a/source4/dsdb/samdb/ldb_modules/schema_fsmo.c
+++ b/source4/dsdb/samdb/ldb_modules/schema_fsmo.c
@@ -150,7 +150,6 @@ static int schema_fsmo_add(struct ldb_module *module, struct ldb_request *req)
static int schema_fsmo_extended(struct ldb_module *module, struct ldb_request *req)
{
- WERROR status;
struct ldb_dn *schema_dn;
struct dsdb_schema *schema;
char *error_string = NULL;
diff --git a/source4/dsdb/schema/schema_init.c b/source4/dsdb/schema/schema_init.c
index 9b8959466d..85fdbe9e87 100644
--- a/source4/dsdb/schema/schema_init.c
+++ b/source4/dsdb/schema/schema_init.c
@@ -566,9 +566,10 @@ WERROR dsdb_read_prefixes_from_ldb(TALLOC_CTX *mem_ctx, struct ldb_context *ldb,
return WERR_NOMEM;
}
for (i=0; i < blob->ctr.dsdb.num_mappings; i++) {
+ char *oid;
(*prefixes)[i].id = blob->ctr.dsdb.mappings[i].id_prefix<<16;
- (*prefixes)[i].oid = talloc_strdup(mem_ctx, blob->ctr.dsdb.mappings[i].oid.oid);
- (*prefixes)[i].oid = talloc_asprintf_append((*prefixes)[i].oid, ".");
+ oid = talloc_strdup(mem_ctx, blob->ctr.dsdb.mappings[i].oid.oid);
+ (*prefixes)[i].oid = talloc_asprintf_append(oid, ".");
(*prefixes)[i].oid_len = strlen(blob->ctr.dsdb.mappings[i].oid.oid);
}
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_pseudo_random.c b/source4/heimdal/lib/gssapi/mech/gss_pseudo_random.c
new file mode 100644
index 0000000000..ba027cb95a
--- /dev/null
+++ b/source4/heimdal/lib/gssapi/mech/gss_pseudo_random.c
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2007 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: gss_pseudo_random.c 23025 2008-04-17 10:01:57Z lha $ */
+
+#include "mech_locl.h"
+RCSID("$Id: gss_pseudo_random.c 23025 2008-04-17 10:01:57Z lha $");
+
+OM_uint32 GSSAPI_LIB_FUNCTION
+gss_pseudo_random(OM_uint32 *minor_status,
+ gss_ctx_id_t context,
+ int prf_key,
+ const gss_buffer_t prf_in,
+ ssize_t desired_output_len,
+ gss_buffer_t prf_out)
+{
+ struct _gss_context *ctx = (struct _gss_context *) context;
+ gssapi_mech_interface m = ctx->gc_mech;
+ OM_uint32 major_status;
+
+ _mg_buffer_zero(prf_out);
+ *minor_status = 0;
+
+ if (ctx == NULL) {
+ *minor_status = 0;
+ return GSS_S_NO_CONTEXT;
+ }
+
+ if (m->gm_pseudo_random == NULL)
+ return GSS_S_UNAVAILABLE;
+
+ major_status = (*m->gm_pseudo_random)(minor_status, ctx->gc_ctx,
+ prf_key, prf_in, desired_output_len,
+ prf_out);
+ if (major_status != GSS_S_COMPLETE)
+ _gss_mg_error(m, major_status, *minor_status);
+
+ return major_status;
+}
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, &copy);
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/cloexec.c b/source4/heimdal/lib/roken/cloexec.c
new file mode 100644
index 0000000000..6308daa1db
--- /dev/null
+++ b/source4/heimdal/lib/roken/cloexec.c
@@ -0,0 +1,60 @@
+/*
+ * 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>
+RCSID("$Id$");
+#endif
+
+#include <unistd.h>
+#include <fcntl.h>
+
+#include <roken.h>
+
+void ROKEN_LIB_FUNCTION
+rk_cloexec(int fd)
+{
+ int ret;
+
+ ret = fcntl(fd, F_GETFD);
+ if (ret == -1)
+ return;
+ if (fcntl(fd, F_SETFD, ret | FD_CLOEXEC) == -1)
+ return;
+}
+
+void ROKEN_LIB_FUNCTION
+rk_cloexec_file(FILE *f)
+{
+ rk_cloexec(fileno(f));
+}
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/roken/xfree.c b/source4/heimdal/lib/roken/xfree.c
new file mode 100644
index 0000000000..7bc21af0b8
--- /dev/null
+++ b/source4/heimdal/lib/roken/xfree.c
@@ -0,0 +1,47 @@
+/*
+ * 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>
+RCSID("$Id$");
+#endif
+
+#include <unistd.h>
+
+#include <roken.h>
+
+void ROKEN_LIB_FUNCTION
+rk_xfree (void *buf)
+{
+ free(buf);
+}
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"
diff --git a/source4/heimdal_build/asn1_deps.pl b/source4/heimdal_build/asn1_deps.pl
index 6b7181c4dd..6c4d10d262 100755
--- a/source4/heimdal_build/asn1_deps.pl
+++ b/source4/heimdal_build/asn1_deps.pl
@@ -29,6 +29,7 @@ if (not defined $options) {
my $header = "$dirname/$prefix.h";
+print "basics:: $header\n";
print "$header: \$(heimdalsrcdir)/$file \$(ASN1C)\n";
print "\t\@echo \"Compiling ASN1 file \$(heimdalsrcdir)/$file\"\n";
print "\t\@\$(heimdalbuildsrcdir)/asn1_compile_wrapper.sh \$(builddir) $dirname \$(ASN1C) \$(call abspath,\$(heimdalsrcdir)/$file) $prefix $options\n\n";
diff --git a/source4/heimdal_build/et_deps.pl b/source4/heimdal_build/et_deps.pl
index 5032d471c7..5914425998 100755
--- a/source4/heimdal_build/et_deps.pl
+++ b/source4/heimdal_build/et_deps.pl
@@ -8,6 +8,7 @@ my $basename = basename($file);
my $header = "$dirname/$basename"; $header =~ s/\.et$/.h/;
my $source = "$dirname/$basename"; $source =~ s/\.et$/.c/;
+print "basics:: $header\n";
print "$header $source: \$(heimdalsrcdir)/$file \$(ET_COMPILER)\n";
print "\t\@echo \"Compiling error table $file\"\n";
print "\t\@\$(heimdalbuildsrcdir)/et_compile_wrapper.sh \$(builddir) $dirname \$(ET_COMPILER) \$(call abspath,\$(heimdalsrcdir)/$file) $source\n\n";
diff --git a/source4/heimdal_build/internal.m4 b/source4/heimdal_build/internal.m4
index 18ecbb75cd..f83fdf7460 100644
--- a/source4/heimdal_build/internal.m4
+++ b/source4/heimdal_build/internal.m4
@@ -186,6 +186,7 @@ SMB_ENABLE(compile_et, NO)
#
LEX_YACC_COMBINATIONS=""
LEX_YACC_COMBINATIONS="$LEX_YACC_COMBINATIONS flex-2.5.33:bison-2.3"
+LEX_YACC_COMBINATIONS="$LEX_YACC_COMBINATIONS flex-2.5.34:bison-2.3"
AC_PROG_LEX
LEX_BASENAME=`basename "$LEX"`
@@ -254,3 +255,7 @@ if test t$ac_cv_func_getprogname != tyes; then
SMB_ENABLE(HEIMDAL_ROKEN_GETPROGNAME, YES)
SMB_ENABLE(HEIMDAL_ROKEN_GETPROGNAME_H, YES)
fi
+
+VPATH="$VPATH:\$(HEIMDAL_VPATH)"
+
+SMB_INCLUDE_MK(heimdal_build/internal.mk)
diff --git a/source4/heimdal_build/internal.mk b/source4/heimdal_build/internal.mk
index 17fc8c93ec..3fb97fea4c 100644
--- a/source4/heimdal_build/internal.mk
+++ b/source4/heimdal_build/internal.mk
@@ -1,11 +1,13 @@
heimdalbuildsrcdir = $(heimdalsrcdir)/../heimdal_build
+HEIMDAL_VPATH = $(heimdalbuildsrcdir):$(heimdalsrcdir)/lib/asn1:$(heimdalsrcdir)/lib/krb5:$(heimdalsrcdir)/lib/gssapi:$(heimdalsrcdir)/lib/hdb:$(heimdalsrcdir)/lib/roken:$(heimdalsrcdir)/lib/des
+
#######################
# Start SUBSYSTEM HEIMDAL_KDC
[SUBSYSTEM::HEIMDAL_KDC]
CFLAGS = -I$(heimdalbuildsrcdir) -I$(heimdalsrcdir)/kdc
-PRIVATE_DEPENDENCIES = HEIMDAL_ROKEN HEIMDAL_KRB5 HEIMDAL_HDB HEIMDAL_HEIM_ASN1 HEIMDAL_DIGEST_ASN1 HEIMDAL_KX509_ASN1
-PUBLIC_DEPENDENCIES = HEIMDAL_NTLM HEIMDAL_HCRYPTO
+PRIVATE_DEPENDENCIES = HEIMDAL_ROKEN HEIMDAL_KRB5 HEIMDAL_HDB HEIMDAL_HEIM_ASN1 \
+ HEIMDAL_DIGEST_ASN1 HEIMDAL_KX509_ASN1 HEIMDAL_NTLM HEIMDAL_HCRYPTO
# End SUBSYSTEM HEIMDAL_KDC
#######################
@@ -61,8 +63,7 @@ HEIMDAL_HDB_OBJ_FILES = \
# Start SUBSYSTEM HEIMDAL_GSSAPI
[SUBSYSTEM::HEIMDAL_GSSAPI]
CFLAGS = -I$(heimdalbuildsrcdir) -I$(heimdalsrcdir)/lib/gssapi -I$(heimdalsrcdir)/lib/gssapi/gssapi -I$(heimdalsrcdir)/lib/gssapi/spnego -I$(heimdalsrcdir)/lib/gssapi/krb5 -I$(heimdalsrcdir)/lib/gssapi/mech
-PRIVATE_DEPENDENCIES = HEIMDAL_HCRYPTO HEIMDAL_HEIM_ASN1 HEIMDAL_SPNEGO_ASN1
-PUBLIC_DEPENDENCIES = HEIMDAL_ROKEN HEIMDAL_KRB5
+PRIVATE_DEPENDENCIES = HEIMDAL_HCRYPTO HEIMDAL_HEIM_ASN1 HEIMDAL_SPNEGO_ASN1 HEIMDAL_ROKEN HEIMDAL_KRB5
# End SUBSYSTEM HEIMDAL_GSSAPI
#######################
@@ -121,6 +122,7 @@ HEIMDAL_GSSAPI_OBJ_FILES = \
$(heimdalsrcdir)/lib/gssapi/mech/gss_inquire_context.o \
$(heimdalsrcdir)/lib/gssapi/mech/gss_release_name.o \
$(heimdalsrcdir)/lib/gssapi/mech/gss_set_cred_option.o \
+ $(heimdalsrcdir)/lib/gssapi/mech/gss_pseudo_random.o \
$(heimdalsrcdir)/lib/gssapi/asn1_GSSAPIContextToken.o \
$(heimdalsrcdir)/lib/gssapi/spnego/init_sec_context.o \
$(heimdalsrcdir)/lib/gssapi/spnego/external.o \
@@ -179,8 +181,8 @@ HEIMDAL_GSSAPI_OBJ_FILES = \
# Start SUBSYSTEM HEIMDAL_KRB5
[SUBSYSTEM::HEIMDAL_KRB5]
CFLAGS = -I$(heimdalbuildsrcdir) -I$(heimdalsrcdir)/lib/krb5 -I$(heimdalsrcdir)/lib/asn1 -I$(heimdalsrcdir)/lib/com_err
-PRIVATE_DEPENDENCIES = HEIMDAL_ROKEN HEIMDAL_PKINIT_ASN1 HEIMDAL_WIND
-PUBLIC_DEPENDENCIES = HEIMDAL_KRB5_ASN1 HEIMDAL_GLUE HEIMDAL_HX509 HEIMDAL_HCRYPTO
+PRIVATE_DEPENDENCIES = HEIMDAL_ROKEN HEIMDAL_PKINIT_ASN1 HEIMDAL_WIND \
+ HEIMDAL_KRB5_ASN1 HEIMDAL_GLUE HEIMDAL_HX509 HEIMDAL_HCRYPTO
# End SUBSYSTEM HEIMDAL_KRB5
#######################
@@ -380,8 +382,12 @@ HEIMDAL_HX509_OBJ_FILES = \
$(heimdalsrcdir)/lib/hx509/print.o \
$(heimdalsrcdir)/lib/hx509/req.o \
$(heimdalsrcdir)/lib/hx509/revoke.o \
+ $(heimdalsrcdir)/lib/hx509/sel.o \
+ $(heimdalsrcdir)/lib/hx509/sel-lex.o \
+ $(heimdalsrcdir)/lib/hx509/sel-gram.o \
$(heimdalsrcdir)/lib/hx509/hx509_err.o
+
#######################
# Start SUBSYSTEM HEIMDAL_WIND
[SUBSYSTEM::HEIMDAL_WIND]
@@ -426,7 +432,7 @@ $(HEIMDAL_ROKEN_GETPROGNAME_H_OBJ_FILES): CFLAGS+=-I$(heimdalbuildsrcdir) -I$(he
# Start SUBSYSTEM HEIMDAL_ROKEN
[SUBSYSTEM::HEIMDAL_ROKEN]
CFLAGS = -I$(heimdalbuildsrcdir) -I$(heimdalsrcdir)/lib/roken -I$(socketwrappersrcdir)
-PUBLIC_DEPENDENCIES = \
+PRIVATE_DEPENDENCIES = \
HEIMDAL_ROKEN_GETPROGNAME \
HEIMDAL_ROKEN_CLOSEFROM \
RESOLV \
@@ -463,13 +469,15 @@ HEIMDAL_ROKEN_OBJ_FILES = \
$(heimdalsrcdir)/lib/roken/simple_exec.o \
$(heimdalsrcdir)/lib/roken/strcollect.o \
$(heimdalsrcdir)/lib/roken/rtbl.o \
+ $(heimdalsrcdir)/lib/roken/cloexec.o \
+ $(heimdalsrcdir)/lib/roken/xfree.o \
$(heimdalbuildsrcdir)/replace.o
#######################
# Start SUBSYSTEM HEIMDAL_GLUE
[SUBSYSTEM::HEIMDAL_GLUE]
CFLAGS = -I$(heimdalbuildsrcdir) -I$(heimdalsrcdir)/lib/krb5 -I$(heimdalsrcdir)/lib/asn1 -I$(heimdalsrcdir)/lib/com_err
-PUBLIC_DEPENDENCIES = LIBNETIF LIBSAMBA-HOSTCONFIG
+PRIVATE_DEPENDENCIES = LIBNETIF LIBSAMBA-HOSTCONFIG
# End SUBSYSTEM HEIMDAL_GLUE
#######################
@@ -579,9 +587,6 @@ mkinclude perl_path_wrapper.sh asn1_deps.pl lib/hx509/ocsp.asn1 ocsp_asn1 \$\(he
mkinclude perl_path_wrapper.sh asn1_deps.pl lib/asn1/kx509.asn1 kx509_asn1 \$\(heimdalsrcdir\)/lib/asn1|
mkinclude perl_path_wrapper.sh asn1_deps.pl lib/hx509/pkcs10.asn1 pkcs10_asn1 \$\(heimdalsrcdir\)/lib/hx509 --preserve-binary=CertificationRequestInfo|
-#
-# Ensure to update ./static_deps.mk when you add a new entry here!
-#
mkinclude perl_path_wrapper.sh et_deps.pl lib/asn1/asn1_err.et \$\(heimdalsrcdir\)/lib/asn1|
mkinclude perl_path_wrapper.sh et_deps.pl lib/hdb/hdb_err.et \$\(heimdalsrcdir\)/lib/hdb|
mkinclude perl_path_wrapper.sh et_deps.pl lib/krb5/heim_err.et \$\(heimdalsrcdir\)/lib/krb5|
@@ -596,17 +601,6 @@ clean::
@-rm -f bin/compile_et bin/asn1_compile
#######################
-# Start SUBSYSTEM HEIMDAL
-[SUBSYSTEM::HEIMDAL]
-CFLAGS = -I$(heimdalbuildsrcdir)
-PUBLIC_DEPENDENCIES = \
- HEIMDAL_GSSAPI HEIMDAL_KRB5
-# End SUBSYSTEM HEIMDAL
-#######################
-
-HEIMDAL_OBJ_FILES = $(heimdalsrcdir)/lib/vers/print_version.o
-
-#######################
# Start BINARY compile_et
[BINARY::samba4kinit]
PRIVATE_DEPENDENCIES = HEIMDAL_KRB5 HEIMDAL_NTLM
@@ -621,4 +615,5 @@ samba4kinit_OBJ_FILES = $(heimdalsrcdir)/kuser/kinit.o \
$(samba4kinit_OBJ_FILES): CFLAGS+=-I$(heimdalbuildsrcdir) -I$(heimdalsrcdir)/lib/roken
dist:: $(heimdalsrcdir)/lib/asn1/lex.c $(heimdalsrcdir)/lib/com_err/lex.c \
- $(heimdalsrcdir)/lib/asn1/parse.c $(heimdalsrcdir)/lib/com_err/parse.c
+ $(heimdalsrcdir)/lib/asn1/parse.c $(heimdalsrcdir)/lib/com_err/parse.c \
+ $(heimdalsrcdir)/lib/hx509/sel-lex.c $(heimdalsrcdir)/lib/hx509/sel-gram.c
diff --git a/source4/heimdal_build/krb5/windc_plugin.h b/source4/heimdal_build/krb5/windc_plugin.h
new file mode 100644
index 0000000000..1df5fd3eb6
--- /dev/null
+++ b/source4/heimdal_build/krb5/windc_plugin.h
@@ -0,0 +1 @@
+#include "heimdal/kdc/windc_plugin.h"
diff --git a/source4/kdc/config.mk b/source4/kdc/config.mk
index b3b8b216f0..2c96e22cb3 100644
--- a/source4/kdc/config.mk
+++ b/source4/kdc/config.mk
@@ -6,7 +6,7 @@
INIT_FUNCTION = server_service_kdc_init
SUBSYSTEM = smbd
PRIVATE_DEPENDENCIES = \
- LIBLDB HEIMDAL HEIMDAL_KDC HEIMDAL_HDB SAMDB
+ HEIMDAL_KDC HDB_LDB
# End SUBSYSTEM KDC
#######################
@@ -17,8 +17,8 @@ KDC_OBJ_FILES = $(addprefix $(kdcsrcdir)/, kdc.o kpasswdd.o)
[SUBSYSTEM::HDB_LDB]
CFLAGS = -Iheimdal/kdc -Iheimdal/lib/hdb
PRIVATE_DEPENDENCIES = \
- LIBLDB auth_sam auth_sam_reply HEIMDAL CREDENTIALS \
- HEIMDAL_HDB_ASN1
+ LIBLDB auth_sam auth_sam_reply CREDENTIALS \
+ HEIMDAL_HDB
# End SUBSYSTEM KDC
#######################
diff --git a/source4/kdc/kdc.h b/source4/kdc/kdc.h
index 0943de4b00..7e82ad24c4 100644
--- a/source4/kdc/kdc.h
+++ b/source4/kdc/kdc.h
@@ -22,9 +22,9 @@
#include "system/kerberos.h"
#include "auth/kerberos/kerberos.h"
-#include "heimdal/kdc/kdc.h"
-#include "heimdal/lib/hdb/hdb.h"
-#include "heimdal/kdc/windc_plugin.h"
+#include <kdc.h>
+#include <hdb.h>
+#include <krb5/windc_plugin.h>
#include "kdc/pac_glue.h"
struct kdc_server;
diff --git a/source4/kdc/kpasswdd.c b/source4/kdc/kpasswdd.c
index b42769c6dc..55dadd9a7e 100644
--- a/source4/kdc/kpasswdd.c
+++ b/source4/kdc/kpasswdd.c
@@ -27,8 +27,6 @@
#include "system/network.h"
#include "lib/util/dlinklist.h"
#include "lib/ldb/include/ldb.h"
-#include "heimdal/lib/krb5/krb5_locl.h"
-#include "heimdal/lib/krb5/krb5-private.h"
#include "auth/gensec/gensec.h"
#include "auth/credentials/credentials.h"
#include "auth/credentials/credentials_krb5.h"
@@ -40,6 +38,10 @@
#include "param/param.h"
#include "kdc/kdc.h"
+/* TODO: remove this */
+#include "heimdal/lib/krb5/krb5_locl.h"
+#include "heimdal/lib/krb5/krb5-private.h"
+
/* hold information about one kdc socket */
struct kpasswd_socket {
struct socket_context *sock;
diff --git a/source4/libcli/smb2/connect.c b/source4/libcli/smb2/connect.c
index cdb5e3b5d4..c89c109b72 100644
--- a/source4/libcli/smb2/connect.c
+++ b/source4/libcli/smb2/connect.c
@@ -112,19 +112,19 @@ static void continue_negprot(struct smb2_request *req)
composite_error(c, NT_STATUS_ACCESS_DENIED);
return;
}
- transport->signing.doing_signing = false;
+ transport->signing_required = false;
break;
case SMB_SIGNING_SUPPORTED:
case SMB_SIGNING_AUTO:
if (transport->negotiate.security_mode & SMB2_NEGOTIATE_SIGNING_REQUIRED) {
- transport->signing.doing_signing = true;
+ transport->signing_required = true;
} else {
- transport->signing.doing_signing = false;
+ transport->signing_required = false;
}
break;
case SMB_SIGNING_REQUIRED:
if (transport->negotiate.security_mode & SMB2_NEGOTIATE_SIGNING_ENABLED) {
- transport->signing.doing_signing = true;
+ transport->signing_required = true;
} else {
composite_error(c, NT_STATUS_ACCESS_DENIED);
return;
diff --git a/source4/libcli/smb2/logoff.c b/source4/libcli/smb2/logoff.c
index b38a08ca43..e3f83f27d8 100644
--- a/source4/libcli/smb2/logoff.c
+++ b/source4/libcli/smb2/logoff.c
@@ -33,6 +33,8 @@ struct smb2_request *smb2_logoff_send(struct smb2_session *session)
req = smb2_request_init(session->transport, SMB2_OP_LOGOFF, 0x04, false, 0);
if (req == NULL) return NULL;
+ req->session = session;
+
SBVAL(req->out.hdr, SMB2_HDR_SESSION_ID, session->uid);
SSVAL(req->out.body, 0x02, 0);
diff --git a/source4/libcli/smb2/session.c b/source4/libcli/smb2/session.c
index 91616319d5..31b3e942e9 100644
--- a/source4/libcli/smb2/session.c
+++ b/source4/libcli/smb2/session.c
@@ -187,14 +187,14 @@ static void session_request_handler(struct smb2_request *req)
return;
}
- if (session->transport->signing.doing_signing) {
- if (session->session_key.length != 16) {
- DEBUG(2,("Wrong session key length %u for SMB2 signing\n",
+ if (session->transport->signing_required) {
+ if (session->session_key.length == 0) {
+ DEBUG(0,("Wrong session key length %u for SMB2 signing\n",
(unsigned)session->session_key.length));
composite_error(c, NT_STATUS_ACCESS_DENIED);
return;
}
- session->transport->signing.signing_started = true;
+ session->signing_active = true;
}
composite_done(c);
@@ -218,7 +218,7 @@ struct composite_context *smb2_session_setup_spnego_send(struct smb2_session *se
ZERO_STRUCT(state->io);
state->io.in.vc_number = 0;
- if (session->transport->signing.doing_signing) {
+ if (session->transport->signing_required) {
state->io.in.security_mode =
SMB2_NEGOTIATE_SIGNING_ENABLED | SMB2_NEGOTIATE_SIGNING_REQUIRED;
}
diff --git a/source4/libcli/smb2/signing.c b/source4/libcli/smb2/signing.c
index fb2c22db4e..0d655d1a86 100644
--- a/source4/libcli/smb2/signing.c
+++ b/source4/libcli/smb2/signing.c
@@ -46,7 +46,7 @@ NTSTATUS smb2_sign_message(struct smb2_request_buffer *buf, DATA_BLOB session_ke
return NT_STATUS_OK;
}
- if (session_key.length != 16) {
+ if (session_key.length == 0) {
DEBUG(2,("Wrong session key length %u for SMB2 signing\n",
(unsigned)session_key.length));
return NT_STATUS_ACCESS_DENIED;
@@ -57,10 +57,9 @@ NTSTATUS smb2_sign_message(struct smb2_request_buffer *buf, DATA_BLOB session_ke
SIVAL(buf->hdr, SMB2_HDR_FLAGS, IVAL(buf->hdr, SMB2_HDR_FLAGS) | SMB2_HDR_FLAG_SIGNED);
ZERO_STRUCT(m);
- hmac_sha256_init(session_key.data, 16, &m);
+ hmac_sha256_init(session_key.data, MIN(session_key.length, 16), &m);
hmac_sha256_update(buf->buffer+NBT_HDR_SIZE, buf->size-NBT_HDR_SIZE, &m);
hmac_sha256_final(res, &m);
-
DEBUG(5,("signed SMB2 message of size %u\n", (unsigned)buf->size - NBT_HDR_SIZE));
memcpy(buf->hdr + SMB2_HDR_SIGNATURE, res, 16);
@@ -95,7 +94,7 @@ NTSTATUS smb2_check_signature(struct smb2_request_buffer *buf, DATA_BLOB session
return NT_STATUS_OK;
}
- if (session_key.length != 16) {
+ if (session_key.length == 0) {
DEBUG(2,("Wrong session key length %u for SMB2 signing\n",
(unsigned)session_key.length));
return NT_STATUS_ACCESS_DENIED;
@@ -106,7 +105,7 @@ NTSTATUS smb2_check_signature(struct smb2_request_buffer *buf, DATA_BLOB session
memset(buf->hdr + SMB2_HDR_SIGNATURE, 0, 16);
ZERO_STRUCT(m);
- hmac_sha256_init(session_key.data, 16, &m);
+ hmac_sha256_init(session_key.data, MIN(session_key.length, 16), &m);
hmac_sha256_update(buf->hdr, buf->size-NBT_HDR_SIZE, &m);
hmac_sha256_final(res, &m);
diff --git a/source4/libcli/smb2/smb2.h b/source4/libcli/smb2/smb2.h
index 2b468d3dc9..5d6341a15b 100644
--- a/source4/libcli/smb2/smb2.h
+++ b/source4/libcli/smb2/smb2.h
@@ -27,11 +27,6 @@
struct smb2_handle;
-struct smb2_signing_context {
- bool doing_signing;
- bool signing_started;
-};
-
/*
information returned from the negotiate process
*/
@@ -78,7 +73,8 @@ struct smb2_transport {
} oplock;
struct smbcli_options options;
- struct smb2_signing_context signing;
+
+ bool signing_required;
};
@@ -98,6 +94,7 @@ struct smb2_session {
struct gensec_security *gensec;
uint64_t uid;
DATA_BLOB session_key;
+ bool signing_active;
};
diff --git a/source4/libcli/smb2/transport.c b/source4/libcli/smb2/transport.c
index 6e0d523e21..d9691bec7c 100644
--- a/source4/libcli/smb2/transport.c
+++ b/source4/libcli/smb2/transport.c
@@ -235,7 +235,7 @@ static NTSTATUS smb2_transport_finish_recv(void *private, DATA_BLOB blob)
req->in.body_size = req->in.size - (SMB2_HDR_BODY+NBT_HDR_SIZE);
req->status = NT_STATUS(IVAL(hdr, SMB2_HDR_STATUS));
- if (req->session && transport->signing.doing_signing) {
+ if (req->session && req->session->signing_active) {
status = smb2_check_signature(&req->in,
req->session->session_key);
if (!NT_STATUS_IS_OK(status)) {
@@ -352,9 +352,7 @@ void smb2_transport_send(struct smb2_request *req)
}
/* possibly sign the message */
- if (req->transport->signing.doing_signing &&
- req->transport->signing.signing_started &&
- req->session) {
+ if (req->session && req->session->signing_active) {
status = smb2_sign_message(&req->out, req->session->session_key);
if (!NT_STATUS_IS_OK(status)) {
req->state = SMB2_REQUEST_ERROR;
diff --git a/source4/librpc/idl/drsblobs.idl b/source4/librpc/idl/drsblobs.idl
index adfc010237..b0cddfcdf9 100644
--- a/source4/librpc/idl/drsblobs.idl
+++ b/source4/librpc/idl/drsblobs.idl
@@ -1,6 +1,6 @@
#include "idl_types.h"
-import "drsuapi.idl", "misc.idl";
+import "drsuapi.idl", "misc.idl", "samr.idl";
[
uuid("12345778-1234-abcd-0001-00000001"),
@@ -359,9 +359,55 @@ interface drsblobs {
typedef struct {
NTTIME time1;
uint32 unknown1;
+ DATA_BLOB value;
+ [flag(NDR_ALIGN4)] DATA_BLOB _pad;
+ } trustAuthInOutSecret1;
+
+ typedef struct {
+ [relative] trustAuthInOutSecret1 *value1;
+ [relative] trustAuthInOutSecret1 *value2;
+ } trustAuthInOutCtr1;
+
+ typedef [v1_enum] enum {
+ TRUST_AUTH_TYPE_NONE = 0,
+ TRUST_AUTH_TYPE_NT4OWF = 1,
+ TRUST_AUTH_TYPE_CLEAR = 2,
+ TRUST_AUTH_TYPE_VERSION = 3
+ } trustAuthType;
+
+ typedef struct {
+ [value(0)] uint32 size;
+ } AuthInfoNone;
+
+ typedef struct {
+ [value(16)] uint32 size;
+ samr_Password password;
+ } AuthInfoNT4Owf;
+
+ typedef struct {
+ uint32 size;
+ uint8 password[size];
+ } AuthInfoClear;
+
+ typedef struct {
+ [value(4)] uint32 size;
+ uint32 version;
+ } AuthInfoVersion;
+
+ typedef [nodiscriminant] union {
+ [case(TRUST_AUTH_TYPE_NONE)] AuthInfoNone none;
+ [case(TRUST_AUTH_TYPE_NT4OWF)] AuthInfoNT4Owf nt4owf;
+ [case(TRUST_AUTH_TYPE_CLEAR)] AuthInfoClear clear;
+ [case(TRUST_AUTH_TYPE_VERSION)] AuthInfoVersion version;
+ } AuthInfo;
+
+ typedef struct {
+ NTTIME LastUpdateTime;
+ trustAuthType AuthType;
+
/*
* the secret value is encoded as UTF16 if it's a string
- * but krb5 trusts have random bytes here, so converting to UTF16
+ * but depending the AuthType, it might also be krb5 trusts have random bytes here, so converting to UTF16
* mayfail...
*
* TODO: We should try handle the case of a random buffer in all places
@@ -372,49 +418,36 @@ interface drsblobs {
* uint32 value_len;
* [charset(UTF16)] uint8 value[value_len];
*/
- DATA_BLOB value;
+ [switch_is(AuthType)] AuthInfo AuthInfo;
[flag(NDR_ALIGN4)] DATA_BLOB _pad;
- } trustAuthInOutSecret1;
+ } AuthenticationInformation;
typedef struct {
- [relative] trustAuthInOutSecret1 *value1;
- [relative] trustAuthInOutSecret1 *value2;
- } trustAuthInOutCtr1;
+ AuthenticationInformation info[1];
+ } AuthenticationInformation1;
typedef struct {
- NTTIME time1;
- uint32 unknown1;
- DATA_BLOB value;
- NTTIME time2;
- uint32 unknown2;
- uint32 unknown3;
- uint32 unknown4;
- [flag(NDR_ALIGN4)] DATA_BLOB _pad;
- } trustAuthInOutSecret2V1;
+ AuthenticationInformation info[2];
+ } AuthenticationInformation2;
typedef struct {
- NTTIME time1;
- uint32 unknown1;
- DATA_BLOB value;
- NTTIME time2;
- uint32 unknown2;
- uint32 unknown3;
- [flag(NDR_ALIGN4)] DATA_BLOB _pad;
- } trustAuthInOutSecret2V2;
+ [relative] AuthenticationInformation1 *current;
+ [relative] AuthenticationInformation1 *previous;
+ } AuthenticationInformationCtr1;
typedef struct {
- [relative] trustAuthInOutSecret2V1 *value1;
- [relative] trustAuthInOutSecret2V2 *value2;
- } trustAuthInOutCtr2;
+ [relative] AuthenticationInformation2 *current;
+ [relative] AuthenticationInformation2 *previous;
+ } AuthenticationInformationCtr2;
typedef [nodiscriminant] union {
- [case(1)] trustAuthInOutCtr1 ctr1;
- [case(2)] trustAuthInOutCtr2 ctr2;
- } trustAuthInOutCtr;
+ [case(1)] AuthenticationInformationCtr1 info1;
+ [case(2)] AuthenticationInformationCtr2 info2;
+ } AuthenticationInformationCtr;
typedef [public] struct {
- uint32 version;
- [switch_is(version)] trustAuthInOutCtr ctr;
+ uint32 count;
+ [switch_is(count)] AuthenticationInformationCtr auth;
} trustAuthInOutBlob;
void decode_trustAuthInOut(
diff --git a/source4/main.mk b/source4/main.mk
index f0ce9685f9..28db54c10f 100644
--- a/source4/main.mk
+++ b/source4/main.mk
@@ -1,5 +1,4 @@
mkinclude dynconfig/config.mk
-mkinclude heimdal_build/internal.mk
mkinclude config.mk
mkinclude dsdb/config.mk
mkinclude smbd/config.mk
diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c
index cb07f6e8ce..95589498e2 100644
--- a/source4/rpc_server/dcerpc_server.c
+++ b/source4/rpc_server/dcerpc_server.c
@@ -947,7 +947,6 @@ _PUBLIC_ NTSTATUS dcesrv_reply(struct dcesrv_call_state *call)
uint32_t length;
struct data_blob_list_item *rep;
struct ncacn_packet pkt;
- const uint32_t overhead = (DCERPC_MAX_SIGN_SIZE+DCERPC_RESPONSE_LENGTH);
rep = talloc(call, struct data_blob_list_item);
NT_STATUS_HAVE_NO_MEMORY(rep);
diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py
index 33aeff2008..6b1fd33b9f 100644
--- a/source4/scripting/python/samba/provision.py
+++ b/source4/scripting/python/samba/provision.py
@@ -133,26 +133,6 @@ findnss_uid = lambda names: findnss(pwd.getpwnam, names)[2]
findnss_gid = lambda names: findnss(grp.getgrnam, names)[2]
-def open_ldb(session_info, credentials, lp, dbname):
- """Open a LDB, thrashing it if it is corrupt.
-
- :param session_info: auth session information
- :param credentials: credentials
- :param lp: Loadparm context
- :param dbname: Path of the database to open.
- :return: a Ldb object
- """
- assert session_info is not None
- try:
- return Ldb(dbname, session_info=session_info, credentials=credentials,
- lp=lp)
- except LdbError, e:
- print e
- os.unlink(dbname)
- return Ldb(dbname, session_info=session_info, credentials=credentials,
- lp=lp)
-
-
def read_and_sub_file(file, subst_vars):
"""Read a file and sub in variables found in it
@@ -799,7 +779,6 @@ def setup_samdb(path, setup_path, session_info, credentials, lp,
setup_add_ldif(samdb, setup_path("provision_configuration_basedn.ldif"), {
"CONFIGDN": names.configdn,
"ACI": aci,
- "EXTENSIBLEOBJECT": "# no objectClass: extensibleObject for local ldb",
})
message("Modifying configuration container")
setup_modify_ldif(samdb, setup_path("provision_configuration_basedn_modify.ldif"), {
@@ -811,7 +790,6 @@ def setup_samdb(path, setup_path, session_info, credentials, lp,
setup_add_ldif(samdb, setup_path("provision_schema_basedn.ldif"), {
"SCHEMADN": names.schemadn,
"ACI": aci,
- "EXTENSIBLEOBJECT": "# no objectClass: extensibleObject for local ldb"
})
message("Modifying schema container")
@@ -1195,7 +1173,7 @@ def provision_backend(setup_dir=None, message=None,
paths = provision_paths_from_lp(lp, names.dnsdomain)
if not os.path.isdir(paths.ldapdir):
- os.makedirs(paths.ldapdir)
+ os.makedirs(paths.ldapdir, 0700)
schemadb_path = os.path.join(paths.ldapdir, "schema-tmp.ldb")
try:
os.unlink(schemadb_path)
@@ -1209,7 +1187,6 @@ def provision_backend(setup_dir=None, message=None,
setup_add_ldif(schemadb, setup_path("provision_schema_basedn.ldif"),
{"SCHEMADN": names.schemadn,
"ACI": "#",
- "EXTENSIBLEOBJECT": "# no objectClass: extensibleObject for local ldb"
})
setup_modify_ldif(schemadb,
setup_path("provision_schema_basedn_modify.ldif"), \
@@ -1252,6 +1229,8 @@ def provision_backend(setup_dir=None, message=None,
slapdcommand="Initailise Fedora DS with: setup-ds.pl --file=%s" % paths.fedoradsinf
+ ldapuser = "--simple-bind-dn=" + names.ldapmanagerdn
+
elif ldap_backend_type == "openldap":
attrs = ["linkID", "lDAPDisplayName"]
res = schemadb.search(expression="(&(&(linkID=*)(!(linkID:1.2.840.113556.1.4.803:=1)))(objectclass=attributeSchema))", base=names.schemadn, scope=SCOPE_SUBTREE, attrs=attrs)
@@ -1290,7 +1269,7 @@ def provision_backend(setup_dir=None, message=None,
setup_db_config(setup_path, os.path.join(paths.ldapdir, "db", "schema"))
if not os.path.exists(os.path.join(paths.ldapdir, "db", "samba", "cn=samba")):
- os.makedirs(os.path.join(paths.ldapdir, "db", "samba", "cn=samba"))
+ os.makedirs(os.path.join(paths.ldapdir, "db", "samba", "cn=samba"), 0700)
setup_file(setup_path("cn=samba.ldif"),
os.path.join(paths.ldapdir, "db", "samba", "cn=samba.ldif"),
@@ -1310,7 +1289,10 @@ def provision_backend(setup_dir=None, message=None,
server_port_string = " -h ldap://0.0.0.0:%d" % ldap_backend_port
else:
server_port_string = ""
- slapdcommand="Start slapd with: slapd -f " + paths.ldapdir + "/slapd.conf -h " + ldapi_uri + server_port_string
+
+ slapdcommand="Start slapd with: slapd -f " + paths.ldapdir + "/slapd.conf -h " + ldapi_uri + server_port_string
+
+ ldapuser = "--username=samba-admin"
schema_command = "bin/ad2oLschema --option=convert:target=" + ldap_backend_type + " -I " + setup_path(mapping) + " -H tdb://" + schemadb_path + " -O " + os.path.join(paths.ldapdir, backend_schema)
@@ -1330,7 +1312,7 @@ def provision_backend(setup_dir=None, message=None,
message("LDAP admin password: %s" % adminpass)
message(slapdcommand)
-
+ message("Run provision with: --ldap-backend=ldapi --ldap-backend-type=" + ldap_backend_type + " --password=" + adminpass + " " + ldapuser)
def create_phpldapadmin_config(path, setup_path, ldapi_uri):
"""Create a PHP LDAP admin configuration file.
diff --git a/source4/smb_server/smb2/negprot.c b/source4/smb_server/smb2/negprot.c
index 3e6e2e1a43..d64b36d659 100644
--- a/source4/smb_server/smb2/negprot.c
+++ b/source4/smb_server/smb2/negprot.c
@@ -122,7 +122,7 @@ static NTSTATUS smb2srv_negprot_backend(struct smb2srv_request *req, struct smb2
case SMB_SIGNING_REQUIRED:
io->out.security_mode = SMB2_NEGOTIATE_SIGNING_ENABLED | SMB2_NEGOTIATE_SIGNING_REQUIRED;
/* force signing on immediately */
- req->smb_conn->doing_signing = true;
+ req->smb_conn->smb2_signing_required = true;
break;
}
io->out.dialect_revision = SMB2_DIALECT_REVISION;
diff --git a/source4/smb_server/smb2/receive.c b/source4/smb_server/smb2/receive.c
index 2f4e9df2b6..cfd6c1d01a 100644
--- a/source4/smb_server/smb2/receive.c
+++ b/source4/smb_server/smb2/receive.c
@@ -235,11 +235,8 @@ void smb2srv_send_reply(struct smb2srv_request *req)
_smb2_setlen(req->out.buffer, req->out.size - NBT_HDR_SIZE);
}
- /* if the request was signed or doing_signing is true, then we
- must sign the reply */
- if (req->session &&
- (req->smb_conn->doing_signing ||
- (IVAL(req->in.hdr, SMB2_HDR_FLAGS) & SMB2_HDR_FLAG_SIGNED))) {
+ /* if signing is active on the session then sign the packet */
+ if (req->session && req->session->smb2_signing.active) {
status = smb2_sign_message(&req->out,
req->session->session_info->session_key);
if (!NT_STATUS_IS_OK(status)) {
@@ -310,18 +307,22 @@ static NTSTATUS smb2srv_reply(struct smb2srv_request *req)
should give a signed reply to any signed request */
if (flags & SMB2_HDR_FLAG_SIGNED) {
NTSTATUS status;
- if (req->session == NULL) {
- /* we can't check signing with no session */
- smb2srv_send_error(req, NT_STATUS_ACCESS_DENIED);
- return NT_STATUS_OK;
+
+ if (!req->session) goto nosession;
+
+ if (!req->session->smb2_signing.active) {
+ /* TODO: workout the correct error code */
+ smb2srv_send_error(req, NT_STATUS_FOOBAR);
+ return NT_STATUS_OK;
}
+
status = smb2_check_signature(&req->in,
req->session->session_info->session_key);
if (!NT_STATUS_IS_OK(status)) {
smb2srv_send_error(req, status);
return NT_STATUS_OK;
}
- } else if (req->smb_conn->doing_signing && req->session != NULL) {
+ } else if (req->session && req->session->smb2_signing.active) {
/* we require signing and this request was not signed */
smb2srv_send_error(req, NT_STATUS_ACCESS_DENIED);
return NT_STATUS_OK;
diff --git a/source4/smb_server/smb2/sesssetup.c b/source4/smb_server/smb2/sesssetup.c
index 9fb3220005..9f8765d6e9 100644
--- a/source4/smb_server/smb2/sesssetup.c
+++ b/source4/smb_server/smb2/sesssetup.c
@@ -90,6 +90,10 @@ static void smb2srv_sesssetup_callback(struct gensec_update_request *greq, void
}
req->session = smb_sess;
+ if (smb_sess->smb2_signing.required) {
+ /* activate smb2 signing on the session */
+ smb_sess->smb2_signing.active = true;
+ }
done:
io->smb2.out.uid = smb_sess->vuid;
failed:
@@ -182,7 +186,15 @@ static void smb2srv_sesssetup_backend(struct smb2srv_request *req, union smb_ses
This is deliberate as windows does not set it even when it does
set SMB2_NEGOTIATE_SIGNING_REQUIRED */
if (io->smb2.in.security_mode & SMB2_NEGOTIATE_SIGNING_REQUIRED) {
- req->smb_conn->doing_signing = true;
+ smb_sess->smb2_signing.required = true;
+ } else if (req->smb_conn->smb2_signing_required) {
+ /*
+ * if required signing was negotiates in SMB2 Negotiate
+ * then the client made an error not using it here
+ */
+ DEBUG(1, ("SMB2 signing required on the connection but not used on session\n"));
+ req->status = NT_STATUS_FOOBAR;
+ goto failed;
}
return;
@@ -212,11 +224,25 @@ void smb2srv_sesssetup_recv(struct smb2srv_request *req)
smb2srv_sesssetup_backend(req, io);
}
-static NTSTATUS smb2srv_logoff_backend(struct smb2srv_request *req)
+static int smb2srv_cleanup_session_destructor(struct smbsrv_session **session)
{
/* TODO: call ntvfs backends to close file of this session */
- talloc_free(req->session);
- req->session = NULL;
+ DEBUG(0,("free session[%p]\n", *session));
+ talloc_free(*session);
+ return 0;
+}
+
+static NTSTATUS smb2srv_logoff_backend(struct smb2srv_request *req)
+{
+ struct smbsrv_session **session_ptr;
+
+ /* we need to destroy the session after sending the reply */
+ session_ptr = talloc(req, struct smbsrv_session *);
+ NT_STATUS_HAVE_NO_MEMORY(session_ptr);
+
+ *session_ptr = req->session;
+ talloc_set_destructor(session_ptr, smb2srv_cleanup_session_destructor);
+
return NT_STATUS_OK;
}
diff --git a/source4/smb_server/smb_server.h b/source4/smb_server/smb_server.h
index dd4ec3281b..4676fc3e9c 100644
--- a/source4/smb_server/smb_server.h
+++ b/source4/smb_server/smb_server.h
@@ -100,6 +100,11 @@ struct smbsrv_session {
struct auth_session_info *session_info;
+ struct {
+ bool required;
+ bool active;
+ } smb2_signing;
+
/* some statistics for the management tools */
struct {
/* the time when the session setup started */
@@ -380,7 +385,7 @@ struct smbsrv_connection {
struct loadparm_context *lp_ctx;
- bool doing_signing;
+ bool smb2_signing_required;
};
struct model_ops;
diff --git a/source4/static_deps.mk b/source4/static_deps.mk
index 085eae938d..2768ea8ab5 100644
--- a/source4/static_deps.mk
+++ b/source4/static_deps.mk
@@ -13,30 +13,5 @@ include/includes.h: \
$(libcharsetsrcdir)/charset.h \
$(gen_ndrsrcdir)/misc.h
-heimdal_basics: \
- $(heimdalsrcdir)/lib/hdb/hdb_asn1.h \
- $(heimdalsrcdir)/lib/gssapi/spnego_asn1.h \
- $(heimdalsrcdir)/lib/gssapi/gssapi_asn1.h \
- $(heimdalsrcdir)/lib/asn1/krb5_asn1.h \
- $(heimdalsrcdir)/lib/asn1/asn1_err.h \
- $(heimdalsrcdir)/lib/asn1/digest_asn1.h \
- $(heimdalsrcdir)/lib/asn1/pkcs8_asn1.h \
- $(heimdalsrcdir)/lib/asn1/pkcs9_asn1.h \
- $(heimdalsrcdir)/lib/asn1/pkcs12_asn1.h \
- $(heimdalsrcdir)/lib/asn1/cms_asn1.h \
- $(heimdalsrcdir)/lib/asn1/rfc2459_asn1.h \
- $(heimdalsrcdir)/lib/asn1/pkinit_asn1.h \
- $(heimdalsrcdir)/lib/asn1/kx509_asn1.h \
- $(heimdalsrcdir)/lib/hx509/ocsp_asn1.h \
- $(heimdalsrcdir)/lib/hx509/pkcs10_asn1.h \
- $(heimdalsrcdir)/lib/hdb/hdb_err.h \
- $(heimdalsrcdir)/lib/krb5/heim_err.h \
- $(heimdalsrcdir)/lib/krb5/k524_err.h \
- $(heimdalsrcdir)/lib/krb5/krb_err.h \
- $(heimdalsrcdir)/lib/krb5/krb5_err.h \
- $(heimdalsrcdir)/lib/gssapi/gkrb5_err.h \
- $(heimdalsrcdir)/lib/hx509/hx509_err.h \
- $(heimdalsrcdir)/lib/wind/wind_err.h
-
proto::
-basics:: include/includes.h idl proto heimdal_basics
+basics:: include/includes.h idl proto
diff --git a/source4/torture/rpc/dssync.c b/source4/torture/rpc/dssync.c
index 2930a9b1f9..d340543f0a 100644
--- a/source4/torture/rpc/dssync.c
+++ b/source4/torture/rpc/dssync.c
@@ -34,6 +34,7 @@
#include "libcli/auth/libcli_auth.h"
#include "auth/gensec/gensec.h"
#include "param/param.h"
+#include "dsdb/samdb/samdb.h"
struct DsSyncBindInfo {
struct dcerpc_pipe *pipe;
@@ -314,6 +315,14 @@ static bool test_GetInfo(struct torture_context *tctx, struct DsSyncTest *ctx)
printf("cldap_netlogon() returned Server Site-Name: %s.\n",search.out.netlogon.nt5_ex.server_site);
}
+ if (!ctx->domain_dn) {
+ struct ldb_context *ldb = ldb_init(ctx, tctx->ev);
+ struct ldb_dn *dn = samdb_dns_domain_to_dn(ldb, ctx, search.out.netlogon.nt5_ex.dns_domain);
+ ctx->domain_dn = ldb_dn_alloc_linearized(ctx, dn);
+ talloc_free(dn);
+ talloc_free(ldb);
+ }
+
return ret;
}
@@ -465,6 +474,9 @@ static void test_analyse_objects(struct torture_context *tctx,
DATA_BLOB *enc_data = NULL;
DATA_BLOB plain_data;
struct drsuapi_DsReplicaAttribute *attr;
+ ndr_pull_flags_fn_t pull_fn = NULL;
+ ndr_print_fn_t print_fn = NULL;
+ void *ptr = NULL;
attr = &cur->object.attribute_ctr.attributes[i];
switch (attr->attid) {
@@ -486,6 +498,9 @@ static void test_analyse_objects(struct torture_context *tctx,
break;
case DRSUAPI_ATTRIBUTE_supplementalCredentials:
name = "supplementalCredentials";
+ pull_fn = (ndr_pull_flags_fn_t)ndr_pull_supplementalCredentialsBlob;
+ print_fn = (ndr_print_fn_t)ndr_print_supplementalCredentialsBlob;
+ ptr = talloc(ctx, struct supplementalCredentialsBlob);
break;
case DRSUAPI_ATTRIBUTE_priorValue:
name = "priorValue";
@@ -495,9 +510,15 @@ static void test_analyse_objects(struct torture_context *tctx,
break;
case DRSUAPI_ATTRIBUTE_trustAuthOutgoing:
name = "trustAuthOutgoing";
+ pull_fn = (ndr_pull_flags_fn_t)ndr_pull_trustAuthInOutBlob;
+ print_fn = (ndr_print_fn_t)ndr_print_trustAuthInOutBlob;
+ ptr = talloc(ctx, struct trustAuthInOutBlob);
break;
case DRSUAPI_ATTRIBUTE_trustAuthIncoming:
name = "trustAuthIncoming";
+ pull_fn = (ndr_pull_flags_fn_t)ndr_pull_trustAuthInOutBlob;
+ print_fn = (ndr_print_fn_t)ndr_print_trustAuthInOutBlob;
+ ptr = talloc(ctx, struct trustAuthInOutBlob);
break;
case DRSUAPI_ATTRIBUTE_initialAuthOutgoing:
name = "initialAuthOutgoing";
@@ -528,7 +549,6 @@ static void test_analyse_objects(struct torture_context *tctx,
name, (long)enc_data->length, (long)plain_data.length));
if (plain_data.length) {
enum ndr_err_code ndr_err;
- struct supplementalCredentialsBlob scb;
dump_data(0, plain_data.data, plain_data.length);
if (save_values_dir) {
char *fname;
@@ -545,15 +565,20 @@ static void test_analyse_objects(struct torture_context *tctx,
talloc_free(fname);
}
- ndr_err = ndr_pull_struct_blob_all(&plain_data, tctx,
- lp_iconv_convenience(tctx->lp_ctx), &scb,
- (ndr_pull_flags_fn_t)ndr_pull_supplementalCredentialsBlob);
- if (NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
- NDR_PRINT_DEBUG(supplementalCredentialsBlob, &scb);
+ if (pull_fn) {
+ ndr_err = ndr_pull_struct_blob_all(&plain_data, ptr,
+ lp_iconv_convenience(tctx->lp_ctx), ptr,
+ pull_fn);
+ if (NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ ndr_print_debug(print_fn, name, ptr);
+ } else {
+ DEBUG(0, ("Failed to decode %s\n", name));
+ }
}
} else {
dump_data(0, enc_data->data, enc_data->length);
}
+ talloc_free(ptr);
}
}
}
@@ -800,7 +825,10 @@ static bool test_FetchNT4Data(struct torture_context *tctx,
r.in.req.req1.data = cookie.data;
status = dcerpc_drsuapi_DsGetNT4ChangeLog(ctx->new_dc.drsuapi.pipe, ctx, &r);
- if (!NT_STATUS_IS_OK(status)) {
+ if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
+ printf("DsGetNT4ChangeLog not supported by target server\n");
+ break;
+ } else if (!NT_STATUS_IS_OK(status)) {
const char *errstr = nt_errstr(status);
if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
errstr = dcerpc_errstr(ctx, ctx->new_dc.drsuapi.pipe->last_fault_code);
diff --git a/source4/torture/rpc/lsa.c b/source4/torture/rpc/lsa.c
index e6102f0a82..4fb459ea25 100644
--- a/source4/torture/rpc/lsa.c
+++ b/source4/torture/rpc/lsa.c
@@ -1830,7 +1830,12 @@ static bool test_EnumTrustDom(struct dcerpc_pipe *p,
enum_status = dcerpc_lsa_EnumTrustDom(p, mem_ctx, &r);
- if (!(NT_STATUS_EQUAL(enum_status, STATUS_MORE_ENTRIES) || NT_STATUS_EQUAL(enum_status, NT_STATUS_NO_MORE_ENTRIES))) {
+ if (NT_STATUS_IS_OK(enum_status)) {
+ if (domains.count == 0) {
+ printf("EnumTrustDom failed - should have returned 'NT_STATUS_NO_MORE_ENTRIES' for 0 trusted domains\n");
+ return false;
+ }
+ } else if (!(NT_STATUS_EQUAL(enum_status, STATUS_MORE_ENTRIES) || NT_STATUS_EQUAL(enum_status, NT_STATUS_NO_MORE_ENTRIES))) {
printf("EnumTrustDom of zero size failed - %s\n", nt_errstr(enum_status));
return false;
}
diff --git a/source4/torture/smb2/connect.c b/source4/torture/smb2/connect.c
index 826bb2d719..e77e32ff7a 100644
--- a/source4/torture/smb2/connect.c
+++ b/source4/torture/smb2/connect.c
@@ -193,6 +193,7 @@ bool torture_smb2_connect(struct torture_context *torture)
{
TALLOC_CTX *mem_ctx = talloc_new(NULL);
struct smb2_tree *tree;
+ struct smb2_request *req;
struct smb2_handle h1, h2;
NTSTATUS status;
@@ -242,7 +243,15 @@ bool torture_smb2_connect(struct torture_context *torture)
return false;
}
- status = smb2_logoff(tree->session);
+ req = smb2_logoff_send(tree->session);
+ if (!req) {
+ printf("smb2_logoff_send() failed\n");
+ return false;
+ }
+
+ req->session = NULL;
+
+ status = smb2_logoff_recv(req);
if (!NT_STATUS_EQUAL(status, NT_STATUS_USER_SESSION_DELETED)) {
printf("Logoff should have disabled session - %s\n", nt_errstr(status));
return false;