aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.in6
-rw-r--r--src/aclocal.m441
-rwxr-xr-xsrc/appl/gss-sample/t_gss_sample.py18
-rw-r--r--src/appl/simple/client/sim_client.c2
-rw-r--r--src/appl/simple/server/sim_server.c3
-rwxr-xr-xsrc/appl/user_user/t_user2user.py6
-rw-r--r--src/ccapi/server/mac/ccs_os_pipe.c4
-rw-r--r--src/clients/kcpytkt/kcpytkt.c48
-rw-r--r--src/clients/kdeltkt/kdeltkt.c37
-rw-r--r--src/clients/kdestroy/kdestroy.c95
-rw-r--r--src/clients/kinit/kinit.c490
-rw-r--r--src/clients/kinit/kinit_kdb.c34
-rw-r--r--src/clients/klist/klist.c462
-rw-r--r--src/clients/kpasswd/Makefile.in10
-rw-r--r--src/clients/kpasswd/deps4
-rw-r--r--src/clients/kpasswd/kpasswd.c110
-rw-r--r--src/clients/kpasswd/ksetpwd.c309
-rw-r--r--src/clients/ksu/ccache.c22
-rw-r--r--src/clients/ksu/ksu.h2
-rw-r--r--src/clients/ksu/main.c2
-rw-r--r--src/clients/kvno/kvno.c299
-rw-r--r--src/config/ac-archive/README52
-rw-r--r--src/config/ac-archive/acx_pthread.m4239
-rw-r--r--src/config/ac-archive/ax_pthread.m4485
-rw-r--r--src/config/ac-archive/ax_recursive_eval.m456
-rw-r--r--src/config/ac-archive/relpaths.m4155
-rwxr-xr-xsrc/config/config.guess119
-rwxr-xr-xsrc/config/config.sub73
-rw-r--r--src/config/post.in4
-rw-r--r--src/config/pre.in13
-rwxr-xr-xsrc/configure1198
-rw-r--r--src/configure.in97
-rw-r--r--src/include/Makefile.in3
-rw-r--r--src/include/autoconf.h.in35
-rw-r--r--src/include/fake-addrinfo.h2
-rw-r--r--src/include/k5-cmocka.h16
-rw-r--r--src/include/k5-input.h6
-rw-r--r--src/include/k5-int.h51
-rw-r--r--src/include/k5-platform.h32
-rw-r--r--src/include/k5-thread.h16
-rw-r--r--src/include/k5-trace.h47
-rw-r--r--src/include/k5-utf8.h61
-rw-r--r--src/include/kdb.h8
-rw-r--r--src/include/kdb_log.h5
-rw-r--r--src/include/krb5/certauth_plugin.h128
-rw-r--r--src/include/krb5/kadm5_auth_plugin.h306
-rw-r--r--src/include/krb5/kdcpolicy_plugin.h128
-rw-r--r--src/include/krb5/kdcpreauth_plugin.h21
-rw-r--r--src/include/krb5/krb5.hin54
-rw-r--r--src/include/net-server.h2
-rw-r--r--src/include/socket-utils.h11
-rw-r--r--src/include/win-mac.h2
-rw-r--r--src/kadmin/cli/deps13
-rw-r--r--src/kadmin/cli/getdate.y7
-rw-r--r--src/kadmin/cli/kadmin.c5
-rw-r--r--src/kadmin/dbutil/dump.c41
-rw-r--r--src/kadmin/dbutil/kdb5_mkey.c6
-rw-r--r--src/kadmin/dbutil/tabdump.c2
-rw-r--r--src/kadmin/ktutil/ktutil.c17
-rw-r--r--src/kadmin/ktutil/ktutil.h3
-rw-r--r--src/kadmin/ktutil/ktutil_funcs.c17
-rw-r--r--src/kadmin/server/Makefile.in6
-rw-r--r--src/kadmin/server/auth.c314
-rw-r--r--src/kadmin/server/auth.h85
-rw-r--r--src/kadmin/server/auth_acl.c755
-rw-r--r--src/kadmin/server/auth_self.c77
-rw-r--r--src/kadmin/server/deps109
-rw-r--r--src/kadmin/server/ipropd_svc.c38
-rw-r--r--src/kadmin/server/misc.c127
-rw-r--r--src/kadmin/server/misc.h17
-rw-r--r--src/kadmin/server/ovsec_kadmd.c8
-rw-r--r--src/kadmin/server/schpw.c49
-rw-r--r--src/kadmin/server/server_stubs.c340
-rw-r--r--src/kadmin/testing/util/tcl_kadm5.c12
-rw-r--r--src/kdc/deps40
-rw-r--r--src/kdc/dispatch.c19
-rw-r--r--src/kdc/do_as_req.c90
-rw-r--r--src/kdc/do_tgs_req.c70
-rw-r--r--src/kdc/extern.c4
-rw-r--r--src/kdc/fast_util.c4
-rw-r--r--src/kdc/kdc_log.c29
-rw-r--r--src/kdc/kdc_preauth.c35
-rw-r--r--src/kdc/kdc_preauth_ec.c41
-rw-r--r--src/kdc/kdc_preauth_encts.c9
-rw-r--r--src/kdc/kdc_util.c57
-rw-r--r--src/kdc/kdc_util.h21
-rw-r--r--src/kdc/main.c8
-rw-r--r--src/kdc/policy.c267
-rw-r--r--src/kdc/policy.h19
-rw-r--r--src/kdc/replay.c2
-rwxr-xr-xsrc/kdc/t_emptytgt.py5
-rw-r--r--src/kdc/t_replay.c13
-rw-r--r--src/kdc/tgs_policy.c13
-rw-r--r--src/lib/apputils/net-server.c254
-rw-r--r--src/lib/apputils/udppktinfo.c14
-rw-r--r--src/lib/apputils/udppktinfo.h2
-rw-r--r--src/lib/crypto/builtin/des/des_int.h2
-rw-r--r--src/lib/crypto/builtin/des/destest.c3
-rw-r--r--src/lib/crypto/builtin/enc_provider/rc4.c2
-rw-r--r--src/lib/crypto/builtin/sha2/sha256.c4
-rw-r--r--src/lib/crypto/builtin/sha2/sha512.c4
-rw-r--r--src/lib/crypto/krb/Makefile.in2
-rw-r--r--src/lib/crypto/krb/crypto_int.h1
-rw-r--r--src/lib/crypto/krb/enctype_util.c16
-rw-r--r--src/lib/crypto/krb/etypes.c33
-rw-r--r--src/lib/crypto/krb/s2k_des.c4
-rw-r--r--src/lib/crypto/krb/s2k_pbkdf2.c4
-rw-r--r--src/lib/crypto/krb/s2k_rc4.c8
-rw-r--r--src/lib/crypto/krb/string_to_key.c7
-rw-r--r--src/lib/crypto/krb/t_fortuna.c2
-rw-r--r--src/lib/crypto/libk5crypto.exports1
-rw-r--r--src/lib/gssapi/generic/gssapi_ext.h11
-rw-r--r--src/lib/gssapi/generic/gssapi_generic.c9
-rw-r--r--src/lib/gssapi/krb5/accept_sec_context.c8
-rw-r--r--src/lib/gssapi/krb5/acquire_cred.c13
-rw-r--r--src/lib/gssapi/krb5/context_time.c5
-rw-r--r--src/lib/gssapi/krb5/copy_ccache.c10
-rw-r--r--src/lib/gssapi/krb5/export_cred.c5
-rw-r--r--src/lib/gssapi/krb5/gssapiP_krb5.h12
-rw-r--r--src/lib/gssapi/krb5/gssapi_krb5.c20
-rw-r--r--src/lib/gssapi/krb5/gssapi_krb5.h14
-rw-r--r--src/lib/gssapi/krb5/iakerb.c4
-rw-r--r--src/lib/gssapi/krb5/init_sec_context.c13
-rw-r--r--src/lib/gssapi/krb5/inq_context.c29
-rw-r--r--src/lib/gssapi/krb5/inq_cred.c46
-rw-r--r--src/lib/gssapi/krb5/k5sealv3.c10
-rw-r--r--src/lib/gssapi/krb5/k5unseal.c2
-rw-r--r--src/lib/gssapi/krb5/naming_exts.c40
-rw-r--r--src/lib/gssapi/krb5/s4u_gss_glue.c2
-rw-r--r--src/lib/gssapi/libgssapi_krb5.exports2
-rw-r--r--src/lib/gssapi/mechglue/g_accept_sec_context.c22
-rw-r--r--src/lib/gssapi/mechglue/g_complete_auth_token.c2
-rw-r--r--src/lib/gssapi/mechglue/g_context_time.c2
-rw-r--r--src/lib/gssapi/mechglue/g_delete_sec_context.c14
-rw-r--r--src/lib/gssapi/mechglue/g_dup_name.c2
-rw-r--r--src/lib/gssapi/mechglue/g_exp_sec_context.c2
-rw-r--r--src/lib/gssapi/mechglue/g_glue.c20
-rw-r--r--src/lib/gssapi/mechglue/g_init_sec_context.c19
-rw-r--r--src/lib/gssapi/mechglue/g_inq_context.c2
-rw-r--r--src/lib/gssapi/mechglue/g_inq_cred_oid.c5
-rw-r--r--src/lib/gssapi/mechglue/g_prf.c2
-rw-r--r--src/lib/gssapi/mechglue/g_process_context.c2
-rw-r--r--src/lib/gssapi/mechglue/g_seal.c4
-rw-r--r--src/lib/gssapi/mechglue/g_sign.c2
-rw-r--r--src/lib/gssapi/mechglue/g_unseal.c2
-rw-r--r--src/lib/gssapi/mechglue/g_unwrap_aead.c2
-rw-r--r--src/lib/gssapi/mechglue/g_unwrap_iov.c4
-rw-r--r--src/lib/gssapi/mechglue/g_verify.c2
-rw-r--r--src/lib/gssapi/mechglue/g_wrap_aead.c2
-rw-r--r--src/lib/gssapi/mechglue/g_wrap_iov.c8
-rw-r--r--src/lib/gssapi32.def3
-rw-r--r--src/lib/kadm5/chpass_util.c8
-rw-r--r--src/lib/kadm5/deps14
-rw-r--r--src/lib/kadm5/kadm_err.et1
-rw-r--r--src/lib/kadm5/srv/Makefile.in20
-rw-r--r--src/lib/kadm5/srv/deps21
-rw-r--r--src/lib/kadm5/srv/libkadm5srv_mit.exports5
-rw-r--r--src/lib/kadm5/srv/server_acl.c823
-rw-r--r--src/lib/kadm5/srv/server_acl.h100
-rw-r--r--src/lib/kadm5/srv/server_kdb.c2
-rw-r--r--src/lib/kadm5/srv/server_misc.c14
-rw-r--r--src/lib/kadm5/srv/svr_principal.c88
-rw-r--r--src/lib/kadm5/unit-test/setkey-test.c3
-rw-r--r--src/lib/kdb/Makefile.in2
-rw-r--r--src/lib/kdb/deps3
-rw-r--r--src/lib/kdb/kdb5.c25
-rw-r--r--src/lib/kdb/kdb_convert.c4
-rw-r--r--src/lib/kdb/kdb_default.c2
-rw-r--r--src/lib/kdb/t_sort_key_data.c5
-rw-r--r--src/lib/krb5/asn.1/asn1_k_encode.c3
-rw-r--r--src/lib/krb5/ccache/Makefile.in3
-rw-r--r--src/lib/krb5/ccache/cc-int.h4
-rw-r--r--src/lib/krb5/ccache/cc_kcm.c4
-rw-r--r--src/lib/krb5/ccache/cc_keyring.c14
-rw-r--r--src/lib/krb5/ccache/cc_memory.c4
-rw-r--r--src/lib/krb5/ccache/cc_mslsa.c1
-rw-r--r--src/lib/krb5/ccache/cc_retr.c5
-rw-r--r--src/lib/krb5/ccache/ccapi/stdcc_util.c40
-rw-r--r--src/lib/krb5/ccache/cccursor.c49
-rw-r--r--src/lib/krb5/ccache/ccmarshal.c2
-rw-r--r--src/lib/krb5/ccache/ccselect.c52
-rw-r--r--src/lib/krb5/ccache/ccselect_hostname.c146
-rw-r--r--src/lib/krb5/ccache/deps11
-rw-r--r--src/lib/krb5/keytab/kt_file.c8
-rw-r--r--src/lib/krb5/keytab/kt_memory.c2
-rw-r--r--src/lib/krb5/keytab/kt_srvtab.c2
-rw-r--r--src/lib/krb5/krb/Makefile.in14
-rw-r--r--src/lib/krb5/krb/deltat.c75
-rw-r--r--src/lib/krb5/krb/deps38
-rw-r--r--src/lib/krb5/krb/fwd_tgt.c28
-rw-r--r--src/lib/krb5/krb/gc_via_tkt.c11
-rw-r--r--src/lib/krb5/krb/gen_save_subkey.c3
-rw-r--r--src/lib/krb5/krb/get_creds.c15
-rw-r--r--src/lib/krb5/krb/get_in_tkt.c294
-rw-r--r--src/lib/krb5/krb/gic_opt.c2
-rw-r--r--src/lib/krb5/krb/gic_pwd.c4
-rw-r--r--src/lib/krb5/krb/init_creds_ctx.h9
-rw-r--r--src/lib/krb5/krb/init_ctx.c3
-rw-r--r--src/lib/krb5/krb/int-proto.h22
-rw-r--r--src/lib/krb5/krb/mk_req.c5
-rw-r--r--src/lib/krb5/krb/pac.c9
-rw-r--r--src/lib/krb5/krb/pac_sign.c21
-rw-r--r--src/lib/krb5/krb/plugin.c5
-rw-r--r--src/lib/krb5/krb/preauth2.c311
-rw-r--r--src/lib/krb5/krb/preauth_ec.c2
-rw-r--r--src/lib/krb5/krb/send_tgs.c24
-rw-r--r--src/lib/krb5/krb/sendauth.c23
-rw-r--r--src/lib/krb5/krb/str_conv.c4
-rwxr-xr-xsrc/lib/krb5/krb/t_expire_warn.py13
-rw-r--r--src/lib/krb5/krb/t_kerb.c12
-rw-r--r--src/lib/krb5/krb/t_parse_host_string.c5
-rw-r--r--src/lib/krb5/krb/t_valid_times.c109
-rw-r--r--src/lib/krb5/krb/valid_times.c4
-rw-r--r--src/lib/krb5/krb/vfy_increds.c2
-rw-r--r--src/lib/krb5/krb/x-deltat.y1
-rw-r--r--src/lib/krb5/os/Makefile.in2
-rw-r--r--src/lib/krb5/os/accessor.c13
-rw-r--r--src/lib/krb5/os/c_ustime.c15
-rw-r--r--src/lib/krb5/os/dnsglue.c2
-rw-r--r--src/lib/krb5/os/dnsglue.h19
-rw-r--r--src/lib/krb5/os/dnssrv.c18
-rw-r--r--src/lib/krb5/os/expand_path.c2
-rw-r--r--src/lib/krb5/os/genaddrs.c8
-rw-r--r--src/lib/krb5/os/hostaddr.c4
-rw-r--r--src/lib/krb5/os/localaddr.c24
-rw-r--r--src/lib/krb5/os/locate_kdc.c43
-rw-r--r--src/lib/krb5/os/sendto_kdc.c5
-rw-r--r--src/lib/krb5/os/t_locate_kdc.c2
-rw-r--r--src/lib/krb5/os/timeofday.c2
-rw-r--r--src/lib/krb5/os/toffset.c5
-rw-r--r--src/lib/krb5/os/trace.c7
-rw-r--r--src/lib/krb5/os/ustime.c9
-rw-r--r--src/lib/krb5/rcache/rc_dfl.c15
-rw-r--r--src/lib/krb5/rcache/ser_rc.c2
-rw-r--r--src/lib/krb5/rcache/t_replay.c8
-rw-r--r--src/lib/krb5/unicode/ure/ure.c2
-rw-r--r--src/lib/krb5_32.def3
-rw-r--r--src/lib/rpc/deps3
-rw-r--r--src/lib/rpc/pmap_rmt.c6
-rw-r--r--src/man/k5identity.man2
-rw-r--r--src/man/k5login.man2
-rw-r--r--src/man/k5srvutil.man2
-rw-r--r--src/man/kadm5.acl.man38
-rw-r--r--src/man/kadmin.man9
-rw-r--r--src/man/kadmind.man2
-rw-r--r--src/man/kdb5_ldap_util.man2
-rw-r--r--src/man/kdb5_util.man2
-rw-r--r--src/man/kdc.conf.man19
-rw-r--r--src/man/kdestroy.man2
-rw-r--r--src/man/kinit.man2
-rw-r--r--src/man/klist.man2
-rw-r--r--src/man/kpasswd.man2
-rw-r--r--src/man/kprop.man2
-rw-r--r--src/man/kpropd.man7
-rw-r--r--src/man/kproplog.man2
-rw-r--r--src/man/krb5-config.man2
-rw-r--r--src/man/krb5.conf.man63
-rw-r--r--src/man/krb5kdc.man2
-rw-r--r--src/man/ksu.man2
-rw-r--r--src/man/kswitch.man2
-rw-r--r--src/man/ktutil.man4
-rw-r--r--src/man/kvno.man2
-rw-r--r--src/man/sclient.man2
-rw-r--r--src/man/sserver.man2
-rw-r--r--src/patchlevel.h8
-rwxr-xr-xsrc/plugins/audit/kdc_j_encode.c29
-rw-r--r--src/plugins/certauth/test/Makefile.in20
-rw-r--r--src/plugins/certauth/test/certauth_test.exports2
-rw-r--r--src/plugins/certauth/test/deps14
-rw-r--r--src/plugins/certauth/test/main.c211
-rw-r--r--src/plugins/kadm5_auth/test/Makefile.in20
-rw-r--r--src/plugins/kadm5_auth/test/deps22
-rw-r--r--src/plugins/kadm5_auth/test/kadm5_auth_test.exports2
-rw-r--r--src/plugins/kadm5_auth/test/main.c305
-rw-r--r--src/plugins/kdb/db2/db2_exp.c5
-rw-r--r--src/plugins/kdb/db2/kdb_db2.c13
-rw-r--r--src/plugins/kdb/db2/kdb_db2.h5
-rw-r--r--src/plugins/kdb/db2/libdb2/hash/hash.c19
-rw-r--r--src/plugins/kdb/db2/lockout.c8
-rw-r--r--src/plugins/kdb/ldap/libkdb_ldap/kdb_ldap.c6
-rw-r--r--src/plugins/kdb/ldap/libkdb_ldap/kdb_ldap.h16
-rw-r--r--src/plugins/kdb/ldap/libkdb_ldap/kdb_ldap_conn.c1
-rw-r--r--src/plugins/kdb/ldap/libkdb_ldap/kerberos.openldap.ldif68
-rw-r--r--src/plugins/kdb/ldap/libkdb_ldap/ldap_handle.c68
-rw-r--r--src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c98
-rw-r--r--src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c2
-rw-r--r--src/plugins/kdb/ldap/libkdb_ldap/ldap_tkt_policy.c2
-rw-r--r--src/plugins/kdb/ldap/libkdb_ldap/lockout.c8
-rw-r--r--src/plugins/kdcpolicy/test/Makefile.in20
-rw-r--r--src/plugins/kdcpolicy/test/deps14
-rw-r--r--src/plugins/kdcpolicy/test/kdcpolicy_test.exports1
-rw-r--r--src/plugins/kdcpolicy/test/main.c111
-rw-r--r--src/plugins/preauth/otp/main.c3
-rw-r--r--src/plugins/preauth/pkinit/Makefile.in8
-rw-r--r--src/plugins/preauth/pkinit/deps11
-rw-r--r--src/plugins/preauth/pkinit/pkinit.h10
-rw-r--r--src/plugins/preauth/pkinit/pkinit_clnt.c7
-rw-r--r--src/plugins/preauth/pkinit/pkinit_crypto.h88
-rw-r--r--src/plugins/preauth/pkinit/pkinit_crypto_nss.c5800
-rw-r--r--src/plugins/preauth/pkinit/pkinit_crypto_openssl.c838
-rw-r--r--src/plugins/preauth/pkinit/pkinit_crypto_openssl.h19
-rw-r--r--src/plugins/preauth/pkinit/pkinit_identity.c32
-rw-r--r--src/plugins/preauth/pkinit/pkinit_matching.c177
-rw-r--r--src/plugins/preauth/pkinit/pkinit_srv.c448
-rw-r--r--src/plugins/preauth/pkinit/pkinit_trace.h78
-rw-r--r--src/plugins/preauth/test/Makefile.in4
-rw-r--r--src/plugins/preauth/test/cltest.c86
-rw-r--r--src/plugins/preauth/test/common.c61
-rw-r--r--src/plugins/preauth/test/common.h41
-rw-r--r--src/plugins/preauth/test/deps14
-rw-r--r--src/plugins/preauth/test/kdctest.c96
-rw-r--r--src/po/Makefile.in2
-rw-r--r--src/po/de.po9301
-rw-r--r--src/po/mit-krb5.pot1592
-rw-r--r--src/slave/kprop.c68
-rw-r--r--src/slave/kprop_util.c4
-rw-r--r--src/slave/kpropd.c203
-rw-r--r--src/tests/Makefile.in27
-rw-r--r--src/tests/create/kdb5_mkdums.c2
-rw-r--r--src/tests/dejagnu/pkinit-certs/ca.pem54
-rw-r--r--src/tests/dejagnu/pkinit-certs/generic.p12bin0 -> 2477 bytes
-rw-r--r--src/tests/dejagnu/pkinit-certs/generic.pem21
-rw-r--r--src/tests/dejagnu/pkinit-certs/kdc.pem50
-rwxr-xr-xsrc/tests/dejagnu/pkinit-certs/make-certs.sh69
-rw-r--r--src/tests/dejagnu/pkinit-certs/privkey-enc.pem52
-rw-r--r--src/tests/dejagnu/pkinit-certs/privkey.pem50
-rw-r--r--src/tests/dejagnu/pkinit-certs/user-enc.p12bin3029 -> 2837 bytes
-rw-r--r--src/tests/dejagnu/pkinit-certs/user-upn.p12bin0 -> 2829 bytes
-rw-r--r--src/tests/dejagnu/pkinit-certs/user-upn.pem28
-rw-r--r--src/tests/dejagnu/pkinit-certs/user-upn2.p12bin0 -> 2813 bytes
-rw-r--r--src/tests/dejagnu/pkinit-certs/user-upn2.pem28
-rw-r--r--src/tests/dejagnu/pkinit-certs/user-upn3.p12bin0 -> 2829 bytes
-rw-r--r--src/tests/dejagnu/pkinit-certs/user-upn3.pem28
-rw-r--r--src/tests/dejagnu/pkinit-certs/user.p12bin3104 -> 2837 bytes
-rw-r--r--src/tests/dejagnu/pkinit-certs/user.pem56
-rw-r--r--src/tests/deps16
-rw-r--r--src/tests/gssapi/Makefile.in27
-rw-r--r--src/tests/gssapi/deps7
-rw-r--r--src/tests/gssapi/t_authind.py20
-rwxr-xr-xsrc/tests/gssapi/t_ccselect.py69
-rwxr-xr-xsrc/tests/gssapi/t_client_keytab.py60
-rw-r--r--src/tests/gssapi/t_enctypes.c14
-rwxr-xr-xsrc/tests/gssapi/t_enctypes.py4
-rwxr-xr-xsrc/tests/gssapi/t_export_cred.py4
-rwxr-xr-xsrc/tests/gssapi/t_gssapi.py130
-rw-r--r--src/tests/gssapi/t_invalid.c57
-rw-r--r--src/tests/gssapi/t_lifetime.c140
-rw-r--r--src/tests/gssapi/t_s4u.c20
-rwxr-xr-xsrc/tests/gssapi/t_s4u.py21
-rw-r--r--src/tests/hammer/kdc5_hammer.c47
-rw-r--r--src/tests/icinterleave.c128
-rw-r--r--src/tests/icred.c67
-rw-r--r--src/tests/kdbtest.c5
-rw-r--r--src/tests/responder.c2
-rwxr-xr-xsrc/tests/t_audit.py11
-rw-r--r--src/tests/t_authdata.py66
-rwxr-xr-xsrc/tests/t_ccache.py60
-rw-r--r--src/tests/t_certauth.py47
-rwxr-xr-xsrc/tests/t_crossrealm.py49
-rwxr-xr-xsrc/tests/t_dump.py31
-rwxr-xr-xsrc/tests/t_general.py37
-rwxr-xr-xsrc/tests/t_hostrealm.py5
-rwxr-xr-xsrc/tests/t_iprop.py103
-rw-r--r--src/tests/t_kadm5_auth.py81
-rwxr-xr-xsrc/tests/t_kadm5_hook.py10
-rwxr-xr-xsrc/tests/t_kadmin_acl.py269
-rw-r--r--src/tests/t_kadmin_parsing.py30
-rwxr-xr-xsrc/tests/t_kdb.py219
-rwxr-xr-xsrc/tests/t_kdb_locking.py5
-rw-r--r--src/tests/t_kdcpolicy.py62
-rwxr-xr-xsrc/tests/t_keydata.py16
-rwxr-xr-xsrc/tests/t_keyrollover.py16
-rwxr-xr-xsrc/tests/t_keytab.py50
-rwxr-xr-xsrc/tests/t_kprop.py13
-rwxr-xr-xsrc/tests/t_localauth.py5
-rwxr-xr-xsrc/tests/t_mkey.py45
-rwxr-xr-xsrc/tests/t_otp.py10
-rwxr-xr-xsrc/tests/t_pkinit.py154
-rwxr-xr-xsrc/tests/t_policy.py101
-rw-r--r--src/tests/t_preauth.py183
-rwxr-xr-xsrc/tests/t_pwqual.py25
-rwxr-xr-xsrc/tests/t_referral.py18
-rwxr-xr-xsrc/tests/t_renew.py78
-rwxr-xr-xsrc/tests/t_salt.py12
-rwxr-xr-xsrc/tests/t_skew.py22
-rwxr-xr-xsrc/tests/t_stringattr.py4
-rw-r--r--src/tests/t_y2038.py75
-rwxr-xr-xsrc/util/depfix.pl2
-rw-r--r--src/util/k5test.py37
-rw-r--r--src/util/profile/prof_parse.c6
-rw-r--r--src/util/profile/profile_tcl.c2
-rw-r--r--src/util/ss/data.c3
-rw-r--r--src/util/support/Makefile.in10
-rw-r--r--src/util/support/cache-addrinfo.h12
-rw-r--r--src/util/support/deps6
-rw-r--r--src/util/support/fake-addrinfo.c16
-rw-r--r--src/util/support/gmt_mktime.c17
-rw-r--r--src/util/support/libkrb5support-fixed.exports5
-rw-r--r--src/util/support/plugins.c5
-rw-r--r--src/util/support/t_utf16.c117
-rw-r--r--src/util/support/threads.c6
-rw-r--r--src/util/support/utf8.c2
-rw-r--r--src/util/support/utf8_conv.c475
-rw-r--r--src/util/verto/README2
-rw-r--r--src/util/verto/libverto.exports1
-rw-r--r--src/util/verto/verto-k5ev.c24
-rw-r--r--src/util/verto/verto-libev.c5
-rw-r--r--src/util/verto/verto.c131
-rw-r--r--src/util/verto/verto.h20
-rw-r--r--src/windows/cns/tktlist.c10
-rw-r--r--src/windows/include/leashwin.h12
-rw-r--r--src/windows/leash/KrbListTickets.cpp12
-rw-r--r--src/windows/leash/LeashView.cpp22
-rw-r--r--src/windows/leashdll/lshfunc.c2
-rw-r--r--src/windows/ms2mit/ms2mit.c2
415 files changed, 21898 insertions, 14289 deletions
diff --git a/src/Makefile.in b/src/Makefile.in
index 2ebf2fb4d0c2..ac9a2a060485 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -12,14 +12,17 @@ SUBDIRS=util include lib \
plugins/audit/test \
@audit_plugin@ \
plugins/kadm5_hook/test \
+ plugins/kadm5_auth/test \
plugins/hostrealm/test \
plugins/localauth/test \
plugins/pwqual/test \
plugins/authdata/greet_server \
plugins/authdata/greet_client \
+ plugins/certauth/test \
plugins/kdb/db2 \
@ldap_plugin_dir@ \
plugins/kdb/test \
+ plugins/kdcpolicy/test \
plugins/preauth/otp \
plugins/preauth/pkinit \
plugins/preauth/test \
@@ -501,7 +504,7 @@ check-pytests-no: check-postrecurse
$(SKIPTESTS)
check-cmocka-no: check-postrecurse
- @echo 'Skipped cmocka tests due to missing library or header file' >> \
+ @echo 'Skipped cmocka tests: cmocka library or header not found' >> \
$(SKIPTESTS)
# Create a test realm and spawn a shell in an environment pointing to it.
@@ -520,6 +523,7 @@ pyrunenv.vals: Makefile
done > $@
echo "tls_impl = '$(TLS_IMPL)'" >> $@
echo "have_sasl = '$(HAVE_SASL)'" >> $@
+ echo "sizeof_time_t = $(SIZEOF_TIME_T)" >> $@
runenv.py: pyrunenv.vals
echo 'env = {}' > $@
diff --git a/src/aclocal.m4 b/src/aclocal.m4
index 9c46da4b5956..d6d1279c3f4f 100644
--- a/src/aclocal.m4
+++ b/src/aclocal.m4
@@ -169,7 +169,7 @@ if test "$enable_thread_support" = yes ; then
fi
dnl Maybe this should be inside the conditional above? Doesn't cache....
if test "$enable_thread_support" = yes; then
- ACX_PTHREAD(,[AC_MSG_ERROR([cannot determine options for enabling thread support; try --disable-thread-support])])
+ AX_PTHREAD(,[AC_MSG_ERROR([cannot determine options for enabling thread support; try --disable-thread-support])])
AC_MSG_NOTICE(PTHREAD_CC = $PTHREAD_CC)
AC_MSG_NOTICE(PTHREAD_CFLAGS = $PTHREAD_CFLAGS)
AC_MSG_NOTICE(PTHREAD_LIBS = $PTHREAD_LIBS)
@@ -450,13 +450,13 @@ krb5_ac_warn_cflags_set=${WARN_CFLAGS+set}
krb5_ac_warn_cxxflags_set=${WARN_CXXFLAGS+set}
])
dnl
-AC_DEFUN(TRY_WARN_CC_FLAG,[dnl
+AC_DEFUN(TRY_WARN_CC_FLAG_1,[dnl
cachevar=`echo "krb5_cv_cc_flag_$1" | sed -e s/=/_eq_/g -e s/-/_dash_/g -e s/[[^a-zA-Z0-9_]]/_/g`
AC_CACHE_CHECK([if C compiler supports $1], [$cachevar],
[# first try without, then with
AC_TRY_COMPILE([], 1;,
[old_cflags="$CFLAGS"
- CFLAGS="$CFLAGS $1"
+ CFLAGS="$CFLAGS $cflags_warning_test_flags $1"
AC_TRY_COMPILE([], 1;, eval $cachevar=yes, eval $cachevar=no)
CFLAGS="$old_cflags"],
[AC_MSG_ERROR(compiling simple test program with $CFLAGS failed)])])
@@ -466,6 +466,21 @@ AC_DEFUN(TRY_WARN_CC_FLAG,[dnl
eval flag_supported='${'$cachevar'}'
])dnl
dnl
+dnl Are additional flags needed to make unsupported warning options
+dnl get reported as errors?
+AC_DEFUN(CHECK_CC_WARNING_TEST_FLAGS,[dnl
+ cflags_warning_test_flags=
+ TRY_WARN_CC_FLAG_1(-Werror=unknown-warning-option)
+ if test $flag_supported = yes; then
+ cflags_warning_test_flags=-Werror=unknown-warning-option
+ fi
+])dnl
+dnl
+AC_DEFUN(TRY_WARN_CC_FLAG,[dnl
+AC_REQUIRE([CHECK_CC_WARNING_TEST_FLAGS])dnl
+TRY_WARN_CC_FLAG_1($1)dnl
+])dnl
+dnl
AC_DEFUN(WITH_CC,[dnl
AC_REQUIRE([KRB5_AC_CHECK_FOR_CFLAGS])dnl
AC_REQUIRE([AC_PROG_CC])dnl
@@ -528,7 +543,7 @@ if test "$GCC" = yes ; then
TRY_WARN_CC_FLAG(-Wno-format-zero-length)
# Other flags here may not be supported on some versions of
# gcc that people want to use.
- for flag in overflow strict-overflow missing-format-attribute missing-prototypes return-type missing-braces parentheses switch unused-function unused-label unused-variable unused-value unknown-pragmas sign-compare newline-eof error=uninitialized error=pointer-arith error=int-conversion error=incompatible-pointer-types error=discarded-qualifiers ; do
+ for flag in overflow strict-overflow missing-format-attribute missing-prototypes return-type missing-braces parentheses switch unused-function unused-label unused-variable unused-value unknown-pragmas sign-compare newline-eof error=uninitialized no-maybe-uninitialized error=pointer-arith error=int-conversion error=incompatible-pointer-types error=discarded-qualifiers error=implicit-int ; do
TRY_WARN_CC_FLAG(-W$flag)
done
# old-style-definition? generates many, many warnings
@@ -615,8 +630,16 @@ else
# works, but it also means that declaration-in-code warnings won't
# be issued.
# -v -fd -errwarn=E_DECLARATION_IN_CODE ...
- WARN_CFLAGS="-errtags=yes -errwarn=E_BAD_PTR_INT_COMBINATION,E_BAD_PTR_INT_COMB_ARG,E_PTR_TO_VOID_IN_ARITHMETIC,E_NO_IMPLICIT_DECL_ALLOWED,E_ATTRIBUTE_PARAM_UNDEFINED"
- WARN_CXXFLAGS="-errtags=yes +w +w2 -xport64"
+ if test "x$krb5_ac_warn_cflags_set" = xset ; then
+ AC_MSG_NOTICE(not adding extra warning flags because WARN_CFLAGS was set)
+ else
+ WARN_CFLAGS="-errtags=yes -errwarn=E_BAD_PTR_INT_COMBINATION,E_BAD_PTR_INT_COMB_ARG,E_PTR_TO_VOID_IN_ARITHMETIC,E_NO_IMPLICIT_DECL_ALLOWED,E_ATTRIBUTE_PARAM_UNDEFINED"
+ fi
+ if test "x$krb5_ac_warn_cxxflags_set" = xset ; then
+ AC_MSG_NOTICE(not adding extra warning flags because WARN_CXXFLAGS was set)
+ else
+ WARN_CXXFLAGS="-errtags=yes +w +w2 -xport64"
+ fi
fi
fi
AC_SUBST(WARN_CFLAGS)
@@ -1352,7 +1375,6 @@ dnl =============================================================
dnl Internal function for testing for getpeername prototype
dnl
AC_DEFUN([KRB5_GETPEERNAME_ARGS],[
-AC_DEFINE([GETPEERNAME_ARG2_TYPE],GETSOCKNAME_ARG2_TYPE,[Type of getpeername second argument.])
AC_DEFINE([GETPEERNAME_ARG3_TYPE],GETSOCKNAME_ARG3_TYPE,[Type of getpeername second argument.])
])
dnl
@@ -1397,7 +1419,6 @@ if test "$sock_set" = no; then
fi
res1=`echo "$res1" | tr -d '*' | sed -e 's/ *$//'`
res2=`echo "$res2" | tr -d '*' | sed -e 's/ *$//'`
-AC_DEFINE_UNQUOTED([GETSOCKNAME_ARG2_TYPE],$res1,[Type of pointer target for argument 2 to getsockname])
AC_DEFINE_UNQUOTED([GETSOCKNAME_ARG3_TYPE],$res2,[Type of pointer target for argument 3 to getsockname])
])
dnl
@@ -1634,8 +1655,8 @@ if test $krb5_cv_pragma_weak_ref = yes ; then
fi])
dnl
dnl
-m4_include(config/ac-archive/acx_pthread.m4)
-m4_include(config/ac-archive/relpaths.m4)
+m4_include(config/ac-archive/ax_pthread.m4)
+m4_include(config/ac-archive/ax_recursive_eval.m4)
dnl
dnl
dnl
diff --git a/src/appl/gss-sample/t_gss_sample.py b/src/appl/gss-sample/t_gss_sample.py
index 8a6b0304f890..0299e45904b8 100755
--- a/src/appl/gss-sample/t_gss_sample.py
+++ b/src/appl/gss-sample/t_gss_sample.py
@@ -31,22 +31,20 @@ gss_server = os.path.join(appdir, 'gss-server')
# Run a gss-server process and a gss-client process, with additional
# gss-client flags given by options and additional gss-server flags
# given by server_options. Return the output of gss-client.
-def run_client_server(realm, options, server_options, expected_code=0):
+def run_client_server(realm, options, server_options, **kwargs):
portstr = str(realm.server_port())
server_args = [gss_server, '-export', '-port', portstr]
server_args += server_options + ['host']
server = realm.start_server(server_args, 'starting...')
- out = realm.run([gss_client, '-port', portstr] + options +
- [hostname, 'host', 'testmsg'], expected_code=expected_code)
+ realm.run([gss_client, '-port', portstr] + options +
+ [hostname, 'host', 'testmsg'], **kwargs)
stop_daemon(server)
- return out
# Run a gss-server and gss-client process, and verify that gss-client
# displayed the expected output for a successful negotiation.
def server_client_test(realm, options, server_options):
- out = run_client_server(realm, options, server_options)
- if 'Signature verified.' not in out:
- fail('Expected message not seen in gss-client output')
+ run_client_server(realm, options, server_options,
+ expected_msg='Signature verified.')
# Make up a filename to hold user's initial credentials.
def ccache_savefile(realm):
@@ -81,10 +79,10 @@ def pw_test(realm, options, server_options=[]):
# IAKERB, gss_aqcuire_cred_with_password() otherwise).
def wrong_pw_test(realm, options, server_options=[], iakerb=False):
options = options + ['-user', realm.user_princ, '-pass', 'wrongpw']
- out = run_client_server(realm, options, server_options, expected_code=1)
failed_op = 'initializing context' if iakerb else 'acquiring creds'
- if 'GSS-API error ' + failed_op not in out:
- fail('Expected error not seen in gss-client output')
+ msg = 'GSS-API error ' + failed_op
+ run_client_server(realm, options, server_options, expected_code=1,
+ expected_msg=msg)
# Perform a test of the server and client with initial credentials
# obtained with the client keytab
diff --git a/src/appl/simple/client/sim_client.c b/src/appl/simple/client/sim_client.c
index bd3c38c72aa7..cda7d220c406 100644
--- a/src/appl/simple/client/sim_client.c
+++ b/src/appl/simple/client/sim_client.c
@@ -62,7 +62,7 @@ int
main(int argc, char *argv[])
{
int sock, i;
- unsigned int len;
+ socklen_t len;
int flags = 0; /* flags for sendto() */
struct servent *serv;
struct hostent *host;
diff --git a/src/appl/simple/server/sim_server.c b/src/appl/simple/server/sim_server.c
index fce5a9c6fd69..f09489c35d30 100644
--- a/src/appl/simple/server/sim_server.c
+++ b/src/appl/simple/server/sim_server.c
@@ -33,6 +33,7 @@
*/
#include "krb5.h"
+#include "port-sockets.h"
#include <stdio.h>
#include <string.h>
#include <unistd.h>
@@ -64,7 +65,7 @@ int
main(int argc, char *argv[])
{
int sock, i;
- unsigned int len;
+ socklen_t len;
int flags = 0; /* for recvfrom() */
int on = 1;
struct servent *serv;
diff --git a/src/appl/user_user/t_user2user.py b/src/appl/user_user/t_user2user.py
index 8bdef8e07b90..2a7d03f8dc87 100755
--- a/src/appl/user_user/t_user2user.py
+++ b/src/appl/user_user/t_user2user.py
@@ -10,9 +10,9 @@ for realm in multipass_realms():
else:
srv_output = realm.start_server(['./uuserver', '9999'], 'Server started')
- output = realm.run(['./uuclient', hostname, 'testing message', '9999'])
- if 'uu-client: server says \"Hello, other end of connection.\"' not in output:
- fail('Message not echoed back.')
+ msg = 'uu-client: server says "Hello, other end of connection."'
+ realm.run(['./uuclient', hostname, 'testing message', '9999'],
+ expected_msg=msg)
success('User-2-user test programs')
diff --git a/src/ccapi/server/mac/ccs_os_pipe.c b/src/ccapi/server/mac/ccs_os_pipe.c
index 67f90307a230..5d9fff20755d 100644
--- a/src/ccapi/server/mac/ccs_os_pipe.c
+++ b/src/ccapi/server/mac/ccs_os_pipe.c
@@ -27,7 +27,7 @@
#include "ccs_os_pipe.h"
#include <mach/port.h>
-/* On Mac OS X ccs_pipe_t is a mach_port_t */
+/* On macOS ccs_pipe_t is a mach_port_t */
/* ------------------------------------------------------------------------ */
@@ -73,7 +73,7 @@ cc_int32 ccs_os_pipe_release (ccs_pipe_t io_pipe)
{
cc_int32 err = 0;
- /* Nothing to do here on Mac OS X */
+ /* Nothing to do here on macOS */
return cci_check_error (err);
}
diff --git a/src/clients/kcpytkt/kcpytkt.c b/src/clients/kcpytkt/kcpytkt.c
index 47147cdc3207..0b8802261e9e 100644
--- a/src/clients/kcpytkt/kcpytkt.c
+++ b/src/clients/kcpytkt/kcpytkt.c
@@ -7,26 +7,29 @@
#include "k5-platform.h"
static char *prog;
+static int quiet = 0;
-static void xusage()
+static void
+xusage()
{
- fprintf(stderr, "xusage: %s [-c from_ccache] [-e etype] [-f flags] dest_ccache service1 service2 ...\n", prog);
+ fprintf(stderr, "xusage: %s [-c from_ccache] [-e etype] [-f flags] "
+ "dest_ccache service1 service2 ...\n", prog);
exit(1);
}
-int quiet = 0;
+static void
+do_kcpytkt(int argc, char *argv[], char *fromccachestr, char *etypestr,
+ int flags);
-static void do_kcpytkt (int argc, char *argv[], char *fromccachestr, char *etypestr, int flags);
-
-int main(int argc, char *argv[])
+int
+main(int argc, char *argv[])
{
int option;
- char *etypestr = 0;
- char *fromccachestr = 0;
+ char *etypestr = NULL, *fromccachestr = NULL;
int flags = 0;
prog = strrchr(argv[0], '/');
- prog = prog ? (prog + 1) : argv[0];
+ prog = (prog != NULL) ? prog + 1 : argv[0];
while ((option = getopt(argc, argv, "c:e:f:hq")) != -1) {
switch (option) {
@@ -49,25 +52,24 @@ int main(int argc, char *argv[])
}
}
- if ((argc - optind) < 2)
+ if (argc - optind < 2)
xusage();
do_kcpytkt(argc - optind, argv + optind, fromccachestr, etypestr, flags);
return 0;
}
-static void do_kcpytkt (int count, char *names[],
- char *fromccachestr, char *etypestr, int flags)
+static void
+do_kcpytkt(int count, char *names[], const char *fromccachestr, char *etypestr,
+ int flags)
{
krb5_context context;
krb5_error_code ret;
- int i, errors;
krb5_enctype etype;
- krb5_ccache fromccache;
- krb5_ccache destccache;
+ krb5_ccache fromccache, destccache;
krb5_principal me;
krb5_creds in_creds, out_creds;
- int retflags;
+ int i, errors, retflags;
char *princ;
ret = krb5_init_context(&context);
@@ -75,8 +77,7 @@ static void do_kcpytkt (int count, char *names[],
com_err(prog, ret, "while initializing krb5 library");
exit(1);
}
-
- if (etypestr) {
+ if (etypestr != NULL) {
ret = krb5_string_to_enctype(etypestr, &etype);
if (ret) {
com_err(prog, ret, "while converting etype");
@@ -88,7 +89,7 @@ static void do_kcpytkt (int count, char *names[],
retflags = KRB5_TC_MATCH_SRV_NAMEONLY;
}
- if (fromccachestr)
+ if (fromccachestr != NULL)
ret = krb5_cc_resolve(context, fromccachestr, &fromccache);
else
ret = krb5_cc_default(context, &fromccache);
@@ -118,9 +119,10 @@ static void do_kcpytkt (int count, char *names[],
ret = krb5_parse_name(context, names[i], &in_creds.server);
if (ret) {
- if (!quiet)
+ if (!quiet) {
fprintf(stderr, "%s: %s while parsing principal name\n",
names[i], error_message(ret));
+ }
errors++;
continue;
}
@@ -140,24 +142,18 @@ static void do_kcpytkt (int count, char *names[],
if (ret) {
fprintf(stderr, "%s: %s while retrieving credentials\n",
princ, error_message(ret));
-
krb5_free_unparsed_name(context, princ);
-
errors++;
continue;
}
ret = krb5_cc_store_cred(context, destccache, &out_creds);
-
krb5_free_principal(context, in_creds.server);
-
if (ret) {
fprintf(stderr, "%s: %s while removing credentials\n",
princ, error_message(ret));
-
krb5_free_cred_contents(context, &out_creds);
krb5_free_unparsed_name(context, princ);
-
errors++;
continue;
}
diff --git a/src/clients/kdeltkt/kdeltkt.c b/src/clients/kdeltkt/kdeltkt.c
index 9c7a549f970b..cd0bf637db69 100644
--- a/src/clients/kdeltkt/kdeltkt.c
+++ b/src/clients/kdeltkt/kdeltkt.c
@@ -7,26 +7,28 @@
#include "k5-platform.h"
static char *prog;
+static int quiet = 0;
-static void xusage()
+static void
+xusage()
{
- fprintf(stderr, "xusage: %s [-c ccache] [-e etype] [-f flags] service1 service2 ...\n", prog);
+ fprintf(stderr, "xusage: %s [-c ccache] [-e etype] [-f flags] service1 "
+ "service2 ...\n", prog);
exit(1);
}
-int quiet = 0;
+static void
+do_kdeltkt(int argc, char *argv[], char *ccachestr, char *etypestr, int flags);
-static void do_kdeltkt (int argc, char *argv[], char *ccachestr, char *etypestr, int flags);
-
-int main(int argc, char *argv[])
+int
+main(int argc, char *argv[])
{
int option;
- char *etypestr = 0;
- char *ccachestr = 0;
+ char *etypestr = NULL, *ccachestr = NULL;
int flags = 0;
prog = strrchr(argv[0], '/');
- prog = prog ? (prog + 1) : argv[0];
+ prog = (prog != NULL) ? prog + 1 : argv[0];
while ((option = getopt(argc, argv, "c:e:f:hq")) != -1) {
switch (option) {
@@ -49,15 +51,16 @@ int main(int argc, char *argv[])
}
}
- if ((argc - optind) < 1)
+ if (argc - optind < 1)
xusage();
do_kdeltkt(argc - optind, argv + optind, ccachestr, etypestr, flags);
return 0;
}
-static void do_kdeltkt (int count, char *names[],
- char *ccachestr, char *etypestr, int flags)
+static void
+do_kdeltkt(int count, char *names[], const char *ccachestr, char *etypestr,
+ int flags)
{
krb5_context context;
krb5_error_code ret;
@@ -75,7 +78,7 @@ static void do_kdeltkt (int count, char *names[],
exit(1);
}
- if (etypestr) {
+ if (etypestr != NULL) {
ret = krb5_string_to_enctype(etypestr, &etype);
if (ret) {
com_err(prog, ret, "while converting etype");
@@ -111,9 +114,10 @@ static void do_kdeltkt (int count, char *names[],
ret = krb5_parse_name(context, names[i], &in_creds.server);
if (ret) {
- if (!quiet)
+ if (!quiet) {
fprintf(stderr, "%s: %s while parsing principal name\n",
names[i], error_message(ret));
+ }
errors++;
continue;
}
@@ -133,9 +137,7 @@ static void do_kdeltkt (int count, char *names[],
if (ret) {
fprintf(stderr, "%s: %s while retrieving credentials\n",
princ, error_message(ret));
-
krb5_free_unparsed_name(context, princ);
-
errors++;
continue;
}
@@ -147,14 +149,11 @@ static void do_kdeltkt (int count, char *names[],
if (ret) {
fprintf(stderr, "%s: %s while removing credentials\n",
princ, error_message(ret));
-
krb5_free_cred_contents(context, &out_creds);
krb5_free_unparsed_name(context, princ);
-
errors++;
continue;
}
-
krb5_free_unparsed_name(context, princ);
krb5_free_cred_contents(context, &out_creds);
}
diff --git a/src/clients/kdestroy/kdestroy.c b/src/clients/kdestroy/kdestroy.c
index f95554903ece..0bf83586c14f 100644
--- a/src/clients/kdestroy/kdestroy.c
+++ b/src/clients/kdestroy/kdestroy.c
@@ -41,7 +41,7 @@ extern int optind;
extern char *optarg;
#ifndef _WIN32
-#define GET_PROGNAME(x) (strrchr((x), '/') ? strrchr((x), '/')+1 : (x))
+#define GET_PROGNAME(x) (strrchr((x), '/') ? strrchr((x), '/') + 1 : (x))
#else
#define GET_PROGNAME(x) max(max(strrchr((x), '/'), strrchr((x), '\\')) + 1,(x))
#endif
@@ -49,10 +49,9 @@ extern char *optarg;
char *progname;
-static void usage()
+static void
+usage()
{
-#define KRB_AVAIL_STRING(x) ((x)?"available":"not available")
-
fprintf(stderr, _("Usage: %s [-A] [-q] [-c cache_name]\n"), progname);
fprintf(stderr, _("\t-A destroy all credential caches in collection\n"));
fprintf(stderr, _("\t-q quiet mode\n"));
@@ -64,18 +63,18 @@ static void usage()
static void
print_remaining_cc_warning(krb5_context context)
{
- krb5_error_code retval;
+ krb5_error_code ret;
krb5_ccache cache;
krb5_cccol_cursor cursor;
- retval = krb5_cccol_cursor_new(context, &cursor);
- if (retval) {
- com_err(progname, retval, _("while listing credential caches"));
+ ret = krb5_cccol_cursor_new(context, &cursor);
+ if (ret) {
+ com_err(progname, ret, _("while listing credential caches"));
exit(1);
}
- retval = krb5_cccol_cursor_next(context, cursor, &cache);
- if (retval == 0 && cache != NULL) {
+ ret = krb5_cccol_cursor_next(context, cursor, &cache);
+ if (ret == 0 && cache != NULL) {
fprintf(stderr,
_("Other credential caches present, use -A to destroy all\n"));
krb5_cc_close(context, cache);
@@ -85,20 +84,14 @@ print_remaining_cc_warning(krb5_context context)
}
int
-main(argc, argv)
- int argc;
- char **argv;
+main(int argc, char *argv[])
{
- krb5_context kcontext;
- krb5_error_code retval;
- int c;
+ krb5_context context;
+ krb5_error_code ret;
krb5_ccache cache = NULL;
krb5_cccol_cursor cursor;
char *cache_name = NULL;
- int code = 0;
- int errflg = 0;
- int quiet = 0;
- int all = 0;
+ int code = 0, errflg = 0, quiet = 0, all = 0, c;
setlocale(LC_ALL, "");
progname = GET_PROGNAME(argv[0]);
@@ -135,62 +128,61 @@ main(argc, argv)
if (optind != argc)
errflg++;
- if (errflg) {
+ if (errflg)
usage();
- }
- retval = krb5_init_context(&kcontext);
- if (retval) {
- com_err(progname, retval, _("while initializing krb5"));
+ ret = krb5_init_context(&context);
+ if (ret) {
+ com_err(progname, ret, _("while initializing krb5"));
exit(1);
}
+ if (cache_name != NULL) {
+ code = krb5_cc_set_default_name(context, cache_name);
+ if (code) {
+ com_err(progname, code, _("while setting default cache name"));
+ exit(1);
+ }
+ }
+
if (all) {
- code = krb5_cccol_cursor_new(kcontext, &cursor);
+ code = krb5_cccol_cursor_new(context, &cursor);
if (code) {
com_err(progname, code, _("while listing credential caches"));
exit(1);
}
- while ((code = krb5_cccol_cursor_next(kcontext, cursor,
- &cache)) == 0 && cache != NULL) {
- code = krb5_cc_get_full_name(kcontext, cache, &cache_name);
+ while (krb5_cccol_cursor_next(context, cursor, &cache) == 0 &&
+ cache != NULL) {
+ code = krb5_cc_get_full_name(context, cache, &cache_name);
if (code) {
com_err(progname, code, _("composing ccache name"));
exit(1);
}
- code = krb5_cc_destroy(kcontext, cache);
+ code = krb5_cc_destroy(context, cache);
if (code && code != KRB5_FCC_NOFILE) {
com_err(progname, code, _("while destroying cache %s"),
cache_name);
}
- krb5_free_string(kcontext, cache_name);
+ krb5_free_string(context, cache_name);
}
- krb5_cccol_cursor_free(kcontext, &cursor);
- krb5_free_context(kcontext);
+ krb5_cccol_cursor_free(context, &cursor);
+ krb5_free_context(context);
return 0;
}
- if (cache_name) {
- code = krb5_cc_resolve (kcontext, cache_name, &cache);
- if (code != 0) {
- com_err(progname, code, _("while resolving %s"), cache_name);
- exit(1);
- }
- } else {
- code = krb5_cc_default(kcontext, &cache);
- if (code) {
- com_err(progname, code, _("while getting default ccache"));
- exit(1);
- }
+ code = krb5_cc_default(context, &cache);
+ if (code) {
+ com_err(progname, code, _("while resolving ccache"));
+ exit(1);
}
- code = krb5_cc_destroy (kcontext, cache);
+ code = krb5_cc_destroy(context, cache);
if (code != 0) {
- com_err (progname, code, _("while destroying cache"));
+ com_err(progname, code, _("while destroying cache"));
if (code != KRB5_FCC_NOFILE) {
- if (quiet)
+ if (quiet) {
fprintf(stderr, _("Ticket cache NOT destroyed!\n"));
- else {
+ } else {
fprintf(stderr, _("Ticket cache %cNOT%c destroyed!\n"),
BELL_CHAR, BELL_CHAR);
}
@@ -199,8 +191,9 @@ main(argc, argv)
}
if (!quiet && !errflg)
- print_remaining_cc_warning(kcontext);
+ print_remaining_cc_warning(context);
+
+ krb5_free_context(context);
- krb5_free_context(kcontext);
return errflg;
}
diff --git a/src/clients/kinit/kinit.c b/src/clients/kinit/kinit.c
index f1cd1b73db60..a518284ea568 100644
--- a/src/clients/kinit/kinit.c
+++ b/src/clients/kinit/kinit.c
@@ -26,7 +26,7 @@
#include "autoconf.h"
#include <k5-int.h>
-#include "k5-platform.h" /* for asprintf and getopt */
+#include "k5-platform.h" /* For asprintf and getopt */
#include <krb5.h>
#include "extern.h"
#include <locale.h>
@@ -37,40 +37,41 @@
#include <com_err.h>
#ifndef _WIN32
-#define GET_PROGNAME(x) (strrchr((x), '/') ? strrchr((x), '/')+1 : (x))
+#define GET_PROGNAME(x) (strrchr((x), '/') ? strrchr((x), '/') + 1 : (x))
#else
#define GET_PROGNAME(x) max(max(strrchr((x), '/'), strrchr((x), '\\')) + 1,(x))
#endif
#ifdef HAVE_PWD_H
#include <pwd.h>
-static
-char * get_name_from_os()
+static char *
+get_name_from_os()
{
struct passwd *pw;
- if ((pw = getpwuid((int) getuid())))
- return pw->pw_name;
- return 0;
+
+ pw = getpwuid(getuid());
+ return (pw != NULL) ? pw->pw_name : NULL;
}
#else /* HAVE_PWD_H */
#ifdef _WIN32
-static
-char * get_name_from_os()
+static char *
+get_name_from_os()
{
static char name[1024];
DWORD name_size = sizeof(name);
+
if (GetUserName(name, &name_size)) {
- name[sizeof(name)-1] = 0; /* Just to be extra safe */
+ name[sizeof(name) - 1] = '\0'; /* Just to be extra safe */
return name;
} else {
- return 0;
+ return NULL;
}
}
#else /* _WIN32 */
-static
-char * get_name_from_os()
+static char *
+get_name_from_os()
{
- return 0;
+ return NULL;
}
#endif /* _WIN32 */
#endif /* HAVE_PWD_H */
@@ -81,7 +82,7 @@ typedef enum { INIT_PW, INIT_KT, RENEW, VALIDATE } action_type;
struct k_opts
{
- /* in seconds */
+ /* In seconds */
krb5_deltat starttime;
krb5_deltat lifetime;
krb5_deltat rlife;
@@ -99,11 +100,11 @@ struct k_opts
int verbose;
- char* principal_name;
- char* service_name;
- char* keytab_name;
- char* k5_in_cache_name;
- char* k5_out_cache_name;
+ char *principal_name;
+ char *service_name;
+ char *keytab_name;
+ char *k5_in_cache_name;
+ char *k5_out_cache_name;
char *armor_ccache;
action_type action;
@@ -121,46 +122,39 @@ struct k5_data
krb5_context ctx;
krb5_ccache in_cc, out_cc;
krb5_principal me;
- char* name;
+ char *name;
krb5_boolean switch_to_cache;
};
-/* if struct[2] == NULL, then long_getopt acts as if the short flag
- struct[3] was specified. If struct[2] != NULL, then struct[3] is
- stored in *(struct[2]), the array index which was specified is
- stored in *index, and long_getopt() returns 0. */
-
+/*
+ * If struct[2] == NULL, then long_getopt acts as if the short flag struct[3]
+ * were specified. If struct[2] != NULL, then struct[3] is stored in
+ * *(struct[2]), the array index which was specified is stored in *index, and
+ * long_getopt() returns 0.
+ */
const char *shopts = "r:fpFPn54aAVl:s:c:kit:T:RS:vX:CEI:";
+#define USAGE_BREAK "\n\t"
+
static void
usage()
{
-#define USAGE_BREAK "\n\t"
-
-#define USAGE_LONG_FORWARDABLE " | --forwardable | --noforwardable"
-#define USAGE_LONG_PROXIABLE " | --proxiable | --noproxiable"
-#define USAGE_LONG_ADDRESSES " | --addresses | --noaddresses"
-#define USAGE_LONG_CANONICALIZE " | --canonicalize"
-#define USAGE_LONG_ENTERPRISE " | --enterprise"
-#define USAGE_LONG_REQUESTPAC "--request-pac | --no-request-pac"
-#define USAGE_BREAK_LONG USAGE_BREAK
-
fprintf(stderr, "Usage: %s [-V] "
"[-l lifetime] [-s start_time] "
USAGE_BREAK
"[-r renewable_life] "
- "[-f | -F" USAGE_LONG_FORWARDABLE "] "
- USAGE_BREAK_LONG
- "[-p | -P" USAGE_LONG_PROXIABLE "] "
- USAGE_BREAK_LONG
+ "[-f | -F | --forwardable | --noforwardable] "
+ USAGE_BREAK
+ "[-p | -P | --proxiable | --noproxiable] "
+ USAGE_BREAK
"-n "
- "[-a | -A" USAGE_LONG_ADDRESSES "] "
- USAGE_BREAK_LONG
- "[" USAGE_LONG_REQUESTPAC "] "
- USAGE_BREAK_LONG
- "[-C" USAGE_LONG_CANONICALIZE "] "
+ "[-a | -A | --addresses | --noaddresses] "
USAGE_BREAK
- "[-E" USAGE_LONG_ENTERPRISE "] "
+ "[--request-pac | --no-request-pac] "
+ USAGE_BREAK
+ "[-C | --canonicalize] "
+ USAGE_BREAK
+ "[-E | --enterprise] "
USAGE_BREAK
"[-v] [-R] "
"[-k [-i|-t keytab_file]] "
@@ -199,15 +193,17 @@ usage()
}
static krb5_context errctx;
-static void extended_com_err_fn (const char *myprog, errcode_t code,
- const char *fmt, va_list args)
+static void
+extended_com_err_fn(const char *myprog, errcode_t code, const char *fmt,
+ va_list args)
{
const char *emsg;
- emsg = krb5_get_error_message (errctx, code);
- fprintf (stderr, "%s: %s ", myprog, emsg);
- krb5_free_error_message (errctx, emsg);
- vfprintf (stderr, fmt, args);
- fprintf (stderr, "\n");
+
+ emsg = krb5_get_error_message(errctx, code);
+ fprintf(stderr, "%s: %s ", myprog, emsg);
+ krb5_free_error_message(errctx, emsg);
+ vfprintf(stderr, fmt, args);
+ fprintf(stderr, "\n");
}
static int
@@ -215,18 +211,13 @@ add_preauth_opt(struct k_opts *opts, char *av)
{
char *sep, *v;
krb5_gic_opt_pa_data *p, *x;
+ size_t newsize = (opts->num_pa_opts + 1) * sizeof(*opts->pa_opts);
+
+ x = realloc(opts->pa_opts, newsize);
+ if (x == NULL)
+ return ENOMEM;
+ opts->pa_opts = x;
- if (opts->num_pa_opts == 0) {
- opts->pa_opts = malloc(sizeof(krb5_gic_opt_pa_data));
- if (opts->pa_opts == NULL)
- return ENOMEM;
- } else {
- size_t newsize = (opts->num_pa_opts + 1) * sizeof(krb5_gic_opt_pa_data);
- x = realloc(opts->pa_opts, newsize);
- if (x == NULL)
- return ENOMEM;
- opts->pa_opts = x;
- }
p = &opts->pa_opts[opts->num_pa_opts];
sep = strchr(av, '=');
if (sep) {
@@ -242,10 +233,7 @@ add_preauth_opt(struct k_opts *opts, char *av)
}
static char *
-parse_options(argc, argv, opts)
- int argc;
- char **argv;
- struct k_opts* opts;
+parse_options(int argc, char **argv, struct k_opts *opts)
{
struct option long_options[] = {
{ "noforwardable", 0, NULL, 'F' },
@@ -260,7 +248,7 @@ parse_options(argc, argv, opts)
{ "no-request-pac", 0, &opts->not_request_pac, 1 },
{ NULL, 0, NULL, 0 }
};
- krb5_error_code code;
+ krb5_error_code ret;
int errflg = 0;
int i;
@@ -271,16 +259,16 @@ parse_options(argc, argv, opts)
break;
case 'l':
/* Lifetime */
- code = krb5_string_to_deltat(optarg, &opts->lifetime);
- if (code != 0 || opts->lifetime == 0) {
+ ret = krb5_string_to_deltat(optarg, &opts->lifetime);
+ if (ret || opts->lifetime == 0) {
fprintf(stderr, _("Bad lifetime value %s\n"), optarg);
errflg++;
}
break;
case 'r':
/* Renewable Time */
- code = krb5_string_to_deltat(optarg, &opts->rlife);
- if (code != 0 || opts->rlife == 0) {
+ ret = krb5_string_to_deltat(optarg, &opts->rlife);
+ if (ret || opts->rlife == 0) {
fprintf(stderr, _("Bad lifetime value %s\n"), optarg);
errflg++;
}
@@ -307,18 +295,18 @@ parse_options(argc, argv, opts)
opts->no_addresses = 1;
break;
case 's':
- code = krb5_string_to_deltat(optarg, &opts->starttime);
- if (code != 0 || opts->starttime == 0) {
+ ret = krb5_string_to_deltat(optarg, &opts->starttime);
+ if (ret || opts->starttime == 0) {
/* Parse as an absolute time; intentionally undocumented
* but left for backwards compatibility. */
krb5_timestamp abs_starttime;
- code = krb5_string_to_timestamp(optarg, &abs_starttime);
- if (code != 0 || abs_starttime == 0) {
+ ret = krb5_string_to_timestamp(optarg, &abs_starttime);
+ if (ret || abs_starttime == 0) {
fprintf(stderr, _("Bad start time value %s\n"), optarg);
errflg++;
} else {
- opts->starttime = abs_starttime - time(0);
+ opts->starttime = ts_delta(abs_starttime, time(NULL));
}
}
break;
@@ -332,8 +320,7 @@ parse_options(argc, argv, opts)
opts->use_client_keytab = 1;
break;
case 't':
- if (opts->keytab_name)
- {
+ if (opts->keytab_name != NULL) {
fprintf(stderr, _("Only one -t option allowed.\n"));
errflg++;
} else {
@@ -341,10 +328,12 @@ parse_options(argc, argv, opts)
}
break;
case 'T':
- if (opts->armor_ccache) {
+ if (opts->armor_ccache != NULL) {
fprintf(stderr, _("Only one armor_ccache\n"));
errflg++;
- } else opts->armor_ccache = optarg;
+ } else {
+ opts->armor_ccache = optarg;
+ }
break;
case 'R':
opts->action = RENEW;
@@ -353,8 +342,7 @@ parse_options(argc, argv, opts)
opts->action = VALIDATE;
break;
case 'c':
- if (opts->k5_out_cache_name)
- {
+ if (opts->k5_out_cache_name != NULL) {
fprintf(stderr, _("Only one -c option allowed\n"));
errflg++;
} else {
@@ -362,7 +350,7 @@ parse_options(argc, argv, opts)
}
break;
case 'I':
- if (opts->k5_in_cache_name) {
+ if (opts->k5_in_cache_name != NULL) {
fprintf(stderr, _("Only one -I option allowed\n"));
errflg++;
} else {
@@ -370,10 +358,9 @@ parse_options(argc, argv, opts)
}
break;
case 'X':
- code = add_preauth_opt(opts, optarg);
- if (code)
- {
- com_err(progname, code, _("while adding preauth option"));
+ ret = add_preauth_opt(opts, optarg);
+ if (ret) {
+ com_err(progname, ret, _("while adding preauth option"));
errflg++;
}
break;
@@ -398,59 +385,49 @@ parse_options(argc, argv, opts)
}
}
- if (opts->forwardable && opts->not_forwardable)
- {
+ if (opts->forwardable && opts->not_forwardable) {
fprintf(stderr, _("Only one of -f and -F allowed\n"));
errflg++;
}
- if (opts->proxiable && opts->not_proxiable)
- {
+ if (opts->proxiable && opts->not_proxiable) {
fprintf(stderr, _("Only one of -p and -P allowed\n"));
errflg++;
}
- if (opts->request_pac && opts->not_request_pac)
- {
+ if (opts->request_pac && opts->not_request_pac) {
fprintf(stderr, _("Only one of --request-pac and --no-request-pac "
"allowed\n"));
errflg++;
}
- if (opts->addresses && opts->no_addresses)
- {
+ if (opts->addresses && opts->no_addresses) {
fprintf(stderr, _("Only one of -a and -A allowed\n"));
errflg++;
}
- if (opts->keytab_name != NULL && opts->use_client_keytab == 1)
- {
+ if (opts->keytab_name != NULL && opts->use_client_keytab == 1) {
fprintf(stderr, _("Only one of -t and -i allowed\n"));
errflg++;
}
if ((opts->keytab_name != NULL || opts->use_client_keytab == 1) &&
- opts->action != INIT_KT)
- {
+ opts->action != INIT_KT) {
opts->action = INIT_KT;
fprintf(stderr, _("keytab specified, forcing -k\n"));
}
-
if (argc - optind > 1) {
fprintf(stderr, _("Extra arguments (starting with \"%s\").\n"),
- argv[optind+1]);
+ argv[optind + 1]);
errflg++;
}
- if (errflg) {
+ if (errflg)
usage();
- }
- opts->principal_name = (optind == argc-1) ? argv[optind] : 0;
+ opts->principal_name = (optind == argc - 1) ? argv[optind] : 0;
return opts->principal_name;
}
static int
-k5_begin(opts, k5)
- struct k_opts* opts;
- struct k5_data* k5;
+k5_begin(struct k_opts *opts, struct k5_data *k5)
{
- krb5_error_code code = 0;
+ krb5_error_code ret;
int success = 0;
int flags = opts->enterprise ? KRB5_PRINCIPAL_PARSE_ENTERPRISE : 0;
krb5_ccache defcache = NULL;
@@ -459,17 +436,17 @@ k5_begin(opts, k5)
const char *deftype = NULL;
char *defrealm, *name;
- code = krb5_init_context(&k5->ctx);
- if (code) {
- com_err(progname, code, _("while initializing Kerberos 5 library"));
+ ret = krb5_init_context(&k5->ctx);
+ if (ret) {
+ com_err(progname, ret, _("while initializing Kerberos 5 library"));
return 0;
}
errctx = k5->ctx;
if (opts->k5_out_cache_name) {
- code = krb5_cc_resolve(k5->ctx, opts->k5_out_cache_name, &k5->out_cc);
- if (code != 0) {
- com_err(progname, code, _("resolving ccache %s"),
+ ret = krb5_cc_resolve(k5->ctx, opts->k5_out_cache_name, &k5->out_cc);
+ if (ret) {
+ com_err(progname, ret, _("resolving ccache %s"),
opts->k5_out_cache_name);
goto cleanup;
}
@@ -480,9 +457,9 @@ k5_begin(opts, k5)
} else {
/* Resolve the default ccache and get its type and default principal
* (if it is initialized). */
- code = krb5_cc_default(k5->ctx, &defcache);
- if (code) {
- com_err(progname, code, _("while getting default ccache"));
+ ret = krb5_cc_default(k5->ctx, &defcache);
+ if (ret) {
+ com_err(progname, ret, _("while getting default ccache"));
goto cleanup;
}
deftype = krb5_cc_get_type(k5->ctx, defcache);
@@ -493,59 +470,58 @@ k5_begin(opts, k5)
/* Choose a client principal name. */
if (opts->principal_name != NULL) {
/* Use the specified principal name. */
- code = krb5_parse_name_flags(k5->ctx, opts->principal_name, flags,
- &k5->me);
- if (code) {
- com_err(progname, code, _("when parsing name %s"),
+ ret = krb5_parse_name_flags(k5->ctx, opts->principal_name, flags,
+ &k5->me);
+ if (ret) {
+ com_err(progname, ret, _("when parsing name %s"),
opts->principal_name);
goto cleanup;
}
} else if (opts->anonymous) {
/* Use the anonymous principal for the local realm. */
- code = krb5_get_default_realm(k5->ctx, &defrealm);
- if (code) {
- com_err(progname, code, _("while getting default realm"));
+ ret = krb5_get_default_realm(k5->ctx, &defrealm);
+ if (ret) {
+ com_err(progname, ret, _("while getting default realm"));
goto cleanup;
}
- code = krb5_build_principal_ext(k5->ctx, &k5->me,
- strlen(defrealm), defrealm,
- strlen(KRB5_WELLKNOWN_NAMESTR),
- KRB5_WELLKNOWN_NAMESTR,
- strlen(KRB5_ANONYMOUS_PRINCSTR),
- KRB5_ANONYMOUS_PRINCSTR,
- 0);
+ ret = krb5_build_principal_ext(k5->ctx, &k5->me,
+ strlen(defrealm), defrealm,
+ strlen(KRB5_WELLKNOWN_NAMESTR),
+ KRB5_WELLKNOWN_NAMESTR,
+ strlen(KRB5_ANONYMOUS_PRINCSTR),
+ KRB5_ANONYMOUS_PRINCSTR, 0);
krb5_free_default_realm(k5->ctx, defrealm);
- if (code) {
- com_err(progname, code, _("while building principal"));
+ if (ret) {
+ com_err(progname, ret, _("while building principal"));
goto cleanup;
}
} else if (opts->action == INIT_KT && opts->use_client_keytab) {
/* Use the first entry from the client keytab. */
- code = krb5_kt_client_default(k5->ctx, &keytab);
- if (code) {
- com_err(progname, code,
+ ret = krb5_kt_client_default(k5->ctx, &keytab);
+ if (ret) {
+ com_err(progname, ret,
_("When resolving the default client keytab"));
goto cleanup;
}
- code = k5_kt_get_principal(k5->ctx, keytab, &k5->me);
+ ret = k5_kt_get_principal(k5->ctx, keytab, &k5->me);
krb5_kt_close(k5->ctx, keytab);
- if (code) {
- com_err(progname, code,
+ if (ret) {
+ com_err(progname, ret,
_("When determining client principal name from keytab"));
goto cleanup;
}
} else if (opts->action == INIT_KT) {
/* Use the default host/service name. */
- code = krb5_sname_to_principal(k5->ctx, NULL, NULL, KRB5_NT_SRV_HST,
- &k5->me);
- if (code) {
- com_err(progname, code,
+ ret = krb5_sname_to_principal(k5->ctx, NULL, NULL, KRB5_NT_SRV_HST,
+ &k5->me);
+ if (ret) {
+ com_err(progname, ret,
_("when creating default server principal name"));
goto cleanup;
}
if (k5->me->realm.data[0] == 0) {
- code = krb5_unparse_name(k5->ctx, k5->me, &k5->name);
- if (code == 0) {
+ ret = krb5_unparse_name(k5->ctx, k5->me, &k5->name);
+ if (ret == 0) {
com_err(progname, KRB5_ERR_HOST_REALM_UNKNOWN,
_("(principal %s)"), k5->name);
} else {
@@ -574,23 +550,22 @@ k5_begin(opts, k5)
fprintf(stderr, _("Unable to identify user\n"));
goto cleanup;
}
- code = krb5_parse_name_flags(k5->ctx, name, flags, &k5->me);
- if (code) {
- com_err(progname, code, _("when parsing name %s"),
- name);
+ ret = krb5_parse_name_flags(k5->ctx, name, flags, &k5->me);
+ if (ret) {
+ com_err(progname, ret, _("when parsing name %s"), name);
goto cleanup;
}
}
if (k5->out_cc == NULL && krb5_cc_support_switch(k5->ctx, deftype)) {
/* Use an existing cache for the client principal if we can. */
- code = krb5_cc_cache_match(k5->ctx, k5->me, &k5->out_cc);
- if (code != 0 && code != KRB5_CC_NOTFOUND) {
- com_err(progname, code, _("while searching for ccache for %s"),
+ ret = krb5_cc_cache_match(k5->ctx, k5->me, &k5->out_cc);
+ if (ret && ret != KRB5_CC_NOTFOUND) {
+ com_err(progname, ret, _("while searching for ccache for %s"),
opts->principal_name);
goto cleanup;
}
- if (code == 0) {
+ if (!ret) {
if (opts->verbose) {
fprintf(stderr, _("Using existing cache: %s\n"),
krb5_cc_get_name(k5->ctx, k5->out_cc));
@@ -599,9 +574,9 @@ k5_begin(opts, k5)
} else if (defcache_princ != NULL) {
/* Create a new cache to avoid overwriting the initialized default
* cache. */
- code = krb5_cc_new_unique(k5->ctx, deftype, NULL, &k5->out_cc);
- if (code) {
- com_err(progname, code, _("while generating new ccache"));
+ ret = krb5_cc_new_unique(k5->ctx, deftype, NULL, &k5->out_cc);
+ if (ret) {
+ com_err(progname, ret, _("while generating new ccache"));
goto cleanup;
}
if (opts->verbose) {
@@ -623,9 +598,9 @@ k5_begin(opts, k5)
}
if (opts->k5_in_cache_name) {
- code = krb5_cc_resolve(k5->ctx, opts->k5_in_cache_name, &k5->in_cc);
- if (code != 0) {
- com_err(progname, code, _("resolving ccache %s"),
+ ret = krb5_cc_resolve(k5->ctx, opts->k5_in_cache_name, &k5->in_cc);
+ if (ret) {
+ com_err(progname, ret, _("resolving ccache %s"),
opts->k5_in_cache_name);
goto cleanup;
}
@@ -635,10 +610,9 @@ k5_begin(opts, k5)
}
}
-
- code = krb5_unparse_name(k5->ctx, k5->me, &k5->name);
- if (code) {
- com_err(progname, code, _("when unparsing name"));
+ ret = krb5_unparse_name(k5->ctx, k5->me, &k5->name);
+ if (ret) {
+ com_err(progname, ret, _("when unparsing name"));
goto cleanup;
}
if (opts->verbose)
@@ -656,33 +630,22 @@ cleanup:
}
static void
-k5_end(k5)
- struct k5_data* k5;
+k5_end(struct k5_data *k5)
{
- if (k5->name)
- krb5_free_unparsed_name(k5->ctx, k5->name);
- if (k5->me)
- krb5_free_principal(k5->ctx, k5->me);
- if (k5->in_cc)
+ krb5_free_unparsed_name(k5->ctx, k5->name);
+ krb5_free_principal(k5->ctx, k5->me);
+ if (k5->in_cc != NULL)
krb5_cc_close(k5->ctx, k5->in_cc);
- if (k5->out_cc)
+ if (k5->out_cc != NULL)
krb5_cc_close(k5->ctx, k5->out_cc);
- if (k5->ctx)
- krb5_free_context(k5->ctx);
+ krb5_free_context(k5->ctx);
errctx = NULL;
memset(k5, 0, sizeof(*k5));
}
-static krb5_error_code
-KRB5_CALLCONV
-kinit_prompter(
- krb5_context ctx,
- void *data,
- const char *name,
- const char *banner,
- int num_prompts,
- krb5_prompt prompts[]
-)
+static krb5_error_code KRB5_CALLCONV
+kinit_prompter(krb5_context ctx, void *data, const char *name,
+ const char *banner, int num_prompts, krb5_prompt prompts[])
{
krb5_boolean *pwprompt = data;
krb5_prompt_type *ptypes;
@@ -694,34 +657,27 @@ kinit_prompter(
if (ptypes != NULL && ptypes[i] == KRB5_PROMPT_TYPE_PASSWORD)
*pwprompt = TRUE;
}
-
return krb5_prompter_posix(ctx, data, name, banner, num_prompts, prompts);
}
static int
-k5_kinit(opts, k5)
- struct k_opts* opts;
- struct k5_data* k5;
+k5_kinit(struct k_opts *opts, struct k5_data *k5)
{
int notix = 1;
krb5_keytab keytab = 0;
krb5_creds my_creds;
- krb5_error_code code = 0;
+ krb5_error_code ret;
krb5_get_init_creds_opt *options = NULL;
krb5_boolean pwprompt = FALSE;
+ krb5_address **addresses = NULL;
int i;
memset(&my_creds, 0, sizeof(my_creds));
- code = krb5_get_init_creds_opt_alloc(k5->ctx, &options);
- if (code)
+ ret = krb5_get_init_creds_opt_alloc(k5->ctx, &options);
+ if (ret)
goto cleanup;
- /*
- From this point on, we can goto cleanup because my_creds is
- initialized.
- */
-
if (opts->lifetime)
krb5_get_init_creds_opt_set_tkt_life(options, opts->lifetime);
if (opts->rlife)
@@ -738,63 +694,61 @@ k5_kinit(opts, k5)
krb5_get_init_creds_opt_set_canonicalize(options, 1);
if (opts->anonymous)
krb5_get_init_creds_opt_set_anonymous(options, 1);
- if (opts->addresses)
- {
- krb5_address **addresses = NULL;
- code = krb5_os_localaddr(k5->ctx, &addresses);
- if (code != 0) {
- com_err(progname, code, _("getting local addresses"));
+ if (opts->addresses) {
+ ret = krb5_os_localaddr(k5->ctx, &addresses);
+ if (ret) {
+ com_err(progname, ret, _("getting local addresses"));
goto cleanup;
}
krb5_get_init_creds_opt_set_address_list(options, addresses);
}
if (opts->no_addresses)
krb5_get_init_creds_opt_set_address_list(options, NULL);
- if (opts->armor_ccache)
- krb5_get_init_creds_opt_set_fast_ccache_name(k5->ctx, options, opts->armor_ccache);
+ if (opts->armor_ccache != NULL) {
+ krb5_get_init_creds_opt_set_fast_ccache_name(k5->ctx, options,
+ opts->armor_ccache);
+ }
if (opts->request_pac)
krb5_get_init_creds_opt_set_pac_request(k5->ctx, options, TRUE);
if (opts->not_request_pac)
krb5_get_init_creds_opt_set_pac_request(k5->ctx, options, FALSE);
- if ((opts->action == INIT_KT) && opts->keytab_name)
- {
+ if (opts->action == INIT_KT && opts->keytab_name != NULL) {
#ifndef _WIN32
if (strncmp(opts->keytab_name, "KDB:", 4) == 0) {
- code = kinit_kdb_init(&k5->ctx,
- krb5_princ_realm(k5->ctx, k5->me)->data);
- if (code != 0) {
- com_err(progname, code,
+ ret = kinit_kdb_init(&k5->ctx, k5->me->realm.data);
+ if (ret) {
+ com_err(progname, ret,
_("while setting up KDB keytab for realm %s"),
- krb5_princ_realm(k5->ctx, k5->me)->data);
+ k5->me->realm.data);
goto cleanup;
}
}
#endif
- code = krb5_kt_resolve(k5->ctx, opts->keytab_name, &keytab);
- if (code != 0) {
- com_err(progname, code, _("resolving keytab %s"),
+ ret = krb5_kt_resolve(k5->ctx, opts->keytab_name, &keytab);
+ if (ret) {
+ com_err(progname, ret, _("resolving keytab %s"),
opts->keytab_name);
goto cleanup;
}
if (opts->verbose)
fprintf(stderr, _("Using keytab: %s\n"), opts->keytab_name);
} else if (opts->action == INIT_KT && opts->use_client_keytab) {
- code = krb5_kt_client_default(k5->ctx, &keytab);
- if (code != 0) {
- com_err(progname, code, _("resolving default client keytab"));
+ ret = krb5_kt_client_default(k5->ctx, &keytab);
+ if (ret) {
+ com_err(progname, ret, _("resolving default client keytab"));
goto cleanup;
}
}
for (i = 0; i < opts->num_pa_opts; i++) {
- code = krb5_get_init_creds_opt_set_pa(k5->ctx, options,
- opts->pa_opts[i].attr,
- opts->pa_opts[i].value);
- if (code != 0) {
- com_err(progname, code, _("while setting '%s'='%s'"),
+ ret = krb5_get_init_creds_opt_set_pa(k5->ctx, options,
+ opts->pa_opts[i].attr,
+ opts->pa_opts[i].value);
+ if (ret) {
+ com_err(progname, ret, _("while setting '%s'='%s'"),
opts->pa_opts[i].attr, opts->pa_opts[i].value);
goto cleanup;
}
@@ -804,43 +758,39 @@ k5_kinit(opts, k5)
}
}
if (k5->in_cc) {
- code = krb5_get_init_creds_opt_set_in_ccache(k5->ctx, options,
- k5->in_cc);
- if (code)
+ ret = krb5_get_init_creds_opt_set_in_ccache(k5->ctx, options,
+ k5->in_cc);
+ if (ret)
goto cleanup;
}
- code = krb5_get_init_creds_opt_set_out_ccache(k5->ctx, options,
- k5->out_cc);
- if (code)
+ ret = krb5_get_init_creds_opt_set_out_ccache(k5->ctx, options, k5->out_cc);
+ if (ret)
goto cleanup;
switch (opts->action) {
case INIT_PW:
- code = krb5_get_init_creds_password(k5->ctx, &my_creds, k5->me,
- 0, kinit_prompter, &pwprompt,
- opts->starttime,
- opts->service_name,
- options);
+ ret = krb5_get_init_creds_password(k5->ctx, &my_creds, k5->me, 0,
+ kinit_prompter, &pwprompt,
+ opts->starttime, opts->service_name,
+ options);
break;
case INIT_KT:
- code = krb5_get_init_creds_keytab(k5->ctx, &my_creds, k5->me,
- keytab,
- opts->starttime,
- opts->service_name,
- options);
+ ret = krb5_get_init_creds_keytab(k5->ctx, &my_creds, k5->me, keytab,
+ opts->starttime, opts->service_name,
+ options);
break;
case VALIDATE:
- code = krb5_get_validated_creds(k5->ctx, &my_creds, k5->me, k5->out_cc,
- opts->service_name);
+ ret = krb5_get_validated_creds(k5->ctx, &my_creds, k5->me, k5->out_cc,
+ opts->service_name);
break;
case RENEW:
- code = krb5_get_renewed_creds(k5->ctx, &my_creds, k5->me, k5->out_cc,
- opts->service_name);
+ ret = krb5_get_renewed_creds(k5->ctx, &my_creds, k5->me, k5->out_cc,
+ opts->service_name);
break;
}
- if (code) {
- char *doing = 0;
+ if (ret) {
+ char *doing = NULL;
switch (opts->action) {
case INIT_PW:
case INIT_KT:
@@ -856,41 +806,40 @@ k5_kinit(opts, k5)
/* If reply decryption failed, or if pre-authentication failed and we
* were prompted for a password, assume the password was wrong. */
- if (code == KRB5KRB_AP_ERR_BAD_INTEGRITY ||
- (pwprompt && code == KRB5KDC_ERR_PREAUTH_FAILED)) {
+ if (ret == KRB5KRB_AP_ERR_BAD_INTEGRITY ||
+ (pwprompt && ret == KRB5KDC_ERR_PREAUTH_FAILED)) {
fprintf(stderr, _("%s: Password incorrect while %s\n"), progname,
doing);
} else {
- com_err(progname, code, _("while %s"), doing);
+ com_err(progname, ret, _("while %s"), doing);
}
goto cleanup;
}
- if ((opts->action != INIT_PW) && (opts->action != INIT_KT)) {
- code = krb5_cc_initialize(k5->ctx, k5->out_cc, opts->canonicalize ?
- my_creds.client : k5->me);
- if (code) {
- com_err(progname, code, _("when initializing cache %s"),
- opts->k5_out_cache_name?opts->k5_out_cache_name:"");
+ if (opts->action != INIT_PW && opts->action != INIT_KT) {
+ ret = krb5_cc_initialize(k5->ctx, k5->out_cc, opts->canonicalize ?
+ my_creds.client : k5->me);
+ if (ret) {
+ com_err(progname, ret, _("when initializing cache %s"),
+ opts->k5_out_cache_name ? opts->k5_out_cache_name : "");
goto cleanup;
}
if (opts->verbose)
fprintf(stderr, _("Initialized cache\n"));
- code = krb5_cc_store_cred(k5->ctx, k5->out_cc, &my_creds);
- if (code) {
- com_err(progname, code, _("while storing credentials"));
+ ret = krb5_cc_store_cred(k5->ctx, k5->out_cc, &my_creds);
+ if (ret) {
+ com_err(progname, ret, _("while storing credentials"));
goto cleanup;
}
if (opts->verbose)
fprintf(stderr, _("Stored credentials\n"));
}
notix = 0;
-
if (k5->switch_to_cache) {
- code = krb5_cc_switch(k5->ctx, k5->out_cc);
- if (code) {
- com_err(progname, code, _("while switching to new ccache"));
+ ret = krb5_cc_switch(k5->ctx, k5->out_cc);
+ if (ret) {
+ com_err(progname, ret, _("while switching to new ccache"));
goto cleanup;
}
}
@@ -901,24 +850,21 @@ cleanup:
#endif
if (options)
krb5_get_init_creds_opt_free(k5->ctx, options);
- if (my_creds.client == k5->me) {
+ if (my_creds.client == k5->me)
my_creds.client = 0;
- }
if (opts->pa_opts) {
free(opts->pa_opts);
opts->pa_opts = NULL;
opts->num_pa_opts = 0;
}
krb5_free_cred_contents(k5->ctx, &my_creds);
- if (keytab)
+ if (keytab != NULL)
krb5_kt_close(k5->ctx, keytab);
- return notix?0:1;
+ return notix ? 0 : 1;
}
int
-main(argc, argv)
- int argc;
- char **argv;
+main(int argc, char *argv[])
{
struct k_opts opts;
struct k5_data k5;
@@ -928,11 +874,11 @@ main(argc, argv)
progname = GET_PROGNAME(argv[0]);
/* Ensure we can be driven from a pipe */
- if(!isatty(fileno(stdin)))
+ if (!isatty(fileno(stdin)))
setvbuf(stdin, 0, _IONBF, 0);
- if(!isatty(fileno(stdout)))
+ if (!isatty(fileno(stdout)))
setvbuf(stdout, 0, _IONBF, 0);
- if(!isatty(fileno(stderr)))
+ if (!isatty(fileno(stderr)))
setvbuf(stderr, 0, _IONBF, 0);
memset(&opts, 0, sizeof(opts));
@@ -940,7 +886,7 @@ main(argc, argv)
memset(&k5, 0, sizeof(k5));
- set_com_err_hook (extended_com_err_fn);
+ set_com_err_hook(extended_com_err_fn);
parse_options(argc, argv, &opts);
diff --git a/src/clients/kinit/kinit_kdb.c b/src/clients/kinit/kinit_kdb.c
index 47baf9010a7b..fbd174bf0c45 100644
--- a/src/clients/kinit/kinit_kdb.c
+++ b/src/clients/kinit/kinit_kdb.c
@@ -36,38 +36,36 @@
#include <kdb.h>
#include "extern.h"
-/** Server handle */
+/* Server handle */
static void *server_handle;
-/**
- * @internal Initialize KDB for given realm
- * @param context pointer to context that will be re-initialized
- * @@param realm name of realm to initialize
- */
+/* Free and reinitialize *pcontext with the KDB opened to the given realm, so
+ * that it can be used with the KDB keytab type. */
krb5_error_code
kinit_kdb_init(krb5_context *pcontext, char *realm)
{
kadm5_config_params config;
- krb5_error_code retval = 0;
+ krb5_error_code ret;
if (*pcontext) {
krb5_free_context(*pcontext);
*pcontext = NULL;
}
memset(&config, 0, sizeof config);
- retval = kadm5_init_krb5_context(pcontext);
- if (retval)
- return retval;
+
+ ret = kadm5_init_krb5_context(pcontext);
+ if (ret)
+ return ret;
+
config.mask = KADM5_CONFIG_REALM;
config.realm = realm;
- retval = kadm5_init(*pcontext, "kinit", NULL /*pass*/,
- "kinit", &config,
- KADM5_STRUCT_VERSION, KADM5_API_VERSION_4, NULL,
- &server_handle);
- if (retval)
- return retval;
- retval = krb5_db_register_keytab(*pcontext);
- return retval;
+ ret = kadm5_init(*pcontext, "kinit", NULL, "kinit", &config,
+ KADM5_STRUCT_VERSION, KADM5_API_VERSION_4, NULL,
+ &server_handle);
+ if (ret)
+ return ret;
+
+ return krb5_db_register_keytab(*pcontext);
}
void
diff --git a/src/clients/klist/klist.c b/src/clients/klist/klist.c
index ba19788a25c4..e9e76d8f3be6 100644
--- a/src/clients/klist/klist.c
+++ b/src/clients/klist/klist.c
@@ -32,13 +32,14 @@
#include <string.h>
#include <stdio.h>
#include <time.h>
+
/* Need definition of INET6 before network headers, for IRIX. */
#if defined(HAVE_ARPA_INET_H)
#include <arpa/inet.h>
#endif
#ifndef _WIN32
-#define GET_PROGNAME(x) (strrchr((x), '/') ? strrchr((x), '/')+1 : (x))
+#define GET_PROGNAME(x) (strrchr((x), '/') ? strrchr((x), '/') + 1 : (x))
#else
#define GET_PROGNAME(x) max(max(strrchr((x), '/'), strrchr((x), '\\')) + 1,(x))
#endif
@@ -56,34 +57,33 @@ int show_adtype = 0, show_all = 0, list_all = 0, use_client_keytab = 0;
int show_config = 0;
char *defname;
char *progname;
-krb5_int32 now;
+krb5_timestamp now;
unsigned int timestamp_width;
-krb5_context kcontext;
+krb5_context context;
-krb5_boolean is_local_tgt (krb5_principal princ, krb5_data *realm);
-char * etype_string (krb5_enctype );
-void show_credential (krb5_creds *);
+static krb5_boolean is_local_tgt(krb5_principal princ, krb5_data *realm);
+static char *etype_string(krb5_enctype );
+static void show_credential(krb5_creds *);
-void list_all_ccaches (void);
-int list_ccache (krb5_ccache);
-void show_all_ccaches (void);
-void do_ccache_name (char *);
-int show_ccache (krb5_ccache);
-int check_ccache (krb5_ccache);
-void do_keytab (char *);
-void printtime (time_t);
-void one_addr (krb5_address *);
-void fillit (FILE *, unsigned int, int);
+static void list_all_ccaches(void);
+static int list_ccache(krb5_ccache);
+static void show_all_ccaches(void);
+static void do_ccache(void);
+static int show_ccache(krb5_ccache);
+static int check_ccache(krb5_ccache);
+static void do_keytab(const char *);
+static void printtime(krb5_timestamp);
+static void one_addr(krb5_address *);
+static void fillit(FILE *, unsigned int, int);
#define DEFAULT 0
#define CCACHE 1
#define KEYTAB 2
-static void usage()
+static void
+usage()
{
-#define KRB_AVAIL_STRING(x) ((x)?"available":"not available")
-
fprintf(stderr, _("Usage: %s [-e] [-V] [[-c] [-l] [-A] [-d] [-f] [-s] "
"[-a [-n]]] [-k [-t] [-K]] [name]\n"), progname);
fprintf(stderr, _("\t-c specifies credentials cache\n"));
@@ -114,21 +114,19 @@ extended_com_err_fn(const char *prog, errcode_t code, const char *fmt,
{
const char *msg;
- msg = krb5_get_error_message(kcontext, code);
+ msg = krb5_get_error_message(context, code);
fprintf(stderr, "%s: %s%s", prog, msg, (*fmt == '\0') ? "" : " ");
- krb5_free_error_message(kcontext, msg);
+ krb5_free_error_message(context, msg);
vfprintf(stderr, fmt, args);
fprintf(stderr, "\n");
}
int
-main(argc, argv)
- int argc;
- char **argv;
+main(int argc, char *argv[])
{
- int c;
- char *name;
- int mode;
+ krb5_error_code ret;
+ char *name, tmp[BUFSIZ];
+ int c, mode;
setlocale(LC_ALL, "");
progname = GET_PROGNAME(argv[0]);
@@ -136,7 +134,7 @@ main(argc, argv)
name = NULL;
mode = DEFAULT;
- /* V=version so v can be used for verbose later if desired. */
+ /* V = version so v can be used for verbose later if desired. */
while ((c = getopt(argc, argv, "dfetKsnacki45lAVC")) != -1) {
switch (c) {
case 'd':
@@ -164,11 +162,13 @@ main(argc, argv)
show_addresses = 1;
break;
case 'c':
- if (mode != DEFAULT) usage();
+ if (mode != DEFAULT)
+ usage();
mode = CCACHE;
break;
case 'k':
- if (mode != DEFAULT) usage();
+ if (mode != DEFAULT)
+ usage();
mode = KEYTAB;
break;
case 'i':
@@ -198,9 +198,8 @@ main(argc, argv)
}
}
- if (no_resolve && !show_addresses) {
+ if (no_resolve && !show_addresses)
usage();
- }
if (mode == DEFAULT || mode == CCACHE) {
if (show_time || show_keys)
@@ -215,7 +214,7 @@ main(argc, argv)
if (argc - optind > 1) {
fprintf(stderr, _("Extra arguments (starting with \"%s\").\n"),
- argv[optind+1]);
+ argv[optind + 1]);
usage();
}
@@ -228,77 +227,82 @@ main(argc, argv)
exit(0);
}
- name = (optind == argc-1) ? argv[optind] : 0;
-
+ name = (optind == argc - 1) ? argv[optind] : NULL;
now = time(0);
- {
- char tmp[BUFSIZ];
- if (!krb5_timestamp_to_sfstring(now, tmp, 20, (char *) NULL) ||
- !krb5_timestamp_to_sfstring(now, tmp, sizeof(tmp),
- (char *) NULL))
- timestamp_width = (int) strlen(tmp);
- else
- timestamp_width = 15;
+ if (!krb5_timestamp_to_sfstring(now, tmp, 20, NULL) ||
+ !krb5_timestamp_to_sfstring(now, tmp, sizeof(tmp), NULL))
+ timestamp_width = (int)strlen(tmp);
+ else
+ timestamp_width = 15;
+
+ ret = krb5_init_context(&context);
+ if (ret) {
+ com_err(progname, ret, _("while initializing krb5"));
+ exit(1);
}
- {
- krb5_error_code retval;
- retval = krb5_init_context(&kcontext);
- if (retval) {
- com_err(progname, retval, _("while initializing krb5"));
+ if (name != NULL && mode != KEYTAB) {
+ ret = krb5_cc_set_default_name(context, name);
+ if (ret) {
+ com_err(progname, ret, _("while setting default cache name"));
exit(1);
}
-
- if (list_all)
- list_all_ccaches();
- else if (show_all)
- show_all_ccaches();
- else if (mode == DEFAULT || mode == CCACHE)
- do_ccache_name(name);
- else
- do_keytab(name);
}
+ if (list_all)
+ list_all_ccaches();
+ else if (show_all)
+ show_all_ccaches();
+ else if (mode == DEFAULT || mode == CCACHE)
+ do_ccache();
+ else
+ do_keytab(name);
return 0;
}
-void do_keytab(name)
- char *name;
+static void
+do_keytab(const char *name)
{
+ krb5_error_code ret;
krb5_keytab kt;
krb5_keytab_entry entry;
krb5_kt_cursor cursor;
- char buf[BUFSIZ]; /* hopefully large enough for any type */
+ unsigned int i;
+ char buf[BUFSIZ]; /* Hopefully large enough for any type */
char *pname;
- int code;
if (name == NULL && use_client_keytab) {
- if ((code = krb5_kt_client_default(kcontext, &kt))) {
- com_err(progname, code, _("while getting default client keytab"));
+ ret = krb5_kt_client_default(context, &kt);
+ if (ret) {
+ com_err(progname, ret, _("while getting default client keytab"));
exit(1);
}
} else if (name == NULL) {
- if ((code = krb5_kt_default(kcontext, &kt))) {
- com_err(progname, code, _("while getting default keytab"));
+ ret = krb5_kt_default(context, &kt);
+ if (ret) {
+ com_err(progname, ret, _("while getting default keytab"));
exit(1);
}
} else {
- if ((code = krb5_kt_resolve(kcontext, name, &kt))) {
- com_err(progname, code, _("while resolving keytab %s"), name);
+ ret = krb5_kt_resolve(context, name, &kt);
+ if (ret) {
+ com_err(progname, ret, _("while resolving keytab %s"), name);
exit(1);
}
}
- if ((code = krb5_kt_get_name(kcontext, kt, buf, BUFSIZ))) {
- com_err(progname, code, _("while getting keytab name"));
+ ret = krb5_kt_get_name(context, kt, buf, BUFSIZ);
+ if (ret) {
+ com_err(progname, ret, _("while getting keytab name"));
exit(1);
}
printf("Keytab name: %s\n", buf);
- if ((code = krb5_kt_start_seq_get(kcontext, kt, &cursor))) {
- com_err(progname, code, _("while starting keytab scan"));
+ ret = krb5_kt_start_seq_get(context, kt, &cursor);
+ if (ret) {
+ com_err(progname, ret, _("while starting keytab scan"));
exit(1);
}
@@ -314,12 +318,14 @@ void do_keytab(name)
printf("\n");
} else {
printf("KVNO Principal\n");
- printf("---- --------------------------------------------------------------------------\n");
+ printf("---- ------------------------------------------------"
+ "--------------------------\n");
}
- while ((code = krb5_kt_next_entry(kcontext, kt, &entry, &cursor)) == 0) {
- if ((code = krb5_unparse_name(kcontext, entry.principal, &pname))) {
- com_err(progname, code, _("while unparsing principal name"));
+ while ((ret = krb5_kt_next_entry(context, kt, &entry, &cursor)) == 0) {
+ ret = krb5_unparse_name(context, entry.principal, &pname);
+ if (ret) {
+ com_err(progname, ret, _("while unparsing principal name"));
exit(1);
}
printf("%4d ", entry.vno);
@@ -332,40 +338,38 @@ void do_keytab(name)
printf(" (%s) " , etype_string(entry.key.enctype));
if (show_keys) {
printf(" (0x");
- {
- unsigned int i;
- for (i = 0; i < entry.key.length; i++)
- printf("%02x", entry.key.contents[i]);
- }
+ for (i = 0; i < entry.key.length; i++)
+ printf("%02x", entry.key.contents[i]);
printf(")");
}
printf("\n");
- krb5_free_unparsed_name(kcontext, pname);
- krb5_free_keytab_entry_contents(kcontext, &entry);
+ krb5_free_unparsed_name(context, pname);
+ krb5_free_keytab_entry_contents(context, &entry);
}
- if (code && code != KRB5_KT_END) {
- com_err(progname, code, _("while scanning keytab"));
+ if (ret && ret != KRB5_KT_END) {
+ com_err(progname, ret, _("while scanning keytab"));
exit(1);
}
- if ((code = krb5_kt_end_seq_get(kcontext, kt, &cursor))) {
- com_err(progname, code, _("while ending keytab scan"));
+ ret = krb5_kt_end_seq_get(context, kt, &cursor);
+ if (ret) {
+ com_err(progname, ret, _("while ending keytab scan"));
exit(1);
}
exit(0);
}
-void
-list_all_ccaches(void)
+static void
+list_all_ccaches()
{
- krb5_error_code code;
+ krb5_error_code ret;
krb5_ccache cache;
krb5_cccol_cursor cursor;
int exit_status;
- code = krb5_cccol_cursor_new(kcontext, &cursor);
- if (code) {
+ ret = krb5_cccol_cursor_new(context, &cursor);
+ if (ret) {
if (!status_only)
- com_err(progname, code, _("while listing ccache collection"));
+ com_err(progname, ret, _("while listing ccache collection"));
exit(1);
}
@@ -373,31 +377,31 @@ list_all_ccaches(void)
printf("%-30s %s\n", "Principal name", "Cache name");
printf("%-30s %s\n", "--------------", "----------");
exit_status = 1;
- while (!(code = krb5_cccol_cursor_next(kcontext, cursor, &cache)) &&
+ while ((ret = krb5_cccol_cursor_next(context, cursor, &cache)) == 0 &&
cache != NULL) {
exit_status = list_ccache(cache) && exit_status;
- krb5_cc_close(kcontext, cache);
+ krb5_cc_close(context, cache);
}
- krb5_cccol_cursor_free(kcontext, &cursor);
+ krb5_cccol_cursor_free(context, &cursor);
exit(exit_status);
}
-int
+static int
list_ccache(krb5_ccache cache)
{
- krb5_error_code code;
+ krb5_error_code ret;
krb5_principal princ = NULL;
char *princname = NULL, *ccname = NULL;
int expired, status = 1;
- code = krb5_cc_get_principal(kcontext, cache, &princ);
- if (code) /* Uninitialized cache file, probably. */
+ ret = krb5_cc_get_principal(context, cache, &princ);
+ if (ret) /* Uninitialized cache file, probably. */
goto cleanup;
- code = krb5_unparse_name(kcontext, princ, &princname);
- if (code)
+ ret = krb5_unparse_name(context, princ, &princname);
+ if (ret)
goto cleanup;
- code = krb5_cc_get_full_name(kcontext, cache, &ccname);
- if (code)
+ ret = krb5_cc_get_full_name(context, cache, &ccname);
+ if (ret)
goto cleanup;
expired = check_ccache(cache);
@@ -408,87 +412,82 @@ list_ccache(krb5_ccache cache)
printf("\n");
status = 0;
+
cleanup:
- krb5_free_principal(kcontext, princ);
- krb5_free_unparsed_name(kcontext, princname);
- krb5_free_string(kcontext, ccname);
+ krb5_free_principal(context, princ);
+ krb5_free_unparsed_name(context, princname);
+ krb5_free_string(context, ccname);
return status;
}
-void
+static void
show_all_ccaches(void)
{
- krb5_error_code code;
+ krb5_error_code ret;
krb5_ccache cache;
krb5_cccol_cursor cursor;
krb5_boolean first;
int exit_status, st;
- code = krb5_cccol_cursor_new(kcontext, &cursor);
- if (code) {
+ ret = krb5_cccol_cursor_new(context, &cursor);
+ if (ret) {
if (!status_only)
- com_err(progname, code, _("while listing ccache collection"));
+ com_err(progname, ret, _("while listing ccache collection"));
exit(1);
}
exit_status = 1;
first = TRUE;
- while (!(code = krb5_cccol_cursor_next(kcontext, cursor, &cache)) &&
+ while ((ret = krb5_cccol_cursor_next(context, cursor, &cache)) == 0 &&
cache != NULL) {
if (!status_only && !first)
printf("\n");
first = FALSE;
st = status_only ? check_ccache(cache) : show_ccache(cache);
exit_status = st && exit_status;
- krb5_cc_close(kcontext, cache);
+ krb5_cc_close(context, cache);
}
- krb5_cccol_cursor_free(kcontext, &cursor);
+ krb5_cccol_cursor_free(context, &cursor);
exit(exit_status);
}
-void
-do_ccache_name(char *name)
+static void
+do_ccache()
{
- krb5_error_code code;
+ krb5_error_code ret;
krb5_ccache cache;
- if (name == NULL) {
- if ((code = krb5_cc_default(kcontext, &cache))) {
- if (!status_only)
- com_err(progname, code, _("while getting default ccache"));
- exit(1);
- }
- } else {
- if ((code = krb5_cc_resolve(kcontext, name, &cache))) {
- if (!status_only)
- com_err(progname, code, _("while resolving ccache %s"),
- name);
- exit(1);
- }
+ ret = krb5_cc_default(context, &cache);
+ if (ret) {
+ if (!status_only)
+ com_err(progname, ret, _("while resolving ccache"));
+ exit(1);
}
exit(status_only ? check_ccache(cache) : show_ccache(cache));
}
/* Display the contents of cache. */
-int
+static int
show_ccache(krb5_ccache cache)
{
krb5_cc_cursor cur;
krb5_creds creds;
krb5_principal princ;
- krb5_error_code code;
+ krb5_error_code ret;
- if ((code = krb5_cc_get_principal(kcontext, cache, &princ))) {
- com_err(progname, code, "");
+ ret = krb5_cc_get_principal(context, cache, &princ);
+ if (ret) {
+ com_err(progname, ret, "");
return 1;
}
- if ((code = krb5_unparse_name(kcontext, princ, &defname))) {
- com_err(progname, code, _("while unparsing principal name"));
+ ret = krb5_unparse_name(context, princ, &defname);
+ if (ret) {
+ com_err(progname, ret, _("while unparsing principal name"));
return 1;
}
printf(_("Ticket cache: %s:%s\nDefault principal: %s\n\n"),
- krb5_cc_get_type(kcontext, cache),
- krb5_cc_get_name(kcontext, cache), defname);
+ krb5_cc_get_type(context, cache), krb5_cc_get_name(context, cache),
+ defname);
/* XXX Translating would disturb table alignment; skip for now. */
fputs("Valid starting", stdout);
fillit(stdout, timestamp_width - sizeof("Valid starting") + 3, (int) ' ');
@@ -496,32 +495,34 @@ show_ccache(krb5_ccache cache)
fillit(stdout, timestamp_width - sizeof("Expires") + 3, (int) ' ');
fputs("Service principal\n", stdout);
- if ((code = krb5_cc_start_seq_get(kcontext, cache, &cur))) {
- com_err(progname, code, _("while starting to retrieve tickets"));
+ ret = krb5_cc_start_seq_get(context, cache, &cur);
+ if (ret) {
+ com_err(progname, ret, _("while starting to retrieve tickets"));
return 1;
}
- while (!(code = krb5_cc_next_cred(kcontext, cache, &cur, &creds))) {
- if (show_config || !krb5_is_config_principal(kcontext, creds.server))
+ while ((ret = krb5_cc_next_cred(context, cache, &cur, &creds)) == 0) {
+ if (show_config || !krb5_is_config_principal(context, creds.server))
show_credential(&creds);
- krb5_free_cred_contents(kcontext, &creds);
+ krb5_free_cred_contents(context, &creds);
}
- krb5_free_principal(kcontext, princ);
- krb5_free_unparsed_name(kcontext, defname);
+ krb5_free_principal(context, princ);
+ krb5_free_unparsed_name(context, defname);
defname = NULL;
- if (code == KRB5_CC_END) {
- if ((code = krb5_cc_end_seq_get(kcontext, cache, &cur))) {
- com_err(progname, code, _("while finishing ticket retrieval"));
+ if (ret == KRB5_CC_END) {
+ ret = krb5_cc_end_seq_get(context, cache, &cur);
+ if (ret) {
+ com_err(progname, ret, _("while finishing ticket retrieval"));
return 1;
}
return 0;
} else {
- com_err(progname, code, _("while retrieving a ticket"));
+ com_err(progname, ret, _("while retrieving a ticket"));
return 1;
}
}
/* Return 0 if cache is accessible, present, and unexpired; return 1 if not. */
-int
+static int
check_ccache(krb5_ccache cache)
{
krb5_error_code ret;
@@ -530,26 +531,26 @@ check_ccache(krb5_ccache cache)
krb5_principal princ;
krb5_boolean found_tgt, found_current_tgt, found_current_cred;
- if (krb5_cc_get_principal(kcontext, cache, &princ) != 0)
+ if (krb5_cc_get_principal(context, cache, &princ) != 0)
return 1;
- if (krb5_cc_start_seq_get(kcontext, cache, &cur) != 0)
+ if (krb5_cc_start_seq_get(context, cache, &cur) != 0)
return 1;
found_tgt = found_current_tgt = found_current_cred = FALSE;
- while (!(ret = krb5_cc_next_cred(kcontext, cache, &cur, &creds))) {
+ while ((ret = krb5_cc_next_cred(context, cache, &cur, &creds)) == 0) {
if (is_local_tgt(creds.server, &princ->realm)) {
found_tgt = TRUE;
- if (creds.times.endtime > now)
+ if (ts_after(creds.times.endtime, now))
found_current_tgt = TRUE;
- } else if (!krb5_is_config_principal(kcontext, creds.server) &&
- creds.times.endtime > now) {
+ } else if (!krb5_is_config_principal(context, creds.server) &&
+ ts_after(creds.times.endtime, now)) {
found_current_cred = TRUE;
}
- krb5_free_cred_contents(kcontext, &creds);
+ krb5_free_cred_contents(context, &creds);
}
- krb5_free_principal(kcontext, princ);
+ krb5_free_principal(context, princ);
if (ret != KRB5_CC_END)
return 1;
- if (krb5_cc_end_seq_get(kcontext, cache, &cur) != 0)
+ if (krb5_cc_end_seq_get(context, cache, &cur) != 0)
return 1;
/* If the cache contains at least one local TGT, require that it be
@@ -560,7 +561,7 @@ check_ccache(krb5_ccache cache)
}
/* Return true if princ is the local krbtgt principal for local_realm. */
-krb5_boolean
+static krb5_boolean
is_local_tgt(krb5_principal princ, krb5_data *realm)
{
return princ->length == 2 && data_eq(princ->realm, *realm) &&
@@ -568,24 +569,20 @@ is_local_tgt(krb5_principal princ, krb5_data *realm)
data_eq(princ->data[1], *realm);
}
-char *
-etype_string(enctype)
- krb5_enctype enctype;
+static char *
+etype_string(krb5_enctype enctype)
{
static char buf[100];
- krb5_error_code retval;
+ krb5_error_code ret;
- if ((retval = krb5_enctype_to_name(enctype, FALSE, buf, sizeof(buf)))) {
- /* XXX if there's an error != EINVAL, I should probably report it */
+ ret = krb5_enctype_to_name(enctype, FALSE, buf, sizeof(buf));
+ if (ret)
snprintf(buf, sizeof(buf), "etype %d", enctype);
- }
-
return buf;
}
static char *
-flags_string(cred)
- register krb5_creds *cred;
+flags_string(krb5_creds *cred)
{
static char buf[32];
int i = 0;
@@ -615,27 +612,21 @@ flags_string(cred)
if (cred->ticket_flags & TKT_FLG_TRANSIT_POLICY_CHECKED)
buf[i++] = 'T';
if (cred->ticket_flags & TKT_FLG_OK_AS_DELEGATE)
- buf[i++] = 'O'; /* D/d are taken. Use short strings? */
+ buf[i++] = 'O'; /* D/d are taken. Use short strings? */
if (cred->ticket_flags & TKT_FLG_ANONYMOUS)
buf[i++] = 'a';
buf[i] = '\0';
- return(buf);
+ return buf;
}
-void
-printtime(tv)
- time_t tv;
+static void
+printtime(krb5_timestamp ts)
{
- char timestring[BUFSIZ];
- char fill;
-
- fill = ' ';
- if (!krb5_timestamp_to_sfstring((krb5_timestamp) tv,
- timestring,
- timestamp_width+1,
- &fill)) {
+ char timestring[BUFSIZ], fill = ' ';
+
+ if (!krb5_timestamp_to_sfstring(ts, timestring, timestamp_width + 1,
+ &fill))
printf("%s", timestring);
- }
}
static void
@@ -663,35 +654,35 @@ print_config_data(int col, krb5_data *data)
putchar('\n');
}
-void
-show_credential(cred)
- register krb5_creds * cred;
+static void
+show_credential(krb5_creds *cred)
{
- krb5_error_code retval;
+ krb5_error_code ret;
krb5_ticket *tkt;
char *name, *sname, *flags;
int extra_field = 0, ccol = 0, i;
- retval = krb5_unparse_name(kcontext, cred->client, &name);
- if (retval) {
- com_err(progname, retval, _("while unparsing client name"));
+ ret = krb5_unparse_name(context, cred->client, &name);
+ if (ret) {
+ com_err(progname, ret, _("while unparsing client name"));
return;
}
- retval = krb5_unparse_name(kcontext, cred->server, &sname);
- if (retval) {
- com_err(progname, retval, _("while unparsing server name"));
- krb5_free_unparsed_name(kcontext, name);
+ ret = krb5_unparse_name(context, cred->server, &sname);
+ if (ret) {
+ com_err(progname, ret, _("while unparsing server name"));
+ krb5_free_unparsed_name(context, name);
return;
}
if (!cred->times.starttime)
cred->times.starttime = cred->times.authtime;
- if (!krb5_is_config_principal(kcontext, cred->server)) {
+ if (!krb5_is_config_principal(context, cred->server)) {
printtime(cred->times.starttime);
- putchar(' '); putchar(' ');
+ putchar(' ');
+ putchar(' ');
printtime(cred->times.endtime);
- putchar(' '); putchar(' ');
-
+ putchar(' ');
+ putchar(' ');
printf("%s\n", sname);
} else {
fputs("config: ", stdout);
@@ -712,7 +703,7 @@ show_credential(cred)
extra_field++;
}
- if (krb5_is_config_principal(kcontext, cred->server))
+ if (krb5_is_config_principal(context, cred->server))
print_config_data(ccol, &cred->ticket);
if (cred->times.renew_till) {
@@ -748,8 +739,8 @@ show_credential(cred)
}
if (show_etype) {
- retval = krb5_decode_ticket(&cred->ticket, &tkt);
- if (retval)
+ ret = krb5_decode_ticket(&cred->ticket, &tkt);
+ if (ret)
goto err_tkt;
if (!extra_field)
@@ -758,13 +749,12 @@ show_credential(cred)
fputs(", ",stdout);
printf(_("Etype (skey, tkt): %s, "),
etype_string(cred->keyblock.enctype));
- printf("%s ",
- etype_string(tkt->enc_part.enctype));
+ printf("%s ", etype_string(tkt->enc_part.enctype));
extra_field++;
err_tkt:
if (tkt != NULL)
- krb5_free_ticket(kcontext, tkt);
+ krb5_free_ticket(context, tkt);
}
if (show_adtype) {
@@ -783,19 +773,18 @@ show_credential(cred)
}
}
- /* if any additional info was printed, extra_field is non-zero */
+ /* If any additional info was printed, extra_field is non-zero. */
if (extra_field)
putchar('\n');
-
if (show_addresses) {
- if (!cred->addresses || !cred->addresses[0]) {
+ if (cred->addresses == NULL || cred->addresses[0] == NULL) {
printf(_("\tAddresses: (none)\n"));
} else {
printf(_("\tAddresses: "));
one_addr(cred->addresses[0]);
- for (i=1; cred->addresses[i]; i++) {
+ for (i = 1; cred->addresses[i] != NULL; i++) {
printf(", ");
one_addr(cred->addresses[i]);
}
@@ -804,45 +793,45 @@ show_credential(cred)
}
}
- krb5_free_unparsed_name(kcontext, name);
- krb5_free_unparsed_name(kcontext, sname);
+ krb5_free_unparsed_name(context, name);
+ krb5_free_unparsed_name(context, sname);
}
#include "port-sockets.h"
-#include "socket-utils.h" /* for ss2sin etc */
+#include "socket-utils.h" /* For ss2sin etc. */
#include "fake-addrinfo.h"
-void one_addr(a)
- krb5_address *a;
+static void
+one_addr(krb5_address *a)
{
struct sockaddr_storage ss;
+ struct sockaddr_in *sinp;
+ struct sockaddr_in6 *sin6p;
int err;
char namebuf[NI_MAXHOST];
- memset (&ss, 0, sizeof (ss));
+ memset(&ss, 0, sizeof(ss));
switch (a->addrtype) {
case ADDRTYPE_INET:
if (a->length != 4) {
- broken:
printf(_("broken address (type %d length %d)"),
a->addrtype, a->length);
return;
}
- {
- struct sockaddr_in *sinp = ss2sin (&ss);
- sinp->sin_family = AF_INET;
- memcpy (&sinp->sin_addr, a->contents, 4);
- }
+ sinp = ss2sin(&ss);
+ sinp->sin_family = AF_INET;
+ memcpy(&sinp->sin_addr, a->contents, 4);
break;
case ADDRTYPE_INET6:
- if (a->length != 16)
- goto broken;
- {
- struct sockaddr_in6 *sin6p = ss2sin6 (&ss);
- sin6p->sin6_family = AF_INET6;
- memcpy (&sin6p->sin6_addr, a->contents, 16);
+ if (a->length != 16) {
+ printf(_("broken address (type %d length %d)"),
+ a->addrtype, a->length);
+ return;
}
+ sin6p = ss2sin6(&ss);
+ sin6p->sin6_family = AF_INET6;
+ memcpy(&sin6p->sin6_addr, a->contents, 16);
break;
default:
printf(_("unknown addrtype %d"), a->addrtype);
@@ -850,25 +839,22 @@ void one_addr(a)
}
namebuf[0] = 0;
- err = getnameinfo (ss2sa (&ss), sa_socklen (ss2sa (&ss)),
- namebuf, sizeof (namebuf), 0, 0,
- no_resolve ? NI_NUMERICHOST : 0U);
+ err = getnameinfo(ss2sa(&ss), sa_socklen(ss2sa(&ss)), namebuf,
+ sizeof(namebuf), 0, 0,
+ no_resolve ? NI_NUMERICHOST : 0U);
if (err) {
printf(_("unprintable address (type %d, error %d %s)"), a->addrtype,
- err, gai_strerror (err));
+ err, gai_strerror(err));
return;
}
- printf ("%s", namebuf);
+ printf("%s", namebuf);
}
-void
-fillit(f, num, c)
- FILE *f;
- unsigned int num;
- int c;
+static void
+fillit(FILE *f, unsigned int num, int c)
{
unsigned int i;
- for (i=0; i<num; i++)
+ for (i = 0; i < num; i++)
fputc(c, f);
}
diff --git a/src/clients/kpasswd/Makefile.in b/src/clients/kpasswd/Makefile.in
index bd4a08cc1daf..294851802af6 100644
--- a/src/clients/kpasswd/Makefile.in
+++ b/src/clients/kpasswd/Makefile.in
@@ -1,16 +1,12 @@
mydir=clients$(S)kpasswd
BUILDTOP=$(REL)..$(S)..
-SRCS=kpasswd.c ksetpwd.c
+SRCS=kpasswd.c
kpasswd: kpasswd.o $(KRB5_BASE_DEPLIBS)
$(CC_LINK) -o kpasswd kpasswd.o $(KRB5_BASE_LIBS)
-ksetpwd: ksetpwd.o $(KRB5_BASE_DEPLIBS)
- $(CC_LINK) -o ksetpwd ksetpwd.o $(KRB5_BASE_LIBS)
-
kpasswd.o: $(srcdir)/kpasswd.c
-ksetpwd.o: $(srcdir)/ksetpwd.c
##WIN32##VERSIONRC = $(BUILDTOP)\windows\version.rc
##WIN32##RCFLAGS=$(CPPFLAGS) -I$(top_srcdir) -D_WIN32 -DRES_ONLY
@@ -22,10 +18,10 @@ ksetpwd.o: $(srcdir)/ksetpwd.c
##WIN32##$(EXERES): $(VERSIONRC)
##WIN32## $(RC) $(RCFLAGS) -DKPASSWD_APP -fo $@ -r $**
-all-unix: kpasswd ksetpwd
+all-unix: kpasswd
clean-unix::
- $(RM) kpasswd.o kpasswd ksetpwd.o ksetpwd
+ $(RM) kpasswd.o kpasswd
install-all install-kdc install-server install-client install-unix:
$(INSTALL_PROGRAM) kpasswd $(DESTDIR)$(CLIENT_BINDIR)/`echo kpasswd|sed '$(transform)'`
diff --git a/src/clients/kpasswd/deps b/src/clients/kpasswd/deps
index 0c01c30cc12e..360b6d73fc62 100644
--- a/src/clients/kpasswd/deps
+++ b/src/clients/kpasswd/deps
@@ -5,7 +5,3 @@ $(OUTPRE)kpasswd.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
$(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-platform.h \
$(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/krb5.h \
kpasswd.c
-$(OUTPRE)ksetpwd.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
- $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-platform.h \
- $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/krb5.h \
- ksetpwd.c
diff --git a/src/clients/kpasswd/kpasswd.c b/src/clients/kpasswd/kpasswd.c
index efc596edf7ce..8dbe611c4fa3 100644
--- a/src/clients/kpasswd/kpasswd.c
+++ b/src/clients/kpasswd/kpasswd.c
@@ -1,4 +1,5 @@
/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+
#include "k5-platform.h"
#include <locale.h>
#include <sys/types.h>
@@ -15,18 +16,18 @@
#ifdef HAVE_PWD_H
#include <pwd.h>
-static
-void get_name_from_passwd_file(program_name, kcontext, me)
- char * program_name;
- krb5_context kcontext;
- krb5_principal * me;
+static void
+get_name_from_passwd_file(char *program_name, krb5_context context,
+ krb5_principal *me)
{
struct passwd *pw;
- krb5_error_code code;
- if ((pw = getpwuid(getuid()))) {
- if ((code = krb5_parse_name(kcontext, pw->pw_name, me))) {
- com_err(program_name, code, _("when parsing name %s"),
- pw->pw_name);
+ krb5_error_code ret;
+
+ pw = getpwuid(getuid());
+ if (pw != NULL) {
+ ret = krb5_parse_name(context, pw->pw_name, me);
+ if (ret) {
+ com_err(program_name, ret, _("when parsing name %s"), pw->pw_name);
exit(1);
}
} else {
@@ -35,9 +36,8 @@ void get_name_from_passwd_file(program_name, kcontext, me)
}
}
#else /* HAVE_PWD_H */
-void get_name_from_passwd_file(kcontext, me)
- krb5_context kcontext;
- krb5_principal * me;
+static void
+get_name_from_passwd_file(krb5_context context, krb5_principal *me)
{
fprintf(stderr, _("Unable to identify user\n"));
exit(1);
@@ -49,13 +49,11 @@ int main(int argc, char *argv[])
krb5_error_code ret;
krb5_context context;
krb5_principal princ = NULL;
- char *pname;
+ char *pname, *message;
+ char pw[1024];
krb5_ccache ccache;
krb5_get_init_creds_opt *opts = NULL;
krb5_creds creds;
- char *message;
-
- char pw[1024];
unsigned int pwlen;
int result_code;
krb5_data result_code_string, result_string;
@@ -73,48 +71,48 @@ int main(int argc, char *argv[])
com_err(argv[0], ret, _("initializing kerberos library"));
exit(1);
}
- if ((ret = krb5_get_init_creds_opt_alloc(context, &opts))) {
+ ret = krb5_get_init_creds_opt_alloc(context, &opts);
+ if (ret) {
com_err(argv[0], ret, _("allocating krb5_get_init_creds_opt"));
exit(1);
}
- /* in order, use the first of:
- - a name specified on the command line
- - the principal name from an existing ccache
- - the name corresponding to the ruid of the process
-
- otherwise, it's an error.
- We always attempt to open the default ccache in order to use FAST if
- possible.
- */
+ /*
+ * In order, use the first of:
+ * - A name specified on the command line
+ * - The principal name from an existing ccache
+ * - The name corresponding to the ruid of the process
+ *
+ * Otherwise, it's an error.
+ * We always attempt to open the default ccache in order to use FAST if
+ * possible.
+ */
ret = krb5_cc_default(context, &ccache);
- if (ret != 0) {
+ if (ret) {
com_err(argv[0], ret, _("opening default ccache"));
exit(1);
}
ret = krb5_cc_get_principal(context, ccache, &princ);
- if (ret != 0 && ret != KRB5_CC_NOTFOUND && ret != KRB5_FCC_NOFILE) {
+ if (ret && ret != KRB5_CC_NOTFOUND && ret != KRB5_FCC_NOFILE) {
com_err(argv[0], ret, _("getting principal from ccache"));
exit(1);
- } else {
- if (princ != NULL) {
- ret = krb5_get_init_creds_opt_set_fast_ccache(context, opts,
- ccache);
- if (ret) {
- com_err(argv[0], ret, _("while setting FAST ccache"));
- exit(1);
- }
+ } else if (princ != NULL) {
+ ret = krb5_get_init_creds_opt_set_fast_ccache(context, opts, ccache);
+ if (ret) {
+ com_err(argv[0], ret, _("while setting FAST ccache"));
+ exit(1);
}
}
ret = krb5_cc_close(context, ccache);
- if (ret != 0) {
+ if (ret) {
com_err(argv[0], ret, _("closing ccache"));
exit(1);
}
- if (pname) {
+ if (pname != NULL) {
krb5_free_principal(context, princ);
princ = NULL;
- if ((ret = krb5_parse_name(context, pname, &princ))) {
+ ret = krb5_parse_name(context, pname, &princ);
+ if (ret) {
com_err(argv[0], ret, _("parsing client name"));
exit(1);
}
@@ -122,33 +120,37 @@ int main(int argc, char *argv[])
if (princ == NULL)
get_name_from_passwd_file(argv[0], context, &princ);
- krb5_get_init_creds_opt_set_tkt_life(opts, 5*60);
+ krb5_get_init_creds_opt_set_tkt_life(opts, 5 * 60);
krb5_get_init_creds_opt_set_renew_life(opts, 0);
krb5_get_init_creds_opt_set_forwardable(opts, 0);
krb5_get_init_creds_opt_set_proxiable(opts, 0);
- if ((ret = krb5_get_init_creds_password(context, &creds, princ, NULL,
- krb5_prompter_posix, NULL,
- 0, "kadmin/changepw", opts))) {
- if (ret == KRB5KRB_AP_ERR_BAD_INTEGRITY)
+ ret = krb5_get_init_creds_password(context, &creds, princ, NULL,
+ krb5_prompter_posix, NULL, 0,
+ "kadmin/changepw", opts);
+ if (ret) {
+ if (ret == KRB5KRB_AP_ERR_BAD_INTEGRITY) {
com_err(argv[0], 0,
_("Password incorrect while getting initial ticket"));
- else
+ } else {
com_err(argv[0], ret, _("getting initial ticket"));
+ }
+
krb5_get_init_creds_opt_free(context, opts);
exit(1);
}
pwlen = sizeof(pw);
- if ((ret = krb5_read_password(context, P1, P2, pw, &pwlen))) {
+ ret = krb5_read_password(context, P1, P2, pw, &pwlen);
+ if (ret) {
com_err(argv[0], ret, _("while reading password"));
krb5_get_init_creds_opt_free(context, opts);
exit(1);
}
- if ((ret = krb5_change_password(context, &creds, pw,
- &result_code, &result_code_string,
- &result_string))) {
+ ret = krb5_change_password(context, &creds, pw, &result_code,
+ &result_code_string, &result_string);
+ if (ret) {
com_err(argv[0], ret, _("changing password"));
krb5_get_init_creds_opt_free(context, opts);
exit(1);
@@ -158,17 +160,15 @@ int main(int argc, char *argv[])
if (krb5_chpw_message(context, &result_string, &message) != 0)
message = NULL;
printf("%.*s%s%s\n",
- (int) result_code_string.length, result_code_string.data,
+ (int)result_code_string.length, result_code_string.data,
message ? ": " : "", message ? message : NULL);
krb5_free_string(context, message);
krb5_get_init_creds_opt_free(context, opts);
exit(2);
}
- if (result_string.data != NULL)
- free(result_string.data);
- if (result_code_string.data != NULL)
- free(result_code_string.data);
+ free(result_string.data);
+ free(result_code_string.data);
krb5_get_init_creds_opt_free(context, opts);
printf(_("Password changed.\n"));
diff --git a/src/clients/kpasswd/ksetpwd.c b/src/clients/kpasswd/ksetpwd.c
deleted file mode 100644
index 2aafb6cedeb0..000000000000
--- a/src/clients/kpasswd/ksetpwd.c
+++ /dev/null
@@ -1,309 +0,0 @@
-/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
-#include <k5-platform.h>
-#include <krb5.h>
-#include <unistd.h>
-#include <time.h>
-
-#define TKTTIMELEFT 60*10 /* ten minutes */
-
-static int verify_creds()
-{
- krb5_context kcontext;
- krb5_ccache ccache;
- krb5_error_code kres;
-
- kres = krb5_init_context(&kcontext);
- if( kres == 0 )
- {
- kres = krb5_cc_default( kcontext, &ccache );
- if( kres == 0 )
- {
- krb5_principal user_princ;
-
- kres = krb5_cc_get_principal( kcontext, ccache, &user_princ );
- if( kres == 0 )
- krb5_free_principal( kcontext, user_princ );
- krb5_cc_close( kcontext, ccache );
- }
- krb5_free_context(kcontext);
- }
- return kres;
-}
-
-static void get_init_creds_opt_init( krb5_get_init_creds_opt *outOptions )
-{
- krb5_preauthtype preauth[] = { KRB5_PADATA_ENC_TIMESTAMP };
- krb5_enctype etypes[] = {ENCTYPE_DES_CBC_MD5, ENCTYPE_DES_CBC_CRC};
- krb5_get_init_creds_opt_set_address_list(outOptions, NULL);
- krb5_get_init_creds_opt_set_etype_list( outOptions, etypes, sizeof(etypes)/sizeof(krb5_enctype) );
- krb5_get_init_creds_opt_set_preauth_list(outOptions, preauth, sizeof(preauth)/sizeof(krb5_preauthtype) );
-}
-
-typedef void * kbrccache_t;
-#define CCACHE_PREFIX_DEFAULT "MEMORY:C_"
-
-static kbrccache_t userinitcontext(
- const char * user, const char * domain, const char * passwd, const char * cachename, int initialize,
- int * outError )
-{
- krb5_context kcontext = 0;
- krb5_ccache kcache = 0;
- krb5_creds kcreds;
- krb5_principal kme = 0;
- krb5_error_code kres;
- char * pPass = strdup( passwd );
- char * pName = NULL;
- char * pCacheName = NULL;
- int numCreds = 0;
-
- memset( &kcreds, 0, sizeof(kcreds) );
- kres = krb5_init_context( &kcontext );
- if( kres )
- goto return_error;
- if( domain )
- kres = krb5_build_principal( kcontext, &kme, strlen(domain), domain, user, (char *) 0 );
- else
- kres = krb5_parse_name( kcontext, user, &kme );
- if( kres )
- goto fail;
- krb5_unparse_name( kcontext, kme, &pName );
- if( cachename )
- {
- if (asprintf(&pCacheName, "%s%s", cachename, pName) < 0)
- {
- kres = KRB5_CC_NOMEM;
- goto fail;
- }
- kres = krb5_cc_resolve( kcontext, pCacheName, &kcache );
- if( kres )
- {
- kres = krb5_cc_resolve( kcontext, CCACHE_PREFIX_DEFAULT, &kcache );
- if( kres == 0 )
- pCacheName = strdup(CCACHE_PREFIX_DEFAULT);
- }
- }
- else
- {
- kres = krb5_cc_default( kcontext, &kcache );
- pCacheName = strdup( krb5_cc_get_name( kcontext, kcache ) );
- }
- if( kres )
- {
- krb5_free_context(kcontext);
- goto return_error;
- }
- if( initialize )
- krb5_cc_initialize( kcontext, kcache, kme );
- if( kres == 0 && user && passwd )
- {
- long timeneeded = time(0L) +TKTTIMELEFT;
- int have_credentials = 0;
- krb5_cc_cursor cc_curs = NULL;
- numCreds = 0;
- if( (kres=krb5_cc_start_seq_get(kcontext, kcache, &cc_curs)) >= 0 )
- {
- while( (kres=krb5_cc_next_cred(kcontext, kcache, &cc_curs, &kcreds))== 0)
- {
- numCreds++;
- if( krb5_principal_compare( kcontext, kme, kcreds.client ) )
- {
- if( kcreds.ticket_flags & TKT_FLG_INITIAL && kcreds.times.endtime>timeneeded )
- have_credentials = 1;
- }
- krb5_free_cred_contents( kcontext, &kcreds );
- if( have_credentials )
- break;
- }
- krb5_cc_end_seq_get( kcontext, kcache, &cc_curs );
- }
- else
- {
- const char * errmsg = error_message(kres);
- fprintf( stderr, "%s user init(%s): %s\n", "setpass", pName, errmsg );
- }
- if( kres != 0 || have_credentials == 0 )
- {
- krb5_get_init_creds_opt *options = NULL;
- kres = krb5_get_init_creds_opt_alloc(kcontext, &options);
- if ( kres == 0 )
- {
- get_init_creds_opt_init(options);
-/*
-** no valid credentials - get new ones
-*/
- kres = krb5_get_init_creds_password( kcontext, &kcreds, kme, pPass,
- NULL /*prompter*/,
- NULL /*data*/,
- 0 /*starttime*/,
- 0 /*in_tkt_service*/,
- options /*options*/ );
- }
- if( kres == 0 )
- {
- if( numCreds <= 0 )
- kres = krb5_cc_initialize( kcontext, kcache, kme );
- if( kres == 0 )
- kres = krb5_cc_store_cred( kcontext, kcache, &kcreds );
- if( kres == 0 )
- have_credentials = 1;
- }
- krb5_get_init_creds_opt_free(kcontext, options);
- }
-#ifdef NOTUSED
- if( have_credentials )
- {
- int mstat;
- kres = gss_krb5_ccache_name( &mstat, pCacheName, NULL );
- if( getenv( ENV_DEBUG_LDAPKERB ) )
- fprintf( stderr, "gss credentials cache set to %s(%d)\n", pCacheName, kres );
- }
-#endif
- krb5_cc_close( kcontext, kcache );
- }
-fail:
- if( kres )
- {
- const char * errmsg = error_message(kres);
- fprintf( stderr, "%s user init(%s): %s\n", "setpass", pName, errmsg );
- }
- krb5_free_principal( kcontext, kme );
- krb5_free_cred_contents( kcontext, &kcreds );
- if( pName )
- free( pName );
- free(pPass);
- krb5_free_context(kcontext);
-
-return_error:
- if( kres )
- {
- if( pCacheName )
- {
- free(pCacheName);
- pCacheName = NULL;
- }
- }
- if( outError )
- *outError = kres;
- return pCacheName;
-}
-
-static int init_creds()
-{
- char user[512];
- char * password = NULL;
- int result;
-
- user[0] = 0;
- result = -1;
-
- for(;;)
- {
- while( user[0] == 0 )
- {
- int userlen;
- printf( "Username: ");
- fflush(stdout);
- if( fgets( user, sizeof(user), stdin ) == NULL )
- return -1;
- userlen = strlen( user);
- if( userlen < 2 )
- continue;
- user[userlen-1] = 0; /* get rid of the newline */
- break;
- }
- {
- kbrccache_t usercontext;
- password = getpass( "Password: ");
- if( ! password )
- return -1;
- result = 0;
- usercontext = userinitcontext( user, NULL, password, NULL, 1, &result );
- if( usercontext )
- break;
- }
- }
- return result;
-}
-
-int main( int argc, char ** argv )
-{
- char * new_password;
- char * new_password2;
- krb5_context kcontext;
- krb5_error_code kerr;
- krb5_principal target_principal;
-
-
- if( argc < 2 )
- {
- fprintf( stderr, "Usage: setpass user@REALM\n");
- exit(1);
- }
-
-/*
-** verify credentials -
-*/
- if( verify_creds() )
- init_creds();
- if( verify_creds() )
- {
- fprintf( stderr, "No user credentials available\n");
- exit(1);
- }
-/*
-** check the principal name -
-*/
- krb5_init_context(&kcontext);
- kerr = krb5_parse_name( kcontext, argv[1], &target_principal );
-
- {
- char * pname = NULL;
- kerr = krb5_unparse_name( kcontext, target_principal, &pname );
- printf( "Changing password for %s:\n", pname);
- fflush( stdout );
- free( pname );
- }
-/*
-** get the new password -
-*/
- for (;;)
- {
- new_password = getpass("Enter new password: ");
- new_password2 = getpass("Verify new password: ");
- if( strcmp( new_password, new_password2 ) == 0)
- break;
- printf("Passwords do not match\n");
- free( new_password );
- free( new_password2 );
- }
-/*
-** change the password -
-*/
- {
- int pw_result;
- krb5_ccache ccache;
- krb5_data pw_res_string, res_string;
-
- kerr = krb5_cc_default( kcontext, &ccache );
- if( kerr == 0 )
- {
- kerr = krb5_set_password_using_ccache(kcontext, ccache, new_password, target_principal,
- &pw_result, &pw_res_string, &res_string );
- if( kerr )
- fprintf( stderr, "Failed: %s\n", error_message(kerr) );
- else
- {
- if( pw_result )
- {
- fprintf( stderr, "Failed(%d)", pw_result );
- if( pw_res_string.length > 0 )
- fprintf( stderr, ": %s", pw_res_string.data);
- if( res_string.length > 0 )
- fprintf( stderr, " %s", res_string.data);
- fprintf( stderr, "\n");
- }
- }
- }
- }
- return(0);
-}
diff --git a/src/clients/ksu/ccache.c b/src/clients/ksu/ccache.c
index a0736f2daad7..2a99521d4b2b 100644
--- a/src/clients/ksu/ccache.c
+++ b/src/clients/ksu/ccache.c
@@ -278,11 +278,11 @@ krb5_error_code krb5_check_exp(context, tkt_time)
context->clockskew);
fprintf(stderr,"krb5_check_exp: currenttime - endtime %d \n",
- (currenttime - tkt_time.endtime ));
+ ts_delta(currenttime, tkt_time.endtime));
}
- if (currenttime - tkt_time.endtime > context->clockskew){
+ if (ts_after(currenttime, ts_incr(tkt_time.endtime, context->clockskew))) {
retval = KRB5KRB_AP_ERR_TKT_EXPIRED ;
return retval;
}
@@ -323,21 +323,11 @@ char *flags_string(cred)
return(buf);
}
-void printtime(tv)
- time_t tv;
+void printtime(krb5_timestamp ts)
{
- char fmtbuf[18];
- char fill;
- krb5_timestamp tstamp;
-
- /* XXXX ASSUMES sizeof(krb5_timestamp) >= sizeof(time_t) */
- (void) localtime((time_t *)&tv);
- tstamp = tv;
- fill = ' ';
- if (!krb5_timestamp_to_sfstring(tstamp,
- fmtbuf,
- sizeof(fmtbuf),
- &fill))
+ char fmtbuf[18], fill = ' ';
+
+ if (!krb5_timestamp_to_sfstring(ts, fmtbuf, sizeof(fmtbuf), &fill))
printf("%s", fmtbuf);
}
diff --git a/src/clients/ksu/ksu.h b/src/clients/ksu/ksu.h
index ee8e9d6a0f79..3bf0bd438449 100644
--- a/src/clients/ksu/ksu.h
+++ b/src/clients/ksu/ksu.h
@@ -150,7 +150,7 @@ extern krb5_boolean krb5_find_princ_in_cred_list
extern krb5_error_code krb5_find_princ_in_cache
(krb5_context, krb5_ccache, krb5_principal, krb5_boolean *);
-extern void printtime (time_t);
+extern void printtime (krb5_timestamp);
/* authorization.c */
extern krb5_boolean fowner (FILE *, uid_t);
diff --git a/src/clients/ksu/main.c b/src/clients/ksu/main.c
index 28342c2d7736..7ff676ca728b 100644
--- a/src/clients/ksu/main.c
+++ b/src/clients/ksu/main.c
@@ -932,7 +932,7 @@ int standard_shell(sh)
static char * ontty()
{
- char *p, *ttyname();
+ char *p;
static char buf[MAXPATHLEN + 5];
int result;
diff --git a/src/clients/kvno/kvno.c b/src/clients/kvno/kvno.c
index 80bee59e2337..77a128d5db82 100644
--- a/src/clients/kvno/kvno.c
+++ b/src/clients/kvno/kvno.c
@@ -36,8 +36,10 @@ extern int optind;
extern char *optarg;
static char *prog;
+static int quiet = 0;
-static void xusage()
+static void
+xusage()
{
fprintf(stderr, _("usage: %s [-C] [-u] [-c ccache] [-e etype]\n"), prog);
fprintf(stderr, _("\t[-k keytab] [-S sname] [-U for_user [-P]]\n"));
@@ -45,18 +47,16 @@ static void xusage()
exit(1);
}
-int quiet = 0;
-
-static void do_v5_kvno (int argc, char *argv[],
- char *ccachestr, char *etypestr, char *keytab_name,
- char *sname, int canon, int unknown,
- char *for_user, int proxy);
+static void do_v5_kvno(int argc, char *argv[], char *ccachestr, char *etypestr,
+ char *keytab_name, char *sname, int canon, int unknown,
+ char *for_user, int proxy);
#include <com_err.h>
-static void extended_com_err_fn (const char *, errcode_t, const char *,
- va_list);
+static void extended_com_err_fn(const char *myprog, errcode_t code,
+ const char *fmt, va_list args);
-int main(int argc, char *argv[])
+int
+main(int argc, char *argv[])
{
int option;
char *etypestr = NULL, *ccachestr = NULL, *keytab_name = NULL;
@@ -64,7 +64,7 @@ int main(int argc, char *argv[])
int canon = 0, unknown = 0, proxy = 0;
setlocale(LC_ALL, "");
- set_com_err_hook (extended_com_err_fn);
+ set_com_err_hook(extended_com_err_fn);
prog = strrchr(argv[0], '/');
prog = prog ? (prog + 1) : argv[0];
@@ -94,7 +94,7 @@ int main(int argc, char *argv[])
break;
case 'S':
sname = optarg;
- if (unknown == 1){
+ if (unknown == 1) {
fprintf(stderr,
_("Options -u and -S are mutually exclusive\n"));
xusage();
@@ -102,7 +102,7 @@ int main(int argc, char *argv[])
break;
case 'u':
unknown = 1;
- if (sname){
+ if (sname != NULL) {
fprintf(stderr,
_("Options -u and -S are mutually exclusive\n"));
xusage();
@@ -129,39 +129,150 @@ int main(int argc, char *argv[])
}
}
- if ((argc - optind) < 1)
+ if (argc - optind < 1)
xusage();
- do_v5_kvno(argc - optind, argv + optind,
- ccachestr, etypestr, keytab_name, sname,
- canon, unknown, for_user, proxy);
+ do_v5_kvno(argc - optind, argv + optind, ccachestr, etypestr, keytab_name,
+ sname, canon, unknown, for_user, proxy);
return 0;
}
#include <k5-int.h>
static krb5_context context;
-static void extended_com_err_fn (const char *myprog, errcode_t code,
- const char *fmt, va_list args)
+static void extended_com_err_fn(const char *myprog, errcode_t code,
+ const char *fmt, va_list args)
{
const char *emsg;
- emsg = krb5_get_error_message (context, code);
- fprintf (stderr, "%s: %s ", myprog, emsg);
- krb5_free_error_message (context, emsg);
- vfprintf (stderr, fmt, args);
- fprintf (stderr, "\n");
+
+ emsg = krb5_get_error_message(context, code);
+ fprintf(stderr, "%s: %s ", myprog, emsg);
+ krb5_free_error_message(context, emsg);
+ vfprintf(stderr, fmt, args);
+ fprintf(stderr, "\n");
+}
+
+/* Request a single service ticket and display its status (unless quiet is
+ * set). On failure, display an error message and return non-zero. */
+static krb5_error_code
+kvno(const char *name, krb5_ccache ccache, krb5_principal me,
+ krb5_enctype etype, krb5_keytab keytab, const char *sname,
+ krb5_flags options, int unknown, krb5_principal for_user_princ, int proxy)
+{
+ krb5_error_code ret;
+ krb5_principal server = NULL;
+ krb5_ticket *ticket = NULL;
+ krb5_creds in_creds, *out_creds = NULL;
+ char *princ = NULL;
+
+ memset(&in_creds, 0, sizeof(in_creds));
+
+ if (sname != NULL) {
+ ret = krb5_sname_to_principal(context, name, sname, KRB5_NT_SRV_HST,
+ &server);
+ } else {
+ ret = krb5_parse_name(context, name, &server);
+ }
+ if (ret) {
+ if (!quiet)
+ com_err(prog, ret, _("while parsing principal name %s"), name);
+ goto cleanup;
+ }
+ if (unknown)
+ krb5_princ_type(context, server) = KRB5_NT_UNKNOWN;
+
+ ret = krb5_unparse_name(context, server, &princ);
+ if (ret) {
+ com_err(prog, ret, _("while formatting parsed principal name for "
+ "'%s'"), name);
+ goto cleanup;
+ }
+
+ in_creds.keyblock.enctype = etype;
+
+ if (for_user_princ != NULL) {
+ if (!proxy && !krb5_principal_compare(context, me, server)) {
+ ret = EINVAL;
+ com_err(prog, ret,
+ _("client and server principal names must match"));
+ goto cleanup;
+ }
+
+ in_creds.client = for_user_princ;
+ in_creds.server = me;
+ ret = krb5_get_credentials_for_user(context, options, ccache,
+ &in_creds, NULL, &out_creds);
+ } else {
+ in_creds.client = me;
+ in_creds.server = server;
+ ret = krb5_get_credentials(context, options, ccache, &in_creds,
+ &out_creds);
+ }
+
+ if (ret) {
+ com_err(prog, ret, _("while getting credentials for %s"), princ);
+ goto cleanup;
+ }
+
+ /* We need a native ticket. */
+ ret = krb5_decode_ticket(&out_creds->ticket, &ticket);
+ if (ret) {
+ com_err(prog, ret, _("while decoding ticket for %s"), princ);
+ goto cleanup;
+ }
+
+ if (keytab != NULL) {
+ ret = krb5_server_decrypt_ticket_keytab(context, keytab, ticket);
+ if (ret) {
+ if (!quiet) {
+ fprintf(stderr, "%s: kvno = %d, keytab entry invalid\n", princ,
+ ticket->enc_part.kvno);
+ }
+ com_err(prog, ret, _("while decrypting ticket for %s"), princ);
+ goto cleanup;
+ }
+ if (!quiet) {
+ printf(_("%s: kvno = %d, keytab entry valid\n"), princ,
+ ticket->enc_part.kvno);
+ }
+ if (proxy) {
+ krb5_free_creds(context, out_creds);
+ out_creds = NULL;
+
+ in_creds.client = ticket->enc_part2->client;
+ in_creds.server = server;
+
+ ret = krb5_get_credentials_for_proxy(context, KRB5_GC_CANONICALIZE,
+ ccache, &in_creds, ticket,
+ &out_creds);
+ if (ret) {
+ com_err(prog, ret, _("%s: constrained delegation failed"),
+ princ);
+ goto cleanup;
+ }
+ }
+ } else {
+ if (!quiet)
+ printf(_("%s: kvno = %d\n"), princ, ticket->enc_part.kvno);
+ }
+
+cleanup:
+ krb5_free_principal(context, server);
+ krb5_free_ticket(context, ticket);
+ krb5_free_creds(context, out_creds);
+ krb5_free_unparsed_name(context, princ);
+ return ret;
}
-static void do_v5_kvno (int count, char *names[],
- char * ccachestr, char *etypestr, char *keytab_name,
- char *sname, int canon, int unknown, char *for_user,
- int proxy)
+static void
+do_v5_kvno(int count, char *names[], char * ccachestr, char *etypestr,
+ char *keytab_name, char *sname, int canon, int unknown,
+ char *for_user, int proxy)
{
krb5_error_code ret;
int i, errors;
krb5_enctype etype;
krb5_ccache ccache;
krb5_principal me;
- krb5_creds in_creds;
krb5_keytab keytab = NULL;
krb5_principal for_user_princ = NULL;
krb5_flags options;
@@ -191,7 +302,7 @@ static void do_v5_kvno (int count, char *names[],
exit(1);
}
- if (keytab_name) {
+ if (keytab_name != NULL) {
ret = krb5_kt_resolve(context, keytab_name, &keytab);
if (ret) {
com_err(prog, ret, _("resolving keytab %s"), keytab_name);
@@ -215,132 +326,16 @@ static void do_v5_kvno (int count, char *names[],
exit(1);
}
- errors = 0;
-
- options = 0;
- if (canon)
- options |= KRB5_GC_CANONICALIZE;
+ options = canon ? KRB5_GC_CANONICALIZE : 0;
+ errors = 0;
for (i = 0; i < count; i++) {
- krb5_principal server = NULL;
- krb5_ticket *ticket = NULL;
- krb5_creds *out_creds = NULL;
- char *princ = NULL;
-
- memset(&in_creds, 0, sizeof(in_creds));
-
- if (sname != NULL) {
- ret = krb5_sname_to_principal(context, names[i],
- sname, KRB5_NT_SRV_HST,
- &server);
- } else {
- ret = krb5_parse_name(context, names[i], &server);
- }
- if (ret) {
- if (!quiet) {
- com_err(prog, ret, _("while parsing principal name %s"),
- names[i]);
- }
- goto error;
- }
- if (unknown == 1) {
- krb5_princ_type(context, server) = KRB5_NT_UNKNOWN;
- }
-
- ret = krb5_unparse_name(context, server, &princ);
- if (ret) {
- com_err(prog, ret, _("while formatting parsed principal name for "
- "'%s'"), names[i]);
- goto error;
- }
-
- in_creds.keyblock.enctype = etype;
-
- if (for_user) {
- if (!proxy &&
- !krb5_principal_compare(context, me, server)) {
- com_err(prog, EINVAL,
- _("client and server principal names must match"));
- goto error;
- }
-
- in_creds.client = for_user_princ;
- in_creds.server = me;
-
- ret = krb5_get_credentials_for_user(context, options, ccache,
- &in_creds, NULL, &out_creds);
- } else {
- in_creds.client = me;
- in_creds.server = server;
- ret = krb5_get_credentials(context, options, ccache,
- &in_creds, &out_creds);
- }
-
- if (ret) {
- com_err(prog, ret, _("while getting credentials for %s"), princ);
- goto error;
- }
-
- /* we need a native ticket */
- ret = krb5_decode_ticket(&out_creds->ticket, &ticket);
- if (ret) {
- com_err(prog, ret, _("while decoding ticket for %s"), princ);
- goto error;
- }
-
- if (keytab) {
- ret = krb5_server_decrypt_ticket_keytab(context, keytab, ticket);
- if (ret) {
- if (!quiet) {
- fprintf(stderr, "%s: kvno = %d, keytab entry invalid\n",
- princ, ticket->enc_part.kvno);
- }
- com_err(prog, ret, _("while decrypting ticket for %s"), princ);
- goto error;
- }
- if (!quiet) {
- printf(_("%s: kvno = %d, keytab entry valid\n"),
- princ, ticket->enc_part.kvno);
- }
- if (proxy) {
- krb5_free_creds(context, out_creds);
- out_creds = NULL;
-
- in_creds.client = ticket->enc_part2->client;
- in_creds.server = server;
-
- ret = krb5_get_credentials_for_proxy(context,
- KRB5_GC_CANONICALIZE,
- ccache,
- &in_creds,
- ticket,
- &out_creds);
- if (ret) {
- com_err(prog, ret,
- _("%s: constrained delegation failed"), princ);
- goto error;
- }
- }
- } else {
- if (!quiet)
- printf(_("%s: kvno = %d\n"), princ, ticket->enc_part.kvno);
- }
-
- continue;
-
- error:
- if (server != NULL)
- krb5_free_principal(context, server);
- if (ticket != NULL)
- krb5_free_ticket(context, ticket);
- if (out_creds != NULL)
- krb5_free_creds(context, out_creds);
- if (princ != NULL)
- krb5_free_unparsed_name(context, princ);
- errors++;
+ if (kvno(names[i], ccache, me, etype, keytab, sname, options, unknown,
+ for_user_princ, proxy) != 0)
+ errors++;
}
- if (keytab)
+ if (keytab != NULL)
krb5_kt_close(context, keytab);
krb5_free_principal(context, me);
krb5_free_principal(context, for_user_princ);
diff --git a/src/config/ac-archive/README b/src/config/ac-archive/README
index 7bc626eb56c3..409d4b3c8f3d 100644
--- a/src/config/ac-archive/README
+++ b/src/config/ac-archive/README
@@ -1,51 +1,9 @@
-*- text -*-
These macros are taken from the autoconf archive at
-ac-archive.sourceforge.net. Unless otherwise noted, they are under
-this modified version of the GNU General Public License version 2
-(also copied from ac-archive.sourceforge.net):
+https://www.gnu.org/software/autoconf-archive/ . They are licensed
+under a modified version of the GNU General Public License as noted in
+the comments near the top of each file.
- Every Autoconf macro presented on this web site 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.
-
- They are distributed in the hope that they 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., 59 Temple
- Place -- Suite 330, Boston, MA 02111-1307, USA.)
-
- As a special exception, the Free Software Foundation gives
- unlimited permission to copy, distribute and modify the configure
- scripts that are the output of Autoconf. You need not follow the
- terms of the GNU General Public License when using or distributing
- such scripts, even though portions of the text of Autoconf appear
- in them. The GNU General Public License (GPL) does govern all
- other use of the material that constitutes the Autoconf program.
-
- Certain portions of the Autoconf source text are designed to be
- copied (in certain cases, depending on the input) into the output
- of Autoconf. We call these the "data" portions. The rest of the
- Autoconf source text consists of comments plus executable code
- that decides which of the data portions to output in any given
- case. We call these comments and executable code the "non-data"
- portions. Autoconf never copies any of the non-data portions into
- its output.
-
- This special exception to the GPL applies to versions of Autoconf
- released by the Free Software Foundation. When you make and
- distribute a modified version of Autoconf, you may extend this
- special exception to the GPL to apply to your modified version as
- well, *unless* your modified version has the potential to copy
- into its output some of the text that was the non-data portion of
- the version that you started with. (In other words, unless your
- change moves or copies text from the non-data portions to the data
- portions.) If your modification has such potential, you must
- delete any notice of this special exception to the GPL from your
- modified version.
-
-acx_pthread.m4 version 1.5 2004/03/01
+ax_pthread.m4 serial 24 2017-02-06
+ax_recursive_eval.m4 serial 1 2017-01-05
diff --git a/src/config/ac-archive/acx_pthread.m4 b/src/config/ac-archive/acx_pthread.m4
deleted file mode 100644
index 6a1537d474fa..000000000000
--- a/src/config/ac-archive/acx_pthread.m4
+++ /dev/null
@@ -1,239 +0,0 @@
-dnl @synopsis ACX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
-dnl
-dnl This macro figures out how to build C programs using POSIX
-dnl threads. It sets the PTHREAD_LIBS output variable to the threads
-dnl library and linker flags, and the PTHREAD_CFLAGS output variable
-dnl to any special C compiler flags that are needed. (The user can also
-dnl force certain compiler flags/libs to be tested by setting these
-dnl environment variables.)
-dnl
-dnl Also sets PTHREAD_CC to any special C compiler that is needed for
-dnl multi-threaded programs (defaults to the value of CC otherwise).
-dnl (This is necessary on AIX to use the special cc_r compiler alias.)
-dnl
-dnl NOTE: You are assumed to not only compile your program with these
-dnl flags, but also link it with them as well. e.g. you should link
-dnl with $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS
-dnl
-dnl If you are only building threads programs, you may wish to
-dnl use these variables in your default LIBS, CFLAGS, and CC:
-dnl
-dnl LIBS="$PTHREAD_LIBS $LIBS"
-dnl CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
-dnl CC="$PTHREAD_CC"
-dnl
-dnl In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute
-dnl constant has a nonstandard name, defines PTHREAD_CREATE_JOINABLE
-dnl to that name (e.g. PTHREAD_CREATE_UNDETACHED on AIX).
-dnl
-dnl ACTION-IF-FOUND is a list of shell commands to run if a threads
-dnl library is found, and ACTION-IF-NOT-FOUND is a list of commands
-dnl to run it if it is not found. If ACTION-IF-FOUND is not specified,
-dnl the default action will define HAVE_PTHREAD.
-dnl
-dnl Please let the authors know if this macro fails on any platform,
-dnl or if you have any other suggestions or comments. This macro was
-dnl based on work by SGJ on autoconf scripts for FFTW (www.fftw.org)
-dnl (with help from M. Frigo), as well as ac_pthread and hb_pthread
-dnl macros posted by AFC to the autoconf macro repository. We are also
-dnl grateful for the helpful feedback of numerous users.
-dnl
-dnl @version $Id: acx_pthread.m4,v 1.5 2004/03/01 19:28:29 guidod Exp $
-dnl @author Steven G. Johnson <stevenj@alum.mit.edu> and Alejandro Forero Cuervo <bachue@bachue.com>
-
-AC_DEFUN([ACX_PTHREAD], [
-AC_REQUIRE([AC_CANONICAL_HOST])
-AC_LANG_SAVE
-AC_LANG_C
-acx_pthread_ok=no
-
-# We used to check for pthread.h first, but this fails if pthread.h
-# requires special compiler flags (e.g. on True64 or Sequent).
-# It gets checked for in the link test anyway.
-
-# First of all, check if the user has set any of the PTHREAD_LIBS,
-# etcetera environment variables, and if threads linking works using
-# them:
-if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then
- save_CFLAGS="$CFLAGS"
- CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
- save_LIBS="$LIBS"
- LIBS="$PTHREAD_LIBS $LIBS"
- AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS])
- AC_TRY_LINK_FUNC(pthread_join, acx_pthread_ok=yes)
- AC_MSG_RESULT($acx_pthread_ok)
- if test x"$acx_pthread_ok" = xno; then
- PTHREAD_LIBS=""
- PTHREAD_CFLAGS=""
- fi
- LIBS="$save_LIBS"
- CFLAGS="$save_CFLAGS"
-fi
-
-# We must check for the threads library under a number of different
-# names; the ordering is very important because some systems
-# (e.g. DEC) have both -lpthread and -lpthreads, where one of the
-# libraries is broken (non-POSIX).
-
-# Create a list of thread flags to try. Items starting with a "-" are
-# C compiler flags, and other items are library names, except for "none"
-# which indicates that we try without any flags at all, and "pthread-config"
-# which is a program returning the flags for the Pth emulation library.
-
-acx_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
-
-# The ordering *is* (sometimes) important. Some notes on the
-# individual items follow:
-
-# pthreads: AIX (must check this before -lpthread)
-# none: in case threads are in libc; should be tried before -Kthread and
-# other compiler flags to prevent continual compiler warnings
-# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
-# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
-# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
-# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads)
-# -pthreads: Solaris/gcc
-# -mthreads: Mingw32/gcc, Lynx/gcc
-# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
-# doesn't hurt to check since this sometimes defines pthreads too;
-# also defines -D_REENTRANT)
-# pthread: Linux, etcetera
-# --thread-safe: KAI C++
-# pthread-config: use pthread-config program (for GNU Pth library)
-
-case "${host_cpu}-${host_os}" in
- *solaris*)
-
- # On Solaris (at least, for some versions), libc contains stubbed
- # (non-functional) versions of the pthreads routines, so link-based
- # tests will erroneously succeed. (We need to link with -pthread or
- # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather
- # a function called by this macro, so we could check for that, but
- # who knows whether they'll stub that too in a future libc.) So,
- # we'll just look for -pthreads and -lpthread first:
-
- acx_pthread_flags="-pthread -pthreads pthread -mt $acx_pthread_flags"
- ;;
-esac
-
-if test x"$acx_pthread_ok" = xno; then
-for flag in $acx_pthread_flags; do
-
- case $flag in
- none)
- AC_MSG_CHECKING([whether pthreads work without any flags])
- ;;
-
- -*)
- AC_MSG_CHECKING([whether pthreads work with $flag])
- PTHREAD_CFLAGS="$flag"
- ;;
-
- pthread-config)
- AC_CHECK_PROG(acx_pthread_config, pthread-config, yes, no)
- if test x"$acx_pthread_config" = xno; then continue; fi
- PTHREAD_CFLAGS="`pthread-config --cflags`"
- PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
- ;;
-
- *)
- AC_MSG_CHECKING([for the pthreads library -l$flag])
- PTHREAD_LIBS="-l$flag"
- ;;
- esac
-
- save_LIBS="$LIBS"
- save_CFLAGS="$CFLAGS"
- LIBS="$PTHREAD_LIBS $LIBS"
- CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
-
- # Check for various functions. We must include pthread.h,
- # since some functions may be macros. (On the Sequent, we
- # need a special flag -Kthread to make this header compile.)
- # We check for pthread_join because it is in -lpthread on IRIX
- # while pthread_create is in libc. We check for pthread_attr_init
- # due to DEC craziness with -lpthreads. We check for
- # pthread_cleanup_push because it is one of the few pthread
- # functions on Solaris that doesn't have a non-functional libc stub.
- # We try pthread_create on general principles.
- AC_TRY_LINK([#include <pthread.h>],
- [pthread_t th; pthread_join(th, 0);
- pthread_attr_init(0); pthread_cleanup_push(0, 0);
- pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],
- [acx_pthread_ok=yes])
-
- LIBS="$save_LIBS"
- CFLAGS="$save_CFLAGS"
-
- AC_MSG_RESULT($acx_pthread_ok)
- if test "x$acx_pthread_ok" = xyes; then
- break;
- fi
-
- PTHREAD_LIBS=""
- PTHREAD_CFLAGS=""
-done
-fi
-
-# Various other checks:
-if test "x$acx_pthread_ok" = xyes; then
- save_LIBS="$LIBS"
- LIBS="$PTHREAD_LIBS $LIBS"
- save_CFLAGS="$CFLAGS"
- CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
-
- # Detect AIX lossage: threads are created detached by default
- # and the JOINABLE attribute has a nonstandard name (UNDETACHED).
- AC_MSG_CHECKING([for joinable pthread attribute])
- AC_TRY_LINK([#include <pthread.h>],
- [int attr=PTHREAD_CREATE_JOINABLE;],
- ok=PTHREAD_CREATE_JOINABLE, ok=unknown)
- if test x"$ok" = xunknown; then
- AC_TRY_LINK([#include <pthread.h>],
- [int attr=PTHREAD_CREATE_UNDETACHED;],
- ok=PTHREAD_CREATE_UNDETACHED, ok=unknown)
- fi
- if test x"$ok" != xPTHREAD_CREATE_JOINABLE; then
- AC_DEFINE(PTHREAD_CREATE_JOINABLE, $ok,
- [Define to the necessary symbol if this constant
- uses a non-standard name on your system.])
- fi
- AC_MSG_RESULT(${ok})
- if test x"$ok" = xunknown; then
- AC_MSG_WARN([we do not know how to create joinable pthreads])
- fi
-
- AC_MSG_CHECKING([if more special flags are required for pthreads])
- flag=no
- case "${host_cpu}-${host_os}" in
- *-aix* | *-freebsd*) flag="-D_THREAD_SAFE";;
- *solaris* | *-osf* | *-hpux*) flag="-D_REENTRANT";;
- esac
- AC_MSG_RESULT(${flag})
- if test "x$flag" != xno; then
- PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS"
- fi
-
- LIBS="$save_LIBS"
- CFLAGS="$save_CFLAGS"
-
- # More AIX lossage: must compile with cc_r
- AC_CHECK_PROG(PTHREAD_CC, cc_r, cc_r, ${CC})
-else
- PTHREAD_CC="$CC"
-fi
-
-AC_SUBST(PTHREAD_LIBS)
-AC_SUBST(PTHREAD_CFLAGS)
-AC_SUBST(PTHREAD_CC)
-
-# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
-if test x"$acx_pthread_ok" = xyes; then
- ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1])
- :
-else
- acx_pthread_ok=no
- $2
-fi
-AC_LANG_RESTORE
-])dnl ACX_PTHREAD
diff --git a/src/config/ac-archive/ax_pthread.m4 b/src/config/ac-archive/ax_pthread.m4
new file mode 100644
index 000000000000..5fbf9fe0d686
--- /dev/null
+++ b/src/config/ac-archive/ax_pthread.m4
@@ -0,0 +1,485 @@
+# ===========================================================================
+# https://www.gnu.org/software/autoconf-archive/ax_pthread.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
+#
+# DESCRIPTION
+#
+# This macro figures out how to build C programs using POSIX threads. It
+# sets the PTHREAD_LIBS output variable to the threads library and linker
+# flags, and the PTHREAD_CFLAGS output variable to any special C compiler
+# flags that are needed. (The user can also force certain compiler
+# flags/libs to be tested by setting these environment variables.)
+#
+# Also sets PTHREAD_CC to any special C compiler that is needed for
+# multi-threaded programs (defaults to the value of CC otherwise). (This
+# is necessary on AIX to use the special cc_r compiler alias.)
+#
+# NOTE: You are assumed to not only compile your program with these flags,
+# but also to link with them as well. For example, you might link with
+# $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS
+#
+# If you are only building threaded programs, you may wish to use these
+# variables in your default LIBS, CFLAGS, and CC:
+#
+# LIBS="$PTHREAD_LIBS $LIBS"
+# CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+# CC="$PTHREAD_CC"
+#
+# In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant
+# has a nonstandard name, this macro defines PTHREAD_CREATE_JOINABLE to
+# that name (e.g. PTHREAD_CREATE_UNDETACHED on AIX).
+#
+# Also HAVE_PTHREAD_PRIO_INHERIT is defined if pthread is found and the
+# PTHREAD_PRIO_INHERIT symbol is defined when compiling with
+# PTHREAD_CFLAGS.
+#
+# ACTION-IF-FOUND is a list of shell commands to run if a threads library
+# is found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it
+# is not found. If ACTION-IF-FOUND is not specified, the default action
+# will define HAVE_PTHREAD.
+#
+# Please let the authors know if this macro fails on any platform, or if
+# you have any other suggestions or comments. This macro was based on work
+# by SGJ on autoconf scripts for FFTW (http://www.fftw.org/) (with help
+# from M. Frigo), as well as ac_pthread and hb_pthread macros posted by
+# Alejandro Forero Cuervo to the autoconf macro repository. We are also
+# grateful for the helpful feedback of numerous users.
+#
+# Updated for Autoconf 2.68 by Daniel Richard G.
+#
+# LICENSE
+#
+# Copyright (c) 2008 Steven G. Johnson <stevenj@alum.mit.edu>
+# Copyright (c) 2011 Daniel Richard G. <skunk@iSKUNK.ORG>
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation, either version 3 of the License, or (at your
+# option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+# Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program. If not, see <https://www.gnu.org/licenses/>.
+#
+# As a special exception, the respective Autoconf Macro's copyright owner
+# gives unlimited permission to copy, distribute and modify the configure
+# scripts that are the output of Autoconf when processing the Macro. You
+# need not follow the terms of the GNU General Public License when using
+# or distributing such scripts, even though portions of the text of the
+# Macro appear in them. The GNU General Public License (GPL) does govern
+# all other use of the material that constitutes the Autoconf Macro.
+#
+# This special exception to the GPL applies to versions of the Autoconf
+# Macro released by the Autoconf Archive. When you make and distribute a
+# modified version of the Autoconf Macro, you may extend this special
+# exception to the GPL to apply to your modified version as well.
+
+#serial 24
+
+AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD])
+AC_DEFUN([AX_PTHREAD], [
+AC_REQUIRE([AC_CANONICAL_HOST])
+AC_REQUIRE([AC_PROG_CC])
+AC_REQUIRE([AC_PROG_SED])
+AC_LANG_PUSH([C])
+ax_pthread_ok=no
+
+# We used to check for pthread.h first, but this fails if pthread.h
+# requires special compiler flags (e.g. on Tru64 or Sequent).
+# It gets checked for in the link test anyway.
+
+# First of all, check if the user has set any of the PTHREAD_LIBS,
+# etcetera environment variables, and if threads linking works using
+# them:
+if test "x$PTHREAD_CFLAGS$PTHREAD_LIBS" != "x"; then
+ ax_pthread_save_CC="$CC"
+ ax_pthread_save_CFLAGS="$CFLAGS"
+ ax_pthread_save_LIBS="$LIBS"
+ AS_IF([test "x$PTHREAD_CC" != "x"], [CC="$PTHREAD_CC"])
+ CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+ LIBS="$PTHREAD_LIBS $LIBS"
+ AC_MSG_CHECKING([for pthread_join using $CC $PTHREAD_CFLAGS $PTHREAD_LIBS])
+ AC_LINK_IFELSE([AC_LANG_CALL([], [pthread_join])], [ax_pthread_ok=yes])
+ AC_MSG_RESULT([$ax_pthread_ok])
+ if test "x$ax_pthread_ok" = "xno"; then
+ PTHREAD_LIBS=""
+ PTHREAD_CFLAGS=""
+ fi
+ CC="$ax_pthread_save_CC"
+ CFLAGS="$ax_pthread_save_CFLAGS"
+ LIBS="$ax_pthread_save_LIBS"
+fi
+
+# We must check for the threads library under a number of different
+# names; the ordering is very important because some systems
+# (e.g. DEC) have both -lpthread and -lpthreads, where one of the
+# libraries is broken (non-POSIX).
+
+# Create a list of thread flags to try. Items starting with a "-" are
+# C compiler flags, and other items are library names, except for "none"
+# which indicates that we try without any flags at all, and "pthread-config"
+# which is a program returning the flags for the Pth emulation library.
+
+ax_pthread_flags="pthreads none -Kthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
+
+# The ordering *is* (sometimes) important. Some notes on the
+# individual items follow:
+
+# pthreads: AIX (must check this before -lpthread)
+# none: in case threads are in libc; should be tried before -Kthread and
+# other compiler flags to prevent continual compiler warnings
+# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
+# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads), Tru64
+# (Note: HP C rejects this with "bad form for `-t' option")
+# -pthreads: Solaris/gcc (Note: HP C also rejects)
+# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
+# doesn't hurt to check since this sometimes defines pthreads and
+# -D_REENTRANT too), HP C (must be checked before -lpthread, which
+# is present but should not be used directly; and before -mthreads,
+# because the compiler interprets this as "-mt" + "-hreads")
+# -mthreads: Mingw32/gcc, Lynx/gcc
+# pthread: Linux, etcetera
+# --thread-safe: KAI C++
+# pthread-config: use pthread-config program (for GNU Pth library)
+
+case $host_os in
+
+ freebsd*)
+
+ # -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
+ # lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
+
+ ax_pthread_flags="-kthread lthread $ax_pthread_flags"
+ ;;
+
+ hpux*)
+
+ # From the cc(1) man page: "[-mt] Sets various -D flags to enable
+ # multi-threading and also sets -lpthread."
+
+ ax_pthread_flags="-mt -pthread pthread $ax_pthread_flags"
+ ;;
+
+ openedition*)
+
+ # IBM z/OS requires a feature-test macro to be defined in order to
+ # enable POSIX threads at all, so give the user a hint if this is
+ # not set. (We don't define these ourselves, as they can affect
+ # other portions of the system API in unpredictable ways.)
+
+ AC_EGREP_CPP([AX_PTHREAD_ZOS_MISSING],
+ [
+# if !defined(_OPEN_THREADS) && !defined(_UNIX03_THREADS)
+ AX_PTHREAD_ZOS_MISSING
+# endif
+ ],
+ [AC_MSG_WARN([IBM z/OS requires -D_OPEN_THREADS or -D_UNIX03_THREADS to enable pthreads support.])])
+ ;;
+
+ solaris*)
+
+ # On Solaris (at least, for some versions), libc contains stubbed
+ # (non-functional) versions of the pthreads routines, so link-based
+ # tests will erroneously succeed. (N.B.: The stubs are missing
+ # pthread_cleanup_push, or rather a function called by this macro,
+ # so we could check for that, but who knows whether they'll stub
+ # that too in a future libc.) So we'll check first for the
+ # standard Solaris way of linking pthreads (-mt -lpthread).
+
+ ax_pthread_flags="-mt,pthread pthread $ax_pthread_flags"
+ ;;
+esac
+
+# GCC generally uses -pthread, or -pthreads on some platforms (e.g. SPARC)
+
+AS_IF([test "x$GCC" = "xyes"],
+ [ax_pthread_flags="-pthread -pthreads $ax_pthread_flags"])
+
+# The presence of a feature test macro requesting re-entrant function
+# definitions is, on some systems, a strong hint that pthreads support is
+# correctly enabled
+
+case $host_os in
+ darwin* | hpux* | linux* | osf* | solaris*)
+ ax_pthread_check_macro="_REENTRANT"
+ ;;
+
+ aix*)
+ ax_pthread_check_macro="_THREAD_SAFE"
+ ;;
+
+ *)
+ ax_pthread_check_macro="--"
+ ;;
+esac
+AS_IF([test "x$ax_pthread_check_macro" = "x--"],
+ [ax_pthread_check_cond=0],
+ [ax_pthread_check_cond="!defined($ax_pthread_check_macro)"])
+
+# Are we compiling with Clang?
+
+AC_CACHE_CHECK([whether $CC is Clang],
+ [ax_cv_PTHREAD_CLANG],
+ [ax_cv_PTHREAD_CLANG=no
+ # Note that Autoconf sets GCC=yes for Clang as well as GCC
+ if test "x$GCC" = "xyes"; then
+ AC_EGREP_CPP([AX_PTHREAD_CC_IS_CLANG],
+ [/* Note: Clang 2.7 lacks __clang_[a-z]+__ */
+# if defined(__clang__) && defined(__llvm__)
+ AX_PTHREAD_CC_IS_CLANG
+# endif
+ ],
+ [ax_cv_PTHREAD_CLANG=yes])
+ fi
+ ])
+ax_pthread_clang="$ax_cv_PTHREAD_CLANG"
+
+ax_pthread_clang_warning=no
+
+# Clang needs special handling, because older versions handle the -pthread
+# option in a rather... idiosyncratic way
+
+if test "x$ax_pthread_clang" = "xyes"; then
+
+ # Clang takes -pthread; it has never supported any other flag
+
+ # (Note 1: This will need to be revisited if a system that Clang
+ # supports has POSIX threads in a separate library. This tends not
+ # to be the way of modern systems, but it's conceivable.)
+
+ # (Note 2: On some systems, notably Darwin, -pthread is not needed
+ # to get POSIX threads support; the API is always present and
+ # active. We could reasonably leave PTHREAD_CFLAGS empty. But
+ # -pthread does define _REENTRANT, and while the Darwin headers
+ # ignore this macro, third-party headers might not.)
+
+ PTHREAD_CFLAGS="-pthread"
+ PTHREAD_LIBS=
+
+ ax_pthread_ok=yes
+
+ # However, older versions of Clang make a point of warning the user
+ # that, in an invocation where only linking and no compilation is
+ # taking place, the -pthread option has no effect ("argument unused
+ # during compilation"). They expect -pthread to be passed in only
+ # when source code is being compiled.
+ #
+ # Problem is, this is at odds with the way Automake and most other
+ # C build frameworks function, which is that the same flags used in
+ # compilation (CFLAGS) are also used in linking. Many systems
+ # supported by AX_PTHREAD require exactly this for POSIX threads
+ # support, and in fact it is often not straightforward to specify a
+ # flag that is used only in the compilation phase and not in
+ # linking. Such a scenario is extremely rare in practice.
+ #
+ # Even though use of the -pthread flag in linking would only print
+ # a warning, this can be a nuisance for well-run software projects
+ # that build with -Werror. So if the active version of Clang has
+ # this misfeature, we search for an option to squash it.
+
+ AC_CACHE_CHECK([whether Clang needs flag to prevent "argument unused" warning when linking with -pthread],
+ [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG],
+ [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG=unknown
+ # Create an alternate version of $ac_link that compiles and
+ # links in two steps (.c -> .o, .o -> exe) instead of one
+ # (.c -> exe), because the warning occurs only in the second
+ # step
+ ax_pthread_save_ac_link="$ac_link"
+ ax_pthread_sed='s/conftest\.\$ac_ext/conftest.$ac_objext/g'
+ ax_pthread_link_step=`$as_echo "$ac_link" | sed "$ax_pthread_sed"`
+ ax_pthread_2step_ac_link="($ac_compile) && (echo ==== >&5) && ($ax_pthread_link_step)"
+ ax_pthread_save_CFLAGS="$CFLAGS"
+ for ax_pthread_try in '' -Qunused-arguments -Wno-unused-command-line-argument unknown; do
+ AS_IF([test "x$ax_pthread_try" = "xunknown"], [break])
+ CFLAGS="-Werror -Wunknown-warning-option $ax_pthread_try -pthread $ax_pthread_save_CFLAGS"
+ ac_link="$ax_pthread_save_ac_link"
+ AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])],
+ [ac_link="$ax_pthread_2step_ac_link"
+ AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])],
+ [break])
+ ])
+ done
+ ac_link="$ax_pthread_save_ac_link"
+ CFLAGS="$ax_pthread_save_CFLAGS"
+ AS_IF([test "x$ax_pthread_try" = "x"], [ax_pthread_try=no])
+ ax_cv_PTHREAD_CLANG_NO_WARN_FLAG="$ax_pthread_try"
+ ])
+
+ case "$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" in
+ no | unknown) ;;
+ *) PTHREAD_CFLAGS="$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG $PTHREAD_CFLAGS" ;;
+ esac
+
+fi # $ax_pthread_clang = yes
+
+if test "x$ax_pthread_ok" = "xno"; then
+for ax_pthread_try_flag in $ax_pthread_flags; do
+
+ case $ax_pthread_try_flag in
+ none)
+ AC_MSG_CHECKING([whether pthreads work without any flags])
+ ;;
+
+ -mt,pthread)
+ AC_MSG_CHECKING([whether pthreads work with -mt -lpthread])
+ PTHREAD_CFLAGS="-mt"
+ PTHREAD_LIBS="-lpthread"
+ ;;
+
+ -*)
+ AC_MSG_CHECKING([whether pthreads work with $ax_pthread_try_flag])
+ PTHREAD_CFLAGS="$ax_pthread_try_flag"
+ ;;
+
+ pthread-config)
+ AC_CHECK_PROG([ax_pthread_config], [pthread-config], [yes], [no])
+ AS_IF([test "x$ax_pthread_config" = "xno"], [continue])
+ PTHREAD_CFLAGS="`pthread-config --cflags`"
+ PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
+ ;;
+
+ *)
+ AC_MSG_CHECKING([for the pthreads library -l$ax_pthread_try_flag])
+ PTHREAD_LIBS="-l$ax_pthread_try_flag"
+ ;;
+ esac
+
+ ax_pthread_save_CFLAGS="$CFLAGS"
+ ax_pthread_save_LIBS="$LIBS"
+ CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+ LIBS="$PTHREAD_LIBS $LIBS"
+
+ # Check for various functions. We must include pthread.h,
+ # since some functions may be macros. (On the Sequent, we
+ # need a special flag -Kthread to make this header compile.)
+ # We check for pthread_join because it is in -lpthread on IRIX
+ # while pthread_create is in libc. We check for pthread_attr_init
+ # due to DEC craziness with -lpthreads. We check for
+ # pthread_cleanup_push because it is one of the few pthread
+ # functions on Solaris that doesn't have a non-functional libc stub.
+ # We try pthread_create on general principles.
+
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>
+# if $ax_pthread_check_cond
+# error "$ax_pthread_check_macro must be defined"
+# endif
+ static void routine(void *a) { a = 0; }
+ static void *start_routine(void *a) { return a; }],
+ [pthread_t th; pthread_attr_t attr;
+ pthread_create(&th, 0, start_routine, 0);
+ pthread_join(th, 0);
+ pthread_attr_init(&attr);
+ pthread_cleanup_push(routine, 0);
+ pthread_cleanup_pop(0) /* ; */])],
+ [ax_pthread_ok=yes],
+ [])
+
+ CFLAGS="$ax_pthread_save_CFLAGS"
+ LIBS="$ax_pthread_save_LIBS"
+
+ AC_MSG_RESULT([$ax_pthread_ok])
+ AS_IF([test "x$ax_pthread_ok" = "xyes"], [break])
+
+ PTHREAD_LIBS=""
+ PTHREAD_CFLAGS=""
+done
+fi
+
+# Various other checks:
+if test "x$ax_pthread_ok" = "xyes"; then
+ ax_pthread_save_CFLAGS="$CFLAGS"
+ ax_pthread_save_LIBS="$LIBS"
+ CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+ LIBS="$PTHREAD_LIBS $LIBS"
+
+ # Detect AIX lossage: JOINABLE attribute is called UNDETACHED.
+ AC_CACHE_CHECK([for joinable pthread attribute],
+ [ax_cv_PTHREAD_JOINABLE_ATTR],
+ [ax_cv_PTHREAD_JOINABLE_ATTR=unknown
+ for ax_pthread_attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>],
+ [int attr = $ax_pthread_attr; return attr /* ; */])],
+ [ax_cv_PTHREAD_JOINABLE_ATTR=$ax_pthread_attr; break],
+ [])
+ done
+ ])
+ AS_IF([test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xunknown" && \
+ test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xPTHREAD_CREATE_JOINABLE" && \
+ test "x$ax_pthread_joinable_attr_defined" != "xyes"],
+ [AC_DEFINE_UNQUOTED([PTHREAD_CREATE_JOINABLE],
+ [$ax_cv_PTHREAD_JOINABLE_ATTR],
+ [Define to necessary symbol if this constant
+ uses a non-standard name on your system.])
+ ax_pthread_joinable_attr_defined=yes
+ ])
+
+ AC_CACHE_CHECK([whether more special flags are required for pthreads],
+ [ax_cv_PTHREAD_SPECIAL_FLAGS],
+ [ax_cv_PTHREAD_SPECIAL_FLAGS=no
+ case $host_os in
+ solaris*)
+ ax_cv_PTHREAD_SPECIAL_FLAGS="-D_POSIX_PTHREAD_SEMANTICS"
+ ;;
+ esac
+ ])
+ AS_IF([test "x$ax_cv_PTHREAD_SPECIAL_FLAGS" != "xno" && \
+ test "x$ax_pthread_special_flags_added" != "xyes"],
+ [PTHREAD_CFLAGS="$ax_cv_PTHREAD_SPECIAL_FLAGS $PTHREAD_CFLAGS"
+ ax_pthread_special_flags_added=yes])
+
+ AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT],
+ [ax_cv_PTHREAD_PRIO_INHERIT],
+ [AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <pthread.h>]],
+ [[int i = PTHREAD_PRIO_INHERIT;]])],
+ [ax_cv_PTHREAD_PRIO_INHERIT=yes],
+ [ax_cv_PTHREAD_PRIO_INHERIT=no])
+ ])
+ AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes" && \
+ test "x$ax_pthread_prio_inherit_defined" != "xyes"],
+ [AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], [1], [Have PTHREAD_PRIO_INHERIT.])
+ ax_pthread_prio_inherit_defined=yes
+ ])
+
+ CFLAGS="$ax_pthread_save_CFLAGS"
+ LIBS="$ax_pthread_save_LIBS"
+
+ # More AIX lossage: compile with *_r variant
+ if test "x$GCC" != "xyes"; then
+ case $host_os in
+ aix*)
+ AS_CASE(["x/$CC"],
+ [x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6],
+ [#handle absolute path differently from PATH based program lookup
+ AS_CASE(["x$CC"],
+ [x/*],
+ [AS_IF([AS_EXECUTABLE_P([${CC}_r])],[PTHREAD_CC="${CC}_r"])],
+ [AC_CHECK_PROGS([PTHREAD_CC],[${CC}_r],[$CC])])])
+ ;;
+ esac
+ fi
+fi
+
+test -n "$PTHREAD_CC" || PTHREAD_CC="$CC"
+
+AC_SUBST([PTHREAD_LIBS])
+AC_SUBST([PTHREAD_CFLAGS])
+AC_SUBST([PTHREAD_CC])
+
+# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
+if test "x$ax_pthread_ok" = "xyes"; then
+ ifelse([$1],,[AC_DEFINE([HAVE_PTHREAD],[1],[Define if you have POSIX threads libraries and header files.])],[$1])
+ :
+else
+ ax_pthread_ok=no
+ $2
+fi
+AC_LANG_POP
+])dnl AX_PTHREAD
diff --git a/src/config/ac-archive/ax_recursive_eval.m4 b/src/config/ac-archive/ax_recursive_eval.m4
new file mode 100644
index 000000000000..0625aca2255d
--- /dev/null
+++ b/src/config/ac-archive/ax_recursive_eval.m4
@@ -0,0 +1,56 @@
+# ===========================================================================
+# https://www.gnu.org/software/autoconf-archive/ax_recursive_eval.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_RECURSIVE_EVAL(VALUE, RESULT)
+#
+# DESCRIPTION
+#
+# Interpolate the VALUE in loop until it doesn't change, and set the
+# result to $RESULT. WARNING: It's easy to get an infinite loop with some
+# unsane input.
+#
+# LICENSE
+#
+# Copyright (c) 2008 Alexandre Duret-Lutz <adl@gnu.org>
+#
+# 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 of the License, or (at your
+# option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+# Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program. If not, see <https://www.gnu.org/licenses/>.
+#
+# As a special exception, the respective Autoconf Macro's copyright owner
+# gives unlimited permission to copy, distribute and modify the configure
+# scripts that are the output of Autoconf when processing the Macro. You
+# need not follow the terms of the GNU General Public License when using
+# or distributing such scripts, even though portions of the text of the
+# Macro appear in them. The GNU General Public License (GPL) does govern
+# all other use of the material that constitutes the Autoconf Macro.
+#
+# This special exception to the GPL applies to versions of the Autoconf
+# Macro released by the Autoconf Archive. When you make and distribute a
+# modified version of the Autoconf Macro, you may extend this special
+# exception to the GPL to apply to your modified version as well.
+
+#serial 1
+
+AC_DEFUN([AX_RECURSIVE_EVAL],
+[_lcl_receval="$1"
+$2=`(test "x$prefix" = xNONE && prefix="$ac_default_prefix"
+ test "x$exec_prefix" = xNONE && exec_prefix="${prefix}"
+ _lcl_receval_old=''
+ while test "[$]_lcl_receval_old" != "[$]_lcl_receval"; do
+ _lcl_receval_old="[$]_lcl_receval"
+ eval _lcl_receval="\"[$]_lcl_receval\""
+ done
+ echo "[$]_lcl_receval")`])
diff --git a/src/config/ac-archive/relpaths.m4 b/src/config/ac-archive/relpaths.m4
deleted file mode 100644
index 15f24b3347e2..000000000000
--- a/src/config/ac-archive/relpaths.m4
+++ /dev/null
@@ -1,155 +0,0 @@
-dnl @synopsis adl_COMPUTE_RELATIVE_PATHS(PATH_LIST)
-dnl
-dnl PATH_LIST is a space-separated list of colon-separated triplets of
-dnl the form 'FROM:TO:RESULT'. This function iterates over these
-dnl triplets and set $RESULT to the relative path from $FROM to $TO.
-dnl Note that $FROM and $TO needs to be absolute filenames for this
-dnl macro to success.
-dnl
-dnl For instance,
-dnl
-dnl first=/usr/local/bin
-dnl second=/usr/local/share
-dnl adl_COMPUTE_RELATIVE_PATHS([first:second:fs second:first:sf])
-dnl # $fs is set to ../share
-dnl # $sf is set to ../bin
-dnl
-dnl $FROM and $TO are both eval'ed recursively and normalized, this
-dnl means that you can call this macro with autoconf's dirnames like
-dnl `prefix' or `datadir'. For example:
-dnl
-dnl adl_COMPUTE_RELATIVE_PATHS([bindir:datadir:bin_to_data])
-dnl
-dnl adl_COMPUTE_RELATIVE_PATHS should also works with DOS filenames.
-dnl
-dnl You may want to use this macro in order to make your package
-dnl relocatable. Instead of hardcoding $datadir into your programs just
-dnl encode $bin_to_data and try to determine $bindir at run-time.
-dnl
-dnl This macro requires adl_NORMALIZE_PATH.
-dnl
-dnl @category Misc
-dnl @author Alexandre Duret-Lutz <duret_g@epita.fr>
-dnl @version 2001-05-25
-dnl @license GPLWithACException
-
-AC_DEFUN([adl_COMPUTE_RELATIVE_PATHS],
-[for _lcl_i in $1; do
- _lcl_from=\[$]`echo "[$]_lcl_i" | sed 's,:.*$,,'`
- _lcl_to=\[$]`echo "[$]_lcl_i" | sed 's,^[[^:]]*:,,' | sed 's,:[[^:]]*$,,'`
- _lcl_result_var=`echo "[$]_lcl_i" | sed 's,^.*:,,'`
- adl_RECURSIVE_EVAL([[$]_lcl_from], [_lcl_from])
- adl_RECURSIVE_EVAL([[$]_lcl_to], [_lcl_to])
- _lcl_notation="$_lcl_from$_lcl_to"
- adl_NORMALIZE_PATH([_lcl_from],['/'])
- adl_NORMALIZE_PATH([_lcl_to],['/'])
- adl_COMPUTE_RELATIVE_PATH([_lcl_from], [_lcl_to], [_lcl_result_tmp])
- adl_NORMALIZE_PATH([_lcl_result_tmp],["[$]_lcl_notation"])
- eval $_lcl_result_var='[$]_lcl_result_tmp'
-done])
-
-## Note:
-## *****
-## The following helper macros are too fragile to be used out
-## of adl_COMPUTE_RELATIVE_PATHS (mainly because they assume that
-## paths are normalized), that's why I'm keeping them in the same file.
-## Still, some of them maybe worth to reuse.
-
-dnl adl_COMPUTE_RELATIVE_PATH(FROM, TO, RESULT)
-dnl ===========================================
-dnl Compute the relative path to go from $FROM to $TO and set the value
-dnl of $RESULT to that value. This function work on raw filenames
-dnl (for instead it will considerate /usr//local and /usr/local as
-dnl two distinct paths), you should really use adl_COMPUTE_REALTIVE_PATHS
-dnl instead to have the paths sanitized automatically.
-dnl
-dnl For instance:
-dnl first_dir=/somewhere/on/my/disk/bin
-dnl second_dir=/somewhere/on/another/disk/share
-dnl adl_COMPUTE_RELATIVE_PATH(first_dir, second_dir, first_to_second)
-dnl will set $first_to_second to '../../../another/disk/share'.
-AC_DEFUN([adl_COMPUTE_RELATIVE_PATH],
-[adl_COMPUTE_COMMON_PATH([$1], [$2], [_lcl_common_prefix])
-adl_COMPUTE_BACK_PATH([$1], [_lcl_common_prefix], [_lcl_first_rel])
-adl_COMPUTE_SUFFIX_PATH([$2], [_lcl_common_prefix], [_lcl_second_suffix])
-$3="[$]_lcl_first_rel[$]_lcl_second_suffix"])
-
-dnl adl_COMPUTE_COMMON_PATH(LEFT, RIGHT, RESULT)
-dnl ============================================
-dnl Compute the common path to $LEFT and $RIGHT and set the result to $RESULT.
-dnl
-dnl For instance:
-dnl first_path=/somewhere/on/my/disk/bin
-dnl second_path=/somewhere/on/another/disk/share
-dnl adl_COMPUTE_COMMON_PATH(first_path, second_path, common_path)
-dnl will set $common_path to '/somewhere/on'.
-AC_DEFUN([adl_COMPUTE_COMMON_PATH],
-[$3=''
-_lcl_second_prefix_match=''
-while test "[$]_lcl_second_prefix_match" != 0; do
- _lcl_first_prefix=`expr "x[$]$1" : "x\([$]$3/*[[^/]]*\)"`
- _lcl_second_prefix_match=`expr "x[$]$2" : "x[$]_lcl_first_prefix"`
- if test "[$]_lcl_second_prefix_match" != 0; then
- if test "[$]_lcl_first_prefix" != "[$]$3"; then
- $3="[$]_lcl_first_prefix"
- else
- _lcl_second_prefix_match=0
- fi
- fi
-done])
-
-dnl adl_COMPUTE_SUFFIX_PATH(PATH, SUBPATH, RESULT)
-dnl ==============================================
-dnl Substrack $SUBPATH from $PATH, and set the resulting suffix
-dnl (or the empty string if $SUBPATH is not a subpath of $PATH)
-dnl to $RESULT.
-dnl
-dnl For instace:
-dnl first_path=/somewhere/on/my/disk/bin
-dnl second_path=/somewhere/on
-dnl adl_COMPUTE_SUFFIX_PATH(first_path, second_path, common_path)
-dnl will set $common_path to '/my/disk/bin'.
-AC_DEFUN([adl_COMPUTE_SUFFIX_PATH],
-[$3=`expr "x[$]$1" : "x[$]$2/*\(.*\)"`])
-
-dnl adl_COMPUTE_BACK_PATH(PATH, SUBPATH, RESULT)
-dnl ============================================
-dnl Compute the relative path to go from $PATH to $SUBPATH, knowing that
-dnl $SUBPATH is a subpath of $PATH (any other words, only repeated '../'
-dnl should be needed to move from $PATH to $SUBPATH) and set the value
-dnl of $RESULT to that value. If $SUBPATH is not a subpath of PATH,
-dnl set $RESULT to the empty string.
-dnl
-dnl For instance:
-dnl first_path=/somewhere/on/my/disk/bin
-dnl second_path=/somewhere/on
-dnl adl_COMPUTE_BACK_PATH(first_path, second_path, back_path)
-dnl will set $back_path to '../../../'.
-AC_DEFUN([adl_COMPUTE_BACK_PATH],
-[adl_COMPUTE_SUFFIX_PATH([$1], [$2], [_lcl_first_suffix])
-$3=''
-_lcl_tmp='xxx'
-while test "[$]_lcl_tmp" != ''; do
- _lcl_tmp=`expr "x[$]_lcl_first_suffix" : "x[[^/]]*/*\(.*\)"`
- if test "[$]_lcl_first_suffix" != ''; then
- _lcl_first_suffix="[$]_lcl_tmp"
- $3="../[$]$3"
- fi
-done])
-
-
-dnl adl_RECURSIVE_EVAL(VALUE, RESULT)
-dnl =================================
-dnl Interpolate the VALUE in loop until it doesn't change,
-dnl and set the result to $RESULT.
-dnl WARNING: It's easy to get an infinite loop with some unsane input.
-AC_DEFUN([adl_RECURSIVE_EVAL],
-[_lcl_receval="$1"
-$2=`(test "x$prefix" = xNONE && prefix="$ac_default_prefix"
- test "x$exec_prefix" = xNONE && exec_prefix="${prefix}"
- _lcl_receval_old=''
- while test "[$]_lcl_receval_old" != "[$]_lcl_receval"; do
- _lcl_receval_old="[$]_lcl_receval"
- eval _lcl_receval="\"[$]_lcl_receval\""
- done
- echo "[$]_lcl_receval")`])
diff --git a/src/config/config.guess b/src/config/config.guess
index c4bd827a7bed..31e01efec3e3 100755
--- a/src/config/config.guess
+++ b/src/config/config.guess
@@ -1,8 +1,8 @@
#! /bin/sh
# Attempt to guess a canonical system name.
-# Copyright 1992-2016 Free Software Foundation, Inc.
+# Copyright 1992-2017 Free Software Foundation, Inc.
-timestamp='2016-05-15'
+timestamp='2017-11-07'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -15,7 +15,7 @@ timestamp='2016-05-15'
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with this program; if not, see <http://www.gnu.org/licenses/>.
+# along with this program; if not, see <https://www.gnu.org/licenses/>.
#
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
@@ -27,7 +27,7 @@ timestamp='2016-05-15'
# Originally written by Per Bothner; maintained since 2000 by Ben Elliston.
#
# You can get the latest version of this script from:
-# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess
+# https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess
#
# Please send patches to <config-patches@gnu.org>.
@@ -39,7 +39,7 @@ Usage: $0 [OPTION]
Output the configuration name of the system \`$me' is run on.
-Operation modes:
+Options:
-h, --help print this help, then exit
-t, --time-stamp print date of last modification, then exit
-v, --version print version number, then exit
@@ -50,7 +50,7 @@ version="\
GNU config.guess ($timestamp)
Originally written by Per Bothner.
-Copyright 1992-2016 Free Software Foundation, Inc.
+Copyright 1992-2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -244,6 +244,9 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'`
echo ${UNAME_MACHINE_ARCH}-unknown-libertybsd${UNAME_RELEASE}
exit ;;
+ *:MidnightBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-midnightbsd${UNAME_RELEASE}
+ exit ;;
*:ekkoBSD:*:*)
echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
exit ;;
@@ -259,6 +262,9 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
*:Sortix:*:*)
echo ${UNAME_MACHINE}-unknown-sortix
exit ;;
+ *:Redox:*:*)
+ echo ${UNAME_MACHINE}-unknown-redox
+ exit ;;
alpha:OSF1:*:*)
case $UNAME_RELEASE in
*4.0)
@@ -315,15 +321,6 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
exitcode=$?
trap '' 0
exit $exitcode ;;
- Alpha\ *:Windows_NT*:*)
- # How do we know it's Interix rather than the generic POSIX subsystem?
- # Should we change UNAME_MACHINE based on the output of uname instead
- # of the specific Alpha model?
- echo alpha-pc-interix
- exit ;;
- 21064:Windows_NT:50:3)
- echo alpha-dec-winnt3.5
- exit ;;
Amiga*:UNIX_System_V:4.0:*)
echo m68k-unknown-sysv4
exit ;;
@@ -485,13 +482,13 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
#endif
#if defined (host_mips) && defined (MIPSEB)
#if defined (SYSTYPE_SYSV)
- printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+ printf ("mips-mips-riscos%ssysv\\n", argv[1]); exit (0);
#endif
#if defined (SYSTYPE_SVR4)
- printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+ printf ("mips-mips-riscos%ssvr4\\n", argv[1]); exit (0);
#endif
#if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
- printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+ printf ("mips-mips-riscos%sbsd\\n", argv[1]); exit (0);
#endif
#endif
exit (-1);
@@ -614,7 +611,7 @@ EOF
*:AIX:*:*)
echo rs6000-ibm-aix
exit ;;
- ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+ ibmrt:4.4BSD:*|romp-ibm:4.4BSD:*)
echo romp-ibm-bsd4.4
exit ;;
ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and
@@ -635,8 +632,8 @@ EOF
9000/[34678]??:HP-UX:*:*)
HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
case "${UNAME_MACHINE}" in
- 9000/31? ) HP_ARCH=m68000 ;;
- 9000/[34]?? ) HP_ARCH=m68k ;;
+ 9000/31?) HP_ARCH=m68000 ;;
+ 9000/[34]??) HP_ARCH=m68k ;;
9000/[678][0-9][0-9])
if [ -x /usr/bin/getconf ]; then
sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
@@ -749,7 +746,7 @@ EOF
{ echo "$SYSTEM_NAME"; exit; }
echo unknown-hitachi-hiuxwe2
exit ;;
- 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+ 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:*)
echo hppa1.1-hp-bsd
exit ;;
9000/8??:4.3bsd:*:*)
@@ -758,7 +755,7 @@ EOF
*9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
echo hppa1.0-hp-mpeix
exit ;;
- hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+ hp7??:OSF1:*:* | hp8?[79]:OSF1:*:*)
echo hppa1.1-hp-osf
exit ;;
hp8??:OSF1:*:*)
@@ -837,10 +834,11 @@ EOF
UNAME_PROCESSOR=`/usr/bin/uname -p`
case ${UNAME_PROCESSOR} in
amd64)
- echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
- *)
- echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ UNAME_PROCESSOR=x86_64 ;;
+ i386)
+ UNAME_PROCESSOR=i586 ;;
esac
+ echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
exit ;;
i*:CYGWIN*:*)
echo ${UNAME_MACHINE}-pc-cygwin
@@ -854,10 +852,6 @@ EOF
*:MSYS*:*)
echo ${UNAME_MACHINE}-pc-msys
exit ;;
- i*:windows32*:*)
- # uname -m includes "-pc" on this system.
- echo ${UNAME_MACHINE}-mingw32
- exit ;;
i*:PW*:*)
echo ${UNAME_MACHINE}-pc-pw32
exit ;;
@@ -873,27 +867,12 @@ EOF
echo ia64-unknown-interix${UNAME_RELEASE}
exit ;;
esac ;;
- [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
- echo i${UNAME_MACHINE}-pc-mks
- exit ;;
- 8664:Windows_NT:*)
- echo x86_64-pc-mks
- exit ;;
- i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
- # How do we know it's Interix rather than the generic POSIX subsystem?
- # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
- # UNAME_MACHINE based on the output of uname instead of i386?
- echo i586-pc-interix
- exit ;;
i*:UWIN*:*)
echo ${UNAME_MACHINE}-pc-uwin
exit ;;
amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
echo x86_64-unknown-cygwin
exit ;;
- p*:CYGWIN*:*)
- echo powerpcle-unknown-cygwin
- exit ;;
prep*:SunOS:5.*:*)
echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit ;;
@@ -1000,6 +979,9 @@ EOF
eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; }
;;
+ mips64el:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
openrisc*:Linux:*:*)
echo or1k-unknown-linux-${LIBC}
exit ;;
@@ -1032,6 +1014,9 @@ EOF
ppcle:Linux:*:*)
echo powerpcle-unknown-linux-${LIBC}
exit ;;
+ riscv32:Linux:*:* | riscv64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
s390:Linux:*:* | s390x:Linux:*:*)
echo ${UNAME_MACHINE}-ibm-linux-${LIBC}
exit ;;
@@ -1090,7 +1075,7 @@ EOF
i*86:*DOS:*:*)
echo ${UNAME_MACHINE}-pc-msdosdjgpp
exit ;;
- i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
+ i*86:*:4.*:*)
UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
@@ -1297,14 +1282,21 @@ EOF
if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then
if [ "$CC_FOR_BUILD" != no_compiler_found ]; then
if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
- (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
- grep IS_64BIT_ARCH >/dev/null
+ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
+ grep IS_64BIT_ARCH >/dev/null
then
case $UNAME_PROCESSOR in
i386) UNAME_PROCESSOR=x86_64 ;;
powerpc) UNAME_PROCESSOR=powerpc64 ;;
esac
fi
+ # On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc
+ if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \
+ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
+ grep IS_PPC >/dev/null
+ then
+ UNAME_PROCESSOR=powerpc
+ fi
fi
elif test "$UNAME_PROCESSOR" = i386 ; then
# Avoid executing cc on OS X 10.9, as it ships with a stub
@@ -1328,15 +1320,18 @@ EOF
*:QNX:*:4*)
echo i386-pc-qnx
exit ;;
- NEO-?:NONSTOP_KERNEL:*:*)
+ NEO-*:NONSTOP_KERNEL:*:*)
echo neo-tandem-nsk${UNAME_RELEASE}
exit ;;
NSE-*:NONSTOP_KERNEL:*:*)
echo nse-tandem-nsk${UNAME_RELEASE}
exit ;;
- NSR-?:NONSTOP_KERNEL:*:*)
+ NSR-*:NONSTOP_KERNEL:*:*)
echo nsr-tandem-nsk${UNAME_RELEASE}
exit ;;
+ NSX-*:NONSTOP_KERNEL:*:*)
+ echo nsx-tandem-nsk${UNAME_RELEASE}
+ exit ;;
*:NonStop-UX:*:*)
echo mips-compaq-nonstopux
exit ;;
@@ -1408,16 +1403,28 @@ EOF
exit ;;
esac
+echo "$0: unable to guess system type" >&2
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}" in
+ mips:Linux | mips64:Linux)
+ # If we got here on MIPS GNU/Linux, output extra information.
+ cat >&2 <<EOF
+
+NOTE: MIPS GNU/Linux systems require a C compiler to fully recognize
+the system type. Please install a C compiler and try again.
+EOF
+ ;;
+esac
+
cat >&2 <<EOF
-$0: unable to guess system type
This script (version $timestamp), has failed to recognize the
-operating system you are using. If your script is old, overwrite
-config.guess and config.sub with the latest versions from:
+operating system you are using. If your script is old, overwrite *all*
+copies of config.guess and config.sub with the latest versions from:
- http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess
+ https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess
and
- http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub
+ https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub
If $0 has already been updated, send the following data and any
information you think might be pertinent to config-patches@gnu.org to
@@ -1449,7 +1456,7 @@ EOF
exit 1
# Local variables:
-# eval: (add-hook 'write-file-hooks 'time-stamp)
+# eval: (add-hook 'write-file-functions 'time-stamp)
# time-stamp-start: "timestamp='"
# time-stamp-format: "%:y-%02m-%02d"
# time-stamp-end: "'"
diff --git a/src/config/config.sub b/src/config/config.sub
index a1f8229449d2..00f68b8e5f3d 100755
--- a/src/config/config.sub
+++ b/src/config/config.sub
@@ -1,8 +1,8 @@
#! /bin/sh
# Configuration validation subroutine script.
-# Copyright 1992-2016 Free Software Foundation, Inc.
+# Copyright 1992-2017 Free Software Foundation, Inc.
-timestamp='2016-08-25'
+timestamp='2017-11-23'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -15,7 +15,7 @@ timestamp='2016-08-25'
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with this program; if not, see <http://www.gnu.org/licenses/>.
+# along with this program; if not, see <https://www.gnu.org/licenses/>.
#
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
@@ -33,7 +33,7 @@ timestamp='2016-08-25'
# Otherwise, we print the canonical config type on stdout and succeed.
# You can get the latest version of this script from:
-# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub
+# https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub
# This file is supposed to be the same for all GNU packages
# and recognize all the CPU types, system types and aliases
@@ -57,7 +57,7 @@ Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS
Canonicalize a configuration name.
-Operation modes:
+Options:
-h, --help print this help, then exit
-t, --time-stamp print date of last modification, then exit
-v, --version print version number, then exit
@@ -67,7 +67,7 @@ Report bugs and patches to <config-patches@gnu.org>."
version="\
GNU config.sub ($timestamp)
-Copyright 1992-2016 Free Software Foundation, Inc.
+Copyright 1992-2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -117,7 +117,7 @@ case $maybe_os in
nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \
- kopensolaris*-gnu* | \
+ kopensolaris*-gnu* | cloudabi*-eabi* | \
storm-chaos* | os2-emx* | rtmk-nova*)
os=-$maybe_os
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
@@ -229,9 +229,6 @@ case $os in
-ptx*)
basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
;;
- -windowsnt*)
- os=`echo $os | sed -e 's/windowsnt/winnt/'`
- ;;
-psos*)
os=-psos
;;
@@ -263,7 +260,7 @@ case $basic_machine in
| fido | fr30 | frv | ft32 \
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
| hexagon \
- | i370 | i860 | i960 | ia64 \
+ | i370 | i860 | i960 | ia16 | ia64 \
| ip2k | iq2000 \
| k1om \
| le32 | le64 \
@@ -301,6 +298,7 @@ case $basic_machine in
| open8 | or1k | or1knd | or32 \
| pdp10 | pdp11 | pj | pjl \
| powerpc | powerpc64 | powerpc64le | powerpcle \
+ | pru \
| pyramid \
| riscv32 | riscv64 \
| rl78 | rx \
@@ -314,7 +312,7 @@ case $basic_machine in
| ubicom32 \
| v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
| visium \
- | we32k \
+ | wasm32 \
| x86 | xc16x | xstormy16 | xtensa \
| z8k | z80)
basic_machine=$basic_machine-unknown
@@ -387,7 +385,7 @@ case $basic_machine in
| h8300-* | h8500-* \
| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
| hexagon-* \
- | i*86-* | i860-* | i960-* | ia64-* \
+ | i*86-* | i860-* | i960-* | ia16-* | ia64-* \
| ip2k-* | iq2000-* \
| k1om-* \
| le32-* | le64-* \
@@ -428,6 +426,7 @@ case $basic_machine in
| orion-* \
| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
+ | pru-* \
| pyramid-* \
| riscv32-* | riscv64-* \
| rl78-* | romp-* | rs6000-* | rx-* \
@@ -444,6 +443,7 @@ case $basic_machine in
| v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
| vax-* \
| visium-* \
+ | wasm32-* \
| we32k-* \
| x86-* | x86_64-* | xc16x-* | xps100-* \
| xstormy16-* | xtensa*-* \
@@ -639,7 +639,7 @@ case $basic_machine in
basic_machine=rs6000-bull
os=-bosx
;;
- dpx2* | dpx2*-bull)
+ dpx2*)
basic_machine=m68k-bull
os=-sysv3
;;
@@ -901,7 +901,7 @@ case $basic_machine in
basic_machine=v70-nec
os=-sysv
;;
- next | m*-next )
+ next | m*-next)
basic_machine=m68k-next
case $os in
-nextstep* )
@@ -946,6 +946,9 @@ case $basic_machine in
nsr-tandem)
basic_machine=nsr-tandem
;;
+ nsx-tandem)
+ basic_machine=nsx-tandem
+ ;;
op50n-* | op60c-*)
basic_machine=hppa1.1-oki
os=-proelf
@@ -1241,6 +1244,9 @@ case $basic_machine in
basic_machine=a29k-wrs
os=-vxworks
;;
+ wasm32)
+ basic_machine=wasm32-unknown
+ ;;
w65*)
basic_machine=w65-wdc
os=-none
@@ -1249,6 +1255,9 @@ case $basic_machine in
basic_machine=hppa1.1-winbond
os=-proelf
;;
+ x64)
+ basic_machine=x86_64-pc
+ ;;
xbox)
basic_machine=i686-pc
os=-mingw32
@@ -1356,8 +1365,8 @@ esac
if [ x"$os" != x"" ]
then
case $os in
- # First match some system type aliases
- # that might get confused with valid system types.
+ # First match some system type aliases that might get confused
+ # with valid system types.
# -solaris* is a basic system type, with this one exception.
-auroraux)
os=-auroraux
@@ -1377,9 +1386,9 @@ case $os in
-gnu/linux*)
os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
;;
- # First accept the basic system types.
+ # Now accept the basic system types.
# The portable systems comes first.
- # Each alternative MUST END IN A *, to match a version number.
+ # Each alternative MUST end in a * to match a version number.
# -sysv* is not here because it comes later, after sysvr4.
-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
| -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
@@ -1395,7 +1404,7 @@ case $os in
| -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
- | -chorusos* | -chorusrdb* | -cegcc* \
+ | -chorusos* | -chorusrdb* | -cegcc* | -glidix* \
| -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
| -midipix* | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
| -linux-newlib* | -linux-musl* | -linux-uclibc* \
@@ -1407,7 +1416,7 @@ case $os in
| -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
| -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
| -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \
- | -onefs* | -tirtos* | -phoenix*)
+ | -onefs* | -tirtos* | -phoenix* | -fuchsia* | -redox*)
# Remember, each alternative MUST END IN *, to match a version number.
;;
-qnx*)
@@ -1482,7 +1491,7 @@ case $os in
-nova*)
os=-rtmk-nova
;;
- -ns2 )
+ -ns2)
os=-nextstep2
;;
-nsk*)
@@ -1537,6 +1546,19 @@ case $os in
-dicos*)
os=-dicos
;;
+ -pikeos*)
+ # Until real need of OS specific support for
+ # particular features comes up, bare metal
+ # configurations are quite functional.
+ case $basic_machine in
+ arm*)
+ os=-eabi
+ ;;
+ *)
+ os=-elf
+ ;;
+ esac
+ ;;
-nacl*)
;;
-ios)
@@ -1636,6 +1658,9 @@ case $basic_machine in
sparc-* | *-sun)
os=-sunos4.1.1
;;
+ pru-*)
+ os=-elf
+ ;;
*-be)
os=-beos
;;
@@ -1681,7 +1706,7 @@ case $basic_machine in
m88k-omron*)
os=-luna
;;
- *-next )
+ *-next)
os=-nextstep
;;
*-sequent)
@@ -1816,7 +1841,7 @@ echo $basic_machine$os
exit
# Local variables:
-# eval: (add-hook 'write-file-hooks 'time-stamp)
+# eval: (add-hook 'write-file-functions 'time-stamp)
# time-stamp-start: "timestamp='"
# time-stamp-format: "%:y-%02m-%02d"
# time-stamp-end: "'"
diff --git a/src/config/post.in b/src/config/post.in
index 77a9bffdf3ed..3643abad1ce0 100644
--- a/src/config/post.in
+++ b/src/config/post.in
@@ -156,7 +156,7 @@ clean: clean-$(WHAT)
clean-unix::
$(RM) $(OBJS) $(DEPTARGETS_CLEAN) $(EXTRA_FILES)
- $(RM) et-[ch]-*.et et-[ch]-*.[ch] testlog
+ $(RM) et-[ch]-*.et et-[ch]-*.[ch] testlog testtrace
-$(RM) -r testdir
clean-windows::
@@ -185,7 +185,7 @@ $(top_srcdir)/configure: @MAINT@ \
$(top_srcdir)/patchlevel.h \
$(top_srcdir)/aclocal.m4
(cd $(top_srcdir) && \
- $(AUTOCONF) --include=$(CONFIG_RELTOPDIR) $(AUTOCONFFLAGS))
+ $(AUTOCONF) -f --include=$(CONFIG_RELTOPDIR) $(AUTOCONFFLAGS))
RECURSE_TARGETS=all-recurse clean-recurse distclean-recurse install-recurse \
generate-files-mac-recurse \
diff --git a/src/config/pre.in b/src/config/pre.in
index e0626320c6e7..3f267eb1fec6 100644
--- a/src/config/pre.in
+++ b/src/config/pre.in
@@ -7,7 +7,7 @@
# srcdir=@srcdir@
# top_srcdir=@top_srcdir@
# but these are only set by autoconf 2.53, and thus not useful to us on
-# Mac OS X yet (as of 10.2):
+# macOS yet (as of 10.2):
# abs_srcdir=@abs_srcdir@
# abs_top_srcdir=@abs_top_srcdir@
# builddir=@builddir@
@@ -402,10 +402,10 @@ HESIOD_LIBS = @HESIOD_LIBS@
KRB5_BASE_LIBS = $(KRB5_LIB) $(K5CRYPTO_LIB) $(COM_ERR_LIB) $(SUPPORT_LIB) $(GEN_LIB) $(LIBS) $(DL_LIB)
KDB5_LIBS = $(KDB5_LIB) $(GSSRPC_LIBS)
GSS_LIBS = $(GSS_KRB5_LIB)
-# needs fixing if ever used on Mac OS X!
+# needs fixing if ever used on macOS!
GSSRPC_LIBS = -lgssrpc $(GSS_LIBS)
KADM_COMM_LIBS = $(GSSRPC_LIBS)
-# need fixing if ever used on Mac OS X!
+# need fixing if ever used on macOS!
KADMSRV_LIBS = -lkadm5srv_mit $(HESIOD_LIBS) $(KDB5_LIBS) $(KADM_COMM_LIBS)
KADMCLNT_LIBS = -lkadm5clnt_mit $(KADM_COMM_LIBS)
@@ -435,11 +435,6 @@ TCL_INCLUDES = @TCL_INCLUDES@
CRYPTO_IMPL = @CRYPTO_IMPL@
PRNG_ALG = @PRNG_ALG@
-# Crypto back-end selection and flags for PKINIT
-PKINIT_CRYPTO_IMPL = @PKINIT_CRYPTO_IMPL@
-PKINIT_CRYPTO_IMPL_CFLAGS = @PKINIT_CRYPTO_IMPL_CFLAGS@
-PKINIT_CRYPTO_IMPL_LIBS = @PKINIT_CRYPTO_IMPL_LIBS@
-
# TLS implementation selection
TLS_IMPL = @TLS_IMPL@
TLS_IMPL_CFLAGS = @TLS_IMPL_CFLAGS@
@@ -451,6 +446,8 @@ HAVE_SASL = @HAVE_SASL@
# Whether we have libresolv 1.1.5 for URI discovery tests
HAVE_RESOLV_WRAPPER = @HAVE_RESOLV_WRAPPER@
+SIZEOF_TIME_T = @SIZEOF_TIME_T@
+
# error table rules
#
### /* these are invoked as $(...) foo.et, which works, but could be better */
diff --git a/src/configure b/src/configure
index 347016811691..dcb7bd72f350 100755
--- a/src/configure
+++ b/src/configure
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for Kerberos 5 1.15.1.
+# Generated by GNU Autoconf 2.69 for Kerberos 5 1.16.
#
# Report bugs to <krb5-bugs@mit.edu>.
#
@@ -584,8 +584,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='Kerberos 5'
PACKAGE_TARNAME='krb5'
-PACKAGE_VERSION='1.15.1'
-PACKAGE_STRING='Kerberos 5 1.15.1'
+PACKAGE_VERSION='1.16'
+PACKAGE_STRING='Kerberos 5 1.16'
PACKAGE_BUGREPORT='krb5-bugs@mit.edu'
PACKAGE_URL=''
@@ -681,6 +681,7 @@ SH5
SH
DO_TCL
KRB5_RCTMPDIR
+SIZEOF_TIME_T
SETENVOBJ
KSU_LIBS
EXTRA_SUPPORT_SYMS
@@ -701,9 +702,6 @@ YASM
TLS_IMPL_LIBS
TLS_IMPL_CFLAGS
TLS_IMPL
-PKINIT_CRYPTO_IMPL_LIBS
-PKINIT_CRYPTO_IMPL_CFLAGS
-PKINIT_CRYPTO_IMPL
PRNG_ALG
CRYPTO_IMPL_LIBS
CRYPTO_IMPL_CFLAGS
@@ -774,14 +772,15 @@ TCL_LIBPATH
TCL_LIBS
TCL_INCLUDES
KRB5_VERSION
-EGREP
-GREP
DL_LIB
THREAD_SUPPORT
PTHREAD_CFLAGS
PTHREAD_LIBS
PTHREAD_CC
-acx_pthread_config
+ax_pthread_config
+EGREP
+GREP
+SED
krb5_cv_host
host_os
host_vendor
@@ -886,11 +885,11 @@ enable_rpath
enable_profiled
with_tcl
enable_athena
+enable_nls
with_vague_errors
enable_audit_plugin
with_crypto_impl
with_prng_alg
-with_pkinit_crypto_impl
with_tls_impl
enable_aesni
enable_kdc_lookaside_cache
@@ -1462,7 +1461,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures Kerberos 5 1.15.1 to adapt to many kinds of systems.
+\`configure' configures Kerberos 5 1.16 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1532,7 +1531,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of Kerberos 5 1.15.1:";;
+ short | recursive ) echo "Configuration of Kerberos 5 1.16:";;
esac
cat <<\_ACEOF
@@ -1551,6 +1550,7 @@ Optional Features:
--disable-rpath suppress run path flags in link lines
--enable-athena build with MIT Project Athena configuration
+ --disable-nls disable native language support
--enable-audit-plugin=IMPL
use audit plugin [ do not use audit ]
--disable-aesni Do not build with AES-NI support
@@ -1575,8 +1575,6 @@ Optional Packages:
--with-vague-errors Do not [do] send helpful errors to client
--with-crypto-impl=IMPL use specified crypto implementation [builtin]
--with-prng-alg=ALG use specified PRNG algorithm. [fortuna]
- --with-pkinit-crypto-impl=IMPL
- use specified pkinit crypto implementation [openssl]
--with-tls-impl=IMPL use specified TLS implementation [auto]
--without-libedit do not compile with libedit
--with-readline compile with GNU Readline
@@ -1674,7 +1672,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-Kerberos 5 configure 1.15.1
+Kerberos 5 configure 1.16
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2238,11 +2236,194 @@ $as_echo "$ac_res" >&6; }
eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
} # ac_fn_c_check_decl
+
+# ac_fn_c_compute_int LINENO EXPR VAR INCLUDES
+# --------------------------------------------
+# Tries to find the compile-time value of EXPR in a program that includes
+# INCLUDES, setting VAR accordingly. Returns whether the value could be
+# computed
+ac_fn_c_compute_int ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if test "$cross_compiling" = yes; then
+ # Depending upon the size, compute the lo and hi bounds.
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) >= 0)];
+test_array [0] = 0;
+return test_array [0];
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_lo=0 ac_mid=0
+ while :; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) <= $ac_mid)];
+test_array [0] = 0;
+return test_array [0];
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_hi=$ac_mid; break
+else
+ as_fn_arith $ac_mid + 1 && ac_lo=$as_val
+ if test $ac_lo -le $ac_mid; then
+ ac_lo= ac_hi=
+ break
+ fi
+ as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ done
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) < 0)];
+test_array [0] = 0;
+return test_array [0];
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_hi=-1 ac_mid=-1
+ while :; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) >= $ac_mid)];
+test_array [0] = 0;
+return test_array [0];
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_lo=$ac_mid; break
+else
+ as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val
+ if test $ac_mid -le $ac_hi; then
+ ac_lo= ac_hi=
+ break
+ fi
+ as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ done
+else
+ ac_lo= ac_hi=
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+# Binary search between lo and hi bounds.
+while test "x$ac_lo" != "x$ac_hi"; do
+ as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) <= $ac_mid)];
+test_array [0] = 0;
+return test_array [0];
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_hi=$ac_mid
+else
+ as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+case $ac_lo in #((
+?*) eval "$3=\$ac_lo"; ac_retval=0 ;;
+'') ac_retval=1 ;;
+esac
+ else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+static long int longval () { return $2; }
+static unsigned long int ulongval () { return $2; }
+#include <stdio.h>
+#include <stdlib.h>
+int
+main ()
+{
+
+ FILE *f = fopen ("conftest.val", "w");
+ if (! f)
+ return 1;
+ if (($2) < 0)
+ {
+ long int i = longval ();
+ if (i != ($2))
+ return 1;
+ fprintf (f, "%ld", i);
+ }
+ else
+ {
+ unsigned long int i = ulongval ();
+ if (i != ($2))
+ return 1;
+ fprintf (f, "%lu", i);
+ }
+ /* Do not output a trailing newline, as this causes \r\n confusion
+ on some platforms. */
+ return ferror (f) || fclose (f) != 0;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ echo >>conftest.val; read $3 <conftest.val; ac_retval=0
+else
+ ac_retval=1
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+rm -f conftest.val
+
+ fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_compute_int
cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by Kerberos 5 $as_me 1.15.1, which was
+It was created by Kerberos 5 $as_me 1.16, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -3704,6 +3885,63 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $
ac_compiler_gnu=$ac_cv_c_compiler_gnu
+ cflags_warning_test_flags=
+ cachevar=`echo "krb5_cv_cc_flag_-Werror=unknown-warning-option" | sed -e s/=/_eq_/g -e s/-/_dash_/g -e s/[^a-zA-Z0-9_]/_/g`
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if C compiler supports -Werror=unknown-warning-option" >&5
+$as_echo_n "checking if C compiler supports -Werror=unknown-warning-option... " >&6; }
+if eval \${$cachevar+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ # first try without, then with
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+1;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ old_cflags="$CFLAGS"
+ CFLAGS="$CFLAGS $cflags_warning_test_flags -Werror=unknown-warning-option"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+1;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ eval $cachevar=yes
+else
+ eval $cachevar=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ CFLAGS="$old_cflags"
+else
+ as_fn_error $? "compiling simple test program with $CFLAGS failed" "$LINENO" 5
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$cachevar
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ if eval test '"${'$cachevar'}"' = yes; then
+ WARN_CFLAGS="$WARN_CFLAGS -Werror=unknown-warning-option"
+ fi
+ eval flag_supported='${'$cachevar'}'
+
+ if test $flag_supported = yes; then
+ cflags_warning_test_flags=-Werror=unknown-warning-option
+ fi
+
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -3923,6 +4161,75 @@ IFS=$ac_save_IFS
case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5
+$as_echo_n "checking for a sed that does not truncate output... " >&6; }
+if ${ac_cv_path_SED+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/
+ for ac_i in 1 2 3 4 5 6 7; do
+ ac_script="$ac_script$as_nl$ac_script"
+ done
+ echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed
+ { ac_script=; unset ac_script;}
+ if test -z "$SED"; then
+ ac_path_SED_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in sed gsed; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_SED="$as_dir/$ac_prog$ac_exec_ext"
+ as_fn_executable_p "$ac_path_SED" || continue
+# Check for GNU ac_path_SED and select it if it is found.
+ # Check for GNU $ac_path_SED
+case `"$ac_path_SED" --version 2>&1` in
+*GNU*)
+ ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo '' >> "conftest.nl"
+ "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_SED_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_SED="$ac_path_SED"
+ ac_path_SED_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_SED_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_SED"; then
+ as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5
+ fi
+else
+ ac_cv_path_SED=$SED
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5
+$as_echo "$ac_cv_path_SED" >&6; }
+ SED="$ac_cv_path_SED"
+ rm -f conftest.sed
+
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
if ${ac_cv_path_GREP+:} false; then :
@@ -4289,7 +4596,7 @@ main ()
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
old_cflags="$CFLAGS"
- CFLAGS="$CFLAGS -Wno-format-zero-length"
+ CFLAGS="$CFLAGS $cflags_warning_test_flags -Wno-format-zero-length"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
@@ -4323,7 +4630,7 @@ $as_echo "$ac_res" >&6; }
# Other flags here may not be supported on some versions of
# gcc that people want to use.
- for flag in overflow strict-overflow missing-format-attribute missing-prototypes return-type missing-braces parentheses switch unused-function unused-label unused-variable unused-value unknown-pragmas sign-compare newline-eof error=uninitialized error=pointer-arith error=int-conversion error=incompatible-pointer-types error=discarded-qualifiers ; do
+ for flag in overflow strict-overflow missing-format-attribute missing-prototypes return-type missing-braces parentheses switch unused-function unused-label unused-variable unused-value unknown-pragmas sign-compare newline-eof error=uninitialized no-maybe-uninitialized error=pointer-arith error=int-conversion error=incompatible-pointer-types error=discarded-qualifiers error=implicit-int ; do
cachevar=`echo "krb5_cv_cc_flag_-W$flag" | sed -e s/=/_eq_/g -e s/-/_dash_/g -e s/[^a-zA-Z0-9_]/_/g`
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if C compiler supports -W$flag" >&5
$as_echo_n "checking if C compiler supports -W$flag... " >&6; }
@@ -4344,7 +4651,7 @@ main ()
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
old_cflags="$CFLAGS"
- CFLAGS="$CFLAGS -W$flag"
+ CFLAGS="$CFLAGS $cflags_warning_test_flags -W$flag"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
@@ -4411,7 +4718,7 @@ main ()
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
old_cflags="$CFLAGS"
- CFLAGS="$CFLAGS -Werror=$flag"
+ CFLAGS="$CFLAGS $cflags_warning_test_flags -Werror=$flag"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
@@ -4464,7 +4771,7 @@ main ()
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
old_cflags="$CFLAGS"
- CFLAGS="$CFLAGS -W$flag"
+ CFLAGS="$CFLAGS $cflags_warning_test_flags -W$flag"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
@@ -4525,7 +4832,7 @@ main ()
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
old_cflags="$CFLAGS"
- CFLAGS="$CFLAGS -Werror-implicit-function-declaration"
+ CFLAGS="$CFLAGS $cflags_warning_test_flags -Werror-implicit-function-declaration"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
@@ -4578,7 +4885,7 @@ main ()
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
old_cflags="$CFLAGS"
- CFLAGS="$CFLAGS -Werror=implicit-function-declaration"
+ CFLAGS="$CFLAGS $cflags_warning_test_flags -Werror=implicit-function-declaration"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
@@ -4668,8 +4975,18 @@ $as_echo "$as_me: adding -O for inline thread-support function elimination" >&6;
# works, but it also means that declaration-in-code warnings won't
# be issued.
# -v -fd -errwarn=E_DECLARATION_IN_CODE ...
- WARN_CFLAGS="-errtags=yes -errwarn=E_BAD_PTR_INT_COMBINATION,E_BAD_PTR_INT_COMB_ARG,E_PTR_TO_VOID_IN_ARITHMETIC,E_NO_IMPLICIT_DECL_ALLOWED,E_ATTRIBUTE_PARAM_UNDEFINED"
- WARN_CXXFLAGS="-errtags=yes +w +w2 -xport64"
+ if test "x$krb5_ac_warn_cflags_set" = xset ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: not adding extra warning flags because WARN_CFLAGS was set" >&5
+$as_echo "$as_me: not adding extra warning flags because WARN_CFLAGS was set" >&6;}
+ else
+ WARN_CFLAGS="-errtags=yes -errwarn=E_BAD_PTR_INT_COMBINATION,E_BAD_PTR_INT_COMB_ARG,E_PTR_TO_VOID_IN_ARITHMETIC,E_NO_IMPLICIT_DECL_ALLOWED,E_ATTRIBUTE_PARAM_UNDEFINED"
+ fi
+ if test "x$krb5_ac_warn_cxxflags_set" = xset ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: not adding extra warning flags because WARN_CXXFLAGS was set" >&5
+$as_echo "$as_me: not adding extra warning flags because WARN_CXXFLAGS was set" >&6;}
+ else
+ WARN_CXXFLAGS="-errtags=yes +w +w2 -xport64"
+ fi
fi
fi
@@ -5808,28 +6125,33 @@ if test "$enable_thread_support" = yes; then
+
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_c_compiler_gnu
-acx_pthread_ok=no
+ax_pthread_ok=no
# We used to check for pthread.h first, but this fails if pthread.h
-# requires special compiler flags (e.g. on True64 or Sequent).
+# requires special compiler flags (e.g. on Tru64 or Sequent).
# It gets checked for in the link test anyway.
# First of all, check if the user has set any of the PTHREAD_LIBS,
# etcetera environment variables, and if threads linking works using
# them:
-if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then
- save_CFLAGS="$CFLAGS"
+if test "x$PTHREAD_CFLAGS$PTHREAD_LIBS" != "x"; then
+ ax_pthread_save_CC="$CC"
+ ax_pthread_save_CFLAGS="$CFLAGS"
+ ax_pthread_save_LIBS="$LIBS"
+ if test "x$PTHREAD_CC" != "x"; then :
+ CC="$PTHREAD_CC"
+fi
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
- save_LIBS="$LIBS"
LIBS="$PTHREAD_LIBS $LIBS"
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS" >&5
-$as_echo_n "checking for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_join using $CC $PTHREAD_CFLAGS $PTHREAD_LIBS" >&5
+$as_echo_n "checking for pthread_join using $CC $PTHREAD_CFLAGS $PTHREAD_LIBS... " >&6; }
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
@@ -5849,18 +6171,19 @@ return pthread_join ();
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
- acx_pthread_ok=yes
+ ax_pthread_ok=yes
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $acx_pthread_ok" >&5
-$as_echo "$acx_pthread_ok" >&6; }
- if test x"$acx_pthread_ok" = xno; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_pthread_ok" >&5
+$as_echo "$ax_pthread_ok" >&6; }
+ if test "x$ax_pthread_ok" = "xno"; then
PTHREAD_LIBS=""
PTHREAD_CFLAGS=""
fi
- LIBS="$save_LIBS"
- CFLAGS="$save_CFLAGS"
+ CC="$ax_pthread_save_CC"
+ CFLAGS="$ax_pthread_save_CFLAGS"
+ LIBS="$ax_pthread_save_LIBS"
fi
# We must check for the threads library under a number of different
@@ -5873,7 +6196,7 @@ fi
# which indicates that we try without any flags at all, and "pthread-config"
# which is a program returning the flags for the Pth emulation library.
-acx_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
+ax_pthread_flags="pthreads none -Kthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
# The ordering *is* (sometimes) important. Some notes on the
# individual items follow:
@@ -5882,58 +6205,269 @@ acx_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -m
# none: in case threads are in libc; should be tried before -Kthread and
# other compiler flags to prevent continual compiler warnings
# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
-# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
-# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
-# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads)
-# -pthreads: Solaris/gcc
-# -mthreads: Mingw32/gcc, Lynx/gcc
+# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads), Tru64
+# (Note: HP C rejects this with "bad form for `-t' option")
+# -pthreads: Solaris/gcc (Note: HP C also rejects)
# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
-# doesn't hurt to check since this sometimes defines pthreads too;
-# also defines -D_REENTRANT)
+# doesn't hurt to check since this sometimes defines pthreads and
+# -D_REENTRANT too), HP C (must be checked before -lpthread, which
+# is present but should not be used directly; and before -mthreads,
+# because the compiler interprets this as "-mt" + "-hreads")
+# -mthreads: Mingw32/gcc, Lynx/gcc
# pthread: Linux, etcetera
# --thread-safe: KAI C++
# pthread-config: use pthread-config program (for GNU Pth library)
-case "${host_cpu}-${host_os}" in
- *solaris*)
+case $host_os in
+
+ freebsd*)
+
+ # -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
+ # lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
+
+ ax_pthread_flags="-kthread lthread $ax_pthread_flags"
+ ;;
+
+ hpux*)
+
+ # From the cc(1) man page: "[-mt] Sets various -D flags to enable
+ # multi-threading and also sets -lpthread."
+
+ ax_pthread_flags="-mt -pthread pthread $ax_pthread_flags"
+ ;;
+
+ openedition*)
+
+ # IBM z/OS requires a feature-test macro to be defined in order to
+ # enable POSIX threads at all, so give the user a hint if this is
+ # not set. (We don't define these ourselves, as they can affect
+ # other portions of the system API in unpredictable ways.)
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+# if !defined(_OPEN_THREADS) && !defined(_UNIX03_THREADS)
+ AX_PTHREAD_ZOS_MISSING
+# endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "AX_PTHREAD_ZOS_MISSING" >/dev/null 2>&1; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: IBM z/OS requires -D_OPEN_THREADS or -D_UNIX03_THREADS to enable pthreads support." >&5
+$as_echo "$as_me: WARNING: IBM z/OS requires -D_OPEN_THREADS or -D_UNIX03_THREADS to enable pthreads support." >&2;}
+fi
+rm -f conftest*
+
+ ;;
+
+ solaris*)
# On Solaris (at least, for some versions), libc contains stubbed
# (non-functional) versions of the pthreads routines, so link-based
- # tests will erroneously succeed. (We need to link with -pthread or
- # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather
- # a function called by this macro, so we could check for that, but
- # who knows whether they'll stub that too in a future libc.) So,
- # we'll just look for -pthreads and -lpthread first:
+ # tests will erroneously succeed. (N.B.: The stubs are missing
+ # pthread_cleanup_push, or rather a function called by this macro,
+ # so we could check for that, but who knows whether they'll stub
+ # that too in a future libc.) So we'll check first for the
+ # standard Solaris way of linking pthreads (-mt -lpthread).
- acx_pthread_flags="-pthread -pthreads pthread -mt $acx_pthread_flags"
+ ax_pthread_flags="-mt,pthread pthread $ax_pthread_flags"
;;
esac
-if test x"$acx_pthread_ok" = xno; then
-for flag in $acx_pthread_flags; do
+# GCC generally uses -pthread, or -pthreads on some platforms (e.g. SPARC)
+
+if test "x$GCC" = "xyes"; then :
+ ax_pthread_flags="-pthread -pthreads $ax_pthread_flags"
+fi
- case $flag in
+# The presence of a feature test macro requesting re-entrant function
+# definitions is, on some systems, a strong hint that pthreads support is
+# correctly enabled
+
+case $host_os in
+ darwin* | hpux* | linux* | osf* | solaris*)
+ ax_pthread_check_macro="_REENTRANT"
+ ;;
+
+ aix*)
+ ax_pthread_check_macro="_THREAD_SAFE"
+ ;;
+
+ *)
+ ax_pthread_check_macro="--"
+ ;;
+esac
+if test "x$ax_pthread_check_macro" = "x--"; then :
+ ax_pthread_check_cond=0
+else
+ ax_pthread_check_cond="!defined($ax_pthread_check_macro)"
+fi
+
+# Are we compiling with Clang?
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC is Clang" >&5
+$as_echo_n "checking whether $CC is Clang... " >&6; }
+if ${ax_cv_PTHREAD_CLANG+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ax_cv_PTHREAD_CLANG=no
+ # Note that Autoconf sets GCC=yes for Clang as well as GCC
+ if test "x$GCC" = "xyes"; then
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+/* Note: Clang 2.7 lacks __clang_[a-z]+__ */
+# if defined(__clang__) && defined(__llvm__)
+ AX_PTHREAD_CC_IS_CLANG
+# endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "AX_PTHREAD_CC_IS_CLANG" >/dev/null 2>&1; then :
+ ax_cv_PTHREAD_CLANG=yes
+fi
+rm -f conftest*
+
+ fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_PTHREAD_CLANG" >&5
+$as_echo "$ax_cv_PTHREAD_CLANG" >&6; }
+ax_pthread_clang="$ax_cv_PTHREAD_CLANG"
+
+ax_pthread_clang_warning=no
+
+# Clang needs special handling, because older versions handle the -pthread
+# option in a rather... idiosyncratic way
+
+if test "x$ax_pthread_clang" = "xyes"; then
+
+ # Clang takes -pthread; it has never supported any other flag
+
+ # (Note 1: This will need to be revisited if a system that Clang
+ # supports has POSIX threads in a separate library. This tends not
+ # to be the way of modern systems, but it's conceivable.)
+
+ # (Note 2: On some systems, notably Darwin, -pthread is not needed
+ # to get POSIX threads support; the API is always present and
+ # active. We could reasonably leave PTHREAD_CFLAGS empty. But
+ # -pthread does define _REENTRANT, and while the Darwin headers
+ # ignore this macro, third-party headers might not.)
+
+ PTHREAD_CFLAGS="-pthread"
+ PTHREAD_LIBS=
+
+ ax_pthread_ok=yes
+
+ # However, older versions of Clang make a point of warning the user
+ # that, in an invocation where only linking and no compilation is
+ # taking place, the -pthread option has no effect ("argument unused
+ # during compilation"). They expect -pthread to be passed in only
+ # when source code is being compiled.
+ #
+ # Problem is, this is at odds with the way Automake and most other
+ # C build frameworks function, which is that the same flags used in
+ # compilation (CFLAGS) are also used in linking. Many systems
+ # supported by AX_PTHREAD require exactly this for POSIX threads
+ # support, and in fact it is often not straightforward to specify a
+ # flag that is used only in the compilation phase and not in
+ # linking. Such a scenario is extremely rare in practice.
+ #
+ # Even though use of the -pthread flag in linking would only print
+ # a warning, this can be a nuisance for well-run software projects
+ # that build with -Werror. So if the active version of Clang has
+ # this misfeature, we search for an option to squash it.
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether Clang needs flag to prevent \"argument unused\" warning when linking with -pthread" >&5
+$as_echo_n "checking whether Clang needs flag to prevent \"argument unused\" warning when linking with -pthread... " >&6; }
+if ${ax_cv_PTHREAD_CLANG_NO_WARN_FLAG+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ax_cv_PTHREAD_CLANG_NO_WARN_FLAG=unknown
+ # Create an alternate version of $ac_link that compiles and
+ # links in two steps (.c -> .o, .o -> exe) instead of one
+ # (.c -> exe), because the warning occurs only in the second
+ # step
+ ax_pthread_save_ac_link="$ac_link"
+ ax_pthread_sed='s/conftest\.\$ac_ext/conftest.$ac_objext/g'
+ ax_pthread_link_step=`$as_echo "$ac_link" | sed "$ax_pthread_sed"`
+ ax_pthread_2step_ac_link="($ac_compile) && (echo ==== >&5) && ($ax_pthread_link_step)"
+ ax_pthread_save_CFLAGS="$CFLAGS"
+ for ax_pthread_try in '' -Qunused-arguments -Wno-unused-command-line-argument unknown; do
+ if test "x$ax_pthread_try" = "xunknown"; then :
+ break
+fi
+ CFLAGS="-Werror -Wunknown-warning-option $ax_pthread_try -pthread $ax_pthread_save_CFLAGS"
+ ac_link="$ax_pthread_save_ac_link"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+int main(void){return 0;}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_link="$ax_pthread_2step_ac_link"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+int main(void){return 0;}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ break
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ done
+ ac_link="$ax_pthread_save_ac_link"
+ CFLAGS="$ax_pthread_save_CFLAGS"
+ if test "x$ax_pthread_try" = "x"; then :
+ ax_pthread_try=no
+fi
+ ax_cv_PTHREAD_CLANG_NO_WARN_FLAG="$ax_pthread_try"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" >&5
+$as_echo "$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" >&6; }
+
+ case "$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" in
+ no | unknown) ;;
+ *) PTHREAD_CFLAGS="$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG $PTHREAD_CFLAGS" ;;
+ esac
+
+fi # $ax_pthread_clang = yes
+
+if test "x$ax_pthread_ok" = "xno"; then
+for ax_pthread_try_flag in $ax_pthread_flags; do
+
+ case $ax_pthread_try_flag in
none)
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pthreads work without any flags" >&5
$as_echo_n "checking whether pthreads work without any flags... " >&6; }
;;
+ -mt,pthread)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pthreads work with -mt -lpthread" >&5
+$as_echo_n "checking whether pthreads work with -mt -lpthread... " >&6; }
+ PTHREAD_CFLAGS="-mt"
+ PTHREAD_LIBS="-lpthread"
+ ;;
+
-*)
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pthreads work with $flag" >&5
-$as_echo_n "checking whether pthreads work with $flag... " >&6; }
- PTHREAD_CFLAGS="$flag"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pthreads work with $ax_pthread_try_flag" >&5
+$as_echo_n "checking whether pthreads work with $ax_pthread_try_flag... " >&6; }
+ PTHREAD_CFLAGS="$ax_pthread_try_flag"
;;
- pthread-config)
- # Extract the first word of "pthread-config", so it can be a program name with args.
+ pthread-config)
+ # Extract the first word of "pthread-config", so it can be a program name with args.
set dummy pthread-config; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_acx_pthread_config+:} false; then :
+if ${ac_cv_prog_ax_pthread_config+:} false; then :
$as_echo_n "(cached) " >&6
else
- if test -n "$acx_pthread_config"; then
- ac_cv_prog_acx_pthread_config="$acx_pthread_config" # Let the user override the test.
+ if test -n "$ax_pthread_config"; then
+ ac_cv_prog_ax_pthread_config="$ax_pthread_config" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
@@ -5942,7 +6476,7 @@ do
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_prog_acx_pthread_config="yes"
+ ac_cv_prog_ax_pthread_config="yes"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
@@ -5950,35 +6484,37 @@ done
done
IFS=$as_save_IFS
- test -z "$ac_cv_prog_acx_pthread_config" && ac_cv_prog_acx_pthread_config="no"
+ test -z "$ac_cv_prog_ax_pthread_config" && ac_cv_prog_ax_pthread_config="no"
fi
fi
-acx_pthread_config=$ac_cv_prog_acx_pthread_config
-if test -n "$acx_pthread_config"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $acx_pthread_config" >&5
-$as_echo "$acx_pthread_config" >&6; }
+ax_pthread_config=$ac_cv_prog_ax_pthread_config
+if test -n "$ax_pthread_config"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_pthread_config" >&5
+$as_echo "$ax_pthread_config" >&6; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
- if test x"$acx_pthread_config" = xno; then continue; fi
- PTHREAD_CFLAGS="`pthread-config --cflags`"
- PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
- ;;
+ if test "x$ax_pthread_config" = "xno"; then :
+ continue
+fi
+ PTHREAD_CFLAGS="`pthread-config --cflags`"
+ PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
+ ;;
*)
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for the pthreads library -l$flag" >&5
-$as_echo_n "checking for the pthreads library -l$flag... " >&6; }
- PTHREAD_LIBS="-l$flag"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for the pthreads library -l$ax_pthread_try_flag" >&5
+$as_echo_n "checking for the pthreads library -l$ax_pthread_try_flag... " >&6; }
+ PTHREAD_LIBS="-l$ax_pthread_try_flag"
;;
esac
- save_LIBS="$LIBS"
- save_CFLAGS="$CFLAGS"
- LIBS="$PTHREAD_LIBS $LIBS"
+ ax_pthread_save_CFLAGS="$CFLAGS"
+ ax_pthread_save_LIBS="$LIBS"
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+ LIBS="$PTHREAD_LIBS $LIBS"
# Check for various functions. We must include pthread.h,
# since some functions may be macros. (On the Sequent, we
@@ -5989,33 +6525,42 @@ $as_echo_n "checking for the pthreads library -l$flag... " >&6; }
# pthread_cleanup_push because it is one of the few pthread
# functions on Solaris that doesn't have a non-functional libc stub.
# We try pthread_create on general principles.
+
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <pthread.h>
+# if $ax_pthread_check_cond
+# error "$ax_pthread_check_macro must be defined"
+# endif
+ static void routine(void *a) { a = 0; }
+ static void *start_routine(void *a) { return a; }
int
main ()
{
-pthread_t th; pthread_join(th, 0);
- pthread_attr_init(0); pthread_cleanup_push(0, 0);
- pthread_create(0,0,0,0); pthread_cleanup_pop(0);
+pthread_t th; pthread_attr_t attr;
+ pthread_create(&th, 0, start_routine, 0);
+ pthread_join(th, 0);
+ pthread_attr_init(&attr);
+ pthread_cleanup_push(routine, 0);
+ pthread_cleanup_pop(0) /* ; */
;
return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
- acx_pthread_ok=yes
+ ax_pthread_ok=yes
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
- LIBS="$save_LIBS"
- CFLAGS="$save_CFLAGS"
+ CFLAGS="$ax_pthread_save_CFLAGS"
+ LIBS="$ax_pthread_save_LIBS"
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $acx_pthread_ok" >&5
-$as_echo "$acx_pthread_ok" >&6; }
- if test "x$acx_pthread_ok" = xyes; then
- break;
- fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_pthread_ok" >&5
+$as_echo "$ax_pthread_ok" >&6; }
+ if test "x$ax_pthread_ok" = "xyes"; then :
+ break
+fi
PTHREAD_LIBS=""
PTHREAD_CFLAGS=""
@@ -6023,85 +6568,130 @@ done
fi
# Various other checks:
-if test "x$acx_pthread_ok" = xyes; then
- save_LIBS="$LIBS"
- LIBS="$PTHREAD_LIBS $LIBS"
- save_CFLAGS="$CFLAGS"
+if test "x$ax_pthread_ok" = "xyes"; then
+ ax_pthread_save_CFLAGS="$CFLAGS"
+ ax_pthread_save_LIBS="$LIBS"
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+ LIBS="$PTHREAD_LIBS $LIBS"
- # Detect AIX lossage: threads are created detached by default
- # and the JOINABLE attribute has a nonstandard name (UNDETACHED).
+ # Detect AIX lossage: JOINABLE attribute is called UNDETACHED.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for joinable pthread attribute" >&5
$as_echo_n "checking for joinable pthread attribute... " >&6; }
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+if ${ax_cv_PTHREAD_JOINABLE_ATTR+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ax_cv_PTHREAD_JOINABLE_ATTR=unknown
+ for ax_pthread_attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <pthread.h>
int
main ()
{
-int attr=PTHREAD_CREATE_JOINABLE;
+int attr = $ax_pthread_attr; return attr /* ; */
;
return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
- ok=PTHREAD_CREATE_JOINABLE
-else
- ok=unknown
+ ax_cv_PTHREAD_JOINABLE_ATTR=$ax_pthread_attr; break
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
- if test x"$ok" = xunknown; then
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ done
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_PTHREAD_JOINABLE_ATTR" >&5
+$as_echo "$ax_cv_PTHREAD_JOINABLE_ATTR" >&6; }
+ if test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xunknown" && \
+ test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xPTHREAD_CREATE_JOINABLE" && \
+ test "x$ax_pthread_joinable_attr_defined" != "xyes"; then :
+
+cat >>confdefs.h <<_ACEOF
+#define PTHREAD_CREATE_JOINABLE $ax_cv_PTHREAD_JOINABLE_ATTR
+_ACEOF
+
+ ax_pthread_joinable_attr_defined=yes
+
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether more special flags are required for pthreads" >&5
+$as_echo_n "checking whether more special flags are required for pthreads... " >&6; }
+if ${ax_cv_PTHREAD_SPECIAL_FLAGS+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ax_cv_PTHREAD_SPECIAL_FLAGS=no
+ case $host_os in
+ solaris*)
+ ax_cv_PTHREAD_SPECIAL_FLAGS="-D_POSIX_PTHREAD_SEMANTICS"
+ ;;
+ esac
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_PTHREAD_SPECIAL_FLAGS" >&5
+$as_echo "$ax_cv_PTHREAD_SPECIAL_FLAGS" >&6; }
+ if test "x$ax_cv_PTHREAD_SPECIAL_FLAGS" != "xno" && \
+ test "x$ax_pthread_special_flags_added" != "xyes"; then :
+ PTHREAD_CFLAGS="$ax_cv_PTHREAD_SPECIAL_FLAGS $PTHREAD_CFLAGS"
+ ax_pthread_special_flags_added=yes
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for PTHREAD_PRIO_INHERIT" >&5
+$as_echo_n "checking for PTHREAD_PRIO_INHERIT... " >&6; }
+if ${ax_cv_PTHREAD_PRIO_INHERIT+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <pthread.h>
int
main ()
{
-int attr=PTHREAD_CREATE_UNDETACHED;
+int i = PTHREAD_PRIO_INHERIT;
;
return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
- ok=PTHREAD_CREATE_UNDETACHED
+ ax_cv_PTHREAD_PRIO_INHERIT=yes
else
- ok=unknown
+ ax_cv_PTHREAD_PRIO_INHERIT=no
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
- fi
- if test x"$ok" != xPTHREAD_CREATE_JOINABLE; then
-$as_echo "#define PTHREAD_CREATE_JOINABLE \$ok" >>confdefs.h
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_PTHREAD_PRIO_INHERIT" >&5
+$as_echo "$ax_cv_PTHREAD_PRIO_INHERIT" >&6; }
+ if test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes" && \
+ test "x$ax_pthread_prio_inherit_defined" != "xyes"; then :
- fi
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${ok}" >&5
-$as_echo "${ok}" >&6; }
- if test x"$ok" = xunknown; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: we do not know how to create joinable pthreads" >&5
-$as_echo "$as_me: WARNING: we do not know how to create joinable pthreads" >&2;}
- fi
+$as_echo "#define HAVE_PTHREAD_PRIO_INHERIT 1" >>confdefs.h
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking if more special flags are required for pthreads" >&5
-$as_echo_n "checking if more special flags are required for pthreads... " >&6; }
- flag=no
- case "${host_cpu}-${host_os}" in
- *-aix* | *-freebsd*) flag="-D_THREAD_SAFE";;
- *solaris* | *-osf* | *-hpux*) flag="-D_REENTRANT";;
- esac
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${flag}" >&5
-$as_echo "${flag}" >&6; }
- if test "x$flag" != xno; then
- PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS"
- fi
+ ax_pthread_prio_inherit_defined=yes
- LIBS="$save_LIBS"
- CFLAGS="$save_CFLAGS"
+fi
+
+ CFLAGS="$ax_pthread_save_CFLAGS"
+ LIBS="$ax_pthread_save_LIBS"
- # More AIX lossage: must compile with cc_r
- # Extract the first word of "cc_r", so it can be a program name with args.
-set dummy cc_r; ac_word=$2
+ # More AIX lossage: compile with *_r variant
+ if test "x$GCC" != "xyes"; then
+ case $host_os in
+ aix*)
+ case "x/$CC" in #(
+ x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6) :
+ #handle absolute path differently from PATH based program lookup
+ case "x$CC" in #(
+ x/*) :
+ if as_fn_executable_p ${CC}_r; then :
+ PTHREAD_CC="${CC}_r"
+fi ;; #(
+ *) :
+ for ac_prog in ${CC}_r
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_PTHREAD_CC+:} false; then :
@@ -6117,7 +6707,7 @@ do
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_prog_PTHREAD_CC="cc_r"
+ ac_cv_prog_PTHREAD_CC="$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
@@ -6125,7 +6715,6 @@ done
done
IFS=$as_save_IFS
- test -z "$ac_cv_prog_PTHREAD_CC" && ac_cv_prog_PTHREAD_CC="${CC}"
fi
fi
PTHREAD_CC=$ac_cv_prog_PTHREAD_CC
@@ -6138,22 +6727,33 @@ $as_echo "no" >&6; }
fi
-else
- PTHREAD_CC="$CC"
+ test -n "$PTHREAD_CC" && break
+done
+test -n "$PTHREAD_CC" || PTHREAD_CC="$CC"
+ ;;
+esac ;; #(
+ *) :
+ ;;
+esac
+ ;;
+ esac
+ fi
fi
+test -n "$PTHREAD_CC" || PTHREAD_CC="$CC"
+
# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
-if test x"$acx_pthread_ok" = xyes; then
+if test "x$ax_pthread_ok" = "xyes"; then
$as_echo "#define HAVE_PTHREAD 1" >>confdefs.h
:
else
- acx_pthread_ok=no
+ ax_pthread_ok=no
as_fn_error $? "cannot determine options for enabling thread support; try --disable-thread-support" "$LINENO" 5
fi
ac_ext=c
@@ -6463,7 +7063,7 @@ done
-KRB5_VERSION=1.15.1
+KRB5_VERSION=1.16
@@ -7755,20 +8355,12 @@ res1=`echo "$res1" | tr -d '*' | sed -e 's/ *$//'`
res2=`echo "$res2" | tr -d '*' | sed -e 's/ *$//'`
cat >>confdefs.h <<_ACEOF
-#define GETSOCKNAME_ARG2_TYPE $res1
-_ACEOF
-
-
-cat >>confdefs.h <<_ACEOF
#define GETSOCKNAME_ARG3_TYPE $res2
_ACEOF
-$as_echo "#define GETPEERNAME_ARG2_TYPE GETSOCKNAME_ARG2_TYPE" >>confdefs.h
-
-
$as_echo "#define GETPEERNAME_ARG3_TYPE GETSOCKNAME_ARG3_TYPE" >>confdefs.h
@@ -7813,10 +8405,20 @@ fi
-ac_fn_c_check_header_mongrel "$LINENO" "libintl.h" "ac_cv_header_libintl_h" "$ac_includes_default"
+# Determine if NLS is desired and supported.
+po=
+# Check whether --enable-nls was given.
+if test "${enable_nls+set}" = set; then :
+ enableval=$enable_nls;
+else
+ enable_nls=check
+fi
+
+if test "$enable_nls" != no; then
+ ac_fn_c_check_header_mongrel "$LINENO" "libintl.h" "ac_cv_header_libintl_h" "$ac_includes_default"
if test "x$ac_cv_header_libintl_h" = xyes; then :
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing dgettext" >&5
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing dgettext" >&5
$as_echo_n "checking for library containing dgettext... " >&6; }
if ${ac_cv_search_dgettext+:} false; then :
$as_echo_n "(cached) " >&6
@@ -7873,13 +8475,14 @@ if test "$ac_res" != no; then :
$as_echo "#define ENABLE_NLS 1" >>confdefs.h
+ nls_enabled=yes
fi
fi
-# Extract the first word of "msgfmt", so it can be a program name with args.
+ # Extract the first word of "msgfmt", so it can be a program name with args.
set dummy msgfmt; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
@@ -7916,9 +8519,16 @@ $as_echo "no" >&6; }
fi
-po=
-if test x"$MSGFMT" != x; then
- po=po
+ if test x"$MSGFMT" != x; then
+ po=po
+ fi
+
+ # Error out if --enable-nls was explicitly requested but can't be enabled.
+ if test "$enable_nls" = yes; then
+ if test "$nls_enabled" != yes -o "x$po" = x; then
+ as_fn_error $? "NLS support requested but cannot be built" "$LINENO" 5
+ fi
+ fi
fi
@@ -8543,147 +9153,6 @@ $as_echo "#define FORTUNA 1" >>confdefs.h
fi
-# WITH_PKINIT_CRYPTO_IMPL
-
-PKINIT_CRYPTO_IMPL="$CRYPTO_IMPL"
-
-# Check whether --with-pkinit-crypto-impl was given.
-if test "${with_pkinit_crypto_impl+set}" = set; then :
- withval=$with_pkinit_crypto_impl; PKINIT_CRYPTO_IMPL=$withval
-{ $as_echo "$as_me:${as_lineno-$LINENO}: pkinit will use '$withval'" >&5
-$as_echo "$as_me: pkinit will use '$withval'" >&6;}
-
-else
- withval=$PKINIT_CRYPTO_IMPL
-fi
-
-case "$withval" in
-builtin|openssl)
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for PKCS7_get_signer_info in -lcrypto" >&5
-$as_echo_n "checking for PKCS7_get_signer_info in -lcrypto... " >&6; }
-if ${ac_cv_lib_crypto_PKCS7_get_signer_info+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lcrypto $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char PKCS7_get_signer_info ();
-int
-main ()
-{
-return PKCS7_get_signer_info ();
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- ac_cv_lib_crypto_PKCS7_get_signer_info=yes
-else
- ac_cv_lib_crypto_PKCS7_get_signer_info=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypto_PKCS7_get_signer_info" >&5
-$as_echo "$ac_cv_lib_crypto_PKCS7_get_signer_info" >&6; }
-if test "x$ac_cv_lib_crypto_PKCS7_get_signer_info" = xyes; then :
- PKINIT_CRYPTO_IMPL_LIBS=-lcrypto
-fi
-
- PKINIT_CRYPTO_IMPL=openssl
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for CMS_get0_content in -lcrypto" >&5
-$as_echo_n "checking for CMS_get0_content in -lcrypto... " >&6; }
-if ${ac_cv_lib_crypto_CMS_get0_content+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lcrypto $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char CMS_get0_content ();
-int
-main ()
-{
-return CMS_get0_content ();
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- ac_cv_lib_crypto_CMS_get0_content=yes
-else
- ac_cv_lib_crypto_CMS_get0_content=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypto_CMS_get0_content" >&5
-$as_echo "$ac_cv_lib_crypto_CMS_get0_content" >&6; }
-if test "x$ac_cv_lib_crypto_CMS_get0_content" = xyes; then :
-
-$as_echo "#define HAVE_OPENSSL_CMS 1" >>confdefs.h
-
-fi
-
- ;;
-nss)
- if test "${PKINIT_CRYPTO_IMPL_CFLAGS+set}" != set; then
- PKINIT_CRYPTO_IMPL_CFLAGS=`pkg-config --cflags nss`
- fi
- if test "${PKINIT_CRYPTO_IMPL_LIBS+set}" != set; then
- PKINIT_CRYPTO_IMPL_LIBS=`pkg-config --libs nss`
- fi
-
-$as_echo "#define PKINIT_CRYPTO_IMPL_NSS 1" >>confdefs.h
-
- save_CFLAGS=$CFLAGS
- CFLAGS="$CFLAGS $PKINIT_CRYPTO_IMPL_CFLAGS"
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-#include <nss.h>
-#if NSS_VMAJOR < 3 || (NSS_VMAJOR == 3 && NSS_VMINOR < 12)
-#error
-#elif NSS_VMAJOR == 3 && NSS_VMINOR == 12 && NSS_VPATCH < 11
-#error
-#endif
-
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-
-else
- as_fn_error $? "NSS version 3.12.11 or later required." "$LINENO" 5
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- CFLAGS=$save_CFLAGS
- ;;
-*)
- as_fn_error $? "Unknown crypto implementation $withval" "$LINENO" 5
- ;;
-esac
-ac_config_commands="$ac_config_commands PKINIT_CRYPTO_IMPL"
-
-
-
-
-
# WITH_TLS_IMPL
@@ -10801,6 +11270,41 @@ _ACEOF
fi
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of time_t" >&5
+$as_echo_n "checking size of time_t... " >&6; }
+if ${ac_cv_sizeof_time_t+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (time_t))" "ac_cv_sizeof_time_t" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_time_t" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (time_t)
+See \`config.log' for more details" "$LINENO" 5; }
+ else
+ ac_cv_sizeof_time_t=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_time_t" >&5
+$as_echo "$ac_cv_sizeof_time_t" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_TIME_T $ac_cv_sizeof_time_t
+_ACEOF
+
+
+SIZEOF_TIME_T=$ac_cv_sizeof_time_t
+
# Determine where to put the replay cache.
@@ -12174,6 +12678,48 @@ if test "$k5_cv_openssl_version_okay" = yes && (test "$enable_pkinit" = yes || t
PKINIT=yes
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for CMS_get0_content in -lcrypto" >&5
+$as_echo_n "checking for CMS_get0_content in -lcrypto... " >&6; }
+if ${ac_cv_lib_crypto_CMS_get0_content+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lcrypto $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char CMS_get0_content ();
+int
+main ()
+{
+return CMS_get0_content ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_crypto_CMS_get0_content=yes
+else
+ ac_cv_lib_crypto_CMS_get0_content=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypto_CMS_get0_content" >&5
+$as_echo "$ac_cv_lib_crypto_CMS_get0_content" >&6; }
+if test "x$ac_cv_lib_crypto_CMS_get0_content" = xyes; then :
+
+$as_echo "#define HAVE_OPENSSL_CMS 1" >>confdefs.h
+
+fi
+
elif test "$k5_cv_openssl_version_okay" = no && test "$enable_pkinit" = yes; then
as_fn_error $? "Version of OpenSSL is too old; cannot enable PKINIT." "$LINENO" 5
else
@@ -12319,6 +12865,9 @@ fi
if test "$HAVE_CMOCKA_LIB" = yes && test "$HAVE_CMOCKA_H" = yes; then
HAVE_CMOCKA=yes
CMOCKA_LIBS='-lcmocka'
+
+$as_echo "#define HAVE_CMOCKA 1" >>confdefs.h
+
fi
@@ -12437,9 +12986,9 @@ fi
done
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ldap_init in -lldap" >&5
-$as_echo_n "checking for ldap_init in -lldap... " >&6; }
-if ${ac_cv_lib_ldap_ldap_init+:} false; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ldap_str2dn in -lldap" >&5
+$as_echo_n "checking for ldap_str2dn in -lldap... " >&6; }
+if ${ac_cv_lib_ldap_ldap_str2dn+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_check_lib_save_LIBS=$LIBS
@@ -12453,47 +13002,32 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
#ifdef __cplusplus
extern "C"
#endif
-char ldap_init ();
+char ldap_str2dn ();
int
main ()
{
-return ldap_init ();
+return ldap_str2dn ();
;
return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
- ac_cv_lib_ldap_ldap_init=yes
+ ac_cv_lib_ldap_ldap_str2dn=yes
else
- ac_cv_lib_ldap_ldap_init=no
+ ac_cv_lib_ldap_ldap_str2dn=no
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ldap_ldap_init" >&5
-$as_echo "$ac_cv_lib_ldap_ldap_init" >&6; }
-if test "x$ac_cv_lib_ldap_ldap_init" = xyes; then :
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ldap_ldap_str2dn" >&5
+$as_echo "$ac_cv_lib_ldap_ldap_str2dn" >&6; }
+if test "x$ac_cv_lib_ldap_ldap_str2dn" = xyes; then :
:
else
- as_fn_error $? "libldap not found or missing ldap_init" "$LINENO" 5
+ as_fn_error $? "libldap not found or missing ldap_str2dn" "$LINENO" 5
fi
- old_LIBS="$LIBS"
- LIBS="$LIBS -lldap"
- for ac_func in ldap_initialize ldap_url_parse_nodn ldap_unbind_ext_s ldap_str2dn ldap_explode_dn
-do :
- as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
-ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
-if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
- cat >>confdefs.h <<_ACEOF
-#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
-_ACEOF
-
-fi
-done
-
- LIBS="$old_LIBS"
BER_OKAY=0
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ber_init in -lldap" >&5
@@ -12911,7 +13445,7 @@ if test "${localedir+set}" != set; then
fi
-# For KCM lib/krb5/ccache to build KCM Mach RPC support for OS X only.
+# For KCM lib/krb5/ccache to build KCM Mach RPC support for macOS only.
case $host in
*-*-darwin* | *-*-rhapsody*) OSX=osx ;;
*) OSX=no ;;
@@ -12948,10 +13482,10 @@ fi
if test "${DEFCCNAME+set}" != set; then
case $host in
*-*-darwin[0-9].* | *-*-darwin10.*)
- # Use the normal default for OS X 10.6 (Darwin 10) and prior.
+ # Use the normal default for macOS 10.6 (Darwin 10) and prior.
;;
*-*-darwin*)
- # For OS X 10.7 (Darwin 11) and later, the native ccache uses
+ # For macOS 10.7 (Darwin 11) and later, the native ccache uses
# the KCM daemon.
DEFCCNAME=KCM:
;;
@@ -13052,9 +13586,11 @@ ac_config_files="$ac_config_files build-tools/kadm-server.pc build-tools/kadm-cl
ac_config_files="$ac_config_files man/Makefile:$srcdir/./config/pre.in:man/Makefile.in:man/deps:$srcdir/./config/post.in"
ac_config_files="$ac_config_files doc/Makefile:$srcdir/./config/pre.in:doc/Makefile.in:doc/deps:$srcdir/./config/post.in"
ac_config_files="$ac_config_files include/Makefile:$srcdir/./config/pre.in:include/Makefile.in:include/deps:$srcdir/./config/post.in"
+ ac_config_files="$ac_config_files plugins/certauth/test/Makefile:$srcdir/./config/pre.in:plugins/certauth/test/Makefile.in:plugins/certauth/test/deps:$srcdir/./config/post.in"
ac_config_files="$ac_config_files plugins/hostrealm/test/Makefile:$srcdir/./config/pre.in:plugins/hostrealm/test/Makefile.in:plugins/hostrealm/test/deps:$srcdir/./config/post.in"
ac_config_files="$ac_config_files plugins/localauth/test/Makefile:$srcdir/./config/pre.in:plugins/localauth/test/Makefile.in:plugins/localauth/test/deps:$srcdir/./config/post.in"
ac_config_files="$ac_config_files plugins/kadm5_hook/test/Makefile:$srcdir/./config/pre.in:plugins/kadm5_hook/test/Makefile.in:plugins/kadm5_hook/test/deps:$srcdir/./config/post.in"
+ ac_config_files="$ac_config_files plugins/kadm5_auth/test/Makefile:$srcdir/./config/pre.in:plugins/kadm5_auth/test/Makefile.in:plugins/kadm5_auth/test/deps:$srcdir/./config/post.in"
ac_config_files="$ac_config_files plugins/pwqual/test/Makefile:$srcdir/./config/pre.in:plugins/pwqual/test/Makefile.in:plugins/pwqual/test/deps:$srcdir/./config/post.in"
ac_config_files="$ac_config_files plugins/audit/Makefile:$srcdir/./config/pre.in:plugins/audit/Makefile.in:plugins/audit/deps:$srcdir/./config/post.in"
ac_config_files="$ac_config_files plugins/audit/test/Makefile:$srcdir/./config/pre.in:plugins/audit/test/Makefile.in:plugins/audit/test/deps:$srcdir/./config/post.in"
@@ -13067,6 +13603,7 @@ ac_config_files="$ac_config_files build-tools/kadm-server.pc build-tools/kadm-cl
ac_config_files="$ac_config_files plugins/kdb/db2/libdb2/recno/Makefile:$srcdir/./config/pre.in:plugins/kdb/db2/libdb2/recno/Makefile.in:plugins/kdb/db2/libdb2/recno/deps:$srcdir/./config/post.in"
ac_config_files="$ac_config_files plugins/kdb/db2/libdb2/test/Makefile:$srcdir/./config/pre.in:plugins/kdb/db2/libdb2/test/Makefile.in:plugins/kdb/db2/libdb2/test/deps:$srcdir/./config/post.in"
ac_config_files="$ac_config_files plugins/kdb/test/Makefile:$srcdir/./config/pre.in:plugins/kdb/test/Makefile.in:plugins/kdb/test/deps:$srcdir/./config/post.in"
+ ac_config_files="$ac_config_files plugins/kdcpolicy/test/Makefile:$srcdir/./config/pre.in:plugins/kdcpolicy/test/Makefile.in:plugins/kdcpolicy/test/deps:$srcdir/./config/post.in"
ac_config_files="$ac_config_files plugins/preauth/otp/Makefile:$srcdir/./config/pre.in:plugins/preauth/otp/Makefile.in:plugins/preauth/otp/deps:$srcdir/./config/post.in"
ac_config_files="$ac_config_files plugins/preauth/test/Makefile:$srcdir/./config/pre.in:plugins/preauth/test/Makefile.in:plugins/preauth/test/deps:$srcdir/./config/post.in"
ac_config_files="$ac_config_files plugins/authdata/greet_client/Makefile:$srcdir/./config/pre.in:plugins/authdata/greet_client/Makefile.in:plugins/authdata/greet_client/deps:$srcdir/./config/post.in"
@@ -13617,7 +14154,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by Kerberos 5 $as_me 1.15.1, which was
+This file was extended by Kerberos 5 $as_me 1.16, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -13683,7 +14220,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
-Kerberos 5 config.status 1.15.1
+Kerberos 5 config.status 1.16
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
@@ -13803,7 +14340,6 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
#
CRYPTO_IMPL=$CRYPTO_IMPL
PRNG_ALG=$PRNG_ALG
-PKINIT_CRYPTO_IMPL=$PKINIT_CRYPTO_IMPL
_ACEOF
@@ -13816,7 +14352,6 @@ do
"plugins/audit/simple/Makefile") CONFIG_FILES="$CONFIG_FILES plugins/audit/simple/Makefile:$srcdir/./config/pre.in:plugins/audit/simple/Makefile.in:plugins/audit/simple/deps:$srcdir/./config/post.in" ;;
"CRYPTO_IMPL") CONFIG_COMMANDS="$CONFIG_COMMANDS CRYPTO_IMPL" ;;
"PRNG_ALG") CONFIG_COMMANDS="$CONFIG_COMMANDS PRNG_ALG" ;;
- "PKINIT_CRYPTO_IMPL") CONFIG_COMMANDS="$CONFIG_COMMANDS PKINIT_CRYPTO_IMPL" ;;
"include/autoconf.h") CONFIG_HEADERS="$CONFIG_HEADERS include/autoconf.h" ;;
"kadmin/testing/scripts/env-setup.sh") CONFIG_FILES="$CONFIG_FILES kadmin/testing/scripts/env-setup.sh:kadmin/testing/scripts/env-setup.shin" ;;
"include/gssrpc/types.h") CONFIG_FILES="$CONFIG_FILES include/gssrpc/types.h:include/gssrpc/types.hin" ;;
@@ -13886,9 +14421,11 @@ do
"man/Makefile") CONFIG_FILES="$CONFIG_FILES man/Makefile:$srcdir/./config/pre.in:man/Makefile.in:man/deps:$srcdir/./config/post.in" ;;
"doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile:$srcdir/./config/pre.in:doc/Makefile.in:doc/deps:$srcdir/./config/post.in" ;;
"include/Makefile") CONFIG_FILES="$CONFIG_FILES include/Makefile:$srcdir/./config/pre.in:include/Makefile.in:include/deps:$srcdir/./config/post.in" ;;
+ "plugins/certauth/test/Makefile") CONFIG_FILES="$CONFIG_FILES plugins/certauth/test/Makefile:$srcdir/./config/pre.in:plugins/certauth/test/Makefile.in:plugins/certauth/test/deps:$srcdir/./config/post.in" ;;
"plugins/hostrealm/test/Makefile") CONFIG_FILES="$CONFIG_FILES plugins/hostrealm/test/Makefile:$srcdir/./config/pre.in:plugins/hostrealm/test/Makefile.in:plugins/hostrealm/test/deps:$srcdir/./config/post.in" ;;
"plugins/localauth/test/Makefile") CONFIG_FILES="$CONFIG_FILES plugins/localauth/test/Makefile:$srcdir/./config/pre.in:plugins/localauth/test/Makefile.in:plugins/localauth/test/deps:$srcdir/./config/post.in" ;;
"plugins/kadm5_hook/test/Makefile") CONFIG_FILES="$CONFIG_FILES plugins/kadm5_hook/test/Makefile:$srcdir/./config/pre.in:plugins/kadm5_hook/test/Makefile.in:plugins/kadm5_hook/test/deps:$srcdir/./config/post.in" ;;
+ "plugins/kadm5_auth/test/Makefile") CONFIG_FILES="$CONFIG_FILES plugins/kadm5_auth/test/Makefile:$srcdir/./config/pre.in:plugins/kadm5_auth/test/Makefile.in:plugins/kadm5_auth/test/deps:$srcdir/./config/post.in" ;;
"plugins/pwqual/test/Makefile") CONFIG_FILES="$CONFIG_FILES plugins/pwqual/test/Makefile:$srcdir/./config/pre.in:plugins/pwqual/test/Makefile.in:plugins/pwqual/test/deps:$srcdir/./config/post.in" ;;
"plugins/audit/Makefile") CONFIG_FILES="$CONFIG_FILES plugins/audit/Makefile:$srcdir/./config/pre.in:plugins/audit/Makefile.in:plugins/audit/deps:$srcdir/./config/post.in" ;;
"plugins/audit/test/Makefile") CONFIG_FILES="$CONFIG_FILES plugins/audit/test/Makefile:$srcdir/./config/pre.in:plugins/audit/test/Makefile.in:plugins/audit/test/deps:$srcdir/./config/post.in" ;;
@@ -13901,6 +14438,7 @@ do
"plugins/kdb/db2/libdb2/recno/Makefile") CONFIG_FILES="$CONFIG_FILES plugins/kdb/db2/libdb2/recno/Makefile:$srcdir/./config/pre.in:plugins/kdb/db2/libdb2/recno/Makefile.in:plugins/kdb/db2/libdb2/recno/deps:$srcdir/./config/post.in" ;;
"plugins/kdb/db2/libdb2/test/Makefile") CONFIG_FILES="$CONFIG_FILES plugins/kdb/db2/libdb2/test/Makefile:$srcdir/./config/pre.in:plugins/kdb/db2/libdb2/test/Makefile.in:plugins/kdb/db2/libdb2/test/deps:$srcdir/./config/post.in" ;;
"plugins/kdb/test/Makefile") CONFIG_FILES="$CONFIG_FILES plugins/kdb/test/Makefile:$srcdir/./config/pre.in:plugins/kdb/test/Makefile.in:plugins/kdb/test/deps:$srcdir/./config/post.in" ;;
+ "plugins/kdcpolicy/test/Makefile") CONFIG_FILES="$CONFIG_FILES plugins/kdcpolicy/test/Makefile:$srcdir/./config/pre.in:plugins/kdcpolicy/test/Makefile.in:plugins/kdcpolicy/test/deps:$srcdir/./config/post.in" ;;
"plugins/preauth/otp/Makefile") CONFIG_FILES="$CONFIG_FILES plugins/preauth/otp/Makefile:$srcdir/./config/pre.in:plugins/preauth/otp/Makefile.in:plugins/preauth/otp/deps:$srcdir/./config/post.in" ;;
"plugins/preauth/test/Makefile") CONFIG_FILES="$CONFIG_FILES plugins/preauth/test/Makefile:$srcdir/./config/pre.in:plugins/preauth/test/Makefile.in:plugins/preauth/test/deps:$srcdir/./config/post.in" ;;
"plugins/authdata/greet_client/Makefile") CONFIG_FILES="$CONFIG_FILES plugins/authdata/greet_client/Makefile:$srcdir/./config/pre.in:plugins/authdata/greet_client/Makefile.in:plugins/authdata/greet_client/deps:$srcdir/./config/post.in" ;;
diff --git a/src/configure.in b/src/configure.in
index 037c9f316149..10f45eb12e16 100644
--- a/src/configure.in
+++ b/src/configure.in
@@ -118,15 +118,29 @@ LIBUTIL=-lutil
])
AC_SUBST(LIBUTIL)
-AC_CHECK_HEADER(libintl.h, [
- AC_SEARCH_LIBS(dgettext, intl, [
- AC_DEFINE(ENABLE_NLS, 1,
- [Define if translation functions should be used.])])])
-
-AC_CHECK_PROG(MSGFMT,msgfmt,msgfmt)
+# Determine if NLS is desired and supported.
po=
-if test x"$MSGFMT" != x; then
- po=po
+AC_ARG_ENABLE([nls],
+AC_HELP_STRING([--disable-nls], [disable native language support]),
+ [], [enable_nls=check])
+if test "$enable_nls" != no; then
+ AC_CHECK_HEADER(libintl.h, [
+ AC_SEARCH_LIBS(dgettext, intl, [
+ AC_DEFINE(ENABLE_NLS, 1,
+ [Define if translation functions should be used.])
+ nls_enabled=yes])])
+
+ AC_CHECK_PROG(MSGFMT,msgfmt,msgfmt)
+ if test x"$MSGFMT" != x; then
+ po=po
+ fi
+
+ # Error out if --enable-nls was explicitly requested but can't be enabled.
+ if test "$enable_nls" = yes; then
+ if test "$nls_enabled" != yes -o "x$po" = x; then
+ AC_MSG_ERROR([NLS support requested but cannot be built])
+ fi
+ fi
fi
AC_SUBST(po)
@@ -264,51 +278,6 @@ if test "$PRNG_ALG" = fortuna; then
AC_DEFINE(FORTUNA,1,[Define if Fortuna PRNG is selected])
fi
-# WITH_PKINIT_CRYPTO_IMPL
-
-PKINIT_CRYPTO_IMPL="$CRYPTO_IMPL"
-AC_ARG_WITH([pkinit-crypto-impl],
-AC_HELP_STRING([--with-pkinit-crypto-impl=IMPL], [use specified pkinit crypto implementation @<:@openssl@:>@]),
-[PKINIT_CRYPTO_IMPL=$withval
-AC_MSG_NOTICE(pkinit will use '$withval')
-], withval=$PKINIT_CRYPTO_IMPL)
-case "$withval" in
-builtin|openssl)
- AC_CHECK_LIB(crypto, PKCS7_get_signer_info, PKINIT_CRYPTO_IMPL_LIBS=-lcrypto)
- PKINIT_CRYPTO_IMPL=openssl
- AC_CHECK_LIB(crypto, CMS_get0_content,
- [AC_DEFINE([HAVE_OPENSSL_CMS], 1,
- [Define if OpenSSL supports cms.])])
- ;;
-nss)
- if test "${PKINIT_CRYPTO_IMPL_CFLAGS+set}" != set; then
- PKINIT_CRYPTO_IMPL_CFLAGS=`pkg-config --cflags nss`
- fi
- if test "${PKINIT_CRYPTO_IMPL_LIBS+set}" != set; then
- PKINIT_CRYPTO_IMPL_LIBS=`pkg-config --libs nss`
- fi
- AC_DEFINE(PKINIT_CRYPTO_IMPL_NSS,1,[Define if pkinit crypto implementation is NSS])
- save_CFLAGS=$CFLAGS
- CFLAGS="$CFLAGS $PKINIT_CRYPTO_IMPL_CFLAGS"
- AC_COMPILE_IFELSE([AC_LANG_SOURCE([
-#include <nss.h>
-#if NSS_VMAJOR < 3 || (NSS_VMAJOR == 3 && NSS_VMINOR < 12)
-#error
-#elif NSS_VMAJOR == 3 && NSS_VMINOR == 12 && NSS_VPATCH < 11
-#error
-#endif
- ])], [], [AC_MSG_ERROR([NSS version 3.12.11 or later required.])])
- CFLAGS=$save_CFLAGS
- ;;
-*)
- AC_MSG_ERROR([Unknown crypto implementation $withval])
- ;;
-esac
-AC_CONFIG_COMMANDS(PKINIT_CRYPTO_IMPL,,PKINIT_CRYPTO_IMPL=$PKINIT_CRYPTO_IMPL)
-AC_SUBST(PKINIT_CRYPTO_IMPL)
-AC_SUBST(PKINIT_CRYPTO_IMPL_CFLAGS)
-AC_SUBST(PKINIT_CRYPTO_IMPL_LIBS)
-
# WITH_TLS_IMPL
AC_ARG_WITH([tls-impl],
@@ -744,6 +713,9 @@ fi
AC_HEADER_TIME
AC_CHECK_TYPE(time_t, long)
+AC_CHECK_SIZEOF(time_t)
+SIZEOF_TIME_T=$ac_cv_sizeof_time_t
+AC_SUBST(SIZEOF_TIME_T)
# Determine where to put the replay cache.
@@ -1085,6 +1057,7 @@ fi
if test "$k5_cv_openssl_version_okay" = yes && (test "$enable_pkinit" = yes || test "$enable_pkinit" = try); then
K5_GEN_MAKEFILE(plugins/preauth/pkinit)
PKINIT=yes
+ AC_CHECK_LIB(crypto, CMS_get0_content, [AC_DEFINE([HAVE_OPENSSL_CMS], 1, [Define if OpenSSL supports cms.])])
elif test "$k5_cv_openssl_version_okay" = no && test "$enable_pkinit" = yes; then
AC_MSG_ERROR([Version of OpenSSL is too old; cannot enable PKINIT.])
else
@@ -1131,6 +1104,7 @@ AC_CHECK_LIB(cmocka, _cmocka_run_group_tests, [HAVE_CMOCKA_LIB=yes])
if test "$HAVE_CMOCKA_LIB" = yes && test "$HAVE_CMOCKA_H" = yes; then
HAVE_CMOCKA=yes
CMOCKA_LIBS='-lcmocka'
+ AC_DEFINE([HAVE_CMOCKA],1,[Define if cmocka library is available.])
fi
AC_SUBST(HAVE_CMOCKA)
AC_SUBST(CMOCKA_LIBS)
@@ -1213,11 +1187,7 @@ ldap_plugin_dir=""
ldap_lib=""
if test -n "$OPENLDAP_PLUGIN"; then
AC_CHECK_HEADERS(ldap.h lber.h, :, [AC_MSG_ERROR($ac_header not found)])
- AC_CHECK_LIB(ldap, ldap_init, :, [AC_MSG_ERROR(libldap not found or missing ldap_init)])
- old_LIBS="$LIBS"
- LIBS="$LIBS -lldap"
- AC_CHECK_FUNCS(ldap_initialize ldap_url_parse_nodn ldap_unbind_ext_s ldap_str2dn ldap_explode_dn)
- LIBS="$old_LIBS"
+ AC_CHECK_LIB(ldap, ldap_str2dn, :, [AC_MSG_ERROR(libldap not found or missing ldap_str2dn)])
BER_OKAY=0
AC_CHECK_LIB(ldap, ber_init, [BER_OKAY=1])
@@ -1342,7 +1312,7 @@ if test "${localedir+set}" != set; then
fi
AC_SUBST(localedir)
-# For KCM lib/krb5/ccache to build KCM Mach RPC support for OS X only.
+# For KCM lib/krb5/ccache to build KCM Mach RPC support for macOS only.
case $host in
*-*-darwin* | *-*-rhapsody*) OSX=osx ;;
*) OSX=no ;;
@@ -1376,10 +1346,10 @@ dnl brackets in the glob patterns.
if test "${DEFCCNAME+set}" != set; then
[case $host in
*-*-darwin[0-9].* | *-*-darwin10.*)
- # Use the normal default for OS X 10.6 (Darwin 10) and prior.
+ # Use the normal default for macOS 10.6 (Darwin 10) and prior.
;;
*-*-darwin*)
- # For OS X 10.7 (Darwin 11) and later, the native ccache uses
+ # For macOS 10.7 (Darwin 11) and later, the native ccache uses
# the KCM daemon.
DEFCCNAME=KCM:
;;
@@ -1392,7 +1362,7 @@ if test "${DEFKTNAME+set}" != set; then
DEFKTNAME=FILE:/etc/krb5.keytab
fi
if test "${DEFCKTNAME+set}" != set; then
- adl_RECURSIVE_EVAL($localstatedir, exp_localstatedir)
+ AX_RECURSIVE_EVAL($localstatedir, exp_localstatedir)
DEFCKTNAME=FILE:$exp_localstatedir/krb5/user/%{euid}/client.keytab
fi
AC_MSG_NOTICE([Default ccache name: $DEFCCNAME])
@@ -1447,9 +1417,11 @@ dnl ccapi ccapi/lib ccapi/lib/unix ccapi/server ccapi/server/unix ccapi/test
kdc slave config-files build-tools man doc include
+ plugins/certauth/test
plugins/hostrealm/test
plugins/localauth/test
plugins/kadm5_hook/test
+ plugins/kadm5_auth/test
plugins/pwqual/test
plugins/audit
plugins/audit/test
@@ -1462,6 +1434,7 @@ dnl ccapi ccapi/lib ccapi/lib/unix ccapi/server ccapi/server/unix ccapi/test
plugins/kdb/db2/libdb2/recno
plugins/kdb/db2/libdb2/test
plugins/kdb/test
+ plugins/kdcpolicy/test
plugins/preauth/otp
plugins/preauth/test
plugins/authdata/greet_client
diff --git a/src/include/Makefile.in b/src/include/Makefile.in
index f5b921833071..cfa5794b72bf 100644
--- a/src/include/Makefile.in
+++ b/src/include/Makefile.in
@@ -140,15 +140,18 @@ install-headers-unix install: krb5/krb5.h profile.h
$(INSTALL_DATA) $(srcdir)/krb5.h $(DESTDIR)$(KRB5_INCDIR)$(S)krb5.h
$(INSTALL_DATA) $(srcdir)/kdb.h $(DESTDIR)$(KRB5_INCDIR)$(S)kdb.h
$(INSTALL_DATA) krb5/krb5.h $(DESTDIR)$(KRB5_INCDIR)$(S)krb5$(S)krb5.h
+ $(INSTALL_DATA) $(srcdir)/krb5/certauth_plugin.h $(DESTDIR)$(KRB5_INCDIR)$(S)krb5$(S)certauth_plugin.h
$(INSTALL_DATA) $(srcdir)/krb5/ccselect_plugin.h $(DESTDIR)$(KRB5_INCDIR)$(S)krb5$(S)ccselect_plugin.h
$(INSTALL_DATA) $(srcdir)/krb5/clpreauth_plugin.h $(DESTDIR)$(KRB5_INCDIR)$(S)krb5$(S)clpreauth_plugin.h
$(INSTALL_DATA) $(srcdir)/krb5/hostrealm_plugin.h $(DESTDIR)$(KRB5_INCDIR)$(S)krb5$(S)hostrealm_plugin.h
+ $(INSTALL_DATA) $(srcdir)/krb5/kdcpolicy_plugin.h $(DESTDIR)$(KRB5_INCDIR)$(S)krb5$(S)kdcpolicy_plugin.h
$(INSTALL_DATA) $(srcdir)/krb5/kdcpreauth_plugin.h $(DESTDIR)$(KRB5_INCDIR)$(S)krb5$(S)kdcpreauth_plugin.h
$(INSTALL_DATA) $(srcdir)/krb5/localauth_plugin.h $(DESTDIR)$(KRB5_INCDIR)$(S)krb5$(S)localauth_plugin.h
$(INSTALL_DATA) $(srcdir)/krb5/locate_plugin.h $(DESTDIR)$(KRB5_INCDIR)$(S)krb5$(S)locate_plugin.h
$(INSTALL_DATA) $(srcdir)/krb5/plugin.h $(DESTDIR)$(KRB5_INCDIR)$(S)krb5$(S)plugin.h
$(INSTALL_DATA) $(srcdir)/krb5/preauth_plugin.h $(DESTDIR)$(KRB5_INCDIR)$(S)krb5$(S)preauth_plugin.h
$(INSTALL_DATA) $(srcdir)/krb5/pwqual_plugin.h $(DESTDIR)$(KRB5_INCDIR)$(S)krb5$(S)pwqual_plugin.h
+ $(INSTALL_DATA) $(srcdir)/krb5/kadm5_auth_plugin.h $(DESTDIR)$(KRB5_INCDIR)$(S)krb5$(S)kadm5_auth_plugin.h
$(INSTALL_DATA) $(srcdir)/krb5/kadm5_hook_plugin.h $(DESTDIR)$(KRB5_INCDIR)$(S)krb5$(S)kadm5_hook_plugin.h
$(INSTALL_DATA) profile.h $(DESTDIR)$(KRB5_INCDIR)$(S)profile.h
$(INSTALL_DATA) $(srcdir)/gssapi.h $(DESTDIR)$(KRB5_INCDIR)$(S)gssapi.h
diff --git a/src/include/autoconf.h.in b/src/include/autoconf.h.in
index b33c5222325e..3dfc128e67bd 100644
--- a/src/include/autoconf.h.in
+++ b/src/include/autoconf.h.in
@@ -62,9 +62,6 @@
#undef GETHOSTBYNAME_R_RETURNS_INT
/* Type of getpeername second argument. */
-#undef GETPEERNAME_ARG2_TYPE
-
-/* Type of getpeername second argument. */
#undef GETPEERNAME_ARG3_TYPE
/* Define if getpwnam_r exists but takes only 4 arguments (e.g., POSIX draft 6
@@ -81,9 +78,6 @@
/* Define if getservbyname_r returns int rather than struct servent * */
#undef GETSERVBYNAME_R_RETURNS_INT
-/* Type of pointer target for argument 2 to getsockname */
-#undef GETSOCKNAME_ARG2_TYPE
-
/* Type of pointer target for argument 3 to getsockname */
#undef GETSOCKNAME_ARG3_TYPE
@@ -124,6 +118,9 @@
/* Define to 1 if you have the `chmod' function. */
#undef HAVE_CHMOD
+/* Define if cmocka library is available. */
+#undef HAVE_CMOCKA
+
/* Define to 1 if you have the `compile' function. */
#undef HAVE_COMPILE
@@ -240,24 +237,9 @@
/* Define to 1 if you have the <lber.h> header file. */
#undef HAVE_LBER_H
-/* Define to 1 if you have the `ldap_explode_dn' function. */
-#undef HAVE_LDAP_EXPLODE_DN
-
/* Define to 1 if you have the <ldap.h> header file. */
#undef HAVE_LDAP_H
-/* Define to 1 if you have the `ldap_initialize' function. */
-#undef HAVE_LDAP_INITIALIZE
-
-/* Define to 1 if you have the `ldap_str2dn' function. */
-#undef HAVE_LDAP_STR2DN
-
-/* Define to 1 if you have the `ldap_unbind_ext_s' function. */
-#undef HAVE_LDAP_UNBIND_EXT_S
-
-/* Define to 1 if you have the `ldap_url_parse_nodn' function. */
-#undef HAVE_LDAP_URL_PARSE_NODN
-
/* Define to 1 if you have the `crypto' library (-lcrypto). */
#undef HAVE_LIBCRYPTO
@@ -333,6 +315,9 @@
/* Define to 1 if you have the `pthread_once' function. */
#undef HAVE_PTHREAD_ONCE
+/* Have PTHREAD_PRIO_INHERIT. */
+#undef HAVE_PTHREAD_PRIO_INHERIT
+
/* Define to 1 if you have the `pthread_rwlock_init' function. */
#undef HAVE_PTHREAD_RWLOCK_INIT
@@ -657,9 +642,6 @@
/* Define to the version of this package. */
#undef PACKAGE_VERSION
-/* Define if pkinit crypto implementation is NSS */
-#undef PKINIT_CRYPTO_IMPL_NSS
-
/* Define if setjmp indicates POSIX interface */
#undef POSIX_SETJMP
@@ -672,7 +654,7 @@
/* Define if termios.h exists and tcsetattr exists */
#undef POSIX_TERMIOS
-/* Define to the necessary symbol if this constant uses a non-standard name on
+/* Define to necessary symbol if this constant uses a non-standard name on
your system. */
#undef PTHREAD_CREATE_JOINABLE
@@ -682,6 +664,9 @@
/* Define as return type of setrpcent */
#undef SETRPCENT_TYPE
+/* The size of `time_t', as computed by sizeof. */
+#undef SIZEOF_TIME_T
+
/* Define for static plugin linkage */
#undef STATIC_PLUGINS
diff --git a/src/include/fake-addrinfo.h b/src/include/fake-addrinfo.h
index 03666a0aaaa7..80ca9f8dfd23 100644
--- a/src/include/fake-addrinfo.h
+++ b/src/include/fake-addrinfo.h
@@ -52,7 +52,7 @@
the data structures and flag values locally.
- On Mac OS X, getaddrinfo results aren't cached (though
+ On macOS, getaddrinfo results aren't cached (though
gethostbyname results are), so we need to build a cache here. Now
things are getting really messy. Because the cache is in use, we
use getservbyname, and throw away thread safety. (Not that the
diff --git a/src/include/k5-cmocka.h b/src/include/k5-cmocka.h
new file mode 100644
index 000000000000..c35b10be0736
--- /dev/null
+++ b/src/include/k5-cmocka.h
@@ -0,0 +1,16 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/* include/k5-cmocka.h - indirect header file for cmocka test programs */
+
+/*
+ * This header conditionally includes cmocka.h, so that "make depend" can work
+ * on cmocka test programs when cmocka isn't available. It also includes the
+ * three system headers required for cmocka.h.
+ */
+
+#include "autoconf.h"
+#include <stdarg.h>
+#include <stddef.h>
+#include <setjmp.h>
+#ifdef HAVE_CMOCKA
+#include <cmocka.h>
+#endif
diff --git a/src/include/k5-input.h b/src/include/k5-input.h
index d42ebce8f271..9f47fa7ab903 100644
--- a/src/include/k5-input.h
+++ b/src/include/k5-input.h
@@ -33,7 +33,7 @@
#ifndef K5_INPUT_H
#define K5_INPUT_H
-#include "k5-int.h"
+#include "k5-platform.h"
/*
* The k5input module defines helpers for safely consuming a fixed-sized block
@@ -45,7 +45,7 @@
struct k5input {
const unsigned char *ptr;
size_t len;
- krb5_error_code status;
+ int32_t status;
};
static inline void
@@ -59,7 +59,7 @@ k5_input_init(struct k5input *in, const void *ptr, size_t len)
/* Only set the status value of in if it hasn't already been set, so status
* reflects the first thing to go wrong. */
static inline void
-k5_input_set_status(struct k5input *in, krb5_error_code status)
+k5_input_set_status(struct k5input *in, int32_t status)
{
if (!in->status)
in->status = status;
diff --git a/src/include/k5-int.h b/src/include/k5-int.h
index 64991738a3e2..e1b1cb040d5e 100644
--- a/src/include/k5-int.h
+++ b/src/include/k5-int.h
@@ -212,6 +212,7 @@ typedef unsigned char u_char;
#define KRB5_CONF_DNS_URI_LOOKUP "dns_uri_lookup"
#define KRB5_CONF_DOMAIN_REALM "domain_realm"
#define KRB5_CONF_ENABLE_ONLY "enable_only"
+#define KRB5_CONF_ENCRYPTED_CHALLENGE_INDICATOR "encrypted_challenge_indicator"
#define KRB5_CONF_ERR_FMT "err_fmt"
#define KRB5_CONF_EXTRA_ADDRESSES "extra_addresses"
#define KRB5_CONF_FORWARDABLE "forwardable"
@@ -720,7 +721,7 @@ krb5_error_code krb5int_c_copy_keyblock_contents(krb5_context context,
const krb5_keyblock *from,
krb5_keyblock *to);
-krb5_error_code krb5_crypto_us_timeofday(krb5_int32 *, krb5_int32 *);
+krb5_error_code krb5_crypto_us_timeofday(krb5_timestamp *, krb5_int32 *);
/*
* End "los-proto.h"
@@ -1155,7 +1156,10 @@ struct plugin_interface {
#define PLUGIN_INTERFACE_AUDIT 7
#define PLUGIN_INTERFACE_TLS 8
#define PLUGIN_INTERFACE_KDCAUTHDATA 9
-#define PLUGIN_NUM_INTERFACES 10
+#define PLUGIN_INTERFACE_CERTAUTH 10
+#define PLUGIN_INTERFACE_KADM5_AUTH 11
+#define PLUGIN_INTERFACE_KDCPOLICY 12
+#define PLUGIN_NUM_INTERFACES 13
/* Retrieve the plugin module of type interface_id and name modname,
* storing the result into module. */
@@ -1194,7 +1198,7 @@ k5_plugin_free_context(krb5_context context);
struct _kdb5_dal_handle; /* private, in kdb5.h */
typedef struct _kdb5_dal_handle kdb5_dal_handle;
struct _kdb_log_context;
-typedef struct krb5_preauth_context_st krb5_preauth_context;
+typedef struct krb5_preauth_context_st *krb5_preauth_context;
struct ccselect_module_handle;
struct localauth_module_handle;
struct hostrealm_module_handle;
@@ -1231,7 +1235,7 @@ struct _krb5_context {
struct plugin_dir_handle libkrb5_plugins;
/* preauth module stuff */
- krb5_preauth_context *preauth_context;
+ krb5_preauth_context preauth_context;
/* cache module stuff */
struct ccselect_module_handle **ccselect_handles;
@@ -2112,6 +2116,7 @@ krb5_get_tgs_ktypes(krb5_context, krb5_const_principal, krb5_enctype **);
krb5_boolean krb5_is_permitted_enctype(krb5_context, krb5_enctype);
krb5_boolean KRB5_CALLCONV krb5int_c_weak_enctype(krb5_enctype);
+krb5_error_code k5_enctype_to_ssf(krb5_enctype enctype, unsigned int *ssf_out);
krb5_error_code krb5_kdc_rep_decrypt_proc(krb5_context, const krb5_keyblock *,
krb5_const_pointer, krb5_kdc_rep *);
@@ -2350,6 +2355,44 @@ k5memdup0(const void *in, size_t len, krb5_error_code *code)
return ptr;
}
+/* Convert a krb5_timestamp to a time_t value, treating the negative range of
+ * krb5_timestamp as times between 2038 and 2106 (if time_t is 64-bit). */
+static inline time_t
+ts2tt(krb5_timestamp timestamp)
+{
+ return (time_t)(uint32_t)timestamp;
+}
+
+/* Return the delta between two timestamps (a - b) as a signed 32-bit value,
+ * without relying on undefined behavior. */
+static inline krb5_deltat
+ts_delta(krb5_timestamp a, krb5_timestamp b)
+{
+ return (krb5_deltat)((uint32_t)a - (uint32_t)b);
+}
+
+/* Increment a timestamp by a signed 32-bit interval, without relying on
+ * undefined behavior. */
+static inline krb5_timestamp
+ts_incr(krb5_timestamp ts, krb5_deltat delta)
+{
+ return (krb5_timestamp)((uint32_t)ts + (uint32_t)delta);
+}
+
+/* Return true if a comes after b. */
+static inline krb5_boolean
+ts_after(krb5_timestamp a, krb5_timestamp b)
+{
+ return (uint32_t)a > (uint32_t)b;
+}
+
+/* Return true if a and b are within d seconds. */
+static inline krb5_boolean
+ts_within(krb5_timestamp a, krb5_timestamp b, krb5_deltat d)
+{
+ return !ts_after(a, ts_incr(b, d)) && !ts_after(b, ts_incr(a, d));
+}
+
krb5_error_code KRB5_CALLCONV
krb5_get_credentials_for_user(krb5_context context, krb5_flags options,
krb5_ccache ccache,
diff --git a/src/include/k5-platform.h b/src/include/k5-platform.h
index 994f46323cb0..548c0486d567 100644
--- a/src/include/k5-platform.h
+++ b/src/include/k5-platform.h
@@ -71,6 +71,13 @@
#define CAN_COPY_VA_LIST
#endif
+/* This attribute prevents unused function warnings in gcc and clang. */
+#ifdef __GNUC__
+#define UNUSED __attribute__((__unused__))
+#else
+#define UNUSED
+#endif
+
#if defined(macintosh) || (defined(__MACH__) && defined(__APPLE__))
#include <TargetConditionals.h>
#endif
@@ -354,19 +361,7 @@ typedef struct { int error; unsigned char did_run; } k5_init_t;
-#if !defined(SHARED) && !defined(_WIN32)
-
-/*
- * In this case, we just don't care about finalization.
- *
- * The code will still define the function, but we won't do anything
- * with it. Annoying: This may generate unused-function warnings.
- */
-
-# define MAKE_FINI_FUNCTION(NAME) \
- static void NAME(void)
-
-#elif defined(USE_LINKER_FINI_OPTION) || defined(_WIN32)
+#if defined(USE_LINKER_FINI_OPTION) || defined(_WIN32)
/* If we're told the linker option will be used, it doesn't really
matter what compiler we're using. Do it the same way
regardless. */
@@ -400,6 +395,15 @@ typedef struct { int error; unsigned char did_run; } k5_init_t;
# endif
+#elif !defined(SHARED)
+
+/*
+ * In this case, we just don't care about finalization. The code will still
+ * define the function, but we won't do anything with it.
+ */
+# define MAKE_FINI_FUNCTION(NAME) \
+ static void NAME(void) UNUSED
+
#elif defined(__GNUC__) && defined(DESTRUCTOR_ATTR_WORKS)
/* If we're using gcc, if the C++ support works, the compiler should
build executables and shared libraries that support the use of
@@ -508,7 +512,7 @@ typedef struct { int error; unsigned char did_run; } k5_init_t;
Linux: byteswap.h, bswap_16 etc.
Solaris 10: none
- Mac OS X: machine/endian.h or byte_order.h, NXSwap{Short,Int,LongLong}
+ macOS: machine/endian.h or byte_order.h, NXSwap{Short,Int,LongLong}
NetBSD: sys/bswap.h, bswap16 etc. */
#if defined(HAVE_BYTESWAP_H) && defined(HAVE_BSWAP_16)
diff --git a/src/include/k5-thread.h b/src/include/k5-thread.h
index 3e3901d6e8fb..a3101239d8a5 100644
--- a/src/include/k5-thread.h
+++ b/src/include/k5-thread.h
@@ -134,6 +134,10 @@
More to be added, perhaps. */
#include <assert.h>
+#ifndef NDEBUG
+#include <stdio.h>
+#include <string.h>
+#endif
/* The mutex structure we use, k5_mutex_t, is defined to some
OS-specific bits. The use of multiple layers of typedefs are an
@@ -363,12 +367,24 @@ static inline int k5_mutex_finish_init(k5_mutex_t *m)
static inline void k5_mutex_lock(k5_mutex_t *m)
{
int r = k5_os_mutex_lock(m);
+#ifndef NDEBUG
+ if (r != 0) {
+ fprintf(stderr, "k5_mutex_lock: Received error %d (%s)\n",
+ r, strerror(r));
+ }
+#endif
assert(r == 0);
}
static inline void k5_mutex_unlock(k5_mutex_t *m)
{
int r = k5_os_mutex_unlock(m);
+#ifndef NDEBUG
+ if (r != 0) {
+ fprintf(stderr, "k5_mutex_unlock: Received error %d (%s)\n",
+ r, strerror(r));
+ }
+#endif
assert(r == 0);
}
diff --git a/src/include/k5-trace.h b/src/include/k5-trace.h
index c75e264e04f2..390a8b7d6fc7 100644
--- a/src/include/k5-trace.h
+++ b/src/include/k5-trace.h
@@ -155,6 +155,20 @@ void krb5int_trace(krb5_context context, const char *fmt, ...);
TRACE(c, "ccselect choosing default cache {ccache} for server " \
"principal {princ}", cache, server)
+#define TRACE_DNS_SRV_ANS(c, host, port, prio, weight) \
+ TRACE(c, "SRV answer: {int} {int} {int} \"{str}\"", prio, weight, \
+ port, host)
+#define TRACE_DNS_SRV_NOTFOUND(c) \
+ TRACE(c, "No SRV records found")
+#define TRACE_DNS_SRV_SEND(c, domain) \
+ TRACE(c, "Sending DNS SRV query for {str}", domain)
+#define TRACE_DNS_URI_ANS(c, uri, prio, weight) \
+ TRACE(c, "URI answer: {int} {int} \"{str}\"", prio, weight, uri)
+#define TRACE_DNS_URI_NOTFOUND(c) \
+ TRACE(c, "No URI records found")
+#define TRACE_DNS_URI_SEND(c, domain) \
+ TRACE(c, "Sending DNS URI query for {str}", domain)
+
#define TRACE_FAST_ARMOR_CCACHE(c, ccache_name) \
TRACE(c, "FAST armor ccache: {str}", ccache_name)
#define TRACE_FAST_ARMOR_CCACHE_KEY(c, keyblock) \
@@ -213,8 +227,19 @@ void krb5int_trace(krb5_context context, const char *fmt, ...);
TRACE(c, "Looked up etypes in keytab: {etypes}", etypes)
#define TRACE_INIT_CREDS_KEYTAB_LOOKUP_FAILED(c, code) \
TRACE(c, "Couldn't lookup etypes in keytab: {kerr}", code)
+#define TRACE_INIT_CREDS_PREAUTH(c) \
+ TRACE(c, "Preauthenticating using KDC method data")
#define TRACE_INIT_CREDS_PREAUTH_DECRYPT_FAIL(c, code) \
TRACE(c, "Decrypt with preauth AS key failed: {kerr}", code)
+#define TRACE_INIT_CREDS_PREAUTH_MORE(c, patype) \
+ TRACE(c, "Continuing preauth mech {int}", (int)patype)
+#define TRACE_INIT_CREDS_PREAUTH_NONE(c) \
+ TRACE(c, "Sending unauthenticated request")
+#define TRACE_INIT_CREDS_PREAUTH_OPTIMISTIC(c) \
+ TRACE(c, "Attempting optimistic preauth")
+#define TRACE_INIT_CREDS_PREAUTH_TRYAGAIN(c, patype, code) \
+ TRACE(c, "Recovering from KDC error {int} using preauth mech {int}", \
+ (int)patype, (int)code)
#define TRACE_INIT_CREDS_RESTART_FAST(c) \
TRACE(c, "Restarting to upgrade to FAST")
#define TRACE_INIT_CREDS_RESTART_PREAUTH_FAILED(c) \
@@ -228,6 +253,13 @@ void krb5int_trace(krb5_context context, const char *fmt, ...);
#define TRACE_INIT_CREDS_SERVICE(c, service) \
TRACE(c, "Setting initial creds service to {str}", service)
+#define TRACE_KADM5_AUTH_VTINIT_FAIL(c, ret) \
+ TRACE(c, "kadm5_auth module failed to init vtable: {kerr}", ret)
+#define TRACE_KADM5_AUTH_INIT_FAIL(c, name, ret) \
+ TRACE(c, "kadm5_auth module {str} failed to init: {kerr}", ret)
+#define TRACE_KADM5_AUTH_INIT_SKIP(c, name) \
+ TRACE(c, "kadm5_auth module {str} declined to initialize", name)
+
#define TRACE_KT_GET_ENTRY(c, keytab, princ, vno, enctype, err) \
TRACE(c, "Retrieving {princ} from {keytab} (vno {int}, enctype {etype}) " \
"with result: {kerr}", princ, keytab, (int) vno, enctype, err)
@@ -287,10 +319,16 @@ void krb5int_trace(krb5_context context, const char *fmt, ...);
#define TRACE_PREAUTH_SKIP(c, name, patype) \
TRACE(c, "Skipping previously used preauth module {str} ({int})", \
name, (int) patype)
-#define TRACE_PREAUTH_TRYAGAIN_INPUT(c, padata) \
- TRACE(c, "Preauth tryagain input types: {patypes}", padata)
+#define TRACE_PREAUTH_TRYAGAIN_INPUT(c, patype, padata) \
+ TRACE(c, "Preauth tryagain input types ({int}): {patypes}", patype, padata)
+#define TRACE_PREAUTH_TRYAGAIN(c, name, patype, code) \
+ TRACE(c, "Preauth module {str} ({int}) tryagain returned: {kerr}", \
+ name, (int)patype, code)
#define TRACE_PREAUTH_TRYAGAIN_OUTPUT(c, padata) \
TRACE(c, "Followup preauth for next request: {patypes}", padata)
+#define TRACE_PREAUTH_WRONG_CONTEXT(c) \
+ TRACE(c, "Wrong context passed to krb5_init_creds_free(); leaking " \
+ "modreq objects")
#define TRACE_PROFILE_ERR(c,subsection, section, retval) \
TRACE(c, "Bad value of {str} from [{str}] in conf file: {kerr}", \
@@ -454,4 +492,9 @@ void krb5int_trace(krb5_context context, const char *fmt, ...);
#define TRACE_GET_CRED_VIA_TKT_EXT_RETURN(c, ret) \
TRACE(c, "Got cred; {kerr}", ret)
+#define TRACE_KDCPOLICY_VTINIT_FAIL(c, ret) \
+ TRACE(c, "KDC policy module failed to init vtable: {kerr}", ret)
+#define TRACE_KDCPOLICY_INIT_SKIP(c, name) \
+ TRACE(c, "kadm5_auth module {str} declined to initialize", name)
+
#endif /* K5_TRACE_H */
diff --git a/src/include/k5-utf8.h b/src/include/k5-utf8.h
index 22f433c8e981..e2f20d45028f 100644
--- a/src/include/k5-utf8.h
+++ b/src/include/k5-utf8.h
@@ -73,57 +73,28 @@
typedef uint16_t krb5_ucs2;
typedef uint32_t krb5_ucs4;
-#define KRB5_MAX_UTF8_LEN (sizeof(krb5_ucs2) * 3/2)
-
int krb5int_utf8_to_ucs2(const char *p, krb5_ucs2 *out);
size_t krb5int_ucs2_to_utf8(krb5_ucs2 c, char *buf);
int krb5int_utf8_to_ucs4(const char *p, krb5_ucs4 *out);
size_t krb5int_ucs4_to_utf8(krb5_ucs4 c, char *buf);
-int
-krb5int_ucs2s_to_utf8s(const krb5_ucs2 *ucs2s,
- char **utf8s,
- size_t *utf8slen);
-
-int
-krb5int_ucs2cs_to_utf8s(const krb5_ucs2 *ucs2s,
- size_t ucs2slen,
- char **utf8s,
- size_t *utf8slen);
-
-int
-krb5int_ucs2les_to_utf8s(const unsigned char *ucs2les,
- char **utf8s,
- size_t *utf8slen);
-
-int
-krb5int_ucs2lecs_to_utf8s(const unsigned char *ucs2les,
- size_t ucs2leslen,
- char **utf8s,
- size_t *utf8slen);
-
-int
-krb5int_utf8s_to_ucs2s(const char *utf8s,
- krb5_ucs2 **ucs2s,
- size_t *ucs2chars);
-
-int
-krb5int_utf8cs_to_ucs2s(const char *utf8s,
- size_t utf8slen,
- krb5_ucs2 **ucs2s,
- size_t *ucs2chars);
-
-int
-krb5int_utf8s_to_ucs2les(const char *utf8s,
- unsigned char **ucs2les,
- size_t *ucs2leslen);
-
-int
-krb5int_utf8cs_to_ucs2les(const char *utf8s,
- size_t utf8slen,
- unsigned char **ucs2les,
- size_t *ucs2leslen);
+/*
+ * Convert a little-endian UTF-16 string to an allocated null-terminated UTF-8
+ * string. nbytes is the length of ucs2bytes in bytes, and must be an even
+ * number. Return EINVAL on invalid input, ENOMEM on out of memory, or 0 on
+ * success.
+ */
+int k5_utf16le_to_utf8(const uint8_t *utf16bytes, size_t nbytes,
+ char **utf8_out);
+
+/*
+ * Convert a UTF-8 string to an allocated little-endian UTF-16 string. The
+ * resulting length is in bytes and will always be even. Return EINVAL on
+ * invalid input, ENOMEM on out of memory, or 0 on success.
+ */
+int k5_utf8_to_utf16le(const char *utf8, uint8_t **utf16_out,
+ size_t *nbytes_out);
/* returns the number of bytes in the UTF-8 string */
size_t krb5int_utf8_bytes(const char *);
diff --git a/src/include/kdb.h b/src/include/kdb.h
index da04724fcedb..5615329c0bb3 100644
--- a/src/include/kdb.h
+++ b/src/include/kdb.h
@@ -69,7 +69,7 @@
/* This version will be incremented when incompatible changes are made to the
* KDB API, and will be kept in sync with the libkdb major version. */
-#define KRB5_KDB_API_VERSION 8
+#define KRB5_KDB_API_VERSION 9
/* Salt types */
#define KRB5_KDB_SALTTYPE_NORMAL 0
@@ -695,6 +695,8 @@ krb5_error_code krb5_db_check_policy_tgs(krb5_context kcontext,
krb5_pa_data ***e_data);
void krb5_db_audit_as_req(krb5_context kcontext, krb5_kdc_req *request,
+ const krb5_address *local_addr,
+ const krb5_address *remote_addr,
krb5_db_entry *client, krb5_db_entry *server,
krb5_timestamp authtime, krb5_error_code error_code);
@@ -865,7 +867,7 @@ krb5_error_code krb5_db_register_keytab(krb5_context context);
* This number indicates the date of the last incompatible change to the DAL.
* The maj_ver field of the module's vtable structure must match this version.
*/
-#define KRB5_KDB_DAL_MAJOR_VERSION 6
+#define KRB5_KDB_DAL_MAJOR_VERSION 7
/*
* A krb5_context can hold one database object. Modules should use
@@ -1356,6 +1358,8 @@ typedef struct _kdb_vftabl {
* AS request.
*/
void (*audit_as_req)(krb5_context kcontext, krb5_kdc_req *request,
+ const krb5_address *local_addr,
+ const krb5_address *remote_addr,
krb5_db_entry *client, krb5_db_entry *server,
krb5_timestamp authtime, krb5_error_code error_code);
diff --git a/src/include/kdb_log.h b/src/include/kdb_log.h
index 25b823674a9f..4239575659a3 100644
--- a/src/include/kdb_log.h
+++ b/src/include/kdb_log.h
@@ -21,9 +21,8 @@ extern "C" {
/*
* DB macros
*/
-#define INDEX(ulog, i) (kdb_ent_header_t *)((char *)(ulog) + \
- sizeof(kdb_hlog_t) + \
- (i) * ulog->kdb_block)
+#define INDEX(ulog, i) (kdb_ent_header_t *)(void *) \
+ ((char *)(ulog) + sizeof(kdb_hlog_t) + (i) * ulog->kdb_block)
/*
* Current DB version #
diff --git a/src/include/krb5/certauth_plugin.h b/src/include/krb5/certauth_plugin.h
new file mode 100644
index 000000000000..3074790f8745
--- /dev/null
+++ b/src/include/krb5/certauth_plugin.h
@@ -0,0 +1,128 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/* include/krb5/certauth_plugin.h - certauth plugin header. */
+/*
+ * Copyright (C) 2017 by Red Hat, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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
+ * COPYRIGHT HOLDER 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.
+ */
+
+/*
+ * Declarations for certauth plugin module implementors.
+ *
+ * The certauth pluggable interface currently has only one supported major
+ * version, which is 1. Major version 1 has a current minor version number of
+ * 1.
+ *
+ * certauth plugin modules should define a function named
+ * certauth_<modulename>_initvt, matching the signature:
+ *
+ * krb5_error_code
+ * certauth_modname_initvt(krb5_context context, int maj_ver, int min_ver,
+ * krb5_plugin_vtable vtable);
+ *
+ * The initvt function should:
+ *
+ * - Check that the supplied maj_ver number is supported by the module, or
+ * return KRB5_PLUGIN_VER_NOTSUPP if it is not.
+ *
+ * - Cast the vtable pointer as appropriate for maj_ver:
+ * maj_ver == 1: Cast to krb5_certauth_vtable
+ *
+ * - Initialize the methods of the vtable, stopping as appropriate for the
+ * supplied min_ver. Optional methods may be left uninitialized.
+ *
+ * Memory for the vtable is allocated by the caller, not by the module.
+ */
+
+#ifndef KRB5_CERTAUTH_PLUGIN_H
+#define KRB5_CERTAUTH_PLUGIN_H
+
+#include <krb5/krb5.h>
+#include <krb5/plugin.h>
+
+/* Abstract module data type. */
+typedef struct krb5_certauth_moddata_st *krb5_certauth_moddata;
+
+/* A module can optionally include <kdb.h> to inspect the client principal
+ * entry when authorizing a request. */
+struct _krb5_db_entry_new;
+
+/*
+ * Optional: Initialize module data.
+ */
+typedef krb5_error_code
+(*krb5_certauth_init_fn)(krb5_context context,
+ krb5_certauth_moddata *moddata_out);
+
+/*
+ * Optional: Clean up the module data.
+ */
+typedef void
+(*krb5_certauth_fini_fn)(krb5_context context, krb5_certauth_moddata moddata);
+
+/*
+ * Mandatory:
+ * Return 0 if the DER-encoded cert is authorized for PKINIT authentication by
+ * princ; otherwise return one of the following error codes:
+ * - KRB5KDC_ERR_CLIENT_NAME_MISMATCH - incorrect SAN value
+ * - KRB5KDC_ERR_INCONSISTENT_KEY_PURPOSE - incorrect EKU
+ * - KRB5KDC_ERR_CERTIFICATE_MISMATCH - other extension error
+ * - KRB5_PLUGIN_NO_HANDLE - the module has no opinion about cert
+ *
+ * - opts is used by built-in modules to receive internal data, and must be
+ * ignored by other modules.
+ * - db_entry receives the client principal database entry, and can be ignored
+ * by modules that do not link with libkdb5.
+ * - *authinds_out optionally returns a null-terminated list of authentication
+ * indicator strings upon KRB5_PLUGIN_NO_HANDLE or accepted authorization.
+ */
+typedef krb5_error_code
+(*krb5_certauth_authorize_fn)(krb5_context context,
+ krb5_certauth_moddata moddata,
+ const uint8_t *cert, size_t cert_len,
+ krb5_const_principal princ, const void *opts,
+ const struct _krb5_db_entry_new *db_entry,
+ char ***authinds_out);
+
+/*
+ * Free indicators allocated by a module. Mandatory if authorize returns
+ * authentication indicators.
+ */
+typedef void
+(*krb5_certauth_free_indicator_fn)(krb5_context context,
+ krb5_certauth_moddata moddata,
+ char **authinds);
+
+typedef struct krb5_certauth_vtable_st {
+ const char *name;
+ krb5_certauth_init_fn init;
+ krb5_certauth_fini_fn fini;
+ krb5_certauth_authorize_fn authorize;
+ krb5_certauth_free_indicator_fn free_ind;
+} *krb5_certauth_vtable;
+
+#endif /* KRB5_CERTAUTH_PLUGIN_H */
diff --git a/src/include/krb5/kadm5_auth_plugin.h b/src/include/krb5/kadm5_auth_plugin.h
new file mode 100644
index 000000000000..d514e99beb93
--- /dev/null
+++ b/src/include/krb5/kadm5_auth_plugin.h
@@ -0,0 +1,306 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ * Copyright (C) 2017 by the Massachusetts Institute of Technology.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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
+ * COPYRIGHT HOLDER 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.
+ */
+
+/*
+ * Declarations for kadm5_auth plugin module implementors.
+ *
+ * The kadm5_auth pluggable interface currently has only one supported major
+ * version, which is 1. Major version 1 has a current minor version number of
+ * 1.
+ *
+ * kadm5_auth plugin modules should define a function named
+ * kadm5_auth_<modulename>_initvt, matching the signature:
+ *
+ * krb5_error_code
+ * kadm5_auth_modname_initvt(krb5_context context, int maj_ver, int min_ver,
+ * krb5_plugin_vtable vtable);
+ *
+ * The initvt function should:
+ *
+ * - Check that the supplied maj_ver number is supported by the module, or
+ * return KRB5_PLUGIN_VER_NOTSUPP if it is not.
+ *
+ * - Cast the vtable pointer as appropriate for maj_ver:
+ * maj_ver == 1: Cast to krb5_kadm5_auth_vtable
+ *
+ * - Initialize the methods of the vtable, stopping as appropriate for the
+ * supplied min_ver. Optional methods may be left uninitialized.
+ *
+ * Memory for the vtable is allocated by the caller, not by the module.
+ */
+
+#ifndef KRB5_KADM5_AUTH_PLUGIN_H
+#define KRB5_KADM5_AUTH_PLUGIN_H
+
+#include <krb5/krb5.h>
+#include <krb5/plugin.h>
+
+/* An abstract type for kadm5_auth module data. */
+typedef struct kadm5_auth_moddata_st *kadm5_auth_moddata;
+
+/*
+ * A module can optionally include <kadm5/admin.h> to inspect principal or
+ * policy records from requests that add or modify principals or policies.
+ * Note that fields of principal and policy structures are only valid if the
+ * corresponding bit is set in the accompanying mask parameter.
+ */
+struct _kadm5_principal_ent_t;
+struct _kadm5_policy_ent_t;
+
+/*
+ * A module can optionally generate restrictions when checking permissions for
+ * adding or modifying a principal entry. Restriction fields will only be
+ * honored if the corresponding mask bit is set. The operable mask bits are
+ * defined in <kadmin/admin.h> and are:
+ *
+ * - KADM5_ATTRIBUTES for require_attrs, forbid_attrs
+ * - KADM5_POLICY for policy
+ * - KADM5_POLICY_CLR to require that policy be unset
+ * - KADM5_PRINC_EXPIRE_TIME for princ_lifetime
+ * - KADM5_PW_EXPIRATION for pw_lifetime
+ * - KADM5_MAX_LIFE for max_life
+ * - KADM5_MAX_RLIFE for max_renewable_life
+ */
+struct kadm5_auth_restrictions {
+ long mask;
+ krb5_flags require_attrs;
+ krb5_flags forbid_attrs;
+ krb5_deltat princ_lifetime;
+ krb5_deltat pw_lifetime;
+ krb5_deltat max_life;
+ krb5_deltat max_renewable_life;
+ char *policy;
+};
+
+/*** Method type declarations ***/
+
+/*
+ * Optional: Initialize module data. acl_file is the realm's configured ACL
+ * file, or NULL if none was configured. Return 0 on success,
+ * KRB5_PLUGIN_NO_HANDLE if the module is inoperable (due to configuration, for
+ * example), and any other error code to abort kadmind startup. Optionally set
+ * *data_out to a module data object to be passed to future calls.
+ */
+typedef krb5_error_code
+(*kadm5_auth_init_fn)(krb5_context context, const char *acl_file,
+ kadm5_auth_moddata *data_out);
+
+/* Optional: Release resources used by module data. */
+typedef void
+(*kadm5_auth_fini_fn)(krb5_context context, kadm5_auth_moddata data);
+
+/*
+ * Each check method below should return 0 to explicitly authorize the request,
+ * KRB5_PLUGIN_NO_HANDLE to neither authorize nor deny the request, and any
+ * other error code (such as EPERM) to explicitly deny the request. If a check
+ * method is not defined, the module will neither authorize nor deny the
+ * request. A request succeeds if at least one kadm5_auth module explicitly
+ * authorizes the request and none of the modules explicitly deny it.
+ */
+
+/* Optional: authorize an add-principal operation, and optionally generate
+ * restrictions. */
+typedef krb5_error_code
+(*kadm5_auth_addprinc_fn)(krb5_context context, kadm5_auth_moddata data,
+ krb5_const_principal client,
+ krb5_const_principal target,
+ const struct _kadm5_principal_ent_t *ent, long mask,
+ struct kadm5_auth_restrictions **rs_out);
+
+/* Optional: authorize a modify-principal operation, and optionally generate
+ * restrictions. */
+typedef krb5_error_code
+(*kadm5_auth_modprinc_fn)(krb5_context context, kadm5_auth_moddata data,
+ krb5_const_principal client,
+ krb5_const_principal target,
+ const struct _kadm5_principal_ent_t *ent, long mask,
+ struct kadm5_auth_restrictions **rs_out);
+
+/* Optional: authorize a set-string operation. */
+typedef krb5_error_code
+(*kadm5_auth_setstr_fn)(krb5_context context, kadm5_auth_moddata data,
+ krb5_const_principal client,
+ krb5_const_principal target,
+ const char *key, const char *value);
+
+/* Optional: authorize a change-password operation. */
+typedef krb5_error_code
+(*kadm5_auth_cpw_fn)(krb5_context context, kadm5_auth_moddata data,
+ krb5_const_principal client, krb5_const_principal target);
+
+/* Optional: authorize a randomize-keys operation. */
+typedef krb5_error_code
+(*kadm5_auth_chrand_fn)(krb5_context context, kadm5_auth_moddata data,
+ krb5_const_principal client,
+ krb5_const_principal target);
+
+/* Optional: authorize a set-key operation. */
+typedef krb5_error_code
+(*kadm5_auth_setkey_fn)(krb5_context context, kadm5_auth_moddata data,
+ krb5_const_principal client,
+ krb5_const_principal target);
+
+/* Optional: authorize a purgekeys operation. */
+typedef krb5_error_code
+(*kadm5_auth_purgekeys_fn)(krb5_context context, kadm5_auth_moddata data,
+ krb5_const_principal client,
+ krb5_const_principal target);
+
+/* Optional: authorize a delete-principal operation. */
+typedef krb5_error_code
+(*kadm5_auth_delprinc_fn)(krb5_context context, kadm5_auth_moddata data,
+ krb5_const_principal client,
+ krb5_const_principal target);
+
+/* Optional: authorize a rename-principal operation. */
+typedef krb5_error_code
+(*kadm5_auth_renprinc_fn)(krb5_context context, kadm5_auth_moddata data,
+ krb5_const_principal client,
+ krb5_const_principal src,
+ krb5_const_principal dest);
+
+/* Optional: authorize a get-principal operation. */
+typedef krb5_error_code
+(*kadm5_auth_getprinc_fn)(krb5_context context, kadm5_auth_moddata data,
+ krb5_const_principal client,
+ krb5_const_principal target);
+
+/* Optional: authorize a get-strings operation. */
+typedef krb5_error_code
+(*kadm5_auth_getstrs_fn)(krb5_context context, kadm5_auth_moddata data,
+ krb5_const_principal client,
+ krb5_const_principal target);
+
+/* Optional: authorize an extract-keys operation. */
+typedef krb5_error_code
+(*kadm5_auth_extract_fn)(krb5_context context, kadm5_auth_moddata data,
+ krb5_const_principal client,
+ krb5_const_principal target);
+
+/* Optional: authorize a list-principals operation. */
+typedef krb5_error_code
+(*kadm5_auth_listprincs_fn)(krb5_context context, kadm5_auth_moddata data,
+ krb5_const_principal client);
+
+/* Optional: authorize an add-policy operation. */
+typedef krb5_error_code
+(*kadm5_auth_addpol_fn)(krb5_context context, kadm5_auth_moddata data,
+ krb5_const_principal client, const char *policy,
+ const struct _kadm5_policy_ent_t *ent, long mask);
+
+/* Optional: authorize a modify-policy operation. */
+typedef krb5_error_code
+(*kadm5_auth_modpol_fn)(krb5_context context, kadm5_auth_moddata data,
+ krb5_const_principal client, const char *policy,
+ const struct _kadm5_policy_ent_t *ent, long mask);
+
+/* Optional: authorize a delete-policy operation. */
+typedef krb5_error_code
+(*kadm5_auth_delpol_fn)(krb5_context context, kadm5_auth_moddata data,
+ krb5_const_principal client, const char *policy);
+
+/* Optional: authorize a get-policy operation. client_policy is the client
+ * principal's policy name, or NULL if it does not have one. */
+typedef krb5_error_code
+(*kadm5_auth_getpol_fn)(krb5_context context, kadm5_auth_moddata data,
+ krb5_const_principal client, const char *policy,
+ const char *client_policy);
+
+/* Optional: authorize a list-policies operation. */
+typedef krb5_error_code
+(*kadm5_auth_listpols_fn)(krb5_context context, kadm5_auth_moddata data,
+ krb5_const_principal client);
+
+/* Optional: authorize an iprop operation. */
+typedef krb5_error_code
+(*kadm5_auth_iprop_fn)(krb5_context context, kadm5_auth_moddata data,
+ krb5_const_principal client);
+
+/*
+ * Optional: receive a notification that the most recent authorized operation
+ * has ended. If a kadm5_auth module is also a KDB module, it can assume that
+ * all KDB methods invoked between a kadm5_auth authorization method invocation
+ * and a kadm5_auth end invocation are performed as part of the authorized
+ * operation.
+ *
+ * The end method may be invoked without a preceding authorization method in
+ * some cases; the module must be prepared to ignore such calls.
+ */
+typedef void
+(*kadm5_auth_end_fn)(krb5_context context, kadm5_auth_moddata data);
+
+/*
+ * Optional: free a restrictions object. This method does not need to be
+ * defined if the module does not generate restrictions objects, or if it
+ * returns aliases to restrictions objects contained from within the module
+ * data.
+ */
+typedef void
+(*kadm5_auth_free_restrictions_fn)(krb5_context context,
+ kadm5_auth_moddata data,
+ struct kadm5_auth_restrictions *rs);
+
+/* kadm5_auth vtable for major version 1. */
+typedef struct kadm5_auth_vtable_st {
+ const char *name; /* Mandatory: name of module. */
+ kadm5_auth_init_fn init;
+ kadm5_auth_fini_fn fini;
+
+ kadm5_auth_addprinc_fn addprinc;
+ kadm5_auth_modprinc_fn modprinc;
+ kadm5_auth_setstr_fn setstr;
+ kadm5_auth_cpw_fn cpw;
+ kadm5_auth_chrand_fn chrand;
+ kadm5_auth_setkey_fn setkey;
+ kadm5_auth_purgekeys_fn purgekeys;
+ kadm5_auth_delprinc_fn delprinc;
+ kadm5_auth_renprinc_fn renprinc;
+
+ kadm5_auth_getprinc_fn getprinc;
+ kadm5_auth_getstrs_fn getstrs;
+ kadm5_auth_extract_fn extract;
+ kadm5_auth_listprincs_fn listprincs;
+
+ kadm5_auth_addpol_fn addpol;
+ kadm5_auth_modpol_fn modpol;
+ kadm5_auth_delpol_fn delpol;
+ kadm5_auth_getpol_fn getpol;
+ kadm5_auth_listpols_fn listpols;
+
+ kadm5_auth_iprop_fn iprop;
+
+ kadm5_auth_end_fn end;
+
+ kadm5_auth_free_restrictions_fn free_restrictions;
+ /* Minor version 1 ends here. */
+} *kadm5_auth_vtable;
+
+#endif /* KRB5_KADM5_AUTH_PLUGIN_H */
diff --git a/src/include/krb5/kdcpolicy_plugin.h b/src/include/krb5/kdcpolicy_plugin.h
new file mode 100644
index 000000000000..c7592c5dba78
--- /dev/null
+++ b/src/include/krb5/kdcpolicy_plugin.h
@@ -0,0 +1,128 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/* include/krb5/kdcpolicy_plugin.h - KDC policy plugin interface */
+/*
+ * Copyright (C) 2017 by Red Hat, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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
+ * COPYRIGHT HOLDER 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.
+ */
+
+/*
+ * Declarations for kdcpolicy plugin module implementors.
+ *
+ * The kdcpolicy pluggable interface currently has only one supported major
+ * version, which is 1. Major version 1 has a current minor version number of
+ * 1.
+ *
+ * kdcpolicy plugin modules should define a function named
+ * kdcpolicy_<modulename>_initvt, matching the signature:
+ *
+ * krb5_error_code
+ * kdcpolicy_modname_initvt(krb5_context context, int maj_ver, int min_ver,
+ * krb5_plugin_vtable vtable);
+ *
+ * The initvt function should:
+ *
+ * - Check that the supplied maj_ver number is supported by the module, or
+ * return KRB5_PLUGIN_VER_NOTSUPP if it is not.
+ *
+ * - Cast the vtable pointer as appropriate for maj_ver:
+ * maj_ver == 1: Cast to krb5_kdcpolicy_vtable
+ *
+ * - Initialize the methods of the vtable, stopping as appropriate for the
+ * supplied min_ver. Optional methods may be left uninitialized.
+ *
+ * Memory for the vtable is allocated by the caller, not by the module.
+ */
+
+#ifndef KRB5_POLICY_PLUGIN_H
+#define KRB5_POLICY_PLUGIN_H
+
+#include <krb5/krb5.h>
+
+/* Abstract module datatype. */
+typedef struct krb5_kdcpolicy_moddata_st *krb5_kdcpolicy_moddata;
+
+/* A module can optionally include kdb.h to inspect principal entries when
+ * authorizing requests. */
+struct _krb5_db_entry_new;
+
+/*
+ * Optional: Initialize module data. Return 0 on success,
+ * KRB5_PLUGIN_NO_HANDLE if the module is inoperable (due to configuration, for
+ * example), and any other error code to abort KDC startup. Optionally set
+ * *data_out to a module data object to be passed to future calls.
+ */
+typedef krb5_error_code
+(*krb5_kdcpolicy_init_fn)(krb5_context context,
+ krb5_kdcpolicy_moddata *data_out);
+
+/* Optional: Clean up module data. */
+typedef krb5_error_code
+(*krb5_kdcpolicy_fini_fn)(krb5_context context,
+ krb5_kdcpolicy_moddata moddata);
+
+/*
+ * Optional: return an error code and set status to an appropriate string
+ * literal to deny an AS request; otherwise return 0. lifetime_out, if set,
+ * restricts the ticket lifetime. renew_lifetime_out, if set, restricts the
+ * ticket renewable lifetime.
+ */
+typedef krb5_error_code
+(*krb5_kdcpolicy_check_as_fn)(krb5_context context,
+ krb5_kdcpolicy_moddata moddata,
+ const krb5_kdc_req *request,
+ const struct _krb5_db_entry_new *client,
+ const struct _krb5_db_entry_new *server,
+ const char *const *auth_indicators,
+ const char **status, krb5_deltat *lifetime_out,
+ krb5_deltat *renew_lifetime_out);
+
+/*
+ * Optional: return an error code and set status to an appropriate string
+ * literal to deny a TGS request; otherwise return 0. lifetime_out, if set,
+ * restricts the ticket lifetime. renew_lifetime_out, if set, restricts the
+ * ticket renewable lifetime.
+ */
+typedef krb5_error_code
+(*krb5_kdcpolicy_check_tgs_fn)(krb5_context context,
+ krb5_kdcpolicy_moddata moddata,
+ const krb5_kdc_req *request,
+ const struct _krb5_db_entry_new *server,
+ const krb5_ticket *ticket,
+ const char *const *auth_indicators,
+ const char **status, krb5_deltat *lifetime_out,
+ krb5_deltat *renew_lifetime_out);
+
+typedef struct krb5_kdcpolicy_vtable_st {
+ const char *name;
+ krb5_kdcpolicy_init_fn init;
+ krb5_kdcpolicy_fini_fn fini;
+ krb5_kdcpolicy_check_as_fn check_as;
+ krb5_kdcpolicy_check_tgs_fn check_tgs;
+} *krb5_kdcpolicy_vtable;
+
+#endif /* KRB5_POLICY_PLUGIN_H */
diff --git a/src/include/krb5/kdcpreauth_plugin.h b/src/include/krb5/kdcpreauth_plugin.h
index f455effaecdb..f388200999ef 100644
--- a/src/include/krb5/kdcpreauth_plugin.h
+++ b/src/include/krb5/kdcpreauth_plugin.h
@@ -34,7 +34,7 @@
* Declarations for kdcpreauth plugin module implementors.
*
* The kdcpreauth interface has a single supported major version, which is 1.
- * Major version 1 has a current minor version of 3. kdcpreauth modules should
+ * Major version 1 has a current minor version of 2. kdcpreauth modules should
* define a function named kdcpreauth_<modulename>_initvt, matching the
* signature:
*
@@ -221,6 +221,25 @@ typedef struct krb5_kdcpreauth_callbacks_st {
/* End of version 3 kdcpreauth callbacks. */
+ /*
+ * Return true if princ matches the principal named in the request or the
+ * client principal (possibly canonicalized). If princ does not match,
+ * attempt a database lookup of princ with aliases allowed and compare the
+ * result to the client principal, returning true if it matches.
+ * Otherwise, return false.
+ */
+ krb5_boolean (*match_client)(krb5_context context,
+ krb5_kdcpreauth_rock rock,
+ krb5_principal princ);
+
+ /*
+ * Get an alias to the client DB entry principal (possibly canonicalized).
+ */
+ krb5_principal (*client_name)(krb5_context context,
+ krb5_kdcpreauth_rock rock);
+
+ /* End of version 4 kdcpreauth callbacks. */
+
} *krb5_kdcpreauth_callbacks;
/* Optional: preauth plugin initialization function. */
diff --git a/src/include/krb5/krb5.hin b/src/include/krb5/krb5.hin
index ac22f4c55098..c86e78274484 100644
--- a/src/include/krb5/krb5.hin
+++ b/src/include/krb5/krb5.hin
@@ -181,7 +181,16 @@ typedef krb5_int32 krb5_cryptotype;
typedef krb5_int32 krb5_preauthtype; /* This may change, later on */
typedef krb5_int32 krb5_flags;
+
+/**
+ * Represents a timestamp in seconds since the POSIX epoch. This legacy type
+ * is used frequently in the ABI, but cannot represent timestamps after 2038 as
+ * a positive number. Code which uses this type should cast values of it to
+ * uint32_t so that negative values are treated as timestamps between 2038 and
+ * 2106 on platforms with 64-bit time_t.
+ */
typedef krb5_int32 krb5_timestamp;
+
typedef krb5_int32 krb5_deltat;
/**
@@ -3221,8 +3230,9 @@ krb5_get_credentials_renew(krb5_context context, krb5_flags options,
*/
krb5_error_code KRB5_CALLCONV
krb5_mk_req(krb5_context context, krb5_auth_context *auth_context,
- krb5_flags ap_req_options, char *service, char *hostname,
- krb5_data *in_data, krb5_ccache ccache, krb5_data *outbuf);
+ krb5_flags ap_req_options, const char *service,
+ const char *hostname, krb5_data *in_data, krb5_ccache ccache,
+ krb5_data *outbuf);
/**
* Create a @c KRB_AP_REQ message using supplied credentials.
@@ -5615,8 +5625,9 @@ krb5_rd_cred(krb5_context context, krb5_auth_context auth_context,
*/
krb5_error_code KRB5_CALLCONV
krb5_fwd_tgt_creds(krb5_context context, krb5_auth_context auth_context,
- char *rhost, krb5_principal client, krb5_principal server,
- krb5_ccache cc, int forwardable, krb5_data *outbuf);
+ const char *rhost, krb5_principal client,
+ krb5_principal server, krb5_ccache cc, int forwardable,
+ krb5_data *outbuf);
/**
* Create and initialize an authentication context.
@@ -6000,15 +6011,19 @@ krb5_error_code KRB5_CALLCONV
krb5_auth_con_getremoteseqnumber(krb5_context context, krb5_auth_context auth_context,
krb5_int32 *seqnumber);
-#if KRB5_DEPRECATED
-/** @deprecated Not replaced.
+/**
+ * Cause an auth context to use cipher state.
+ *
+ * @param [in] context Library context
+ * @param [in] auth_context Authentication context
*
- * RFC 4120 doesn't have anything like the initvector concept;
- * only really old protocols may need this API.
+ * Prepare @a auth_context to use cipher state when krb5_mk_priv() or
+ * krb5_rd_priv() encrypt or decrypt data.
+ *
+ * @retval 0 Success; otherwise - Kerberos error codes
*/
-KRB5_ATTR_DEPRECATED krb5_error_code KRB5_CALLCONV
+krb5_error_code KRB5_CALLCONV
krb5_auth_con_initivector(krb5_context context, krb5_auth_context auth_context);
-#endif
/**
* Set the replay cache in an auth context.
@@ -7306,6 +7321,9 @@ typedef struct _krb5_init_creds_context *krb5_init_creds_context;
*
* @param [in] context Library context
* @param [in] ctx Initial credentials context
+ *
+ * @a context must be the same as the one passed to krb5_init_creds_init() for
+ * this initial credentials context.
*/
void KRB5_CALLCONV
krb5_init_creds_free(krb5_context context, krb5_init_creds_context ctx);
@@ -7320,6 +7338,9 @@ krb5_init_creds_free(krb5_context context, krb5_init_creds_context ctx);
* krb5_init_creds_init(). On successful return, the credentials can be
* retrieved with krb5_init_creds_get_creds().
*
+ * @a context must be the same as the one passed to krb5_init_creds_init() for
+ * this initial credentials context.
+ *
* @retval 0 Success; otherwise - Kerberos error codes
*/
krb5_error_code KRB5_CALLCONV
@@ -7370,6 +7391,10 @@ krb5_init_creds_get_error(krb5_context context, krb5_init_creds_context ctx,
* This function creates a new context for acquiring initial credentials. Use
* krb5_init_creds_free() to free @a ctx when it is no longer needed.
*
+ * Any subsequent calls to krb5_init_creds_step(), krb5_init_creds_get(), or
+ * krb5_init_creds_free() for this initial credentials context must use the
+ * same @a context argument as the one passed to this function.
+ *
* @retval 0 Success; otherwise - Kerberos error codes
*/
krb5_error_code KRB5_CALLCONV
@@ -7419,6 +7444,9 @@ krb5_init_creds_set_keytab(krb5_context context, krb5_init_creds_context ctx,
* transmit the next request using TCP rather than UDP. If this function
* returns any other error, the initial credential exchange has failed.
*
+ * @a context must be the same as the one passed to krb5_init_creds_init() for
+ * this initial credentials context.
+ *
* @retval 0 Success; otherwise - Kerberos error codes
*/
krb5_error_code KRB5_CALLCONV
@@ -8229,9 +8257,9 @@ krb5_pac_parse(krb5_context context, const void *ptr, size_t len,
* If successful, @a pac is marked as verified.
*
* @note A checksum mismatch can occur if the PAC was copied from a cross-realm
- * TGT by an ignorant KDC; also Apple Mac OS X Server Open Directory (as of
- * 10.6) generates PACs with no server checksum at all. One should consider
- * not failing the whole authentication because of this reason, but, instead,
+ * TGT by an ignorant KDC; also macOS Server Open Directory (as of 10.6)
+ * generates PACs with no server checksum at all. One should consider not
+ * failing the whole authentication because of this reason, but, instead,
* treating the ticket as if it did not contain a PAC or marking the PAC
* information as non-verified.
*
diff --git a/src/include/net-server.h b/src/include/net-server.h
index 37721e7f17a0..e5edcc49d5a1 100644
--- a/src/include/net-server.h
+++ b/src/include/net-server.h
@@ -86,7 +86,7 @@ void loop_free(verto_ctx *ctx);
*/
typedef void (*loop_respond_fn)(void *arg, krb5_error_code code,
krb5_data *response);
-void dispatch(void *handle, struct sockaddr *local_addr,
+void dispatch(void *handle, const krb5_fulladdr *local_addr,
const krb5_fulladdr *remote_addr, krb5_data *request,
int is_tcp, verto_ctx *vctx, loop_respond_fn respond, void *arg);
krb5_error_code make_toolong_error (void *handle, krb5_data **);
diff --git a/src/include/socket-utils.h b/src/include/socket-utils.h
index 156663683047..e1f33aa31763 100644
--- a/src/include/socket-utils.h
+++ b/src/include/socket-utils.h
@@ -119,6 +119,17 @@ sa_is_inet(struct sockaddr *sa)
return sa->sa_family == AF_INET || sa->sa_family == AF_INET6;
}
+/* Return true if sa is an IPv4 or IPv6 wildcard address. */
+static inline int
+sa_is_wildcard(struct sockaddr *sa)
+{
+ if (sa->sa_family == AF_INET6)
+ return IN6_IS_ADDR_UNSPECIFIED(&sa2sin6(sa)->sin6_addr);
+ else if (sa->sa_family == AF_INET)
+ return sa2sin(sa)->sin_addr.s_addr == INADDR_ANY;
+ return 0;
+}
+
/* Return the length of an IPv4 or IPv6 socket structure; abort if it is
* neither. */
static inline socklen_t
diff --git a/src/include/win-mac.h b/src/include/win-mac.h
index 1994388b71d3..c3744ed14ee6 100644
--- a/src/include/win-mac.h
+++ b/src/include/win-mac.h
@@ -225,9 +225,7 @@ typedef _W64 int ssize_t;
HINSTANCE get_lib_instance(void);
-#define GETSOCKNAME_ARG2_TYPE struct sockaddr
#define GETSOCKNAME_ARG3_TYPE size_t
-#define GETPEERNAME_ARG2_TYPE GETSOCKNAME_ARG2_TYPE
#define GETPEERNAME_ARG3_TYPE GETSOCKNAME_ARG3_TYPE
#endif /* !RES_ONLY */
diff --git a/src/kadmin/cli/deps b/src/kadmin/cli/deps
index a9c997b395ab..a5873fc79443 100644
--- a/src/kadmin/cli/deps
+++ b/src/kadmin/cli/deps
@@ -5,14 +5,21 @@ $(OUTPRE)kadmin.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
$(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssrpc/types.h \
$(BUILDTOP)/include/kadm5/admin.h $(BUILDTOP)/include/kadm5/chpass_util_strings.h \
$(BUILDTOP)/include/kadm5/kadm_err.h $(BUILDTOP)/include/krb5/krb5.h \
+ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \
$(COM_ERR_DEPS) $(top_srcdir)/include/adm_proto.h $(top_srcdir)/include/gssrpc/auth.h \
$(top_srcdir)/include/gssrpc/auth_gss.h $(top_srcdir)/include/gssrpc/auth_unix.h \
$(top_srcdir)/include/gssrpc/clnt.h $(top_srcdir)/include/gssrpc/rename.h \
$(top_srcdir)/include/gssrpc/rpc.h $(top_srcdir)/include/gssrpc/rpc_msg.h \
$(top_srcdir)/include/gssrpc/svc.h $(top_srcdir)/include/gssrpc/svc_auth.h \
- $(top_srcdir)/include/gssrpc/xdr.h $(top_srcdir)/include/k5-platform.h \
- $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/kdb.h \
- $(top_srcdir)/include/krb5.h kadmin.c kadmin.h
+ $(top_srcdir)/include/gssrpc/xdr.h $(top_srcdir)/include/k5-buf.h \
+ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \
+ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \
+ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \
+ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \
+ $(top_srcdir)/include/kdb.h $(top_srcdir)/include/krb5.h \
+ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \
+ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \
+ kadmin.c kadmin.h
$(OUTPRE)kadmin_ct.$(OBJEXT): $(COM_ERR_DEPS) $(SS_DEPS) \
kadmin_ct.c
$(OUTPRE)ss_wrapper.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
diff --git a/src/kadmin/cli/getdate.y b/src/kadmin/cli/getdate.y
index 4f0c56f7eb20..059f112da13a 100644
--- a/src/kadmin/cli/getdate.y
+++ b/src/kadmin/cli/getdate.y
@@ -6,7 +6,7 @@
** <rsalz@bbn.com> and Jim Berets <jberets@bbn.com> in August, 1990;
** send any email to Rich.
**
-** This grammar has nine shift/reduce conflicts.
+** This grammar has four shift/reduce conflicts.
**
** This code is in the public domain and has no copyright.
*/
@@ -118,7 +118,7 @@ static int getdate_yyerror (char *);
#define EPOCH 1970
-#define EPOCH_END 2038 /* assumes 32 bits */
+#define EPOCH_END 2106 /* assumes unsigned 32-bit range */
#define HOUR(x) ((time_t)(x) * 60)
#define SECSPERDAY (24L * 60L * 60L)
@@ -176,6 +176,9 @@ static time_t yyRelSeconds;
%}
+/* Mute shift/reduce warning as per header comment. */
+%expect 4
+
%union {
time_t Number;
enum _MERIDIAN Meridian;
diff --git a/src/kadmin/cli/kadmin.c b/src/kadmin/cli/kadmin.c
index c53c677a82d0..aee5c83b9546 100644
--- a/src/kadmin/cli/kadmin.c
+++ b/src/kadmin/cli/kadmin.c
@@ -31,8 +31,7 @@
* library */
/* for "_" macro */
-#include "k5-platform.h"
-#include <krb5.h>
+#include "k5-int.h"
#include <kadm5/admin.h>
#include <adm_proto.h>
#include <errno.h>
@@ -144,8 +143,8 @@ strdate(krb5_timestamp when)
{
struct tm *tm;
static char out[40];
+ time_t lcltim = ts2tt(when);
- time_t lcltim = when;
tm = localtime(&lcltim);
strftime(out, sizeof(out), "%a %b %d %H:%M:%S %Z %Y", tm);
return out;
diff --git a/src/kadmin/dbutil/dump.c b/src/kadmin/dbutil/dump.c
index f7889bd234f5..aca136f0b62f 100644
--- a/src/kadmin/dbutil/dump.c
+++ b/src/kadmin/dbutil/dump.c
@@ -370,11 +370,12 @@ k5beta7_common(krb5_context context, krb5_db_entry *entry,
fprintf(fp, "princ\t%d\t%lu\t%d\t%d\t%d\t%s\t", (int)entry->len,
(unsigned long)strlen(name), counter, (int)entry->n_key_data,
(int)entry->e_length, name);
- fprintf(fp, "%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d", entry->attributes,
- entry->max_life, entry->max_renewable_life, entry->expiration,
- entry->pw_expiration,
- omit_nra ? 0 : entry->last_success,
- omit_nra ? 0 : entry->last_failed,
+ fprintf(fp, "%d\t%d\t%d\t%u\t%u\t%u\t%u\t%d", entry->attributes,
+ entry->max_life, entry->max_renewable_life,
+ (unsigned int)entry->expiration,
+ (unsigned int)entry->pw_expiration,
+ (unsigned int)(omit_nra ? 0 : entry->last_success),
+ (unsigned int)(omit_nra ? 0 : entry->last_failed),
omit_nra ? 0 : entry->fail_auth_count);
/* Write out tagged data. */
@@ -688,6 +689,10 @@ process_tl_data(const char *fname, FILE *filep, int lineno,
_("cannot read tagged data type and length"));
return EINVAL;
}
+ if (i1 < INT16_MIN || i1 > INT16_MAX || u1 > UINT16_MAX) {
+ load_err(fname, lineno, _("data type or length overflowed"));
+ return EINVAL;
+ }
tl->tl_data_type = i1;
tl->tl_data_length = u1;
if (read_octets_or_minus1(filep, tl->tl_data_length,
@@ -708,7 +713,7 @@ process_k5beta7_princ(krb5_context context, const char *fname, FILE *filep,
{
int retval, nread, i, j;
krb5_db_entry *dbentry;
- int t1, t2, t3, t4, t5, t6, t7;
+ int t1, t2, t3, t4;
unsigned int u1, u2, u3, u4, u5;
char *name = NULL;
krb5_key_data *kp = NULL, *kd;
@@ -735,6 +740,10 @@ process_k5beta7_princ(krb5_context context, const char *fname, FILE *filep,
goto fail;
/* Get memory for and form tagged data linked list */
+ if (u3 > UINT16_MAX) {
+ load_err(fname, *linenop, _("cannot allocate tl_data (too large)"));
+ goto fail;
+ }
if (alloc_tl_data(u3, &dbentry->tl_data))
goto fail;
dbentry->n_tl_data = u3;
@@ -764,8 +773,8 @@ process_k5beta7_princ(krb5_context context, const char *fname, FILE *filep,
}
/* Get the fixed principal attributes */
- nread = fscanf(filep, "%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t",
- &t1, &t2, &t3, &t4, &t5, &t6, &t7, &u1);
+ nread = fscanf(filep, "%d\t%d\t%d\t%u\t%u\t%d\t%d\t%d\t",
+ &t1, &t2, &t3, &u1, &u2, &u3, &u4, &u5);
if (nread != 8) {
load_err(fname, *linenop, _("cannot read principal attributes"));
goto fail;
@@ -773,11 +782,11 @@ process_k5beta7_princ(krb5_context context, const char *fname, FILE *filep,
dbentry->attributes = t1;
dbentry->max_life = t2;
dbentry->max_renewable_life = t3;
- dbentry->expiration = t4;
- dbentry->pw_expiration = t5;
- dbentry->last_success = t6;
- dbentry->last_failed = t7;
- dbentry->fail_auth_count = u1;
+ dbentry->expiration = u1;
+ dbentry->pw_expiration = u2;
+ dbentry->last_success = u3;
+ dbentry->last_failed = u4;
+ dbentry->fail_auth_count = u5;
dbentry->mask = KADM5_LOAD | KADM5_PRINCIPAL | KADM5_ATTRIBUTES |
KADM5_MAX_LIFE | KADM5_MAX_RLIFE |
KADM5_PRINC_EXPIRE_TIME | KADM5_LAST_SUCCESS |
@@ -823,13 +832,17 @@ process_k5beta7_princ(krb5_context context, const char *fname, FILE *filep,
load_err(fname, *linenop, _("cannot read key size and version"));
goto fail;
}
+ if (t1 > KRB5_KDB_V1_KEY_DATA_ARRAY) {
+ load_err(fname, *linenop, _("unsupported key_data_ver version"));
+ goto fail;
+ }
kd->key_data_ver = t1;
kd->key_data_kvno = t2;
for (j = 0; j < t1; j++) {
nread = fscanf(filep, "%d\t%d\t", &t3, &t4);
- if (nread != 2) {
+ if (nread != 2 || t4 < 0) {
load_err(fname, *linenop,
_("cannot read key type and length"));
goto fail;
diff --git a/src/kadmin/dbutil/kdb5_mkey.c b/src/kadmin/dbutil/kdb5_mkey.c
index 7df8cbc83f21..2efe3176e81b 100644
--- a/src/kadmin/dbutil/kdb5_mkey.c
+++ b/src/kadmin/dbutil/kdb5_mkey.c
@@ -44,8 +44,8 @@ static char *strdate(krb5_timestamp when)
{
struct tm *tm;
static char out[40];
+ time_t lcltim = ts2tt(when);
- time_t lcltim = when;
tm = localtime(&lcltim);
strftime(out, sizeof(out), "%a %b %d %H:%M:%S %Z %Y", tm);
return out;
@@ -481,7 +481,7 @@ kdb5_use_mkey(int argc, char *argv[])
cur_actkvno != NULL;
prev_actkvno = cur_actkvno, cur_actkvno = cur_actkvno->next) {
- if (new_actkvno->act_time < cur_actkvno->act_time) {
+ if (ts_after(cur_actkvno->act_time, new_actkvno->act_time)) {
if (prev_actkvno) {
prev_actkvno->next = new_actkvno;
new_actkvno->next = cur_actkvno;
@@ -499,7 +499,7 @@ kdb5_use_mkey(int argc, char *argv[])
}
}
- if (actkvno_list->act_time > now) {
+ if (ts_after(actkvno_list->act_time, now)) {
com_err(progname, EINVAL,
_("there must be one master key currently active"));
exit_status++;
diff --git a/src/kadmin/dbutil/tabdump.c b/src/kadmin/dbutil/tabdump.c
index 69a3482ec935..fb36b060ac96 100644
--- a/src/kadmin/dbutil/tabdump.c
+++ b/src/kadmin/dbutil/tabdump.c
@@ -148,7 +148,7 @@ write_date_iso(struct rec_args *args, krb5_timestamp when)
struct tm *tm = NULL;
struct rechandle *h = args->rh;
- t = when;
+ t = ts2tt(when);
tm = gmtime(&t);
if (tm == NULL) {
errno = EINVAL;
diff --git a/src/kadmin/ktutil/ktutil.c b/src/kadmin/ktutil/ktutil.c
index ef16d37a5693..6a8586da8207 100644
--- a/src/kadmin/ktutil/ktutil.c
+++ b/src/kadmin/ktutil/ktutil.c
@@ -140,7 +140,8 @@ void ktutil_add_entry(argc, argv)
char *princ = NULL;
char *enctype = NULL;
krb5_kvno kvno = 0;
- int use_pass = 0, use_key = 0, i;
+ int use_pass = 0, use_key = 0, use_kvno = 0, i;
+ char *salt = NULL;
for (i = 1; i < argc; i++) {
if ((strlen(argv[i]) == 2) && !strncmp(argv[i], "-p", 2)) {
@@ -149,6 +150,7 @@ void ktutil_add_entry(argc, argv)
}
if ((strlen(argv[i]) == 2) && !strncmp(argv[i], "-k", 2)) {
kvno = (krb5_kvno) atoi(argv[++i]);
+ use_kvno++;
continue;
}
if ((strlen(argv[i]) == 2) && !strncmp(argv[i], "-e", 2)) {
@@ -163,15 +165,22 @@ void ktutil_add_entry(argc, argv)
use_key++;
continue;
}
+ if ((strlen(argv[i]) == 2) && !strncmp(argv[i], "-s", 2)) {
+ salt = argv[++i];
+ continue;
+ }
}
- if (argc != 8 || !(princ && kvno && enctype) || (use_pass+use_key != 1)) {
+ if (!((argc == 8 && princ && use_kvno && enctype) ||
+ (argc == 10 && princ && use_kvno && enctype && salt)) ||
+ use_pass + use_key != 1) {
fprintf(stderr, _("usage: %s (-key | -password) -p principal "
- "-k kvno -e enctype\n"), argv[0]);
+ "-k kvno -e enctype [-s salt]\n"), argv[0]);
return;
}
- retval = ktutil_add(kcontext, &ktlist, princ, kvno, enctype, use_pass);
+ retval = ktutil_add(kcontext, &ktlist, princ, kvno, enctype, use_pass,
+ salt);
if (retval)
com_err(argv[0], retval, _("while adding new entry"));
}
diff --git a/src/kadmin/ktutil/ktutil.h b/src/kadmin/ktutil/ktutil.h
index c4839ff12aa8..8bf491525095 100644
--- a/src/kadmin/ktutil/ktutil.h
+++ b/src/kadmin/ktutil/ktutil.h
@@ -38,7 +38,8 @@ krb5_error_code ktutil_add (krb5_context,
char *,
krb5_kvno,
char *,
- int);
+ int,
+ char *);
krb5_error_code ktutil_read_keytab (krb5_context,
char *,
diff --git a/src/kadmin/ktutil/ktutil_funcs.c b/src/kadmin/ktutil/ktutil_funcs.c
index 20a348c80582..7a3aa0dcad59 100644
--- a/src/kadmin/ktutil/ktutil_funcs.c
+++ b/src/kadmin/ktutil/ktutil_funcs.c
@@ -87,13 +87,14 @@ krb5_error_code ktutil_delete(context, list, idx)
* one first.
*/
krb5_error_code ktutil_add(context, list, princ_str, kvno,
- enctype_str, use_pass)
+ enctype_str, use_pass, salt_str)
krb5_context context;
krb5_kt_list *list;
char *princ_str;
krb5_kvno kvno;
char *enctype_str;
int use_pass;
+ char *salt_str;
{
krb5_keytab_entry *entry;
krb5_kt_list lp = NULL, prev = NULL;
@@ -101,7 +102,7 @@ krb5_error_code ktutil_add(context, list, princ_str, kvno,
krb5_enctype enctype;
krb5_timestamp now;
krb5_error_code retval;
- krb5_data password, salt;
+ krb5_data password, salt, defsalt = empty_data();
krb5_keyblock key;
char buf[BUFSIZ];
char promptstr[1024];
@@ -165,9 +166,14 @@ krb5_error_code ktutil_add(context, list, princ_str, kvno,
&password.length);
if (retval)
goto cleanup;
- retval = krb5_principal2salt(context, princ, &salt);
- if (retval)
- goto cleanup;
+ if (salt_str != NULL) {
+ salt = string2data(salt_str);
+ } else {
+ retval = krb5_principal2salt(context, princ, &defsalt);
+ if (retval)
+ goto cleanup;
+ salt = defsalt;
+ }
retval = krb5_c_string_to_key(context, enctype, &password,
&salt, &key);
if (retval)
@@ -225,6 +231,7 @@ cleanup:
if (prev)
prev->next = NULL;
ktutil_free_kt_list(context, lp);
+ krb5_free_data_contents(context, &defsalt);
return retval;
}
diff --git a/src/kadmin/server/Makefile.in b/src/kadmin/server/Makefile.in
index 3a013a4d4e15..16d5cc54aa4c 100644
--- a/src/kadmin/server/Makefile.in
+++ b/src/kadmin/server/Makefile.in
@@ -7,8 +7,10 @@ LOCALINCLUDES = -I$(top_srcdir)/lib/gssapi/generic \
-I$(BUILDTOP)/lib/gssapi/krb5 -I$(top_srcdir)/lib/kadm5/srv
PROG = kadmind
-OBJS = kadm_rpc_svc.o server_stubs.o ovsec_kadmd.o schpw.o misc.o ipropd_svc.o
-SRCS = kadm_rpc_svc.c server_stubs.c ovsec_kadmd.c schpw.c misc.c ipropd_svc.c
+OBJS = auth.o auth_acl.o auth_self.o kadm_rpc_svc.o server_stubs.o \
+ ovsec_kadmd.o schpw.o misc.o ipropd_svc.o
+SRCS = auth.o auth_acl.c auth_self.c kadm_rpc_svc.c server_stubs.c \
+ ovsec_kadmd.c schpw.c misc.c ipropd_svc.c
all: $(PROG)
diff --git a/src/kadmin/server/auth.c b/src/kadmin/server/auth.c
new file mode 100644
index 000000000000..081b20a8b678
--- /dev/null
+++ b/src/kadmin/server/auth.c
@@ -0,0 +1,314 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/* kadmin/server/auth.c - kadm5_auth pluggable interface consumer */
+/*
+ * Copyright (C) 2017 by the Massachusetts Institute of Technology.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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
+ * COPYRIGHT HOLDER 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 "k5-int.h"
+#include <kadm5/admin.h>
+#include <krb5/kadm5_auth_plugin.h>
+#include "auth.h"
+
+typedef struct {
+ struct kadm5_auth_vtable_st vt;
+ kadm5_auth_moddata data;
+} *auth_handle;
+
+static auth_handle *handles;
+
+void
+auth_fini(krb5_context context)
+{
+ auth_handle *hp, h;
+
+ if (handles == NULL)
+ return;
+ for (hp = handles; *hp != NULL; hp++) {
+ h = *hp;
+ if (h->vt.fini != NULL)
+ h->vt.fini(context, h->data);
+ free(h);
+ }
+ free(handles);
+ handles = NULL;
+}
+
+krb5_error_code
+auth_init(krb5_context context, const char *acl_file)
+{
+ krb5_error_code ret;
+ krb5_plugin_initvt_fn *modules = NULL, *mod;
+ size_t count;
+ auth_handle h = NULL;
+ const int intf = PLUGIN_INTERFACE_KADM5_AUTH;
+
+ ret = k5_plugin_register(context, intf, "acl", kadm5_auth_acl_initvt);
+ if (ret)
+ goto cleanup;
+ ret = k5_plugin_register(context, intf, "self", kadm5_auth_self_initvt);
+ if (ret)
+ goto cleanup;
+ ret = k5_plugin_load_all(context, PLUGIN_INTERFACE_KADM5_AUTH, &modules);
+ if (ret)
+ goto cleanup;
+
+ /* Allocate a large enough list of handles. */
+ for (count = 0; modules[count] != NULL; count++);
+ handles = k5calloc(count + 1, sizeof(*handles), &ret);
+ if (handles == NULL)
+ goto cleanup;
+
+ /* For each module, allocate a handle, initialize its vtable, and
+ * initialize its module data. */
+ count = 0;
+ for (mod = modules; *mod != NULL; mod++) {
+ h = k5alloc(sizeof(*h), &ret);
+ if (h == NULL)
+ goto cleanup;
+ ret = (*mod)(context, 1, 1, (krb5_plugin_vtable)&h->vt);
+ if (ret) { /* Failed vtable init is non-fatal. */
+ TRACE_KADM5_AUTH_VTINIT_FAIL(context, ret);
+ free(h);
+ h = NULL;
+ continue;
+ }
+ h->data = NULL;
+ if (h->vt.init != NULL) {
+ ret = h->vt.init(context, acl_file, &h->data);
+ if (ret == KRB5_PLUGIN_NO_HANDLE) {
+ TRACE_KADM5_AUTH_INIT_SKIP(context, h->vt.name);
+ free(h);
+ h = NULL;
+ continue;
+ }
+ if (ret) {
+ TRACE_KADM5_AUTH_INIT_FAIL(context, h->vt.name, ret);
+ goto cleanup;
+ }
+ }
+ handles[count++] = h;
+ handles[count] = NULL;
+ h = NULL;
+ }
+
+ ret = 0;
+
+cleanup:
+ if (ret)
+ auth_fini(context);
+ free(h);
+ k5_plugin_free_modules(context, modules);
+ return ret;
+}
+
+/* Invoke the appropriate method from h->vt for opcode, passing client and the
+ * correct subset of p1, p2, s1, s2, polent, and mask for the method. */
+static krb5_error_code
+call_module(krb5_context context, auth_handle h, int opcode,
+ krb5_const_principal client, krb5_const_principal p1,
+ krb5_const_principal p2, const char *s1, const char *s2,
+ const kadm5_policy_ent_rec *polent, long mask)
+{
+ /* addprinc and modprinc are handled through auth_restrict(). */
+ assert(opcode != OP_ADDPRINC && opcode != OP_MODPRINC);
+
+ if (opcode == OP_SETSTR && h->vt.setstr != NULL)
+ return h->vt.setstr(context, h->data, client, p1, s1, s2);
+ else if (opcode == OP_CPW && h->vt.cpw != NULL)
+ return h->vt.cpw(context, h->data, client, p1);
+ else if (opcode == OP_CHRAND && h->vt.chrand != NULL)
+ return h->vt.chrand(context, h->data, client, p1);
+ else if (opcode == OP_SETKEY && h->vt.setkey != NULL)
+ return h->vt.setkey(context, h->data, client, p1);
+ else if (opcode == OP_PURGEKEYS && h->vt.purgekeys != NULL)
+ return h->vt.purgekeys(context, h->data, client, p1);
+ else if (opcode == OP_DELPRINC && h->vt.delprinc != NULL)
+ return h->vt.delprinc(context, h->data, client, p1);
+ else if (opcode == OP_RENPRINC && h->vt.renprinc != NULL)
+ return h->vt.renprinc(context, h->data, client, p1, p2);
+ else if (opcode == OP_GETPRINC && h->vt.getprinc != NULL)
+ return h->vt.getprinc(context, h->data, client, p1);
+ else if (opcode == OP_GETSTRS && h->vt.getstrs != NULL)
+ return h->vt.getstrs(context, h->data, client, p1);
+ else if (opcode == OP_EXTRACT && h->vt.extract != NULL)
+ return h->vt.extract(context, h->data, client, p1);
+ else if (opcode == OP_LISTPRINCS && h->vt.listprincs != NULL)
+ return h->vt.listprincs(context, h->data, client);
+ else if (opcode == OP_ADDPOL && h->vt.addpol != NULL)
+ return h->vt.addpol(context, h->data, client, s1, polent, mask);
+ else if (opcode == OP_MODPOL && h->vt.modpol != NULL)
+ return h->vt.modpol(context, h->data, client, s1, polent, mask);
+ else if (opcode == OP_DELPOL && h->vt.delpol != NULL)
+ return h->vt.delpol(context, h->data, client, s1);
+ else if (opcode == OP_GETPOL && h->vt.getpol != NULL)
+ return h->vt.getpol(context, h->data, client, s1, s2);
+ else if (opcode == OP_LISTPOLS && h->vt.listpols != NULL)
+ return h->vt.listpols(context, h->data, client);
+ else if (opcode == OP_IPROP && h->vt.iprop != NULL)
+ return h->vt.iprop(context, h->data, client);
+
+ return KRB5_PLUGIN_NO_HANDLE;
+}
+
+krb5_boolean
+auth(krb5_context context, int opcode, krb5_const_principal client,
+ krb5_const_principal p1, krb5_const_principal p2, const char *s1,
+ const char *s2, const kadm5_policy_ent_rec *polent, long mask)
+{
+ krb5_error_code ret;
+ krb5_boolean authorized = FALSE;
+ auth_handle *hp, h;
+
+ for (hp = handles; *hp != NULL; hp++) {
+ h = *hp;
+
+ ret = call_module(context, h, opcode, client, p1, p2, s1, s2,
+ polent, mask);
+ if (!ret)
+ authorized = TRUE;
+ else if (ret != KRB5_PLUGIN_NO_HANDLE)
+ return FALSE;
+ }
+
+ return authorized;
+}
+
+/* Impose restrictions, modifying *ent and *mask. */
+static krb5_error_code
+impose_restrictions(krb5_context context,
+ const struct kadm5_auth_restrictions *rs,
+ kadm5_principal_ent_t ent, long *mask)
+{
+ krb5_error_code ret;
+ krb5_timestamp now;
+
+ if (rs == NULL)
+ return 0;
+ if (rs->mask & (KADM5_PRINC_EXPIRE_TIME | KADM5_PW_EXPIRATION)) {
+ ret = krb5_timeofday(context, &now);
+ if (ret)
+ return ret;
+ }
+
+ if (rs->mask & KADM5_ATTRIBUTES) {
+ ent->attributes |= rs->require_attrs;
+ ent->attributes &= rs->forbid_attrs;
+ *mask |= KADM5_ATTRIBUTES;
+ }
+ if (rs->mask & KADM5_POLICY_CLR) {
+ *mask &= ~KADM5_POLICY;
+ *mask |= KADM5_POLICY_CLR;
+ } else if (rs->mask & KADM5_POLICY) {
+ if (ent->policy != NULL && strcmp(ent->policy, rs->policy) != 0) {
+ free(ent->policy);
+ ent->policy = NULL;
+ }
+ if (ent->policy == NULL) {
+ ent->policy = strdup(rs->policy);
+ if (ent->policy == NULL)
+ return ENOMEM;
+ }
+ *mask |= KADM5_POLICY;
+ }
+ if (rs->mask & KADM5_PRINC_EXPIRE_TIME) {
+ if (!(*mask & KADM5_PRINC_EXPIRE_TIME) ||
+ ts_after(ent->princ_expire_time, ts_incr(now, rs->princ_lifetime)))
+ ent->princ_expire_time = now + rs->princ_lifetime;
+ *mask |= KADM5_PRINC_EXPIRE_TIME;
+ }
+ if (rs->mask & KADM5_PW_EXPIRATION) {
+ if (!(*mask & KADM5_PW_EXPIRATION) ||
+ ts_after(ent->pw_expiration, ts_incr(now, rs->pw_lifetime)))
+ ent->pw_expiration = now + rs->pw_lifetime;
+ *mask |= KADM5_PW_EXPIRATION;
+ }
+ if (rs->mask & KADM5_MAX_LIFE) {
+ if (!(*mask & KADM5_MAX_LIFE) || ent->max_life > rs->max_life)
+ ent->max_life = rs->max_life;
+ *mask |= KADM5_MAX_LIFE;
+ }
+ if (rs->mask & KADM5_MAX_RLIFE) {
+ if (!(*mask & KADM5_MAX_RLIFE) ||
+ ent->max_renewable_life > rs->max_renewable_life)
+ ent->max_renewable_life = rs->max_renewable_life;
+ *mask |= KADM5_MAX_RLIFE;
+ }
+ return 0;
+}
+
+krb5_boolean
+auth_restrict(krb5_context context, int opcode, krb5_const_principal client,
+ kadm5_principal_ent_t ent, long *mask)
+{
+ auth_handle *hp, h;
+ krb5_boolean authorized = FALSE;
+ krb5_error_code ret, rs_ret;
+ krb5_const_principal target = ent->principal;
+ struct kadm5_auth_restrictions *rs;
+
+ assert(opcode == OP_ADDPRINC || opcode == OP_MODPRINC);
+ for (hp = handles; *hp != NULL; hp++) {
+ h = *hp;
+
+ ret = KRB5_PLUGIN_NO_HANDLE;
+ rs = NULL;
+ if (opcode == OP_ADDPRINC && h->vt.addprinc != NULL) {
+ ret = h->vt.addprinc(context, h->data, client, target, ent, *mask,
+ &rs);
+ } else if (opcode == OP_MODPRINC && h->vt.modprinc != NULL) {
+ ret = h->vt.modprinc(context, h->data, client, target, ent, *mask,
+ &rs);
+ }
+ if (rs != NULL) {
+ rs_ret = impose_restrictions(context, rs, ent, mask);
+ if (h->vt.free_restrictions != NULL)
+ h->vt.free_restrictions(context, h->data, rs);
+ if (rs_ret)
+ return FALSE;
+ }
+ if (!ret)
+ authorized = TRUE;
+ else if (ret != KRB5_PLUGIN_NO_HANDLE)
+ return FALSE;
+ }
+
+ return authorized;
+}
+
+void
+auth_end(krb5_context context)
+{
+ auth_handle *hp, h;
+
+ for (hp = handles; *hp != NULL; hp++) {
+ h = *hp;
+ if (h->vt.end != NULL)
+ h->vt.end(context, h->data);
+ }
+}
diff --git a/src/kadmin/server/auth.h b/src/kadmin/server/auth.h
new file mode 100644
index 000000000000..4d265add7c0d
--- /dev/null
+++ b/src/kadmin/server/auth.h
@@ -0,0 +1,85 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/* kadmin/server/auth.h - kadmin authorization declarations */
+/*
+ * Copyright (C) 2017 by the Massachusetts Institute of Technology.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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
+ * COPYRIGHT HOLDER 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.
+ */
+
+#ifndef AUTH_H
+#define AUTH_H
+
+#define OP_ADDPRINC 1
+#define OP_MODPRINC 2
+#define OP_SETSTR 3
+#define OP_CPW 4
+#define OP_CHRAND 5
+#define OP_SETKEY 6
+#define OP_PURGEKEYS 7
+#define OP_DELPRINC 8
+#define OP_RENPRINC 9
+#define OP_GETPRINC 10
+#define OP_GETSTRS 11
+#define OP_EXTRACT 12
+#define OP_LISTPRINCS 13
+#define OP_ADDPOL 14
+#define OP_MODPOL 15
+#define OP_DELPOL 16
+#define OP_GETPOL 17
+#define OP_LISTPOLS 18
+#define OP_IPROP 19
+
+/* Initialize all authorization modules. */
+krb5_error_code auth_init(krb5_context context, const char *acl_file);
+
+/* Release authorization module state. */
+void auth_fini(krb5_context context);
+
+/* Authorize the operation given by opcode, using the appropriate subset of p1,
+ * p2, s1, s2, polent, and mask. */
+krb5_boolean auth(krb5_context context, int opcode,
+ krb5_const_principal client, krb5_const_principal p1,
+ krb5_const_principal p2, const char *s1, const char *s2,
+ const kadm5_policy_ent_rec *polent, long mask);
+
+/* Authorize an add-principal or modify-principal operation, and apply
+ * restrictions to ent and mask if any modules supply them. */
+krb5_boolean auth_restrict(krb5_context context, int opcode,
+ krb5_const_principal client,
+ kadm5_principal_ent_t ent, long *mask);
+
+/* Notify modules that the most recent authorized operation has ended. */
+void auth_end(krb5_context context);
+
+/* initvt declarations for built-in modules */
+
+krb5_error_code kadm5_auth_acl_initvt(krb5_context context, int maj_ver,
+ int min_ver, krb5_plugin_vtable vtable);
+krb5_error_code kadm5_auth_self_initvt(krb5_context context, int maj_ver,
+ int min_ver, krb5_plugin_vtable vtable);
+
+#endif /* AUTH_H */
diff --git a/src/kadmin/server/auth_acl.c b/src/kadmin/server/auth_acl.c
new file mode 100644
index 000000000000..efe9c6961bbb
--- /dev/null
+++ b/src/kadmin/server/auth_acl.c
@@ -0,0 +1,755 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/* kadmin/server/auth_acl.c - ACL kadm5_auth module */
+/*
+ * Copyright 1995-2004, 2007, 2008, 2017 by the Massachusetts Institute of
+ * Technology. All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ */
+
+#include "k5-int.h"
+#include <syslog.h>
+#include <kadm5/admin.h>
+#include <krb5/kadm5_auth_plugin.h>
+#include "adm_proto.h"
+#include <ctype.h>
+#include "auth.h"
+
+/*
+ * Access control bits.
+ */
+#define ACL_ADD 1
+#define ACL_DELETE 2
+#define ACL_MODIFY 4
+#define ACL_CHANGEPW 8
+/* #define ACL_CHANGE_OWN_PW 16 */
+#define ACL_INQUIRE 32
+#define ACL_EXTRACT 64
+#define ACL_LIST 128
+#define ACL_SETKEY 256
+#define ACL_IPROP 512
+
+#define ACL_ALL_MASK (ACL_ADD | \
+ ACL_DELETE | \
+ ACL_MODIFY | \
+ ACL_CHANGEPW | \
+ ACL_INQUIRE | \
+ ACL_LIST | \
+ ACL_IPROP | \
+ ACL_SETKEY)
+
+struct acl_op_table {
+ char op;
+ uint32_t mask;
+};
+
+struct acl_entry {
+ struct acl_entry *next;
+ krb5_principal client;
+ uint32_t op_allowed;
+ krb5_principal target;
+ struct kadm5_auth_restrictions *rs;
+};
+
+static const struct acl_op_table acl_op_table[] = {
+ { 'a', ACL_ADD },
+ { 'd', ACL_DELETE },
+ { 'm', ACL_MODIFY },
+ { 'c', ACL_CHANGEPW },
+ { 'i', ACL_INQUIRE },
+ { 'l', ACL_LIST },
+ { 'p', ACL_IPROP },
+ { 's', ACL_SETKEY },
+ { 'x', ACL_ALL_MASK },
+ { '*', ACL_ALL_MASK },
+ { 'e', ACL_EXTRACT },
+ { '\0', 0 }
+};
+
+struct wildstate {
+ int nwild;
+ const krb5_data *backref[9];
+};
+
+struct acl_state {
+ struct acl_entry *list;
+};
+
+/*
+ * Get a line from the ACL file. Lines ending with \ are continued on the next
+ * line. The caller should set *lineno to 1 and *incr to 0 before the first
+ * call. On successful return, *lineno will be the line number of the line
+ * read. Return a pointer to the line on success, or NULL on end of file or
+ * read failure.
+ */
+static char *
+get_line(FILE *fp, const char *fname, int *lineno, int *incr)
+{
+ const int chunksize = 128;
+ struct k5buf buf;
+ size_t old_len;
+ char *p;
+
+ /* Increment *lineno by the number of newlines from the last line. */
+ *lineno += *incr;
+ *incr = 0;
+
+ k5_buf_init_dynamic(&buf);
+ for (;;) {
+ /* Read at least part of a line into the buffer. */
+ old_len = buf.len;
+ p = k5_buf_get_space(&buf, chunksize);
+ if (p == NULL)
+ return NULL;
+
+ if (fgets(p, chunksize, fp) == NULL) {
+ /* We reached the end. Return a final unterminated line, if there
+ * is one and it's not a comment. */
+ k5_buf_truncate(&buf, old_len);
+ if (buf.len > 0 && *(char *)buf.data != '#')
+ return buf.data;
+ k5_buf_free(&buf);
+ return NULL;
+ }
+
+ /* Set the buffer length based on the actual amount read. */
+ k5_buf_truncate(&buf, old_len + strlen(p));
+
+ p = buf.data;
+ if (buf.len > 0 && p[buf.len - 1] == '\n') {
+ /* We have a complete raw line in the buffer. */
+ (*incr)++;
+ k5_buf_truncate(&buf, buf.len - 1);
+ if (buf.len > 0 && p[buf.len - 1] == '\\') {
+ /* This line has a continuation marker; keep reading. */
+ k5_buf_truncate(&buf, buf.len - 1);
+ } else if (buf.len == 0 || *p == '#') {
+ /* This line is empty or a comment. Start over. */
+ *lineno += *incr;
+ *incr = 0;
+ k5_buf_truncate(&buf, 0);
+ } else {
+ return buf.data;
+ }
+ }
+ }
+}
+
+/*
+ * Parse a restrictions field. Return NULL on failure.
+ *
+ * Allowed restrictions are:
+ * [+-]flagname (recognized by krb5_flagspec_to_mask)
+ * flag is forced to indicated value
+ * -clearpolicy policy is forced clear
+ * -policy pol policy is forced to be "pol"
+ * -{expire,pwexpire,maxlife,maxrenewlife} deltat
+ * associated value will be forced to
+ * MIN(deltat, requested value)
+ */
+static struct kadm5_auth_restrictions *
+parse_restrictions(const char *str, const char *fname)
+{
+ char *copy = NULL, *token, *arg, *save;
+ const char *delims = "\t\n\f\v\r ,";
+ krb5_deltat delta;
+ struct kadm5_auth_restrictions *rs;
+
+ copy = strdup(str);
+ if (copy == NULL)
+ return NULL;
+
+ rs = calloc(1, sizeof(*rs));
+ if (rs == NULL) {
+ free(copy);
+ return NULL;
+ }
+
+ rs->forbid_attrs = ~(krb5_flags)0;
+ for (token = strtok_r(copy, delims, &save); token != NULL;
+ token = strtok_r(NULL, delims, &save)) {
+
+ if (krb5_flagspec_to_mask(token, &rs->require_attrs,
+ &rs->forbid_attrs) == 0) {
+ rs->mask |= KADM5_ATTRIBUTES;
+ continue;
+ }
+
+ if (strcmp(token, "-clearpolicy") == 0) {
+ rs->mask |= KADM5_POLICY_CLR;
+ continue;
+ }
+
+ /* Everything else needs an argument. */
+ arg = strtok_r(NULL, delims, &save);
+ if (arg == NULL)
+ goto error;
+
+ if (strcmp(token, "-policy") == 0) {
+ if (rs->policy != NULL)
+ goto error;
+ rs->policy = strdup(arg);
+ if (rs->policy == NULL)
+ goto error;
+ rs->mask |= KADM5_POLICY;
+ continue;
+ }
+
+ /* All other arguments must be a deltat. */
+ if (krb5_string_to_deltat(arg, &delta) != 0)
+ goto error;
+
+ if (strcmp(token, "-expire") == 0) {
+ rs->princ_lifetime = delta;
+ rs->mask |= KADM5_PRINC_EXPIRE_TIME;
+ } else if (strcmp(token, "-pwexpire") == 0) {
+ rs->pw_lifetime = delta;
+ rs->mask |= KADM5_PW_EXPIRATION;
+ } else if (strcmp(token, "-maxlife") == 0) {
+ rs->max_life = delta;
+ rs->mask |= KADM5_MAX_LIFE;
+ } else if (strcmp(token, "-maxrenewlife") == 0) {
+ rs->max_renewable_life = delta;
+ rs->mask |= KADM5_MAX_RLIFE;
+ } else {
+ goto error;
+ }
+ }
+
+ free(copy);
+ return rs;
+
+error:
+ krb5_klog_syslog(LOG_ERR, _("%s: invalid restrictions: %s"), fname, str);
+ free(copy);
+ free(rs->policy);
+ free(rs);
+ return NULL;
+}
+
+static void
+free_acl_entry(struct acl_entry *entry)
+{
+ krb5_free_principal(NULL, entry->client);
+ krb5_free_principal(NULL, entry->target);
+ if (entry->rs != NULL) {
+ free(entry->rs->policy);
+ free(entry->rs);
+ }
+ free(entry);
+}
+
+/* Parse the four fields of an ACL entry and return a structure representing
+ * it. Log a message and return NULL on error. */
+static struct acl_entry *
+parse_entry(krb5_context context, const char *client, const char *ops,
+ const char *target, const char *rs, const char *line,
+ const char *fname)
+{
+ struct acl_entry *entry;
+ const char *op;
+ char rop;
+ int t;
+
+ entry = calloc(1, sizeof(*entry));
+ if (entry == NULL)
+ return NULL;
+
+ for (op = ops; *op; op++) {
+ rop = isupper((unsigned char)*op) ? tolower((unsigned char)*op) : *op;
+ for (t = 0; acl_op_table[t].op; t++) {
+ if (rop == acl_op_table[t].op) {
+ if (rop == *op)
+ entry->op_allowed |= acl_op_table[t].mask;
+ else
+ entry->op_allowed &= ~acl_op_table[t].mask;
+ break;
+ }
+ }
+ if (!acl_op_table[t].op) {
+ krb5_klog_syslog(LOG_ERR,
+ _("Unrecognized ACL operation '%c' in %s"),
+ *op, line);
+ goto error;
+ }
+ }
+
+ if (strcmp(client, "*") != 0) {
+ if (krb5_parse_name(context, client, &entry->client) != 0) {
+ krb5_klog_syslog(LOG_ERR, _("Cannot parse client principal '%s'"),
+ client);
+ goto error;
+ }
+ }
+
+ if (target != NULL && strcmp(target, "*") != 0) {
+ if (krb5_parse_name(context, target, &entry->target) != 0) {
+ krb5_klog_syslog(LOG_ERR, _("Cannot parse target principal '%s'"),
+ target);
+ goto error;
+ }
+ }
+
+ if (rs != NULL) {
+ entry->rs = parse_restrictions(rs, fname);
+ if (entry->rs == NULL)
+ goto error;
+ }
+
+ return entry;
+
+error:
+ free_acl_entry(entry);
+ return NULL;
+}
+
+/* Parse the contents of an ACL line. */
+static struct acl_entry *
+parse_line(krb5_context context, const char *line, const char *fname)
+{
+ struct acl_entry *entry = NULL;
+ char *copy;
+ char *client, *client_end, *ops, *ops_end, *target, *target_end, *rs, *end;
+ const char *ws = "\t\n\f\v\r ,";
+
+ /*
+ * Format:
+ * entry ::= [<whitespace>] <principal> <whitespace> <opstring>
+ * [<whitespace> <target> [<whitespace> <restrictions>
+ * [<whitespace>]]]
+ */
+
+ /* Make a copy and remove any trailing whitespace. */
+ copy = strdup(line);
+ if (copy == NULL)
+ return NULL;
+ end = copy + strlen(copy);
+ while (end > copy && isspace(end[-1]))
+ *--end = '\0';
+
+ /* Find the beginning and end of each field. The end of restrictions is
+ * the end of copy. */
+ client = copy + strspn(copy, ws);
+ client_end = client + strcspn(client, ws);
+ ops = client_end + strspn(client_end, ws);
+ ops_end = ops + strcspn(ops, ws);
+ target = ops_end + strspn(ops_end, ws);
+ target_end = target + strcspn(target, ws);
+ rs = target_end + strspn(target_end, ws);
+
+ /* Terminate the first three fields. */
+ *client_end = *ops_end = *target_end = '\0';
+
+ /* The last two fields are optional; represent them as NULL if not present.
+ * The first two fields are required. */
+ if (*target == '\0')
+ target = NULL;
+ if (*rs == '\0')
+ rs = NULL;
+ if (*client != '\0' && *ops != '\0')
+ entry = parse_entry(context, client, ops, target, rs, line, fname);
+ free(copy);
+ return entry;
+}
+
+/* Free all ACL entries. */
+static void
+free_acl_entries(struct acl_state *state)
+{
+ struct acl_entry *entry, *next;
+
+ for (entry = state->list; entry != NULL; entry = next) {
+ next = entry->next;
+ free_acl_entry(entry);
+ }
+ state->list = NULL;
+}
+
+/* Open and parse the ACL file. */
+static krb5_error_code
+load_acl_file(krb5_context context, const char *fname, struct acl_state *state)
+{
+ krb5_error_code ret;
+ FILE *fp;
+ char *line;
+ struct acl_entry **entry_slot;
+ int lineno, incr;
+
+ state->list = NULL;
+
+ /* Open the ACL file for reading. */
+ fp = fopen(fname, "r");
+ if (fp == NULL) {
+ krb5_klog_syslog(LOG_ERR, _("%s while opening ACL file %s"),
+ error_message(errno), fname);
+ ret = errno;
+ k5_setmsg(context, errno, _("Cannot open %s: %s"), fname,
+ error_message(ret));
+ return ret;
+ }
+
+ set_cloexec_file(fp);
+ lineno = 1;
+ incr = 0;
+ entry_slot = &state->list;
+
+ /* Get a non-comment line. */
+ while ((line = get_line(fp, fname, &lineno, &incr)) != NULL) {
+ /* Parse it. Fail out on syntax error. */
+ *entry_slot = parse_line(context, line, fname);
+ if (*entry_slot == NULL) {
+ krb5_klog_syslog(LOG_ERR,
+ _("%s: syntax error at line %d <%.10s...>"),
+ fname, lineno, line);
+ k5_setmsg(context, EINVAL,
+ _("%s: syntax error at line %d <%.10s...>"),
+ fname, lineno, line);
+ free_acl_entries(state);
+ free(line);
+ fclose(fp);
+ return EINVAL;
+ }
+ entry_slot = &(*entry_slot)->next;
+ free(line);
+ }
+
+ fclose(fp);
+ return 0;
+}
+
+/*
+ * See if two data entries match. If e1 is a wildcard (matching a whole
+ * component only) and targetflag is false, save an alias to e2 into
+ * ws->backref. If e1 is a back-reference and targetflag is true, compare the
+ * appropriate entry in ws->backref to e2. If ws is NULL, do not store or
+ * match back-references.
+ */
+static krb5_boolean
+match_data(const krb5_data *e1, const krb5_data *e2, krb5_boolean targetflag,
+ struct wildstate *ws)
+{
+ int n;
+
+ if (data_eq_string(*e1, "*")) {
+ if (ws != NULL && !targetflag) {
+ if (ws->nwild < 9)
+ ws->backref[ws->nwild++] = e2;
+ }
+ return TRUE;
+ }
+
+ if (ws != NULL && targetflag && e1->length == 2 && e1->data[0] == '*' &&
+ e1->data[1] >= '1' && e1->data[1] <= '9') {
+ n = e1->data[1] - '1';
+ if (n >= ws->nwild)
+ return FALSE;
+ return data_eq(*e2, *ws->backref[n]);
+ } else {
+ return data_eq(*e2, *e1);
+ }
+}
+
+/* Return true if p1 matches p2. p1 may contain wildcards if targetflag is
+ * false, or backreferences if it is true. */
+static krb5_boolean
+match_princ(krb5_const_principal p1, krb5_const_principal p2,
+ krb5_boolean targetflag, struct wildstate *ws)
+{
+ int i;
+
+ /* The principals must be of the same length. */
+ if (p1->length != p2->length)
+ return FALSE;
+
+ /* The realm must match, and does not interact with wildcard state. */
+ if (!match_data(&p1->realm, &p2->realm, targetflag, NULL))
+ return FALSE;
+
+ /* All components of the principals must match. */
+ for (i = 0; i < p1->length; i++) {
+ if (!match_data(&p1->data[i], &p2->data[i], targetflag, ws))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* Find an ACL entry matching principal and target_principal. Return NULL if
+ * none is found. */
+static struct acl_entry *
+find_entry(struct acl_state *state, krb5_const_principal client,
+ krb5_const_principal target)
+{
+ struct acl_entry *entry;
+ struct wildstate ws;
+
+ for (entry = state->list; entry != NULL; entry = entry->next) {
+ memset(&ws, 0, sizeof(ws));
+ if (entry->client != NULL) {
+ if (!match_princ(entry->client, client, FALSE, &ws))
+ continue;
+ }
+
+ if (entry->target != NULL) {
+ if (target == NULL)
+ continue;
+ if (!match_princ(entry->target, target, TRUE, &ws))
+ continue;
+ }
+
+ return entry;
+ }
+
+ return NULL;
+}
+
+/* Return true if op is permitted for this principal. Set *rs_out (if not
+ * NULL) according to any restrictions in the ACL entry. */
+static krb5_error_code
+acl_check(kadm5_auth_moddata data, uint32_t op, krb5_const_principal client,
+ krb5_const_principal target, struct kadm5_auth_restrictions **rs_out)
+{
+ struct acl_entry *entry;
+
+ if (rs_out != NULL)
+ *rs_out = NULL;
+
+ entry = find_entry((struct acl_state *)data, client, target);
+ if (entry == NULL)
+ return KRB5_PLUGIN_NO_HANDLE;
+ if (!(entry->op_allowed & op))
+ return KRB5_PLUGIN_NO_HANDLE;
+
+ if (rs_out != NULL && entry->rs != NULL && entry->rs->mask)
+ *rs_out = entry->rs;
+
+ return 0;
+}
+
+static krb5_error_code
+acl_init(krb5_context context, const char *acl_file,
+ kadm5_auth_moddata *data_out)
+{
+ krb5_error_code ret;
+ struct acl_state *state;
+
+ *data_out = NULL;
+ if (acl_file == NULL)
+ return KRB5_PLUGIN_NO_HANDLE;
+ state = malloc(sizeof(*state));
+ state->list = NULL;
+ ret = load_acl_file(context, acl_file, state);
+ if (ret) {
+ free(state);
+ return ret;
+ }
+ *data_out = (kadm5_auth_moddata)state;
+ return 0;
+}
+
+static void
+acl_fini(krb5_context context, kadm5_auth_moddata data)
+{
+ if (data == NULL)
+ return;
+ free_acl_entries((struct acl_state *)data);
+ free(data);
+}
+
+static krb5_error_code
+acl_addprinc(krb5_context context, kadm5_auth_moddata data,
+ krb5_const_principal client, krb5_const_principal target,
+ const struct _kadm5_principal_ent_t *ent, long mask,
+ struct kadm5_auth_restrictions **rs_out)
+{
+ return acl_check(data, ACL_ADD, client, target, rs_out);
+}
+
+static krb5_error_code
+acl_modprinc(krb5_context context, kadm5_auth_moddata data,
+ krb5_const_principal client, krb5_const_principal target,
+ const struct _kadm5_principal_ent_t *ent, long mask,
+ struct kadm5_auth_restrictions **rs_out)
+{
+ return acl_check(data, ACL_MODIFY, client, target, rs_out);
+}
+
+static krb5_error_code
+acl_setstr(krb5_context context, kadm5_auth_moddata data,
+ krb5_const_principal client, krb5_const_principal target,
+ const char *key, const char *value)
+{
+ return acl_check(data, ACL_MODIFY, client, target, NULL);
+}
+
+static krb5_error_code
+acl_cpw(krb5_context context, kadm5_auth_moddata data,
+ krb5_const_principal client, krb5_const_principal target)
+{
+ return acl_check(data, ACL_CHANGEPW, client, target, NULL);
+}
+
+static krb5_error_code
+acl_chrand(krb5_context context, kadm5_auth_moddata data,
+ krb5_const_principal client, krb5_const_principal target)
+{
+ return acl_check(data, ACL_CHANGEPW, client, target, NULL);
+}
+
+static krb5_error_code
+acl_setkey(krb5_context context, kadm5_auth_moddata data,
+ krb5_const_principal client, krb5_const_principal target)
+{
+ return acl_check(data, ACL_SETKEY, client, target, NULL);
+}
+
+static krb5_error_code
+acl_purgekeys(krb5_context context, kadm5_auth_moddata data,
+ krb5_const_principal client, krb5_const_principal target)
+{
+ return acl_check(data, ACL_MODIFY, client, target, NULL);
+}
+
+static krb5_error_code
+acl_delprinc(krb5_context context, kadm5_auth_moddata data,
+ krb5_const_principal client, krb5_const_principal target)
+{
+ return acl_check(data, ACL_DELETE, client, target, NULL);
+}
+
+static krb5_error_code
+acl_renprinc(krb5_context context, kadm5_auth_moddata data,
+ krb5_const_principal client, krb5_const_principal src,
+ krb5_const_principal dest)
+{
+ struct kadm5_auth_restrictions *rs;
+
+ if (acl_check(data, ACL_DELETE, client, src, NULL) == 0 &&
+ acl_check(data, ACL_ADD, client, dest, &rs) == 0 && rs == NULL)
+ return 0;
+ return KRB5_PLUGIN_NO_HANDLE;
+}
+
+static krb5_error_code
+acl_getprinc(krb5_context context, kadm5_auth_moddata data,
+ krb5_const_principal client, krb5_const_principal target)
+{
+ return acl_check(data, ACL_INQUIRE, client, target, NULL);
+}
+
+static krb5_error_code
+acl_getstrs(krb5_context context, kadm5_auth_moddata data,
+ krb5_const_principal client, krb5_const_principal target)
+{
+ return acl_check(data, ACL_INQUIRE, client, target, NULL);
+}
+
+static krb5_error_code
+acl_extract(krb5_context context, kadm5_auth_moddata data,
+ krb5_const_principal client, krb5_const_principal target)
+{
+ return acl_check(data, ACL_EXTRACT, client, target, NULL);
+}
+
+static krb5_error_code
+acl_listprincs(krb5_context context, kadm5_auth_moddata data,
+ krb5_const_principal client)
+{
+ return acl_check(data, ACL_LIST, client, NULL, NULL);
+}
+
+static krb5_error_code
+acl_addpol(krb5_context context, kadm5_auth_moddata data,
+ krb5_const_principal client, const char *policy,
+ const struct _kadm5_policy_ent_t *ent, long mask)
+{
+ return acl_check(data, ACL_ADD, client, NULL, NULL);
+}
+
+static krb5_error_code
+acl_modpol(krb5_context context, kadm5_auth_moddata data,
+ krb5_const_principal client, const char *policy,
+ const struct _kadm5_policy_ent_t *ent, long mask)
+{
+ return acl_check(data, ACL_MODIFY, client, NULL, NULL);
+}
+
+static krb5_error_code
+acl_delpol(krb5_context context, kadm5_auth_moddata data,
+ krb5_const_principal client, const char *policy)
+{
+ return acl_check(data, ACL_DELETE, client, NULL, NULL);
+}
+
+static krb5_error_code
+acl_getpol(krb5_context context, kadm5_auth_moddata data,
+ krb5_const_principal client, const char *policy,
+ const char *client_policy)
+{
+ return acl_check(data, ACL_INQUIRE, client, NULL, NULL);
+}
+
+static krb5_error_code
+acl_listpols(krb5_context context, kadm5_auth_moddata data,
+ krb5_const_principal client)
+{
+ return acl_check(data, ACL_LIST, client, NULL, NULL);
+}
+
+static krb5_error_code
+acl_iprop(krb5_context context, kadm5_auth_moddata data,
+ krb5_const_principal client)
+{
+ return acl_check(data, ACL_IPROP, client, NULL, NULL);
+}
+
+krb5_error_code
+kadm5_auth_acl_initvt(krb5_context context, int maj_ver, int min_ver,
+ krb5_plugin_vtable vtable)
+{
+ kadm5_auth_vtable vt;
+
+ if (maj_ver != 1)
+ return KRB5_PLUGIN_VER_NOTSUPP;
+ vt = (kadm5_auth_vtable)vtable;
+ vt->name = "acl";
+ vt->init = acl_init;
+ vt->fini = acl_fini;
+ vt->addprinc = acl_addprinc;
+ vt->modprinc = acl_modprinc;
+ vt->setstr = acl_setstr;
+ vt->cpw = acl_cpw;
+ vt->chrand = acl_chrand;
+ vt->setkey = acl_setkey;
+ vt->purgekeys = acl_purgekeys;
+ vt->delprinc = acl_delprinc;
+ vt->renprinc = acl_renprinc;
+ vt->getprinc = acl_getprinc;
+ vt->getstrs = acl_getstrs;
+ vt->extract = acl_extract;
+ vt->listprincs = acl_listprincs;
+ vt->addpol = acl_addpol;
+ vt->modpol = acl_modpol;
+ vt->delpol = acl_delpol;
+ vt->getpol = acl_getpol;
+ vt->listpols = acl_listpols;
+ vt->iprop = acl_iprop;
+ return 0;
+}
diff --git a/src/kadmin/server/auth_self.c b/src/kadmin/server/auth_self.c
new file mode 100644
index 000000000000..253d4bc596ae
--- /dev/null
+++ b/src/kadmin/server/auth_self.c
@@ -0,0 +1,77 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/* kadmin/server/auth_self.c - self-service kadm5_auth module */
+/*
+ * Copyright (C) 2017 by the Massachusetts Institute of Technology.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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
+ * COPYRIGHT HOLDER 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 "k5-int.h"
+#include <kadm5/admin.h>
+#include <krb5/kadm5_auth_plugin.h>
+#include "auth.h"
+
+/* Authorize a principal to operate on itself. Applies to cpw, chrand,
+ * purgekeys, getprinc, and getstrs. */
+static krb5_error_code
+self_compare(krb5_context context, kadm5_auth_moddata data,
+ krb5_const_principal client, krb5_const_principal target)
+{
+ if (krb5_principal_compare(context, client, target))
+ return 0;
+ return KRB5_PLUGIN_NO_HANDLE;
+}
+
+/* Authorize a principal to get the policy record for its own policy. */
+static krb5_error_code
+self_getpol(krb5_context context, kadm5_auth_moddata data,
+ krb5_const_principal client, const char *policy,
+ const char *client_policy)
+{
+ if (client_policy != NULL && strcmp(policy, client_policy) == 0)
+ return 0;
+ return KRB5_PLUGIN_NO_HANDLE;
+}
+
+krb5_error_code
+kadm5_auth_self_initvt(krb5_context context, int maj_ver, int min_ver,
+ krb5_plugin_vtable vtable)
+{
+ kadm5_auth_vtable vt;
+
+ if (maj_ver != 1)
+ return KRB5_PLUGIN_VER_NOTSUPP;
+ vt = (kadm5_auth_vtable)vtable;
+ vt->name = "self";
+ vt->cpw = self_compare;
+ vt->chrand = self_compare;
+ vt->purgekeys = self_compare;
+ vt->getprinc = self_compare;
+ vt->getstrs = self_compare;
+ vt->getpol = self_getpol;
+ return 0;
+}
diff --git a/src/kadmin/server/deps b/src/kadmin/server/deps
index 44311af19af7..99aef7500e00 100644
--- a/src/kadmin/server/deps
+++ b/src/kadmin/server/deps
@@ -1,6 +1,44 @@
#
# Generated makefile dependencies follow.
#
+$(OUTPRE)auth_acl.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
+ $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssrpc/types.h \
+ $(BUILDTOP)/include/kadm5/admin.h $(BUILDTOP)/include/kadm5/chpass_util_strings.h \
+ $(BUILDTOP)/include/kadm5/kadm_err.h $(BUILDTOP)/include/krb5/krb5.h \
+ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \
+ $(COM_ERR_DEPS) $(top_srcdir)/include/adm_proto.h $(top_srcdir)/include/gssrpc/auth.h \
+ $(top_srcdir)/include/gssrpc/auth_gss.h $(top_srcdir)/include/gssrpc/auth_unix.h \
+ $(top_srcdir)/include/gssrpc/clnt.h $(top_srcdir)/include/gssrpc/rename.h \
+ $(top_srcdir)/include/gssrpc/rpc.h $(top_srcdir)/include/gssrpc/rpc_msg.h \
+ $(top_srcdir)/include/gssrpc/svc.h $(top_srcdir)/include/gssrpc/svc_auth.h \
+ $(top_srcdir)/include/gssrpc/xdr.h $(top_srcdir)/include/k5-buf.h \
+ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \
+ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \
+ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \
+ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \
+ $(top_srcdir)/include/kdb.h $(top_srcdir)/include/krb5.h \
+ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/kadm5_auth_plugin.h \
+ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \
+ $(top_srcdir)/include/socket-utils.h auth.h auth_acl.c
+$(OUTPRE)auth_self.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
+ $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssrpc/types.h \
+ $(BUILDTOP)/include/kadm5/admin.h $(BUILDTOP)/include/kadm5/chpass_util_strings.h \
+ $(BUILDTOP)/include/kadm5/kadm_err.h $(BUILDTOP)/include/krb5/krb5.h \
+ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \
+ $(COM_ERR_DEPS) $(top_srcdir)/include/gssrpc/auth.h \
+ $(top_srcdir)/include/gssrpc/auth_gss.h $(top_srcdir)/include/gssrpc/auth_unix.h \
+ $(top_srcdir)/include/gssrpc/clnt.h $(top_srcdir)/include/gssrpc/rename.h \
+ $(top_srcdir)/include/gssrpc/rpc.h $(top_srcdir)/include/gssrpc/rpc_msg.h \
+ $(top_srcdir)/include/gssrpc/svc.h $(top_srcdir)/include/gssrpc/svc_auth.h \
+ $(top_srcdir)/include/gssrpc/xdr.h $(top_srcdir)/include/k5-buf.h \
+ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \
+ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \
+ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \
+ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \
+ $(top_srcdir)/include/kdb.h $(top_srcdir)/include/krb5.h \
+ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/kadm5_auth_plugin.h \
+ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \
+ $(top_srcdir)/include/socket-utils.h auth.h auth_self.c
$(OUTPRE)kadm_rpc_svc.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
$(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssapi/gssapi_ext.h \
$(BUILDTOP)/include/gssapi/gssapi_krb5.h $(BUILDTOP)/include/gssrpc/types.h \
@@ -29,28 +67,27 @@ $(OUTPRE)server_stubs.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
$(BUILDTOP)/include/gssapi/gssapi_krb5.h $(BUILDTOP)/include/gssrpc/types.h \
$(BUILDTOP)/include/kadm5/admin.h $(BUILDTOP)/include/kadm5/admin_internal.h \
$(BUILDTOP)/include/kadm5/chpass_util_strings.h $(BUILDTOP)/include/kadm5/kadm_err.h \
- $(BUILDTOP)/include/kadm5/kadm_rpc.h $(BUILDTOP)/include/kadm5/server_acl.h \
- $(BUILDTOP)/include/kadm5/server_internal.h $(BUILDTOP)/include/krb5/krb5.h \
- $(COM_ERR_DEPS) $(VERTO_DEPS) $(top_srcdir)/include/adm_proto.h \
- $(top_srcdir)/include/gssrpc/auth.h $(top_srcdir)/include/gssrpc/auth_gss.h \
- $(top_srcdir)/include/gssrpc/auth_unix.h $(top_srcdir)/include/gssrpc/clnt.h \
- $(top_srcdir)/include/gssrpc/rename.h $(top_srcdir)/include/gssrpc/rpc.h \
- $(top_srcdir)/include/gssrpc/rpc_msg.h $(top_srcdir)/include/gssrpc/svc.h \
- $(top_srcdir)/include/gssrpc/svc_auth.h $(top_srcdir)/include/gssrpc/xdr.h \
- $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-thread.h \
- $(top_srcdir)/include/kdb.h $(top_srcdir)/include/krb5.h \
- $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/net-server.h \
- $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \
- misc.h server_stubs.c
+ $(BUILDTOP)/include/kadm5/kadm_rpc.h $(BUILDTOP)/include/kadm5/server_internal.h \
+ $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(VERTO_DEPS) \
+ $(top_srcdir)/include/adm_proto.h $(top_srcdir)/include/gssrpc/auth.h \
+ $(top_srcdir)/include/gssrpc/auth_gss.h $(top_srcdir)/include/gssrpc/auth_unix.h \
+ $(top_srcdir)/include/gssrpc/clnt.h $(top_srcdir)/include/gssrpc/rename.h \
+ $(top_srcdir)/include/gssrpc/rpc.h $(top_srcdir)/include/gssrpc/rpc_msg.h \
+ $(top_srcdir)/include/gssrpc/svc.h $(top_srcdir)/include/gssrpc/svc_auth.h \
+ $(top_srcdir)/include/gssrpc/xdr.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/kdb.h \
+ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/plugin.h \
+ $(top_srcdir)/include/net-server.h $(top_srcdir)/include/port-sockets.h \
+ $(top_srcdir)/include/socket-utils.h auth.h misc.h \
+ server_stubs.c
$(OUTPRE)ovsec_kadmd.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
$(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssapi/gssapi_alloc.h \
$(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/gssrpc/types.h \
$(BUILDTOP)/include/kadm5/admin.h $(BUILDTOP)/include/kadm5/admin_internal.h \
$(BUILDTOP)/include/kadm5/chpass_util_strings.h $(BUILDTOP)/include/kadm5/kadm_err.h \
- $(BUILDTOP)/include/kadm5/kadm_rpc.h $(BUILDTOP)/include/kadm5/server_acl.h \
- $(BUILDTOP)/include/kadm5/server_internal.h $(BUILDTOP)/include/krb5/krb5.h \
- $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \
- $(BUILDTOP)/lib/gssapi/generic/gssapi_err_generic.h \
+ $(BUILDTOP)/include/kadm5/kadm_rpc.h $(BUILDTOP)/include/kadm5/server_internal.h \
+ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
+ $(BUILDTOP)/include/profile.h $(BUILDTOP)/lib/gssapi/generic/gssapi_err_generic.h \
$(BUILDTOP)/lib/gssapi/krb5/gssapi_err_krb5.h $(COM_ERR_DEPS) \
$(VERTO_DEPS) $(top_srcdir)/include/adm_proto.h $(top_srcdir)/include/gssrpc/auth.h \
$(top_srcdir)/include/gssrpc/auth_gss.h $(top_srcdir)/include/gssrpc/auth_gssapi.h \
@@ -71,7 +108,7 @@ $(OUTPRE)ovsec_kadmd.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
$(top_srcdir)/lib/gssapi/generic/gssapiP_generic.h \
$(top_srcdir)/lib/gssapi/generic/gssapi_ext.h $(top_srcdir)/lib/gssapi/generic/gssapi_generic.h \
$(top_srcdir)/lib/gssapi/krb5/gssapiP_krb5.h $(top_srcdir)/lib/gssapi/krb5/gssapi_krb5.h \
- misc.h ovsec_kadmd.c
+ auth.h misc.h ovsec_kadmd.c
$(OUTPRE)schpw.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
$(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssrpc/types.h \
$(BUILDTOP)/include/kadm5/admin.h $(BUILDTOP)/include/kadm5/admin_internal.h \
@@ -97,23 +134,23 @@ $(OUTPRE)misc.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
$(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssrpc/types.h \
$(BUILDTOP)/include/kadm5/admin.h $(BUILDTOP)/include/kadm5/admin_internal.h \
$(BUILDTOP)/include/kadm5/chpass_util_strings.h $(BUILDTOP)/include/kadm5/kadm_err.h \
- $(BUILDTOP)/include/kadm5/server_acl.h $(BUILDTOP)/include/kadm5/server_internal.h \
- $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
- $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(VERTO_DEPS) \
- $(top_srcdir)/include/gssrpc/auth.h $(top_srcdir)/include/gssrpc/auth_gss.h \
- $(top_srcdir)/include/gssrpc/auth_unix.h $(top_srcdir)/include/gssrpc/clnt.h \
- $(top_srcdir)/include/gssrpc/rename.h $(top_srcdir)/include/gssrpc/rpc.h \
- $(top_srcdir)/include/gssrpc/rpc_msg.h $(top_srcdir)/include/gssrpc/svc.h \
- $(top_srcdir)/include/gssrpc/svc_auth.h $(top_srcdir)/include/gssrpc/xdr.h \
- $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \
- $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \
- $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \
- $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \
- $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/kdb.h \
- $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \
- $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/net-server.h \
- $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \
- misc.c misc.h
+ $(BUILDTOP)/include/kadm5/server_internal.h $(BUILDTOP)/include/krb5/krb5.h \
+ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \
+ $(COM_ERR_DEPS) $(VERTO_DEPS) $(top_srcdir)/include/gssrpc/auth.h \
+ $(top_srcdir)/include/gssrpc/auth_gss.h $(top_srcdir)/include/gssrpc/auth_unix.h \
+ $(top_srcdir)/include/gssrpc/clnt.h $(top_srcdir)/include/gssrpc/rename.h \
+ $(top_srcdir)/include/gssrpc/rpc.h $(top_srcdir)/include/gssrpc/rpc_msg.h \
+ $(top_srcdir)/include/gssrpc/svc.h $(top_srcdir)/include/gssrpc/svc_auth.h \
+ $(top_srcdir)/include/gssrpc/xdr.h $(top_srcdir)/include/k5-buf.h \
+ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \
+ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \
+ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \
+ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \
+ $(top_srcdir)/include/kdb.h $(top_srcdir)/include/krb5.h \
+ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \
+ $(top_srcdir)/include/net-server.h $(top_srcdir)/include/port-sockets.h \
+ $(top_srcdir)/include/socket-utils.h auth.h misc.c \
+ misc.h
$(OUTPRE)ipropd_svc.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
$(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssapi/gssapi_ext.h \
$(BUILDTOP)/include/gssrpc/types.h $(BUILDTOP)/include/kadm5/admin.h \
@@ -131,5 +168,5 @@ $(OUTPRE)ipropd_svc.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
$(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/kdb.h \
$(top_srcdir)/include/kdb_log.h $(top_srcdir)/include/krb5.h \
$(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/net-server.h \
- $(top_srcdir)/lib/gssapi/krb5/gssapi_krb5.h $(top_srcdir)/lib/kadm5/srv/server_acl.h \
+ $(top_srcdir)/lib/gssapi/krb5/gssapi_krb5.h auth.h \
ipropd_svc.c misc.h
diff --git a/src/kadmin/server/ipropd_svc.c b/src/kadmin/server/ipropd_svc.c
index bce668f4221a..e6e190136f88 100644
--- a/src/kadmin/server/ipropd_svc.c
+++ b/src/kadmin/server/ipropd_svc.c
@@ -16,7 +16,6 @@
#include <kadm5/admin.h>
#include <kadm5/kadm_rpc.h>
#include <kadm5/server_internal.h>
-#include <server_acl.h>
#include <adm_proto.h>
#include <string.h>
#include <gssapi_krb5.h>
@@ -25,6 +24,7 @@
#include <arpa/inet.h>
#include <netdb.h>
#include <kdb_log.h>
+#include "auth.h"
#include "misc.h"
#include "osconf.h"
@@ -129,6 +129,20 @@ buf_to_string(gss_buffer_desc *b)
return s;
}
+static krb5_boolean
+iprop_acl_check(krb5_context context, const char *client_name)
+{
+ krb5_principal client_princ;
+ krb5_boolean result;
+
+ if (krb5_parse_name(context, client_name, &client_princ) != 0)
+ return FALSE;
+ result = auth(context, OP_IPROP, client_princ,
+ NULL, NULL, NULL, NULL, NULL, 0);
+ krb5_free_principal(context, client_princ);
+ return result;
+}
+
kdb_incr_result_t *
iprop_get_updates_1_svc(kdb_last_t *arg, struct svc_req *rqstp)
{
@@ -174,11 +188,7 @@ iprop_get_updates_1_svc(kdb_last_t *arg, struct svc_req *rqstp)
DPRINT("%s: clprinc=`%s'\n\tsvcprinc=`%s'\n", whoami, client_name,
service_name);
- if (!kadm5int_acl_check(handle->context,
- rqst2name(rqstp),
- ACL_IPROP,
- NULL,
- NULL)) {
+ if (!iprop_acl_check(handle->context, client_name)) {
ret.ret = UPDATE_PERM_DENIED;
DPRINT("%s: PERMISSION DENIED: clprinc=`%s'\n\tsvcprinc=`%s'\n",
@@ -301,11 +311,7 @@ ipropx_resync(uint32_t vers, struct svc_req *rqstp)
DPRINT("%s: clprinc=`%s'\n\tsvcprinc=`%s'\n",
whoami, client_name, service_name);
- if (!kadm5int_acl_check(handle->context,
- rqst2name(rqstp),
- ACL_IPROP,
- NULL,
- NULL)) {
+ if (!iprop_acl_check(handle->context, client_name)) {
ret.ret = UPDATE_PERM_DENIED;
DPRINT("%s: Permission denied\n", whoami);
@@ -532,9 +538,9 @@ krb5_iprop_prog_1(struct svc_req *rqstp,
union {
kdb_last_t iprop_get_updates_1_arg;
} argument;
- char *result;
+ void *result;
bool_t (*_xdr_argument)(), (*_xdr_result)();
- char *(*local)(/* union XXX *, struct svc_req * */);
+ void *(*local)(/* union XXX *, struct svc_req * */);
char *whoami = "krb5_iprop_prog_1";
if (!check_iprop_rpcsec_auth(rqstp)) {
@@ -555,19 +561,19 @@ krb5_iprop_prog_1(struct svc_req *rqstp,
case IPROP_GET_UPDATES:
_xdr_argument = xdr_kdb_last_t;
_xdr_result = xdr_kdb_incr_result_t;
- local = (char *(*)()) iprop_get_updates_1_svc;
+ local = (void *(*)()) iprop_get_updates_1_svc;
break;
case IPROP_FULL_RESYNC:
_xdr_argument = xdr_void;
_xdr_result = xdr_kdb_fullresync_result_t;
- local = (char *(*)()) iprop_full_resync_1_svc;
+ local = (void *(*)()) iprop_full_resync_1_svc;
break;
case IPROP_FULL_RESYNC_EXT:
_xdr_argument = xdr_u_int32;
_xdr_result = xdr_kdb_fullresync_result_t;
- local = (char *(*)()) iprop_full_resync_ext_1_svc;
+ local = (void *(*)()) iprop_full_resync_ext_1_svc;
break;
default:
diff --git a/src/kadmin/server/misc.c b/src/kadmin/server/misc.c
index 27a6376af6b1..6b258a6a056e 100644
--- a/src/kadmin/server/misc.c
+++ b/src/kadmin/server/misc.c
@@ -7,96 +7,9 @@
#include <k5-int.h>
#include <kdb.h>
#include <kadm5/server_internal.h>
-#include <kadm5/server_acl.h>
#include "misc.h"
+#include "auth.h"
#include "net-server.h"
-
-/*
- * Function: chpass_principal_wrapper_3
- *
- * Purpose: wrapper to kadm5_chpass_principal that checks to see if
- * pw_min_life has been reached. if not it returns an error.
- * otherwise it calls kadm5_chpass_principal
- *
- * Arguments:
- * principal (input) krb5_principals whose password we are
- * changing
- * keepold (input) whether to preserve old keys
- * n_ks_tuple (input) the number of key-salt tuples in ks_tuple
- * ks_tuple (input) array of tuples indicating the caller's
- * requested enctypes/salttypes
- * password (input) password we are going to change to.
- * <return value> 0 on success error code on failure.
- *
- * Requires:
- * kadm5_init to have been run.
- *
- * Effects:
- * calls kadm5_chpass_principal which changes the kdb and the
- * the admin db.
- *
- */
-kadm5_ret_t
-chpass_principal_wrapper_3(void *server_handle,
- krb5_principal principal,
- krb5_boolean keepold,
- int n_ks_tuple,
- krb5_key_salt_tuple *ks_tuple,
- char *password)
-{
- kadm5_ret_t ret;
-
- ret = check_min_life(server_handle, principal, NULL, 0);
- if (ret)
- return ret;
-
- return kadm5_chpass_principal_3(server_handle, principal,
- keepold, n_ks_tuple, ks_tuple,
- password);
-}
-
-
-/*
- * Function: randkey_principal_wrapper_3
- *
- * Purpose: wrapper to kadm5_randkey_principal which checks the
- * password's min. life.
- *
- * Arguments:
- * principal (input) krb5_principal whose password we are
- * changing
- * keepold (input) whether to preserve old keys
- * n_ks_tuple (input) the number of key-salt tuples in ks_tuple
- * ks_tuple (input) array of tuples indicating the caller's
- * requested enctypes/salttypes
- * key (output) new random key
- * <return value> 0, error code on error.
- *
- * Requires:
- * kadm5_init needs to be run
- *
- * Effects:
- * calls kadm5_randkey_principal
- *
- */
-kadm5_ret_t
-randkey_principal_wrapper_3(void *server_handle,
- krb5_principal principal,
- krb5_boolean keepold,
- int n_ks_tuple,
- krb5_key_salt_tuple *ks_tuple,
- krb5_keyblock **keys, int *n_keys)
-{
- kadm5_ret_t ret;
-
- ret = check_min_life(server_handle, principal, NULL, 0);
- if (ret)
- return ret;
- return kadm5_randkey_principal_3(server_handle, principal,
- keepold, n_ks_tuple, ks_tuple,
- keys, n_keys);
-}
-
kadm5_ret_t
schpw_util_wrapper(void *server_handle,
krb5_principal client,
@@ -107,8 +20,6 @@ schpw_util_wrapper(void *server_handle,
{
kadm5_ret_t ret;
kadm5_server_handle_t handle = server_handle;
- krb5_boolean access_granted;
- krb5_boolean self;
/*
* If no target is explicitly provided, then the target principal
@@ -117,32 +28,22 @@ schpw_util_wrapper(void *server_handle,
if (target == NULL)
target = client;
- /*
- * A principal can always change its own password, as long as it
- * has an initial ticket and meets the minimum password lifetime
- * requirement.
- */
- self = krb5_principal_compare(handle->context, client, target);
- if (self) {
+ /* If the client is changing its own password, require it to use an initial
+ * ticket, and enforce the policy min_life. */
+ if (krb5_principal_compare(handle->context, client, target)) {
+ if (!initial_flag) {
+ strlcpy(msg_ret, "Ticket must be derived from a password",
+ msg_len);
+ return KADM5_AUTH_INITIAL;
+ }
+
ret = check_min_life(server_handle, target, msg_ret, msg_len);
if (ret != 0)
return ret;
-
- access_granted = initial_flag;
- } else
- access_granted = FALSE;
-
- if (!access_granted &&
- kadm5int_acl_check_krb(handle->context, client,
- ACL_CHANGEPW, target, NULL)) {
- /*
- * Otherwise, principals with appropriate privileges can change
- * any password
- */
- access_granted = TRUE;
}
- if (access_granted) {
+ if (auth(handle->context, OP_CPW, client, target,
+ NULL, NULL, NULL, NULL, 0)) {
ret = kadm5_chpass_principal_util(server_handle,
target,
new_pw, ret_pw,
@@ -159,7 +60,7 @@ kadm5_ret_t
check_min_life(void *server_handle, krb5_principal principal,
char *msg_ret, unsigned int msg_len)
{
- krb5_int32 now;
+ krb5_timestamp now;
kadm5_ret_t ret;
kadm5_policy_ent_rec pol;
kadm5_principal_ent_rec princ;
@@ -184,7 +85,7 @@ check_min_life(void *server_handle, krb5_principal principal,
(void) kadm5_free_principal_ent(handle->lhandle, &princ);
return (ret == KADM5_UNK_POLICY) ? 0 : ret;
}
- if((now - princ.last_pwd_change) < pol.pw_min_life &&
+ if(ts_delta(now, princ.last_pwd_change) < pol.pw_min_life &&
!(princ.attributes & KRB5_KDB_REQUIRES_PWCHANGE)) {
if (msg_ret != NULL) {
time_t until;
diff --git a/src/kadmin/server/misc.h b/src/kadmin/server/misc.h
index ea0fc7d2217a..3a112a0b7b2e 100644
--- a/src/kadmin/server/misc.h
+++ b/src/kadmin/server/misc.h
@@ -13,23 +13,6 @@ int
setup_gss_names(struct svc_req *, gss_buffer_desc *,
gss_buffer_desc *);
-
-kadm5_ret_t
-chpass_principal_wrapper_3(void *server_handle,
- krb5_principal principal,
- krb5_boolean keepold,
- int n_ks_tuple,
- krb5_key_salt_tuple *ks_tuple,
- char *password);
-
-kadm5_ret_t
-randkey_principal_wrapper_3(void *server_handle,
- krb5_principal principal,
- krb5_boolean keepold,
- int n_ks_tuple,
- krb5_key_salt_tuple *ks_tuple,
- krb5_keyblock **keys, int *n_keys);
-
kadm5_ret_t
schpw_util_wrapper(void *server_handle, krb5_principal client,
krb5_principal target, krb5_boolean initial_flag,
diff --git a/src/kadmin/server/ovsec_kadmd.c b/src/kadmin/server/ovsec_kadmd.c
index a3edd3b00169..6c875901a976 100644
--- a/src/kadmin/server/ovsec_kadmd.c
+++ b/src/kadmin/server/ovsec_kadmd.c
@@ -51,7 +51,6 @@
#include <gssrpc/auth_gssapi.h>
#include <kadm5/admin.h>
#include <kadm5/kadm_rpc.h>
-#include <kadm5/server_acl.h>
#include <adm_proto.h>
#include "kdb_kt.h" /* for krb5_ktkdb_set_context */
#include <string.h>
@@ -59,6 +58,7 @@
#include <kdb_log.h>
#include "misc.h"
+#include "auth.h"
#if defined(NEED_DAEMON_PROTO)
int daemon(int, int);
@@ -356,6 +356,7 @@ main(int argc, char *argv[])
verto_ctx *vctx;
const char *pid_file = NULL;
char **db_args = NULL, **tmpargs;
+ const char *acl_file;
int ret, i, db_args_size = 0, strong_random = 1, proponly = 0;
setlocale(LC_ALL, "");
@@ -505,7 +506,8 @@ main(int argc, char *argv[])
if (svcauth_gss_set_svc_name(GSS_C_NO_NAME) != TRUE)
fail_to_start(0, _("Cannot initialize GSSAPI service name"));
- ret = kadm5int_acl_init(context, 0, params.acl_file);
+ acl_file = (*params.acl_file != '\0') ? params.acl_file : NULL;
+ ret = auth_init(context, acl_file);
if (ret)
fail_to_start(ret, _("initializing ACL file"));
@@ -550,7 +552,7 @@ main(int argc, char *argv[])
svcauth_gssapi_unset_names();
kadm5_destroy(global_server_handle);
loop_free(vctx);
- kadm5int_acl_finish(context, 0);
+ auth_fini(context);
(void)gss_release_name(&minor_status, &gss_changepw_name);
(void)gss_release_name(&minor_status, &gss_oldchangepw_name);
for (i = 0; i < 4; i++)
diff --git a/src/kadmin/server/schpw.c b/src/kadmin/server/schpw.c
index 900adf7a0997..491cba91aa1a 100644
--- a/src/kadmin/server/schpw.c
+++ b/src/kadmin/server/schpw.c
@@ -18,8 +18,8 @@
static krb5_error_code
process_chpw_request(krb5_context context, void *server_handle, char *realm,
- krb5_keytab keytab, const krb5_fulladdr *local_faddr,
- const krb5_fulladdr *remote_faddr, krb5_data *req,
+ krb5_keytab keytab, const krb5_fulladdr *local_addr,
+ const krb5_fulladdr *remote_addr, krb5_data *req,
krb5_data *rep)
{
krb5_error_code ret;
@@ -42,7 +42,7 @@ process_chpw_request(krb5_context context, void *server_handle, char *realm,
struct sockaddr_storage ss;
socklen_t salen;
char addrbuf[100];
- krb5_address *addr = remote_faddr->address;
+ krb5_address *addr = remote_addr->address;
*rep = empty_data();
@@ -205,15 +205,6 @@ process_chpw_request(krb5_context context, void *server_handle, char *realm,
goto chpwfail;
}
- /* for cpw, verify that this is an AS_REQ ticket */
- if (vno == 1 &&
- (ticket->enc_part2->flags & TKT_FLG_INITIAL) == 0) {
- numresult = KRB5_KPASSWD_INITIAL_FLAG_NEEDED;
- strlcpy(strresult, "Ticket must be derived from a password",
- sizeof(strresult));
- goto chpwfail;
- }
-
/* change the password */
ptr = k5memdup0(clear.data, clear.length, &ret);
@@ -237,7 +228,7 @@ process_chpw_request(krb5_context context, void *server_handle, char *realm,
sin->sin_family = AF_INET;
memcpy(&sin->sin_addr, addr->contents, addr->length);
- sin->sin_port = htons(remote_faddr->port);
+ sin->sin_port = htons(remote_addr->port);
salen = sizeof(*sin);
break;
}
@@ -246,7 +237,7 @@ process_chpw_request(krb5_context context, void *server_handle, char *realm,
sin6->sin6_family = AF_INET6;
memcpy(&sin6->sin6_addr, addr->contents, addr->length);
- sin6->sin6_port = htons(remote_faddr->port);
+ sin6->sin6_port = htons(remote_addr->port);
salen = sizeof(*sin6);
break;
}
@@ -292,6 +283,9 @@ process_chpw_request(krb5_context context, void *server_handle, char *realm,
case KADM5_AUTH_CHANGEPW:
numresult = KRB5_KPASSWD_ACCESSDENIED;
break;
+ case KADM5_AUTH_INITIAL:
+ numresult = KRB5_KPASSWD_INITIAL_FLAG_NEEDED;
+ break;
case KADM5_PASS_Q_TOOSHORT:
case KADM5_PASS_REUSE:
case KADM5_PASS_Q_CLASS:
@@ -326,7 +320,7 @@ chpwfail:
if (ap_rep.length) {
ret = krb5_auth_con_setaddrs(context, auth_context,
- local_faddr->address, NULL);
+ local_addr->address, NULL);
if (ret) {
numresult = KRB5_KPASSWD_HARDERROR;
strlcpy(strresult,
@@ -366,7 +360,7 @@ chpwfail:
to mk_error do. */
krberror.error = ret;
krberror.error -= ERROR_TABLE_BASE_krb5;
- if (krberror.error < 0 || krberror.error > KRB_ERR_MAX)
+ if (krberror.error > KRB_ERR_MAX)
krberror.error = KRB_ERR_GENERIC;
krberror.client = NULL;
@@ -436,29 +430,15 @@ bailout:
/* Dispatch routine for set/change password */
void
-dispatch(void *handle, struct sockaddr *local_saddr,
- const krb5_fulladdr *remote_faddr, krb5_data *request, int is_tcp,
+dispatch(void *handle, const krb5_fulladdr *local_addr,
+ const krb5_fulladdr *remote_addr, krb5_data *request, int is_tcp,
verto_ctx *vctx, loop_respond_fn respond, void *arg)
{
krb5_error_code ret;
krb5_keytab kt = NULL;
kadm5_server_handle_t server_handle = (kadm5_server_handle_t)handle;
- krb5_fulladdr local_faddr;
- krb5_address **local_kaddrs = NULL, local_kaddr_buf;
krb5_data *response = NULL;
- if (local_saddr == NULL) {
- ret = krb5_os_localaddr(server_handle->context, &local_kaddrs);
- if (ret != 0)
- goto egress;
-
- local_faddr.address = local_kaddrs[0];
- local_faddr.port = 0;
- } else {
- local_faddr.address = &local_kaddr_buf;
- init_addr(&local_faddr, local_saddr);
- }
-
ret = krb5_kt_resolve(server_handle->context, "KDB:", &kt);
if (ret != 0) {
krb5_klog_syslog(LOG_ERR, _("chpw: Couldn't open admin keytab %s"),
@@ -474,14 +454,13 @@ dispatch(void *handle, struct sockaddr *local_saddr,
handle,
server_handle->params.realm,
kt,
- &local_faddr,
- remote_faddr,
+ local_addr,
+ remote_addr,
request,
response);
egress:
if (ret)
krb5_free_data(server_handle->context, response);
- krb5_free_addresses(server_handle->context, local_kaddrs);
krb5_kt_close(server_handle->context, kt);
(*respond)(arg, ret, ret == 0 ? response : NULL);
}
diff --git a/src/kadmin/server/server_stubs.c b/src/kadmin/server/server_stubs.c
index 86c162590e4b..cfef97fec147 100644
--- a/src/kadmin/server/server_stubs.c
+++ b/src/kadmin/server/server_stubs.c
@@ -12,10 +12,10 @@
#include <kadm5/admin.h>
#include <kadm5/kadm_rpc.h>
#include <kadm5/server_internal.h>
-#include <kadm5/server_acl.h>
#include <syslog.h>
#include <adm_proto.h> /* krb5_klog_syslog */
#include "misc.h"
+#include "auth.h"
extern gss_name_t gss_changepw_name;
extern gss_name_t gss_oldchangepw_name;
@@ -216,19 +216,6 @@ static gss_name_t acceptor_name(gss_ctx_id_t context)
return name;
}
-static int cmp_gss_krb5_name(kadm5_server_handle_t handle,
- gss_name_t gss_name, krb5_principal princ)
-{
- krb5_principal princ2;
- int status;
-
- if (! gss_to_krb5_name(handle, gss_name, &princ2))
- return 0;
- status = krb5_principal_compare(handle->context, princ, princ2);
- krb5_free_principal(handle->context, princ2);
- return status;
-}
-
static int gss_to_krb5_name(kadm5_server_handle_t handle,
gss_name_t gss_name, krb5_principal *princ)
{
@@ -314,12 +301,76 @@ stub_cleanup(kadm5_server_handle_t handle, char *princ_str,
{
OM_uint32 minor_stat;
+ auth_end(handle->context);
free_server_handle(handle);
free(princ_str);
gss_release_buffer(&minor_stat, client_name);
gss_release_buffer(&minor_stat, service_name);
}
+static krb5_boolean
+stub_auth(kadm5_server_handle_t handle, int opcode, krb5_const_principal p1,
+ krb5_const_principal p2, const char *s1, const char *s2)
+{
+ return auth(handle->context, opcode, handle->current_caller, p1, p2,
+ s1, s2, NULL, 0);
+}
+
+static krb5_boolean
+stub_auth_pol(kadm5_server_handle_t handle, int opcode, const char *policy,
+ const kadm5_policy_ent_rec *polent, long mask)
+{
+ return auth(handle->context, opcode, handle->current_caller, NULL, NULL,
+ policy, NULL, polent, mask);
+}
+
+static krb5_boolean
+stub_auth_restrict(kadm5_server_handle_t handle, int opcode,
+ kadm5_principal_ent_t ent, long *mask)
+{
+ return auth_restrict(handle->context, opcode, handle->current_caller,
+ ent, mask);
+}
+
+/* Return true if the client authenticated to kadmin/changepw and princ is not
+ * the client principal. */
+static krb5_boolean
+changepw_not_self(kadm5_server_handle_t handle, struct svc_req *rqstp,
+ krb5_const_principal princ)
+{
+ return CHANGEPW_SERVICE(rqstp) &&
+ !krb5_principal_compare(handle->context, handle->current_caller,
+ princ);
+}
+
+static krb5_boolean
+ticket_is_initial(struct svc_req *rqstp)
+{
+ OM_uint32 status, minor_stat;
+ krb5_flags flags;
+
+ status = gss_krb5_get_tkt_flags(&minor_stat, rqstp->rq_svccred, &flags);
+ if (status != GSS_S_COMPLETE)
+ return 0;
+ return (flags & TKT_FLG_INITIAL) != 0;
+}
+
+/* If a key change request is for the client's own principal, verify that the
+ * client used an initial ticket and enforce the policy min_life. */
+static kadm5_ret_t
+check_self_keychange(kadm5_server_handle_t handle, struct svc_req *rqstp,
+ krb5_principal princ)
+{
+ if (!krb5_principal_compare(handle->context, handle->current_caller,
+ princ))
+ return 0;
+
+ if (!ticket_is_initial(rqstp))
+ return KADM5_AUTH_INITIAL;
+
+ return check_min_life(handle, princ, NULL, 0);
+}
+
static int
log_unauth(
char *op,
@@ -387,7 +438,6 @@ create_principal_2_svc(cprinc_arg *arg, generic_ret *ret,
gss_buffer_desc client_name = GSS_C_EMPTY_BUFFER;
gss_buffer_desc service_name = GSS_C_EMPTY_BUFFER;
kadm5_server_handle_t handle;
- restriction_t *rp;
const char *errmsg = NULL;
ret->code = stub_setup(arg->api_version, rqstp, arg->rec.principal,
@@ -396,11 +446,8 @@ create_principal_2_svc(cprinc_arg *arg, generic_ret *ret,
if (ret->code)
goto exit_func;
- if (CHANGEPW_SERVICE(rqstp)
- || !kadm5int_acl_check(handle->context, rqst2name(rqstp), ACL_ADD,
- arg->rec.principal, &rp)
- || kadm5int_acl_impose_restrictions(handle->context,
- &arg->rec, &arg->mask, rp)) {
+ if (CHANGEPW_SERVICE(rqstp) ||
+ !stub_auth_restrict(handle, OP_ADDPRINC, &arg->rec, &arg->mask)) {
ret->code = KADM5_AUTH_ADD;
log_unauth("kadm5_create_principal", prime_arg,
&client_name, &service_name, rqstp);
@@ -431,7 +478,6 @@ create_principal3_2_svc(cprinc3_arg *arg, generic_ret *ret,
gss_buffer_desc client_name = GSS_C_EMPTY_BUFFER;
gss_buffer_desc service_name = GSS_C_EMPTY_BUFFER;
kadm5_server_handle_t handle;
- restriction_t *rp;
const char *errmsg = NULL;
ret->code = stub_setup(arg->api_version, rqstp, arg->rec.principal,
@@ -440,11 +486,8 @@ create_principal3_2_svc(cprinc3_arg *arg, generic_ret *ret,
if (ret->code)
goto exit_func;
- if (CHANGEPW_SERVICE(rqstp)
- || !kadm5int_acl_check(handle->context, rqst2name(rqstp), ACL_ADD,
- arg->rec.principal, &rp)
- || kadm5int_acl_impose_restrictions(handle->context,
- &arg->rec, &arg->mask, rp)) {
+ if (CHANGEPW_SERVICE(rqstp) ||
+ !stub_auth_restrict(handle, OP_ADDPRINC, &arg->rec, &arg->mask)) {
ret->code = KADM5_AUTH_ADD;
log_unauth("kadm5_create_principal", prime_arg,
&client_name, &service_name, rqstp);
@@ -498,9 +541,8 @@ delete_principal_2_svc(dprinc_arg *arg, generic_ret *ret,
if (ret->code)
goto exit_func;
- if (CHANGEPW_SERVICE(rqstp)
- || !kadm5int_acl_check(handle->context, rqst2name(rqstp), ACL_DELETE,
- arg->princ, NULL)) {
+ if (CHANGEPW_SERVICE(rqstp) ||
+ !stub_auth(handle, OP_DELPRINC, arg->princ, NULL, NULL, NULL)) {
ret->code = KADM5_AUTH_DELETE;
log_unauth("kadm5_delete_principal", prime_arg,
&client_name, &service_name, rqstp);
@@ -540,7 +582,6 @@ modify_principal_2_svc(mprinc_arg *arg, generic_ret *ret,
gss_buffer_desc client_name = GSS_C_EMPTY_BUFFER;
gss_buffer_desc service_name = GSS_C_EMPTY_BUFFER;
kadm5_server_handle_t handle;
- restriction_t *rp;
const char *errmsg = NULL;
ret->code = stub_setup(arg->api_version, rqstp, arg->rec.principal,
@@ -549,11 +590,8 @@ modify_principal_2_svc(mprinc_arg *arg, generic_ret *ret,
if (ret->code)
goto exit_func;
- if (CHANGEPW_SERVICE(rqstp)
- || !kadm5int_acl_check(handle->context, rqst2name(rqstp), ACL_MODIFY,
- arg->rec.principal, &rp)
- || kadm5int_acl_impose_restrictions(handle->context,
- &arg->rec, &arg->mask, rp)) {
+ if (CHANGEPW_SERVICE(rqstp) ||
+ !stub_auth_restrict(handle, OP_MODPRINC, &arg->rec, &arg->mask)) {
ret->code = KADM5_AUTH_MODIFY;
log_unauth("kadm5_modify_principal", prime_arg,
&client_name, &service_name, rqstp);
@@ -592,7 +630,6 @@ rename_principal_2_svc(rprinc_arg *arg, generic_ret *ret,
gss_buffer_desc client_name = GSS_C_EMPTY_BUFFER;
gss_buffer_desc service_name = GSS_C_EMPTY_BUFFER;
kadm5_server_handle_t handle;
- restriction_t *rp;
const char *errmsg = NULL;
size_t tlen1, tlen2, clen, slen;
char *tdots1, *tdots2, *cdots, *sdots;
@@ -617,29 +654,19 @@ rename_principal_2_svc(rprinc_arg *arg, generic_ret *ret,
slen = service_name.length;
trunc_name(&slen, &sdots);
- ret->code = KADM5_OK;
- if (! CHANGEPW_SERVICE(rqstp)) {
- if (!kadm5int_acl_check(handle->context, rqst2name(rqstp),
- ACL_DELETE, arg->src, NULL))
+ if (CHANGEPW_SERVICE(rqstp) ||
+ !stub_auth(handle, OP_RENPRINC, arg->src, arg->dest, NULL, NULL)) {
+ ret->code = KADM5_AUTH_INSUFFICIENT;
+ log_unauth("kadm5_rename_principal", prime_arg1, &client_name,
+ &service_name, rqstp);
+ } else {
+ ret->code = check_lockdown_keys(handle, arg->src);
+ if (ret->code == KADM5_PROTECT_KEYS) {
+ log_unauth("kadm5_rename_principal", prime_arg1, &client_name,
+ &service_name, rqstp);
ret->code = KADM5_AUTH_DELETE;
- /* any restrictions at all on the ADD kills the RENAME */
- if (!kadm5int_acl_check(handle->context, rqst2name(rqstp),
- ACL_ADD, arg->dest, &rp) || rp) {
- if (ret->code == KADM5_AUTH_DELETE)
- ret->code = KADM5_AUTH_INSUFFICIENT;
- else
- ret->code = KADM5_AUTH_ADD;
- }
- if (ret->code == KADM5_OK) {
- ret->code = check_lockdown_keys(handle, arg->src);
- if (ret->code == KADM5_PROTECT_KEYS) {
- log_unauth("kadm5_rename_principal", prime_arg1, &client_name,
- &service_name, rqstp);
- ret->code = KADM5_AUTH_DELETE;
- }
}
- } else
- ret->code = KADM5_AUTH_INSUFFICIENT;
+ }
if (ret->code != KADM5_OK) {
/* okay to cast lengths to int because trunc_name limits max value */
krb5_klog_syslog(LOG_NOTICE,
@@ -696,12 +723,8 @@ get_principal_2_svc(gprinc_arg *arg, gprinc_ret *ret, struct svc_req *rqstp)
funcname = "kadm5_get_principal";
- if (! cmp_gss_krb5_name(handle, rqst2name(rqstp), arg->princ) &&
- (CHANGEPW_SERVICE(rqstp) || !kadm5int_acl_check(handle->context,
- rqst2name(rqstp),
- ACL_INQUIRE,
- arg->princ,
- NULL))) {
+ if (changepw_not_self(handle, rqstp, arg->princ) ||
+ !stub_auth(handle, OP_GETPRINC, arg->princ, NULL, NULL, NULL)) {
ret->code = KADM5_AUTH_GET;
log_unauth(funcname, prime_arg,
&client_name, &service_name, rqstp);
@@ -743,11 +766,8 @@ get_princs_2_svc(gprincs_arg *arg, gprincs_ret *ret, struct svc_req *rqstp)
if (prime_arg == NULL)
prime_arg = "*";
- if (CHANGEPW_SERVICE(rqstp) || !kadm5int_acl_check(handle->context,
- rqst2name(rqstp),
- ACL_LIST,
- NULL,
- NULL)) {
+ if (CHANGEPW_SERVICE(rqstp) ||
+ !stub_auth(handle, OP_LISTPRINCS, NULL, NULL, NULL, NULL)) {
ret->code = KADM5_AUTH_LIST;
log_unauth("kadm5_get_principals", prime_arg,
&client_name, &service_name, rqstp);
@@ -793,17 +813,15 @@ chpass_principal_2_svc(chpass_arg *arg, generic_ret *ret,
&service_name, rqstp);
ret->code = KADM5_AUTH_CHANGEPW;
}
- } else if (cmp_gss_krb5_name(handle, rqst2name(rqstp), arg->princ)) {
- ret->code = chpass_principal_wrapper_3(handle, arg->princ, FALSE, 0,
- NULL, arg->pass);
- } else if (!(CHANGEPW_SERVICE(rqstp)) &&
- kadm5int_acl_check(handle->context, rqst2name(rqstp),
- ACL_CHANGEPW, arg->princ, NULL)) {
- ret->code = kadm5_chpass_principal(handle, arg->princ, arg->pass);
- } else {
+ } else if (changepw_not_self(handle, rqstp, arg->princ) ||
+ !stub_auth(handle, OP_CPW, arg->princ, NULL, NULL, NULL)) {
+ ret->code = KADM5_AUTH_CHANGEPW;
log_unauth("kadm5_chpass_principal", prime_arg,
&client_name, &service_name, rqstp);
- ret->code = KADM5_AUTH_CHANGEPW;
+ } else {
+ ret->code = check_self_keychange(handle, rqstp, arg->princ);
+ if (!ret->code)
+ ret->code = kadm5_chpass_principal(handle, arg->princ, arg->pass);
}
if (ret->code != KADM5_AUTH_CHANGEPW) {
@@ -845,20 +863,18 @@ chpass_principal3_2_svc(chpass3_arg *arg, generic_ret *ret,
&service_name, rqstp);
ret->code = KADM5_AUTH_CHANGEPW;
}
- } else if (cmp_gss_krb5_name(handle, rqst2name(rqstp), arg->princ)) {
- ret->code = chpass_principal_wrapper_3(handle, arg->princ,
- arg->keepold, arg->n_ks_tuple,
- arg->ks_tuple, arg->pass);
- } else if (!(CHANGEPW_SERVICE(rqstp)) &&
- kadm5int_acl_check(handle->context, rqst2name(rqstp),
- ACL_CHANGEPW, arg->princ, NULL)) {
- ret->code = kadm5_chpass_principal_3(handle, arg->princ, arg->keepold,
- arg->n_ks_tuple, arg->ks_tuple,
- arg->pass);
- } else {
+ } else if (changepw_not_self(handle, rqstp, arg->princ) ||
+ !stub_auth(handle, OP_CPW, arg->princ, NULL, NULL, NULL)) {
+ ret->code = KADM5_AUTH_CHANGEPW;
log_unauth("kadm5_chpass_principal", prime_arg,
&client_name, &service_name, rqstp);
- ret->code = KADM5_AUTH_CHANGEPW;
+ } else {
+ ret->code = check_self_keychange(handle, rqstp, arg->princ);
+ if (!ret->code) {
+ ret->code = kadm5_chpass_principal_3(handle, arg->princ,
+ arg->keepold, arg->n_ks_tuple,
+ arg->ks_tuple, arg->pass);
+ }
}
if (ret->code != KADM5_AUTH_CHANGEPW) {
@@ -901,8 +917,7 @@ setv4key_principal_2_svc(setv4key_arg *arg, generic_ret *ret,
ret->code = KADM5_AUTH_SETKEY;
}
} else if (!(CHANGEPW_SERVICE(rqstp)) &&
- kadm5int_acl_check(handle->context, rqst2name(rqstp),
- ACL_SETKEY, arg->princ, NULL)) {
+ stub_auth(handle, OP_SETKEY, arg->princ, NULL, NULL, NULL)) {
ret->code = kadm5_setv4key_principal(handle, arg->princ,
arg->keyblock);
} else {
@@ -952,8 +967,7 @@ setkey_principal_2_svc(setkey_arg *arg, generic_ret *ret,
ret->code = KADM5_AUTH_SETKEY;
}
} else if (!(CHANGEPW_SERVICE(rqstp)) &&
- kadm5int_acl_check(handle->context, rqst2name(rqstp),
- ACL_SETKEY, arg->princ, NULL)) {
+ stub_auth(handle, OP_SETKEY, arg->princ, NULL, NULL, NULL)) {
ret->code = kadm5_setkey_principal(handle, arg->princ, arg->keyblocks,
arg->n_keys);
} else {
@@ -1002,8 +1016,7 @@ setkey_principal3_2_svc(setkey3_arg *arg, generic_ret *ret,
ret->code = KADM5_AUTH_SETKEY;
}
} else if (!(CHANGEPW_SERVICE(rqstp)) &&
- kadm5int_acl_check(handle->context, rqst2name(rqstp),
- ACL_SETKEY, arg->princ, NULL)) {
+ stub_auth(handle, OP_SETKEY, arg->princ, NULL, NULL, NULL)) {
ret->code = kadm5_setkey_principal_3(handle, arg->princ, arg->keepold,
arg->n_ks_tuple, arg->ks_tuple,
arg->keyblocks, arg->n_keys);
@@ -1053,8 +1066,7 @@ setkey_principal4_2_svc(setkey4_arg *arg, generic_ret *ret,
ret->code = KADM5_AUTH_SETKEY;
}
} else if (!(CHANGEPW_SERVICE(rqstp)) &&
- kadm5int_acl_check(handle->context, rqst2name(rqstp),
- ACL_SETKEY, arg->princ, NULL)) {
+ stub_auth(handle, OP_SETKEY, arg->princ, NULL, NULL, NULL)) {
ret->code = kadm5_setkey_principal_4(handle, arg->princ, arg->keepold,
arg->key_data, arg->n_key_data);
} else {
@@ -1079,8 +1091,8 @@ exit_func:
return TRUE;
}
-/* Empty out *keys/*nkeys if princ is protected with the lockdown attribute, or
- * if we fail to check. */
+/* Empty out *keys / *nkeys if princ is protected with the lockdown
+ * attribute, or if we fail to check. */
static kadm5_ret_t
chrand_check_lockdown(kadm5_server_handle_t handle, krb5_principal princ,
krb5_keyblock **keys, int *nkeys)
@@ -1119,17 +1131,17 @@ chrand_principal_2_svc(chrand_arg *arg, chrand_ret *ret, struct svc_req *rqstp)
funcname = "kadm5_randkey_principal";
- if (cmp_gss_krb5_name(handle, rqst2name(rqstp), arg->princ)) {
- ret->code = randkey_principal_wrapper_3(handle, arg->princ, FALSE, 0,
- NULL, &k, &nkeys);
- } else if (!(CHANGEPW_SERVICE(rqstp)) &&
- kadm5int_acl_check(handle->context, rqst2name(rqstp),
- ACL_CHANGEPW, arg->princ, NULL)) {
- ret->code = kadm5_randkey_principal(handle, arg->princ, &k, &nkeys);
- } else {
+ if (changepw_not_self(handle, rqstp, arg->princ) ||
+ !stub_auth(handle, OP_CHRAND, arg->princ, NULL, NULL, NULL)) {
+ ret->code = KADM5_AUTH_CHANGEPW;
log_unauth(funcname, prime_arg,
&client_name, &service_name, rqstp);
- ret->code = KADM5_AUTH_CHANGEPW;
+ } else {
+ ret->code = check_self_keychange(handle, rqstp, arg->princ);
+ if (!ret->code) {
+ ret->code = kadm5_randkey_principal(handle, arg->princ,
+ &k, &nkeys);
+ }
}
if (ret->code == KADM5_OK) {
@@ -1176,20 +1188,19 @@ chrand_principal3_2_svc(chrand3_arg *arg, chrand_ret *ret,
funcname = "kadm5_randkey_principal";
- if (cmp_gss_krb5_name(handle, rqst2name(rqstp), arg->princ)) {
- ret->code = randkey_principal_wrapper_3(handle, arg->princ,
- arg->keepold, arg->n_ks_tuple,
- arg->ks_tuple, &k, &nkeys);
- } else if (!(CHANGEPW_SERVICE(rqstp)) &&
- kadm5int_acl_check(handle->context, rqst2name(rqstp),
- ACL_CHANGEPW, arg->princ, NULL)) {
- ret->code = kadm5_randkey_principal_3(handle, arg->princ, arg->keepold,
- arg->n_ks_tuple, arg->ks_tuple,
- &k, &nkeys);
- } else {
+ if (changepw_not_self(handle, rqstp, arg->princ) ||
+ !stub_auth(handle, OP_CHRAND, arg->princ, NULL, NULL, NULL)) {
+ ret->code = KADM5_AUTH_CHANGEPW;
log_unauth(funcname, prime_arg,
&client_name, &service_name, rqstp);
- ret->code = KADM5_AUTH_CHANGEPW;
+ } else {
+ ret->code = check_self_keychange(handle, rqstp, arg->princ);
+ if (!ret->code) {
+ ret->code = kadm5_randkey_principal_3(handle, arg->princ,
+ arg->keepold,
+ arg->n_ks_tuple,
+ arg->ks_tuple, &k, &nkeys);
+ }
}
if (ret->code == KADM5_OK) {
@@ -1233,9 +1244,9 @@ create_policy_2_svc(cpol_arg *arg, generic_ret *ret, struct svc_req *rqstp)
prime_arg = arg->rec.policy;
- if (CHANGEPW_SERVICE(rqstp) || !kadm5int_acl_check(handle->context,
- rqst2name(rqstp),
- ACL_ADD, NULL, NULL)) {
+ if (CHANGEPW_SERVICE(rqstp) ||
+ !stub_auth_pol(handle, OP_ADDPOL, arg->rec.policy,
+ &arg->rec, arg->mask)) {
ret->code = KADM5_AUTH_ADD;
log_unauth("kadm5_create_policy", prime_arg,
&client_name, &service_name, rqstp);
@@ -1275,9 +1286,8 @@ delete_policy_2_svc(dpol_arg *arg, generic_ret *ret, struct svc_req *rqstp)
prime_arg = arg->name;
- if (CHANGEPW_SERVICE(rqstp) || !kadm5int_acl_check(handle->context,
- rqst2name(rqstp),
- ACL_DELETE, NULL, NULL)) {
+ if (CHANGEPW_SERVICE(rqstp) ||
+ !stub_auth(handle, OP_DELPOL, NULL, NULL, arg->name, NULL)) {
log_unauth("kadm5_delete_policy", prime_arg,
&client_name, &service_name, rqstp);
ret->code = KADM5_AUTH_DELETE;
@@ -1316,9 +1326,9 @@ modify_policy_2_svc(mpol_arg *arg, generic_ret *ret, struct svc_req *rqstp)
prime_arg = arg->rec.policy;
- if (CHANGEPW_SERVICE(rqstp) || !kadm5int_acl_check(handle->context,
- rqst2name(rqstp),
- ACL_MODIFY, NULL, NULL)) {
+ if (CHANGEPW_SERVICE(rqstp) ||
+ !stub_auth_pol(handle, OP_MODPOL, arg->rec.policy,
+ &arg->rec, arg->mask)) {
log_unauth("kadm5_modify_policy", prime_arg,
&client_name, &service_name, rqstp);
ret->code = KADM5_AUTH_MODIFY;
@@ -1349,7 +1359,9 @@ get_policy_2_svc(gpol_arg *arg, gpol_ret *ret, struct svc_req *rqstp)
kadm5_ret_t ret2;
kadm5_principal_ent_rec caller_ent;
kadm5_server_handle_t handle;
- const char *errmsg = NULL;
+ const char *errmsg = NULL, *cpolicy = NULL;
+
+ memset(&caller_ent, 0, sizeof(caller_ent));
ret->code = stub_setup(arg->api_version, rqstp, NULL, &handle,
&ret->api_version, &client_name, &service_name,
@@ -1361,31 +1373,20 @@ get_policy_2_svc(gpol_arg *arg, gpol_ret *ret, struct svc_req *rqstp)
prime_arg = arg->name;
- ret->code = KADM5_AUTH_GET;
- if (!CHANGEPW_SERVICE(rqstp) && kadm5int_acl_check(handle->context,
- rqst2name(rqstp),
- ACL_INQUIRE, NULL, NULL))
- ret->code = KADM5_OK;
- else {
- ret->code = kadm5_get_principal(handle->lhandle,
- handle->current_caller, &caller_ent,
- KADM5_PRINCIPAL_NORMAL_MASK);
- if (ret->code == KADM5_OK) {
- if (caller_ent.aux_attributes & KADM5_POLICY &&
- strcmp(caller_ent.policy, arg->name) == 0) {
- ret->code = KADM5_OK;
- } else {
- ret->code = KADM5_AUTH_GET;
- }
- ret2 = kadm5_free_principal_ent(handle->lhandle,
- &caller_ent);
- ret->code = ret->code ? ret->code : ret2;
- }
- }
+ /* Look up the client principal's policy value. */
+ ret2 = kadm5_get_principal(handle->lhandle, handle->current_caller,
+ &caller_ent, KADM5_PRINCIPAL_NORMAL_MASK);
+ if (ret2 == KADM5_OK && (caller_ent.aux_attributes & KADM5_POLICY))
+ cpolicy = caller_ent.policy;
- if (ret->code == KADM5_OK) {
+ ret->code = KADM5_AUTH_GET;
+ if ((CHANGEPW_SERVICE(rqstp) &&
+ (cpolicy == NULL || strcmp(cpolicy, arg->name) != 0)) ||
+ !stub_auth(handle, OP_GETPOL, NULL, NULL, arg->name, cpolicy)) {
+ ret->code = KADM5_AUTH_GET;
+ log_unauth(funcname, prime_arg, &client_name, &service_name, rqstp);
+ } else {
ret->code = kadm5_get_policy(handle, arg->name, &ret->rec);
-
if (ret->code != 0)
errmsg = krb5_get_error_message(handle->context, ret->code);
@@ -1394,13 +1395,10 @@ get_policy_2_svc(gpol_arg *arg, gpol_ret *ret, struct svc_req *rqstp)
&client_name, &service_name, rqstp);
if (errmsg != NULL)
krb5_free_error_message(handle->context, errmsg);
-
- } else {
- log_unauth(funcname, prime_arg,
- &client_name, &service_name, rqstp);
}
exit_func:
+ (void)kadm5_free_principal_ent(handle->lhandle, &caller_ent);
stub_cleanup(handle, NULL, &client_name, &service_name);
return TRUE;
}
@@ -1424,9 +1422,8 @@ get_pols_2_svc(gpols_arg *arg, gpols_ret *ret, struct svc_req *rqstp)
if (prime_arg == NULL)
prime_arg = "*";
- if (CHANGEPW_SERVICE(rqstp) || !kadm5int_acl_check(handle->context,
- rqst2name(rqstp),
- ACL_LIST, NULL, NULL)) {
+ if (CHANGEPW_SERVICE(rqstp) ||
+ !stub_auth(handle, OP_LISTPOLS, NULL, NULL, NULL, NULL)) {
ret->code = KADM5_AUTH_LIST;
log_unauth("kadm5_get_policies", prime_arg,
&client_name, &service_name, rqstp);
@@ -1494,10 +1491,8 @@ purgekeys_2_svc(purgekeys_arg *arg, generic_ret *ret, struct svc_req *rqstp)
funcname = "kadm5_purgekeys";
- if (!cmp_gss_krb5_name(handle, rqst2name(rqstp), arg->princ) &&
- (CHANGEPW_SERVICE(rqstp)
- || !kadm5int_acl_check(handle->context, rqst2name(rqstp), ACL_MODIFY,
- arg->princ, NULL))) {
+ if (CHANGEPW_SERVICE(rqstp) ||
+ !stub_auth(handle, OP_PURGEKEYS, arg->princ, NULL, NULL, NULL)) {
ret->code = KADM5_AUTH_MODIFY;
log_unauth(funcname, prime_arg, &client_name, &service_name, rqstp);
} else {
@@ -1532,12 +1527,8 @@ get_strings_2_svc(gstrings_arg *arg, gstrings_ret *ret, struct svc_req *rqstp)
if (ret->code)
goto exit_func;
- if (! cmp_gss_krb5_name(handle, rqst2name(rqstp), arg->princ) &&
- (CHANGEPW_SERVICE(rqstp) || !kadm5int_acl_check(handle->context,
- rqst2name(rqstp),
- ACL_INQUIRE,
- arg->princ,
- NULL))) {
+ if (CHANGEPW_SERVICE(rqstp) ||
+ !stub_auth(handle, OP_GETSTRS, arg->princ, NULL, NULL, NULL)) {
ret->code = KADM5_AUTH_GET;
log_unauth("kadm5_get_strings", prime_arg,
&client_name, &service_name, rqstp);
@@ -1574,9 +1565,9 @@ set_string_2_svc(sstring_arg *arg, generic_ret *ret, struct svc_req *rqstp)
if (ret->code)
goto exit_func;
- if (CHANGEPW_SERVICE(rqstp)
- || !kadm5int_acl_check(handle->context, rqst2name(rqstp), ACL_MODIFY,
- arg->princ, NULL)) {
+ if (CHANGEPW_SERVICE(rqstp) ||
+ !stub_auth(handle, OP_SETSTR, arg->princ, NULL,
+ arg->key, arg->value)) {
ret->code = KADM5_AUTH_MODIFY;
log_unauth("kadm5_mod_strings", prime_arg,
&client_name, &service_name, rqstp);
@@ -1665,8 +1656,7 @@ get_principal_keys_2_svc(getpkeys_arg *arg, getpkeys_ret *ret,
goto exit_func;
if (!(CHANGEPW_SERVICE(rqstp)) &&
- kadm5int_acl_check(handle->context, rqst2name(rqstp),
- ACL_EXTRACT, arg->princ, NULL)) {
+ stub_auth(handle, OP_EXTRACT, arg->princ, NULL, NULL, NULL)) {
ret->code = kadm5_get_principal_keys(handle, arg->princ, arg->kvno,
&ret->key_data, &ret->n_key_data);
} else {
diff --git a/src/kadmin/testing/util/tcl_kadm5.c b/src/kadmin/testing/util/tcl_kadm5.c
index a4997c60ca04..9dde579ef397 100644
--- a/src/kadmin/testing/util/tcl_kadm5.c
+++ b/src/kadmin/testing/util/tcl_kadm5.c
@@ -697,13 +697,13 @@ static Tcl_DString *unparse_principal_ent(kadm5_principal_ent_t princ,
} else
Tcl_DStringAppendElement(str, "null");
- sprintf(buf, "%d", princ->princ_expire_time);
+ sprintf(buf, "%u", (unsigned int)princ->princ_expire_time);
Tcl_DStringAppendElement(str, buf);
- sprintf(buf, "%d", princ->last_pwd_change);
+ sprintf(buf, "%u", (unsigned int)princ->last_pwd_change);
Tcl_DStringAppendElement(str, buf);
- sprintf(buf, "%d", princ->pw_expiration);
+ sprintf(buf, "%u", (unsigned int)princ->pw_expiration);
Tcl_DStringAppendElement(str, buf);
sprintf(buf, "%d", princ->max_life);
@@ -722,7 +722,7 @@ static Tcl_DString *unparse_principal_ent(kadm5_principal_ent_t princ,
} else
Tcl_DStringAppendElement(str, "null");
- sprintf(buf, "%d", princ->mod_date);
+ sprintf(buf, "%u", (unsigned int)princ->mod_date);
Tcl_DStringAppendElement(str, buf);
if (mask & KADM5_ATTRIBUTES) {
@@ -758,10 +758,10 @@ static Tcl_DString *unparse_principal_ent(kadm5_principal_ent_t princ,
sprintf(buf, "%d", princ->max_renewable_life);
Tcl_DStringAppendElement(str, buf);
- sprintf(buf, "%d", princ->last_success);
+ sprintf(buf, "%u", (unsigned int)princ->last_success);
Tcl_DStringAppendElement(str, buf);
- sprintf(buf, "%d", princ->last_failed);
+ sprintf(buf, "%u", (unsigned int)princ->last_failed);
Tcl_DStringAppendElement(str, buf);
sprintf(buf, "%d", princ->fail_auth_count);
diff --git a/src/kdc/deps b/src/kdc/deps
index b5257c715f88..6bc00f7a938c 100644
--- a/src/kdc/deps
+++ b/src/kdc/deps
@@ -171,20 +171,22 @@ $(OUTPRE)main.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
$(top_srcdir)/include/krb5/kdcpreauth_plugin.h $(top_srcdir)/include/krb5/plugin.h \
$(top_srcdir)/include/net-server.h $(top_srcdir)/include/port-sockets.h \
$(top_srcdir)/include/socket-utils.h extern.h kdc5_err.h \
- kdc_audit.h kdc_util.h main.c realm_data.h reqstate.h
+ kdc_audit.h kdc_util.h main.c policy.h realm_data.h \
+ reqstate.h
$(OUTPRE)policy.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
$(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
$(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(VERTO_DEPS) \
- $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \
- $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \
- $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \
- $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \
- $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/kdb.h \
- $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \
+ $(top_srcdir)/include/adm_proto.h $(top_srcdir)/include/k5-buf.h \
+ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \
+ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \
+ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \
+ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \
+ $(top_srcdir)/include/kdb.h $(top_srcdir)/include/krb5.h \
+ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/kdcpolicy_plugin.h \
$(top_srcdir)/include/krb5/kdcpreauth_plugin.h $(top_srcdir)/include/krb5/plugin.h \
$(top_srcdir)/include/net-server.h $(top_srcdir)/include/port-sockets.h \
$(top_srcdir)/include/socket-utils.h extern.h kdc_util.h \
- policy.c realm_data.h reqstate.h
+ policy.c policy.h realm_data.h reqstate.h
$(OUTPRE)extern.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
$(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
$(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \
@@ -279,14 +281,14 @@ $(OUTPRE)kdc_log.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
$(OUTPRE)t_replay.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
$(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
$(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(VERTO_DEPS) \
- $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \
- $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \
- $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \
- $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-queue.h \
- $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \
- $(top_srcdir)/include/kdb.h $(top_srcdir)/include/krb5.h \
- $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/kdcpreauth_plugin.h \
- $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/net-server.h \
- $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \
- extern.h kdc_util.h realm_data.h replay.c reqstate.h \
- t_replay.c
+ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-cmocka.h \
+ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \
+ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \
+ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \
+ $(top_srcdir)/include/k5-queue.h $(top_srcdir)/include/k5-thread.h \
+ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/kdb.h \
+ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \
+ $(top_srcdir)/include/krb5/kdcpreauth_plugin.h $(top_srcdir)/include/krb5/plugin.h \
+ $(top_srcdir)/include/net-server.h $(top_srcdir)/include/port-sockets.h \
+ $(top_srcdir)/include/socket-utils.h extern.h kdc_util.h \
+ realm_data.h replay.c reqstate.h t_replay.c
diff --git a/src/kdc/dispatch.c b/src/kdc/dispatch.c
index 3a169ebc7f40..3867ff952e49 100644
--- a/src/kdc/dispatch.c
+++ b/src/kdc/dispatch.c
@@ -94,8 +94,8 @@ static void
reseed_random(krb5_context kdc_err_context)
{
krb5_error_code retval;
- krb5_int32 now, now_usec;
- krb5_int32 usec_difference;
+ krb5_timestamp now;
+ krb5_int32 now_usec, usec_difference;
krb5_data data;
retval = krb5_crypto_us_timeofday(&now, &now_usec);
@@ -104,7 +104,7 @@ reseed_random(krb5_context kdc_err_context)
if (last_os_random == 0)
last_os_random = now;
/* Grab random data from OS every hour*/
- if (now-last_os_random >= 60 * 60) {
+ if (ts_delta(now, last_os_random) >= 60 * 60) {
krb5_c_random_os_entropy(kdc_err_context, 0, NULL);
last_os_random = now;
}
@@ -119,8 +119,8 @@ reseed_random(krb5_context kdc_err_context)
}
void
-dispatch(void *cb, struct sockaddr *local_saddr,
- const krb5_fulladdr *from, krb5_data *pkt, int is_tcp,
+dispatch(void *cb, const krb5_fulladdr *local_addr,
+ const krb5_fulladdr *remote_addr, krb5_data *pkt, int is_tcp,
verto_ctx *vctx, loop_respond_fn respond, void *arg)
{
krb5_error_code retval;
@@ -150,8 +150,8 @@ dispatch(void *cb, struct sockaddr *local_saddr,
const char *name = 0;
char buf[46];
- name = inet_ntop (ADDRTYPE2FAMILY (from->address->addrtype),
- from->address->contents, buf, sizeof (buf));
+ name = inet_ntop(ADDRTYPE2FAMILY(remote_addr->address->addrtype),
+ remote_addr->address->contents, buf, sizeof(buf));
if (name == 0)
name = "[unknown address type]";
if (response)
@@ -177,7 +177,7 @@ dispatch(void *cb, struct sockaddr *local_saddr,
/* try TGS_REQ first; they are more common! */
if (krb5_is_tgs_req(pkt)) {
- retval = process_tgs_req(handle, pkt, from, &response);
+ retval = process_tgs_req(handle, pkt, remote_addr, &response);
} else if (krb5_is_as_req(pkt)) {
if (!(retval = decode_krb5_as_req(pkt, &as_req))) {
/*
@@ -187,7 +187,8 @@ dispatch(void *cb, struct sockaddr *local_saddr,
*/
state->active_realm = setup_server_realm(handle, as_req->server);
if (state->active_realm != NULL) {
- process_as_req(as_req, pkt, from, state->active_realm, vctx,
+ process_as_req(as_req, pkt, local_addr, remote_addr,
+ state->active_realm, vctx,
finish_dispatch_cache, state);
return;
} else {
diff --git a/src/kdc/do_as_req.c b/src/kdc/do_as_req.c
index 712ccb794680..7c8da63e1861 100644
--- a/src/kdc/do_as_req.c
+++ b/src/kdc/do_as_req.c
@@ -87,7 +87,7 @@ get_key_exp(krb5_db_entry *entry)
return entry->pw_expiration;
if (entry->pw_expiration == 0)
return entry->expiration;
- return min(entry->expiration, entry->pw_expiration);
+ return ts_min(entry->expiration, entry->pw_expiration);
}
/*
@@ -160,7 +160,8 @@ struct as_req_state {
struct kdc_request_state *rstate;
char *sname, *cname;
void *pa_context;
- const krb5_fulladdr *from;
+ const krb5_fulladdr *local_addr;
+ const krb5_fulladdr *remote_addr;
krb5_data **auth_indicators;
krb5_error_code preauth_err;
@@ -207,6 +208,13 @@ finish_process_as_req(struct as_req_state *state, krb5_error_code errcode)
state->ticket_reply.enc_part2 = &state->enc_tkt_reply;
+ errcode = check_kdcpolicy_as(kdc_context, state->request, state->client,
+ state->server, state->auth_indicators,
+ state->kdc_time, &state->enc_tkt_reply.times,
+ &state->status);
+ if (errcode)
+ goto egress;
+
/*
* Find the server key
*/
@@ -239,10 +247,8 @@ finish_process_as_req(struct as_req_state *state, krb5_error_code errcode)
state->reply.ticket = &state->ticket_reply;
state->reply_encpart.session = &state->session_key;
if ((errcode = fetch_last_req_info(state->client,
- &state->reply_encpart.last_req))) {
- state->status = "FETCH_LAST_REQ";
+ &state->reply_encpart.last_req)))
goto egress;
- }
state->reply_encpart.nonce = state->request->nonce;
state->reply_encpart.key_exp = get_key_exp(state->client);
state->reply_encpart.flags = state->enc_tkt_reply.flags;
@@ -300,27 +306,21 @@ finish_process_as_req(struct as_req_state *state, krb5_error_code errcode)
errcode = krb5_encrypt_tkt_part(kdc_context, &state->server_keyblock,
&state->ticket_reply);
- if (errcode) {
- state->status = "ENCRYPT_TICKET";
+ if (errcode)
goto egress;
- }
errcode = kau_make_tkt_id(kdc_context, &state->ticket_reply,
&au_state->tkt_out_id);
- if (errcode) {
- state->status = "GENERATE_TICKET_ID";
+ if (errcode)
goto egress;
- }
state->ticket_reply.enc_part.kvno = server_key->key_data_kvno;
errcode = kdc_fast_response_handle_padata(state->rstate,
state->request,
&state->reply,
state->client_keyblock.enctype);
- if (errcode) {
- state->status = "MAKE_FAST_RESPONSE";
+ if (errcode)
goto egress;
- }
/* now encode/encrypt the response */
@@ -328,10 +328,8 @@ finish_process_as_req(struct as_req_state *state, krb5_error_code errcode)
errcode = kdc_fast_handle_reply_key(state->rstate, &state->client_keyblock,
&as_encrypting_key);
- if (errcode) {
- state->status = "MAKE_FAST_REPLY_KEY";
+ if (errcode)
goto egress;
- }
errcode = return_enc_padata(kdc_context, state->req_pkt, state->request,
as_encrypting_key, state->server,
&state->reply_encpart, FALSE);
@@ -348,10 +346,8 @@ finish_process_as_req(struct as_req_state *state, krb5_error_code errcode)
&state->reply, &response);
if (state->client_key != NULL)
state->reply.enc_part.kvno = state->client_key->key_data_kvno;
- if (errcode) {
- state->status = "ENCODE_KDC_REP";
+ if (errcode)
goto egress;
- }
/* these parts are left on as a courtesy from krb5_encode_kdc_rep so we
can use them in raw form if needed. But, we don't... */
@@ -359,14 +355,14 @@ finish_process_as_req(struct as_req_state *state, krb5_error_code errcode)
state->reply.enc_part.ciphertext.length);
free(state->reply.enc_part.ciphertext.data);
- log_as_req(kdc_context, state->from, state->request, &state->reply,
- state->client, state->cname, state->server,
- state->sname, state->authtime, 0, 0, 0);
+ log_as_req(kdc_context, state->local_addr, state->remote_addr,
+ state->request, &state->reply, state->client, state->cname,
+ state->server, state->sname, state->authtime, 0, 0, 0);
did_log = 1;
egress:
- if (errcode != 0)
- assert (state->status != 0);
+ if (errcode != 0 && state->status == NULL)
+ state->status = "UNKNOWN_REASON";
au_state->status = state->status;
au_state->reply = &state->reply;
@@ -381,8 +377,8 @@ egress:
emsg = krb5_get_error_message(kdc_context, errcode);
if (state->status) {
- log_as_req(kdc_context,
- state->from, state->request, &state->reply, state->client,
+ log_as_req(kdc_context, state->local_addr, state->remote_addr,
+ state->request, &state->reply, state->client,
state->cname, state->server, state->sname, state->authtime,
state->status, errcode, emsg);
did_log = 1;
@@ -492,7 +488,8 @@ finish_preauth(void *arg, krb5_error_code code)
/*ARGSUSED*/
void
process_as_req(krb5_kdc_req *request, krb5_data *req_pkt,
- const krb5_fulladdr *from, kdc_realm_t *kdc_active_realm,
+ const krb5_fulladdr *local_addr,
+ const krb5_fulladdr *remote_addr, kdc_realm_t *kdc_active_realm,
verto_ctx *vctx, loop_respond_fn respond, void *arg)
{
krb5_error_code errcode;
@@ -511,7 +508,8 @@ process_as_req(krb5_kdc_req *request, krb5_data *req_pkt,
state->arg = arg;
state->request = request;
state->req_pkt = req_pkt;
- state->from = from;
+ state->local_addr = local_addr;
+ state->remote_addr = remote_addr;
state->active_realm = kdc_active_realm;
errcode = kdc_make_rstate(kdc_active_realm, &state->rstate);
@@ -522,7 +520,8 @@ process_as_req(krb5_kdc_req *request, krb5_data *req_pkt,
}
/* Initialize audit state. */
- errcode = kau_init_kdc_req(kdc_context, state->request, from, &au_state);
+ errcode = kau_init_kdc_req(kdc_context, state->request, remote_addr,
+ &au_state);
if (errcode) {
(*respond)(arg, errcode, NULL);
kdc_free_rstate(state->rstate);
@@ -543,7 +542,6 @@ process_as_req(krb5_kdc_req *request, krb5_data *req_pkt,
if (fetch_asn1_field((unsigned char *) req_pkt->data,
1, 4, &encoded_req_body) != 0) {
errcode = ASN1_BAD_ID;
- state->status = "FETCH_REQ_BODY";
goto errout;
}
errcode = kdc_find_fast(&state->request, &encoded_req_body, NULL, NULL,
@@ -556,10 +554,8 @@ process_as_req(krb5_kdc_req *request, krb5_data *req_pkt,
/* Not a FAST request; copy the encoded request body. */
errcode = krb5_copy_data(kdc_context, &encoded_req_body,
&state->inner_body);
- if (errcode) {
- state->status = "COPY_REQ_BODY";
+ if (errcode)
goto errout;
- }
}
au_state->request = state->request;
state->rock.request = state->request;
@@ -574,10 +570,8 @@ process_as_req(krb5_kdc_req *request, krb5_data *req_pkt,
}
if ((errcode = krb5_unparse_name(kdc_context,
state->request->client,
- &state->cname))) {
- state->status = "UNPARSE_CLIENT";
+ &state->cname)))
goto errout;
- }
limit_string(state->cname);
if (!state->request->server) {
@@ -587,10 +581,8 @@ process_as_req(krb5_kdc_req *request, krb5_data *req_pkt,
}
if ((errcode = krb5_unparse_name(kdc_context,
state->request->server,
- &state->sname))) {
- state->status = "UNPARSE_SERVER";
+ &state->sname)))
goto errout;
- }
limit_string(state->sname);
/*
@@ -670,18 +662,14 @@ process_as_req(krb5_kdc_req *request, krb5_data *req_pkt,
au_state->stage = VALIDATE_POL;
- if ((errcode = krb5_timeofday(kdc_context, &state->kdc_time))) {
- state->status = "TIMEOFDAY";
+ if ((errcode = krb5_timeofday(kdc_context, &state->kdc_time)))
goto errout;
- }
state->authtime = state->kdc_time; /* for audit_as_request() */
if ((errcode = validate_as_request(kdc_active_realm,
state->request, *state->client,
*state->server, state->kdc_time,
&state->status, &state->e_data))) {
- if (!state->status)
- state->status = "UNKNOWN_REASON";
errcode += ERROR_TABLE_BASE_krb5;
goto errout;
}
@@ -701,10 +689,8 @@ process_as_req(krb5_kdc_req *request, krb5_data *req_pkt,
}
if ((errcode = krb5_c_make_random_key(kdc_context, useenctype,
- &state->session_key))) {
- state->status = "MAKE_RANDOM_KEY";
+ &state->session_key)))
goto errout;
- }
/*
* Canonicalization is only effective if we are issuing a TGT
@@ -785,10 +771,8 @@ process_as_req(krb5_kdc_req *request, krb5_data *req_pkt,
state->request->client = NULL;
errcode = krb5_copy_principal(kdc_context, krb5_anonymous_principal(),
&state->request->client);
- if (errcode) {
- state->status = "COPY_ANONYMOUS_PRINCIPAL";
+ if (errcode)
goto errout;
- }
state->enc_tkt_reply.client = state->request->client;
setflag(state->client->attributes, KRB5_KDB_REQUIRES_PRE_AUTH);
}
@@ -841,6 +825,8 @@ prepare_error_as(struct kdc_request_state *rstate, krb5_kdc_req *request,
kdc_realm_t *kdc_active_realm = rstate->realm_data;
size_t count;
+ errpkt.magic = KV5M_ERROR;
+
if (e_data_in != NULL) {
/* Add a PA-FX-COOKIE to e_data_in. e_data is a shallow copy
* containing aliases. */
@@ -854,7 +840,7 @@ prepare_error_as(struct kdc_request_state *rstate, krb5_kdc_req *request,
e_data[count] = cookie;
}
- errpkt.ctime = request->nonce;
+ errpkt.ctime = 0;
errpkt.cusec = 0;
retval = krb5_us_timeofday(kdc_context, &errpkt.stime, &errpkt.susec);
diff --git a/src/kdc/do_tgs_req.c b/src/kdc/do_tgs_req.c
index 547a41441767..cc5a6923629a 100644
--- a/src/kdc/do_tgs_req.c
+++ b/src/kdc/do_tgs_req.c
@@ -195,15 +195,12 @@ process_tgs_req(struct server_handle *handle, krb5_data *pkt,
if (!header_ticket) {
errcode = KRB5_NO_TKT_SUPPLIED; /* XXX? */
- status="UNEXPECTED NULL in header_ticket";
goto cleanup;
}
errcode = kau_make_tkt_id(kdc_context, header_ticket,
&au_state->tkt_in_id);
- if (errcode) {
- status = "GENERATE_TICKET_ID";
+ if (errcode)
goto cleanup;
- }
scratch.length = pa_tgs_req->length;
scratch.data = (char *) pa_tgs_req->contents;
@@ -264,16 +261,12 @@ process_tgs_req(struct server_handle *handle, krb5_data *pkt,
au_state->stage = VALIDATE_POL;
- if ((errcode = krb5_timeofday(kdc_context, &kdc_time))) {
- status = "TIME_OF_DAY";
+ if ((errcode = krb5_timeofday(kdc_context, &kdc_time)))
goto cleanup;
- }
if ((retval = validate_tgs_request(kdc_active_realm,
request, *server, header_ticket,
kdc_time, &status, &e_data))) {
- if (!status)
- status = "UNKNOWN_REASON";
if (retval == KDC_ERR_POLICY || retval == KDC_ERR_BADOPTION)
au_state->violation = PROT_CONSTRAINT;
errcode = retval + ERROR_TABLE_BASE_krb5;
@@ -340,7 +333,6 @@ process_tgs_req(struct server_handle *handle, krb5_data *pkt,
retval = kau_make_tkt_id(kdc_context, request->second_ticket[st_idx],
&au_state->evid_tkt_id);
if (retval) {
- status = "GENERATE_TICKET_ID";
errcode = retval;
goto cleanup;
}
@@ -500,12 +492,12 @@ process_tgs_req(struct server_handle *handle, krb5_data *pkt,
old_starttime = enc_tkt_reply.times.starttime ?
enc_tkt_reply.times.starttime : enc_tkt_reply.times.authtime;
- old_life = enc_tkt_reply.times.endtime - old_starttime;
+ old_life = ts_delta(enc_tkt_reply.times.endtime, old_starttime);
enc_tkt_reply.times.starttime = kdc_time;
enc_tkt_reply.times.endtime =
- min(header_ticket->enc_part2->times.renew_till,
- kdc_time + old_life);
+ ts_min(header_ticket->enc_part2->times.renew_till,
+ ts_incr(kdc_time, old_life));
} else {
/* not a renew request */
enc_tkt_reply.times.starttime = kdc_time;
@@ -518,6 +510,12 @@ process_tgs_req(struct server_handle *handle, krb5_data *pkt,
kdc_get_ticket_renewtime(kdc_active_realm, request, header_enc_tkt, client,
server, &enc_tkt_reply);
+ errcode = check_kdcpolicy_tgs(kdc_context, request, server, header_ticket,
+ auth_indicators, kdc_time,
+ &enc_tkt_reply.times, &status);
+ if (errcode)
+ goto cleanup;
+
/*
* Set authtime to be the same as header or evidence ticket's
*/
@@ -723,10 +721,8 @@ process_tgs_req(struct server_handle *handle, krb5_data *pkt,
&ticket_reply);
if (!isflagset(request->kdc_options, KDC_OPT_ENC_TKT_IN_SKEY))
krb5_free_keyblock_contents(kdc_context, &encrypting_key);
- if (errcode) {
- status = "ENCRYPT_TICKET";
+ if (errcode)
goto cleanup;
- }
ticket_reply.enc_part.kvno = ticket_kvno;
/* Start assembling the response */
au_state->stage = ENCR_REP;
@@ -740,10 +736,8 @@ process_tgs_req(struct server_handle *handle, krb5_data *pkt,
s4u_x509_user,
&reply,
&reply_encpart);
- if (errcode) {
- status = "MAKE_S4U2SELF_PADATA";
+ if (errcode)
au_state->status = status;
- }
kau_s4u2self(kdc_context, errcode ? FALSE : TRUE, au_state);
if (errcode)
goto cleanup;
@@ -775,16 +769,12 @@ process_tgs_req(struct server_handle *handle, krb5_data *pkt,
header_ticket->enc_part2->session->enctype;
errcode = kdc_fast_response_handle_padata(state, request, &reply,
subkey ? subkey->enctype : header_ticket->enc_part2->session->enctype);
- if (errcode !=0 ) {
- status = "MAKE_FAST_RESPONSE";
+ if (errcode)
goto cleanup;
- }
errcode =kdc_fast_handle_reply_key(state,
subkey?subkey:header_ticket->enc_part2->session, &reply_key);
- if (errcode) {
- status = "MAKE_FAST_REPLY_KEY";
+ if (errcode)
goto cleanup;
- }
errcode = return_enc_padata(kdc_context, pkt, request,
reply_key, server, &reply_encpart,
is_referral &&
@@ -796,10 +786,8 @@ process_tgs_req(struct server_handle *handle, krb5_data *pkt,
}
errcode = kau_make_tkt_id(kdc_context, &ticket_reply, &au_state->tkt_out_id);
- if (errcode) {
- status = "GENERATE_TICKET_ID";
+ if (errcode)
goto cleanup;
- }
if (kdc_fast_hide_client(state))
reply.client = (krb5_principal)krb5_anonymous_principal();
@@ -807,11 +795,8 @@ process_tgs_req(struct server_handle *handle, krb5_data *pkt,
subkey ? 1 : 0,
reply_key,
&reply, response);
- if (errcode) {
- status = "ENCODE_KDC_REP";
- } else {
+ if (!errcode)
status = "ISSUE";
- }
memset(ticket_reply.enc_part.ciphertext.data, 0,
ticket_reply.enc_part.ciphertext.length);
@@ -823,7 +808,8 @@ process_tgs_req(struct server_handle *handle, krb5_data *pkt,
free(reply.enc_part.ciphertext.data);
cleanup:
- assert(status != NULL);
+ if (status == NULL)
+ status = "UNKNOWN_REASON";
if (reply_key)
krb5_free_keyblock(kdc_context, reply_key);
if (errcode)
@@ -909,7 +895,8 @@ prepare_error_tgs (struct kdc_request_state *state,
krb5_data *scratch, *e_data_asn1 = NULL, *fast_edata = NULL;
kdc_realm_t *kdc_active_realm = state->realm_data;
- errpkt.ctime = request->nonce;
+ errpkt.magic = KV5M_ERROR;
+ errpkt.ctime = 0;
errpkt.cusec = 0;
if ((retval = krb5_us_timeofday(kdc_context, &errpkt.stime,
@@ -1052,7 +1039,7 @@ gen_session_key(kdc_realm_t *kdc_active_realm, krb5_kdc_req *req,
retval = get_2ndtkt_enctype(kdc_active_realm, req, &useenctype,
status);
if (retval != 0)
- goto cleanup;
+ return retval;
}
if (useenctype == 0) {
useenctype = select_session_keytype(kdc_active_realm, server,
@@ -1062,17 +1049,10 @@ gen_session_key(kdc_realm_t *kdc_active_realm, krb5_kdc_req *req,
if (useenctype == 0) {
/* unsupported ktype */
*status = "BAD_ENCRYPTION_TYPE";
- retval = KRB5KDC_ERR_ETYPE_NOSUPP;
- goto cleanup;
- }
- retval = krb5_c_make_random_key(kdc_context, useenctype, skey);
- if (retval != 0) {
- /* random key failed */
- *status = "MAKE_RANDOM_KEY";
- goto cleanup;
+ return KRB5KDC_ERR_ETYPE_NOSUPP;
}
-cleanup:
- return retval;
+
+ return krb5_c_make_random_key(kdc_context, useenctype, skey);
}
/*
diff --git a/src/kdc/extern.c b/src/kdc/extern.c
index fe627494b8d3..84b5c6ad5d1c 100644
--- a/src/kdc/extern.c
+++ b/src/kdc/extern.c
@@ -37,6 +37,8 @@
kdc_realm_t **kdc_realmlist = (kdc_realm_t **) NULL;
int kdc_numrealms = 0;
krb5_data empty_string = {0, 0, ""};
-krb5_timestamp kdc_infinity = KRB5_INT32_MAX; /* XXX */
krb5_keyblock psr_key;
krb5_int32 max_dgram_reply_size = MAX_DGRAM_SIZE;
+
+/* With ts_after(), this is the largest timestamp value. */
+krb5_timestamp kdc_infinity = -1;
diff --git a/src/kdc/fast_util.c b/src/kdc/fast_util.c
index 9df940219cd8..e05107ef328d 100644
--- a/src/kdc/fast_util.c
+++ b/src/kdc/fast_util.c
@@ -607,7 +607,7 @@ kdc_fast_read_cookie(krb5_context context, struct kdc_request_state *state,
ret = krb5_timeofday(context, &now);
if (ret)
goto cleanup;
- if (now - COOKIE_LIFETIME > cookie->time) {
+ if (ts2tt(now) > cookie->time + COOKIE_LIFETIME) {
/* Don't accept the cookie contents. Only return an error if the
* cookie is relevant to the request. */
if (is_relevant(cookie->data, req->padata))
@@ -700,7 +700,7 @@ kdc_fast_make_cookie(krb5_context context, struct kdc_request_state *state,
ret = krb5_timeofday(context, &now);
if (ret)
goto cleanup;
- cookie.time = now;
+ cookie.time = ts2tt(now);
cookie.data = contents;
ret = encode_krb5_secure_cookie(&cookie, &der_cookie);
if (ret)
diff --git a/src/kdc/kdc_log.c b/src/kdc/kdc_log.c
index 94a2a1c87c91..7e8733980a41 100644
--- a/src/kdc/kdc_log.c
+++ b/src/kdc/kdc_log.c
@@ -54,7 +54,9 @@
/* Someday, pass local address/port as well. */
/* Currently no info about name canonicalization is logged. */
void
-log_as_req(krb5_context context, const krb5_fulladdr *from,
+log_as_req(krb5_context context,
+ const krb5_fulladdr *local_addr,
+ const krb5_fulladdr *remote_addr,
krb5_kdc_req *request, krb5_kdc_rep *reply,
krb5_db_entry *client, const char *cname,
krb5_db_entry *server, const char *sname,
@@ -67,8 +69,8 @@ log_as_req(krb5_context context, const krb5_fulladdr *from,
const char *cname2 = cname ? cname : "<unknown client>";
const char *sname2 = sname ? sname : "<unknown server>";
- fromstring = inet_ntop(ADDRTYPE2FAMILY (from->address->addrtype),
- from->address->contents,
+ fromstring = inet_ntop(ADDRTYPE2FAMILY(remote_addr->address->addrtype),
+ remote_addr->address->contents,
fromstringbuf, sizeof(fromstringbuf));
if (!fromstring)
fromstring = "<unknown>";
@@ -79,9 +81,9 @@ log_as_req(krb5_context context, const krb5_fulladdr *from,
/* success */
char rep_etypestr[128];
rep_etypes2str(rep_etypestr, sizeof(rep_etypestr), reply);
- krb5_klog_syslog(LOG_INFO, _("AS_REQ (%s) %s: ISSUE: authtime %d, %s, "
+ krb5_klog_syslog(LOG_INFO, _("AS_REQ (%s) %s: ISSUE: authtime %u, %s, "
"%s for %s"),
- ktypestr, fromstring, authtime,
+ ktypestr, fromstring, (unsigned int)authtime,
rep_etypestr, cname2, sname2);
} else {
/* fail */
@@ -89,14 +91,15 @@ log_as_req(krb5_context context, const krb5_fulladdr *from,
ktypestr, fromstring, status,
cname2, sname2, emsg ? ", " : "", emsg ? emsg : "");
}
- krb5_db_audit_as_req(context, request, client, server, authtime,
- errcode);
+ krb5_db_audit_as_req(context, request,
+ local_addr->address, remote_addr->address,
+ client, server, authtime, errcode);
#if 0
/* Sun (OpenSolaris) version would probably something like this.
The client and server names passed can be null, unlike in the
logging routines used above. Note that a struct in_addr is
used, but the real address could be an IPv6 address. */
- audit_krb5kdc_as_req(some in_addr *, (in_port_t)from->port, 0,
+ audit_krb5kdc_as_req(some in_addr *, (in_port_t)remote_addr->port, 0,
cname, sname, errcode);
#endif
}
@@ -156,10 +159,10 @@ log_tgs_req(krb5_context ctx, const krb5_fulladdr *from,
name (useful), and doesn't log ktypestr (probably not
important). */
if (errcode != KRB5KDC_ERR_SERVER_NOMATCH) {
- krb5_klog_syslog(LOG_INFO, _("TGS_REQ (%s) %s: %s: authtime %d, %s%s "
+ krb5_klog_syslog(LOG_INFO, _("TGS_REQ (%s) %s: %s: authtime %u, %s%s "
"%s for %s%s%s"),
- ktypestr, fromstring, status, authtime, rep_etypestr,
- !errcode ? "," : "", logcname, logsname,
+ ktypestr, fromstring, status, (unsigned int)authtime,
+ rep_etypestr, !errcode ? "," : "", logcname, logsname,
errcode ? ", " : "", errcode ? emsg : "");
if (isflagset(c_flags, KRB5_KDB_FLAG_PROTOCOL_TRANSITION))
krb5_klog_syslog(LOG_INFO,
@@ -171,9 +174,9 @@ log_tgs_req(krb5_context ctx, const krb5_fulladdr *from,
logaltcname);
} else
- krb5_klog_syslog(LOG_INFO, _("TGS_REQ %s: %s: authtime %d, %s for %s, "
+ krb5_klog_syslog(LOG_INFO, _("TGS_REQ %s: %s: authtime %u, %s for %s, "
"2nd tkt client %s"),
- fromstring, status, authtime,
+ fromstring, status, (unsigned int)authtime,
logcname, logsname, logaltcname);
/* OpenSolaris: audit_krb5kdc_tgs_req(...) or
diff --git a/src/kdc/kdc_preauth.c b/src/kdc/kdc_preauth.c
index 605fcb7addc6..81d0b8cffd39 100644
--- a/src/kdc/kdc_preauth.c
+++ b/src/kdc/kdc_preauth.c
@@ -568,8 +568,37 @@ set_cookie(krb5_context context, krb5_kdcpreauth_rock rock,
return kdc_fast_set_cookie(rock->rstate, pa_type, data);
}
+static krb5_boolean
+match_client(krb5_context context, krb5_kdcpreauth_rock rock,
+ krb5_principal princ)
+{
+ krb5_db_entry *ent;
+ krb5_boolean match = FALSE;
+ krb5_principal req_client = rock->request->client;
+ krb5_principal client = rock->client->princ;
+
+ /* Check for a direct match against the request principal or
+ * the post-canon client principal. */
+ if (krb5_principal_compare_flags(context, princ, req_client,
+ KRB5_PRINCIPAL_COMPARE_ENTERPRISE) ||
+ krb5_principal_compare(context, princ, client))
+ return TRUE;
+
+ if (krb5_db_get_principal(context, princ, KRB5_KDB_FLAG_ALIAS_OK, &ent))
+ return FALSE;
+ match = krb5_principal_compare(context, ent->princ, client);
+ krb5_db_free_principal(context, ent);
+ return match;
+}
+
+static krb5_principal
+client_name(krb5_context context, krb5_kdcpreauth_rock rock)
+{
+ return rock->client->princ;
+}
+
static struct krb5_kdcpreauth_callbacks_st callbacks = {
- 3,
+ 4,
max_time_skew,
client_keys,
free_keys,
@@ -583,7 +612,9 @@ static struct krb5_kdcpreauth_callbacks_st callbacks = {
client_keyblock,
add_auth_indicator,
get_cookie,
- set_cookie
+ set_cookie,
+ match_client,
+ client_name
};
static krb5_error_code
diff --git a/src/kdc/kdc_preauth_ec.c b/src/kdc/kdc_preauth_ec.c
index feef3683141c..7e636b3f9fed 100644
--- a/src/kdc/kdc_preauth_ec.c
+++ b/src/kdc/kdc_preauth_ec.c
@@ -56,7 +56,6 @@ ec_verify(krb5_context context, krb5_data *req_pkt, krb5_kdc_req *request,
krb5_kdcpreauth_verify_respond_fn respond, void *arg)
{
krb5_error_code retval = 0;
- krb5_timestamp now;
krb5_enc_data *enc = NULL;
krb5_data scratch, plain;
krb5_keyblock *armor_key = cb->fast_armor(context, rock);
@@ -66,6 +65,8 @@ ec_verify(krb5_context context, krb5_data *req_pkt, krb5_kdc_req *request,
krb5_keyblock *kdc_challenge_key;
krb5_kdcpreauth_modreq modreq = NULL;
int i = 0;
+ char *ai = NULL, *realmstr = NULL;
+ krb5_data realm = request->server->realm;
plain.data = NULL;
@@ -84,6 +85,15 @@ ec_verify(krb5_context context, krb5_data *req_pkt, krb5_kdc_req *request,
if (plain.data == NULL)
retval = ENOMEM;
}
+
+ /* Check for a configured FAST ec auth indicator. */
+ realmstr = k5memdup0(realm.data, realm.length, &retval);
+ if (realmstr != NULL)
+ retval = profile_get_string(context->profile, KRB5_CONF_REALMS,
+ realmstr,
+ KRB5_CONF_ENCRYPTED_CHALLENGE_INDICATOR,
+ NULL, &ai);
+
if (retval == 0)
retval = cb->client_keys(context, rock, &client_keys);
if (retval == 0) {
@@ -113,21 +123,20 @@ ec_verify(krb5_context context, krb5_data *req_pkt, krb5_kdc_req *request,
if (retval == 0)
retval = decode_krb5_pa_enc_ts(&plain, &ts);
if (retval == 0)
- retval = krb5_timeofday(context, &now);
+ retval = krb5_check_clockskew(context, ts->patimestamp);
if (retval == 0) {
- if (labs(now-ts->patimestamp) < context->clockskew) {
- enc_tkt_reply->flags |= TKT_FLG_PRE_AUTH;
- /*
- * If this fails, we won't generate a reply to the client. That
- * may cause the client to fail, but at this point the KDC has
- * considered this a success, so the return value is ignored.
- */
- if (krb5_c_fx_cf2_simple(context, armor_key, "kdcchallengearmor",
- &client_keys[i], "challengelongterm",
- &kdc_challenge_key) == 0)
- modreq = (krb5_kdcpreauth_modreq)kdc_challenge_key;
- } else { /*skew*/
- retval = KRB5KRB_AP_ERR_SKEW;
+ enc_tkt_reply->flags |= TKT_FLG_PRE_AUTH;
+ /*
+ * If this fails, we won't generate a reply to the client. That may
+ * cause the client to fail, but at this point the KDC has considered
+ * this a success, so the return value is ignored.
+ */
+ if (krb5_c_fx_cf2_simple(context, armor_key, "kdcchallengearmor",
+ &client_keys[i], "challengelongterm",
+ &kdc_challenge_key) == 0) {
+ modreq = (krb5_kdcpreauth_modreq)kdc_challenge_key;
+ if (ai != NULL)
+ cb->add_auth_indicator(context, rock, ai);
}
}
cb->free_keys(context, rock, client_keys);
@@ -137,6 +146,8 @@ ec_verify(krb5_context context, krb5_data *req_pkt, krb5_kdc_req *request,
krb5_free_enc_data(context, enc);
if (ts)
krb5_free_pa_enc_ts(context, ts);
+ free(realmstr);
+ free(ai);
(*respond)(arg, retval, modreq, NULL, NULL);
}
diff --git a/src/kdc/kdc_preauth_encts.c b/src/kdc/kdc_preauth_encts.c
index e80dc12a8cf3..25fc784576ef 100644
--- a/src/kdc/kdc_preauth_encts.c
+++ b/src/kdc/kdc_preauth_encts.c
@@ -58,7 +58,6 @@ enc_ts_verify(krb5_context context, krb5_data *req_pkt, krb5_kdc_req *request,
krb5_keyblock key;
krb5_key_data * client_key;
krb5_int32 start;
- krb5_timestamp timenow;
scratch.data = (char *)pa->contents;
scratch.length = pa->length;
@@ -95,14 +94,10 @@ enc_ts_verify(krb5_context context, krb5_data *req_pkt, krb5_kdc_req *request,
if ((retval = decode_krb5_pa_enc_ts(&enc_ts_data, &pa_enc)) != 0)
goto cleanup;
- if ((retval = krb5_timeofday(context, &timenow)) != 0)
+ retval = krb5_check_clockskew(context, pa_enc->patimestamp);
+ if (retval)
goto cleanup;
- if (labs(timenow - pa_enc->patimestamp) > context->clockskew) {
- retval = KRB5KRB_AP_ERR_SKEW;
- goto cleanup;
- }
-
setflag(enc_tkt_reply->flags, TKT_FLG_PRE_AUTH);
retval = 0;
diff --git a/src/kdc/kdc_util.c b/src/kdc/kdc_util.c
index 29f9dbbf07eb..754570c01310 100644
--- a/src/kdc/kdc_util.c
+++ b/src/kdc/kdc_util.c
@@ -642,7 +642,6 @@ validate_as_request(kdc_realm_t *kdc_active_realm,
krb5_db_entry server, krb5_timestamp kdc_time,
const char **status, krb5_pa_data ***e_data)
{
- int errcode;
krb5_error_code ret;
/*
@@ -654,7 +653,7 @@ validate_as_request(kdc_realm_t *kdc_active_realm,
}
/* The client must not be expired */
- if (client.expiration && client.expiration < kdc_time) {
+ if (client.expiration && ts_after(kdc_time, client.expiration)) {
*status = "CLIENT EXPIRED";
if (vague_errors)
return(KRB_ERR_GENERIC);
@@ -664,7 +663,7 @@ validate_as_request(kdc_realm_t *kdc_active_realm,
/* The client's password must not be expired, unless the server is
a KRB5_KDC_PWCHANGE_SERVICE. */
- if (client.pw_expiration && client.pw_expiration < kdc_time &&
+ if (client.pw_expiration && ts_after(kdc_time, client.pw_expiration) &&
!isflagset(server.attributes, KRB5_KDB_PWCHANGE_SERVICE)) {
*status = "CLIENT KEY EXPIRED";
if (vague_errors)
@@ -674,7 +673,7 @@ validate_as_request(kdc_realm_t *kdc_active_realm,
}
/* The server must not be expired */
- if (server.expiration && server.expiration < kdc_time) {
+ if (server.expiration && ts_after(kdc_time, server.expiration)) {
*status = "SERVICE EXPIRED";
return(KDC_ERR_SERVICE_EXP);
}
@@ -750,12 +749,6 @@ validate_as_request(kdc_realm_t *kdc_active_realm,
if (ret && ret != KRB5_PLUGIN_OP_NOTSUPP)
return errcode_to_protocol(ret);
- /* Check against local policy. */
- errcode = against_local_policy_as(request, client, server,
- kdc_time, status, e_data);
- if (errcode)
- return errcode;
-
return 0;
}
@@ -1220,8 +1213,10 @@ kdc_process_for_user(kdc_realm_t *kdc_active_realm,
req_data.data = (char *)pa_data->contents;
code = decode_krb5_pa_for_user(&req_data, &for_user);
- if (code)
+ if (code) {
+ *status = "DECODE_PA_FOR_USER";
return code;
+ }
code = verify_for_user_checksum(kdc_context, tgs_session, for_user);
if (code) {
@@ -1320,8 +1315,10 @@ kdc_process_s4u_x509_user(krb5_context context,
req_data.data = (char *)pa_data->contents;
code = decode_krb5_pa_s4u_x509_user(&req_data, s4u_x509_user);
- if (code)
+ if (code) {
+ *status = "DECODE_PA_S4U_X509_USER";
return code;
+ }
code = verify_s4u_x509_user_checksum(context,
tgs_subkey ? tgs_subkey :
@@ -1624,6 +1621,7 @@ kdc_process_s4u2proxy_req(kdc_realm_t *kdc_active_realm,
* that is validated previously in validate_tgs_request().
*/
if (request->kdc_options & (NON_TGT_OPTION | KDC_OPT_ENC_TKT_IN_SKEY)) {
+ *status = "INVALID_S4U2PROXY_OPTIONS";
return KRB5KDC_ERR_BADOPTION;
}
@@ -1631,6 +1629,7 @@ kdc_process_s4u2proxy_req(kdc_realm_t *kdc_active_realm,
if (!krb5_principal_compare(kdc_context,
server->princ, /* after canon */
server_princ)) {
+ *status = "EVIDENCE_TICKET_MISMATCH";
return KRB5KDC_ERR_SERVER_NOMATCH;
}
@@ -1760,14 +1759,19 @@ kdc_get_ticket_endtime(kdc_realm_t *kdc_active_realm,
krb5_db_entry *server,
krb5_timestamp *out_endtime)
{
- krb5_timestamp until, life;
+ krb5_timestamp until;
+ krb5_deltat life;
if (till == 0)
till = kdc_infinity;
- until = min(till, endtime);
+ until = ts_min(till, endtime);
- life = until - starttime;
+ /* Determine the requested lifetime, capped at the maximum valid time
+ * interval. */
+ life = ts_delta(until, starttime);
+ if (ts_after(until, starttime) && life < 0)
+ life = INT32_MAX;
if (client != NULL && client->max_life != 0)
life = min(life, client->max_life);
@@ -1776,7 +1780,7 @@ kdc_get_ticket_endtime(kdc_realm_t *kdc_active_realm,
if (kdc_active_realm->realm_maxlife != 0)
life = min(life, kdc_active_realm->realm_maxlife);
- *out_endtime = starttime + life;
+ *out_endtime = ts_incr(starttime, life);
}
/*
@@ -1791,6 +1795,7 @@ kdc_get_ticket_renewtime(kdc_realm_t *realm, krb5_kdc_req *request,
{
krb5_timestamp rtime, max_rlife;
+ clear(tkt->flags, TKT_FLG_RENEWABLE);
tkt->times.renew_till = 0;
/* Don't issue renewable tickets if the client or server don't allow it,
@@ -1806,25 +1811,27 @@ kdc_get_ticket_renewtime(kdc_realm_t *realm, krb5_kdc_req *request,
if (isflagset(request->kdc_options, KDC_OPT_RENEWABLE))
rtime = request->rtime ? request->rtime : kdc_infinity;
else if (isflagset(request->kdc_options, KDC_OPT_RENEWABLE_OK) &&
- tkt->times.endtime < request->till)
+ ts_after(request->till, tkt->times.endtime))
rtime = request->till;
else
return;
/* Truncate it to the allowable renewable time. */
if (tgt != NULL)
- rtime = min(rtime, tgt->times.renew_till);
+ rtime = ts_min(rtime, tgt->times.renew_till);
max_rlife = min(server->max_renewable_life, realm->realm_maxrlife);
if (client != NULL)
max_rlife = min(max_rlife, client->max_renewable_life);
- rtime = min(rtime, tkt->times.starttime + max_rlife);
+ rtime = ts_min(rtime, ts_incr(tkt->times.starttime, max_rlife));
- /* Make the ticket renewable if the truncated requested time is larger than
- * the ticket end time. */
- if (rtime > tkt->times.endtime) {
- setflag(tkt->flags, TKT_FLG_RENEWABLE);
- tkt->times.renew_till = rtime;
- }
+ /* If the client only specified renewable-ok, don't issue a renewable
+ * ticket unless the truncated renew time exceeds the ticket end time. */
+ if (!isflagset(request->kdc_options, KDC_OPT_RENEWABLE) &&
+ !ts_after(rtime, tkt->times.endtime))
+ return;
+
+ setflag(tkt->flags, TKT_FLG_RENEWABLE);
+ tkt->times.renew_till = rtime;
}
/**
diff --git a/src/kdc/kdc_util.h b/src/kdc/kdc_util.h
index bcf05fc2779f..f99efcf505d1 100644
--- a/src/kdc/kdc_util.h
+++ b/src/kdc/kdc_util.h
@@ -140,7 +140,7 @@ cammac_check_kdcver(krb5_context context, krb5_cammac *cammac,
/* do_as_req.c */
void
process_as_req (krb5_kdc_req *, krb5_data *,
- const krb5_fulladdr *, kdc_realm_t *,
+ const krb5_fulladdr *, const krb5_fulladdr *, kdc_realm_t *,
verto_ctx *, loop_respond_fn, void *);
/* do_tgs_req.c */
@@ -151,7 +151,7 @@ process_tgs_req (struct server_handle *, krb5_data *,
/* dispatch.c */
void
dispatch (void *,
- struct sockaddr *,
+ const krb5_fulladdr *,
const krb5_fulladdr *,
krb5_data *,
int,
@@ -166,17 +166,6 @@ kdc_err(krb5_context call_context, errcode_t code, const char *fmt, ...)
#endif
;
-/* policy.c */
-int
-against_local_policy_as (krb5_kdc_req *, krb5_db_entry,
- krb5_db_entry, krb5_timestamp,
- const char **, krb5_pa_data ***);
-
-int
-against_local_policy_tgs (krb5_kdc_req *, krb5_db_entry,
- krb5_ticket *, const char **,
- krb5_pa_data ***);
-
/* kdc_preauth.c */
krb5_boolean
enctype_requires_etype_info_2(krb5_enctype enctype);
@@ -346,7 +335,9 @@ kdc_get_ticket_renewtime(kdc_realm_t *realm, krb5_kdc_req *request,
krb5_db_entry *server, krb5_enc_tkt_part *tkt);
void
-log_as_req(krb5_context context, const krb5_fulladdr *from,
+log_as_req(krb5_context context,
+ const krb5_fulladdr *local_addr,
+ const krb5_fulladdr *remote_addr,
krb5_kdc_req *request, krb5_kdc_rep *reply,
krb5_db_entry *client, const char *cname,
krb5_db_entry *server, const char *sname,
@@ -452,6 +443,8 @@ struct krb5_kdcpreauth_rock_st {
#define max(a, b) ((a) > (b) ? (a) : (b))
#endif
+#define ts_min(a, b) (ts_after(a, b) ? (b) : (a))
+
#define ADDRTYPE2FAMILY(X) \
((X) == ADDRTYPE_INET6 ? AF_INET6 : (X) == ADDRTYPE_INET ? AF_INET : -1)
diff --git a/src/kdc/main.c b/src/kdc/main.c
index ebc852bba2e9..f2226da2597f 100644
--- a/src/kdc/main.c
+++ b/src/kdc/main.c
@@ -31,6 +31,7 @@
#include "kdc_util.h"
#include "kdc_audit.h"
#include "extern.h"
+#include "policy.h"
#include "kdc5_err.h"
#include "kdb_kt.h"
#include "net-server.h"
@@ -986,6 +987,12 @@ int main(int argc, char **argv)
load_preauth_plugins(&shandle, kcontext, ctx);
load_authdata_plugins(kcontext);
+ retval = load_kdcpolicy_plugins(kcontext);
+ if (retval) {
+ kdc_err(kcontext, retval, _("while loading KDC policy plugin"));
+ finish_realms();
+ return 1;
+ }
retval = setup_sam();
if (retval) {
@@ -1068,6 +1075,7 @@ int main(int argc, char **argv)
krb5_klog_syslog(LOG_INFO, _("shutting down"));
unload_preauth_plugins(kcontext);
unload_authdata_plugins(kcontext);
+ unload_kdcpolicy_plugins(kcontext);
unload_audit_modules(kcontext);
krb5_klog_close(kcontext);
finish_realms();
diff --git a/src/kdc/policy.c b/src/kdc/policy.c
index 6cba4303f81d..26c16f97cb53 100644
--- a/src/kdc/policy.c
+++ b/src/kdc/policy.c
@@ -1,67 +1,246 @@
/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
/* kdc/policy.c - Policy decision routines for KDC */
/*
- * Copyright 1990 by the Massachusetts Institute of Technology.
+ * Copyright (C) 2017 by Red Hat, Inc.
+ * All rights reserved.
*
- * Export of this software from the United States of America may
- * require a specific license from the United States Government.
- * It is the responsibility of any person or organization contemplating
- * export to obtain such a license before exporting.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
*
- * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
- * distribute this software and its documentation for any purpose and
- * without fee is hereby granted, provided that the above copyright
- * notice appear in all copies and that both that copyright notice and
- * this permission notice appear in supporting documentation, and that
- * the name of M.I.T. not be used in advertising or publicity pertaining
- * to distribution of the software without specific, written prior
- * permission. Furthermore if you modify this software you must label
- * your software as modified software and not distribute it in such a
- * fashion that it might be confused with the original M.I.T. software.
- * M.I.T. makes no representations about the suitability of
- * this software for any purpose. It is provided "as is" without express
- * or implied warranty.
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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
+ * COPYRIGHT HOLDER 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 "k5-int.h"
#include "kdc_util.h"
#include "extern.h"
+#include "policy.h"
+#include "adm_proto.h"
+#include <krb5/kdcpolicy_plugin.h>
+#include <syslog.h>
+
+typedef struct kdcpolicy_handle_st {
+ struct krb5_kdcpolicy_vtable_st vt;
+ krb5_kdcpolicy_moddata moddata;
+} *kdcpolicy_handle;
+
+static kdcpolicy_handle *handles;
+
+static void
+free_indicators(char **ais)
+{
+ size_t i;
-int
-against_local_policy_as(register krb5_kdc_req *request, krb5_db_entry client,
- krb5_db_entry server, krb5_timestamp kdc_time,
- const char **status, krb5_pa_data ***e_data)
+ if (ais == NULL)
+ return;
+ for (i = 0; ais[i] != NULL; i++)
+ free(ais[i]);
+ free(ais);
+}
+
+/* Convert inds to a null-terminated list of C strings. */
+static krb5_error_code
+authind_strings(krb5_data *const *inds, char ***strs_out)
{
-#if 0
- /* An AS request must include the addresses field */
- if (request->addresses == 0) {
- *status = "NO ADDRESS";
- return KRB5KDC_ERR_POLICY;
+ krb5_error_code ret;
+ char **list = NULL;
+ size_t i, count;
+
+ *strs_out = NULL;
+
+ for (count = 0; inds != NULL && inds[count] != NULL; count++);
+ list = k5calloc(count + 1, sizeof(*list), &ret);
+ if (list == NULL)
+ goto error;
+
+ for (i = 0; i < count; i++) {
+ list[i] = k5memdup0(inds[i]->data, inds[i]->length, &ret);
+ if (list[i] == NULL)
+ goto error;
}
-#endif
- return 0; /* not against policy */
+ *strs_out = list;
+ return 0;
+
+error:
+ free_indicators(list);
+ return ret;
+}
+
+/* Constrain times->endtime to life and times->renew_till to rlife, relative to
+ * now. */
+static void
+update_ticket_times(krb5_ticket_times *times, krb5_timestamp now,
+ krb5_deltat life, krb5_deltat rlife)
+{
+ if (life)
+ times->endtime = ts_min(ts_incr(now, life), times->endtime);
+ if (rlife)
+ times->renew_till = ts_min(ts_incr(now, rlife), times->renew_till);
+}
+
+/* Check an AS request against kdcpolicy modules, updating times with any
+ * module endtime constraints. Set an appropriate status string on error. */
+krb5_error_code
+check_kdcpolicy_as(krb5_context context, const krb5_kdc_req *request,
+ const krb5_db_entry *client, const krb5_db_entry *server,
+ krb5_data *const *auth_indicators, krb5_timestamp kdc_time,
+ krb5_ticket_times *times, const char **status)
+{
+ krb5_deltat life, rlife;
+ krb5_error_code ret;
+ kdcpolicy_handle *hp, h;
+ char **ais = NULL;
+
+ *status = NULL;
+
+ ret = authind_strings(auth_indicators, &ais);
+ if (ret)
+ goto done;
+
+ for (hp = handles; *hp != NULL; hp++) {
+ h = *hp;
+ if (h->vt.check_as == NULL)
+ continue;
+
+ ret = h->vt.check_as(context, h->moddata, request, client, server,
+ (const char **)ais, status, &life, &rlife);
+ if (ret)
+ goto done;
+
+ update_ticket_times(times, kdc_time, life, rlife);
+ }
+
+done:
+ free_indicators(ais);
+ return ret;
}
/*
- * This is where local policy restrictions for the TGS should placed.
+ * Check the TGS request against the local TGS policy. Accepts an
+ * authentication indicator for the module policy decisions. Returns 0 and a
+ * NULL status string on success.
*/
krb5_error_code
-against_local_policy_tgs(register krb5_kdc_req *request, krb5_db_entry server,
- krb5_ticket *ticket, const char **status,
- krb5_pa_data ***e_data)
+check_kdcpolicy_tgs(krb5_context context, const krb5_kdc_req *request,
+ const krb5_db_entry *server, const krb5_ticket *ticket,
+ krb5_data *const *auth_indicators, krb5_timestamp kdc_time,
+ krb5_ticket_times *times, const char **status)
{
-#if 0
- /*
- * For example, if your site wants to disallow ticket forwarding,
- * you might do something like this:
- */
-
- if (isflagset(request->kdc_options, KDC_OPT_FORWARDED)) {
- *status = "FORWARD POLICY";
- return KRB5KDC_ERR_POLICY;
+ krb5_deltat life, rlife;
+ krb5_error_code ret;
+ kdcpolicy_handle *hp, h;
+ char **ais = NULL;
+
+ *status = NULL;
+
+ ret = authind_strings(auth_indicators, &ais);
+ if (ret)
+ goto done;
+
+ for (hp = handles; *hp != NULL; hp++) {
+ h = *hp;
+ if (h->vt.check_tgs == NULL)
+ continue;
+
+ ret = h->vt.check_tgs(context, h->moddata, request, server, ticket,
+ (const char **)ais, status, &life, &rlife);
+ if (ret)
+ goto done;
+
+ update_ticket_times(times, kdc_time, life, rlife);
}
-#endif
- return 0; /* not against policy */
+done:
+ free_indicators(ais);
+ return ret;
+}
+
+void
+unload_kdcpolicy_plugins(krb5_context context)
+{
+ kdcpolicy_handle *hp, h;
+
+ for (hp = handles; *hp != NULL; hp++) {
+ h = *hp;
+ if (h->vt.fini != NULL)
+ h->vt.fini(context, h->moddata);
+ free(h);
+ }
+ free(handles);
+ handles = NULL;
+}
+
+krb5_error_code
+load_kdcpolicy_plugins(krb5_context context)
+{
+ krb5_error_code ret;
+ krb5_plugin_initvt_fn *modules = NULL, *mod;
+ kdcpolicy_handle h;
+ size_t count;
+
+ ret = k5_plugin_load_all(context, PLUGIN_INTERFACE_KDCPOLICY, &modules);
+ if (ret)
+ goto cleanup;
+
+ for (count = 0; modules[count] != NULL; count++);
+ handles = k5calloc(count + 1, sizeof(*handles), &ret);
+ if (handles == NULL)
+ goto cleanup;
+
+ count = 0;
+ for (mod = modules; *mod != NULL; mod++) {
+ h = k5calloc(1, sizeof(*h), &ret);
+ if (h == NULL)
+ goto cleanup;
+
+ ret = (*mod)(context, 1, 1, (krb5_plugin_vtable)&h->vt);
+ if (ret) { /* Version mismatch. */
+ TRACE_KDCPOLICY_VTINIT_FAIL(context, ret);
+ free(h);
+ continue;
+ }
+ if (h->vt.init != NULL) {
+ ret = h->vt.init(context, &h->moddata);
+ if (ret == KRB5_PLUGIN_NO_HANDLE) {
+ TRACE_KDCPOLICY_INIT_SKIP(context, h->vt.name);
+ free(h);
+ continue;
+ }
+ if (ret) {
+ kdc_err(context, ret, _("while loading policy module %s"),
+ h->vt.name);
+ free(h);
+ goto cleanup;
+ }
+ }
+ handles[count++] = h;
+ }
+
+ ret = 0;
+
+cleanup:
+ if (ret)
+ unload_kdcpolicy_plugins(context);
+ k5_plugin_free_modules(context, modules);
+ return ret;
}
diff --git a/src/kdc/policy.h b/src/kdc/policy.h
index 6b000dc90346..2a57b0a01683 100644
--- a/src/kdc/policy.h
+++ b/src/kdc/policy.h
@@ -26,11 +26,22 @@
#ifndef __KRB5_KDC_POLICY__
#define __KRB5_KDC_POLICY__
-extern int against_postdate_policy (krb5_timestamp);
+krb5_error_code
+load_kdcpolicy_plugins(krb5_context context);
-extern int against_flag_policy_as (const krb5_kdc_req *);
+void
+unload_kdcpolicy_plugins(krb5_context context);
-extern int against_flag_policy_tgs (const krb5_kdc_req *,
- const krb5_ticket *);
+krb5_error_code
+check_kdcpolicy_as(krb5_context context, const krb5_kdc_req *request,
+ const krb5_db_entry *client, const krb5_db_entry *server,
+ krb5_data *const *auth_indicators, krb5_timestamp kdc_time,
+ krb5_ticket_times *times, const char **status);
+
+krb5_error_code
+check_kdcpolicy_tgs(krb5_context context, const krb5_kdc_req *request,
+ const krb5_db_entry *server, const krb5_ticket *ticket,
+ krb5_data *const *auth_indicators, krb5_timestamp kdc_time,
+ krb5_ticket_times *times, const char **status);
#endif /* __KRB5_KDC_POLICY__ */
diff --git a/src/kdc/replay.c b/src/kdc/replay.c
index 8da7ac19aef3..caca783bf1ab 100644
--- a/src/kdc/replay.c
+++ b/src/kdc/replay.c
@@ -61,7 +61,7 @@ static size_t total_size = 0;
static krb5_ui_4 seed;
#define STALE_TIME (2*60) /* two minutes */
-#define STALE(ptr, now) (abs((ptr)->timein - (now)) >= STALE_TIME)
+#define STALE(ptr, now) (ts_after(now, ts_incr((ptr)->timein, STALE_TIME)))
/* Return x rotated to the left by r bits. */
static inline krb5_ui_4
diff --git a/src/kdc/t_emptytgt.py b/src/kdc/t_emptytgt.py
index 8f7717a011c2..2d0432e338ac 100755
--- a/src/kdc/t_emptytgt.py
+++ b/src/kdc/t_emptytgt.py
@@ -2,7 +2,6 @@
from k5test import *
realm = K5Realm(create_host=False)
-output = realm.run([kvno, 'krbtgt/'], expected_code=1)
-if 'not found in Kerberos database' not in output:
- fail('TGT lookup for empty realm failed in unexpected way')
+realm.run([kvno, 'krbtgt/'], expected_code=1,
+ expected_msg='not found in Kerberos database')
success('Empty tgt lookup.')
diff --git a/src/kdc/t_replay.c b/src/kdc/t_replay.c
index 1442e0e8ceee..00bb39012680 100644
--- a/src/kdc/t_replay.c
+++ b/src/kdc/t_replay.c
@@ -36,10 +36,7 @@
#ifndef NOCACHE
-#include <stdarg.h>
-#include <stddef.h>
-#include <setjmp.h>
-#include <cmocka.h>
+#include "k5-cmocka.h"
/* For wrapping functions */
#include "k5-int.h"
@@ -623,6 +620,8 @@ test_kdc_check_lookaside_hit(void **state)
assert_true(data_eq(rep, *result_data));
assert_int_equal(hits, 1);
assert_int_equal(e->num_hits, 1);
+
+ krb5_free_data(context, result_data);
}
static void
@@ -700,6 +699,8 @@ test_kdc_check_lookaside_hit_multiple(void **state)
assert_int_equal(e1->num_hits, 1);
assert_int_equal(e2->num_hits, 0);
+ krb5_free_data(context, result_data);
+
/* Set result_data so we can verify that it is reset to NULL. */
result_data = &req1;
result = kdc_check_lookaside(context, &req2, &result_data);
@@ -733,6 +734,8 @@ test_kdc_check_lookaside_hit_hash_collision(void **state)
assert_int_equal(e1->num_hits, 1);
assert_int_equal(e2->num_hits, 0);
+ krb5_free_data(context, result_data);
+
/* Set result_data so we can verify that it is reset to NULL. */
result_data = &req1;
result = kdc_check_lookaside(context, &req2, &result_data);
@@ -903,7 +906,7 @@ test_kdc_insert_lookaside_cache_expire(void **state)
assert_non_null(e);
e->num_hits = 5;
- time_return(STALE_TIME, 0);
+ time_return(STALE_TIME + 1, 0);
kdc_insert_lookaside(context, &req2, NULL);
assert_null(K5_LIST_FIRST(&hash_table[req_hash1]));
diff --git a/src/kdc/tgs_policy.c b/src/kdc/tgs_policy.c
index a30cacc665a1..33cfbcd8184f 100644
--- a/src/kdc/tgs_policy.c
+++ b/src/kdc/tgs_policy.c
@@ -186,7 +186,7 @@ static int
check_tgs_svc_time(krb5_kdc_req *req, krb5_db_entry server, krb5_ticket *tkt,
krb5_timestamp kdc_time, const char **status)
{
- if (server.expiration && server.expiration < kdc_time) {
+ if (server.expiration && ts_after(kdc_time, server.expiration)) {
*status = "SERVICE EXPIRED";
return KDC_ERR_SERVICE_EXP;
}
@@ -222,7 +222,7 @@ check_tgs_times(krb5_kdc_req *req, krb5_ticket_times *times,
KDC time. */
if (req->kdc_options & KDC_OPT_VALIDATE) {
starttime = times->starttime ? times->starttime : times->authtime;
- if (starttime > kdc_time) {
+ if (ts_after(starttime, kdc_time)) {
*status = "NOT_YET_VALID";
return KRB_AP_ERR_TKT_NYV;
}
@@ -231,7 +231,8 @@ check_tgs_times(krb5_kdc_req *req, krb5_ticket_times *times,
* Check the renew_till time. The endtime was already
* been checked in the initial authentication check.
*/
- if ((req->kdc_options & KDC_OPT_RENEW) && times->renew_till < kdc_time) {
+ if ((req->kdc_options & KDC_OPT_RENEW) &&
+ ts_after(kdc_time, times->renew_till)) {
*status = "TKT_EXPIRED";
return KRB_AP_ERR_TKT_EXPIRED;
}
@@ -374,11 +375,5 @@ validate_tgs_request(kdc_realm_t *kdc_active_realm,
if (ret && ret != KRB5_PLUGIN_OP_NOTSUPP)
return errcode_to_protocol(ret);
- /* Check local policy. */
- errcode = against_local_policy_tgs(request, server, ticket,
- status, e_data);
- if (errcode)
- return errcode;
-
return 0;
}
diff --git a/src/lib/apputils/net-server.c b/src/lib/apputils/net-server.c
index 29ec84a15b22..a40da927ef16 100644
--- a/src/lib/apputils/net-server.c
+++ b/src/lib/apputils/net-server.c
@@ -105,17 +105,6 @@ paddr(struct sockaddr *sa)
return buf;
}
-/* Return true if sa is an IPv4 or IPv6 wildcard address. */
-static int
-is_wildcard(struct sockaddr *sa)
-{
- if (sa->sa_family == AF_INET6)
- return IN6_IS_ADDR_UNSPECIFIED(&sa2sin6(sa)->sin6_addr);
- else if (sa->sa_family == AF_INET)
- return sa2sin(sa)->sin_addr.s_addr == INADDR_ANY;
- return 0;
-}
-
/* KDC data. */
enum conn_type {
@@ -142,8 +131,8 @@ struct connection {
struct sockaddr_storage addr_s;
socklen_t addrlen;
char addrbuf[56];
- krb5_fulladdr faddr;
- krb5_address kaddr;
+ krb5_address remote_addr_buf;
+ krb5_fulladdr remote_addr;
/* Incoming data (TCP) */
size_t bufsiz;
@@ -451,14 +440,6 @@ loop_add_rpc_service(int default_port, const char *addresses, u_long prognum,
#define SOCKET_ERRNO errno
#include "foreachaddr.h"
-struct socksetup {
- verto_ctx *ctx;
- void *handle;
- const char *prog;
- krb5_error_code retval;
- int listen_backlog;
-};
-
static void
free_connection(struct connection *conn)
{
@@ -533,7 +514,7 @@ free_socket(verto_ctx *ctx, verto_ev *ev)
static verto_ev *
make_event(verto_ctx *ctx, verto_ev_flag flags, verto_callback callback,
- int sock, struct connection *conn, int addevent)
+ int sock, struct connection *conn)
{
verto_ev *ev;
void *tmp;
@@ -544,45 +525,44 @@ make_event(verto_ctx *ctx, verto_ev_flag flags, verto_callback callback,
return NULL;
}
- if (addevent) {
- if (!ADD(events, ev, tmp)) {
- com_err(conn->prog, ENOMEM, _("cannot save event"));
- verto_del(ev);
- return NULL;
- }
+ if (!ADD(events, ev, tmp)) {
+ com_err(conn->prog, ENOMEM, _("cannot save event"));
+ verto_del(ev);
+ return NULL;
}
verto_set_private(ev, conn, free_socket);
return ev;
}
-static verto_ev *
-add_fd(struct socksetup *data, int sock, enum conn_type conntype,
- verto_ev_flag flags, verto_callback callback, int addevent)
+static krb5_error_code
+add_fd(int sock, enum conn_type conntype, verto_ev_flag flags, void *handle,
+ const char *prog, verto_ctx *ctx, verto_callback callback,
+ verto_ev **ev_out)
{
struct connection *newconn;
+ *ev_out = NULL;
+
#ifndef _WIN32
if (sock >= FD_SETSIZE) {
- data->retval = EMFILE; /* XXX */
- com_err(data->prog, 0,
- _("file descriptor number %d too high"), sock);
- return 0;
+ com_err(prog, 0, _("file descriptor number %d too high"), sock);
+ return EMFILE;
}
#endif
newconn = malloc(sizeof(*newconn));
if (newconn == NULL) {
- data->retval = ENOMEM;
- com_err(data->prog, ENOMEM,
+ com_err(prog, ENOMEM,
_("cannot allocate storage for connection info"));
- return 0;
+ return ENOMEM;
}
memset(newconn, 0, sizeof(*newconn));
- newconn->handle = data->handle;
- newconn->prog = data->prog;
+ newconn->handle = handle;
+ newconn->prog = prog;
newconn->type = conntype;
- return make_event(data->ctx, flags, callback, sock, newconn, addevent);
+ *ev_out = make_event(ctx, flags, callback, sock, newconn);
+ return 0;
}
static void process_packet(verto_ctx *ctx, verto_ev *ev);
@@ -592,77 +572,62 @@ static void process_tcp_connection_write(verto_ctx *ctx, verto_ev *ev);
static void accept_rpc_connection(verto_ctx *ctx, verto_ev *ev);
static void process_rpc_connection(verto_ctx *ctx, verto_ev *ev);
-static verto_ev *
-add_tcp_read_fd(struct socksetup *data, int sock)
-{
- return add_fd(data, sock, CONN_TCP,
- VERTO_EV_FLAG_IO_READ | VERTO_EV_FLAG_PERSIST,
- process_tcp_connection_read, 1);
-}
-
/*
* Create a socket and bind it to addr. Ensure the socket will work with
* select(). Set the socket cloexec, reuseaddr, and if applicable v6-only.
- * Does not call listen(). Returns -1 on failure after logging an error.
+ * Does not call listen(). On failure, log an error and return an error code.
*/
-static int
-create_server_socket(struct socksetup *data, struct sockaddr *addr, int type)
+static krb5_error_code
+create_server_socket(struct sockaddr *addr, int type, const char *prog,
+ int *fd_out)
{
- int sock;
+ int sock, e;
+
+ *fd_out = -1;
sock = socket(addr->sa_family, type, 0);
if (sock == -1) {
- data->retval = errno;
- com_err(data->prog, errno, _("Cannot create TCP server socket on %s"),
+ e = errno;
+ com_err(prog, e, _("Cannot create TCP server socket on %s"),
paddr(addr));
- return -1;
+ return e;
}
set_cloexec_fd(sock);
#ifndef _WIN32 /* Windows FD_SETSIZE is a count. */
if (sock >= FD_SETSIZE) {
close(sock);
- com_err(data->prog, 0, _("TCP socket fd number %d (for %s) too high"),
+ com_err(prog, 0, _("TCP socket fd number %d (for %s) too high"),
sock, paddr(addr));
- return -1;
+ return EMFILE;
}
#endif
- if (setreuseaddr(sock, 1) < 0) {
- com_err(data->prog, errno,
- _("Cannot enable SO_REUSEADDR on fd %d"), sock);
- }
+ if (setreuseaddr(sock, 1) < 0)
+ com_err(prog, errno, _("Cannot enable SO_REUSEADDR on fd %d"), sock);
if (addr->sa_family == AF_INET6) {
#ifdef IPV6_V6ONLY
- if (setv6only(sock, 1))
- com_err(data->prog, errno,
- _("setsockopt(%d,IPV6_V6ONLY,1) failed"), sock);
- else
- com_err(data->prog, 0, _("setsockopt(%d,IPV6_V6ONLY,1) worked"),
+ if (setv6only(sock, 1)) {
+ com_err(prog, errno, _("setsockopt(%d,IPV6_V6ONLY,1) failed"),
sock);
+ } else {
+ com_err(prog, 0, _("setsockopt(%d,IPV6_V6ONLY,1) worked"), sock);
+ }
#else
krb5_klog_syslog(LOG_INFO, _("no IPV6_V6ONLY socket option support"));
#endif /* IPV6_V6ONLY */
}
if (bind(sock, addr, sa_socklen(addr)) == -1) {
- data->retval = errno;
- com_err(data->prog, errno, _("Cannot bind server socket on %s"),
- paddr(addr));
+ e = errno;
+ com_err(prog, e, _("Cannot bind server socket on %s"), paddr(addr));
close(sock);
- return -1;
+ return e;
}
- return sock;
-}
-
-static verto_ev *
-add_rpc_data_fd(struct socksetup *data, int sock)
-{
- return add_fd(data, sock, CONN_RPC,
- VERTO_EV_FLAG_IO_READ | VERTO_EV_FLAG_PERSIST,
- process_rpc_connection, 1);
+ *fd_out = sock;
+ return 0;
}
static const int one = 1;
@@ -716,12 +681,13 @@ static const enum conn_type bind_conn_types[] =
* The conn_type of this socket.
*/
static krb5_error_code
-setup_socket(struct socksetup *data, struct bind_address *ba,
- struct sockaddr *sock_address, verto_callback vcb,
- enum conn_type ctype)
+setup_socket(struct bind_address *ba, struct sockaddr *sock_address,
+ void *handle, const char *prog, verto_ctx *ctx,
+ int tcp_listen_backlog, verto_callback vcb, enum conn_type ctype)
{
krb5_error_code ret;
struct connection *conn;
+ verto_ev_flag flags;
verto_ev *ev = NULL;
int sock = -1;
@@ -729,18 +695,16 @@ setup_socket(struct socksetup *data, struct bind_address *ba,
bind_type_names[ba->type], paddr(sock_address));
/* Create the socket. */
- sock = create_server_socket(data, sock_address, bind_socktypes[ba->type]);
- if (sock == -1) {
- ret = data->retval;
+ ret = create_server_socket(sock_address, bind_socktypes[ba->type], prog,
+ &sock);
+ if (ret)
goto cleanup;
- }
/* Listen for backlogged connections on TCP sockets. (For RPC sockets this
* will be done by svc_register().) */
- if (ba->type == TCP && listen(sock, data->listen_backlog) != 0) {
+ if (ba->type == TCP && listen(sock, tcp_listen_backlog) != 0) {
ret = errno;
- com_err(data->prog, errno,
- _("Cannot listen on %s server socket on %s"),
+ com_err(prog, errno, _("Cannot listen on %s server socket on %s"),
bind_type_names[ba->type], paddr(sock_address));
goto cleanup;
}
@@ -748,7 +712,7 @@ setup_socket(struct socksetup *data, struct bind_address *ba,
/* Set non-blocking I/O for UDP and TCP listener sockets. */
if (ba->type != RPC && setnbio(sock) != 0) {
ret = errno;
- com_err(data->prog, errno,
+ com_err(prog, errno,
_("cannot set listening %s socket on %s non-blocking"),
bind_type_names[ba->type], paddr(sock_address));
goto cleanup;
@@ -757,19 +721,18 @@ setup_socket(struct socksetup *data, struct bind_address *ba,
/* Turn off the linger option for TCP sockets. */
if (ba->type == TCP && setnolinger(sock) != 0) {
ret = errno;
- com_err(data->prog, errno,
- _("cannot set SO_LINGER on %s socket on %s"),
+ com_err(prog, errno, _("cannot set SO_LINGER on %s socket on %s"),
bind_type_names[ba->type], paddr(sock_address));
goto cleanup;
}
/* Try to turn on pktinfo for UDP wildcard sockets. */
- if (ba->type == UDP && is_wildcard(sock_address)) {
+ if (ba->type == UDP && sa_is_wildcard(sock_address)) {
krb5_klog_syslog(LOG_DEBUG, _("Setting pktinfo on socket %s"),
paddr(sock_address));
ret = set_pktinfo(sock, sock_address->sa_family);
if (ret) {
- com_err(data->prog, ret,
+ com_err(prog, ret,
_("Cannot request packet info for UDP socket address "
"%s port %d"), paddr(sock_address), ba->port);
krb5_klog_syslog(LOG_INFO, _("System does not support pktinfo yet "
@@ -780,13 +743,11 @@ setup_socket(struct socksetup *data, struct bind_address *ba,
}
/* Add the socket to the event loop. */
- ev = add_fd(data, sock, ctype,
- VERTO_EV_FLAG_IO_READ |
- VERTO_EV_FLAG_PERSIST |
- VERTO_EV_FLAG_REINITIABLE, vcb, 1);
- if (ev == NULL) {
+ flags = VERTO_EV_FLAG_IO_READ | VERTO_EV_FLAG_PERSIST |
+ VERTO_EV_FLAG_REINITIABLE;
+ ret = add_fd(sock, ctype, flags, handle, prog, ctx, vcb, &ev);
+ if (ret) {
krb5_klog_syslog(LOG_ERR, _("Error attempting to add verto event"));
- ret = data->retval;
goto cleanup;
}
@@ -829,13 +790,10 @@ cleanup:
* This function uses getaddrinfo to figure out all the addresses. This will
* automatically figure out which socket families that should be used on the
* host making it useful even for wildcard addresses.
- *
- * Arguments:
- * - data
- * A pointer to the socksetup data.
*/
static krb5_error_code
-setup_addresses(struct socksetup *data)
+setup_addresses(verto_ctx *ctx, void *handle, const char *prog,
+ int tcp_listen_backlog)
{
/* An bind_type enum map for the verto callback functions. */
static verto_callback *const verto_callbacks[] = {
@@ -896,8 +854,8 @@ setup_addresses(struct socksetup *data)
/* Set the real port number. */
sa_setport(ai->ai_addr, addr.port);
- ret = setup_socket(data, &addr, ai->ai_addr,
- verto_callbacks[addr.type],
+ ret = setup_socket(&addr, ai->ai_addr, handle, prog, ctx,
+ tcp_listen_backlog, verto_callbacks[addr.type],
bind_conn_types[addr.type]);
if (ret) {
krb5_klog_syslog(LOG_ERR,
@@ -929,9 +887,9 @@ krb5_error_code
loop_setup_network(verto_ctx *ctx, void *handle, const char *prog,
int tcp_listen_backlog)
{
- struct socksetup setup_data;
+ krb5_error_code ret;
verto_ev *ev;
- int i, ret;
+ int i;
/* Check to make sure that at least one address was added to the loop. */
if (bind_addresses.n == 0)
@@ -942,15 +900,9 @@ loop_setup_network(verto_ctx *ctx, void *handle, const char *prog,
verto_del(ev);
events.n = 0;
- setup_data.ctx = ctx;
- setup_data.handle = handle;
- setup_data.prog = prog;
- setup_data.retval = 0;
- setup_data.listen_backlog = tcp_listen_backlog;
-
krb5_klog_syslog(LOG_INFO, _("setting up network..."));
- ret = setup_addresses(&setup_data);
- if (ret != 0) {
+ ret = setup_addresses(ctx, handle, prog, tcp_listen_backlog);
+ if (ret) {
com_err(prog, ret, _("Error setting up network"));
exit(1);
}
@@ -999,8 +951,10 @@ struct udp_dispatch_state {
void *handle;
const char *prog;
int port_fd;
- krb5_address addr;
- krb5_fulladdr faddr;
+ krb5_address remote_addr_buf;
+ krb5_fulladdr remote_addr;
+ krb5_address local_addr_buf;
+ krb5_fulladdr local_addr;
socklen_t saddr_len;
socklen_t daddr_len;
struct sockaddr_storage saddr;
@@ -1132,10 +1086,15 @@ process_packet(verto_ctx *ctx, verto_ev *ev)
state->request.length = cc;
state->request.data = state->pktbuf;
- state->faddr.address = &state->addr;
- init_addr(&state->faddr, ss2sa(&state->saddr));
+
+ state->remote_addr.address = &state->remote_addr_buf;
+ init_addr(&state->remote_addr, ss2sa(&state->saddr));
+
+ state->local_addr.address = &state->local_addr_buf;
+ init_addr(&state->local_addr, ss2sa(&state->daddr));
+
/* This address is in net order. */
- dispatch(state->handle, ss2sa(&state->daddr), &state->faddr,
+ dispatch(state->handle, &state->local_addr, &state->remote_addr,
&state->request, 0, ctx, process_packet_response, state);
}
@@ -1186,9 +1145,9 @@ accept_tcp_connection(verto_ctx *ctx, verto_ev *ev)
struct sockaddr_storage addr_s;
struct sockaddr *addr = (struct sockaddr *)&addr_s;
socklen_t addrlen = sizeof(addr_s);
- struct socksetup sockdata;
struct connection *newconn, *conn;
char tmpbuf[10];
+ verto_ev_flag flags;
verto_ev *newev;
conn = verto_get_private(ev);
@@ -1204,13 +1163,9 @@ accept_tcp_connection(verto_ctx *ctx, verto_ev *ev)
#endif
setnbio(s), setnolinger(s), setkeepalive(s);
- sockdata.ctx = ctx;
- sockdata.handle = conn->handle;
- sockdata.prog = conn->prog;
- sockdata.retval = 0;
-
- newev = add_tcp_read_fd(&sockdata, s);
- if (newev == NULL) {
+ flags = VERTO_EV_FLAG_IO_READ | VERTO_EV_FLAG_PERSIST;
+ if (add_fd(s, CONN_TCP, flags, conn->handle, conn->prog, ctx,
+ process_tcp_connection_read, &newev) != 0) {
close(s);
return;
}
@@ -1253,14 +1208,16 @@ accept_tcp_connection(verto_ctx *ctx, verto_ev *ev)
return;
}
newconn->offset = 0;
- newconn->faddr.address = &newconn->kaddr;
- init_addr(&newconn->faddr, ss2sa(&newconn->addr_s));
+ newconn->remote_addr.address = &newconn->remote_addr_buf;
+ init_addr(&newconn->remote_addr, ss2sa(&newconn->addr_s));
SG_SET(&newconn->sgbuf[0], newconn->lenbuf, 4);
SG_SET(&newconn->sgbuf[1], 0, 0);
}
struct tcp_dispatch_state {
struct sockaddr_storage local_saddr;
+ krb5_address local_addr_buf;
+ krb5_fulladdr local_addr;
struct connection *conn;
krb5_data request;
verto_ctx *ctx;
@@ -1288,7 +1245,7 @@ process_tcp_response(void *arg, krb5_error_code code, krb5_data *response)
state->conn->sgnum = 2;
ev = make_event(state->ctx, VERTO_EV_FLAG_IO_WRITE | VERTO_EV_FLAG_PERSIST,
- process_tcp_connection_write, state->sock, state->conn, 1);
+ process_tcp_connection_write, state->sock, state->conn);
if (ev) {
free(state);
return;
@@ -1381,7 +1338,6 @@ process_tcp_connection_read(verto_ctx *ctx, verto_ev *ev)
} else {
/* msglen known. */
socklen_t local_saddrlen = sizeof(struct sockaddr_storage);
- struct sockaddr *local_saddrp = NULL;
len = conn->msglen - (conn->offset - 4);
nread = SOCKET_READ(verto_get_fd(ev),
@@ -1403,10 +1359,14 @@ process_tcp_connection_read(verto_ctx *ctx, verto_ev *ev)
state->request.data = conn->buffer + 4;
if (getsockname(verto_get_fd(ev), ss2sa(&state->local_saddr),
- &local_saddrlen) == 0)
- local_saddrp = ss2sa(&state->local_saddr);
-
- dispatch(state->conn->handle, local_saddrp, &conn->faddr,
+ &local_saddrlen) < 0) {
+ krb5_klog_syslog(LOG_ERR, _("getsockname failed: %s"),
+ error_message(errno));
+ goto kill_tcp_connection;
+ }
+ state->local_addr.address = &state->local_addr_buf;
+ init_addr(&state->local_addr, ss2sa(&state->local_saddr));
+ dispatch(state->conn->handle, &state->local_addr, &conn->remote_addr,
&state->request, 1, ctx, process_tcp_response, state);
}
@@ -1489,18 +1449,13 @@ have_event_for_fd(int fd)
static void
accept_rpc_connection(verto_ctx *ctx, verto_ev *ev)
{
- struct socksetup sockdata;
+ verto_ev_flag flags;
struct connection *conn;
fd_set fds;
register int s;
conn = verto_get_private(ev);
- sockdata.ctx = ctx;
- sockdata.handle = conn->handle;
- sockdata.prog = conn->prog;
- sockdata.retval = 0;
-
/* Service the woken RPC listener descriptor. */
FD_ZERO(&fds);
FD_SET(verto_get_fd(ev), &fds);
@@ -1519,8 +1474,9 @@ accept_rpc_connection(verto_ctx *ctx, verto_ev *ev)
if (!FD_ISSET(s, &svc_fdset) || have_event_for_fd(s))
continue;
- newev = add_rpc_data_fd(&sockdata, s);
- if (newev == NULL)
+ flags = VERTO_EV_FLAG_IO_READ | VERTO_EV_FLAG_PERSIST;
+ if (add_fd(s, CONN_RPC, flags, conn->handle, conn->prog, ctx,
+ process_rpc_connection, &newev) != 0)
continue;
newconn = verto_get_private(newev);
@@ -1559,8 +1515,8 @@ accept_rpc_connection(verto_ctx *ctx, verto_ev *ev)
if (++tcp_or_rpc_data_counter > max_tcp_or_rpc_data_connections)
kill_lru_tcp_or_rpc_connection(newconn->handle, newev);
- newconn->faddr.address = &newconn->kaddr;
- init_addr(&newconn->faddr, ss2sa(&newconn->addr_s));
+ newconn->remote_addr.address = &newconn->remote_addr_buf;
+ init_addr(&newconn->remote_addr, ss2sa(&newconn->addr_s));
}
}
diff --git a/src/lib/apputils/udppktinfo.c b/src/lib/apputils/udppktinfo.c
index bc7ad09b070c..c096c12b7e61 100644
--- a/src/lib/apputils/udppktinfo.c
+++ b/src/lib/apputils/udppktinfo.c
@@ -141,19 +141,17 @@ is_socket_bound_to_wildcard(int sock)
{
struct sockaddr_storage bound_addr;
socklen_t bound_addr_len = sizeof(bound_addr);
+ struct sockaddr *sa = ss2sa(&bound_addr);
- if (getsockname(sock, ss2sa(&bound_addr), &bound_addr_len) < 0)
+ if (getsockname(sock, sa, &bound_addr_len) < 0)
return -1;
- switch (ss2sa(&bound_addr)->sa_family) {
- case AF_INET:
- return ss2sin(&bound_addr)->sin_addr.s_addr == INADDR_ANY;
- case AF_INET6:
- return IN6_IS_ADDR_UNSPECIFIED(&ss2sin6(&bound_addr)->sin6_addr);
- default:
+ if (!sa_is_inet(sa)) {
errno = EINVAL;
return -1;
}
+
+ return sa_is_wildcard(sa);
}
#ifdef HAVE_IP_PKTINFO
@@ -402,7 +400,7 @@ set_msg_from_ipv6_pktinfo(struct msghdr *msg, struct cmsghdr *cmsgptr,
/*
* Because of the possibility of asymmetric routing, we
* normally don't want to specify an interface. However,
- * Mac OS X doesn't like sending from a link-local address
+ * macOS doesn't like sending from a link-local address
* (which can come up in testing at least, if you wind up
* with a "foo.local" name) unless we do specify the
* interface.
diff --git a/src/lib/apputils/udppktinfo.h b/src/lib/apputils/udppktinfo.h
index b0c7ea36b7b9..ff5759ab7ad3 100644
--- a/src/lib/apputils/udppktinfo.h
+++ b/src/lib/apputils/udppktinfo.h
@@ -32,7 +32,7 @@
* This holds whatever additional information might be needed to
* properly send back to the client from the correct local address.
*
- * In this case, we only need one datum so far: On Mac OS X, the
+ * In this case, we only need one datum so far: On macOS, the
* kernel doesn't seem to like sending from link-local addresses
* unless we specify the correct interface.
*/
diff --git a/src/lib/crypto/builtin/des/des_int.h b/src/lib/crypto/builtin/des/des_int.h
index 0801cb5828c9..67e40a19ca32 100644
--- a/src/lib/crypto/builtin/des/des_int.h
+++ b/src/lib/crypto/builtin/des/des_int.h
@@ -74,7 +74,7 @@
#endif /* defined(__MACH__) && defined(__APPLE__) */
/* Macro to add deprecated attribute to DES types and functions */
-/* Currently only defined on Mac OS X 10.5 and later. */
+/* Currently only defined on macOS 10.5 and later. */
#ifndef KRB5INT_DES_DEPRECATED
#define KRB5INT_DES_DEPRECATED
#endif
diff --git a/src/lib/crypto/builtin/des/destest.c b/src/lib/crypto/builtin/des/destest.c
index 6eeb070d867f..dd2f68ec4032 100644
--- a/src/lib/crypto/builtin/des/destest.c
+++ b/src/lib/crypto/builtin/des/destest.c
@@ -52,6 +52,7 @@
/* Test a DES implementation against known inputs & outputs. */
#include "des_int.h"
+#include <ctype.h>
#include <stdio.h>
void convert (char *, unsigned char []);
@@ -160,7 +161,7 @@ convert(text, cblock)
{
register int i;
for (i = 0; i < 8; i++) {
- if (text[i*2] < 0 || text[i*2] >= 128)
+ if (!isascii((unsigned char)text[i * 2]))
abort ();
if (value[(int) text[i*2]] == -1 || value[(int) text[i*2+1]] == -1) {
printf("Bad value byte %d in %s\n", i, text);
diff --git a/src/lib/crypto/builtin/enc_provider/rc4.c b/src/lib/crypto/builtin/enc_provider/rc4.c
index 3776f80715ab..df710489eaf0 100644
--- a/src/lib/crypto/builtin/enc_provider/rc4.c
+++ b/src/lib/crypto/builtin/enc_provider/rc4.c
@@ -113,7 +113,7 @@ k5_arcfour_docrypt(krb5_key key, const krb5_data *state, krb5_crypto_iov *data,
return KRB5_BAD_MSIZE;
if (state != NULL) {
- cipher_state = (ArcFourCipherState *)state->data;
+ cipher_state = (ArcFourCipherState *)(void *)state->data;
arcfour_ctx = &cipher_state->ctx;
if (cipher_state->initialized == 0) {
ret = k5_arcfour_init(arcfour_ctx, key->keyblock.contents,
diff --git a/src/lib/crypto/builtin/sha2/sha256.c b/src/lib/crypto/builtin/sha2/sha256.c
index e34bed575c5f..2b5cbe480503 100644
--- a/src/lib/crypto/builtin/sha2/sha256.c
+++ b/src/lib/crypto/builtin/sha2/sha256.c
@@ -211,14 +211,14 @@ k5_sha256_update(SHA256_CTX *m, const void *v, size_t len)
#if !defined(WORDS_BIGENDIAN) || defined(_CRAY)
int i;
uint32_t current[16];
- struct x32 *u = (struct x32*)m->save;
+ struct x32 *u = (struct x32*)(void*)m->save;
for(i = 0; i < 8; i++){
current[2*i+0] = swap_uint32_t(u[i].a);
current[2*i+1] = swap_uint32_t(u[i].b);
}
calc(m, current);
#else
- calc(m, (uint32_t*)m->save);
+ calc(m, (uint32_t*)(void*)m->save);
#endif
offset = 0;
}
diff --git a/src/lib/crypto/builtin/sha2/sha512.c b/src/lib/crypto/builtin/sha2/sha512.c
index 8f0ce894033f..6130655576c9 100644
--- a/src/lib/crypto/builtin/sha2/sha512.c
+++ b/src/lib/crypto/builtin/sha2/sha512.c
@@ -217,14 +217,14 @@ k5_sha512_update (SHA512_CTX *m, const void *v, size_t len)
#if !defined(WORDS_BIGENDIAN) || defined(_CRAY)
int i;
uint64_t current[16];
- struct x64 *us = (struct x64*)m->save;
+ struct x64 *us = (struct x64*)(void*)m->save;
for(i = 0; i < 8; i++){
current[2*i+0] = swap_uint64_t(us[i].a);
current[2*i+1] = swap_uint64_t(us[i].b);
}
calc(m, current);
#else
- calc(m, (uint64_t*)m->save);
+ calc(m, (uint64_t*)(void*)m->save);
#endif
offset = 0;
}
diff --git a/src/lib/crypto/krb/Makefile.in b/src/lib/crypto/krb/Makefile.in
index c5660c5fe1fa..fc01a2ced4ae 100644
--- a/src/lib/crypto/krb/Makefile.in
+++ b/src/lib/crypto/krb/Makefile.in
@@ -212,7 +212,7 @@ depend: $(SRCS)
check-unix: t_fortuna
if [ $(PRNG_ALG) = fortuna ]; then \
- $(RUN_TEST) ./t_fortuna > t_fortuna.output; \
+ $(RUN_TEST) ./t_fortuna > t_fortuna.output && \
cmp t_fortuna.output $(srcdir)/t_fortuna.expected; \
fi
diff --git a/src/lib/crypto/krb/crypto_int.h b/src/lib/crypto/krb/crypto_int.h
index d75b49c693f0..e5099291e309 100644
--- a/src/lib/crypto/krb/crypto_int.h
+++ b/src/lib/crypto/krb/crypto_int.h
@@ -111,6 +111,7 @@ struct krb5_keytypes {
prf_func prf;
krb5_cksumtype required_ctype;
krb5_flags flags;
+ unsigned int ssf;
};
#define ETYPE_WEAK 1
diff --git a/src/lib/crypto/krb/enctype_util.c b/src/lib/crypto/krb/enctype_util.c
index 0ed74bd6ebde..b1b40e7ecd6e 100644
--- a/src/lib/crypto/krb/enctype_util.c
+++ b/src/lib/crypto/krb/enctype_util.c
@@ -131,3 +131,19 @@ krb5_enctype_to_name(krb5_enctype enctype, krb5_boolean shortest,
return ENOMEM;
return 0;
}
+
+/* The security of a mechanism cannot be summarized with a simple integer
+ * value, but we provide a per-enctype value for Cyrus SASL's SSF. */
+krb5_error_code
+k5_enctype_to_ssf(krb5_enctype enctype, unsigned int *ssf_out)
+{
+ const struct krb5_keytypes *ktp;
+
+ *ssf_out = 0;
+
+ ktp = find_enctype(enctype);
+ if (ktp == NULL)
+ return EINVAL;
+ *ssf_out = ktp->ssf;
+ return 0;
+}
diff --git a/src/lib/crypto/krb/etypes.c b/src/lib/crypto/krb/etypes.c
index 0e5e977d418a..53d4a5c79b47 100644
--- a/src/lib/crypto/krb/etypes.c
+++ b/src/lib/crypto/krb/etypes.c
@@ -42,7 +42,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = {
krb5int_des_string_to_key, k5_rand2key_des,
krb5int_des_prf,
CKSUMTYPE_RSA_MD5_DES,
- ETYPE_WEAK },
+ ETYPE_WEAK, 56 },
{ ENCTYPE_DES_CBC_MD4,
"des-cbc-md4", { 0 }, "DES cbc mode with RSA-MD4",
&krb5int_enc_des, &krb5int_hash_md4,
@@ -51,7 +51,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = {
krb5int_des_string_to_key, k5_rand2key_des,
krb5int_des_prf,
CKSUMTYPE_RSA_MD4_DES,
- ETYPE_WEAK },
+ ETYPE_WEAK, 56 },
{ ENCTYPE_DES_CBC_MD5,
"des-cbc-md5", { "des" }, "DES cbc mode with RSA-MD5",
&krb5int_enc_des, &krb5int_hash_md5,
@@ -60,7 +60,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = {
krb5int_des_string_to_key, k5_rand2key_des,
krb5int_des_prf,
CKSUMTYPE_RSA_MD5_DES,
- ETYPE_WEAK },
+ ETYPE_WEAK, 56 },
{ ENCTYPE_DES_CBC_RAW,
"des-cbc-raw", { 0 }, "DES cbc mode raw",
&krb5int_enc_des, NULL,
@@ -69,7 +69,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = {
krb5int_des_string_to_key, k5_rand2key_des,
krb5int_des_prf,
0,
- ETYPE_WEAK },
+ ETYPE_WEAK, 56 },
{ ENCTYPE_DES3_CBC_RAW,
"des3-cbc-raw", { 0 }, "Triple DES cbc mode raw",
&krb5int_enc_des3, NULL,
@@ -78,7 +78,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = {
krb5int_dk_string_to_key, k5_rand2key_des3,
NULL, /*PRF*/
0,
- ETYPE_WEAK },
+ ETYPE_WEAK, 112 },
{ ENCTYPE_DES3_CBC_SHA1,
"des3-cbc-sha1", { "des3-hmac-sha1", "des3-cbc-sha1-kd" },
@@ -89,7 +89,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = {
krb5int_dk_string_to_key, k5_rand2key_des3,
krb5int_dk_prf,
CKSUMTYPE_HMAC_SHA1_DES3,
- 0 /*flags*/ },
+ 0 /*flags*/, 112 },
{ ENCTYPE_DES_HMAC_SHA1,
"des-hmac-sha1", { 0 }, "DES with HMAC/sha1",
@@ -99,7 +99,10 @@ const struct krb5_keytypes krb5int_enctypes_list[] = {
krb5int_dk_string_to_key, k5_rand2key_des,
NULL, /*PRF*/
0,
- ETYPE_WEAK },
+ ETYPE_WEAK, 56 },
+
+ /* rc4-hmac uses a 128-bit key, but due to weaknesses in the RC4 cipher, we
+ * consider its strength degraded and assign it an SSF value of 64. */
{ ENCTYPE_ARCFOUR_HMAC,
"arcfour-hmac", { "rc4-hmac", "arcfour-hmac-md5" },
"ArcFour with HMAC/md5",
@@ -110,7 +113,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = {
krb5int_arcfour_decrypt, krb5int_arcfour_string_to_key,
k5_rand2key_direct, krb5int_arcfour_prf,
CKSUMTYPE_HMAC_MD5_ARCFOUR,
- 0 /*flags*/ },
+ 0 /*flags*/, 64 },
{ ENCTYPE_ARCFOUR_HMAC_EXP,
"arcfour-hmac-exp", { "rc4-hmac-exp", "arcfour-hmac-md5-exp" },
"Exportable ArcFour with HMAC/md5",
@@ -121,7 +124,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = {
krb5int_arcfour_decrypt, krb5int_arcfour_string_to_key,
k5_rand2key_direct, krb5int_arcfour_prf,
CKSUMTYPE_HMAC_MD5_ARCFOUR,
- ETYPE_WEAK
+ ETYPE_WEAK, 40
},
{ ENCTYPE_AES128_CTS_HMAC_SHA1_96,
@@ -133,7 +136,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = {
krb5int_aes_string_to_key, k5_rand2key_direct,
krb5int_dk_prf,
CKSUMTYPE_HMAC_SHA1_96_AES128,
- 0 /*flags*/ },
+ 0 /*flags*/, 128 },
{ ENCTYPE_AES256_CTS_HMAC_SHA1_96,
"aes256-cts-hmac-sha1-96", { "aes256-cts", "aes256-sha1" },
"AES-256 CTS mode with 96-bit SHA-1 HMAC",
@@ -143,7 +146,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = {
krb5int_aes_string_to_key, k5_rand2key_direct,
krb5int_dk_prf,
CKSUMTYPE_HMAC_SHA1_96_AES256,
- 0 /*flags*/ },
+ 0 /*flags*/, 256 },
{ ENCTYPE_CAMELLIA128_CTS_CMAC,
"camellia128-cts-cmac", { "camellia128-cts" },
@@ -155,7 +158,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = {
krb5int_camellia_string_to_key, k5_rand2key_direct,
krb5int_dk_cmac_prf,
CKSUMTYPE_CMAC_CAMELLIA128,
- 0 /*flags*/ },
+ 0 /*flags*/, 128 },
{ ENCTYPE_CAMELLIA256_CTS_CMAC,
"camellia256-cts-cmac", { "camellia256-cts" },
"Camellia-256 CTS mode with CMAC",
@@ -166,7 +169,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = {
krb5int_camellia_string_to_key, k5_rand2key_direct,
krb5int_dk_cmac_prf,
CKSUMTYPE_CMAC_CAMELLIA256,
- 0 /*flags */ },
+ 0 /*flags */, 256 },
{ ENCTYPE_AES128_CTS_HMAC_SHA256_128,
"aes128-cts-hmac-sha256-128", { "aes128-sha2" },
@@ -177,7 +180,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = {
krb5int_aes2_string_to_key, k5_rand2key_direct,
krb5int_aes2_prf,
CKSUMTYPE_HMAC_SHA256_128_AES128,
- 0 /*flags*/ },
+ 0 /*flags*/, 128 },
{ ENCTYPE_AES256_CTS_HMAC_SHA384_192,
"aes256-cts-hmac-sha384-192", { "aes256-sha2" },
"AES-256 CTS mode with 192-bit SHA-384 HMAC",
@@ -187,7 +190,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = {
krb5int_aes2_string_to_key, k5_rand2key_direct,
krb5int_aes2_prf,
CKSUMTYPE_HMAC_SHA384_192_AES256,
- 0 /*flags*/ },
+ 0 /*flags*/, 256 },
};
const int krb5int_enctypes_length =
diff --git a/src/lib/crypto/krb/s2k_des.c b/src/lib/crypto/krb/s2k_des.c
index 31a613bebc61..d5c29befcb2e 100644
--- a/src/lib/crypto/krb/s2k_des.c
+++ b/src/lib/crypto/krb/s2k_des.c
@@ -509,7 +509,7 @@ des_s2k(const krb5_data *pw, const krb5_data *salt, unsigned char *key_out)
#define FETCH4(VAR, IDX) VAR = temp.ui[IDX/4]
#define PUT4(VAR, IDX) temp.ui[IDX/4] = VAR
- copylen = pw->length + (salt ? salt->length : 0);
+ copylen = pw->length + salt->length;
/* Don't need NUL termination, at this point we're treating it as
a byte array, not a string. */
copy = malloc(copylen);
@@ -517,7 +517,7 @@ des_s2k(const krb5_data *pw, const krb5_data *salt, unsigned char *key_out)
return ENOMEM;
if (pw->length > 0)
memcpy(copy, pw->data, pw->length);
- if (salt != NULL && salt->length > 0)
+ if (salt->length > 0)
memcpy(copy + pw->length, salt->data, salt->length);
memset(&temp, 0, sizeof(temp));
diff --git a/src/lib/crypto/krb/s2k_pbkdf2.c b/src/lib/crypto/krb/s2k_pbkdf2.c
index ec5856c2be79..1fea03408c76 100644
--- a/src/lib/crypto/krb/s2k_pbkdf2.c
+++ b/src/lib/crypto/krb/s2k_pbkdf2.c
@@ -47,7 +47,7 @@ krb5int_dk_string_to_key(const struct krb5_keytypes *ktp,
keybytes = ktp->enc->keybytes;
keylength = ktp->enc->keylength;
- concatlen = string->length + (salt ? salt->length : 0);
+ concatlen = string->length + salt->length;
concat = k5alloc(concatlen, &ret);
if (ret != 0)
@@ -63,7 +63,7 @@ krb5int_dk_string_to_key(const struct krb5_keytypes *ktp,
if (string->length > 0)
memcpy(concat, string->data, string->length);
- if (salt != NULL && salt->length > 0)
+ if (salt->length > 0)
memcpy(concat + string->length, salt->data, salt->length);
krb5int_nfold(concatlen*8, concat, keybytes*8, foldstring);
diff --git a/src/lib/crypto/krb/s2k_rc4.c b/src/lib/crypto/krb/s2k_rc4.c
index 49ad89d323b0..081a91217c69 100644
--- a/src/lib/crypto/krb/s2k_rc4.c
+++ b/src/lib/crypto/krb/s2k_rc4.c
@@ -10,6 +10,7 @@ krb5int_arcfour_string_to_key(const struct krb5_keytypes *ktp,
krb5_error_code err = 0;
krb5_crypto_iov iov;
krb5_data hash_out;
+ char *utf8;
unsigned char *copystr;
size_t copystrlen;
@@ -20,8 +21,11 @@ krb5int_arcfour_string_to_key(const struct krb5_keytypes *ktp,
return (KRB5_BAD_MSIZE);
/* We ignore salt per the Microsoft spec. */
- err = krb5int_utf8cs_to_ucs2les(string->data, string->length, &copystr,
- &copystrlen);
+ utf8 = k5memdup0(string->data, string->length, &err);
+ if (utf8 == NULL)
+ return err;
+ err = k5_utf8_to_utf16le(utf8, &copystr, &copystrlen);
+ free(utf8);
if (err)
return err;
diff --git a/src/lib/crypto/krb/string_to_key.c b/src/lib/crypto/krb/string_to_key.c
index b55ee75d2f34..352a8e8dcce2 100644
--- a/src/lib/crypto/krb/string_to_key.c
+++ b/src/lib/crypto/krb/string_to_key.c
@@ -43,6 +43,7 @@ krb5_c_string_to_key_with_params(krb5_context context, krb5_enctype enctype,
const krb5_data *params, krb5_keyblock *key)
{
krb5_error_code ret;
+ krb5_data empty = empty_data();
const struct krb5_keytypes *ktp;
size_t keylength;
@@ -51,8 +52,12 @@ krb5_c_string_to_key_with_params(krb5_context context, krb5_enctype enctype,
return KRB5_BAD_ENCTYPE;
keylength = ktp->enc->keylength;
+ /* For compatibility with past behavior, treat a null salt as empty. */
+ if (salt == NULL)
+ salt = &empty;
+
/* Fail gracefully if someone is using the old AFS string-to-key hack. */
- if (salt != NULL && salt->length == SALT_TYPE_AFS_LENGTH)
+ if (salt->length == SALT_TYPE_AFS_LENGTH)
return EINVAL;
key->contents = malloc(keylength);
diff --git a/src/lib/crypto/krb/t_fortuna.c b/src/lib/crypto/krb/t_fortuna.c
index 4f25bee62cb5..508ffcf915c7 100644
--- a/src/lib/crypto/krb/t_fortuna.c
+++ b/src/lib/crypto/krb/t_fortuna.c
@@ -85,7 +85,7 @@ head_tail_test(struct fortuna_state *st)
{
static unsigned char buffer[1024 * 1024];
unsigned char c;
- size_t i, len = sizeof(buffer);
+ int i, len = sizeof(buffer);
int bit, bits[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
double res;
diff --git a/src/lib/crypto/libk5crypto.exports b/src/lib/crypto/libk5crypto.exports
index 447e45644453..82eb5f30c031 100644
--- a/src/lib/crypto/libk5crypto.exports
+++ b/src/lib/crypto/libk5crypto.exports
@@ -108,3 +108,4 @@ krb5int_nfold
k5_allow_weak_pbkdf2iter
krb5_c_prfplus
krb5_c_derive_prfplus
+k5_enctype_to_ssf
diff --git a/src/lib/gssapi/generic/gssapi_ext.h b/src/lib/gssapi/generic/gssapi_ext.h
index 9ad44216d05e..9d3a7e736736 100644
--- a/src/lib/gssapi/generic/gssapi_ext.h
+++ b/src/lib/gssapi/generic/gssapi_ext.h
@@ -575,4 +575,15 @@ gss_import_cred(
}
#endif
+/*
+ * When used with gss_inquire_sec_context_by_oid(), return a buffer set with
+ * the first member containing an unsigned 32-bit integer in network byte
+ * order. This is the Security Strength Factor (SSF) associated with the
+ * secure channel established by the security context. NOTE: This value is
+ * made available solely as an indication for use by APIs like Cyrus SASL that
+ * classify the strength of a secure channel via this number. The strength of
+ * a channel cannot necessarily be represented by a simple number.
+ */
+GSS_DLLIMP extern gss_OID GSS_C_SEC_CONTEXT_SASL_SSF;
+
#endif /* GSSAPI_EXT_H_ */
diff --git a/src/lib/gssapi/generic/gssapi_generic.c b/src/lib/gssapi/generic/gssapi_generic.c
index 5496aa33582c..fa144c2bf9cc 100644
--- a/src/lib/gssapi/generic/gssapi_generic.c
+++ b/src/lib/gssapi/generi