diff options
author | assar <assar@FreeBSD.org> | 2001-02-13 16:46:19 +0000 |
---|---|---|
committer | assar <assar@FreeBSD.org> | 2001-02-13 16:46:19 +0000 |
commit | 3a971fe69aad52dfd248901ae796e64a96ae3e37 (patch) | |
tree | ac7b5c62510ffa9f0316643bcb19a3fed3d5bef7 /crypto/heimdal/kdc | |
parent | 2934fc23653f64b32f4db32233d7eda11ca274f0 (diff) | |
parent | ebfe6dc471c206300fd82c7c0fd145f683aa52f6 (diff) | |
download | FreeBSD-src-3a971fe69aad52dfd248901ae796e64a96ae3e37.zip FreeBSD-src-3a971fe69aad52dfd248901ae796e64a96ae3e37.tar.gz |
This commit was generated by cvs2svn to compensate for changes in r72445,
which included commits to RCS files with non-trunk default branches.
Diffstat (limited to 'crypto/heimdal/kdc')
-rw-r--r-- | crypto/heimdal/kdc/524.c | 242 | ||||
-rw-r--r-- | crypto/heimdal/kdc/Makefile.am | 21 | ||||
-rw-r--r-- | crypto/heimdal/kdc/Makefile.in | 402 | ||||
-rw-r--r-- | crypto/heimdal/kdc/config.c | 26 | ||||
-rw-r--r-- | crypto/heimdal/kdc/connect.c | 91 | ||||
-rw-r--r-- | crypto/heimdal/kdc/hprop.8 | 181 | ||||
-rw-r--r-- | crypto/heimdal/kdc/hprop.c | 513 | ||||
-rw-r--r-- | crypto/heimdal/kdc/hprop.h | 34 | ||||
-rw-r--r-- | crypto/heimdal/kdc/hpropd.8 | 58 | ||||
-rw-r--r-- | crypto/heimdal/kdc/hpropd.c | 73 | ||||
-rw-r--r-- | crypto/heimdal/kdc/kadb.h | 12 | ||||
-rw-r--r-- | crypto/heimdal/kdc/kaserver.c | 90 | ||||
-rw-r--r-- | crypto/heimdal/kdc/kdc.8 | 34 | ||||
-rw-r--r-- | crypto/heimdal/kdc/kdc_locl.h | 36 | ||||
-rw-r--r-- | crypto/heimdal/kdc/kerberos4.c | 212 | ||||
-rw-r--r-- | crypto/heimdal/kdc/kerberos5.c | 356 | ||||
-rw-r--r-- | crypto/heimdal/kdc/kstash.8 | 56 | ||||
-rw-r--r-- | crypto/heimdal/kdc/kstash.c | 188 | ||||
-rw-r--r-- | crypto/heimdal/kdc/log.c | 4 | ||||
-rw-r--r-- | crypto/heimdal/kdc/main.c | 11 | ||||
-rw-r--r-- | crypto/heimdal/kdc/misc.c | 31 | ||||
-rw-r--r-- | crypto/heimdal/kdc/mit_dump.c | 370 | ||||
-rw-r--r-- | crypto/heimdal/kdc/string2key.8 | 76 | ||||
-rw-r--r-- | crypto/heimdal/kdc/v4_dump.c | 142 |
24 files changed, 2308 insertions, 951 deletions
diff --git a/crypto/heimdal/kdc/524.c b/crypto/heimdal/kdc/524.c index fb188de..df70988 100644 --- a/crypto/heimdal/kdc/524.c +++ b/crypto/heimdal/kdc/524.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997-1999 Kungliga Tekniska Högskolan + * Copyright (c) 1997-2001 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -33,17 +33,158 @@ #include "kdc_locl.h" -RCSID("$Id: 524.c,v 1.10 1999/12/02 17:04:58 joda Exp $"); +RCSID("$Id: 524.c,v 1.19 2001/01/30 01:44:07 assar Exp $"); #ifdef KRB4 +/* + * fetch the server from `t', returning the name in malloced memory in + * `spn' and the entry itself in `server' + */ + +static krb5_error_code +fetch_server (const Ticket *t, + char **spn, + hdb_entry **server, + const char *from) +{ + krb5_error_code ret; + krb5_principal sprinc; + + ret = principalname2krb5_principal(&sprinc, t->sname, t->realm); + if (ret) { + kdc_log(0, "principalname2krb5_principal: %s", + krb5_get_err_text(context, ret)); + return ret; + } + ret = krb5_unparse_name(context, sprinc, spn); + if (ret) { + krb5_free_principal(context, sprinc); + kdc_log(0, "krb5_unparse_name: %s", krb5_get_err_text(context, ret)); + return ret; + } + ret = db_fetch(sprinc, server); + krb5_free_principal(context, sprinc); + if (ret) { + kdc_log(0, + "Request to convert ticket from %s for unknown principal %s: %s", + from, *spn, krb5_get_err_text(context, ret)); + if (ret == ENOENT) + ret = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN; + return ret; + } + return 0; +} + +static krb5_error_code +log_524 (const EncTicketPart *et, + const char *from, + const char *spn) +{ + krb5_principal client; + char *cpn; + krb5_error_code ret; + + ret = principalname2krb5_principal(&client, et->cname, et->crealm); + if (ret) { + kdc_log(0, "principalname2krb5_principal: %s", + krb5_get_err_text (context, ret)); + return ret; + } + ret = krb5_unparse_name(context, client, &cpn); + if (ret) { + krb5_free_principal(context, client); + kdc_log(0, "krb5_unparse_name: %s", + krb5_get_err_text (context, ret)); + return ret; + } + kdc_log(1, "524-REQ %s from %s for %s", cpn, from, spn); + free(cpn); + krb5_free_principal(context, client); + return 0; +} + +static krb5_error_code +verify_flags (const EncTicketPart *et, + const char *spn) +{ + if(et->endtime < kdc_time){ + kdc_log(0, "Ticket expired (%s)", spn); + return KRB5KRB_AP_ERR_TKT_EXPIRED; + } + if(et->flags.invalid){ + kdc_log(0, "Ticket not valid (%s)", spn); + return KRB5KRB_AP_ERR_TKT_NYV; + } + return 0; +} + +/* + * set the `et->caddr' to the most appropriate address to use, where + * `addr' is the address the request was received from. + */ + +static krb5_error_code +set_address (EncTicketPart *et, + struct sockaddr *addr, + const char *from) +{ + krb5_error_code ret; + krb5_address *v4_addr; + + v4_addr = malloc (sizeof(*v4_addr)); + if (v4_addr == NULL) + return ENOMEM; + + ret = krb5_sockaddr2address(addr, v4_addr); + if(ret) { + free (v4_addr); + kdc_log(0, "Failed to convert address (%s)", from); + return ret; + } + + if (et->caddr && !krb5_address_search (context, v4_addr, et->caddr)) { + kdc_log(0, "Incorrect network address (%s)", from); + krb5_free_address(context, v4_addr); + free (v4_addr); + return KRB5KRB_AP_ERR_BADADDR; + } + if(v4_addr->addr_type == KRB5_ADDRESS_INET) { + /* we need to collapse the addresses in the ticket to a + single address; best guess is to use the address the + connection came from */ + + if (et->caddr != NULL) { + free_HostAddresses(et->caddr); + } else { + et->caddr = malloc (sizeof (*et->caddr)); + if (et->caddr == NULL) { + krb5_free_address(context, v4_addr); + free(v4_addr); + return ENOMEM; + } + } + et->caddr->val = v4_addr; + et->caddr->len = 1; + } else { + krb5_free_address(context, v4_addr); + free(v4_addr); + } + return 0; +} + +/* + * process a 5->4 request, based on `t', and received `from, addr', + * returning the reply in `reply' + */ + krb5_error_code -do_524(Ticket *t, krb5_data *reply, const char *from, struct sockaddr *addr) +do_524(const Ticket *t, krb5_data *reply, + const char *from, struct sockaddr *addr) { krb5_error_code ret = 0; - krb5_principal sprinc = NULL; krb5_crypto crypto; - hdb_entry *server; + hdb_entry *server = NULL; Key *skey; krb5_data et_data; EncTicketPart et; @@ -53,21 +194,28 @@ do_524(Ticket *t, krb5_data *reply, const char *from, struct sockaddr *addr) unsigned char buf[MAX_KTXT_LEN + 4 * 4]; size_t len; - principalname2krb5_principal(&sprinc, t->sname, t->realm); - krb5_unparse_name(context, sprinc, &spn); - server = db_fetch(sprinc); - if(server == NULL){ - kdc_log(0, "Request to convert ticket from %s for unknown principal %s", - from, spn); + if(!enable_524) { + ret = KRB5KDC_ERR_POLICY; + kdc_log(0, "Rejected ticket conversion request from %s", from); goto out; } + + ret = fetch_server (t, &spn, &server, from); + if (ret) { + goto out; + } + ret = hdb_enctype2key(context, server, t->enc_part.etype, &skey); if(ret){ - kdc_log(0, "No suitable key found for server (%s) " - "when converting ticket from ", spn, from); + kdc_log(0, "No suitable key found for server (%s) from %s", spn, from); + goto out; + } + ret = krb5_crypto_init(context, &skey->key, 0, &crypto); + if (ret) { + kdc_log(0, "krb5_crypto_init failed: %s", + krb5_get_err_text(context, ret)); goto out; } - krb5_crypto_init(context, &skey->key, 0, &crypto); ret = krb5_decrypt_EncryptedData (context, crypto, KRB5_KU_TICKET, @@ -85,66 +233,32 @@ do_524(Ticket *t, krb5_data *reply, const char *from, struct sockaddr *addr) kdc_log(0, "Failed to decode ticket from %s for %s", from, spn); goto out; } - { - krb5_principal client; - char *cpn; - principalname2krb5_principal(&client, et.cname, et.crealm); - krb5_unparse_name(context, client, &cpn); - kdc_log(1, "524-REQ %s from %s for %s", cpn, from, spn); - free(cpn); - krb5_free_principal(context, client); - } - if(et.endtime < kdc_time){ - kdc_log(0, "Ticket expired (%s)", spn); + ret = log_524 (&et, from, spn); + if (ret) { free_EncTicketPart(&et); - ret = KRB5KRB_AP_ERR_TKT_EXPIRED; goto out; } - if(et.flags.invalid){ - kdc_log(0, "Ticket not valid (%s)", spn); + + ret = verify_flags (&et, spn); + if (ret) { free_EncTicketPart(&et); - ret = KRB5KRB_AP_ERR_TKT_NYV; goto out; } - { - krb5_addresses *save_caddr, new_addr; - krb5_address v4_addr; - ret = krb5_sockaddr2address(addr, &v4_addr); - if(ret) { - kdc_log(0, "Failed to convert address (%s)", spn); - free_EncTicketPart(&et); - goto out; - } - - if (et.caddr && !krb5_address_search (context, &v4_addr, et.caddr)) { - kdc_log(0, "Incorrect network address (%s)", spn); - free_EncTicketPart(&et); - krb5_free_address(context, &v4_addr); - ret = KRB5KRB_AP_ERR_BADADDR; - goto out; - } - if(v4_addr.addr_type == KRB5_ADDRESS_INET) { - /* we need to collapse the addresses in the ticket to a - single address; best guess is to use the address the - connection came from */ - save_caddr = et.caddr; - new_addr.len = 1; - new_addr.val = &v4_addr; - et.caddr = &new_addr; - } - ret = encode_v4_ticket(buf + sizeof(buf) - 1, sizeof(buf), - &et, &t->sname, &len); - if(v4_addr.addr_type == KRB5_ADDRESS_INET) - et.caddr = save_caddr; + ret = set_address (&et, addr, from); + if (ret) { + free_EncTicketPart(&et); + goto out; } + ret = encode_v4_ticket(buf + sizeof(buf) - 1, sizeof(buf), + &et, &t->sname, &len); free_EncTicketPart(&et); if(ret){ kdc_log(0, "Failed to encode v4 ticket (%s)", spn); goto out; } - ret = get_des_key(server, &skey); + ret = get_des_key(server, FALSE, &skey); if(ret){ kdc_log(0, "No DES key for server (%s)", spn); goto out; @@ -173,11 +287,9 @@ out: if(spn) free(spn); - if(sprinc) - krb5_free_principal(context, sprinc); - hdb_free_entry(context, server); - free(server); + if(server) + free_ent (server); return ret; } -#endif +#endif /* KRB4 */ diff --git a/crypto/heimdal/kdc/Makefile.am b/crypto/heimdal/kdc/Makefile.am index 3e3df20..674ec4d 100644 --- a/crypto/heimdal/kdc/Makefile.am +++ b/crypto/heimdal/kdc/Makefile.am @@ -1,8 +1,8 @@ -# $Id: Makefile.am,v 1.33 1999/05/13 23:32:35 assar Exp $ +# $Id: Makefile.am,v 1.41 2000/11/15 22:51:12 assar Exp $ include $(top_srcdir)/Makefile.am.common -INCLUDES += $(INCLUDE_krb4) +INCLUDES += $(INCLUDE_krb4) -I$(srcdir)/../lib/krb5 bin_PROGRAMS = string2key @@ -10,10 +10,10 @@ sbin_PROGRAMS = kstash libexec_PROGRAMS = hprop hpropd kdc -man_MANS = kdc.8 kstash.8 hprop.8 hpropd.8 +man_MANS = kdc.8 kstash.8 hprop.8 hpropd.8 string2key.8 -hprop_SOURCES = hprop.c hprop-common.c hprop.h kadb.h -hpropd_SOURCES = hpropd.c hprop-common.c hprop.h +hprop_SOURCES = hprop.c mit_dump.c v4_dump.c hprop.h kadb.h +hpropd_SOURCES = hpropd.c hprop.h kstash_SOURCES = kstash.c headers.h @@ -36,27 +36,32 @@ kdc_SOURCES = \ hprop_LDADD = \ $(top_builddir)/lib/hdb/libhdb.la \ + $(LIB_openldap) \ $(top_builddir)/lib/krb5/libkrb5.la \ $(LIB_kdb) $(LIB_krb4) \ - $(top_builddir)/lib/des/libdes.la \ + $(LIB_des) \ $(top_builddir)/lib/asn1/libasn1.la \ $(LIB_roken) \ $(DBLIB) hpropd_LDADD = \ $(top_builddir)/lib/hdb/libhdb.la \ + $(LIB_openldap) \ $(top_builddir)/lib/krb5/libkrb5.la \ $(LIB_kdb) $(LIB_krb4) \ - $(top_builddir)/lib/des/libdes.la \ + $(LIB_des) \ $(top_builddir)/lib/asn1/libasn1.la \ $(LIB_roken) \ $(DBLIB) LDADD = $(top_builddir)/lib/hdb/libhdb.la \ + $(LIB_openldap) \ $(top_builddir)/lib/krb5/libkrb5.la \ $(LIB_krb4) \ - $(top_builddir)/lib/des/libdes.la \ + $(LIB_des) \ $(top_builddir)/lib/asn1/libasn1.la \ $(LIB_roken) \ $(DBLIB) +kdc_LDADD = $(LDADD) $(LIB_pidfile) + diff --git a/crypto/heimdal/kdc/Makefile.in b/crypto/heimdal/kdc/Makefile.in index 6ba90e1..d5c394d 100644 --- a/crypto/heimdal/kdc/Makefile.in +++ b/crypto/heimdal/kdc/Makefile.in @@ -1,6 +1,6 @@ -# Makefile.in generated automatically by automake 1.4 from Makefile.am +# Makefile.in generated automatically by automake 1.4a from Makefile.am -# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. +# Copyright (C) 1994, 1995-9, 2000 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -10,15 +10,6 @@ # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. -# $Id: Makefile.am,v 1.33 1999/05/13 23:32:35 assar Exp $ - - -# $Id: Makefile.am.common,v 1.3 1999/04/01 14:58:43 joda Exp $ - - -# $Id: Makefile.am.common,v 1.13 1999/11/01 03:19:58 assar Exp $ - - SHELL = @SHELL@ srcdir = @srcdir@ @@ -40,8 +31,6 @@ mandir = @mandir@ includedir = @includedir@ oldincludedir = /usr/include -DESTDIR = - pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ @@ -54,9 +43,10 @@ AUTOMAKE = @AUTOMAKE@ AUTOHEADER = @AUTOHEADER@ INSTALL = @INSTALL@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) +INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_FLAG = transform = @program_transform_name@ NORMAL_INSTALL = : @@ -65,26 +55,39 @@ POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : + +@SET_MAKE@ host_alias = @host_alias@ host_triplet = @host@ -AFS_EXTRA_LD = @AFS_EXTRA_LD@ AIX_EXTRA_KAFS = @AIX_EXTRA_KAFS@ +AMDEP = @AMDEP@ +AMTAR = @AMTAR@ +AS = @AS@ AWK = @AWK@ CANONICAL_HOST = @CANONICAL_HOST@ CATMAN = @CATMAN@ CATMANEXT = @CATMANEXT@ CC = @CC@ +CPP = @CPP@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ DBLIB = @DBLIB@ +DEPDIR = @DEPDIR@ +DIR_des = @DIR_des@ +DIR_roken = @DIR_roken@ +DLLTOOL = @DLLTOOL@ EXEEXT = @EXEEXT@ EXTRA_LIB45 = @EXTRA_LIB45@ GROFF = @GROFF@ +INCLUDES_roken = @INCLUDES_roken@ INCLUDE_ = @INCLUDE_@ -LD = @LD@ LEX = @LEX@ LIBOBJS = @LIBOBJS@ LIBTOOL = @LIBTOOL@ LIB_ = @LIB_@ LIB_AUTH_SUBDIRS = @LIB_AUTH_SUBDIRS@ +LIB_des = @LIB_des@ +LIB_des_appl = @LIB_des_appl@ LIB_kdb = @LIB_kdb@ LIB_otp = @LIB_otp@ LIB_roken = @LIB_roken@ @@ -92,31 +95,43 @@ LIB_security = @LIB_security@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ -MAKE_X_PROGS_BIN_PROGS = @MAKE_X_PROGS_BIN_PROGS@ -MAKE_X_PROGS_BIN_SCRPTS = @MAKE_X_PROGS_BIN_SCRPTS@ -MAKE_X_PROGS_LIBEXEC_PROGS = @MAKE_X_PROGS_LIBEXEC_PROGS@ NEED_WRITEAUTH_FALSE = @NEED_WRITEAUTH_FALSE@ NEED_WRITEAUTH_TRUE = @NEED_WRITEAUTH_TRUE@ -NM = @NM@ NROFF = @NROFF@ +OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ RANLIB = @RANLIB@ +STRIP = @STRIP@ VERSION = @VERSION@ VOID_RETSIGTYPE = @VOID_RETSIGTYPE@ WFLAGS = @WFLAGS@ WFLAGS_NOIMPLICITINT = @WFLAGS_NOIMPLICITINT@ WFLAGS_NOUNUSED = @WFLAGS_NOUNUSED@ YACC = @YACC@ +dpagaix_CFLAGS = @dpagaix_CFLAGS@ +dpagaix_LDADD = @dpagaix_LDADD@ +install_sh = @install_sh@ + +# $Id: Makefile.am,v 1.41 2000/11/15 22:51:12 assar Exp $ + + +# $Id: Makefile.am.common,v 1.3 1999/04/01 14:58:43 joda Exp $ + + +# $Id: Makefile.am.common,v 1.23 2000/12/05 09:11:09 joda Exp $ + AUTOMAKE_OPTIONS = foreign no-dependencies SUFFIXES = .et .h .1 .3 .5 .8 .cat1 .cat3 .cat5 .cat8 .x -INCLUDES = -I$(top_builddir)/include $(INCLUDE_krb4) +INCLUDES = -I$(top_builddir)/include $(INCLUDES_roken) $(INCLUDE_krb4) -I$(srcdir)/../lib/krb5 AM_CFLAGS = $(WFLAGS) +CP = cp + COMPILE_ET = $(top_builddir)/lib/com_err/compile_et buildinclude = $(top_builddir)/include @@ -136,6 +151,7 @@ LIB_getsockopt = @LIB_getsockopt@ LIB_logout = @LIB_logout@ LIB_logwtmp = @LIB_logwtmp@ LIB_odm_initialize = @LIB_odm_initialize@ +LIB_pidfile = @LIB_pidfile@ LIB_readline = @LIB_readline@ LIB_res_search = @LIB_res_search@ LIB_setpcred = @LIB_setpcred@ @@ -144,6 +160,8 @@ LIB_socket = @LIB_socket@ LIB_syslog = @LIB_syslog@ LIB_tgetent = @LIB_tgetent@ +LIBS = @LIBS@ + HESIODLIB = @HESIODLIB@ HESIODINCLUDE = @HESIODINCLUDE@ INCLUDE_hesiod = @INCLUDE_hesiod@ @@ -152,24 +170,20 @@ LIB_hesiod = @LIB_hesiod@ INCLUDE_krb4 = @INCLUDE_krb4@ LIB_krb4 = @LIB_krb4@ +INCLUDE_openldap = @INCLUDE_openldap@ +LIB_openldap = @LIB_openldap@ + INCLUDE_readline = @INCLUDE_readline@ LEXLIB = @LEXLIB@ -cat1dir = $(mandir)/cat1 -cat3dir = $(mandir)/cat3 -cat5dir = $(mandir)/cat5 -cat8dir = $(mandir)/cat8 - -MANRX = \(.*\)\.\([0-9]\) -CATSUFFIX = @CATSUFFIX@ - NROFF_MAN = groff -mandoc -Tascii -@KRB4_TRUE@LIB_kafs = $(top_builddir)/lib/kafs/libkafs.la $(AIX_EXTRA_KAFS) +@KRB4_TRUE@LIB_kafs = @KRB4_TRUE@$(top_builddir)/lib/kafs/libkafs.la $(AIX_EXTRA_KAFS) -@KRB5_TRUE@LIB_krb5 = $(top_builddir)/lib/krb5/libkrb5.la $(top_builddir)/lib/asn1/libasn1.la -@KRB5_TRUE@LIB_gssapi = $(top_builddir)/lib/gssapi/libgssapi.la +@KRB5_TRUE@LIB_krb5 = @KRB5_TRUE@$(top_builddir)/lib/krb5/libkrb5.la \ +@KRB5_TRUE@ $(top_builddir)/lib/asn1/libasn1.la +@KRB5_TRUE@LIB_gssapi = @KRB5_TRUE@$(top_builddir)/lib/gssapi/libgssapi.la CHECK_LOCAL = $(PROGRAMS) @@ -179,26 +193,64 @@ sbin_PROGRAMS = kstash libexec_PROGRAMS = hprop hpropd kdc -man_MANS = kdc.8 kstash.8 hprop.8 hpropd.8 +man_MANS = kdc.8 kstash.8 hprop.8 hpropd.8 string2key.8 -hprop_SOURCES = hprop.c hprop-common.c hprop.h kadb.h -hpropd_SOURCES = hpropd.c hprop-common.c hprop.h +hprop_SOURCES = hprop.c mit_dump.c v4_dump.c hprop.h kadb.h +hpropd_SOURCES = hpropd.c hprop.h kstash_SOURCES = kstash.c headers.h string2key_SOURCES = string2key.c headers.h -kdc_SOURCES = 524.c config.c connect.c kaserver.c kdc_locl.h kerberos4.c kerberos4.h kerberos5.c log.c main.c misc.c rx.h - - -hprop_LDADD = $(top_builddir)/lib/hdb/libhdb.la $(top_builddir)/lib/krb5/libkrb5.la $(LIB_kdb) $(LIB_krb4) $(top_builddir)/lib/des/libdes.la $(top_builddir)/lib/asn1/libasn1.la $(LIB_roken) $(DBLIB) - - -hpropd_LDADD = $(top_builddir)/lib/hdb/libhdb.la $(top_builddir)/lib/krb5/libkrb5.la $(LIB_kdb) $(LIB_krb4) $(top_builddir)/lib/des/libdes.la $(top_builddir)/lib/asn1/libasn1.la $(LIB_roken) $(DBLIB) - - -LDADD = $(top_builddir)/lib/hdb/libhdb.la $(top_builddir)/lib/krb5/libkrb5.la $(LIB_krb4) $(top_builddir)/lib/des/libdes.la $(top_builddir)/lib/asn1/libasn1.la $(LIB_roken) $(DBLIB) - +kdc_SOURCES = \ + 524.c \ + config.c \ + connect.c \ + kaserver.c \ + kdc_locl.h \ + kerberos4.c \ + kerberos4.h \ + kerberos5.c \ + log.c \ + main.c \ + misc.c \ + rx.h + + +hprop_LDADD = \ + $(top_builddir)/lib/hdb/libhdb.la \ + $(LIB_openldap) \ + $(top_builddir)/lib/krb5/libkrb5.la \ + $(LIB_kdb) $(LIB_krb4) \ + $(LIB_des) \ + $(top_builddir)/lib/asn1/libasn1.la \ + $(LIB_roken) \ + $(DBLIB) + + +hpropd_LDADD = \ + $(top_builddir)/lib/hdb/libhdb.la \ + $(LIB_openldap) \ + $(top_builddir)/lib/krb5/libkrb5.la \ + $(LIB_kdb) $(LIB_krb4) \ + $(LIB_des) \ + $(top_builddir)/lib/asn1/libasn1.la \ + $(LIB_roken) \ + $(DBLIB) + + +LDADD = $(top_builddir)/lib/hdb/libhdb.la \ + $(LIB_openldap) \ + $(top_builddir)/lib/krb5/libkrb5.la \ + $(LIB_krb4) \ + $(LIB_des) \ + $(top_builddir)/lib/asn1/libasn1.la \ + $(LIB_roken) \ + $(DBLIB) + + +kdc_LDADD = $(LDADD) $(LIB_pidfile) +subdir = kdc mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = ../include/config.h CONFIG_CLEAN_FILES = @@ -211,61 +263,61 @@ PROGRAMS = $(bin_PROGRAMS) $(libexec_PROGRAMS) $(sbin_PROGRAMS) DEFS = @DEFS@ -I. -I$(srcdir) -I../include CPPFLAGS = @CPPFLAGS@ LDFLAGS = @LDFLAGS@ -LIBS = @LIBS@ X_CFLAGS = @X_CFLAGS@ X_LIBS = @X_LIBS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ -string2key_OBJECTS = string2key.$(OBJEXT) -string2key_LDADD = $(LDADD) -string2key_DEPENDENCIES = $(top_builddir)/lib/hdb/libhdb.la \ -$(top_builddir)/lib/krb5/libkrb5.la $(top_builddir)/lib/des/libdes.la \ -$(top_builddir)/lib/asn1/libasn1.la -string2key_LDFLAGS = -hprop_OBJECTS = hprop.$(OBJEXT) hprop-common.$(OBJEXT) +am_hprop_OBJECTS = hprop.$(OBJEXT) mit_dump.$(OBJEXT) v4_dump.$(OBJEXT) +hprop_OBJECTS = $(am_hprop_OBJECTS) hprop_DEPENDENCIES = $(top_builddir)/lib/hdb/libhdb.la \ -$(top_builddir)/lib/krb5/libkrb5.la $(top_builddir)/lib/des/libdes.la \ -$(top_builddir)/lib/asn1/libasn1.la +$(top_builddir)/lib/krb5/libkrb5.la $(top_builddir)/lib/asn1/libasn1.la hprop_LDFLAGS = -hpropd_OBJECTS = hpropd.$(OBJEXT) hprop-common.$(OBJEXT) +am_hpropd_OBJECTS = hpropd.$(OBJEXT) +hpropd_OBJECTS = $(am_hpropd_OBJECTS) hpropd_DEPENDENCIES = $(top_builddir)/lib/hdb/libhdb.la \ -$(top_builddir)/lib/krb5/libkrb5.la $(top_builddir)/lib/des/libdes.la \ -$(top_builddir)/lib/asn1/libasn1.la +$(top_builddir)/lib/krb5/libkrb5.la $(top_builddir)/lib/asn1/libasn1.la hpropd_LDFLAGS = -kdc_OBJECTS = 524.$(OBJEXT) config.$(OBJEXT) connect.$(OBJEXT) \ +am_kdc_OBJECTS = 524.$(OBJEXT) config.$(OBJEXT) connect.$(OBJEXT) \ kaserver.$(OBJEXT) kerberos4.$(OBJEXT) kerberos5.$(OBJEXT) \ log.$(OBJEXT) main.$(OBJEXT) misc.$(OBJEXT) -kdc_LDADD = $(LDADD) +kdc_OBJECTS = $(am_kdc_OBJECTS) kdc_DEPENDENCIES = $(top_builddir)/lib/hdb/libhdb.la \ -$(top_builddir)/lib/krb5/libkrb5.la $(top_builddir)/lib/des/libdes.la \ -$(top_builddir)/lib/asn1/libasn1.la +$(top_builddir)/lib/krb5/libkrb5.la $(top_builddir)/lib/asn1/libasn1.la kdc_LDFLAGS = -kstash_OBJECTS = kstash.$(OBJEXT) +am_kstash_OBJECTS = kstash.$(OBJEXT) +kstash_OBJECTS = $(am_kstash_OBJECTS) kstash_LDADD = $(LDADD) kstash_DEPENDENCIES = $(top_builddir)/lib/hdb/libhdb.la \ -$(top_builddir)/lib/krb5/libkrb5.la $(top_builddir)/lib/des/libdes.la \ -$(top_builddir)/lib/asn1/libasn1.la +$(top_builddir)/lib/krb5/libkrb5.la $(top_builddir)/lib/asn1/libasn1.la kstash_LDFLAGS = -CFLAGS = @CFLAGS@ +am_string2key_OBJECTS = string2key.$(OBJEXT) +string2key_OBJECTS = $(am_string2key_OBJECTS) +string2key_LDADD = $(LDADD) +string2key_DEPENDENCIES = $(top_builddir)/lib/hdb/libhdb.la \ +$(top_builddir)/lib/krb5/libkrb5.la $(top_builddir)/lib/asn1/libasn1.la +string2key_LDFLAGS = COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CFLAGS = @CFLAGS@ CCLD = $(CC) -LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ +LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +DIST_SOURCES = $(hprop_SOURCES) $(hpropd_SOURCES) $(kdc_SOURCES) \ +$(kstash_SOURCES) $(string2key_SOURCES) man8dir = $(mandir)/man8 MANS = $(man_MANS) +depcomp = DIST_COMMON = Makefile.am Makefile.in -DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -TAR = tar GZIP_ENV = --best -SOURCES = $(string2key_SOURCES) $(hprop_SOURCES) $(hpropd_SOURCES) $(kdc_SOURCES) $(kstash_SOURCES) -OBJECTS = $(string2key_OBJECTS) $(hprop_OBJECTS) $(hpropd_OBJECTS) $(kdc_OBJECTS) $(kstash_OBJECTS) +SOURCES = $(hprop_SOURCES) $(hpropd_SOURCES) $(kdc_SOURCES) $(kstash_SOURCES) $(string2key_SOURCES) +OBJECTS = $(am_hprop_OBJECTS) $(am_hpropd_OBJECTS) $(am_kdc_OBJECTS) $(am_kstash_OBJECTS) $(am_string2key_OBJECTS) all: all-redirect .SUFFIXES: -.SUFFIXES: .1 .3 .5 .8 .S .c .cat1 .cat3 .cat5 .cat8 .et .h .lo .o .obj .s .x +.SUFFIXES: .1 .3 .5 .8 .c .cat1 .cat3 .cat5 .cat8 .et .h .lo .o .obj .x $(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) $(top_srcdir)/Makefile.am.common $(top_srcdir)/cf/Makefile.am.common cd $(top_srcdir) && $(AUTOMAKE) --foreign kdc/Makefile @@ -288,15 +340,18 @@ install-binPROGRAMS: $(bin_PROGRAMS) $(mkinstalldirs) $(DESTDIR)$(bindir) @list='$(bin_PROGRAMS)'; for p in $$list; do \ if test -f $$p; then \ - echo " $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \ - $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \ + f="`echo $$p|sed -e 's/$(EXEEXT)$$//' -e '$(transform)' -e 's/$$/$(EXEEXT)/'`"; \ + echo " $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $(INSTALL_STRIP_FLAG) $$p $(DESTDIR)$(bindir)/$$f"; \ + $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $(INSTALL_STRIP_FLAG) $$p $(DESTDIR)$(bindir)/$$f; \ else :; fi; \ done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) - list='$(bin_PROGRAMS)'; for p in $$list; do \ - rm -f $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \ + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + f="`echo $$p|sed -e 's/$(EXEEXT)$$//' -e '$(transform)' -e 's/$$/$(EXEEXT)/'`"; \ + echo " rm -f $(DESTDIR)$(bindir)/$$f"; \ + rm -f $(DESTDIR)$(bindir)/$$f; \ done mostlyclean-libexecPROGRAMS: @@ -313,15 +368,18 @@ install-libexecPROGRAMS: $(libexec_PROGRAMS) $(mkinstalldirs) $(DESTDIR)$(libexecdir) @list='$(libexec_PROGRAMS)'; for p in $$list; do \ if test -f $$p; then \ - echo " $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(libexecdir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \ - $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(libexecdir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \ + f="`echo $$p|sed -e 's/$(EXEEXT)$$//' -e '$(transform)' -e 's/$$/$(EXEEXT)/'`"; \ + echo " $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $(INSTALL_STRIP_FLAG) $$p $(DESTDIR)$(libexecdir)/$$f"; \ + $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $(INSTALL_STRIP_FLAG) $$p $(DESTDIR)$(libexecdir)/$$f; \ else :; fi; \ done uninstall-libexecPROGRAMS: @$(NORMAL_UNINSTALL) - list='$(libexec_PROGRAMS)'; for p in $$list; do \ - rm -f $(DESTDIR)$(libexecdir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \ + @list='$(libexec_PROGRAMS)'; for p in $$list; do \ + f="`echo $$p|sed -e 's/$(EXEEXT)$$//' -e '$(transform)' -e 's/$$/$(EXEEXT)/'`"; \ + echo " rm -f $(DESTDIR)$(libexecdir)/$$f"; \ + rm -f $(DESTDIR)$(libexecdir)/$$f; \ done mostlyclean-sbinPROGRAMS: @@ -338,31 +396,20 @@ install-sbinPROGRAMS: $(sbin_PROGRAMS) $(mkinstalldirs) $(DESTDIR)$(sbindir) @list='$(sbin_PROGRAMS)'; for p in $$list; do \ if test -f $$p; then \ - echo " $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(sbindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \ - $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(sbindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \ + f="`echo $$p|sed -e 's/$(EXEEXT)$$//' -e '$(transform)' -e 's/$$/$(EXEEXT)/'`"; \ + echo " $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $(INSTALL_STRIP_FLAG) $$p $(DESTDIR)$(sbindir)/$$f"; \ + $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $(INSTALL_STRIP_FLAG) $$p $(DESTDIR)$(sbindir)/$$f; \ else :; fi; \ done uninstall-sbinPROGRAMS: @$(NORMAL_UNINSTALL) - list='$(sbin_PROGRAMS)'; for p in $$list; do \ - rm -f $(DESTDIR)$(sbindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \ + @list='$(sbin_PROGRAMS)'; for p in $$list; do \ + f="`echo $$p|sed -e 's/$(EXEEXT)$$//' -e '$(transform)' -e 's/$$/$(EXEEXT)/'`"; \ + echo " rm -f $(DESTDIR)$(sbindir)/$$f"; \ + rm -f $(DESTDIR)$(sbindir)/$$f; \ done -.c.o: - $(COMPILE) -c $< - -# FIXME: We should only use cygpath when building on Windows, -# and only if it is available. -.c.obj: - $(COMPILE) -c `cygpath -w $<` - -.s.o: - $(COMPILE) -c $< - -.S.o: - $(COMPILE) -c $< - mostlyclean-compile: -rm -f *.o core *.core -rm -f *.$(OBJEXT) @@ -374,15 +421,6 @@ distclean-compile: maintainer-clean-compile: -.c.lo: - $(LIBTOOL) --mode=compile $(COMPILE) -c $< - -.s.lo: - $(LIBTOOL) --mode=compile $(COMPILE) -c $< - -.S.lo: - $(LIBTOOL) --mode=compile $(COMPILE) -c $< - mostlyclean-libtool: -rm -f *.lo @@ -393,10 +431,6 @@ distclean-libtool: maintainer-clean-libtool: -string2key$(EXEEXT): $(string2key_OBJECTS) $(string2key_DEPENDENCIES) - @rm -f string2key$(EXEEXT) - $(LINK) $(string2key_LDFLAGS) $(string2key_OBJECTS) $(string2key_LDADD) $(LIBS) - hprop$(EXEEXT): $(hprop_OBJECTS) $(hprop_DEPENDENCIES) @rm -f hprop$(EXEEXT) $(LINK) $(hprop_LDFLAGS) $(hprop_OBJECTS) $(hprop_LDADD) $(LIBS) @@ -413,6 +447,16 @@ kstash$(EXEEXT): $(kstash_OBJECTS) $(kstash_DEPENDENCIES) @rm -f kstash$(EXEEXT) $(LINK) $(kstash_LDFLAGS) $(kstash_OBJECTS) $(kstash_LDADD) $(LIBS) +string2key$(EXEEXT): $(string2key_OBJECTS) $(string2key_DEPENDENCIES) + @rm -f string2key$(EXEEXT) + $(LINK) $(string2key_LDFLAGS) $(string2key_OBJECTS) $(string2key_LDADD) $(LIBS) +.c.o: + $(COMPILE) -c $< +.c.obj: + $(COMPILE) -c `cygpath -w $<` +.c.lo: + $(LTCOMPILE) -c -o $@ $< + install-man8: $(mkinstalldirs) $(DESTDIR)$(man8dir) @list='$(man8_MANS)'; \ @@ -426,6 +470,7 @@ install-man8: else file=$$i; fi; \ ext=`echo $$i | sed -e 's/^.*\\.//'`; \ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ + inst=`echo $$inst | sed -e 's/^.*\///'`; \ inst=`echo $$inst | sed '$(transform)'`.$$ext; \ echo " $(INSTALL_DATA) $$file $(DESTDIR)$(man8dir)/$$inst"; \ $(INSTALL_DATA) $$file $(DESTDIR)$(man8dir)/$$inst; \ @@ -441,6 +486,7 @@ uninstall-man8: for i in $$list; do \ ext=`echo $$i | sed -e 's/^.*\\.//'`; \ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ + inst=`echo $$inst | sed -e 's/^.*\///'`; \ inst=`echo $$inst | sed '$(transform)'`.$$ext; \ echo " rm -f $(DESTDIR)$(man8dir)/$$inst"; \ rm -f $(DESTDIR)$(man8dir)/$$inst; \ @@ -454,23 +500,27 @@ uninstall-man: tags: TAGS -ID: $(HEADERS) $(SOURCES) $(LISP) - list='$(SOURCES) $(HEADERS)'; \ - unique=`for i in $$list; do echo $$i; done | \ - awk ' { files[$$0] = 1; } \ +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ - here=`pwd` && cd $(srcdir) \ - && mkid -f$$here/ID $$unique $(LISP) + mkid -fID $$unique $(LISP) -TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ - list='$(SOURCES) $(HEADERS)'; \ - unique=`for i in $$list; do echo $$i; done | \ - awk ' { files[$$0] = 1; } \ + list='$(SOURCES) $(HEADERS) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ - || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS) + || etags $(ETAGS_ARGS) $$tags $$unique $(LISP) mostlyclean-tags: @@ -483,17 +533,16 @@ maintainer-clean-tags: distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) -subdir = kdc - distdir: $(DISTFILES) @for file in $(DISTFILES); do \ d=$(srcdir); \ if test -d $$d/$$file; then \ - cp -pr $$/$$file $(distdir)/$$file; \ + cp -pR $$d/$$file $(distdir) \ + || exit 1; \ else \ test -f $(distdir)/$$file \ - || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ - || cp -p $$d/$$file $(distdir)/$$file || :; \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ fi; \ done $(MAKE) $(AM_MAKEFLAGS) top_distdir="$(top_distdir)" distdir="$(distdir)" dist-hook @@ -524,7 +573,7 @@ uninstall: uninstall-am all-am: Makefile $(PROGRAMS) $(MANS) all-local all-redirect: all-am install-strip: - $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install + $(MAKE) $(AM_MAKEFLAGS) INSTALL_STRIP_FLAG=-s install installdirs: $(mkinstalldirs) $(DESTDIR)$(bindir) $(DESTDIR)$(libexecdir) \ $(DESTDIR)$(sbindir) $(DESTDIR)$(mandir)/man8 @@ -539,6 +588,7 @@ distclean-generic: -rm -f config.cache config.log stamp-h stamp-h[0-9]* maintainer-clean-generic: + -rm -f Makefile.in mostlyclean-am: mostlyclean-binPROGRAMS mostlyclean-libexecPROGRAMS \ mostlyclean-sbinPROGRAMS mostlyclean-compile \ mostlyclean-libtool mostlyclean-tags \ @@ -585,7 +635,7 @@ distclean-tags clean-tags maintainer-clean-tags distdir info-am info \ dvi-am dvi check-local check check-am installcheck-am installcheck \ install-exec-am install-exec install-data-local install-data-am \ install-data install-am install uninstall-am uninstall all-local \ -all-redirect all-am all installdirs mostlyclean-generic \ +all-redirect all-am all install-strip installdirs mostlyclean-generic \ distclean-generic clean-generic maintainer-clean-generic clean \ mostlyclean distclean maintainer-clean @@ -595,7 +645,10 @@ install-suid-programs: for file in $$foo; do \ x=$(DESTDIR)$(bindir)/$$file; \ if chown 0:0 $$x && chmod u+s $$x; then :; else \ - chmod 0 $$x; fi; done + echo "*"; \ + echo "* Failed to install $$x setuid root"; \ + echo "*"; \ + fi; done install-exec-hook: install-suid-programs @@ -607,8 +660,8 @@ install-build-headers:: $(include_HEADERS) $(build_HEADERZ) else file="$$f"; fi; \ if cmp -s $$file $(buildinclude)/$$f 2> /dev/null ; then \ : ; else \ - echo " cp $$file $(buildinclude)/$$f"; \ - cp $$file $(buildinclude)/$$f; \ + echo " $(CP) $$file $(buildinclude)/$$f"; \ + $(CP) $$file $(buildinclude)/$$f; \ fi ; \ done @@ -677,87 +730,8 @@ dist-cat8-mans: dist-hook: dist-cat1-mans dist-cat3-mans dist-cat5-mans dist-cat8-mans -install-cat1-mans: - @ext=1;\ - foo='$(man1_MANS)'; \ - bar='$(man_MANS)'; \ - for i in $$bar; do \ - case $$i in \ - *.1) foo="$$foo $$i";; \ - esac; done; \ - if test "$$foo"; then \ - $(mkinstalldirs) $(DESTDIR)$(cat1dir); \ - for x in $$foo; do \ - f=`echo $$x | sed 's/\.[^.]*$$/.cat1/'`; \ - if test -f "$(srcdir)/$$f"; then \ - b=`echo $$x | sed 's!$(MANRX)!\1!'`; \ - echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat1dir)/$$b.$(CATSUFFIX)";\ - $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat1dir)/$$b.$(CATSUFFIX);\ - fi; \ - done ;\ - fi - -install-cat3-mans: - @ext=3;\ - foo='$(man3_MANS)'; \ - bar='$(man_MANS)'; \ - for i in $$bar; do \ - case $$i in \ - *.3) foo="$$foo $$i";; \ - esac; done; \ - if test "$$foo"; then \ - $(mkinstalldirs) $(DESTDIR)$(cat3dir); \ - for x in $$foo; do \ - f=`echo $$x | sed 's/\.[^.]*$$/.cat3/'`; \ - if test -f "$(srcdir)/$$f"; then \ - b=`echo $$x | sed 's!$(MANRX)!\1!'`; \ - echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat3dir)/$$b.$(CATSUFFIX)";\ - $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat3dir)/$$b.$(CATSUFFIX);\ - fi; \ - done ;\ - fi - -install-cat5-mans: - @ext=5;\ - foo='$(man5_MANS)'; \ - bar='$(man_MANS)'; \ - for i in $$bar; do \ - case $$i in \ - *.5) foo="$$foo $$i";; \ - esac; done; \ - if test "$$foo"; then \ - $(mkinstalldirs) $(DESTDIR)$(cat5dir); \ - for x in $$foo; do \ - f=`echo $$x | sed 's/\.[^.]*$$/.cat5/'`; \ - if test -f "$(srcdir)/$$f"; then \ - b=`echo $$x | sed 's!$(MANRX)!\1!'`; \ - echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat5dir)/$$b.$(CATSUFFIX)";\ - $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat5dir)/$$b.$(CATSUFFIX);\ - fi; \ - done ;\ - fi - -install-cat8-mans: - @ext=8;\ - foo='$(man8_MANS)'; \ - bar='$(man_MANS)'; \ - for i in $$bar; do \ - case $$i in \ - *.8) foo="$$foo $$i";; \ - esac; done; \ - if test "$$foo"; then \ - $(mkinstalldirs) $(DESTDIR)$(cat8dir); \ - for x in $$foo; do \ - f=`echo $$x | sed 's/\.[^.]*$$/.cat8/'`; \ - if test -f "$(srcdir)/$$f"; then \ - b=`echo $$x | sed 's!$(MANRX)!\1!'`; \ - echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat8dir)/$$b.$(CATSUFFIX)";\ - $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat8dir)/$$b.$(CATSUFFIX);\ - fi; \ - done ;\ - fi - -install-cat-mans: install-cat1-mans install-cat3-mans install-cat5-mans install-cat8-mans +install-cat-mans: + $(SHELL) $(top_srcdir)/cf/install-catman.sh "$(INSTALL_DATA)" "$(mkinstalldirs)" "$(srcdir)" "$(DESTDIR)$(mandir)" '$(CATMANEXT)' $(man_MANS) $(man1_MANS) $(man3_MANS) $(man5_MANS) $(man8_MANS) install-data-local: install-cat-mans diff --git a/crypto/heimdal/kdc/config.c b/crypto/heimdal/kdc/config.c index 3db7173..0621db1 100644 --- a/crypto/heimdal/kdc/config.c +++ b/crypto/heimdal/kdc/config.c @@ -35,7 +35,7 @@ #include <getarg.h> #include <parse_bytes.h> -RCSID("$Id: config.c,v 1.30 2000/02/11 17:47:19 assar Exp $"); +RCSID("$Id: config.c,v 1.33 2000/09/10 19:27:17 joda Exp $"); static char *config_file; /* location of kdc config file */ @@ -58,12 +58,15 @@ krb5_boolean encode_as_rep_as_tgs_rep; /* bug compatibility */ krb5_boolean check_ticket_addresses; krb5_boolean allow_null_ticket_addresses; +krb5_boolean allow_anonymous; static struct getarg_strings addresses_str; /* addresses to listen on */ krb5_addresses explicit_addresses; #ifdef KRB4 char *v4_realm; +int enable_v4 = -1; +int enable_524 = -1; #endif #ifdef KASERVER krb5_boolean enable_kaserver = -1; @@ -93,6 +96,12 @@ static struct getargs args[] = { #endif { "enable-http", 'H', arg_flag, &enable_http, "turn on HTTP support" }, #ifdef KRB4 + { "kerberos4", 0, arg_negative_flag, &enable_v4, + "don't respond to kerberos 4 requests" + }, + { "524", 0, arg_negative_flag, &enable_524, + "don't respond to 524 requests" + }, { "v4-realm", 'r', arg_string, &v4_realm, "realm to serve v4-requests for" @@ -239,7 +248,7 @@ configure(int argc, char **argv) usage(1); if(config_file == NULL) - config_file = HDB_DB_DIR "/kdc.conf"; + config_file = _PATH_KDC_CONF; if(krb5_config_parse_file(config_file, &cf)) cf = NULL; @@ -288,6 +297,15 @@ configure(int argc, char **argv) } } +#ifdef KRB4 + if(enable_v4 == -1) + enable_v4 = krb5_config_get_bool_default(context, cf, TRUE, "kdc", + "enable-kerberos4", NULL); + if(enable_524 == -1) + enable_524 = krb5_config_get_bool_default(context, cf, enable_v4, + "kdc", "enable-524", NULL); +#endif + if(enable_http == -1) enable_http = krb5_config_get_bool(context, cf, "kdc", "enable-http", NULL); @@ -297,6 +315,10 @@ configure(int argc, char **argv) allow_null_ticket_addresses = krb5_config_get_bool(context, cf, "kdc", "allow-null-ticket-addresses", NULL); + + allow_anonymous = + krb5_config_get_bool(context, cf, "kdc", + "allow-anonymous", NULL); #ifdef KRB4 if(v4_realm == NULL){ p = krb5_config_get_string (context, cf, diff --git a/crypto/heimdal/kdc/connect.c b/crypto/heimdal/kdc/connect.c index 0ce23b5..4533cea 100644 --- a/crypto/heimdal/kdc/connect.c +++ b/crypto/heimdal/kdc/connect.c @@ -33,7 +33,7 @@ #include "kdc_locl.h" -RCSID("$Id: connect.c,v 1.70 2000/02/19 18:41:24 assar Exp $"); +RCSID("$Id: connect.c,v 1.80 2000/10/08 21:36:29 assar Exp $"); /* * a tuple describing on what to listen @@ -129,10 +129,18 @@ add_standard_ports (int family) add_port_service(family, "kerberos", 88, "tcp"); add_port_service(family, "kerberos-sec", 88, "udp"); add_port_service(family, "kerberos-sec", 88, "tcp"); - add_port_service(family, "kerberos-iv", 750, "udp"); - add_port_service(family, "kerberos-iv", 750, "tcp"); if(enable_http) add_port_service(family, "http", 80, "tcp"); +#ifdef KRB4 + if(enable_v4) { + add_port_service(family, "kerberos-iv", 750, "udp"); + add_port_service(family, "kerberos-iv", 750, "tcp"); + } + if(enable_524) { + add_port_service(family, "krb524", 4444, "udp"); + add_port_service(family, "krb524", 4444, "tcp"); + } +#endif #ifdef KASERVER if (enable_kaserver) add_port_service(family, "afs3-kaserver", 7004, "udp"); @@ -195,10 +203,31 @@ struct descr { time_t timeout; struct sockaddr_storage __ss; struct sockaddr *sa; - int sock_len; + socklen_t sock_len; char addr_string[128]; }; +static void +init_descr(struct descr *d) +{ + memset(d, 0, sizeof(*d)); + d->sa = (struct sockaddr *)&d->__ss; + d->s = -1; +} + +/* + * re-intialize all `n' ->sa in `d'. + */ + +static void +reinit_descrs (struct descr *d, int n) +{ + int i; + + for (i = 0; i < n; ++i) + d[i].sa = (struct sockaddr *)&d[i].__ss; +} + /* * Create the socket (family, type, port) in `d' */ @@ -211,9 +240,7 @@ init_socket(struct descr *d, krb5_address *a, int family, int type, int port) struct sockaddr *sa = (struct sockaddr *)&__ss; int sa_size; - memset(d, 0, sizeof(*d)); - d->sa = (struct sockaddr *)&d->__ss; - d->s = -1; + init_descr (d); ret = krb5_addr2sockaddr (a, sa, &sa_size, port); if (ret) { @@ -286,7 +313,8 @@ init_sockets(struct descr **desc) parse_ports(port_str); d = malloc(addresses.len * num_ports * sizeof(*d)); if (d == NULL) - krb5_errx(context, 1, "malloc(%u) failed", num_ports * sizeof(*d)); + krb5_errx(context, 1, "malloc(%lu) failed", + (unsigned long)num_ports * sizeof(*d)); for (i = 0; i < num_ports; i++){ for (j = 0; j < addresses.len; ++j) { @@ -311,7 +339,9 @@ init_sockets(struct descr **desc) krb5_free_addresses (context, &addresses); d = realloc(d, num * sizeof(*d)); if (d == NULL && num != 0) - krb5_errx(context, 1, "realloc(%u) failed", num * sizeof(*d)); + krb5_errx(context, 1, "realloc(%lu) failed", + (unsigned long)num * sizeof(*d)); + reinit_descrs (d, num); *desc = d; return num; } @@ -482,30 +512,35 @@ de_http(char *buf) #define TCP_TIMEOUT 4 /* - * accept a new TCP connection on `d[index]' + * accept a new TCP connection on `d[parent]' and store it in `d[child]' */ static void -add_new_tcp (struct descr *d, int index, int min_free) +add_new_tcp (struct descr *d, int parent, int child) { int s; - d->sock_len = sizeof(d->__ss); - s = accept(d[index].s, d->sa, &d->sock_len); + if (child == -1) + return; + + d[child].sock_len = sizeof(d[child].__ss); + s = accept(d[parent].s, d[child].sa, &d[child].sock_len); if(s < 0) { krb5_warn(context, errno, "accept"); return; } - if(min_free == -1){ - close(s); + + if (s >= FD_SETSIZE) { + krb5_warnx(context, "socket FD too large"); + close (s); return; } - - d[min_free].s = s; - d[min_free].timeout = time(NULL) + TCP_TIMEOUT; - d[min_free].type = SOCK_STREAM; - addr_to_string (d[min_free].sa, d[min_free].sock_len, - d[min_free].addr_string, sizeof(d[min_free].addr_string)); + + d[child].s = s; + d[child].timeout = time(NULL) + TCP_TIMEOUT; + d[child].type = SOCK_STREAM; + addr_to_string (d[child].sa, d[child].sock_len, + d[child].addr_string, sizeof(d[child].addr_string)); } /* @@ -556,7 +591,7 @@ handle_vanilla_tcp (struct descr *d) krb5_ret_int32(sp, &len); krb5_storage_free(sp); if(d->len - 4 >= len) { - memcpy(d->buf, d->buf + 4, d->len - 4); + memmove(d->buf, d->buf + 4, d->len - 4); return 1; } return 0; @@ -709,8 +744,9 @@ loop(void) int min_free = -1; int max_fd = 0; int i; + FD_ZERO(&fds); - for(i = 0; i < ndescr; i++){ + for(i = 0; i < ndescr; i++) { if(d[i].s >= 0){ if(d[i].type == SOCK_STREAM && d[i].timeout && d[i].timeout < time(NULL)) { @@ -721,8 +757,10 @@ loop(void) } if(max_fd < d[i].s) max_fd = d[i].s; + if (max_fd >= FD_SETSIZE) + krb5_errx(context, 1, "fd too large"); FD_SET(d[i].s, &fds); - }else if(min_free < 0 || i < min_free) + } else if(min_free < 0 || i < min_free) min_free = i; } if(min_free == -1){ @@ -730,11 +768,12 @@ loop(void) tmp = realloc(d, (ndescr + 4) * sizeof(*d)); if(tmp == NULL) krb5_warnx(context, "No memory"); - else{ + else { d = tmp; + reinit_descrs (d, ndescr); memset(d + ndescr, 0, 4 * sizeof(*d)); for(i = ndescr; i < ndescr + 4; i++) - d[i].s = -1; + init_descr (&d[i]); min_free = ndescr; ndescr += 4; } diff --git a/crypto/heimdal/kdc/hprop.8 b/crypto/heimdal/kdc/hprop.8 index d700577..441b14d 100644 --- a/crypto/heimdal/kdc/hprop.8 +++ b/crypto/heimdal/kdc/hprop.8 @@ -1,6 +1,6 @@ -.\" $Id: hprop.8,v 1.3 1997/09/03 20:33:04 joda Exp $ +.\" $Id: hprop.8,v 1.8 2001/01/30 04:18:41 assar Exp $ .\" -.Dd September 3, 1997 +.Dd June 19, 2000 .Dt HPROP 8 .Os HEIMDAL .Sh NAME @@ -9,58 +9,159 @@ propagate the KDC database .Sh SYNOPSIS .Nm -.Op Fl 4DEhnv -.Op Fl d Ar file -.Op Fl -database= Ns Ar file -.Op Fl -decrypt -.Op Fl -encrypt -.Op Fl -help -.Op Fl k -.Op Fl -keytab= Ns Ar file -.Op Fl m Ar file -.Op Fl -master-key= Ns Ar file -.Op Fl -stdout -.Op Fl -v4-db -.Op Fl -verbose +.Oo Fl m Ar file \*(Ba Xo +.Fl -master-key= Ns Pa file Oc +.Xc +.Oo Fl d Ar file \*(Ba Xo +.Fl -database= Ns Pa file Oc +.Xc +.Op Fl -source= Ns Ar heimdal|mit-dump|krb4-db|krb4-dump +.Op Fl 4 | Fl -v4-db +.Op Fl K | Fl -ka-db +.Oo Fl c Ar cell \*(Ba Xo +.Fl -cell= Ns Ar cell Oc +.Xc +.Op Fl S | Fl -kaspecials +.Oo Fl r Ar string \*(Ba Xo +.Fl -v4-realm= Ns Ar string Oc +.Xc +.Oo Fl k Ar keytab \*(Ba Xo +.Fl -keytab= Ns Ar keytab Oc +.Xc +.Oo Fl R Ar string \*(Ba Xo +.Fl -v5-realm= Ns Ar string Oc +.Xc +.Op Fl D | Fl -decrypt +.Op Fl E | Fl -encrypt +.Op Fl n | Fl -stdout +.Op Fl v | Fl -verbose .Op Fl -version -.Ar host ... +.Op Fl h | Fl -help +.Ar host Ns Op :port +... .Sh DESCRIPTION .Nm -propagates the database from a master KDC to a slave. It connects to -all +takes a principal database in a specified format and converts it into +a stream of Heimdal database records. This stream can either be +written to standard out, or (more commonly) be propagated to a +.Xr hpropd 8 +server running on a different machine. +.Pp +If propagating, it connects to all .Ar hosts specified on the command by opening a TCP connection to port 754 (service hprop) and sends the database in encrypted form. .Pp -Options supported: +Supported options: .Bl -tag -width Ds -.It Fl d Ar file -.It Fl -database= Ns Ar file +.It Xo +.Fl m Ar file Ns , +.Fl -master-key= Ns Pa file +.Xc +Where to find the master key to encrypt or decrypt keys with. +.It Xo +.Fl d Ar file Ns , +.Fl -database= Ns Pa file +.Xc The database to be propagated. -.It Fl D -.It Fl -decrypt +.It Xo +.Fl -source= Ns Ar heimdal|mit-dump|krb4-db|krb4-dump +.Xc +Specifies the type of the source database. Alternatives include: +.Bl -tag -width krb4-dump +.It heimdal +a Heimdal database +.It mit-dump +a MIT Kerberos 5 dump file +.It krb4-db +a Kerberos 4 database +.It krb4-dump +a Kerberos 4 dump file +.It kaserver +a Transarc kaserver database +.El +.It Xo +.Fl k Ar keytab Ns , +.Fl -keytab= Ns Ar keytab +.Xc +The keytab to use for fetching the key to be used for authenticating +to the propagation daemon(s). The key +.Pa kadmin/hprop +is used from this keytab. The default is to fetch the key from the +KDC database. +.It Xo +.Fl R Ar string Ns , +.Fl -v5-realm= Ns Ar string +.Xc +Local realm override. +.It Xo +.Fl D Ns , +.Fl -decrypt +.Xc The encryption keys in the database can either be in clear, or encrypted with a master key. This option thansmits the database with unencrypted keys. -.It Fl E -.It Fl -encrypt +.It Xo +.Fl E Ns , +.Fl -encrypt +.Xc This option thansmits the database with encrypted keys. -.It Fl k -.It Fl -keytab= Ns Ar file -The keytab to use for fetching the key to be used for authenticating -to the propagation daemon(s). The key -.Pa kadmin/hprop -is used from this keytab. -.It Fl m Ar file -.It Fl -master-key= Ns Ar file -Where to find the master key to encrypt or decrypt keys with. -.It Fl n -.It Fl -stdout +.It Xo +.Fl n Ns , +.Fl -stdout +.Xc Dump the database on stdout, in a format that can be fed to hpropd. -.It Fl 4 -.It Fl -v4-db -Use a version 4 database. This option is only available if the code is -compiled with Kerberos 4 support. .El + +The following options are only valid if +.Nm hprop +is compiled with support for Kerberos 4 (kaserver). +.Bl -tag -width Ds +.It Xo +.Fl r Ar string Ns , +.Fl -v4-realm= Ns Ar string +.Xc +v4 realm to use +.It Xo +.Fl c Ar cell Ns , +.Fl -cell= Ns Ar cell +.Xc +The AFS cell name, used if reading a kaserver database. +.It Xo +.Fl S Ns , +.Fl -kaspecials +.Xc +Also dump the principals marked as special in the kaserver database. +.It Xo +.Fl 4 Ns , +.Fl -v4-db +.Xc +Deprecated, identical to +.Sq --source=krb4-db . +.It Xo +.Fl K Ns , +.Fl -ka-db +.Xc +Deprecated, identical to +.Sq --source=kaserver . +.El + +.Sh EXAMPLES +The following will propagate a database to another machine (which +should run +.Xr hpropd 8): +.Bd -literal -offset indent +$ hprop slave-1 slave-2 +.Ed + +Copy a Kerberos 4 database to a Kerberos 5 slave: +.Bd -literal -offset indent +$ hprop --source=krb4-db -E krb5-slave +.Ed + +Convert a Kerberos 4 dump-file for use with a Heimdal KDC: +.Bd -literal -offset indent +$ hprop -n --source=krb4-dump -d /var/kerberos/principal.dump -E | hpropd -n +.Ed .Sh SEE ALSO .Xr hpropd 8 diff --git a/crypto/heimdal/kdc/hprop.c b/crypto/heimdal/kdc/hprop.c index 3be6a6f..8ce9f10 100644 --- a/crypto/heimdal/kdc/hprop.c +++ b/crypto/heimdal/kdc/hprop.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan + * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -33,7 +33,7 @@ #include "hprop.h" -RCSID("$Id: hprop.c,v 1.40 1999/12/04 18:02:18 assar Exp $"); +RCSID("$Id: hprop.c,v 1.60 2001/02/05 03:40:00 assar Exp $"); static int version_flag; static int help_flag; @@ -44,38 +44,40 @@ static int to_stdout; static int verbose_flag; static int encrypt_flag; static int decrypt_flag; -static EncryptionKey mkey5; -static krb5_data msched5; +static hdb_master_key mkey5; + +static char *source_type; -static int v4_db; -static int ka_db; static char *afs_cell; +static char *realm; #ifdef KRB4 -static char *realm; +static int v4_db; + +static des_cblock mkey4; +static des_key_schedule msched4; #ifdef KASERVER_DB static int kaspecials_flag; +static int ka_db; +static int ka_use_null_salt; #endif #endif +static char *local_realm=NULL; + static int -open_socket(krb5_context context, const char *hostname) +open_socket(krb5_context context, const char *hostname, const char *port) { struct addrinfo *ai, *a; struct addrinfo hints; int error; - char portstr[NI_MAXSERV]; memset (&hints, 0, sizeof(hints)); hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; - snprintf (portstr, sizeof(portstr), - "%u", - ntohs(krb5_getportbyname (context, "hprop", "tcp", HPROP_PORT))); - - error = getaddrinfo (hostname, portstr, &hints, &ai); + error = getaddrinfo (hostname, port, &hints, &ai); if (error) { warnx ("%s: %s", hostname, gai_strerror(error)); return -1; @@ -100,44 +102,117 @@ open_socket(krb5_context context, const char *hostname) return -1; } -struct prop_data{ - krb5_context context; - krb5_auth_context auth_context; - int sock; -}; - -int hdb_entry2value(krb5_context, hdb_entry*, krb5_data*); - -static krb5_error_code +krb5_error_code v5_prop(krb5_context context, HDB *db, hdb_entry *entry, void *appdata) { krb5_error_code ret; struct prop_data *pd = appdata; krb5_data data; - if(encrypt_flag) - _hdb_seal_keys_int(entry, 0, msched5); - if(decrypt_flag) - _hdb_unseal_keys_int(entry, 0, msched5); + if(encrypt_flag) { + ret = hdb_seal_keys_mkey(context, entry, mkey5); + if (ret) { + krb5_warn(context, ret, "hdb_seal_keys_mkey"); + return ret; + } + } + if(decrypt_flag) { + ret = hdb_unseal_keys_mkey(context, entry, mkey5); + if (ret) { + krb5_warn(context, ret, "hdb_unseal_keys_mkey"); + return ret; + } + } ret = hdb_entry2value(context, entry, &data); - if(ret) return ret; + if(ret) { + krb5_warn(context, ret, "hdb_entry2value"); + return ret; + } if(to_stdout) - ret = send_clear(context, STDOUT_FILENO, data); + ret = krb5_write_message(context, &pd->sock, &data); else - ret = send_priv(context, pd->auth_context, &data, pd->sock); + ret = krb5_write_priv_message(context, pd->auth_context, + &pd->sock, &data); krb5_data_free(&data); return ret; } #ifdef KRB4 -static des_cblock mkey4; -static des_key_schedule msched4; + static char realm_buf[REALM_SZ]; static int -v4_prop(void *arg, Principal *p) +kdb_prop(void *arg, Principal *p) +{ + int ret; + struct v4_principal pr; + + memset(&pr, 0, sizeof(pr)); + + if(p->attributes != 0) { + warnx("%s.%s has non-zero attributes - skipping", + p->name, p->instance); + return 0; + } + strlcpy(pr.name, p->name, sizeof(pr.name)); + strlcpy(pr.instance, p->instance, sizeof(pr.instance)); + + copy_to_key(&p->key_low, &p->key_high, pr.key); + kdb_encrypt_key(&pr.key, &pr.key, &mkey4, msched4, DES_DECRYPT); + pr.exp_date = p->exp_date; + pr.mod_date = p->mod_date; + strlcpy(pr.mod_name, p->mod_name, sizeof(pr.mod_name)); + strlcpy(pr.mod_instance, p->mod_instance, sizeof(pr.mod_instance)); + pr.max_life = p->max_life; + pr.mkvno = -1; /* p->kdc_key_ver; */ + pr.kvno = p->key_version; + + ret = v4_prop(arg, &pr); + memset(&pr, 0, sizeof(pr)); + return ret; +} + +#endif /* KRB4 */ + +#ifndef KRB4 +static time_t +krb_life_to_time(time_t start, int life) +{ + static int lifetimes[] = { + 38400, 41055, 43894, 46929, 50174, 53643, 57352, 61318, + 65558, 70091, 74937, 80119, 85658, 91581, 97914, 104684, + 111922, 119661, 127935, 136781, 146239, 156350, 167161, 178720, + 191077, 204289, 218415, 233517, 249664, 266926, 285383, 305116, + 326213, 348769, 372885, 398668, 426234, 455705, 487215, 520904, + 556921, 595430, 636601, 680618, 727680, 777995, 831789, 889303, + 950794, 1016537, 1086825, 1161973, 1242318, 1328218, 1420057, 1518247, + 1623226, 1735464, 1855462, 1983758, 2120925, 2267576, 2424367, 2592000 + }; + +#if 0 + int i; + double q = exp((log(2592000.0) - log(38400.0)) / 63); + double x = 38400; + for(i = 0; i < 64; i++) { + lifetimes[i] = (int)x; + x *= q; + } +#endif + + if(life == 0xff) + return NEVERDATE; + if(life < 0x80) + return start + life * 5 * 60; + if(life > 0xbf) + life = 0xbf; + return start + lifetimes[life - 0x80]; +} +#endif /* !KRB4 */ + +int +v4_prop(void *arg, struct v4_principal *p) { struct prop_data *pd = arg; hdb_entry ent; @@ -161,46 +236,47 @@ v4_prop(void *arg, Principal *p) free(s); } - ent.kvno = p->key_version; + ent.kvno = p->kvno; ent.keys.len = 3; ent.keys.val = malloc(ent.keys.len * sizeof(*ent.keys.val)); - ent.keys.val[0].mkvno = NULL; + if(p->mkvno != -1) { + ent.keys.val[0].mkvno = malloc (sizeof(*ent.keys.val[0].mkvno)); #if 0 - ent.keys.val[0].mkvno = malloc (sizeof(*ent.keys.val[0].mkvno)); - *(ent.keys.val[0].mkvno) = p->kdc_key_ver; /* XXX */ + *(ent.keys.val[0].mkvno) = p->mkvno; /* XXX */ +#else + *(ent.keys.val[0].mkvno) = 0; #endif + } else + ent.keys.val[0].mkvno = NULL; ent.keys.val[0].salt = calloc(1, sizeof(*ent.keys.val[0].salt)); - ent.keys.val[0].salt->type = pa_pw_salt; + ent.keys.val[0].salt->type = KRB5_PADATA_PW_SALT; ent.keys.val[0].key.keytype = ETYPE_DES_CBC_MD5; krb5_data_alloc(&ent.keys.val[0].key.keyvalue, sizeof(des_cblock)); - - { - unsigned char *key = ent.keys.val[0].key.keyvalue.data; - unsigned char null_key[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; - memcpy(key, &p->key_low, 4); - memcpy(key + 4, &p->key_high, 4); - kdb_encrypt_key((des_cblock*)key, (des_cblock*)key, - &mkey4, msched4, DES_DECRYPT); - if(memcmp(key, null_key, sizeof(null_key)) == 0) { - free_Key(&ent.keys.val[0]); - ent.keys.val = 0; - ent.flags.invalid = 1; - } - } + memcpy(ent.keys.val[0].key.keyvalue.data, p->key, 8); + copy_Key(&ent.keys.val[0], &ent.keys.val[1]); ent.keys.val[1].key.keytype = ETYPE_DES_CBC_MD4; copy_Key(&ent.keys.val[0], &ent.keys.val[2]); ent.keys.val[2].key.keytype = ETYPE_DES_CBC_CRC; - ALLOC(ent.max_life); - *ent.max_life = krb_life_to_time(0, p->max_life); - if(*ent.max_life == NEVERDATE){ - free(ent.max_life); - ent.max_life = NULL; + { + int life = krb_life_to_time(0, p->max_life); + if(life == NEVERDATE){ + ent.max_life = NULL; + } else { + /* clean up lifetime a bit */ + if(life > 86400) + life = (life + 86399) / 86400 * 86400; + else if(life > 3600) + life = (life + 3599) / 3600 * 3600; + ALLOC(ent.max_life); + *ent.max_life = life; + } } - ALLOC(ent.pw_end); - *ent.pw_end = p->exp_date; + ALLOC(ent.valid_end); + *ent.valid_end = p->exp_date; + ret = krb5_make_principal(pd->context, &ent.created_by.principal, realm, "kadmin", @@ -253,11 +329,12 @@ v4_prop(void *arg, Principal *p) ret = v5_prop (pd->context, NULL, &ent, pd); } -out: + out: hdb_free_entry(pd->context, &ent); return ret; } +#ifdef KRB4 #ifdef KASERVER_DB #include "kadb.h" @@ -301,9 +378,15 @@ ka_convert(struct prop_data *pd, int fd, struct ka_entry *ent, hdb.keys.val = malloc(hdb.keys.len * sizeof(*hdb.keys.val)); hdb.keys.val[0].mkvno = NULL; hdb.keys.val[0].salt = calloc(1, sizeof(*hdb.keys.val[0].salt)); - hdb.keys.val[0].salt->type = hdb_afs3_salt; - hdb.keys.val[0].salt->salt.data = strdup(cell); - hdb.keys.val[0].salt->salt.length = strlen(cell); + if (ka_use_null_salt) { + hdb.keys.val[0].salt->type = hdb_pw_salt; + hdb.keys.val[0].salt->salt.data = NULL; + hdb.keys.val[0].salt->salt.length = 0; + } else { + hdb.keys.val[0].salt->type = hdb_afs3_salt; + hdb.keys.val[0].salt->salt.data = strdup(cell); + hdb.keys.val[0].salt->salt.length = strlen(cell); + } hdb.keys.val[0].key.keytype = ETYPE_DES_CBC_MD5; krb5_data_copy(&hdb.keys.val[0].key.keyvalue, ent->key, sizeof(ent->key)); @@ -315,11 +398,19 @@ ka_convert(struct prop_data *pd, int fd, struct ka_entry *ent, ALLOC(hdb.max_life); *hdb.max_life = ntohl(ent->max_life); - if(ntohl(ent->pw_end) != NEVERDATE && ntohl(ent->pw_end) != -1){ - ALLOC(hdb.pw_end); - *hdb.pw_end = ntohl(ent->pw_end); + if(ntohl(ent->valid_end) != NEVERDATE && ntohl(ent->valid_end) != -1){ + ALLOC(hdb.valid_end); + *hdb.valid_end = ntohl(ent->valid_end); } + if (ntohl(ent->pw_change) != NEVERDATE && + ent->pw_expire != 255 && + ent->pw_expire != 0) { + ALLOC(hdb.pw_end); + *hdb.pw_end = ntohl(ent->pw_change) + + 24 * 60 * 60 * ent->pw_expire; + } + ret = krb5_make_principal(pd->context, &hdb.created_by.principal, realm, "kadmin", @@ -390,19 +481,30 @@ ka_dump(struct prop_data *pd, const char *file, const char *cell) struct getargs args[] = { { "master-key", 'm', arg_string, &mkeyfile, "v5 master key file", "file" }, + { "database", 'd', arg_string, &database, "database", "file" }, + { "source", 0, arg_string, &source_type, "type of database to read", + "heimdal" + "|mit-dump" + "|krb4-dump" #ifdef KRB4 + "|krb4-db" +#ifdef KASERVER_DB + "|kaserver" #endif - { "database", 'd', arg_string, &database, "database", "file" }, +#endif + }, + #ifdef KRB4 - { "v4-db", '4', arg_flag, &v4_db, "use version 4 database" }, - { "v4-realm", 'r', arg_string, &realm, "v4 realm to use" }, + { "v4-db", '4', arg_flag, &v4_db }, #endif + { "v4-realm", 'r', arg_string, &realm, "v4 realm to use" }, #ifdef KASERVER_DB - { "ka-db", 'K', arg_flag, &ka_db, "use kaserver database" }, + { "ka-db", 'K', arg_flag, &ka_db }, { "cell", 'c', arg_string, &afs_cell, "name of AFS cell" }, { "kaspecials", 'S', arg_flag, &kaspecials_flag, "dump KASPECIAL keys"}, #endif { "keytab", 'k', arg_string, &ktname, "keytab to use for authentication", "keytab" }, + { "v5-realm", 'R', arg_string, &local_realm, "v5 realm to use" }, { "decrypt", 'D', arg_flag, &decrypt_flag, "decrypt keys" }, { "encrypt", 'E', arg_flag, &encrypt_flag, "encrypt keys" }, { "stdout", 'n', arg_flag, &to_stdout, "dump to stdout" }, @@ -430,6 +532,9 @@ get_creds(krb5_context context, krb5_ccache *cache) krb5_preauthtype preauth = KRB5_PADATA_ENC_TIMESTAMP; krb5_creds creds; + ret = krb5_kt_register(context, &hdb_kt_ops); + if(ret) krb5_err(context, 1, ret, "krb5_kt_register"); + ret = krb5_kt_resolve(context, ktname, &keytab); if(ret) krb5_err(context, 1, ret, "krb5_kt_resolve"); @@ -456,53 +561,109 @@ get_creds(krb5_context context, krb5_ccache *cache) if(ret) krb5_err(context, 1, ret, "krb5_cc_store_cred"); } +enum hprop_source { + HPROP_HEIMDAL = 1, + HPROP_KRB4_DB, + HPROP_KRB4_DUMP, + HPROP_KASERVER, + HPROP_MIT_DUMP +}; + +#define IS_TYPE_V4(X) ((X) == HPROP_KRB4_DB || (X) == HPROP_KRB4_DUMP || (X) == HPROP_KASERVER) + +struct { + int type; + const char *name; +} types[] = { + { HPROP_HEIMDAL, "heimdal" }, + { HPROP_KRB4_DUMP, "krb4-dump" }, +#ifdef KRB4 + { HPROP_KRB4_DB, "krb4-db" }, +#ifdef KASERVER_DB + { HPROP_KASERVER, "kaserver" }, +#endif +#endif + { HPROP_MIT_DUMP, "mit-dump" } +}; + +static int +parse_source_type(const char *s) +{ + int i; + for(i = 0; i < sizeof(types) / sizeof(types[0]); i++) { + if(strstr(types[i].name, s) == types[i].name) + return types[i].type; + } + return 0; +} + static void iterate (krb5_context context, const char *database, const char *afs_cell, HDB *db, - int v4_db, int ka_db, + int type, struct prop_data *pd) { + int ret; + + switch(type) { + case HPROP_KRB4_DUMP: + ret = v4_prop_dump(pd, database); + break; #ifdef KRB4 - if(v4_db) { - int e = kerb_db_iterate ((k_iter_proc_t)v4_prop, pd); - if(e) + case HPROP_KRB4_DB: + ret = kerb_db_iterate ((k_iter_proc_t)kdb_prop, pd); + if(ret) krb5_errx(context, 1, "kerb_db_iterate: %s", - krb_get_err_text(e)); + krb_get_err_text(ret)); + break; #ifdef KASERVER_DB - } else if(ka_db) { - int e = ka_dump(pd, database, afs_cell); - if(e) - krb5_errx(context, 1, "ka_dump: %s", krb_get_err_text(e)); -#endif - } else + case HPROP_KASERVER: + ret = ka_dump(pd, database, afs_cell); + if(ret) + krb5_errx(context, 1, "ka_dump: %s", krb_get_err_text(ret)); + break; #endif - { - krb5_error_code ret = hdb_foreach(context, db, HDB_F_DECRYPT, - v5_prop, pd); +#endif /* KRB4 */ + case HPROP_MIT_DUMP: + ret = mit_prop_dump(pd, database); + if (ret) + krb5_errx(context, 1, "mit_prop_dump: %s", + krb5_get_err_text(context, ret)); + break; + case HPROP_HEIMDAL: + ret = hdb_foreach(context, db, HDB_F_DECRYPT, v5_prop, pd); if(ret) krb5_err(context, 1, ret, "hdb_foreach"); + break; } } static int -dump_database (krb5_context context, int v4_db, int ka_db, +dump_database (krb5_context context, int type, const char *database, const char *afs_cell, HDB *db) { + krb5_error_code ret; struct prop_data pd; + krb5_data data; pd.context = context; pd.auth_context = NULL; pd.sock = STDOUT_FILENO; - iterate (context, database, afs_cell, db, v4_db, ka_db, &pd); + iterate (context, database, afs_cell, db, type, &pd); + krb5_data_zero (&data); + ret = krb5_write_message (context, &pd.sock, &data); + if (ret) + krb5_err(context, 1, ret, "krb5_write_message"); + return 0; } static int -propagate_database (krb5_context context, int v4_db, int ka_db, +propagate_database (krb5_context context, int type, const char *database, const char *afs_cell, HDB *db, krb5_ccache ccache, int optind, int argc, char **argv) @@ -517,7 +678,18 @@ propagate_database (krb5_context context, int v4_db, int ka_db, struct prop_data pd; krb5_data data; - fd = open_socket(context, argv[i]); + char *port, portstr[NI_MAXSERV]; + + port = strchr(argv[i], ':'); + if(port == NULL) { + snprintf(portstr, sizeof(portstr), "%u", + ntohs(krb5_getportbyname (context, "hprop", "tcp", + HPROP_PORT))); + port = portstr; + } else + *port++ = '\0'; + + fd = open_socket(context, argv[i], port); if(fd < 0) { krb5_warn (context, errno, "connect %s", argv[i]); continue; @@ -530,6 +702,13 @@ propagate_database (krb5_context context, int v4_db, int ka_db, close(fd); continue; } + + if (local_realm) { + krb5_realm my_realm; + krb5_get_default_realm(context,&my_realm); + + krb5_princ_set_realm(context,server,&my_realm); + } auth_context = NULL; ret = krb5_sendauth(context, @@ -556,18 +735,16 @@ propagate_database (krb5_context context, int v4_db, int ka_db, pd.auth_context = auth_context; pd.sock = fd; - iterate (context, database, afs_cell, db, - v4_db, ka_db, &pd); + iterate (context, database, afs_cell, db, type, &pd); - data.data = NULL; - data.length = 0; - ret = send_priv(context, auth_context, &data, fd); + krb5_data_zero (&data); + ret = krb5_write_priv_message(context, auth_context, &fd, &data); if(ret) - krb5_warn(context, ret, "send_priv"); + krb5_warn(context, ret, "krb5_write_priv_message"); - ret = recv_priv(context, auth_context, fd, &data); + ret = krb5_read_priv_message(context, auth_context, &fd, &data); if(ret) - krb5_warn(context, ret, "recv_priv"); + krb5_warn(context, ret, "krb5_read_priv_message"); else krb5_data_free (&data); @@ -577,6 +754,28 @@ propagate_database (krb5_context context, int v4_db, int ka_db, return 0; } +#ifdef KRB4 + +static void +v4_get_masterkey (krb5_context context, char *database) +{ + int e; + + e = kerb_db_set_name (database); + if(e) + krb5_errx(context, 1, "kerb_db_set_name: %s", + krb_get_err_text(e)); + e = kdb_get_master_key(0, &mkey4, msched4); + if(e) + krb5_errx(context, 1, "kdb_get_master_key: %s", + krb_get_err_text(e)); + e = kdb_verify_master_key(&mkey4, msched4, NULL); + if (e < 0) + krb5_errx(context, 1, "kdb_verify_master_key failed"); +} + +#endif + int main(int argc, char **argv) { @@ -586,6 +785,8 @@ main(int argc, char **argv) HDB *db; int optind = 0; + int type = 0; + set_progname(argv[0]); if(getarg(args, num_args, argc, argv, &optind)) @@ -603,31 +804,51 @@ main(int argc, char **argv) if(ret) exit(1); + if(local_realm) + krb5_set_default_realm(context, local_realm); + + if(encrypt_flag && decrypt_flag) krb5_errx(context, 1, - "Only one of `--encrypt' and `--decrypt' is meaningful"); + "only one of `--encrypt' and `--decrypt' is meaningful"); + +#ifdef KRB4 + if(v4_db) { + if(type != 0) + krb5_errx(context, 1, "more than one database type specified"); + type = HPROP_KRB4_DB; + } +#ifdef KASERVER_DB + if(ka_db) { + if(type != 0) + krb5_errx(context, 1, "more than one database type specified"); + type = HPROP_KASERVER; + } +#endif +#endif + + if(source_type != NULL) { + if(type != 0) + krb5_errx(context, 1, "more than one database type specified"); + type = parse_source_type(source_type); + if(type == 0) + krb5_errx(context, 1, "unknown source type `%s'", source_type); + } else if(type == 0) + type = HPROP_HEIMDAL; if(!to_stdout) get_creds(context, &ccache); - ret = hdb_read_master_key(context, mkeyfile, &mkey5); - if(ret && ret != ENOENT) - krb5_err(context, 1, ret, "hdb_read_master_key"); - if(ret) { - if(encrypt_flag || decrypt_flag) - krb5_errx(context, 1, "No master key file found"); - } else { - ret = hdb_process_master_key(context, mkey5, &msched5); + if(decrypt_flag || encrypt_flag) { + ret = hdb_read_master_key(context, mkeyfile, &mkey5); + if(ret && ret != ENOENT) + krb5_err(context, 1, ret, "hdb_read_master_key"); if(ret) - krb5_err(context, 1, ret, "hdb_process_master_key"); + krb5_errx(context, 1, "No master key file found"); } #ifdef KRB4 - if (v4_db -#ifdef KASERVER_DB - || ka_db -#endif -) { + if (IS_TYPE_V4(type)) { int e; if (realm == NULL) { @@ -638,39 +859,55 @@ main(int argc, char **argv) realm = realm_buf; } } +#endif - if(v4_db) { - int e = kerb_db_set_name (database); - if(e) - krb5_errx(context, 1, "kerb_db_set_name: %s", - krb_get_err_text(e)); - e = kdb_get_master_key(0, &mkey4, msched4); - if(e) - krb5_errx(context, 1, "kdb_get_master_key: %s", - krb_get_err_text(e)); - } else + switch(type) { +#ifdef KRB4 + case HPROP_KRB4_DB: + if (database == NULL) + krb5_errx(context, 1, "no database specified"); + v4_get_masterkey (context, database); + break; #ifdef KASERVER_DB - if (ka_db) { - /* no preparation required */ - } else + case HPROP_KASERVER: + if (database == NULL) + database = DEFAULT_DATABASE; + ka_use_null_salt = krb5_config_get_bool_default(context, NULL, FALSE, + "hprop", + "afs_uses_null_salt", + NULL); + + break; #endif #endif /* KRB4 */ - { - ret = hdb_create (context, &db, database); - if(ret) - krb5_err(context, 1, ret, "hdb_create: %s", database); - ret = db->open(context, db, O_RDONLY, 0); - if(ret) - krb5_err(context, 1, ret, "db->open"); - } + case HPROP_KRB4_DUMP: + if (database == NULL) + krb5_errx(context, 1, "no dump file specified"); +#ifdef KRB4 + v4_get_masterkey (context, database); +#endif + break; + case HPROP_MIT_DUMP: + if (database == NULL) + krb5_errx(context, 1, "no dump file specified"); + break; + case HPROP_HEIMDAL: + ret = hdb_create (context, &db, database); + if(ret) + krb5_err(context, 1, ret, "hdb_create: %s", database); + ret = db->open(context, db, O_RDONLY, 0); + if(ret) + krb5_err(context, 1, ret, "db->open"); + break; + default: + krb5_errx(context, 1, "unknown dump type `%d'", type); + break; + } if (to_stdout) - dump_database (context, v4_db, ka_db, - database, afs_cell, db); + dump_database (context, type, database, afs_cell, db); else - propagate_database (context, v4_db, ka_db, - database, afs_cell, - db, ccache, - optind, argc, argv); + propagate_database (context, type, database, afs_cell, + db, ccache, optind, argc, argv); return 0; } diff --git a/crypto/heimdal/kdc/hprop.h b/crypto/heimdal/kdc/hprop.h index 3802c5d..0bcab88 100644 --- a/crypto/heimdal/kdc/hprop.h +++ b/crypto/heimdal/kdc/hprop.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997 Kungliga Tekniska Högskolan + * Copyright (c) 1997 - 2000 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -31,25 +31,45 @@ * SUCH DAMAGE. */ -/* $Id: hprop.h,v 1.7 1999/12/02 17:04:59 joda Exp $ */ +/* $Id: hprop.h,v 1.13 2001/01/26 15:54:19 joda Exp $ */ #ifndef __HPROP_H__ #define __HPROP_H__ #include "headers.h" +struct prop_data{ + krb5_context context; + krb5_auth_context auth_context; + int sock; +}; + #define HPROP_VERSION "hprop-0.0" #define HPROP_NAME "hprop" -#define HPROP_KEYTAB "FILE:/etc/hprop.keytab" +#define HPROP_KEYTAB "HDB:" #define HPROP_PORT 754 #ifndef NEVERDATE #define NEVERDATE ((1U << 31) - 1) #endif -krb5_error_code send_priv(krb5_context, krb5_auth_context, krb5_data*, int); -krb5_error_code recv_priv(krb5_context, krb5_auth_context, int, krb5_data*); -krb5_error_code send_clear(krb5_context context, int fd, krb5_data data); -krb5_error_code recv_clear(krb5_context context, int fd, krb5_data *out); +krb5_error_code v5_prop(krb5_context, HDB*, hdb_entry*, void*); +int mit_prop_dump(void*, const char*); + +struct v4_principal { + char name[64]; + char instance[64]; + des_cblock key; + int kvno; + int mkvno; + time_t exp_date; + time_t mod_date; + char mod_name[64]; + char mod_instance[64]; + int max_life; +}; + +int v4_prop(void*, struct v4_principal*); +int v4_prop_dump(void *arg, const char*); #endif /* __HPROP_H__ */ diff --git a/crypto/heimdal/kdc/hpropd.8 b/crypto/heimdal/kdc/hpropd.8 index de4249a..687795e 100644 --- a/crypto/heimdal/kdc/hpropd.8 +++ b/crypto/heimdal/kdc/hpropd.8 @@ -1,4 +1,4 @@ -.\" $Id: hpropd.8,v 1.1 1997/08/27 23:42:34 assar Exp $ +.\" $Id: hpropd.8,v 1.5 2000/11/12 15:37:33 joda Exp $ .\" .Dd Aug 27, 1997 .Dt HPROPD 8 @@ -9,19 +9,65 @@ receive a propagated database .Sh SYNOPSIS .Nm -.Op Fl d Ar database -.Op Fl -database= Ns Ar database +.Oo Fl d Ar file \*(Ba Xo +.Fl -database= Ns Ar file Oc +.Xc +.Op Fl n | Fl -stdin +.Op Fl -print +.Op Fl i | Fl -no-inetd +.Oo Fl k Ar keytab \*(Ba Xo +.Fl -keytab= Ns Ar keytab Oc +.Xc +.Op Fl 4 | Fl -v4dump .Sh DESCRIPTION .Nm receives databases sent by .Nm hprop . and writes it as a local database. .Pp +By default, +.Nm +expects to be started from +.Nm inetd +if stdin is a socket and expects to receive the dumped database over +stdin otherwise. +If the database is sent over the network, it is authenticated and +encrypted. +Only connections from +.Li kadmin/hprop +are accepted. +.Pp Options supported: .Bl -tag -width Ds -.It Fl d Ar database -.It Fl -database= Ns Ar database -the database to create. +.It Xo +.Fl d Ar file Ns , +.Fl -database= Ns Ar file +.Xc +database +.It Xo +.Fl n Ns , +.Fl -stdin +.Xc +read from stdin +.It Xo +.Fl -print +.Xc +print dump to stdout +.It Xo +.Fl i Ns , +.Fl -no-inetd +.Xc +Not started from inetd +.It Xo +.Fl k Ar keytab Ns , +.Fl -keytab= Ns Ar keytab +.Xc +keytab to use for authentication +.It Xo +.Fl 4 Ns , +.Fl -v4dump +.Xc +create v4 type DB .El .Sh SEE ALSO .Xr hprop 8 diff --git a/crypto/heimdal/kdc/hpropd.c b/crypto/heimdal/kdc/hpropd.c index df29240..2cfdd15 100644 --- a/crypto/heimdal/kdc/hpropd.c +++ b/crypto/heimdal/kdc/hpropd.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997-2000 Kungliga Tekniska Högskolan + * Copyright (c) 1997-2001 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -33,7 +33,7 @@ #include "hprop.h" -RCSID("$Id: hpropd.c,v 1.22 2000/01/06 21:39:24 assar Exp $"); +RCSID("$Id: hpropd.c,v 1.31 2001/01/25 12:37:39 assar Exp $"); #ifdef KRB4 static des_cblock mkey4; @@ -127,10 +127,10 @@ dump_krb4(krb5_context context, hdb_entry *ent, int fd) free(p); } - if (ent->pw_end == NULL) - strcat(buf, time2str(60*60*24*365*50)); /* passwd will never expire */ + if (ent->valid_end == NULL) + strcat(buf, time2str(60*60*24*365*50)); /* no expiration */ else - strcat(buf, time2str(*ent->pw_end)); + strcat(buf, time2str(*ent->valid_end)); strcat(buf, " "); if (ent->modified_by == NULL) @@ -168,6 +168,7 @@ static int from_stdin; #ifdef KRB4 static int v4dump; #endif +static char *ktname = NULL; struct getargs args[] = { { "database", 'd', arg_string, &database, "database", "file" }, @@ -175,6 +176,7 @@ struct getargs args[] = { { "print", 0, arg_flag, &print_dump, "print dump to stdout" }, { "inetd", 'i', arg_negative_flag, &inetd_flag, "Not started from inetd" }, + { "keytab", 'k', arg_string, &ktname, "keytab to use for authentication", "keytab" }, #ifdef KRB4 { "v4dump", '4', arg_flag, &v4dump, "create v4 type DB" }, #endif @@ -197,20 +199,18 @@ main(int argc, char **argv) krb5_error_code ret; krb5_context context; krb5_auth_context ac = NULL; - krb5_principal server; krb5_principal c1, c2; krb5_authenticator authent; krb5_keytab keytab; int fd; HDB *db; - char hostname[128]; int optind = 0; char *tmp_db; krb5_log_facility *fac; int nprincs; #ifdef KRB4 int e; - int fd_out; + int fd_out = -1; #endif set_progname(argv[0]); @@ -250,8 +250,10 @@ main(int argc, char **argv) else { struct sockaddr_storage ss; struct sockaddr *sa = (struct sockaddr *)&ss; - int sin_len = sizeof(ss); + socklen_t sin_len = sizeof(ss); char addr_name[256]; + krb5_ticket *ticket; + char *server; fd = STDIN_FILENO; if (inetd_flag == -1) { @@ -277,21 +279,34 @@ main(int argc, char **argv) krb5_log(context, fac, 0, "Connection from %s", addr_name); - gethostname(hostname, sizeof(hostname)); - ret = krb5_sname_to_principal(context, hostname, HPROP_NAME, - KRB5_NT_SRV_HST, &server); + ret = krb5_kt_register(context, &hdb_kt_ops); if(ret) - krb5_err(context, 1, ret, "krb5_sname_to_principal"); - - ret = krb5_kt_default(context, &keytab); - if(ret) - krb5_err(context, 1, ret, "krb5_kt_default"); - - ret = krb5_recvauth(context, &ac, &fd, HPROP_VERSION, - server, 0, keytab, NULL); + krb5_err(context, 1, ret, "krb5_kt_register"); + + if (ktname != NULL) { + ret = krb5_kt_resolve(context, ktname, &keytab); + if (ret) + krb5_err (context, 1, ret, "krb5_kt_resolve %s", ktname); + } else { + ret = krb5_kt_default (context, &keytab); + if (ret) + krb5_err (context, 1, ret, "krb5_kt_default"); + } + + ret = krb5_recvauth(context, &ac, &fd, HPROP_VERSION, NULL, + 0, keytab, &ticket); if(ret) krb5_err(context, 1, ret, "krb5_recvauth"); + ret = krb5_unparse_name(context, ticket->server, &server); + if (ret) + krb5_err(context, 1, ret, "krb5_unparse_name"); + if (strncmp(server, "hprop/", 5) != 0) + krb5_errx(context, 1, "ticket not for hprop (%s)", server); + + free(server); + krb5_free_ticket (context, ticket); + ret = krb5_auth_getauthenticator(context, ac, &authent); if(ret) krb5_err(context, 1, ret, "krb5_auth_getauthenticator"); @@ -347,21 +362,21 @@ main(int argc, char **argv) krb5_data data; hdb_entry entry; - if(from_stdin){ - ret = recv_clear(context, fd, &data); - if(ret) - krb5_err(context, 1, ret, "recv_clear"); - }else{ - ret = recv_priv(context, ac, fd, &data); + if(from_stdin) { + ret = krb5_read_message(context, &fd, &data); + if(ret != 0 && ret != HEIM_ERR_EOF) + krb5_err(context, 1, ret, "krb5_read_message"); + } else { + ret = krb5_read_priv_message(context, ac, &fd, &data); if(ret) - krb5_err(context, 1, ret, "recv_priv"); + krb5_err(context, 1, ret, "krb5_read_priv_message"); } - if(data.length == 0) { + if(ret == HEIM_ERR_EOF || data.length == 0) { if(!from_stdin) { data.data = NULL; data.length = 0; - send_priv(context, ac, &data, fd); + krb5_write_priv_message(context, ac, &fd, &data); } if(!print_dump) { #ifdef KRB4 diff --git a/crypto/heimdal/kdc/kadb.h b/crypto/heimdal/kdc/kadb.h index e85dbe2..5c98ccc 100644 --- a/crypto/heimdal/kdc/kadb.h +++ b/crypto/heimdal/kdc/kadb.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998 Kungliga Tekniska Högskolan + * Copyright (c) 1998 - 2000 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: kadb.h,v 1.2 1999/12/02 17:04:59 joda Exp $ */ +/* $Id: kadb.h,v 1.3 2000/03/03 12:36:26 assar Exp $ */ #ifndef __kadb_h__ #define __kadb_h__ @@ -56,7 +56,7 @@ struct ka_header { struct ka_entry { int32_t flags; /* see below */ int32_t next; /* next in hash list */ - int32_t pw_end; /* expiration date */ + int32_t valid_end; /* expiration date */ int32_t mod_time; /* time last modified */ int32_t mod_ptr; /* pointer to modifier */ int32_t pw_change; /* last pw change */ @@ -66,6 +66,10 @@ struct ka_entry { char name[64]; char instance[64]; char key[8]; + u_char pw_expire; /* # days before password expires */ + u_char spare; + u_char attempts; + u_char locktime; }; #define KAFNORMAL (1<<0) @@ -75,4 +79,6 @@ struct ka_entry { #define KAFNOCPW (1<<6) /* ! allow principal to change its own key */ #define KAFSPECIAL (1<<8) /* set if special AuthServer principal */ +#define DEFAULT_DATABASE "/usr/afs/db/kaserver.DB0" + #endif /* __kadb_h__ */ diff --git a/crypto/heimdal/kdc/kaserver.c b/crypto/heimdal/kdc/kaserver.c index 64121eb..175ddb6 100644 --- a/crypto/heimdal/kdc/kaserver.c +++ b/crypto/heimdal/kdc/kaserver.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997 - 2000 Kungliga Tekniska Högskolan + * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -33,7 +33,7 @@ #include "kdc_locl.h" -RCSID("$Id: kaserver.c,v 1.10 2000/02/13 19:21:22 assar Exp $"); +RCSID("$Id: kaserver.c,v 1.15 2001/01/28 21:51:05 assar Exp $"); #ifdef KASERVER @@ -277,9 +277,6 @@ create_reply_ticket (struct rx_header *hdr, krb5_generate_random_block(&fyrtiosjuelva, sizeof(fyrtiosjuelva)); fyrtiosjuelva &= 0xffffffff; krb5_store_int32 (sp, fyrtiosjuelva); -#if 0 - krb5_store_int32 (sp, 4711); /* XXX */ -#endif krb5_store_int32 (sp, challenge); sp->store (sp, session, 8); memset (&session, 0, sizeof(session)); @@ -398,30 +395,45 @@ do_authenticate (struct rx_header *hdr, time_t max_life; u_int8_t life; int32_t chal; + char client_name[256]; + char server_name[256]; krb5_data_zero (&request); unparse_auth_args (sp, &name, &instance, &start_time, &end_time, &request, &max_seq_len); + snprintf (client_name, sizeof(client_name), "%s.%s@%s", + name, instance, v4_realm); + client_entry = db_fetch4 (name, instance, v4_realm); if (client_entry == NULL) { - kdc_log(0, "Client not found in database: %s.%s@%s", - name, instance, v4_realm); + kdc_log(0, "Client not found in database: %s", + client_name); make_error_reply (hdr, KANOENT, reply); goto out; } + snprintf (server_name, sizeof(server_name), "%s.%s@%s", + "krbtgt", v4_realm, v4_realm); + server_entry = db_fetch4 ("krbtgt", v4_realm, v4_realm); if (server_entry == NULL) { - kdc_log(0, "Server not found in database: %s.%s@%s", - "krbtgt", v4_realm, v4_realm); + kdc_log(0, "Server not found in database: %s", server_name); make_error_reply (hdr, KANOENT, reply); goto out; } + ret = check_flags (client_entry, client_name, + server_entry, server_name, + TRUE); + if (ret) { + make_error_reply (hdr, KAPWEXPIRED, reply); + goto out; + } + /* find a DES key */ - ret = get_des_key(client_entry, &ckey); + ret = get_des_key(client_entry, TRUE, &ckey); if(ret){ kdc_log(0, "%s", krb5_get_err_text(context, ret)); make_error_reply (hdr, KANOKEYS, reply); @@ -429,7 +441,7 @@ do_authenticate (struct rx_header *hdr, } /* find a DES key */ - ret = get_des_key(server_entry, &skey); + ret = get_des_key(server_entry, TRUE, &skey); if(ret){ kdc_log(0, "%s", krb5_get_err_text(context, ret)); make_error_reply (hdr, KANOKEYS, reply); @@ -457,6 +469,11 @@ do_authenticate (struct rx_header *hdr, krb5_ret_int32 (reply_sp, &chal); krb5_storage_free (reply_sp); + if (abs(chal - kdc_time) > context->max_skew) { + make_error_reply (hdr, KACLOCKSKEW, reply); + goto out; + } + /* life */ max_life = end_time - kdc_time; if (client_entry->max_life) @@ -484,14 +501,10 @@ out: free (name); if (instance) free (instance); - if (client_entry) { - hdb_free_entry (context, client_entry); - free (client_entry); - } - if (server_entry) { - hdb_free_entry (context, server_entry); - free (server_entry); - } + if (client_entry) + free_ent (client_entry); + if (server_entry) + free_ent (server_entry); } static krb5_error_code @@ -575,6 +588,7 @@ do_getticket (struct rx_header *hdr, char pname[ANAME_SZ]; char pinst[INST_SZ]; char prealm[REALM_SZ]; + char server_name[256]; krb5_data_zero (&aticket); krb5_data_zero (×); @@ -582,14 +596,24 @@ do_getticket (struct rx_header *hdr, unparse_getticket_args (sp, &kvno, &auth_domain, &aticket, &name, &instance, ×, &max_seq_len); + snprintf (server_name, sizeof(server_name), + "%s.%s@%s", name, instance, v4_realm); + server_entry = db_fetch4 (name, instance, v4_realm); if (server_entry == NULL) { - kdc_log(0, "Server not found in database: %s.%s@%s", - name, instance, v4_realm); + kdc_log(0, "Server not found in database: %s", server_name); make_error_reply (hdr, KANOENT, reply); goto out; } + ret = check_flags (NULL, NULL, + server_entry, server_name, + FALSE); + if (ret) { + make_error_reply (hdr, KAPWEXPIRED, reply); + goto out; + } + krbtgt_entry = db_fetch4 ("krbtgt", v4_realm, v4_realm); if (krbtgt_entry == NULL) { kdc_log(0, "Server not found in database: %s.%s@%s", @@ -599,7 +623,7 @@ do_getticket (struct rx_header *hdr, } /* find a DES key */ - ret = get_des_key(krbtgt_entry, &kkey); + ret = get_des_key(krbtgt_entry, TRUE, &kkey); if(ret){ kdc_log(0, "%s", krb5_get_err_text(context, ret)); make_error_reply (hdr, KANOKEYS, reply); @@ -607,7 +631,7 @@ do_getticket (struct rx_header *hdr, } /* find a DES key */ - ret = get_des_key(server_entry, &skey); + ret = get_des_key(server_entry, TRUE, &skey); if(ret){ kdc_log(0, "%s", krb5_get_err_text(context, ret)); make_error_reply (hdr, KANOKEYS, reply); @@ -627,6 +651,14 @@ do_getticket (struct rx_header *hdr, char sinstance[SNAME_SZ]; u_int32_t paddress; + if (aticket.length > sizeof(ticket.dat)) { + kdc_log(0, "ticket too long (%u > %u)", + (unsigned)aticket.length, + (unsigned)sizeof(ticket.dat)); + make_error_reply (hdr, KABADTICKET, reply); + goto out; + } + ticket.length = aticket.length; memcpy (ticket.dat, aticket.data, ticket.length); @@ -707,14 +739,10 @@ out: free (name); if (instance) free (instance); - if (krbtgt_entry) { - hdb_free_entry (context, krbtgt_entry); - free (krbtgt_entry); - } - if (server_entry) { - hdb_free_entry (context, server_entry); - free (server_entry); - } + if (krbtgt_entry) + free_ent (krbtgt_entry); + if (server_entry) + free_ent (server_entry); } krb5_error_code diff --git a/crypto/heimdal/kdc/kdc.8 b/crypto/heimdal/kdc/kdc.8 index 181a3ce..359c17d 100644 --- a/crypto/heimdal/kdc/kdc.8 +++ b/crypto/heimdal/kdc/kdc.8 @@ -1,4 +1,4 @@ -.\" $Id: kdc.8,v 1.5 2000/02/13 21:04:32 assar Exp $ +.\" $Id: kdc.8,v 1.11 2001/01/26 22:46:28 assar Exp $ .\" .Dd July 27, 1997 .Dt KDC 8 @@ -9,11 +9,15 @@ Kerberos 5 server .Sh SYNOPSIS .Nm -.Op Fl c Ar file -.Op Fl -config-file= Ns Ar file +.Oo Fl c Ar file \*(Ba Xo +.Fl -config-file= Ns Ar file Oc +.Xc .Op Fl p | Fl -no-require-preauth .Op Fl -max-request= Ns Ar size .Op Fl H | Fl -enable-http +.Oo Fl r Ar string \*(Ba Xo +.Fl -v4-realm= Ns Ar string Oc +.Xc .Op Fl K | Fl -no-kaserver .Op Fl r Ar realm .Op Fl -v4-realm= Ns Ar realm @@ -21,7 +25,6 @@ Kerberos 5 server .Fl -ports= Ns Ar string Oc .Xc .Op Fl -addresses= Ns Ar list of addresses - .Sh DESCRIPTION .Nm serves requests for tickets. When it starts, it first checks the flags @@ -99,8 +102,8 @@ and then start the KDC with .Fl -config-file= Ns Ar /etc/krb5.conf ) . All options should be in a section called .Dq kdc . -Options are called the same as the long option name, and takes the -same arguments. The only difference is the pre-authentication flag, +All the command-line options can preferably be added in the +configuration file. The only difference is the pre-authentication flag, that has to be specified as: .Pp .Dl require-preauth = no @@ -108,6 +111,25 @@ that has to be specified as: (in fact you can specify the option as .Fl -require-preauth=no ) . .Pp +And there are some configuration options which do not have +command-line equivalents: +.Bl -tag -width "xxx" -offset indent +.It Li check-ticket-addresses = Va boolean +Check the addresses in the ticket when processing TGS requests. The +default is FALSE. +.It Li allow-null-ticket-addresses = Va boolean +Permit tickets with no addresses. This option is only relevant when +check-ticket-addresses is TRUE. +.It Li allow-anonymous = Va boolean +Permit anonymous tickets with no addresses. +.It encode_as_rep_as_tgs_rep = Va boolean +Encode AS-Rep as TGS-Rep to be bug-compatible with old DCE code. The +Heimdal clients allow both. +.It kdc_warn_pwexpire = Va time +How long before password/principal expiration the KDC should start +sending out warning messages. +.El +.Pp An example of a config file: .Bd -literal -offset indent [kdc] diff --git a/crypto/heimdal/kdc/kdc_locl.h b/crypto/heimdal/kdc/kdc_locl.h index c703030..2cc753c 100644 --- a/crypto/heimdal/kdc/kdc_locl.h +++ b/crypto/heimdal/kdc/kdc_locl.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997-2000 Kungliga Tekniska Högskolan + * Copyright (c) 1997-2001 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -32,7 +32,7 @@ */ /* - * $Id: kdc_locl.h,v 1.40 2000/02/11 17:46:29 assar Exp $ + * $Id: kdc_locl.h,v 1.48 2001/01/30 01:44:07 assar Exp $ */ #ifndef __KDC_LOCL_H__ @@ -61,38 +61,52 @@ extern int enable_http; extern krb5_boolean encode_as_rep_as_tgs_rep; extern krb5_boolean check_ticket_addresses; extern krb5_boolean allow_null_ticket_addresses; +extern krb5_boolean allow_anonymous; #ifdef KRB4 extern char *v4_realm; +extern int enable_v4; +extern int enable_524; #endif #ifdef KASERVER extern krb5_boolean enable_kaserver; #endif +#define _PATH_KDC_CONF HDB_DB_DIR "/kdc.conf" +#define DEFAULT_LOG_DEST "0-1/FILE:" HDB_DB_DIR "/kdc.log" + extern struct timeval now; #define kdc_time (now.tv_sec) krb5_error_code as_rep (KDC_REQ*, krb5_data*, const char*, struct sockaddr*); void configure (int, char**); -hdb_entry* db_fetch (krb5_principal); -void kdc_log (int, const char*, ...); -char* kdc_log_msg (int, const char*, ...); -char* kdc_log_msg_va (int, const char*, va_list); +krb5_error_code db_fetch (krb5_principal, hdb_entry**); +void free_ent(hdb_entry *); +void kdc_log (int, const char*, ...) + __attribute__ ((format (printf, 2,3))); + +char* kdc_log_msg (int, const char*, ...) + __attribute__ ((format (printf, 2,3))); +char* kdc_log_msg_va (int, const char*, va_list) + __attribute__ ((format (printf, 2,0))); void kdc_openlog (krb5_config_section*); void loop (void); void set_master_key (EncryptionKey); krb5_error_code tgs_rep (KDC_REQ*, krb5_data*, const char*, struct sockaddr *); Key* unseal_key (Key*); +krb5_error_code check_flags(hdb_entry *client, const char *client_name, + hdb_entry *server, const char *server_name, + krb5_boolean is_as_req); #ifdef KRB4 -hdb_entry* db_fetch4 (const char*, const char*, const char*); -krb5_error_code do_524 (Ticket*, krb5_data*, const char*, struct sockaddr*); +krb5_error_code db_fetch4 (const char*, const char*, const char*, hdb_entry**); +krb5_error_code do_524 (const Ticket*, krb5_data*, const char*, struct sockaddr*); krb5_error_code do_version4 (unsigned char*, size_t, krb5_data*, const char*, struct sockaddr_in*); -krb5_error_code encode_v4_ticket (void*, size_t, EncTicketPart*, - PrincipalName*, size_t*); +krb5_error_code encode_v4_ticket (void*, size_t, const EncTicketPart*, + const PrincipalName*, size_t*); krb5_error_code encrypt_v4_ticket (void*, size_t, des_cblock*, EncryptedData*); -krb5_error_code get_des_key(hdb_entry*, Key**); +krb5_error_code get_des_key(hdb_entry*, krb5_boolean, Key**); int maybe_version4 (unsigned char*, int); #endif diff --git a/crypto/heimdal/kdc/kerberos4.c b/crypto/heimdal/kdc/kerberos4.c index 23d59dd..111bd9f 100644 --- a/crypto/heimdal/kdc/kerberos4.c +++ b/crypto/heimdal/kdc/kerberos4.c @@ -33,12 +33,10 @@ #include "kdc_locl.h" -RCSID("$Id: kerberos4.c,v 1.27 2000/02/13 19:27:36 assar Exp $"); +RCSID("$Id: kerberos4.c,v 1.36 2001/01/30 01:44:08 assar Exp $"); #ifdef KRB4 -#include "kerberos4.h" - #ifndef swap32 static u_int32_t swap32(u_int32_t x) @@ -61,7 +59,7 @@ make_err_reply(krb5_data *reply, int code, const char *msg) { KTEXT_ST er; - /* name, instance and realm is not checked in most (all?) version + /* name, instance and realm are not checked in most (all?) implementations; msg is also never used, but we send it anyway (for debugging purposes) */ @@ -74,51 +72,92 @@ make_err_reply(krb5_data *reply, int code, const char *msg) static krb5_boolean valid_princ(krb5_context context, krb5_principal princ) { + krb5_error_code ret; char *s; hdb_entry *ent; - krb5_unparse_name(context, princ, &s); - ent = db_fetch(princ); - if(ent == NULL){ - kdc_log(7, "Lookup %s failed", s); + + ret = krb5_unparse_name(context, princ, &s); + if (ret) + return 0; + ret = db_fetch(princ, &ent); + if (ret) { + kdc_log(7, "Lookup %s failed: %s", s, + krb5_get_err_text (context, ret)); free(s); return 0; } kdc_log(7, "Lookup %s succeeded", s); free(s); - hdb_free_entry(context, ent); - free(ent); + free_ent(ent); return 1; } -hdb_entry* -db_fetch4(const char *name, const char *instance, const char *realm) +krb5_error_code +db_fetch4(const char *name, const char *instance, const char *realm, + hdb_entry **ent) { krb5_principal p; - hdb_entry *ent; krb5_error_code ret; ret = krb5_425_conv_principal_ext(context, name, instance, realm, valid_princ, 0, &p); if(ret) - return NULL; - ent = db_fetch(p); + return ret; + ret = db_fetch(p, ent); krb5_free_principal(context, p); - return ent; + return ret; } krb5_error_code -get_des_key(hdb_entry *principal, Key **key) +get_des_key(hdb_entry *principal, krb5_boolean prefer_afs_key, Key **ret_key) { - krb5_error_code ret; + Key *v5_key = NULL, *v4_key = NULL, *afs_key = NULL; + int i; + krb5_enctype etypes[] = { ETYPE_DES_CBC_MD5, + ETYPE_DES_CBC_MD4, + ETYPE_DES_CBC_CRC }; + + for(i = 0; + i < sizeof(etypes)/sizeof(etypes[0]) + && (v5_key == NULL || v4_key == NULL || afs_key == NULL); + ++i) { + Key *key = NULL; + while(hdb_next_enctype2key(context, principal, etypes[i], &key) == 0) { + if(key->salt == NULL) { + if(v5_key == NULL) + v5_key = key; + } else if(key->salt->type == hdb_pw_salt && + key->salt->salt.length == 0) { + if(v4_key == NULL) + v4_key = key; + } else if(key->salt->type == hdb_afs3_salt) { + if(afs_key == NULL) + afs_key = key; + } + } + } - ret = hdb_enctype2key(context, principal, ETYPE_DES_CBC_MD5, key); - if(ret) - ret = hdb_enctype2key(context, principal, ETYPE_DES_CBC_MD4, key); - if(ret) - ret = hdb_enctype2key(context, principal, ETYPE_DES_CBC_CRC, key); - if(ret) - return ret; - if ((*key)->key.keyvalue.length == 0) + if(prefer_afs_key) { + if(afs_key) + *ret_key = afs_key; + else if(v4_key) + *ret_key = v4_key; + else if(v5_key) + *ret_key = v5_key; + else + return KERB_ERR_NULL_KEY; + } else { + if(v4_key) + *ret_key = v4_key; + else if(afs_key) + *ret_key = afs_key; + else if(v5_key) + *ret_key = v5_key; + else + return KERB_ERR_NULL_KEY; + } + + if((*ret_key)->key.keyvalue.length == 0) return KERB_ERR_NULL_KEY; return 0; } @@ -150,6 +189,14 @@ do_version4(unsigned char *buf, int32_t req_time; time_t max_life; u_int8_t life; + char client_name[256]; + char server_name[256]; + + if(!enable_v4) { + kdc_log(0, "Rejected version 4 request from %s", from); + make_err_reply(reply, KDC_GEN_ERR, "function not enabled"); + return 0; + } sp = krb5_storage_from_mem(buf, len); RCHECK(krb5_ret_int8(sp, &pvno), out); @@ -172,24 +219,38 @@ do_version4(unsigned char *buf, RCHECK(krb5_ret_int8(sp, &life), out1); RCHECK(krb5_ret_stringz(sp, &sname), out1); RCHECK(krb5_ret_stringz(sp, &sinst), out1); - kdc_log(0, "AS-REQ %s.%s@%s from %s for %s.%s", - name, inst, realm, from, sname, sinst); + snprintf (client_name, sizeof(client_name), + "%s.%s@%s", name, inst, realm); + snprintf (server_name, sizeof(server_name), + "%s.%s@%s", sname, sinst, v4_realm); + + kdc_log(0, "AS-REQ %s from %s for %s", + client_name, from, server_name); - client = db_fetch4(name, inst, realm); - if(client == NULL){ - kdc_log(0, "Client not found in database: %s.%s@%s", - name, inst, realm); + ret = db_fetch4(name, inst, realm, &client); + if(ret) { + kdc_log(0, "Client not found in database: %s: %s", + client_name, krb5_get_err_text(context, ret)); make_err_reply(reply, KERB_ERR_PRINCIPAL_UNKNOWN, NULL); goto out1; } - server = db_fetch4(sname, sinst, v4_realm); - if(server == NULL){ - kdc_log(0, "Server not found in database: %s.%s@%s", - sname, sinst, v4_realm); + ret = db_fetch4(sname, sinst, v4_realm, &server); + if(ret){ + kdc_log(0, "Server not found in database: %s: %s", + server_name, krb5_get_err_text(context, ret)); make_err_reply(reply, KERB_ERR_PRINCIPAL_UNKNOWN, NULL); goto out1; } + ret = check_flags (client, client_name, + server, server_name, + TRUE); + if (ret) { + /* good error code? */ + make_err_reply(reply, KERB_ERR_NAME_EXP, NULL); + goto out1; + } + /* * There's no way to do pre-authentication in v4 and thus no * good error code to return if preauthentication is required. @@ -200,14 +261,13 @@ do_version4(unsigned char *buf, || server->flags.require_preauth) { kdc_log(0, "Pre-authentication required for v4-request: " - "%s.%s@%s for %s.%s@%s", - name, inst, realm, - sname, sinst, v4_realm); + "%s for %s", + client_name, server_name); make_err_reply(reply, KERB_ERR_NULL_KEY, NULL); goto out1; } - ret = get_des_key(client, &ckey); + ret = get_des_key(client, FALSE, &ckey); if(ret){ kdc_log(0, "%s", krb5_get_err_text(context, ret)); /* XXX */ @@ -230,7 +290,7 @@ do_version4(unsigned char *buf, } #endif - ret = get_des_key(server, &skey); + ret = get_des_key(server, FALSE, &skey); if(ret){ kdc_log(0, "%s", krb5_get_err_text(context, ret)); /* XXX */ @@ -295,12 +355,13 @@ do_version4(unsigned char *buf, goto out2; } - tgt = db_fetch(tgt_princ); - if(tgt == NULL){ + ret = db_fetch(tgt_princ, &tgt); + if(ret){ char *s; s = kdc_log_msg(0, "Ticket-granting ticket not " - "found in database: krbtgt.%s@%s", - realm, v4_realm); + "found in database: krbtgt.%s@%s: %s", + realm, v4_realm, + krb5_get_err_text(context, ret)); make_err_reply(reply, KFAILURE, s); free(s); goto out2; @@ -314,7 +375,7 @@ do_version4(unsigned char *buf, goto out2; } - ret = get_des_key(tgt, &tkey); + ret = get_des_key(tgt, FALSE, &tkey); if(ret){ kdc_log(0, "%s", krb5_get_err_text(context, ret)); /* XXX */ @@ -349,8 +410,12 @@ do_version4(unsigned char *buf, RCHECK(krb5_ret_int8(sp, &life), out2); RCHECK(krb5_ret_stringz(sp, &sname), out2); RCHECK(krb5_ret_stringz(sp, &sinst), out2); - kdc_log(0, "TGS-REQ %s.%s@%s from %s for %s.%s", - ad.pname, ad.pinst, ad.prealm, from, sname, sinst); + snprintf (server_name, sizeof(server_name), + "%s.%s@%s", + sname, sinst, v4_realm); + + kdc_log(0, "TGS-REQ %s.%s@%s from %s for %s", + ad.pname, ad.pinst, ad.prealm, from, server_name); if(strcmp(ad.prealm, realm)){ kdc_log(0, "Can't hop realms %s -> %s", realm, ad.prealm); @@ -367,28 +432,38 @@ do_version4(unsigned char *buf, } #if 0 - client = db_fetch4(ad.pname, ad.pinst, ad.prealm); - if(client == NULL){ + ret = db_fetch4(ad.pname, ad.pinst, ad.prealm, &client); + if(ret){ char *s; - s = kdc_log_msg(0, "Client not found in database: %s.%s@%s", - ad.pname, ad.pinst, ad.prealm); + s = kdc_log_msg(0, "Client not found in database: %s.%s@%s: %s", + ad.pname, ad.pinst, ad.prealm, + krb5_get_err_text(context, ret)); make_err_reply(reply, KERB_ERR_PRINCIPAL_UNKNOWN, s); free(s); goto out2; } #endif - server = db_fetch4(sname, sinst, v4_realm); - if(server == NULL){ + ret = db_fetch4(sname, sinst, v4_realm, &server); + if(ret){ char *s; - s = kdc_log_msg(0, "Server not found in database: %s.%s@%s", - sname, sinst, v4_realm); + s = kdc_log_msg(0, "Server not found in database: %s: %s", + server_name, krb5_get_err_text(context, ret)); make_err_reply(reply, KERB_ERR_PRINCIPAL_UNKNOWN, s); free(s); goto out2; } - ret = get_des_key(server, &skey); + ret = check_flags (NULL, NULL, + server, server_name, + FALSE); + if (ret) { + /* good error code? */ + make_err_reply(reply, KERB_ERR_NAME_EXP, NULL); + goto out2; + } + + ret = get_des_key(server, FALSE, &skey); if(ret){ kdc_log(0, "%s", krb5_get_err_text(context, ret)); /* XXX */ @@ -433,11 +508,8 @@ do_version4(unsigned char *buf, out2: if(tgt_princ) krb5_free_principal(context, tgt_princ); - if(tgt){ - hdb_free_entry(context, tgt); - free(tgt); - } - + if(tgt) + free_ent(tgt); break; } @@ -460,14 +532,10 @@ out: free(sname); if(sinst) free(sinst); - if(client){ - hdb_free_entry(context, client); - free(client); - } - if(server){ - hdb_free_entry(context, server); - free(server); - } + if(client) + free_ent(client); + if(server) + free_ent(server); krb5_storage_free(sp); return 0; } @@ -498,8 +566,8 @@ encrypt_v4_ticket(void *buf, size_t len, des_cblock *key, EncryptedData *reply) } krb5_error_code -encode_v4_ticket(void *buf, size_t len, EncTicketPart *et, - PrincipalName *service, size_t *size) +encode_v4_ticket(void *buf, size_t len, const EncTicketPart *et, + const PrincipalName *service, size_t *size) { krb5_storage *sp; krb5_error_code ret; diff --git a/crypto/heimdal/kdc/kerberos5.c b/crypto/heimdal/kdc/kerberos5.c index 7100274..90cc49e 100644 --- a/crypto/heimdal/kdc/kerberos5.c +++ b/crypto/heimdal/kdc/kerberos5.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997-1999 Kungliga Tekniska Högskolan + * Copyright (c) 1997-2000 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -33,7 +33,7 @@ #include "kdc_locl.h" -RCSID("$Id: kerberos5.c,v 1.109 2000/01/18 03:13:00 assar Exp $"); +RCSID("$Id: kerberos5.c,v 1.123 2001/01/30 01:44:08 assar Exp $"); #define MAX_TIME ((time_t)((1U << 31) - 1)) @@ -71,62 +71,34 @@ find_padata(KDC_REQ *req, int *start, int type) return NULL; } -#if 0 - -static krb5_error_code -find_keys(hdb_entry *client, - hdb_entry *server, - Key **ckey, - krb5_enctype *cetype, - Key **skey, - krb5_enctype *setype, - unsigned *etypes, - unsigned num_etypes) -{ - int i; - krb5_error_code ret; - for(i = 0; i < num_etypes; i++) { - if(client){ - ret = hdb_enctype2key(context, client, etypes[i], ckey); - if(ret) - continue; - } - if(server){ - ret = hdb_enctype2key(context, server, etypes[i], skey); - if(ret) - continue; - } - if(etype) - *cetype = *setype = etypes[i]; - return 0; - } - return KRB5KDC_ERR_ETYPE_NOSUPP; -} - -#else +/* + * return the first appropriate key of `princ' in `ret_key'. Look for + * all the etypes in (`etypes', `len'), stopping as soon as we find + * one, but preferring one that has default salt + */ static krb5_error_code find_etype(hdb_entry *princ, unsigned *etypes, unsigned len, - Key **key, int *index) + Key **ret_key, krb5_enctype *ret_etype) { int i; krb5_error_code ret = KRB5KDC_ERR_ETYPE_NOSUPP; - for(i = 0; i < len ; i++) { - krb5_error_code tmp; + for(i = 0; ret != 0 && i < len ; i++) { + Key *key = NULL; - tmp = hdb_enctype2key(context, princ, etypes[i], key); - if (tmp == 0) { - if ((*key)->key.keyvalue.length != 0) { - ret = 0; - break; - } else { + while (hdb_next_enctype2key(context, princ, etypes[i], &key) == 0) { + if (key->key.keyvalue.length == 0) { ret = KRB5KDC_ERR_NULL_KEY; + continue; } + *ret_key = key; + *ret_etype = etypes[i]; + ret = 0; + if (key->salt == NULL) + return ret; } } - if(index) - *index = i; return ret; } @@ -140,30 +112,44 @@ find_keys(hdb_entry *client, int *etypes, unsigned num_etypes) { - int i; krb5_error_code ret; + if(client){ /* find client key */ - ret = find_etype(client, etypes, num_etypes, ckey, &i); + ret = find_etype(client, etypes, num_etypes, ckey, cetype); if (ret) { kdc_log(0, "Client has no support for etypes"); return ret; } - *cetype = etypes[i]; } if(server){ /* find server key */ - ret = find_etype(server, etypes, num_etypes, skey, NULL); + ret = find_etype(server, etypes, num_etypes, skey, setype); if (ret) { kdc_log(0, "Server has no support for etypes"); return ret; } - *setype = (*skey)->key.keytype; } return 0; } -#endif + +static krb5_error_code +make_anonymous_principalname (PrincipalName *pn) +{ + pn->name_type = KRB5_NT_PRINCIPAL; + pn->name_string.len = 1; + pn->name_string.val = malloc(sizeof(*pn->name_string.val)); + if (pn->name_string.val == NULL) + return ENOMEM; + pn->name_string.val[0] = strdup("anonymous"); + if (pn->name_string.val[0] == NULL) { + free(pn->name_string.val); + pn->name_string.val = NULL; + return ENOMEM; + } + return 0; +} static krb5_error_code encode_reply(KDC_REP *rep, EncTicketPart *et, EncKDCRepPart *ek, @@ -185,7 +171,12 @@ encode_reply(KDC_REP *rep, EncTicketPart *et, EncKDCRepPart *ek, } - krb5_crypto_init(context, skey, etype, &crypto); + ret = krb5_crypto_init(context, skey, etype, &crypto); + if (ret) { + kdc_log(0, "krb5_crypto_init failed: %s", + krb5_get_err_text(context, ret)); + return ret; + } krb5_encrypt_EncryptedData(context, crypto, @@ -208,7 +199,12 @@ encode_reply(KDC_REP *rep, EncTicketPart *et, EncKDCRepPart *ek, krb5_get_err_text(context, ret)); return ret; } - krb5_crypto_init(context, ckey, 0, &crypto); + ret = krb5_crypto_init(context, ckey, 0, &crypto); + if (ret) { + kdc_log(0, "krb5_crypto_init failed: %s", + krb5_get_err_text(context, ret)); + return ret; + } if(rep->msg_type == krb_as_rep) { krb5_encrypt_EncryptedData(context, crypto, @@ -266,8 +262,8 @@ get_pa_etype_info(METHOD_DATA *md, hdb_entry *client) return ENOMEM; for(i = 0; i < client->keys.len; i++) { pa.val[i].etype = client->keys.val[i].key.keytype; - ALLOC(pa.val[i].salttype); if(client->keys.val[i].salt){ + ALLOC(pa.val[i].salttype); #if 0 if(client->keys.val[i].salt->type == hdb_pw_salt) *pa.val[i].salttype = 0; /* or 1? or NULL? */ @@ -290,19 +286,20 @@ get_pa_etype_info(METHOD_DATA *md, hdb_entry *client) krb5_copy_data(context, &client->keys.val[i].salt->salt, &pa.val[i].salt); } else { -#if 0 - *pa.val[i].salttype = 1; /* or 0 with salt? */ -#else - *pa.val[i].salttype = pa_pw_salt; -#endif + /* we return no salt type at all, as that should indicate + * the default salt type and make everybody happy. some + * systems (like w2k) dislike being told the salt type + * here. */ + + pa.val[i].salttype = NULL; pa.val[i].salt = NULL; } } len = length_ETYPE_INFO(&pa); buf = malloc(len); - if (buf) { + if (buf == NULL) { free_ETYPE_INFO(&pa); - return ret; + return ENOMEM; } ret = encode_ETYPE_INFO(buf + len - 1, len, &pa, &len); free_ETYPE_INFO(&pa); @@ -315,13 +312,19 @@ get_pa_etype_info(METHOD_DATA *md, hdb_entry *client) free(buf); return ret; } - md->val[md->len - 1].padata_type = pa_etype_info; + md->val[md->len - 1].padata_type = KRB5_PADATA_ETYPE_INFO; md->val[md->len - 1].padata_value.length = len; md->val[md->len - 1].padata_value.data = buf; return 0; } -static int +/* + * verify the flags on `client' and `server', returning 0 + * if they are OK and generating an error messages and returning + * and error code otherwise. + */ + +krb5_error_code check_flags(hdb_entry *client, const char *client_name, hdb_entry *server, const char *server_name, krb5_boolean is_as_req) @@ -393,11 +396,18 @@ check_flags(hdb_entry *client, const char *client_name, return 0; } +/* + * Return TRUE if `from' is part of `addresses' taking into consideration + * the configuration variables that tells us how strict we should be about + * these checks + */ + static krb5_boolean -check_addresses(HostAddresses *addresses, struct sockaddr *from) +check_addresses(HostAddresses *addresses, const struct sockaddr *from) { krb5_error_code ret; krb5_address addr; + krb5_boolean result; if(check_ticket_addresses == 0) return TRUE; @@ -409,7 +419,9 @@ check_addresses(HostAddresses *addresses, struct sockaddr *from) if(ret) return FALSE; - return krb5_address_search(context, &addr, addresses); + result = krb5_address_search(context, &addr, addresses); + krb5_free_address (context, &addr); + return result; } krb5_error_code @@ -430,9 +442,10 @@ as_rep(KDC_REQ *req, krb5_error_code ret = 0; const char *e_text = NULL; krb5_crypto crypto; - Key *ckey, *skey; + memset(&rep, 0, sizeof(rep)); + if(b->sname == NULL){ server_name = "<unknown server>"; ret = KRB5KRB_ERR_GENERIC; @@ -456,17 +469,18 @@ as_rep(KDC_REQ *req, if(ret) goto out; - client = db_fetch(client_princ); - if(client == NULL){ - kdc_log(0, "UNKNOWN -- %s", client_name); + ret = db_fetch(client_princ, &client); + if(ret){ + kdc_log(0, "UNKNOWN -- %s: %s", client_name, + krb5_get_err_text(context, ret)); ret = KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN; goto out; } - server = db_fetch(server_princ); - - if(server == NULL){ - kdc_log(0, "UNKNOWN -- %s", server_name); + ret = db_fetch(server_princ, &server); + if(ret){ + kdc_log(0, "UNKNOWN -- %s: %s", server_name, + krb5_get_err_text(context, ret)); ret = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN; goto out; } @@ -483,7 +497,7 @@ as_rep(KDC_REQ *req, PA_DATA *pa; int found_pa = 0; kdc_log(5, "Looking for pa-data -- %s", client_name); - while((pa = find_padata(req, &i, pa_enc_timestamp))){ + while((pa = find_padata(req, &i, KRB5_PADATA_ENC_TIMESTAMP))){ krb5_data ts_data; PA_ENC_TS_ENC p; time_t patime; @@ -523,7 +537,14 @@ as_rep(KDC_REQ *req, continue; } - krb5_crypto_init(context, &pa_key->key, 0, &crypto); + ret = krb5_crypto_init(context, &pa_key->key, 0, &crypto); + if (ret) { + kdc_log(0, "krb5_crypto_init failed: %s", + krb5_get_err_text(context, ret)); + free_EncryptedData(&enc_data); + continue; + } + ret = krb5_decrypt_EncryptedData (context, crypto, KRB5_KU_PA_ENC_TIMESTAMP, @@ -586,7 +607,7 @@ as_rep(KDC_REQ *req, ret = realloc_method_data(&method_data); pa = &method_data.val[method_data.len-1]; - pa->padata_type = pa_enc_timestamp; + pa->padata_type = KRB5_PADATA_ENC_TIMESTAMP; pa->padata_value.length = 0; pa->padata_value.data = NULL; @@ -627,23 +648,19 @@ as_rep(KDC_REQ *req, { char *cet; char *set; - krb5_enctype_to_string(context, cetype, &cet); - krb5_enctype_to_string(context, setype, &set); - kdc_log(5, "Using %s/%s", cet, set); - free(cet); - free(set); + + ret = krb5_enctype_to_string(context, cetype, &cet); + if(ret == 0) { + ret = krb5_enctype_to_string(context, setype, &set); + if (ret == 0) { + kdc_log(5, "Using %s/%s", cet, set); + free(set); + } else + free(cet); + } else + kdc_log(5, "Using e-types %d/%d", cetype, setype); } - - memset(&rep, 0, sizeof(rep)); - rep.pvno = 5; - rep.msg_type = krb_as_rep; - copy_Realm(&b->realm, &rep.crealm); - copy_PrincipalName(b->cname, &rep.cname); - rep.ticket.tkt_vno = 5; - copy_Realm(&b->realm, &rep.ticket.realm); - copy_PrincipalName(b->sname, &rep.ticket.sname); - { char str[128]; unparse_flags(KDCOptions2int(f), KDCOptions_units, str, sizeof(str)); @@ -651,13 +668,25 @@ as_rep(KDC_REQ *req, kdc_log(2, "Requested flags: %s", str); } - if(f.renew || f.validate || f.proxy || f.forwarded || f.enc_tkt_in_skey || - f.request_anonymous){ + + if(f.renew || f.validate || f.proxy || f.forwarded || f.enc_tkt_in_skey + || (f.request_anonymous && !allow_anonymous)) { ret = KRB5KDC_ERR_BADOPTION; kdc_log(0, "Bad KDC options -- %s", client_name); goto out; } + rep.pvno = 5; + rep.msg_type = krb_as_rep; + copy_Realm(&b->realm, &rep.crealm); + if (f.request_anonymous) + make_anonymous_principalname (&rep.cname); + else + copy_PrincipalName(b->cname, &rep.cname); + rep.ticket.tkt_vno = 5; + copy_Realm(&b->realm, &rep.ticket.realm); + copy_PrincipalName(b->sname, &rep.ticket.sname); + et.flags.initial = 1; if(client->flags.forwardable && server->flags.forwardable) et.flags.forwardable = f.forwardable; @@ -689,7 +718,7 @@ as_rep(KDC_REQ *req, } krb5_generate_random_keyblock(context, setype, &et.key); - copy_PrincipalName(b->cname, &et.cname); + copy_PrincipalName(&rep.cname, &et.cname); copy_Realm(&b->realm, &et.crealm); { @@ -706,10 +735,13 @@ as_rep(KDC_REQ *req, } fix_time(&b->till); t = *b->till; + + /* be careful not overflowing */ + if(client->max_life) - t = min(t, start + *client->max_life); + t = start + min(t - start, *client->max_life); if(server->max_life) - t = min(t, start + *server->max_life); + t = start + min(t - start, *server->max_life); #if 0 t = min(t, start + realm->max_life); #endif @@ -728,9 +760,9 @@ as_rep(KDC_REQ *req, if(t == 0) t = MAX_TIME; if(client->max_renew) - t = min(t, start + *client->max_renew); + t = start + min(t - start, *client->max_renew); if(server->max_renew) - t = min(t, start + *server->max_renew); + t = start + min(t - start, *server->max_renew); #if 0 t = min(t, start + realm->max_renew); #endif @@ -739,6 +771,9 @@ as_rep(KDC_REQ *req, et.flags.renewable = 1; } } + + if (f.request_anonymous) + et.flags.anonymous = 1; if(b->addresses){ ALLOC(et.caddr); @@ -836,15 +871,10 @@ out2: free(client_name); krb5_free_principal(context, server_princ); free(server_name); - if(client){ - hdb_free_entry(context, client); - free(client); - } - if(server){ - hdb_free_entry(context, server); - free(server); - } - + if(client) + free_ent(client); + if(server) + free_ent(server); return ret; } @@ -948,11 +978,11 @@ check_tgs_flags(KDC_REQ_BODY *b, EncTicketPart *tgt, EncTicketPart *et) old_life -= *tgt->starttime; else old_life -= tgt->authtime; - et->endtime = min(*b->till, *et->starttime + old_life); + et->endtime = min(*et->renew_till, *et->starttime + old_life); } /* checks for excess flags */ - if(f.request_anonymous){ + if(f.request_anonymous && !allow_anonymous){ kdc_log(0, "Request for anonymous ticket"); return KRB5KDC_ERR_BADOPTION; } @@ -1089,7 +1119,10 @@ tgs_make_reply(KDC_REQ_BODY *b, &rep.ticket.realm); krb5_principal2principalname(&rep.ticket.sname, server->principal); copy_Realm(&tgt->crealm, &rep.crealm); - copy_PrincipalName(&tgt->cname, &rep.cname); + if (f.request_anonymous) + make_anonymous_principalname (&tgt->cname); + else + copy_PrincipalName(&tgt->cname, &rep.cname); rep.ticket.tkt_vno = 5; ek.caddr = et.caddr; @@ -1140,7 +1173,8 @@ tgs_make_reply(KDC_REQ_BODY *b, } et.flags.pre_authent = tgt->flags.pre_authent; - et.flags.hw_authent = tgt->flags.hw_authent; + et.flags.hw_authent = tgt->flags.hw_authent; + et.flags.anonymous = tgt->flags.anonymous; /* XXX Check enc-authorization-data */ et.authorization_data = auth_data; @@ -1228,7 +1262,12 @@ tgs_check_authenticator(krb5_auth_context ac, krb5_get_err_text(context, ret)); goto out; } - krb5_crypto_init(context, key, 0, &crypto); + ret = krb5_crypto_init(context, key, 0, &crypto); + if (ret) { + kdc_log(0, "krb5_crypto_init failed: %s", + krb5_get_err_text(context, ret)); + goto out; + } ret = krb5_verify_checksum(context, crypto, KRB5_KU_TGS_REQ_AUTH_CKSUM, @@ -1312,12 +1351,13 @@ tgs_rep2(KDC_REQ_BODY *b, ap_req.ticket.sname, ap_req.ticket.realm); - krbtgt = db_fetch(princ); + ret = db_fetch(princ, &krbtgt); - if(krbtgt == NULL) { + if(ret) { char *p; krb5_unparse_name(context, princ, &p); - kdc_log(0, "Ticket-granting ticket not found in database: %s", p); + kdc_log(0, "Ticket-granting ticket not found in database: %s: %s", + p, krb5_get_err_text(context, ret)); free(p); ret = KRB5KRB_AP_ERR_NOT_US; goto out2; @@ -1352,14 +1392,15 @@ tgs_rep2(KDC_REQ_BODY *b, else verify_ap_req_flags = 0; - ret = krb5_verify_ap_req(context, - &ac, - &ap_req, - princ, - &tkey->key, - verify_ap_req_flags, - &ap_req_options, - &ticket); + ret = krb5_verify_ap_req2(context, + &ac, + &ap_req, + princ, + &tkey->key, + verify_ap_req_flags, + &ap_req_options, + &ticket, + KRB5_KU_TGS_REQ_AUTH); krb5_free_principal(context, princ); if(ret) { @@ -1381,6 +1422,7 @@ tgs_rep2(KDC_REQ_BODY *b, ac, &subkey); if(ret){ + krb5_auth_con_free(context, ac); kdc_log(0, "Failed to get remote subkey: %s", krb5_get_err_text(context, ret)); goto out2; @@ -1388,17 +1430,25 @@ tgs_rep2(KDC_REQ_BODY *b, if(subkey == NULL){ ret = krb5_auth_con_getkey(context, ac, &subkey); if(ret) { + krb5_auth_con_free(context, ac); kdc_log(0, "Failed to get session key: %s", krb5_get_err_text(context, ret)); goto out2; } } if(subkey == NULL){ + krb5_auth_con_free(context, ac); kdc_log(0, "Failed to get key for enc-authorization-data"); ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; /* ? */ goto out2; } - krb5_crypto_init(context, subkey, 0, &crypto); + ret = krb5_crypto_init(context, subkey, 0, &crypto); + if (ret) { + krb5_auth_con_free(context, ac); + kdc_log(0, "krb5_crypto_init failed: %s", + krb5_get_err_text(context, ret)); + goto out2; + } ret = krb5_decrypt_EncryptedData (context, crypto, KRB5_KU_TGS_REQ_AUTH_DAT_SUBKEY, @@ -1406,6 +1456,7 @@ tgs_rep2(KDC_REQ_BODY *b, &ad); krb5_crypto_destroy(context, crypto); if(ret){ + krb5_auth_con_free(context, ac); kdc_log(0, "Failed to decrypt enc-authorization-data"); ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; /* ? */ goto out2; @@ -1414,6 +1465,7 @@ tgs_rep2(KDC_REQ_BODY *b, ALLOC(auth_data); ret = decode_AuthorizationData(ad.data, ad.length, auth_data, NULL); if(ret){ + krb5_auth_con_free(context, ac); free(auth_data); auth_data = NULL; kdc_log(0, "Failed to decode authorization data"); @@ -1460,10 +1512,11 @@ tgs_rep2(KDC_REQ_BODY *b, goto out2; } principalname2krb5_principal(&p, t->sname, t->realm); - uu = db_fetch(p); + ret = db_fetch(p, &uu); krb5_free_principal(context, p); - if(uu == NULL){ - ret = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN; + if(ret){ + if (ret == ENOENT) + ret = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN; goto out; } ret = hdb_enctype2key(context, uu, t->enc_part.etype, &tkey); @@ -1491,10 +1544,9 @@ tgs_rep2(KDC_REQ_BODY *b, else kdc_log(0, "TGS-REQ %s from %s for %s", cpn, from, spn); server_lookup: - server = db_fetch(sp); - + ret = db_fetch(sp, &server); - if(server == NULL){ + if(ret){ Realm req_rlm, new_rlm; if(loop++ < 2 && (req_rlm = is_krbtgt(&sp->name))){ new_rlm = find_rpath(req_rlm); @@ -1509,19 +1561,24 @@ tgs_rep2(KDC_REQ_BODY *b, goto server_lookup; } } - kdc_log(0, "Server not found in database: %s", spn); - ret = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN; + kdc_log(0, "Server not found in database: %s: %s", spn, + krb5_get_err_text(context, ret)); + if (ret == ENOENT) + ret = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN; goto out; } - client = db_fetch(cp); - if(client == NULL) - kdc_log(1, "Client not found in database: %s", cpn); + ret = db_fetch(cp, &client); + if(ret) + kdc_log(1, "Client not found in database: %s: %s", + cpn, krb5_get_err_text(context, ret)); #if 0 /* XXX check client only if same realm as krbtgt-instance */ - if(client == NULL){ - kdc_log(0, "Client not found in database: %s", cpn); - ret = KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN; + if(ret){ + kdc_log(0, "Client not found in database: %s: %s", + cpn, krb5_get_err_text(context, ret)); + if (ret == ENOENT) + ret = KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN; goto out; } #endif @@ -1561,15 +1618,10 @@ tgs_rep2(KDC_REQ_BODY *b, free(spn); free(cpn); - if(server){ - hdb_free_entry(context, server); - free(server); - } - if(client){ - hdb_free_entry(context, client); - free(client); - } - + if(server) + free_ent(server); + if(client) + free_ent(client); } out2: if(ret) @@ -1593,10 +1645,8 @@ out2: free(auth_data); } - if(krbtgt){ - hdb_free_entry(context, krbtgt); - free(krbtgt); - } + if(krbtgt) + free_ent(krbtgt); return ret; } @@ -1617,7 +1667,7 @@ tgs_rep(KDC_REQ *req, goto out; } - tgs_req = find_padata(req, &i, pa_tgs_req); + tgs_req = find_padata(req, &i, KRB5_PADATA_TGS_REQ); if(tgs_req == NULL){ ret = KRB5KDC_ERR_PADATA_TYPE_NOSUPP; diff --git a/crypto/heimdal/kdc/kstash.8 b/crypto/heimdal/kdc/kstash.8 index e9a7502..92b532d 100644 --- a/crypto/heimdal/kdc/kstash.8 +++ b/crypto/heimdal/kdc/kstash.8 @@ -1,27 +1,59 @@ -.\" $Id: kstash.8,v 1.2 2000/01/08 10:57:31 assar Exp $ +.\" $Id: kstash.8,v 1.3 2000/09/01 16:37:52 joda Exp $ .\" -.Dd Aug 27, 1997 +.Dd September 1, 2000 .Dt KSTASH 8 .Os HEIMDAL .Sh NAME .Nm kstash .Nd -Store the KDC master password in a file +store the KDC master password in a file .Sh SYNOPSIS .Nm -.Op Fl k Ar file -.Op Fl -key-file= Ns Ar file +.Oo Fl e Ar string \*(Ba Xo +.Fl -enctype= Ns Ar string Oc +.Xc +.Oo Fl k Ar file \*(Ba Xo +.Fl -key-file= Ns Ar file Oc +.Xc +.Op Fl -convert-file +.Op Fl -master-key-fd= Ns Ar fd +.Op Fl h | Fl -help +.Op Fl -version .Sh DESCRIPTION .Nm -allows you to the master password and store in a file that will be read -by the KDC. +reads the Kerberos master key and stores it in a file that will be +used by the KDC. .Pp -Options supported: +Supported options: .Bl -tag -width Ds -.It Fl k Ar file -.It Fl -key-file= Ns Ar file -Specify what file the master key is stored in. The default is -.Pa m-key . +.It Xo +.Fl e Ar string Ns , +.Fl -enctype= Ns Ar string +.Xc +the encryption type to use, defaults to DES3-CBC-SHA1 +.It Xo +.Fl k Ar file Ns , +.Fl -key-file= Ns Ar file +.Xc +the name of the master key file +.It Xo +.Fl -convert-file +.Xc +don't ask for a new master key, just read an old master key file, and +writes it back in the new keyfile format +.It Xo +.Fl -master-key-fd= Ns Ar fd +.Xc +filedescriptor to read passphrase from, if not specified the +passphrase will be read from the terminal .El +.\".Sh ENVIRONMENT +.\".Sh FILES +.\".Sh EXAMPLES +.\".Sh DIAGNOSTICS .Sh SEE ALSO .Xr kdc 8 +.\".Sh STANDARDS +.\".Sh HISTORY +.\".Sh AUTHORS +.\".Sh BUGS diff --git a/crypto/heimdal/kdc/kstash.c b/crypto/heimdal/kdc/kstash.c index 5b79fd1..edb00b2 100644 --- a/crypto/heimdal/kdc/kstash.c +++ b/crypto/heimdal/kdc/kstash.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997-1999 Kungliga Tekniska Högskolan + * Copyright (c) 1997-2001 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -33,122 +33,41 @@ #include "headers.h" -RCSID("$Id: kstash.c,v 1.10 1999/11/13 04:14:17 assar Exp $"); +RCSID("$Id: kstash.c,v 1.14 2001/01/30 17:08:35 assar Exp $"); krb5_context context; char *keyfile = HDB_DB_DIR "/m-key"; -char *v4_keyfile; int convert_flag; int help_flag; int version_flag; +int master_key_fd = -1; + +char *enctype_str = "des3-cbc-sha1"; + struct getargs args[] = { + { "enctype", 'e', arg_string, &enctype_str, "encryption type" }, { "key-file", 'k', arg_string, &keyfile, "master key file", "file" }, - { "version4-key-file", '4', arg_string, &v4_keyfile, - "kerberos 4 master key file", "file" }, { "convert-file", 0, arg_flag, &convert_flag, - "convert keytype of keyfile" }, + "just convert keyfile to new format" }, + { "master-key-fd", 0, arg_integer, &master_key_fd, + "filedescriptor to read passphrase from", "fd" }, { "help", 'h', arg_flag, &help_flag }, { "version", 0, arg_flag, &version_flag } }; int num_args = sizeof(args) / sizeof(args[0]); -static void -write_keyfile(EncryptionKey key) -{ - FILE *f; - char buf[1024]; - size_t len; - -#ifdef HAVE_UMASK - umask(077); -#endif - - f = fopen(keyfile, "w"); - if(f == NULL) - krb5_err(context, 1, errno, "%s", keyfile); - encode_EncryptionKey((unsigned char *)buf + sizeof(buf) - 1, - sizeof(buf), &key, &len); - fwrite(buf + sizeof(buf) - len, len, 1, f); - memset(buf, 0, sizeof(buf)); - if(ferror(f)) { - int e = errno; - unlink(keyfile); - krb5_err(context, 1, e, "%s", keyfile); - } - fclose(f); - chmod(keyfile, 0400); -} - -static int -convert_file(void) -{ - FILE *f; - unsigned char buf[1024]; - char *fn; - size_t len; - EncryptionKey key; - krb5_error_code ret; - - f = fopen(keyfile, "r"); - if(f == NULL) { - krb5_warn(context, errno, "%s", keyfile); - return 1; - } - len = fread(buf, 1, sizeof(buf), f); - if(ferror(f)) { - krb5_warn(context, errno, "fread"); - ret = 1; - goto out1; - } - fclose(f); - ret = decode_EncryptionKey(buf, len, &key, &len); - memset(buf, 0, sizeof(buf)); - if(ret) { - krb5_warn(context, ret, "decode_EncryptionKey"); - goto out2; - } - if(key.keytype == KEYTYPE_DES) - key.keytype = ETYPE_DES_CBC_MD5; - else if(key.keytype == ETYPE_DES_CBC_MD5) { - krb5_warnx(context, "keyfile already converted"); - ret = 0; - goto out2; - } else { - krb5_warnx(context, "bad encryption key type (%d)", key.keytype); - ret = 1; - goto out2; - } - asprintf(&fn, "%s.old", keyfile); - if(fn == NULL) { - krb5_warn(context, ENOMEM, "malloc"); - ret = 1; - goto out1; - } - if(rename(keyfile, fn) < 0) { - krb5_warn(context, errno, "rename"); - ret = 1; - goto out1; - } - write_keyfile(key); - krb5_free_keyblock_contents(context, &key); - return 0; -out1: - memset(buf, 0, sizeof(buf)); - return ret ? 1 : 0; -out2: - krb5_free_keyblock_contents(context, &key); - return ret ? 1 : 0; -} - int main(int argc, char **argv) { char buf[1024]; - EncryptionKey key; - FILE *f; + krb5_error_code ret; + + krb5_enctype enctype; + + hdb_master_key mkey; krb5_program_setup(&context, argc, argv, args, num_args, NULL); @@ -159,30 +78,71 @@ main(int argc, char **argv) exit(0); } - if(convert_flag) - exit(convert_file()); - - key.keytype = ETYPE_DES_CBC_MD5; /* XXX */ - if(v4_keyfile) { - f = fopen(v4_keyfile, "r"); - if(f == NULL) - krb5_err(context, 1, errno, "fopen(%s)", v4_keyfile); - key.keyvalue.length = sizeof(des_cblock); - key.keyvalue.data = malloc(key.keyvalue.length); - fread(key.keyvalue.data, 1, key.keyvalue.length, f); - fclose(f); + ret = krb5_string_to_enctype(context, enctype_str, &enctype); + if(ret) + krb5_err(context, 1, ret, "krb5_string_to_enctype"); + + ret = hdb_read_master_key(context, keyfile, &mkey); + if(ret && ret != ENOENT) + krb5_err(context, 1, ret, "reading master key from %s", keyfile); + + if (convert_flag) { + if (ret) + krb5_err(context, 1, ret, "reading master key from %s", keyfile); } else { + krb5_keyblock key; krb5_salt salt; salt.salttype = KRB5_PW_SALT; /* XXX better value? */ salt.saltvalue.data = NULL; salt.saltvalue.length = 0; - if(des_read_pw_string(buf, sizeof(buf), "Master key: ", 1)) - exit(1); - krb5_string_to_key_salt(context, key.keytype, buf, salt, &key); + if(master_key_fd != -1) { + ssize_t n; + n = read(master_key_fd, buf, sizeof(buf)); + if(n <= 0) + krb5_err(context, 1, errno, "failed to read passphrase"); + buf[n] = '\0'; + buf[strcspn(buf, "\r\n")] = '\0'; + } else { + if(des_read_pw_string(buf, sizeof(buf), "Master key: ", 1)) + exit(1); + } + krb5_string_to_key_salt(context, enctype, buf, salt, &key); + ret = hdb_add_master_key(context, &key, &mkey); + + krb5_free_keyblock_contents(context, &key); + } - write_keyfile(key); - krb5_free_keyblock_contents(context, &key); - exit(0); + { + char *new, *old; + asprintf(&old, "%s.old", keyfile); + asprintf(&new, "%s.new", keyfile); + if(unlink(new) < 0 && errno != ENOENT) { + ret = errno; + goto out; + } + krb5_warnx(context, "writing key to `%s'", keyfile); + ret = hdb_write_master_key(context, new, mkey); + if(ret) + unlink(new); + else { + unlink(old); + if(link(keyfile, old) < 0 && errno != ENOENT) { + ret = errno; + unlink(new); + } else if(rename(new, keyfile) < 0) { + ret = errno; + } + } + out: + free(old); + free(new); + if(ret) + krb5_warn(context, errno, "writing master key file"); + } + + hdb_free_master_key(context, mkey); + + exit(ret != 0); } diff --git a/crypto/heimdal/kdc/log.c b/crypto/heimdal/kdc/log.c index ddbdbee..5a36969 100644 --- a/crypto/heimdal/kdc/log.c +++ b/crypto/heimdal/kdc/log.c @@ -32,7 +32,7 @@ */ #include "kdc_locl.h" -RCSID("$Id: log.c,v 1.12 1999/12/02 17:05:00 joda Exp $"); +RCSID("$Id: log.c,v 1.13 2000/09/10 19:27:29 joda Exp $"); static krb5_log_facility *logf; @@ -51,7 +51,7 @@ kdc_openlog(krb5_config_section *cf) krb5_addlog_dest(context, logf, *p); krb5_config_free_strings(s); }else - krb5_addlog_dest(context, logf, "0-1/FILE:" HDB_DB_DIR "/kdc.log"); + krb5_addlog_dest(context, logf, DEFAULT_LOG_DEST); krb5_set_warn_dest(context, logf); } diff --git a/crypto/heimdal/kdc/main.c b/crypto/heimdal/kdc/main.c index 46d7aba..a14ae84 100644 --- a/crypto/heimdal/kdc/main.c +++ b/crypto/heimdal/kdc/main.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 1999 Kungliga Tekniska Högskolan + * Copyright (c) 1997 - 2000 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -33,7 +33,7 @@ #include "kdc_locl.h" -RCSID("$Id: main.c,v 1.21 1999/12/02 17:05:00 joda Exp $"); +RCSID("$Id: main.c,v 1.24 2000/12/31 07:46:14 assar Exp $"); sig_atomic_t exit_flag = 0; krb5_context context; @@ -50,7 +50,9 @@ main(int argc, char **argv) krb5_error_code ret; set_progname(argv[0]); - krb5_init_context(&context); + ret = krb5_init_context(&context); + if (ret) + errx (1, "krb5_init_context failed: %d", ret); configure(argc, argv); @@ -88,10 +90,13 @@ main(int argc, char **argv) sigemptyset(&sa.sa_mask); sigaction(SIGINT, &sa, NULL); + sigaction(SIGTERM, &sa, NULL); } #else signal(SIGINT, sigterm); + signal(SIGTERM, sigterm); #endif + pidfile(NULL); loop(); krb5_free_context(context); return 0; diff --git a/crypto/heimdal/kdc/misc.c b/crypto/heimdal/kdc/misc.c index e476ebc..aebdc68 100644 --- a/crypto/heimdal/kdc/misc.c +++ b/crypto/heimdal/kdc/misc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997 Kungliga Tekniska Högskolan + * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -33,17 +33,20 @@ #include "kdc_locl.h" -RCSID("$Id: misc.c,v 1.18 1999/12/02 17:05:00 joda Exp $"); +RCSID("$Id: misc.c,v 1.22 2001/01/30 03:54:21 assar Exp $"); struct timeval now; -hdb_entry* -db_fetch(krb5_principal principal) +krb5_error_code +db_fetch(krb5_principal principal, hdb_entry **h) { hdb_entry *ent; - krb5_error_code ret; + krb5_error_code ret = HDB_ERR_NOENTRY; int i; - ALLOC(ent); + + ent = malloc (sizeof (*ent)); + if (ent == NULL) + return ENOMEM; ent->principal = principal; for(i = 0; i < num_db; i++) { @@ -55,9 +58,19 @@ db_fetch(krb5_principal principal) } ret = db[i]->fetch(context, db[i], HDB_F_DECRYPT, ent); db[i]->close(context, db[i]); - if(ret == 0) - return ent; + if(ret == 0) { + *h = ent; + return 0; + } } free(ent); - return NULL; + return ret; +} + +void +free_ent(hdb_entry *ent) +{ + hdb_free_entry (context, ent); + free (ent); } + diff --git a/crypto/heimdal/kdc/mit_dump.c b/crypto/heimdal/kdc/mit_dump.c new file mode 100644 index 0000000..336d265 --- /dev/null +++ b/crypto/heimdal/kdc/mit_dump.c @@ -0,0 +1,370 @@ +/* + * Copyright (c) 2000 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "hprop.h" + +RCSID("$Id: mit_dump.c,v 1.3 2000/08/09 09:57:37 joda Exp $"); + +/* +can have any number of princ stanzas. +format is as follows (only \n indicates newlines) +princ\t%d\t (%d is KRB5_KDB_V1_BASE_LENGTH, always 38) +%d\t (strlen of principal e.g. shadow/foo@ANDREW.CMU.EDU) +%d\t (number of tl_data) +%d\t (number of key data, e.g. how many keys for this user) +%d\t (extra data length) +%s\t (principal name) +%d\t (attributes) +%d\t (max lifetime, seconds) +%d\t (max renewable life, seconds) +%d\t (expiration, seconds since epoch or 2145830400 for never) +%d\t (password expiration, seconds, 0 for never) +%d\t (last successful auth, seconds since epoch) +%d\t (last failed auth, per above) +%d\t (failed auth count) +foreach tl_data 0 to number of tl_data - 1 as above + %d\t%d\t (data type, data length) + foreach tl_data 0 to length-1 + %02x (tl data contents[element n]) + except if tl_data length is 0 + %d (always -1) + \t +foreach key 0 to number of keys - 1 as above + %d\t%d\t (key data version, kvno) + foreach version 0 to key data version - 1 (a key or a salt) + %d\t%d\t(data type for this key, data length for this key) + foreach key data length 0 to length-1 + %02x (key data contents[element n]) + except if key_data length is 0 + %d (always -1) + \t +foreach extra data length 0 to length - 1 + %02x (extra data part) +unless no extra data + %d (always -1) +;\n + +*/ + +static int +hex_to_octet_string(const char *ptr, krb5_data *data) +{ + int i; + unsigned int v; + for(i = 0; i < data->length; i++) { + if(sscanf(ptr + 2 * i, "%02x", &v) != 1) + return -1; + ((unsigned char*)data->data)[i] = v; + } + return 2 * i; +} + +static char * +nexttoken(char **p) +{ + char *q; + do { + q = strsep(p, " \t"); + } while(q && *q == '\0'); + return q; +} + +static size_t +getdata(char **p, unsigned char *buf, size_t len) +{ + size_t i; + int v; + char *q = nexttoken(p); + i = 0; + while(*q && i < len) { + if(sscanf(q, "%02x", &v) != 1) + break; + buf[i++] = v; + q += 2; + } + return i; +} + +static int +getint(char **p) +{ + int val; + char *q = nexttoken(p); + sscanf(q, "%d", &val); + return val; +} + +#include <kadm5/admin.h> + +static void +attr_to_flags(unsigned attr, HDBFlags *flags) +{ + flags->postdate = !(attr & KRB5_KDB_DISALLOW_POSTDATED); + flags->forwardable = !(attr & KRB5_KDB_DISALLOW_FORWARDABLE); + flags->initial = !!(attr & KRB5_KDB_DISALLOW_TGT_BASED); + flags->renewable = !(attr & KRB5_KDB_DISALLOW_RENEWABLE); + flags->proxiable = !(attr & KRB5_KDB_DISALLOW_PROXIABLE); + /* DUP_SKEY */ + flags->invalid = !!(attr & KRB5_KDB_DISALLOW_ALL_TIX); + flags->require_preauth = !!(attr & KRB5_KDB_REQUIRES_PRE_AUTH); + /* HW_AUTH */ + flags->server = !(attr & KRB5_KDB_DISALLOW_SVR); + flags->change_pw = !!(attr & KRB5_KDB_PWCHANGE_SERVICE); + flags->client = 1; /* XXX */ +} + +#define KRB5_KDB_SALTTYPE_NORMAL 0 +#define KRB5_KDB_SALTTYPE_V4 1 +#define KRB5_KDB_SALTTYPE_NOREALM 2 +#define KRB5_KDB_SALTTYPE_ONLYREALM 3 +#define KRB5_KDB_SALTTYPE_SPECIAL 4 +#define KRB5_KDB_SALTTYPE_AFS3 5 + +static krb5_error_code +fix_salt(krb5_context context, hdb_entry *ent, int key_num) +{ + krb5_error_code ret; + Salt *salt = ent->keys.val[key_num].salt; + /* fix salt type */ + switch((int)salt->type) { + case KRB5_KDB_SALTTYPE_NORMAL: + salt->type = KRB5_PADATA_PW_SALT; + break; + case KRB5_KDB_SALTTYPE_V4: + krb5_data_free(&salt->salt); + salt->type = KRB5_PADATA_PW_SALT; + break; + case KRB5_KDB_SALTTYPE_NOREALM: + { + size_t len; + int i; + krb5_error_code ret; + char *p; + + len = 0; + for (i = 0; i < ent->principal->name.name_string.len; ++i) + len += strlen(ent->principal->name.name_string.val[i]); + ret = krb5_data_alloc (&salt->salt, len); + if (ret) + return ret; + p = salt->salt.data; + for (i = 0; i < ent->principal->name.name_string.len; ++i) { + memcpy (p, + ent->principal->name.name_string.val[i], + strlen(ent->principal->name.name_string.val[i])); + p += strlen(ent->principal->name.name_string.val[i]); + } + + salt->type = KRB5_PADATA_PW_SALT; + break; + } + case KRB5_KDB_SALTTYPE_ONLYREALM: + krb5_data_free(&salt->salt); + ret = krb5_data_copy(&salt->salt, + ent->principal->realm, + strlen(ent->principal->realm)); + if(ret) + return ret; + salt->type = KRB5_PADATA_PW_SALT; + break; + case KRB5_KDB_SALTTYPE_SPECIAL: + salt->type = KRB5_PADATA_PW_SALT; + break; + case KRB5_KDB_SALTTYPE_AFS3: + krb5_data_free(&salt->salt); + ret = krb5_data_copy(&salt->salt, + ent->principal->realm, + strlen(ent->principal->realm)); + if(ret) + return ret; + salt->type = KRB5_PADATA_AFS3_SALT; + break; + default: + abort(); + } + return 0; +} + +int +mit_prop_dump(void *arg, const char *file) +{ + krb5_error_code ret; + char buf [1024]; + FILE *f; + int lineno = 0; + struct hdb_entry ent; + + struct prop_data *pd = arg; + + f = fopen(file, "r"); + if(f == NULL) + return errno; + + while(fgets(buf, sizeof(buf), f)) { + char *p = buf, *q; + + int i; + + int num_tl_data; + int num_key_data; + int extra_data_length; + int attributes; + + int tmp; + + lineno++; + + memset(&ent, 0, sizeof(ent)); + + q = nexttoken(&p); + if(strcmp(q, "kdb5_util") == 0) { + int major; + q = nexttoken(&p); /* load_dump */ + if(strcmp(q, "load_dump")) + errx(1, "line %d: unknown version", lineno); + q = nexttoken(&p); /* load_dump */ + if(strcmp(q, "version")) + errx(1, "line %d: unknown version", lineno); + q = nexttoken(&p); /* x.0 */ + if(sscanf(q, "%d", &major) != 1) + errx(1, "line %d: unknown version", lineno); + if(major != 4) + errx(1, "unknown dump file format, got %d, expected 4", major); + continue; + } else if(strcmp(q, "princ") != 0) { + warnx("line %d: not a principal", lineno); + continue; + } + tmp = getint(&p); + if(tmp != 38) { + warnx("line %d: bad base length %d != 38", lineno, tmp); + continue; + } + q = nexttoken(&p); /* length of principal */ + num_tl_data = getint(&p); /* number of tl-data */ + num_key_data = getint(&p); /* number of key-data */ + extra_data_length = getint(&p); /* length of extra data */ + q = nexttoken(&p); /* principal name */ + krb5_parse_name(pd->context, q, &ent.principal); + attributes = getint(&p); /* attributes */ + attr_to_flags(attributes, &ent.flags); + tmp = getint(&p); /* max life */ + if(tmp != 0) { + ALLOC(ent.max_life); + *ent.max_life = tmp; + } + tmp = getint(&p); /* max renewable life */ + if(tmp != 0) { + ALLOC(ent.max_renew); + *ent.max_renew = tmp; + } + tmp = getint(&p); /* expiration */ + if(tmp != 0 && tmp != 2145830400) { + ALLOC(ent.valid_end); + *ent.valid_end = tmp; + } + tmp = getint(&p); /* pw expiration */ + if(tmp != 0) { + ALLOC(ent.pw_end); + *ent.pw_end = tmp; + } + q = nexttoken(&p); /* last auth */ + q = nexttoken(&p); /* last failed auth */ + q = nexttoken(&p); /* fail auth count */ + for(i = 0; i < num_tl_data; i++) { + unsigned long val; + int tl_type, tl_length; + unsigned char *buf; + krb5_principal princ; + + tl_type = getint(&p); /* data type */ + tl_length = getint(&p); /* data length */ + +#define KRB5_TL_LAST_PWD_CHANGE 1 +#define KRB5_TL_MOD_PRINC 2 + switch(tl_type) { + case KRB5_TL_MOD_PRINC: + buf = malloc(tl_length); + getdata(&p, buf, tl_length); /* data itself */ + val = buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24); + ret = krb5_parse_name(pd->context, buf + 4, &princ); + free(buf); + ALLOC(ent.modified_by); + ent.modified_by->time = val; + ent.modified_by->principal = princ; + break; + default: + nexttoken(&p); + break; + } + } + ALLOC_SEQ(&ent.keys, num_key_data); + for(i = 0; i < num_key_data; i++) { + int key_versions; + key_versions = getint(&p); /* key data version */ + ent.kvno = getint(&p); /* XXX kvno */ + + ALLOC(ent.keys.val[i].mkvno); + *ent.keys.val[i].mkvno = 0; + + /* key version 0 -- actual key */ + ent.keys.val[i].key.keytype = getint(&p); /* key type */ + tmp = getint(&p); /* key length */ + /* the first two bytes of the key is the key length -- + skip it */ + krb5_data_alloc(&ent.keys.val[i].key.keyvalue, tmp - 2); + q = nexttoken(&p); /* key itself */ + hex_to_octet_string(q + 4, &ent.keys.val[i].key.keyvalue); + + if(key_versions > 1) { + /* key version 1 -- optional salt */ + ALLOC(ent.keys.val[i].salt); + ent.keys.val[i].salt->type = getint(&p); /* salt type */ + tmp = getint(&p); /* salt length */ + if(tmp > 0) { + krb5_data_alloc(&ent.keys.val[i].salt->salt, tmp - 2); + q = nexttoken(&p); /* salt itself */ + hex_to_octet_string(q + 4, &ent.keys.val[i].salt->salt); + } else { + ent.keys.val[i].salt->salt.length = 0; + ent.keys.val[i].salt->salt.data = NULL; + tmp = getint(&p); /* -1, if no data. */ + } + fix_salt(pd->context, &ent, i); + } + } + q = nexttoken(&p); /* extra data */ + v5_prop(pd->context, NULL, &ent, arg); + } + return 0; +} diff --git a/crypto/heimdal/kdc/string2key.8 b/crypto/heimdal/kdc/string2key.8 new file mode 100644 index 0000000..be8b1f6 --- /dev/null +++ b/crypto/heimdal/kdc/string2key.8 @@ -0,0 +1,76 @@ +.\" $Id: string2key.8,v 1.2 2000/03/04 14:02:55 assar Exp $ +.\" +.Dd March 4, 2000 +.Dt STRING2KEY 8 +.Os HEIMDAL +.Sh NAME +.Nm string2key +.Nd +map a password into a key +.Sh SYNOPSIS +.Nm +.Op Fl 5 | Fl -version5 +.Op Fl 4 | Fl -version4 +.Op Fl a | Fl -afs +.Oo Fl c Ar cell \*(Ba Xo +.Fl -cell= Ns Ar cell Oc +.Xc +.Oo Fl w Ar password \*(Ba Xo +.Fl -password= Ns Ar password Oc +.Xc +.Oo Fl p Ar principal \*(Ba Xo +.Fl -principal= Ns Ar principal Oc +.Xc +.Oo Fl k Ar string \*(Ba Xo +.Fl -keytype= Ns Ar string Oc +.Xc +.Ar password +.Sh DESCRIPTION +.Nm +performs the string-to-key function. +This is useful when you want to handle the raw key instead of the password. +Supported options: +.Bl -tag -width Ds +.It Xo +.Fl 5 Ns , +.Fl -version5 +.Xc +Output Kerberos v5 string-to-key +.It Xo +.Fl 4 Ns , +.Fl -version4 +.Xc +Output Kerberos v4 string-to-key +.It Xo +.Fl a Ns , +.Fl -afs +.Xc +Output AFS string-to-key +.It Xo +.Fl c Ar cell Ns , +.Fl -cell= Ns Ar cell +.Xc +AFS cell to use +.It Xo +.Fl w Ar password Ns , +.Fl -password= Ns Ar password +.Xc +Password to use +.It Xo +.Fl p Ar principal Ns , +.Fl -principal= Ns Ar principal +.Xc +Kerberos v5 principal to use +.It Xo +.Fl k Ar string Ns , +.Fl -keytype= Ns Ar string +.Xc +Keytype +.It Xo +.Fl -version +.Xc +print version +.It Xo +.Fl -help +.Xc +.El diff --git a/crypto/heimdal/kdc/v4_dump.c b/crypto/heimdal/kdc/v4_dump.c new file mode 100644 index 0000000..dc0a8f2 --- /dev/null +++ b/crypto/heimdal/kdc/v4_dump.c @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2000 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "hprop.h" + +RCSID("$Id: v4_dump.c,v 1.4 2001/01/26 15:55:07 joda Exp $"); + +static time_t +time_parse(const char *cp) +{ + char wbuf[5]; + struct tm tp; + int local; + + memset(&tp, 0, sizeof(tp)); /* clear out the struct */ + + /* new format is YYYYMMDDHHMM UTC, + old format is YYMMDDHHMM local time */ + if (strlen(cp) > 10) { /* new format */ + strlcpy(wbuf, cp, sizeof(wbuf)); + tp.tm_year = atoi(wbuf) - 1900; + cp += 4; + local = 0; + } else { + wbuf[0] = *cp++; + wbuf[1] = *cp++; + wbuf[2] = '\0'; + tp.tm_year = atoi(wbuf); + if(tp.tm_year < 38) + tp.tm_year += 100; + local = 1; + } + + wbuf[0] = *cp++; + wbuf[1] = *cp++; + wbuf[2] = 0; + tp.tm_mon = atoi(wbuf) - 1; + + wbuf[0] = *cp++; + wbuf[1] = *cp++; + tp.tm_mday = atoi(wbuf); + + wbuf[0] = *cp++; + wbuf[1] = *cp++; + tp.tm_hour = atoi(wbuf); + + wbuf[0] = *cp++; + wbuf[1] = *cp++; + tp.tm_min = atoi(wbuf); + + return(tm2time(tp, local)); +} + +/* convert a version 4 dump file */ +int +v4_prop_dump(void *arg, const char *file) +{ + char buf [1024]; + FILE *f; + int lineno = 0; + + f = fopen(file, "r"); + if(f == NULL) + return errno; + + while(fgets(buf, sizeof(buf), f)) { + int ret; + unsigned long key[2]; /* yes, long */ + char exp_date[64], mod_date[64]; + struct v4_principal pr; + int attributes; + + memset(&pr, 0, sizeof(pr)); + errno = 0; + lineno++; + ret = sscanf(buf, "%s %s %d %d %d %d %lx %lx %s %s %s %s", + pr.name, pr.instance, + &pr.max_life, &pr.mkvno, &pr.kvno, + &attributes, + &key[0], &key[1], + exp_date, mod_date, + pr.mod_name, pr.mod_instance); + if(ret != 12){ + warnx("Line %d malformed (ignored)", lineno); + continue; + } + if(attributes != 0) { + warnx("Line %d (%s.%s) has non-zero attributes - skipping", + lineno, pr.name, pr.instance); + continue; + } + pr.key[0] = (key[0] >> 24) & 0xff; + pr.key[1] = (key[0] >> 16) & 0xff; + pr.key[2] = (key[0] >> 8) & 0xff; + pr.key[3] = (key[0] >> 0) & 0xff; + pr.key[4] = (key[1] >> 24) & 0xff; + pr.key[5] = (key[1] >> 16) & 0xff; + pr.key[6] = (key[1] >> 8) & 0xff; + pr.key[7] = (key[1] >> 0) & 0xff; + pr.exp_date = time_parse(exp_date); + pr.mod_date = time_parse(mod_date); + if (pr.instance[0] == '*') + pr.instance[0] = '\0'; + if (pr.mod_name[0] == '*') + pr.mod_name[0] = '\0'; + if (pr.mod_instance[0] == '*') + pr.mod_instance[0] = '\0'; + v4_prop(arg, &pr); + memset(&pr, 0, sizeof(pr)); + } + return 0; +} |