From 574a9c0456c182831b3d01a4d7ee0c737b91b107 Mon Sep 17 00:00:00 2001 From: Russ Allbery Date: Tue, 9 Jun 2009 14:39:39 -0700 Subject: Remove Subversion Id strings --- client/keytab.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'client/keytab.c') diff --git a/client/keytab.c b/client/keytab.c index eb37ec1..2d31a27 100644 --- a/client/keytab.c +++ b/client/keytab.c @@ -1,5 +1,4 @@ -/* $Id$ - * +/* * Implementation of keytab handling for the wallet client. * * Written by Russ Allbery -- cgit v1.2.3 From b093893870d56cd460b16645496ec6c30c62a02f Mon Sep 17 00:00:00 2001 From: Russ Allbery Date: Mon, 8 Feb 2010 19:41:27 -0800 Subject: Initial port to Heimdal Just get the client code to compile with Heimdal. This will need more work later to use my regular Kerberos portability layer. --- client/keytab.c | 4 ++++ client/srvtab.c | 13 +++++++++++++ configure.ac | 4 ++++ 3 files changed, 21 insertions(+) (limited to 'client/keytab.c') diff --git a/client/keytab.c b/client/keytab.c index 2d31a27..bdd0134 100644 --- a/client/keytab.c +++ b/client/keytab.c @@ -47,7 +47,11 @@ merge_keytab(krb5_context ctx, const char *newfile, const char *file) status = krb5_kt_add_entry(ctx, old, &entry); if (status != 0) die_krb5(ctx, status, "cannot write to keytab %s", file); +#ifdef HAVE_KRB5_KT_FREE_ENTRY + krb5_kt_free_entry(ctx, &entry); +#else krb5_free_keytab_entry_contents(ctx, &entry); +#endif } if (status != KRB5_KT_END) die_krb5(ctx, status, "error reading temporary keytab %s", newfile); diff --git a/client/srvtab.c b/client/srvtab.c index 0cca70d..a01026e 100644 --- a/client/srvtab.c +++ b/client/srvtab.c @@ -58,8 +58,13 @@ write_srvtab(krb5_context ctx, const char *srvtab, const char *principal, ret = krb5_kt_get_entry(ctx, kt, princ, 0, ENCTYPE_DES_CBC_CRC, &entry); if (ret != 0) die_krb5(ctx, ret, "error reading DES key from keytab %s", keytab); +#ifdef HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK + if (entry.keyblock.keyvalue.length != 8) + die("invalid DES key length in keytab"); +#else if (entry.key.length != 8) die("invalid DES key length in keytab"); +#endif krb5_kt_close(ctx, kt); /* Convert the principal to a Kerberos v4 principal. */ @@ -80,9 +85,17 @@ write_srvtab(krb5_context ctx, const char *srvtab, const char *principal, length += strlen(realm); data[length++] = '\0'; data[length++] = '\0'; +#ifdef HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK + memcpy(data + length, entry.keyblock.keyvalue.data, 8); +#else memcpy(data + length, entry.key.contents, 8); +#endif length += 8; +#ifdef HAVE_KRB5_KT_FREE_ENTRY + krb5_kt_free_entry(ctx, &entry); +#else krb5_free_keytab_entry_contents(ctx, &entry); +#endif /* Write out the srvtab file. */ write_file(srvtab, data, length); diff --git a/configure.ac b/configure.ac index bada657..bc55ad0 100644 --- a/configure.ac +++ b/configure.ac @@ -45,6 +45,10 @@ AC_ARG_WITH([wallet-port], RRA_LIB_REMCTL RRA_LIB_KRB5 +RRA_LIB_KRB5_SWITCH +AC_CHECK_FUNCS([krb5_kt_free_entry]) +AC_CHECK_MEMBERS([krb5_keytab_entry.keyblock], , , [#include ]) +RRA_LIB_KRB5_RESTORE RRA_LIB_AFS AS_IF([test x"$rra_afs" = xtrue], [RRA_LIB_KRB4 -- cgit v1.2.3 From 2d33440272200cad20a5a4c58e5d8aa0dfad9a1f Mon Sep 17 00:00:00 2001 From: Russ Allbery Date: Tue, 9 Feb 2010 13:37:58 -0800 Subject: Remove kaserver synchronization support from the wallet client The wallet client no longer enables kaserver synchronization when a srvtab is requested with -S. Instead, it just extracts the DES key from the keytab and writes it to a srvtab. It no longer forces the kvno of the srvtab to 0 (a Stanford-specific action) and instead preserves the kvno from the key in the keytab. This should now do the right thing for sites that use a KDC that serves both Kerberos v4 and Kerberos v5 from the same database. --- NEWS | 8 ++++++++ TODO | 10 ---------- client/keytab.c | 38 +----------------------------------- client/srvtab.c | 8 ++------ client/wallet.pod | 44 ++++++++++++----------------------------- tests/client/basic-t.in | 38 ++++++++---------------------------- tests/data/cmd-fake | 51 +----------------------------------------------- tests/data/fake-srvtab | Bin 47 -> 50 bytes 8 files changed, 33 insertions(+), 164 deletions(-) (limited to 'client/keytab.c') diff --git a/NEWS b/NEWS index 60c0945..f8bc57b 100644 --- a/NEWS +++ b/NEWS @@ -18,6 +18,14 @@ wallet 0.10 (unreleased) Remove the kasetkey client for setting keys in an AFS kaserver. + The wallet client no longer enables kaserver synchronization when a + srvtab is requested with -S. Instead, it just extracts the DES key + from the keytab and writes it to a srvtab. It no longer forces the + kvno of the srvtab to 0 (a Stanford-specific action) and instead + preserves the kvno from the key in the keytab. This should now do the + right thing for sites that use a KDC that serves both Kerberos v4 and + Kerberos v5 from the same database. + Correctly handle storing of data that begins with a dash and don't parse it as an argument to wallet-backend. diff --git a/TODO b/TODO index 7448019..1b1bd78 100644 --- a/TODO +++ b/TODO @@ -67,16 +67,6 @@ Release 1.0: an ACL without having to write it into the database. Redo default ACL creation using that functionality. -* The wallet client currently sets sync kaserver whenever writing a keytab - to a srvtab. This is correct for sites using kaserver and wrong for - everyone else. Remove or rethink this once Stanford's kaserver - migration is over. - -* The wallet client currently hard-codes a kvno of 0 in srvtabs, which is - correct for how kasetkey works but probably isn't correct for people - using Heimdal or MIT to serve both K4 and K5 from the same KDC. Rethink - once Stanford's kaserver migration is over. - * Add a hook to enforce ACL naming standards. Future work: diff --git a/client/keytab.c b/client/keytab.c index bdd0134..393ce3c 100644 --- a/client/keytab.c +++ b/client/keytab.c @@ -2,7 +2,7 @@ * Implementation of keytab handling for the wallet client. * * Written by Russ Allbery - * Copyright 2007, 2008 Board of Trustees, Leland Stanford Jr. University + * Copyright 2007, 2008, 2010 Board of Trustees, Leland Stanford Jr. University * * See LICENSE for licensing terms. */ @@ -63,39 +63,6 @@ merge_keytab(krb5_context ctx, const char *newfile, const char *file) } -/* - * Configure a given keytab to be synchronized with an AFS kaserver if it - * isn't already. Returns true on success, false on failure. - */ -static int -set_sync(struct remctl *r, const char *type, const char *name) -{ - const char *command[7]; - char *data = NULL; - size_t length = 0; - int status; - - command[0] = type; - command[1] = "getattr"; - command[2] = "keytab"; - command[3] = name; - command[4] = "sync"; - command[5] = NULL; - status = run_command(r, command, &data, &length); - if (status != 0) - return 0; - if (data == NULL || strstr(data, "kaserver\n") == NULL) { - command[1] = "setattr"; - command[5] = "kaserver"; - command[6] = NULL; - status = run_command(r, command, NULL, NULL); - if (status != 0) - return 0; - } - return 1; -} - - /* * Given a remctl object, the Kerberos context, the name of a keytab object, * and a file name, call the correct wallet commands to download a keytab and @@ -111,9 +78,6 @@ get_keytab(struct remctl *r, krb5_context ctx, const char *type, size_t length = 0; int status; - if (srvtab != NULL) - if (!set_sync(r, type, name)) - return 255; command[0] = type; command[1] = "get"; command[2] = "keytab"; diff --git a/client/srvtab.c b/client/srvtab.c index a01026e..5b52955 100644 --- a/client/srvtab.c +++ b/client/srvtab.c @@ -2,7 +2,7 @@ * Implementation of srvtab handling for the wallet client. * * Written by Russ Allbery - * Copyright 2007, 2008 Board of Trustees, Leland Stanford Jr. University + * Copyright 2007, 2008, 2010 Board of Trustees, Leland Stanford Jr. University * * See LICENSE for licensing terms. */ @@ -28,10 +28,6 @@ * keytab and write it to the newly created srvtab file as a srvtab. Convert * the principal from Kerberos v5 form to Kerberos v4 form. * - * We always force the kvno to 0 for the srvtab. This works with how the - * wallet synchronizes keys with kasetkey, even though it's not particularly - * correct. - * * On any failure, print an error message to standard error and then exit. */ void @@ -84,7 +80,7 @@ write_srvtab(krb5_context ctx, const char *srvtab, const char *principal, strcpy(data + length, realm); length += strlen(realm); data[length++] = '\0'; - data[length++] = '\0'; + data[length++] = (unsigned char) entry.vno; #ifdef HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK memcpy(data + length, entry.keyblock.keyvalue.data, 8); #else diff --git a/client/wallet.pod b/client/wallet.pod index 657929b..6451e72 100644 --- a/client/wallet.pod +++ b/client/wallet.pod @@ -114,9 +114,19 @@ C object, and must be used in conjunction with the B<-f> flag. After the keytab is saved to the file specified by B<-f>, the DES key for that principal will be extracted and written as a Kerberos v4 srvtab to the file I. Any existing contents of I will be -destroyed. For more information on how the principal is converted to -Kerberos v4, see the description of the B attribute under -L. +destroyed. + +The Kerberos v4 principal name will be generated from the Kerberos v5 +principal name using the krb5_524_conv_principal() function of the +Kerberos libraries. See its documentation for more information, but +briefly (and in the absence of special configuration), the Kerberos v4 +principal name will be the same as the Kerberos v5 principal name except +that the components are separated by C<.> instead of C; the second +component is truncated after the first C<.> if the first component is one +of the recognized host-based principals (generally C, C, +C, or C); and the first component is C if the Kerberos v5 +principal component is C. The principal name must not contain more +than two components. =item B<-s> I @@ -377,34 +387,6 @@ Keytabs retrieved with C set will contain all keys present in the KDC for that Kerberos principal and therefore may contain different enctypes than those requested by this attribute. -=item sync - -Sets the external systems to which the key of a given principal is -synchronized. The only supported value for this attribute is C, -which says to synchronize the key with an AFS Kerberos v4 kaserver. - -If this attribute is set on a keytab, whenever the C command is run -for that keytab, the DES key will be extracted from that keytab and set in -the configured AFS kaserver. If the B<-S> option is given to the -B client, the srvtab corresponding to the keytab will be written -to the file specified with that option. The Kerberos v4 principal name -will be the same as the Kerberos v5 principal name except that the -components are separated by C<.> instead of C; the second component is -truncated after the first C<.> if the first component is one of C, -C, C, C, or C; and the first component is C -if the Kerberos v5 principal component is C. The principal name -must not contain more than two components. - -If this attribute is set, calling C will also destroy the -principal from the AFS kaserver, with a principal mapping determined as -above. - -The realm of the srvtab defaults to the same realm as the keytab. You can -change this by setting the v4_realm configuration option in the [realms] -section of krb5.conf for the local realm. The keytab must be for a -principal in the default local realm for the B<-S> option to work -correctly. - =back =head1 CONFIGURATION diff --git a/tests/client/basic-t.in b/tests/client/basic-t.in index 05a7abe..752e5d9 100644 --- a/tests/client/basic-t.in +++ b/tests/client/basic-t.in @@ -3,7 +3,8 @@ # Test suite for the wallet command-line client. # # Written by Russ Allbery -# Copyright 2006, 2007, 2008 Board of Trustees, Leland Stanford Jr. University +# Copyright 2006, 2007, 2008, 2010 +# Board of Trustees, Leland Stanford Jr. University # # See LICENSE for licensing terms. @@ -46,10 +47,10 @@ if [ ! -f data/pid ] ; then exit 1 fi -# We need a modified krb5.conf file for the srvtab test to work, since we need -# to add a v4_realm setting for the test-k5.stanford.edu realm that the keytab -# is for. Despite all the Stanford hard-coding, this test isn't -# Stanford-specific. It just matches the data files shipped with the package. +# We need a modified krb5.conf file to test wallet configuration settings in +# krb5.conf. Despite the hard-coding of test-k5.stanford.edu, this test isn't +# Stanford-specific; it just matches the files that are distributed with the +# package. krb5conf= for p in /etc/krb5.conf /usr/local/etc/krb5.conf data/krb5.conf ; do if [ -r "$p" ] ; then @@ -63,7 +64,7 @@ for p in /etc/krb5.conf /usr/local/etc/krb5.conf data/krb5.conf ; do [realms] test-k5.stanford.edu = { - v4_realm = TEST.STANFORD.EDU + v4_realm = test-k5.stanford.edu } EOF KRB5_CONFIG="./krb5.conf" @@ -77,8 +78,7 @@ if [ -z "$krb5conf" ] ; then fi # Make sure everything's clean. -rm -f output output.bak keytab keytab.bak srvtab srvtab.bak sync-kaserver \ - autocreated +rm -f output output.bak keytab keytab.bak srvtab srvtab.bak autocreated # Now, we can finally run our tests. First, basic operations. runsuccess "" "$wallet" -k "$principal" -p 14373 -s localhost -c fake-wallet \ @@ -139,11 +139,6 @@ if cmp keytab data/fake-keytab >/dev/null 2>&1 ; then else printcount "not ok" fi -if [ ! -f sync-kaserver ] ; then - printcount "ok" -else - printcount "not ok" -fi # Test srvtab support. runsuccess "" "$wallet" -f keytab -S srvtab get keytab service/fake-srvtab @@ -153,23 +148,12 @@ else printcount "not ok" fi rm keytab -if [ -f sync-kaserver ] ; then - printcount "ok" -else - printcount "not ok" -fi runsuccess "" "$wallet" -f keytab -S srvtab get keytab service/fake-srvtab if cmp keytab data/fake-keytab >/dev/null 2>&1 ; then printcount "ok" else printcount "not ok" fi -if [ -f sync-kaserver ] ; then - printcount "ok" - rm sync-kaserver -else - printcount "not ok" -fi if cmp srvtab data/fake-srvtab >/dev/null 2>&1 ; then printcount "ok" else @@ -196,12 +180,6 @@ fi # Test srvtab download into a merged keytab with an older version. cp data/fake-keytab-old keytab runsuccess "" "$wallet" -f keytab -S srvtab get keytab service/fake-srvtab -if [ -f sync-kaserver ] ; then - printcount "ok" - rm sync-kaserver -else - printcount "not ok" -fi if cmp srvtab data/fake-srvtab >/dev/null 2>&1 ; then printcount "ok" else diff --git a/tests/data/cmd-fake b/tests/data/cmd-fake index 9c9e38c..199bd57 100755 --- a/tests/data/cmd-fake +++ b/tests/data/cmd-fake @@ -4,7 +4,7 @@ # the client test suite. It doesn't test any of the wallet server code. # # Written by Russ Allbery -# Copyright 2007, 2008 Board of Trustees, Leland Stanford Jr. University +# Copyright 2007, 2008, 2010 Board of Trustees, Leland Stanford Jr. University # See LICENSE for licensing terms. command="$1" @@ -17,55 +17,6 @@ if [ "$type" != "keytab" ] && [ "$type" != "file" ] ; then fi case "$command" in -getattr) - if [ -n "$3" ] ; then - echo "Too many arguments" >&2 - exit 1 - fi - if [ "$type" != "keytab" ] || [ "$2" != sync ] ; then - echo "Unknown attribute $2" >&2 - exit 1 - fi - case "$1" in - service/fake-srvtab) - if [ -f sync-kaserver ] ; then - echo "kaserver" - fi - ;; - *) - echo "Looking at sync attribute of wrong keytab" >&2 - exit 1 - ;; - esac - ;; -setattr) - if [ -n "$4" ] ; then - echo "Too many arguments" >&2 - exit 1 - fi - if [ "$type" != "keytab" ] || [ "$2" != sync ] ; then - echo "Unknown attribute $2" >&2 - exit 1 - fi - case "$1" in - service/fake-srvtab) - if [ "$3" = "kaserver" ] ; then - touch sync-kaserver - else - if [ "$3" = "" ] ; then - rm sync-kaserver - else - echo "Invalid attribute value $3" >&2 - exit 1 - fi - fi - ;; - *) - echo "Looking at sync attribute of wrong keytab" >&2 - exit 1 - ;; - esac - ;; check) if [ -n "$2" ] ; then echo "Too many arguments" >&2 diff --git a/tests/data/fake-srvtab b/tests/data/fake-srvtab index 3c0ec65..f454af2 100644 Binary files a/tests/data/fake-srvtab and b/tests/data/fake-srvtab differ -- cgit v1.2.3 From d05f66dbff10b525d37f60ee01d5b9f94bf5192e Mon Sep 17 00:00:00 2001 From: Russ Allbery Date: Tue, 9 Feb 2010 16:00:04 -0800 Subject: Update util code and import Kerberos portability glue Use the Kerberos portability layer from rra-c-util 3.0 and avoid Kerberos API calls deprecated on Heimdal. Break util/util.h into separate header files and update all source files accordingly. The test suite is not yet updated. That will come in subsequent commits. --- Makefile.am | 11 ++-- NEWS | 3 + client/file.c | 6 +- client/internal.h | 4 +- client/keytab.c | 9 ++- client/krb5.c | 15 +++-- client/remctl.c | 5 +- client/srvtab.c | 10 +-- client/wallet.c | 8 ++- configure.ac | 4 +- portable/krb5-extra.c | 108 +++++++++++++++++++++++++++++++ portable/krb5.h | 74 ++++++++++++++++++++++ util/concat.c | 3 +- util/concat.h | 36 +++++++++++ util/macros.h | 17 +++++ util/messages-krb5.c | 74 +++------------------- util/messages-krb5.h | 39 ++++++++++++ util/messages.c | 29 +++------ util/messages.h | 96 ++++++++++++++++++++++++++++ util/util.h | 171 -------------------------------------------------- util/xmalloc.c | 24 ++----- util/xmalloc.h | 100 +++++++++++++++++++++++++++++ 22 files changed, 540 insertions(+), 306 deletions(-) create mode 100644 portable/krb5-extra.c create mode 100644 portable/krb5.h create mode 100644 util/concat.h create mode 100644 util/macros.h create mode 100644 util/messages-krb5.h create mode 100644 util/messages.h delete mode 100644 util/util.h create mode 100644 util/xmalloc.h (limited to 'client/keytab.c') diff --git a/Makefile.am b/Makefile.am index 57fb6eb..27a6e39 100644 --- a/Makefile.am +++ b/Makefile.am @@ -39,11 +39,14 @@ EXTRA_DIST = LICENSE autogen client/wallet.pod config/allow-extract \ docs/setup examples/stanford.conf $(PERL_FILES) $(TEST_FILES) noinst_LIBRARIES = portable/libportable.a util/libutil.a -portable_libportable_a_SOURCES = portable/dummy.c portable/macros.h \ - portable/stdbool.h portable/system.h +portable_libportable_a_SOURCES = portable/dummy.c portable/krb5-extra.c \ + portable/krb5.h portable/macros.h portable/stdbool.h \ + portable/system.h +portable_libportable_a_CPPFLAGS = $(KRB5_CPPFLAGS) portable_libportable_a_LIBADD = $(LIBOBJS) -util_libutil_a_SOURCES = util/concat.c util/messages.c util/messages-krb5.c \ - util/util.h util/xmalloc.c +util_libutil_a_SOURCES = util/concat.c util/concat.h util/macros.h \ + util/messages-krb5.c util/messages-krb5.h util/messages.c \ + util/messages.h util/xmalloc.c util/xmalloc.h util_libutil_a_CPPFLAGS = $(KRB5_CPPFLAGS) bin_PROGRAMS = client/wallet diff --git a/NEWS b/NEWS index e7931dd..1d3a5e3 100644 --- a/NEWS +++ b/NEWS @@ -52,6 +52,8 @@ wallet 0.10 (unreleased) Update to rra-c-util 3.0: + * Use Kerberos portability layer to support Heimdal. + * Avoid Kerberos API calls deprecated on Heimdal. * Sanity-check the results of krb5-config before proceeding. * Fall back on manual probing if krb5-config results don't work. * Add --with-krb5-include and --with-krb5-lib configure options. @@ -64,6 +66,7 @@ wallet 0.10 (unreleased) * Change AC_TRY_* to AC_*_IFELSE as recommended by Autoconf. * Use AC_TYPE_LONG_LONG_INT instead of AC_CHECK_TYPES([long long]). * Provide a proper bool type with Sun Studio 12 on Solaris 10. + * Break util/util.h into separate header files per module. wallet 0.9 (2008-04-24) diff --git a/client/file.c b/client/file.c index 670a30d..c9edf3a 100644 --- a/client/file.c +++ b/client/file.c @@ -2,7 +2,7 @@ * File handling for the wallet client. * * Written by Russ Allbery - * Copyright 2007, 2008 Board of Trustees, Leland Stanford Jr. University + * Copyright 2007, 2008, 2010 Board of Trustees, Leland Stanford Jr. University * * See LICENSE for licensing terms. */ @@ -15,7 +15,9 @@ #include #include -#include +#include +#include +#include /* * Given a filename, some data, and a length, write that data to the given diff --git a/client/internal.h b/client/internal.h index e48616a..7fe962b 100644 --- a/client/internal.h +++ b/client/internal.h @@ -2,7 +2,7 @@ * Internal support functions for the wallet client. * * Written by Russ Allbery - * Copyright 2007, 2008 Board of Trustees, Leland Stanford Jr. University + * Copyright 2007, 2008, 2010 Board of Trustees, Leland Stanford Jr. University * * See LICENSE for licensing terms. */ @@ -11,8 +11,8 @@ #define CLIENT_INTERNAL_H 1 #include +#include -#include #include /* Forward declarations to avoid unnecessary includes. */ diff --git a/client/keytab.c b/client/keytab.c index 393ce3c..5f2076f 100644 --- a/client/keytab.c +++ b/client/keytab.c @@ -8,12 +8,15 @@ */ #include +#include #include #include #include -#include +#include +#include +#include /* @@ -47,11 +50,7 @@ merge_keytab(krb5_context ctx, const char *newfile, const char *file) status = krb5_kt_add_entry(ctx, old, &entry); if (status != 0) die_krb5(ctx, status, "cannot write to keytab %s", file); -#ifdef HAVE_KRB5_KT_FREE_ENTRY krb5_kt_free_entry(ctx, &entry); -#else - krb5_free_keytab_entry_contents(ctx, &entry); -#endif } if (status != KRB5_KT_END) die_krb5(ctx, status, "error reading temporary keytab %s", newfile); diff --git a/client/krb5.c b/client/krb5.c index 3698dd3..38172ae 100644 --- a/client/krb5.c +++ b/client/krb5.c @@ -15,7 +15,8 @@ #include #include -#include +#include +#include /* @@ -29,7 +30,7 @@ kinit(krb5_context ctx, const char *principal) krb5_principal princ; krb5_ccache ccache; krb5_creds creds; - krb5_get_init_creds_opt opts; + krb5_get_init_creds_opt *opts; krb5_error_code status; char cache_name[] = "/tmp/krb5cc_wallet_XXXXXX"; int fd; @@ -38,17 +39,21 @@ kinit(krb5_context ctx, const char *principal) status = krb5_parse_name(ctx, principal, &princ); if (status != 0) die_krb5(ctx, status, "invalid Kerberos principal %s", principal); - krb5_get_init_creds_opt_init(&opts); + status = krb5_get_init_creds_opt_alloc(ctx, &opts); + if (status != 0) + die_krb5(ctx, status, "cannot allocate credential options"); + krb5_get_init_creds_opt_set_default_flags(ctx, "wallet", princ->realm, + opts); memset(&creds, 0, sizeof(creds)); status = krb5_get_init_creds_password(ctx, &creds, princ, NULL, - krb5_prompter_posix, NULL, 0, NULL, &opts); + krb5_prompter_posix, NULL, 0, NULL, opts); if (status != 0) die_krb5(ctx, status, "authentication failed"); /* Put the new credentials into a ticket cache. */ fd = mkstemp(cache_name); if (fd < 0) - sysdie("cannot create temporary ticket cache", cache_name); + sysdie("cannot create temporary ticket cache %s", cache_name); status = krb5_cc_resolve(ctx, cache_name, &ccache); if (status != 0) die_krb5(ctx, status, "cannot create cache %s", cache_name); diff --git a/client/remctl.c b/client/remctl.c index 8dfeb0a..a4ff097 100644 --- a/client/remctl.c +++ b/client/remctl.c @@ -2,7 +2,7 @@ * remctl interface for the wallet client. * * Written by Russ Allbery - * Copyright 2007 Board of Trustees, Leland Stanford Jr. University + * Copyright 2007, 2010 Board of Trustees, Leland Stanford Jr. University * * See LICENSE for licensing terms. */ @@ -13,7 +13,8 @@ #include #include -#include +#include +#include /* diff --git a/client/srvtab.c b/client/srvtab.c index 5b52955..b26e6fc 100644 --- a/client/srvtab.c +++ b/client/srvtab.c @@ -8,12 +8,12 @@ */ #include +#include #include -#include - #include -#include +#include +#include #ifndef KRB5_KRB4_COMPAT # define ANAME_SZ 40 @@ -87,11 +87,7 @@ write_srvtab(krb5_context ctx, const char *srvtab, const char *principal, memcpy(data + length, entry.key.contents, 8); #endif length += 8; -#ifdef HAVE_KRB5_KT_FREE_ENTRY krb5_kt_free_entry(ctx, &entry); -#else - krb5_free_keytab_entry_contents(ctx, &entry); -#endif /* Write out the srvtab file. */ write_file(srvtab, data, length); diff --git a/client/wallet.c b/client/wallet.c index 4225d45..ce0f4e7 100644 --- a/client/wallet.c +++ b/client/wallet.c @@ -2,21 +2,23 @@ * The client program for the wallet system. * * Written by Russ Allbery - * Copyright 2006, 2007, 2008 + * Copyright 2006, 2007, 2008, 2010 * Board of Trustees, Leland Stanford Jr. University * * See LICENSE for licensing terms. */ #include +#include #include #include -#include #include #include -#include +#include +#include +#include /* * Basic wallet behavior options set either on the command line or via diff --git a/configure.ac b/configure.ac index 1b91ff0..f66a682 100644 --- a/configure.ac +++ b/configure.ac @@ -25,7 +25,9 @@ AC_PROG_RANLIB RRA_LIB_REMCTL RRA_LIB_KRB5 RRA_LIB_KRB5_SWITCH -AC_CHECK_FUNCS([krb5_kt_free_entry]) +AC_CHECK_FUNCS([krb5_get_init_creds_opt_alloc \ + krb5_get_init_creds_opt_set_default_flags \ + krb5_kt_free_entry]) AC_CHECK_MEMBERS([krb5_keytab_entry.keyblock], , , [#include ]) RRA_LIB_KRB5_RESTORE diff --git a/portable/krb5-extra.c b/portable/krb5-extra.c new file mode 100644 index 0000000..09a717b --- /dev/null +++ b/portable/krb5-extra.c @@ -0,0 +1,108 @@ +/* + * Portability glue functions for Kerberos. + * + * This file provides definitions of the interfaces that portable/krb5.h + * ensures exist if the function wasn't available in the Kerberos libraries. + * Everything in this file will be protected by #ifndef. If the native + * Kerberos libraries are fully capable, this file will be skipped. + * + * Written by Russ Allbery + * This work is hereby placed in the public domain by its author. + */ + +#include +#include +#include + +#include + +/* Figure out what header files to include for error reporting. */ +#if !defined(HAVE_KRB5_GET_ERROR_MESSAGE) && !defined(HAVE_KRB5_GET_ERR_TEXT) +# if !defined(HAVE_KRB5_GET_ERROR_STRING) +# if defined(HAVE_IBM_SVC_KRB5_SVC_H) +# include +# elif defined(HAVE_ET_COM_ERR_H) +# include +# else +# include +# endif +# endif +#endif + +/* Used for unused parameters to silence gcc warnings. */ +#define UNUSED __attribute__((__unused__)) + +/* + * This string is returned for unknown error messages. We use a static + * variable so that we can be sure not to free it. + */ +static const char error_unknown[] = "unknown error"; + + +#ifndef HAVE_KRB5_GET_ERROR_MESSAGE +/* + * Given a Kerberos error code, return the corresponding error. Prefer the + * Kerberos interface if available since it will provide context-specific + * error information, whereas the error_message() call will only provide a + * fixed message. + */ +const char * +krb5_get_error_message(krb5_context ctx UNUSED, krb5_error_code code UNUSED) +{ + const char *msg = NULL; + +# if defined(HAVE_KRB5_GET_ERROR_STRING) + msg = krb5_get_error_string(ctx); +# elif defined(HAVE_KRB5_GET_ERR_TEXT) + msg = krb5_get_err_text(ctx, code); +# elif defined(HAVE_KRB5_SVC_GET_MSG) + krb5_svc_get_msg(code, (char **) &msg); +# else + msg = error_message(code); +# endif + if (msg == NULL) + return error_unknown; + else + return msg; +} +#endif /* !HAVE_KRB5_GET_ERROR_MESSAGE */ + + +#ifndef HAVE_KRB5_FREE_ERROR_MESSAGE +/* + * Free an error string if necessary. If we returned a static string, make + * sure we don't free it. + * + * This code assumes that the set of implementations that have + * krb5_free_error_message is a subset of those with krb5_get_error_message. + * If this assumption ever breaks, we may call the wrong free function. + */ +static void +krb5_free_error_message(krb5_context ctx UNUSED, const char *msg) +{ + if (msg == error_unknown) + return; +# if defined(HAVE_KRB5_GET_ERROR_STRING) + krb5_free_error_string(ctx, (char *) msg); +# elif defined(HAVE_KRB5_SVC_GET_MSG) + krb5_free_string(ctx, (char *) msg); +# endif +} +#endif /* !HAVE_KRB5_FREE_ERROR_MESSAGE */ + + +#ifndef HAVE_KRB5_GET_INIT_CREDS_OPT_ALLOC +/* + * Allocate and initialize a krb5_get_init_creds_opt struct. This code + * assumes that an all-zero bit pattern will create a NULL pointer. + */ +krb5_error_code +krb5_get_init_creds_opt_alloc(krb5_context ctx, krb5_get_init_creds_opt **opts) +{ + *opts = calloc(1, sizeof(krb5_get_init_creds_opt)); + if (*opts == NULL) + return errno; + krb5_get_init_creds_opt_init(*opts); + return 0; +} +#endif /* !HAVE_KRB5_GET_INIT_CREDS_OPT_ALLOC */ diff --git a/portable/krb5.h b/portable/krb5.h new file mode 100644 index 0000000..117f5ce --- /dev/null +++ b/portable/krb5.h @@ -0,0 +1,74 @@ +/* + * Portability wrapper around krb5.h. + * + * This header includes krb5.h and then adjusts for various portability + * issues, primarily between MIT Kerberos and Heimdal, so that code can be + * written to a consistent API. + * + * Unfortunately, due to the nature of the differences between MIT Kerberos + * and Heimdal, it's not possible to write code to either one of the APIs and + * adjust for the other one. In general, this header tries to make available + * the Heimdal API and fix it for MIT Kerberos, but there are places where MIT + * Kerberos requires a more specific call. For those cases, it provides the + * most specific interface. + * + * For example, MIT Kerberos has krb5_free_unparsed_name() whereas Heimdal + * prefers the generic krb5_xfree(). In this case, this header provides + * krb5_free_unparsed_name() for both APIs since it's the most specific call. + * + * Written by Russ Allbery + * This work is hereby placed in the public domain by its author. + */ + +#ifndef PORTABLE_KRB5_H +#define PORTABLE_KRB5_H 1 + +#include +#include + +#include + +BEGIN_DECLS + +/* Default to a hidden visibility for all portability functions. */ +#pragma GCC visibility push(hidden) + +/* + * krb5_{get,free}_error_message are the preferred APIs for both current MIT + * and current Heimdal, but there are tons of older APIs we may have to fall + * back on for earlier versions. + * + * This function should be called immediately after the corresponding error + * without any intervening Kerberos calls. Otherwise, the correct error + * message and supporting information may not be returned. + */ +#ifndef HAVE_KRB5_GET_ERROR_MESSAGE +const char *krb5_get_error_message(krb5_context, krb5_error_code); +#endif +#ifndef HAVE_KRB5_FREE_ERROR_MESSAGE +void krb5_free_error_message(krb5_context, const char *); +#endif + +/* + * Both current MIT and current Heimdal prefer _opt_alloc, but older versions + * of both require allocating your own struct and calling _opt_init. + */ +#ifndef HAVE_KRB5_GET_INIT_CREDS_OPT_ALLOC +krb5_error_code krb5_get_init_creds_opt_alloc(krb5_context, + krb5_get_init_creds_opt **); +#endif + +/* Heimdal-specific. */ +#ifndef HAVE_KRB5_GET_INIT_CREDS_OPT_SET_DEFAULT_FLAGS +#define krb5_get_init_creds_opt_set_default_flags(c, p, r, o) /* empty */ +#endif + +/* Heimdal: krb5_kt_free_entry, MIT: krb5_free_keytab_entry_contents. */ +#ifndef HAVE_KRB5_KT_FREE_ENTRY +# define krb5_kt_free_entry(c, e) krb5_free_keytab_entry_contents((c), (e)) +#endif + +/* Undo default visibility change. */ +#pragma GCC visibility pop + +#endif /* !PORTABLE_KRB5_H */ diff --git a/util/concat.c b/util/concat.c index bef67db..bdbd836 100644 --- a/util/concat.c +++ b/util/concat.c @@ -25,7 +25,8 @@ #include #include -#include +#include +#include /* Abbreviation for cleaner code. */ #define VA_NEXT(var, type) ((var) = (type) va_arg(args, type)) diff --git a/util/concat.h b/util/concat.h new file mode 100644 index 0000000..ef8b38d --- /dev/null +++ b/util/concat.h @@ -0,0 +1,36 @@ +/* + * Prototypes for string concatenation with dynamic memory allocation. + * + * Written by Russ Allbery + * This work is hereby placed in the public domain by its author. + */ + +#ifndef UTIL_CONCAT_H +#define UTIL_CONCAT_H 1 + +#include +#include + +BEGIN_DECLS + +/* Default to a hidden visibility for all util functions. */ +#pragma GCC visibility push(hidden) + +/* Concatenate NULL-terminated strings into a newly allocated string. */ +char *concat(const char *first, ...) + __attribute__((__malloc__, __nonnull__(1))); + +/* + * Given a base path and a file name, create a newly allocated path string. + * The name will be appended to base with a / between them. Exceptionally, if + * name begins with a slash, it will be strdup'd and returned as-is. + */ +char *concatpath(const char *base, const char *name) + __attribute__((__malloc__, __nonnull__(2))); + +/* Undo default visibility change. */ +#pragma GCC visibility pop + +END_DECLS + +#endif /* UTIL_CONCAT_H */ diff --git a/util/macros.h b/util/macros.h new file mode 100644 index 0000000..97b2c2b --- /dev/null +++ b/util/macros.h @@ -0,0 +1,17 @@ +/* + * Some standard helpful macros. + * + * Written by Russ Allbery + * This work is hereby placed in the public domain by its author. + */ + +#ifndef UTIL_MACROS_H +#define UTIL_MACROS_H 1 + +#include +#include + +/* Used for unused parameters to silence gcc warnings. */ +#define UNUSED __attribute__((__unused__)) + +#endif /* UTIL_MACROS_H */ diff --git a/util/messages-krb5.c b/util/messages-krb5.c index 00f4a2e..7f35d29 100644 --- a/util/messages-krb5.c +++ b/util/messages-krb5.c @@ -6,76 +6,20 @@ * formatted message. * * Written by Russ Allbery - * Copyright 2006, 2007, 2008 + * Copyright 2006, 2007, 2008, 2009, 2010 * Board of Trustees, Leland Stanford Jr. University * * See LICENSE for licensing terms. */ #include +#include #include -#include -#if !defined(HAVE_KRB5_GET_ERROR_MESSAGE) && !defined(HAVE_KRB5_GET_ERR_TEXT) -# if defined(HAVE_IBM_SVC_KRB5_SVC_H) -# include -# elif defined(HAVE_ET_COM_ERR_H) -# include -# else -# include -# endif -#endif - -#include - -/* - * This string is returned for unknown error messages. We use a static - * variable so that we can be sure not to free it. - */ -static const char error_unknown[] = "unknown error"; - - -/* - * Given a Kerberos error code, return the corresponding error. Prefer the - * Kerberos interface if available since it will provide context-specific - * error information, whereas the error_message() call will only provide a - * fixed message. - */ -static const char * -get_error(krb5_context ctx UNUSED, krb5_error_code code) -{ - const char *msg = NULL; - -#if defined(HAVE_KRB5_GET_ERROR_MESSAGE) - msg = krb5_get_error_message(ctx, code); -#elif defined(HAVE_KRB5_GET_ERR_TEXT) - msg = krb5_get_err_text(ctx, code); -#elif defined(HAVE_KRB5_SVC_GET_MSG) - krb5_svc_get_msg(code, &msg); -#else - msg = error_message(code); -#endif - if (msg == NULL) - return error_unknown; - else - return msg; -} - - -/* - * Free an error string if necessary. - */ -static void -free_error(krb5_context ctx UNUSED, const char *msg) -{ - if (msg == error_unknown) - return; -#if defined(HAVE_KRB5_FREE_ERROR_MESSAGE) - krb5_free_error_message(ctx, msg); -#elif defined(HAVE_KRB5_SVC_GET_MSG) - krb5_free_string((char *) msg); -#endif -} +#include +#include +#include +#include /* @@ -88,7 +32,7 @@ die_krb5(krb5_context ctx, krb5_error_code code, const char *format, ...) char *message; va_list args; - k5_msg = get_error(ctx, code); + k5_msg = krb5_get_error_message(ctx, code); va_start(args, format); if (xvasprintf(&message, format, args) < 0) die("internal error: unable to format error message"); @@ -107,12 +51,12 @@ warn_krb5(krb5_context ctx, krb5_error_code code, const char *format, ...) char *message; va_list args; - k5_msg = get_error(ctx, code); + k5_msg = krb5_get_error_message(ctx, code); va_start(args, format); if (xvasprintf(&message, format, args) < 0) die("internal error: unable to format error message"); va_end(args); warn("%s: %s", message, k5_msg); free(message); - free_error(ctx, k5_msg); + krb5_free_error_message(ctx, k5_msg); } diff --git a/util/messages-krb5.h b/util/messages-krb5.h new file mode 100644 index 0000000..3b763c8 --- /dev/null +++ b/util/messages-krb5.h @@ -0,0 +1,39 @@ +/* + * Prototypes for error handling for Kerberos. + * + * Written by Russ Allbery + * Copyright 2006, 2007, 2008, 2009, 2010 + * Board of Trustees, Leland Stanford Jr. University + * + * See LICENSE for licensing terms. + */ + +#ifndef UTIL_MESSAGES_KRB5_H +#define UTIL_MESSAGES_KRB5_H 1 + +#include +#include + +#include +#include + +BEGIN_DECLS + +/* Default to a hidden visibility for all util functions. */ +#pragma GCC visibility push(hidden) + +/* + * The Kerberos versions of the reporting functions. These take a context and + * an error code to get the Kerberos error. + */ +void die_krb5(krb5_context, krb5_error_code, const char *, ...) + __attribute__((__nonnull__, __noreturn__, __format__(printf, 3, 4))); +void warn_krb5(krb5_context, krb5_error_code, const char *, ...) + __attribute__((__nonnull__, __format__(printf, 3, 4))); + +/* Undo default visibility change. */ +#pragma GCC visibility pop + +END_DECLS + +#endif /* UTIL_MESSAGES_KRB5_H */ diff --git a/util/messages.c b/util/messages.c index 0a106f6..ef920b2 100644 --- a/util/messages.c +++ b/util/messages.c @@ -51,26 +51,13 @@ * va_list, and the applicable errno value (if any). * * Copyright 2008 Board of Trustees, Leland Stanford Jr. University - * Copyright 2004, 2005, 2006 + * Copyright (c) 2004, 2005, 2006 * by Internet Systems Consortium, Inc. ("ISC") - * Copyright 1991, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, - * 2003 by The Internet Software Consortium and Rich Salz + * Copyright (c) 1991, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, + * 2002, 2003 by The Internet Software Consortium and Rich Salz * - * This code is derived from software contributed to the Internet Software - * Consortium by Rich Salz. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. -*/ + * See LICENSE for licensing terms. + */ #include #include @@ -90,7 +77,9 @@ # define LOG_CRIT EVENTLOG_ERROR_TYPE #endif -#include +#include +#include +#include /* The default handler lists. */ static message_handler_func stdout_handlers[2] = { @@ -211,7 +200,7 @@ message_log_syslog(int pri, int len, const char *fmt, va_list args, int err) eventlog = RegisterEventSource(NULL, message_program_name); if (eventlog != NULL) { - ReportEvent(eventlog, pri, 0, 0, NULL, 1, 0, &buffer, NULL); + ReportEvent(eventlog, (WORD) pri, 0, 0, NULL, 1, 0, &buffer, NULL); CloseEventLog(eventlog); } } diff --git a/util/messages.h b/util/messages.h new file mode 100644 index 0000000..ff86f39 --- /dev/null +++ b/util/messages.h @@ -0,0 +1,96 @@ +/* + * Prototypes for message and error reporting (possibly fatal). + * + * Copyright 2008, 2010 Board of Trustees, Leland Stanford Jr. University + * Copyright (c) 2004, 2005, 2006 + * by Internet Systems Consortium, Inc. ("ISC") + * Copyright (c) 1991, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, + * 2002, 2003 by The Internet Software Consortium and Rich Salz + * + * See LICENSE for licensing terms. + */ + +#ifndef UTIL_MESSAGES_H +#define UTIL_MESSAGES_H 1 + +#include +#include + +#include + +BEGIN_DECLS + +/* Default to a hidden visibility for all util functions. */ +#pragma GCC visibility push(hidden) + +/* + * The reporting functions. The ones prefaced by "sys" add a colon, a space, + * and the results of strerror(errno) to the output and are intended for + * reporting failures of system calls. + */ +void debug(const char *, ...) + __attribute__((__nonnull__, __format__(printf, 1, 2))); +void notice(const char *, ...) + __attribute__((__nonnull__, __format__(printf, 1, 2))); +void sysnotice(const char *, ...) + __attribute__((__nonnull__, __format__(printf, 1, 2))); +void warn(const char *, ...) + __attribute__((__nonnull__, __format__(printf, 1, 2))); +void syswarn(const char *, ...) + __attribute__((__nonnull__, __format__(printf, 1, 2))); +void die(const char *, ...) + __attribute__((__nonnull__, __noreturn__, __format__(printf, 1, 2))); +void sysdie(const char *, ...) + __attribute__((__nonnull__, __noreturn__, __format__(printf, 1, 2))); + +/* + * Set the handlers for various message functions. All of these functions + * take a count of the number of handlers and then function pointers for each + * of those handlers. These functions are not thread-safe; they set global + * variables. + */ +void message_handlers_debug(int count, ...); +void message_handlers_notice(int count, ...); +void message_handlers_warn(int count, ...); +void message_handlers_die(int count, ...); + +/* + * Some useful handlers, intended to be passed to message_handlers_*. All + * handlers take the length of the formatted message, the format, a variadic + * argument list, and the errno setting if any. + */ +void message_log_stdout(int, const char *, va_list, int) + __attribute((__nonnull__)); +void message_log_stderr(int, const char *, va_list, int) + __attribute((__nonnull__)); +void message_log_syslog_debug(int, const char *, va_list, int) + __attribute((__nonnull__)); +void message_log_syslog_info(int, const char *, va_list, int) + __attribute((__nonnull__)); +void message_log_syslog_notice(int, const char *, va_list, int) + __attribute((__nonnull__)); +void message_log_syslog_warning(int, const char *, va_list, int) + __attribute((__nonnull__)); +void message_log_syslog_err(int, const char *, va_list, int) + __attribute((__nonnull__)); +void message_log_syslog_crit(int, const char *, va_list, int) + __attribute((__nonnull__)); + +/* The type of a message handler. */ +typedef void (*message_handler_func)(int, const char *, va_list, int); + +/* If non-NULL, called before exit and its return value passed to exit. */ +extern int (*message_fatal_cleanup)(void); + +/* + * If non-NULL, prepended (followed by ": ") to all messages printed by either + * message_log_stdout or message_log_stderr. + */ +extern const char *message_program_name; + +/* Undo default visibility change. */ +#pragma GCC visibility pop + +END_DECLS + +#endif /* UTIL_MESSAGES_H */ diff --git a/util/util.h b/util/util.h deleted file mode 100644 index 6ac7fa7..0000000 --- a/util/util.h +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Utility functions. - * - * This is a variety of utility functions that are used internally by pieces - * of remctl. Many of them came originally from INN. - * - * Written by Russ Allbery - * Copyright 2005, 2006, 2007, 2008 - * Board of Trustees, Leland Stanford Jr. University - * Copyright 2004, 2005, 2006, 2007 - * by Internet Systems Consortium, Inc. ("ISC") - * Copyright 1991, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, - * 2003 by The Internet Software Consortium and Rich Salz - * - * See LICENSE for licensing terms. - */ - -#ifndef UTIL_UTIL_H -#define UTIL_UTIL_H 1 - -#include -#include - -#include -#include -#include - -/* Used for unused parameters to silence gcc warnings. */ -#define UNUSED __attribute__((__unused__)) - -BEGIN_DECLS - -/* Concatenate NULL-terminated strings into a newly allocated string. */ -extern char *concat(const char *first, ...); - -/* - * Given a base path and a file name, create a newly allocated path string. - * The name will be appended to base with a / between them. Exceptionally, if - * name begins with a slash, it will be strdup'd and returned as-is. - */ -extern char *concatpath(const char *base, const char *name); - -/* - * The reporting functions. The ones prefaced by "sys" add a colon, a space, - * and the results of strerror(errno) to the output and are intended for - * reporting failures of system calls. - */ -extern void debug(const char *, ...) - __attribute__((__format__(printf, 1, 2))); -extern void notice(const char *, ...) - __attribute__((__format__(printf, 1, 2))); -extern void sysnotice(const char *, ...) - __attribute__((__format__(printf, 1, 2))); -extern void warn(const char *, ...) - __attribute__((__format__(printf, 1, 2))); -extern void syswarn(const char *, ...) - __attribute__((__format__(printf, 1, 2))); -extern void die(const char *, ...) - __attribute__((__noreturn__, __format__(printf, 1, 2))); -extern void sysdie(const char *, ...) - __attribute__((__noreturn__, __format__(printf, 1, 2))); - -/* - * The Kerberos versions of the reporting functions. These take a context and - * an error code to get the Kerberos error. - */ -void die_krb5(krb5_context, krb5_error_code, const char *, ...) - __attribute__((__noreturn__, __format__(printf, 3, 4))); -void warn_krb5(krb5_context, krb5_error_code, const char *, ...) - __attribute__((__format__(printf, 3, 4))); - -/* - * Set the handlers for various message functions. All of these functions - * take a count of the number of handlers and then function pointers for each - * of those handlers. These functions are not thread-safe; they set global - * variables. - */ -extern void message_handlers_debug(int count, ...); -extern void message_handlers_notice(int count, ...); -extern void message_handlers_warn(int count, ...); -extern void message_handlers_die(int count, ...); - -/* - * Some useful handlers, intended to be passed to message_handlers_*. All - * handlers take the length of the formatted message, the format, a variadic - * argument list, and the errno setting if any. - */ -extern void message_log_stdout(int, const char *, va_list, int); -extern void message_log_stderr(int, const char *, va_list, int); -extern void message_log_syslog_debug(int, const char *, va_list, int); -extern void message_log_syslog_info(int, const char *, va_list, int); -extern void message_log_syslog_notice(int, const char *, va_list, int); -extern void message_log_syslog_warning(int, const char *, va_list, int); -extern void message_log_syslog_err(int, const char *, va_list, int); -extern void message_log_syslog_crit(int, const char *, va_list, int); - -/* The type of a message handler. */ -typedef void (*message_handler_func)(int, const char *, va_list, int); - -/* If non-NULL, called before exit and its return value passed to exit. */ -extern int (*message_fatal_cleanup)(void); - -/* - * If non-NULL, prepended (followed by ": ") to all messages printed by either - * message_log_stdout or message_log_stderr. - */ -extern const char *message_program_name; - -/* - * The functions are actually macros so that we can pick up the file and line - * number information for debugging error messages without the user having to - * pass those in every time. - */ -#define xcalloc(n, size) x_calloc((n), (size), __FILE__, __LINE__) -#define xmalloc(size) x_malloc((size), __FILE__, __LINE__) -#define xrealloc(p, size) x_realloc((p), (size), __FILE__, __LINE__) -#define xstrdup(p) x_strdup((p), __FILE__, __LINE__) -#define xstrndup(p, size) x_strndup((p), (size), __FILE__, __LINE__) -#define xvasprintf(p, f, a) x_vasprintf((p), (f), (a), __FILE__, __LINE__) - -/* - * asprintf is a special case since it takes variable arguments. If we have - * support for variadic macros, we can still pass in the file and line and - * just need to put them somewhere else in the argument list than last. - * Otherwise, just call x_asprintf directly. This means that the number of - * arguments x_asprintf takes must vary depending on whether variadic macros - * are supported. - */ -#ifdef HAVE_C99_VAMACROS -# define xasprintf(p, f, ...) \ - x_asprintf((p), __FILE__, __LINE__, (f), __VA_ARGS__) -#elif HAVE_GNU_VAMACROS -# define xasprintf(p, f, args...) \ - x_asprintf((p), __FILE__, __LINE__, (f), args) -#else -# define xasprintf x_asprintf -#endif - -/* - * Last two arguments are always file and line number. These are internal - * implementations that should not be called directly. - */ -extern void *x_calloc(size_t, size_t, const char *, int); -extern void *x_malloc(size_t, const char *, int); -extern void *x_realloc(void *, size_t, const char *, int); -extern char *x_strdup(const char *, const char *, int); -extern char *x_strndup(const char *, size_t, const char *, int); -extern int x_vasprintf(char **, const char *, va_list, const char *, int); - -/* asprintf special case. */ -#if HAVE_C99_VAMACROS || HAVE_GNU_VAMACROS -extern int x_asprintf(char **, const char *, int, const char *, ...); -#else -extern int x_asprintf(char **, const char *, ...); -#endif - -/* Failure handler takes the function, the size, the file, and the line. */ -typedef void (*xmalloc_handler_type)(const char *, size_t, const char *, int); - -/* The default error handler. */ -void xmalloc_fail(const char *, size_t, const char *, int); - -/* - * Assign to this variable to choose a handler other than the default, which - * just calls sysdie. - */ -extern xmalloc_handler_type xmalloc_error_handler; - -END_DECLS - -#endif /* UTIL_UTIL_H */ diff --git a/util/xmalloc.c b/util/xmalloc.c index 412890e..4e05f96 100644 --- a/util/xmalloc.c +++ b/util/xmalloc.c @@ -55,25 +55,12 @@ * header file defines macros named xmalloc, etc. that pass the file name and * line number to these functions. * - * Copyright 2004, 2005, 2006 + * Copyright (c) 2004, 2005, 2006 * by Internet Systems Consortium, Inc. ("ISC") - * Copyright 1991, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, - * 2003 by The Internet Software Consortium and Rich Salz + * Copyright (c) 1991, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, + * 2002, 2003 by The Internet Software Consortium and Rich Salz * - * This code is derived from software contributed to the Internet Software - * Consortium by Rich Salz. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. + * See LICENSE for licensing terms. */ #include @@ -81,7 +68,8 @@ #include -#include +#include +#include /* diff --git a/util/xmalloc.h b/util/xmalloc.h new file mode 100644 index 0000000..657a6bb --- /dev/null +++ b/util/xmalloc.h @@ -0,0 +1,100 @@ +/* + * Prototypes for malloc routines with failure handling. + * + * Copyright 2010 Board of Trustees, Leland Stanford Jr. University + * Copyright (c) 2004, 2005, 2006 + * by Internet Systems Consortium, Inc. ("ISC") + * Copyright (c) 1991, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, + * 2002, 2003 by The Internet Software Consortium and Rich Salz + * + * See LICENSE for licensing terms. + */ + +#ifndef UTIL_XMALLOC_H +#define UTIL_XMALLOC_H 1 + +#include +#include + +#include + +/* + * The functions are actually macros so that we can pick up the file and line + * number information for debugging error messages without the user having to + * pass those in every time. + */ +#define xcalloc(n, size) x_calloc((n), (size), __FILE__, __LINE__) +#define xmalloc(size) x_malloc((size), __FILE__, __LINE__) +#define xrealloc(p, size) x_realloc((p), (size), __FILE__, __LINE__) +#define xstrdup(p) x_strdup((p), __FILE__, __LINE__) +#define xstrndup(p, size) x_strndup((p), (size), __FILE__, __LINE__) +#define xvasprintf(p, f, a) x_vasprintf((p), (f), (a), __FILE__, __LINE__) + +/* + * asprintf is a special case since it takes variable arguments. If we have + * support for variadic macros, we can still pass in the file and line and + * just need to put them somewhere else in the argument list than last. + * Otherwise, just call x_asprintf directly. This means that the number of + * arguments x_asprintf takes must vary depending on whether variadic macros + * are supported. + */ +#ifdef HAVE_C99_VAMACROS +# define xasprintf(p, f, ...) \ + x_asprintf((p), __FILE__, __LINE__, (f), __VA_ARGS__) +#elif HAVE_GNU_VAMACROS +# define xasprintf(p, f, args...) \ + x_asprintf((p), __FILE__, __LINE__, (f), args) +#else +# define xasprintf x_asprintf +#endif + +BEGIN_DECLS + +/* Default to a hidden visibility for all util functions. */ +#pragma GCC visibility push(hidden) + +/* + * Last two arguments are always file and line number. These are internal + * implementations that should not be called directly. + */ +void *x_calloc(size_t, size_t, const char *, int) + __attribute__((__alloc_size__(1, 2), __malloc__, __nonnull__)); +void *x_malloc(size_t, const char *, int) + __attribute__((__alloc_size__(1), __malloc__, __nonnull__)); +void *x_realloc(void *, size_t, const char *, int) + __attribute__((__alloc_size__(2), __malloc__, __nonnull__(3))); +char *x_strdup(const char *, const char *, int) + __attribute__((__malloc__, __nonnull__)); +char *x_strndup(const char *, size_t, const char *, int) + __attribute__((__malloc__, __nonnull__)); +int x_vasprintf(char **, const char *, va_list, const char *, int) + __attribute__((__nonnull__)); + +/* asprintf special case. */ +#if HAVE_C99_VAMACROS || HAVE_GNU_VAMACROS +int x_asprintf(char **, const char *, int, const char *, ...) + __attribute__((__nonnull__, __format__(printf, 4, 5))); +#else +int x_asprintf(char **, const char *, ...) + __attribute__((__nonnull__, __format__(printf, 2, 3))); +#endif + +/* Failure handler takes the function, the size, the file, and the line. */ +typedef void (*xmalloc_handler_type)(const char *, size_t, const char *, int); + +/* The default error handler. */ +void xmalloc_fail(const char *, size_t, const char *, int) + __attribute__((__nonnull__)); + +/* + * Assign to this variable to choose a handler other than the default, which + * just calls sysdie. + */ +extern xmalloc_handler_type xmalloc_error_handler; + +/* Undo default visibility change. */ +#pragma GCC visibility pop + +END_DECLS + +#endif /* UTIL_XMALLOC_H */ -- cgit v1.2.3 From 534f2111ab41ed63024d811a3d8f5b81256d83a9 Mon Sep 17 00:00:00 2001 From: Jon Robertson Date: Tue, 27 Jul 2010 12:40:12 -0700 Subject: Adding wallet rekey capability -- work in progress, testing First, testing version of wallet rekey code, committed in order to get feedback from Russ. This code will eventually take an existing keytab file, and for every principal belonging to our default realm in it, get new versions of that keytab and merge them into the file. This allows for quietly rekeying principals automatically. --- client/file.c | 26 ++++++++ client/keytab.c | 179 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- client/wallet.c | 6 +- 3 files changed, 209 insertions(+), 2 deletions(-) (limited to 'client/keytab.c') diff --git a/client/file.c b/client/file.c index 66d5f63..f24d3ca 100644 --- a/client/file.c +++ b/client/file.c @@ -46,6 +46,32 @@ overwrite_file(const char *name, const void *data, size_t length) sysdie("close of %s failed (file probably truncated)", name); } +/* + * Given a filename, some data, and a length, write that data to the given + * file safely, but overwrite any existing file by that name. + */ +void +append_file(const char *name, const void *data, size_t length) +{ + int fd; + ssize_t status; + + if (access(name, F_OK) == 0) + if (unlink(name) < 0) + sysdie("unable to delete existing file %s", name); + fd = open(name, O_WRONLY | O_APPEND); + if (fd < 0) + sysdie("open of %s failed", name); + if (length > 0) { + status = write(fd, data, length); + if (status < 0) + sysdie("write to %s failed", name); + else if (status != (ssize_t) length) + die("write to %s truncated", name); + } + if (close(fd) < 0) + sysdie("close of %s failed (file probably truncated)", name); +} /* * Given a filename, some data, and a length, write that data to the given diff --git a/client/keytab.c b/client/keytab.c index 5f2076f..d81079a 100644 --- a/client/keytab.c +++ b/client/keytab.c @@ -17,7 +17,85 @@ #include #include #include +#include +/* List of principals we have already encountered. */ +struct principal_name { + char *princ; + struct principal_name* next; +}; + +/* + * Given a context, a keytab file, and a realm, return a list of all + * principals in that file. + */ +struct principal_name +keytab_principals(krb5_context ctx, const char *file, char *realm) +{ + char *princname = NULL, *princrealm = NULL; + bool found; + krb5_keytab keytab = NULL; + krb5_kt_cursor cursor; + krb5_keytab_entry entry; + krb5_error_code status; + struct principal_name *names_seen = NULL, *current_seen = NULL; + + memset(&entry, 0, sizeof(entry)); + status = krb5_kt_resolve(ctx, file, &keytab); + if (status != 0) + die_krb5(ctx, status, "cannot open keytab %s", file); + status = krb5_kt_start_seq_get(ctx, keytab, &cursor); + if (status != 0) + die_krb5(ctx, status, "cannot read keytab %s", file); + while ((status = krb5_kt_next_entry(ctx, keytab, &entry, &cursor)) == 0) { + status = krb5_unparse_name(ctx, entry.principal, &princname); + if (status != 0) + sysdie("error, cannot unparse name for a principal"); + + found = false; + current_seen = names_seen; + while (current_seen != NULL) { + if (strcmp(current_seen->princ, princname)) { + found = true; + break; + } + current_seen = current_seen->next; + } + + /* Add any new principals in the correct realm to the list. */ + if (found == false) { + princrealm = strchr(princname, '@'); + if (princrealm != NULL) { + *princrealm = '\0'; + princrealm++; + } + if (princrealm != NULL && strcmp(princrealm, realm) == 0) { + current_seen = xmalloc(sizeof(struct principal_name)); + current_seen->princ = xstrdup(princname); + current_seen->next = names_seen; + names_seen = current_seen; + } + } + + krb5_kt_free_entry(ctx, &entry); + free(princname); + } + + if (status != KRB5_KT_END) + die_krb5(ctx, status, "error reading keytab %s", file); + krb5_kt_end_seq_get(ctx, keytab, &cursor); + krb5_kt_close(ctx, keytab); + + /* TODO: Testing the principals correctly made, remove after. */ + warn("Exiting keytab_principals"); + current_seen = names_seen; + while (current_seen != NULL) { + warn("found principal %s", current_seen->princ); + current_seen = current_seen->next; + } + + return *names_seen; +} /* * Given keytab data as a pointer to memory and a length and the path of a @@ -61,11 +139,36 @@ merge_keytab(krb5_context ctx, const char *newfile, const char *file) krb5_kt_close(ctx, temp); } +/* + * Given a remctl object, the type and name of a keytab object, and + * references to keytab data and data length, call the correct wallet + * commands to download a keytab and return the keytab data. Returns the + * status of the remctl command. + */ +int +download_keytab(struct remctl *r, const char *type, const char *name, + char **data, size_t *length) +{ + const char *command[5]; + int status; + + command[0] = type; + command[1] = "get"; + command[2] = "keytab"; + command[3] = name; + command[4] = NULL; + status = run_command(r, command, data, length); + if (*data == NULL) { + warn("no data returned by wallet server"); + return 255; + } + return status; +} /* * Given a remctl object, the Kerberos context, the name of a keytab object, * and a file name, call the correct wallet commands to download a keytab and - * write it to that file. Returns the setatus or 255 on an internal error. + * write it to that file. Returns the status or 255 on an internal error. */ int get_keytab(struct remctl *r, krb5_context ctx, const char *type, @@ -105,3 +208,77 @@ get_keytab(struct remctl *r, krb5_context ctx, const char *type, } return 0; } + +/* + * Given a remctl object, the Kerberos context, the type and name of a keytab + * object, and a file name, iterate through every existing principal in the + * keytab, get fresh keys for those principals, and save the old and new + * keys to that file. Returns the status, or 255 on an internal error. + */ +int +rekey_keytab(struct remctl *r, krb5_context ctx, const char *type, + const char *file) +{ + char *realm = NULL; + char *data = NULL; + char *tempfile, *backupfile; + size_t length = 0; + int status; + bool error = false, rekeyed = false; + struct principal_name *names_seen, *current_seen; + + tempfile = concat(file, ".new", (char *) 0); + + krb5_get_default_realm(ctx, &realm); + *names_seen = keytab_principals(ctx, file, realm); + /* keytab_principals(ctx, file, realm); */ + + /* TODO: Testing we got back the principals correctly, delete. */ + warn("Finished keytab_principals"); + current_seen = names_seen; + while (current_seen != NULL) { + warn("found principal %s", current_seen->princ); + current_seen = current_seen->next; + } + return 0; + + current_seen = names_seen; + while (current_seen != NULL) { + status = download_keytab(r, type, current_seen->princ, &data, + &length); + if (status != 0) { + warn("error rekeying for principal %s", current_seen->princ); + error = true; + } else { + if (data != NULL) { + append_file(tempfile, data, length); + rekeyed = true; + } + } + warn("seen principal %s", current_seen->princ); + current_seen = current_seen->next; + } + + /* If no new keytab data, then leave the keytab as-is. */ + if (rekeyed == false) + sysdie("no rekeyed principals found"); + + /* Now merge the original keytab file with the one containing the new. */ + if (access(file, F_OK) == 0) { + + /* If error, first copy the keytab file to filename.old */ + if (error == true) { + data = read_file(file, &length); + backupfile = concat(file, ".old", (char *) 0); + overwrite_file(backupfile, data, length); + } + merge_keytab(ctx, tempfile, file); + } else { + data = read_file(tempfile, &length); + write_file(file, data, length); + } + if (unlink(tempfile) < 0) + sysdie("unlink of temporary keytab file %s failed", tempfile); + free(tempfile); + return 0; +} diff --git a/client/wallet.c b/client/wallet.c index e6d8eb9..9c1eb09 100644 --- a/client/wallet.c +++ b/client/wallet.c @@ -194,7 +194,7 @@ main(int argc, char *argv[]) } argc -= optind; argv += optind; - if (argc < 3) + if (argc < 3 && strcmp(argv[0], "rekey") != 0) usage(1); /* -f is only supported for get and store and -S with get keytab. */ @@ -242,6 +242,10 @@ main(int argc, char *argv[]) } else { status = get_file(r, options.type, argv[1], argv[2], file); } + } else if (strcmp(argv[0], "rekey") == 0) { + if (argc > 2) + die("too many arguments"); + status = rekey_keytab(r, ctx, "keytab", argv[1]); } else { count = argc + 1; if (strcmp(argv[0], "store") == 0) { -- cgit v1.2.3 From 5047dee97b80e2db2c57a2654a549e87411c1813 Mon Sep 17 00:00:00 2001 From: Jon Robertson Date: Tue, 27 Jul 2010 17:08:56 -0700 Subject: Finished first pass of the rekey command Cleaned up several bugs preventing the rekey command from working (bad calls to variables, matching on version of principal name already stripped of realm), and removed debugging code. --- client/file.c | 3 --- client/keytab.c | 77 ++++++++++++++++++++++----------------------------------- client/wallet.c | 2 +- 3 files changed, 30 insertions(+), 52 deletions(-) (limited to 'client/keytab.c') diff --git a/client/file.c b/client/file.c index f24d3ca..581d4a7 100644 --- a/client/file.c +++ b/client/file.c @@ -56,9 +56,6 @@ append_file(const char *name, const void *data, size_t length) int fd; ssize_t status; - if (access(name, F_OK) == 0) - if (unlink(name) < 0) - sysdie("unable to delete existing file %s", name); fd = open(name, O_WRONLY | O_APPEND); if (fd < 0) sysdie("open of %s failed", name); diff --git a/client/keytab.c b/client/keytab.c index d81079a..94a7858 100644 --- a/client/keytab.c +++ b/client/keytab.c @@ -29,7 +29,7 @@ struct principal_name { * Given a context, a keytab file, and a realm, return a list of all * principals in that file. */ -struct principal_name +struct principal_name * keytab_principals(krb5_context ctx, const char *file, char *realm) { char *princname = NULL, *princrealm = NULL; @@ -38,7 +38,7 @@ keytab_principals(krb5_context ctx, const char *file, char *realm) krb5_kt_cursor cursor; krb5_keytab_entry entry; krb5_error_code status; - struct principal_name *names_seen = NULL, *current_seen = NULL; + struct principal_name *names = NULL, *current = NULL; memset(&entry, 0, sizeof(entry)); status = krb5_kt_resolve(ctx, file, &keytab); @@ -52,29 +52,29 @@ keytab_principals(krb5_context ctx, const char *file, char *realm) if (status != 0) sysdie("error, cannot unparse name for a principal"); + /* Separate into principal and realm. */ + princrealm = strchr(princname, '@'); + if (princrealm != NULL) { + *princrealm = '\0'; + princrealm++; + } + if (princrealm == NULL || strcmp(princrealm, realm) != 0) + break; + + /* Check to see if the principal has already been listed. */ found = false; - current_seen = names_seen; - while (current_seen != NULL) { - if (strcmp(current_seen->princ, princname)) { + for (current = names; current != NULL; current = current->next) { + if (strcmp(current->princ, princname) == 0) { found = true; break; } - current_seen = current_seen->next; } - /* Add any new principals in the correct realm to the list. */ if (found == false) { - princrealm = strchr(princname, '@'); - if (princrealm != NULL) { - *princrealm = '\0'; - princrealm++; - } - if (princrealm != NULL && strcmp(princrealm, realm) == 0) { - current_seen = xmalloc(sizeof(struct principal_name)); - current_seen->princ = xstrdup(princname); - current_seen->next = names_seen; - names_seen = current_seen; - } + current = xmalloc(sizeof(struct principal_name)); + current->princ = xstrdup(princname); + current->next = names; + names = current; } krb5_kt_free_entry(ctx, &entry); @@ -86,15 +86,7 @@ keytab_principals(krb5_context ctx, const char *file, char *realm) krb5_kt_end_seq_get(ctx, keytab, &cursor); krb5_kt_close(ctx, keytab); - /* TODO: Testing the principals correctly made, remove after. */ - warn("Exiting keytab_principals"); - current_seen = names_seen; - while (current_seen != NULL) { - warn("found principal %s", current_seen->princ); - current_seen = current_seen->next; - } - - return *names_seen; + return names; } /* @@ -225,38 +217,27 @@ rekey_keytab(struct remctl *r, krb5_context ctx, const char *type, size_t length = 0; int status; bool error = false, rekeyed = false; - struct principal_name *names_seen, *current_seen; + struct principal_name *names, *current; tempfile = concat(file, ".new", (char *) 0); krb5_get_default_realm(ctx, &realm); - *names_seen = keytab_principals(ctx, file, realm); - /* keytab_principals(ctx, file, realm); */ - - /* TODO: Testing we got back the principals correctly, delete. */ - warn("Finished keytab_principals"); - current_seen = names_seen; - while (current_seen != NULL) { - warn("found principal %s", current_seen->princ); - current_seen = current_seen->next; - } - return 0; + names = keytab_principals(ctx, file, realm); - current_seen = names_seen; - while (current_seen != NULL) { - status = download_keytab(r, type, current_seen->princ, &data, - &length); + for (current = names; current != NULL; current = current->next) { + status = download_keytab(r, type, current->princ, &data, &length); if (status != 0) { - warn("error rekeying for principal %s", current_seen->princ); + warn("error rekeying for principal %s", current->princ); error = true; } else { if (data != NULL) { - append_file(tempfile, data, length); + if (access(tempfile, F_OK) == 0) + append_file(tempfile, data, length); + else + write_file(tempfile, data, length); rekeyed = true; } } - warn("seen principal %s", current_seen->princ); - current_seen = current_seen->next; } /* If no new keytab data, then leave the keytab as-is. */ @@ -278,7 +259,7 @@ rekey_keytab(struct remctl *r, krb5_context ctx, const char *type, write_file(file, data, length); } if (unlink(tempfile) < 0) - sysdie("unlink of temporary keytab file %s failed", tempfile); + sysdie("unlink of temporary keytab file %s failed", tempfile); free(tempfile); return 0; } diff --git a/client/wallet.c b/client/wallet.c index 9c1eb09..d61fc74 100644 --- a/client/wallet.c +++ b/client/wallet.c @@ -245,7 +245,7 @@ main(int argc, char *argv[]) } else if (strcmp(argv[0], "rekey") == 0) { if (argc > 2) die("too many arguments"); - status = rekey_keytab(r, ctx, "keytab", argv[1]); + status = rekey_keytab(r, ctx, options.type, argv[1]); } else { count = argc + 1; if (strcmp(argv[0], "store") == 0) { -- cgit v1.2.3 From 5a48a5d5f7f2af72cf84114453748fbd2a337537 Mon Sep 17 00:00:00 2001 From: Russ Allbery Date: Wed, 28 Jul 2010 22:05:05 -0700 Subject: Break wallet-rekey out into a separate client program Build a separate wallet-rekey client that rekeys every keytab given on the command-line. Fix some coding style issues and add internal prototypes. Build the shared source for both clients into an uninstalled library to save compilation time. --- .gitignore | 1 + Makefile.am | 17 ++++-- client/file.c | 6 ++- client/internal.h | 46 ++++++++++++++++ client/keytab.c | 73 ++++++++++++------------- client/options.c | 71 ++++++++++++++++++++++++ client/wallet-rekey.c | 147 ++++++++++++++++++++++++++++++++++++++++++++++++++ client/wallet.c | 85 +++-------------------------- 8 files changed, 324 insertions(+), 122 deletions(-) create mode 100644 client/options.c create mode 100644 client/wallet-rekey.c (limited to 'client/keytab.c') diff --git a/.gitignore b/.gitignore index 10cfbf8..67f4760 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ /aclocal.m4 /build-aux/ /client/wallet +/client/wallet-rekey /config.h /config.h.in /config.h.in~ diff --git a/Makefile.am b/Makefile.am index d5dccd9..10f47d9 100644 --- a/Makefile.am +++ b/Makefile.am @@ -57,15 +57,22 @@ util_libutil_a_SOURCES = util/concat.c util/concat.h util/macros.h \ util/messages.h util/xmalloc.c util/xmalloc.h util_libutil_a_CPPFLAGS = $(KRB5_CPPFLAGS) -bin_PROGRAMS = client/wallet +noinst_LIBRARIES += client/libwallet.a +client_libwallet_a_SOURCES = client/file.c client/internal.h client/keytab.c \ + client/krb5.c client/options.c client/remctl.c client/srvtab.c +client_libwallet_a_CPPFLAGS = $(REMCTL_CPPFLAGS) $(KRB5_CPPFLAGS) + +bin_PROGRAMS = client/wallet client/wallet-rekey dist_sbin_SCRIPTS = server/keytab-backend server/wallet-admin \ server/wallet-backend server/wallet-report -client_wallet_SOURCES = client/file.c client/internal.h client/keytab.c \ - client/krb5.c client/remctl.c client/srvtab.c client/wallet.c client_wallet_CPPFLAGS = $(REMCTL_CPPFLAGS) $(KRB5_CPPFLAGS) client_wallet_LDFLAGS = $(REMCTL_LDFLAGS) $(KRB5_LDFLAGS) -client_wallet_LDADD = util/libutil.a portable/libportable.a $(REMCTL_LIBS) \ - $(KRB5_LIBS) +client_wallet_LDADD = client/libwallet.a util/libutil.a \ + portable/libportable.a $(REMCTL_LIBS) $(KRB5_LIBS) +client_wallet_rekey_CPPFLAGS = $(REMCTL_CPPFLAGS) $(KRB5_CPPFLAGS) +client_wallet_rekey_LDFLAGS = $(REMCTL_LDFLAGS) $(KRB5_LDFLAGS) +client_wallet_rekey_LDADD = client/libwallet.a util/libutil.a \ + portable/libportable.a $(REMCTL_LIBS) $(KRB5_LIBS) dist_man_MANS = client/wallet.1 server/keytab-backend.8 \ server/wallet-admin.8 server/wallet-backend.8 server/wallet-report.8 diff --git a/client/file.c b/client/file.c index 581d4a7..861da6a 100644 --- a/client/file.c +++ b/client/file.c @@ -46,9 +46,10 @@ overwrite_file(const char *name, const void *data, size_t length) sysdie("close of %s failed (file probably truncated)", name); } + /* - * Given a filename, some data, and a length, write that data to the given - * file safely, but overwrite any existing file by that name. + * Given a filename, some data, and a length, append that data to an existing + * file. Dies on any failure. */ void append_file(const char *name, const void *data, size_t length) @@ -70,6 +71,7 @@ append_file(const char *name, const void *data, size_t length) sysdie("close of %s failed (file probably truncated)", name); } + /* * Given a filename, some data, and a length, write that data to the given * file safely and atomically by creating file.new, writing the data, linking diff --git a/client/internal.h b/client/internal.h index d82196c..c8e5802 100644 --- a/client/internal.h +++ b/client/internal.h @@ -15,12 +15,42 @@ #include +/* + * Allow defaults to be set for a particular site with configure options if + * people don't want to use krb5.conf for some reason. + */ +#ifndef WALLET_SERVER +# define WALLET_SERVER NULL +#endif +#ifndef WALLET_PORT +# define WALLET_PORT 0 +#endif + /* Forward declarations to avoid unnecessary includes. */ struct remctl; struct iovec; +/* + * Basic wallet behavior options set either on the command line or via + * krb5.conf. If set via krb5.conf, we allocate memory for the strings, but + * we never free them. + */ +struct options { + char *type; + char *server; + char *principal; + char *user; + int port; +}; + BEGIN_DECLS +/* + * Set default options from the system krb5.conf or from compile-time + * defaults. + */ +void default_options(krb5_context ctx, struct options *options); + /* * Given a Kerberos context and a principal name, obtain Kerberos credentials * for that principal and store them in a temporary ticket cache for use by @@ -74,12 +104,28 @@ int get_file(struct remctl *, const char *prefix, const char *type, int get_keytab(struct remctl *, krb5_context, const char *type, const char *name, const char *file, const char *srvtab); +/* + * Given a remctl object, the Kerberos context, the type for the wallet + * interface, and a file name of a keytab, iterate through every existing + * principal in the keytab in the local realm, get fresh keys for those + * principals, and save the old and new keys to that file. Returns true on + * success and false on partial failure to retrieve all the keys. + */ +bool rekey_keytab(struct remctl *, krb5_context, const char *type, + const char *file); + /* * Given a filename, some data, and a length, write that data to the given * file with error checking, overwriting any existing contents. */ void overwrite_file(const char *name, const void *data, size_t length); +/* + * Given a filename, some data, and a length, append that data to an existing + * file. Dies on any failure. + */ +void append_file(const char *name, const void *data, size_t length); + /* * Given a filename, some data, and a length, write that data to the given * file safely and atomically by creating file.new, writing the data, linking diff --git a/client/keytab.c b/client/keytab.c index 94a7858..41baa73 100644 --- a/client/keytab.c +++ b/client/keytab.c @@ -25,11 +25,12 @@ struct principal_name { struct principal_name* next; }; + /* * Given a context, a keytab file, and a realm, return a list of all * principals in that file. */ -struct principal_name * +static struct principal_name * keytab_principals(krb5_context ctx, const char *file, char *realm) { char *princname = NULL, *princrealm = NULL; @@ -69,31 +70,27 @@ keytab_principals(krb5_context ctx, const char *file, char *realm) break; } } - if (found == false) { current = xmalloc(sizeof(struct principal_name)); current->princ = xstrdup(princname); current->next = names; names = current; } - krb5_kt_free_entry(ctx, &entry); free(princname); } - if (status != KRB5_KT_END) die_krb5(ctx, status, "error reading keytab %s", file); krb5_kt_end_seq_get(ctx, keytab, &cursor); krb5_kt_close(ctx, keytab); - return names; } + /* - * Given keytab data as a pointer to memory and a length and the path of a - * second keytab, merge the keys in the memory keytab into the file keytab. - * Currently, this doesn't do any cleanup of old kvnos and doesn't handle - * duplicate kvnos correctly. Dies on any error. + * Given two files containing keytab data, second keytab, merge the keys into + * the new file. Currently, this doesn't do any cleanup of old kvnos and + * doesn't handle duplicate kvnos correctly. Dies on any error. */ static void merge_keytab(krb5_context ctx, const char *newfile, const char *file) @@ -131,13 +128,14 @@ merge_keytab(krb5_context ctx, const char *newfile, const char *file) krb5_kt_close(ctx, temp); } + /* * Given a remctl object, the type and name of a keytab object, and * references to keytab data and data length, call the correct wallet * commands to download a keytab and return the keytab data. Returns the * status of the remctl command. */ -int +static int download_keytab(struct remctl *r, const char *type, const char *name, char **data, size_t *length) { @@ -157,6 +155,7 @@ download_keytab(struct remctl *r, const char *type, const char *name, return status; } + /* * Given a remctl object, the Kerberos context, the name of a keytab object, * and a file name, call the correct wallet commands to download a keytab and @@ -201,13 +200,15 @@ get_keytab(struct remctl *r, krb5_context ctx, const char *type, return 0; } + /* - * Given a remctl object, the Kerberos context, the type and name of a keytab - * object, and a file name, iterate through every existing principal in the - * keytab, get fresh keys for those principals, and save the old and new - * keys to that file. Returns the status, or 255 on an internal error. + * Given a remctl object, the Kerberos context, the type for the wallet + * interface, and a file name of a keytab, iterate through every existing + * principal in the keytab in the local realm, get fresh keys for those + * principals, and save the old and new keys to that file. Returns true on + * success and false on partial failure to retrieve all the keys. */ -int +bool rekey_keytab(struct remctl *r, krb5_context ctx, const char *type, const char *file) { @@ -220,46 +221,46 @@ rekey_keytab(struct remctl *r, krb5_context ctx, const char *type, struct principal_name *names, *current; tempfile = concat(file, ".new", (char *) 0); - krb5_get_default_realm(ctx, &realm); names = keytab_principals(ctx, file, realm); - for (current = names; current != NULL; current = current->next) { status = download_keytab(r, type, current->princ, &data, &length); if (status != 0) { warn("error rekeying for principal %s", current->princ); error = true; - } else { - if (data != NULL) { - if (access(tempfile, F_OK) == 0) - append_file(tempfile, data, length); - else - write_file(tempfile, data, length); - rekeyed = true; - } + } else if (data != NULL) { + if (access(tempfile, F_OK) == 0) + append_file(tempfile, data, length); + else + write_file(tempfile, data, length); + rekeyed = true; } } /* If no new keytab data, then leave the keytab as-is. */ - if (rekeyed == false) - sysdie("no rekeyed principals found"); + if (!rekeyed) + sysdie("no rekeyable principals found"); - /* Now merge the original keytab file with the one containing the new. */ - if (access(file, F_OK) == 0) { - - /* If error, first copy the keytab file to filename.old */ - if (error == true) { + /* + * Now merge the original keytab file with the one containing the new + * keys. If there is an error, first make a backup of the current keytab + * file as keytab.old. + */ + if (access(file, F_OK) != 0) + link(tempfile, file); + else { + if (error) { data = read_file(file, &length); backupfile = concat(file, ".old", (char *) 0); overwrite_file(backupfile, data, length); + warn("partial failure to rekey keytab %s, old keyab left in %s", + file, backupfile); + free(backupfile); } merge_keytab(ctx, tempfile, file); - } else { - data = read_file(tempfile, &length); - write_file(file, data, length); } if (unlink(tempfile) < 0) sysdie("unlink of temporary keytab file %s failed", tempfile); free(tempfile); - return 0; + return !error; } diff --git a/client/options.c b/client/options.c new file mode 100644 index 0000000..2f1de70 --- /dev/null +++ b/client/options.c @@ -0,0 +1,71 @@ +/* + * Set default options for wallet clients. + * + * This file provides the functions to set default options from the krb5.conf + * file for both wallet and wallet-rekey. + * + * Written by Russ Allbery + * Copyright 2006, 2007, 2008, 2010 + * Board of Trustees, Leland Stanford Jr. University + * + * See LICENSE for licensing terms. + */ + +#include +#include +#include + +#include + + +/* + * Load a string option from Kerberos appdefaults. This requires an annoying + * workaround because one cannot specify a default value of NULL. + */ +static void +default_string(krb5_context ctx, const char *opt, const char *defval, + char **result) +{ + if (defval == NULL) + defval = ""; + krb5_appdefault_string(ctx, "wallet", NULL, opt, defval, result); + if (*result != NULL && (*result)[0] == '\0') { + free(*result); + *result = NULL; + } +} + + +/* + * Load a number option from Kerberos appdefaults. The native interface + * doesn't support numbers, so we actually read a string and then convert. + */ +static void +default_number(krb5_context ctx, const char *opt, int defval, int *result) +{ + char *tmp = NULL; + + krb5_appdefault_string(ctx, "wallet", NULL, opt, "", &tmp); + if (tmp != NULL && tmp[0] != '\0') + *result = atoi(tmp); + else + *result = defval; + if (tmp != NULL) + free(tmp); +} + + +/* + * Set option defaults and then get krb5.conf configuration, if any, and + * override the defaults. Later, command-line options will override those + * defaults. + */ +void +default_options(krb5_context ctx, struct options *options) +{ + default_string(ctx, "wallet_type", "wallet", &options->type); + default_string(ctx, "wallet_server", WALLET_SERVER, &options->server); + default_string(ctx, "wallet_principal", NULL, &options->principal); + default_number(ctx, "wallet_port", WALLET_PORT, &options->port); + options->user = NULL; +} diff --git a/client/wallet-rekey.c b/client/wallet-rekey.c new file mode 100644 index 0000000..3a9687c --- /dev/null +++ b/client/wallet-rekey.c @@ -0,0 +1,147 @@ +/* + * A specialized wallet client for rekeying a keytab. + * + * Written by Russ Allbery + * and Jon Robertson + * Copyright 2010 Board of Trustees, Leland Stanford Jr. University + * + * See LICENSE for licensing terms. + */ + +#include +#include +#include + +#include +#include + +#include +#include +#include + +/* + * Usage message. Use as a format and pass the port number and default server + * name. + */ +static const char usage_message[] = "\ +Usage: wallet-rekey [options] [ ...]\n\ +\n\ +Options:\n\ + -c Command prefix to use (default: wallet)\n\ + -k Kerberos principal of the server\n\ + -h Display this help\n\ + -p Port of server (default: %d, if zero, remctl default)\n\ + -s Server hostname (default: %s)\n\ + -u Authenticate as before rekeying\n\ + -v Display the version of wallet\n"; + + +/* + * Display the usage message for wallet-rekey. + */ +static void +usage(int status) +{ + fprintf((status == 0) ? stdout : stderr, usage_message, WALLET_PORT, + (WALLET_SERVER == NULL) ? "" : WALLET_SERVER); + exit(status); +} + + +/* + * Main routine. Parse the arguments and then perform the desired operation. + */ +int +main(int argc, char *argv[]) +{ + krb5_context ctx; + krb5_error_code retval; + struct options options; + int option, i; + bool okay = true; + struct remctl *r; + long tmp; + char *end; + + /* Set up logging and identity. */ + message_program_name = "wallet"; + + /* Initialize default configuration. */ + retval = krb5_init_context(&ctx); + if (retval != 0) + die_krb5(ctx, retval, "cannot initialize Kerberos"); + default_options(ctx, &options); + + while ((option = getopt(argc, argv, "c:k:hp:S:s:u:v")) != EOF) { + switch (option) { + case 'c': + options.type = optarg; + break; + case 'k': + options.principal = optarg; + break; + case 'h': + usage(0); + break; + case 'p': + errno = 0; + tmp = strtol(optarg, &end, 10); + if (tmp <= 0 || tmp > 65535 || *end != '\0') + die("invalid port number %s", optarg); + options.port = tmp; + break; + case 's': + options.server = optarg; + break; + case 'u': + options.user = optarg; + break; + case 'v': + printf("%s\n", PACKAGE_STRING); + exit(0); + break; + default: + usage(1); + break; + } + } + argc -= optind; + argv += optind; + + /* + * If no server was set at configure time and none was set on the command + * line or with krb5.conf settings, we can't continue. + */ + if (options.server == NULL) + die("no server specified in krb5.conf or with -s"); + + /* If a user was specified, obtain Kerberos tickets. */ + if (options.user != NULL) + kinit(ctx, options.user); + + /* Open a remctl connection. */ + r = remctl_new(); + if (r == NULL) + sysdie("cannot allocate memory"); + if (!remctl_open(r, options.server, options.port, options.principal)) + die("%s", remctl_error(r)); + + /* + * Rekey all the keytabs given on the command line, or the system keytab + * if none were given. + */ + if (argc == 0) + okay = rekey_keytab(r, ctx, options.type, "/etc/krb5.keytab"); + else { + for (i = 0; i < argc; i++) { + okay = rekey_keytab(r, ctx, options.type, argv[i]); + if (!okay) + break; + } + } + remctl_close(r); + krb5_free_context(ctx); + if (options.user != NULL) + kdestroy(); + exit(okay ? 0 : 1); +} diff --git a/client/wallet.c b/client/wallet.c index d61fc74..dc04dcd 100644 --- a/client/wallet.c +++ b/client/wallet.c @@ -22,30 +22,9 @@ #include /* - * Basic wallet behavior options set either on the command line or via - * krb5.conf. If set via krb5.conf, we allocate memory for the strings, but - * we never free them. + * Usage message. Use as a format and pass the port number and default server + * name. */ -struct options { - char *type; - char *server; - char *principal; - char *user; - int port; -}; - -/* - * Allow defaults to be set for a particular site with configure options if - * people don't want to use krb5.conf for some reason. - */ -#ifndef WALLET_SERVER -# define WALLET_SERVER NULL -#endif -#ifndef WALLET_PORT -# define WALLET_PORT 0 -#endif - -/* Usage message. Use as a format and pass the port number. */ static const char usage_message[] = "\ Usage: wallet [options] [ ...]\n\ wallet [options] acl [ ...]\n\ @@ -58,11 +37,12 @@ Options:\n\ -p Port of server (default: %d, if zero, remctl default)\n\ -S For the get keytab command, srvtab output file\n\ -s Server hostname (default: %s)\n\ + -u Authenticate as before running command\n\ -v Display the version of wallet\n"; /* - * Display the usage message for remctl. + * Display the usage message for wallet. */ static void usage(int status) @@ -73,59 +53,6 @@ usage(int status) } -/* - * Load a string option from Kerberos appdefaults. This requires an annoying - * workaround because one cannot specify a default value of NULL. - */ -static void -default_string(krb5_context ctx, const char *opt, const char *defval, - char **result) -{ - if (defval == NULL) - defval = ""; - krb5_appdefault_string(ctx, "wallet", NULL, opt, defval, result); - if (*result != NULL && (*result)[0] == '\0') { - free(*result); - *result = NULL; - } -} - - -/* - * Load a number option from Kerberos appdefaults. The native interface - * doesn't support numbers, so we actually read a string and then convert. - */ -static void -default_number(krb5_context ctx, const char *opt, int defval, int *result) -{ - char *tmp = NULL; - - krb5_appdefault_string(ctx, "wallet", NULL, opt, "", &tmp); - if (tmp != NULL && tmp[0] != '\0') - *result = atoi(tmp); - else - *result = defval; - if (tmp != NULL) - free(tmp); -} - - -/* - * Set option defaults and then get krb5.conf configuration, if any, and - * override the defaults. Later, command-line options will override those - * defaults. - */ -static void -set_defaults(krb5_context ctx, struct options *options) -{ - default_string(ctx, "wallet_type", "wallet", &options->type); - default_string(ctx, "wallet_server", WALLET_SERVER, &options->server); - default_string(ctx, "wallet_principal", NULL, &options->principal); - default_number(ctx, "wallet_port", WALLET_PORT, &options->port); - options->user = NULL; -} - - /* * Main routine. Parse the arguments and then perform the desired operation. */ @@ -151,7 +78,7 @@ main(int argc, char *argv[]) retval = krb5_init_context(&ctx); if (retval != 0) die_krb5(ctx, retval, "cannot initialize Kerberos"); - set_defaults(ctx, &options); + default_options(ctx, &options); while ((option = getopt(argc, argv, "c:f:k:hp:S:s:u:v")) != EOF) { switch (option) { @@ -194,7 +121,7 @@ main(int argc, char *argv[]) } argc -= optind; argv += optind; - if (argc < 3 && strcmp(argv[0], "rekey") != 0) + if (argc < 3) usage(1); /* -f is only supported for get and store and -S with get keytab. */ -- cgit v1.2.3 From 81b7ba2a6503b4bc7199d78adf97d956b1e932a5 Mon Sep 17 00:00:00 2001 From: Russ Allbery Date: Thu, 29 Jul 2010 19:20:46 -0700 Subject: Fix wallet-rekey with foreign realm keytab entries The loop handling finding principals to rekey was not correctly coping with principals from foreign realms. --- client/keytab.c | 4 ++-- tests/data/fake-keytab-old | Bin 334 -> 785 bytes tests/data/fake-keytab-rekey | Bin 698 -> 1149 bytes 3 files changed, 2 insertions(+), 2 deletions(-) (limited to 'client/keytab.c') diff --git a/client/keytab.c b/client/keytab.c index 41baa73..e00c2dd 100644 --- a/client/keytab.c +++ b/client/keytab.c @@ -51,7 +51,7 @@ keytab_principals(krb5_context ctx, const char *file, char *realm) while ((status = krb5_kt_next_entry(ctx, keytab, &entry, &cursor)) == 0) { status = krb5_unparse_name(ctx, entry.principal, &princname); if (status != 0) - sysdie("error, cannot unparse name for a principal"); + die_krb5(ctx, status, "cannot unparse name for a principal"); /* Separate into principal and realm. */ princrealm = strchr(princname, '@'); @@ -60,7 +60,7 @@ keytab_principals(krb5_context ctx, const char *file, char *realm) princrealm++; } if (princrealm == NULL || strcmp(princrealm, realm) != 0) - break; + continue; /* Check to see if the principal has already been listed. */ found = false; diff --git a/tests/data/fake-keytab-old b/tests/data/fake-keytab-old index 714d9b6..f7ee9c0 100644 Binary files a/tests/data/fake-keytab-old and b/tests/data/fake-keytab-old differ diff --git a/tests/data/fake-keytab-rekey b/tests/data/fake-keytab-rekey index 6c9c7f2..4e7a507 100644 Binary files a/tests/data/fake-keytab-rekey and b/tests/data/fake-keytab-rekey differ -- cgit v1.2.3 From dacc1c6b8e8d4bdd1daffb84efd58f16e45e3cba Mon Sep 17 00:00:00 2001 From: Russ Allbery Date: Thu, 29 Jul 2010 19:25:17 -0700 Subject: Abort rekeying if we fail on the first principal If we get a failure to rekey a principal before we've succeeded with any principal, abort rather than continuing. --- client/keytab.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'client/keytab.c') diff --git a/client/keytab.c b/client/keytab.c index e00c2dd..16a94f3 100644 --- a/client/keytab.c +++ b/client/keytab.c @@ -227,6 +227,8 @@ rekey_keytab(struct remctl *r, krb5_context ctx, const char *type, status = download_keytab(r, type, current->princ, &data, &length); if (status != 0) { warn("error rekeying for principal %s", current->princ); + if (!rekeyed) + die("aborting, keytab unchanged"); error = true; } else if (data != NULL) { if (access(tempfile, F_OK) == 0) -- cgit v1.2.3 From 1a57d2409a43623cd1396bff6b22f815dbc9e799 Mon Sep 17 00:00:00 2001 From: Russ Allbery Date: Fri, 13 Aug 2010 17:46:36 -0700 Subject: Use die instead of sysdie for no rekeyable principals In wallet-rekey, if the keytab we're supposed to rekey has no rekeyable principals, die rather than sysdie since there's no errno error to report. --- client/keytab.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'client/keytab.c') diff --git a/client/keytab.c b/client/keytab.c index 16a94f3..76c30f7 100644 --- a/client/keytab.c +++ b/client/keytab.c @@ -241,7 +241,7 @@ rekey_keytab(struct remctl *r, krb5_context ctx, const char *type, /* If no new keytab data, then leave the keytab as-is. */ if (!rekeyed) - sysdie("no rekeyable principals found"); + die("no rekeyable principals found"); /* * Now merge the original keytab file with the one containing the new -- cgit v1.2.3 From a0432d103c690119255cbf7d612531d4af616efb Mon Sep 17 00:00:00 2001 From: Russ Allbery Date: Fri, 13 Aug 2010 18:32:00 -0700 Subject: Various minor fixes for wallet-rekey Rekey the keytab in the same principal order as what's stored in the keytab rather than reversing it, since that makes it easier to test. Suppress the error message about no data from the server if the server sent an error. Fix some coding style and spelling errors. --- client/keytab.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'client/keytab.c') diff --git a/client/keytab.c b/client/keytab.c index 76c30f7..9a7734e 100644 --- a/client/keytab.c +++ b/client/keytab.c @@ -22,7 +22,7 @@ /* List of principals we have already encountered. */ struct principal_name { char *princ; - struct principal_name* next; + struct principal_name *next; }; @@ -39,7 +39,7 @@ keytab_principals(krb5_context ctx, const char *file, char *realm) krb5_kt_cursor cursor; krb5_keytab_entry entry; krb5_error_code status; - struct principal_name *names = NULL, *current = NULL; + struct principal_name *names = NULL, *current = NULL, *last = NULL; memset(&entry, 0, sizeof(entry)); status = krb5_kt_resolve(ctx, file, &keytab); @@ -69,12 +69,16 @@ keytab_principals(krb5_context ctx, const char *file, char *realm) found = true; break; } + last = current; } if (found == false) { current = xmalloc(sizeof(struct principal_name)); current->princ = xstrdup(princname); - current->next = names; - names = current; + current->next = NULL; + if (last == NULL) + names = current; + else + last->next = current; } krb5_kt_free_entry(ctx, &entry); free(princname); @@ -148,7 +152,7 @@ download_keytab(struct remctl *r, const char *type, const char *name, command[3] = name; command[4] = NULL; status = run_command(r, command, data, length); - if (*data == NULL) { + if (*data == NULL && status == 0) { warn("no data returned by wallet server"); return 255; } @@ -255,7 +259,7 @@ rekey_keytab(struct remctl *r, krb5_context ctx, const char *type, data = read_file(file, &length); backupfile = concat(file, ".old", (char *) 0); overwrite_file(backupfile, data, length); - warn("partial failure to rekey keytab %s, old keyab left in %s", + warn("partial failure to rekey keytab %s, old keytab left in %s", file, backupfile); free(backupfile); } -- cgit v1.2.3 From 7a572127a7305a17bf84c26e66e65ab37f66b77d Mon Sep 17 00:00:00 2001 From: Russ Allbery Date: Wed, 27 Feb 2013 14:21:48 -0800 Subject: Check for errors when renaming new keytab When linking the temporary keytab to its final file name, wallet wasn't checking for errors. Caught by the new gcc warnings. Change-Id: Ia75b231754bafc800e9e521345b85da256c95ed1 Reviewed-on: https://gerrit.stanford.edu/840 Reviewed-by: Russ Allbery Tested-by: Russ Allbery --- client/keytab.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'client/keytab.c') diff --git a/client/keytab.c b/client/keytab.c index 9a7734e..6614c4b 100644 --- a/client/keytab.c +++ b/client/keytab.c @@ -252,9 +252,11 @@ rekey_keytab(struct remctl *r, krb5_context ctx, const char *type, * keys. If there is an error, first make a backup of the current keytab * file as keytab.old. */ - if (access(file, F_OK) != 0) - link(tempfile, file); - else { + if (access(file, F_OK) != 0) { + if (link(tempfile, file) < 0) + sysdie("rename of temporary keytab %s to %s failed", tempfile, + file); + } else { if (error) { data = read_file(file, &length); backupfile = concat(file, ".old", (char *) 0); -- cgit v1.2.3 From 4d11772001f65264bf714711550acdbb05900f4c Mon Sep 17 00:00:00 2001 From: Russ Allbery Date: Wed, 27 Feb 2013 14:46:47 -0800 Subject: Use correct form of Stanford's copyright statement Change-Id: I06dd9ecca19315179bdd34d4b301548fe7604331 Reviewed-on: https://gerrit.stanford.edu/842 Reviewed-by: Russ Allbery Tested-by: Russ Allbery --- client/file.c | 3 ++- client/internal.h | 3 ++- client/keytab.c | 3 ++- client/krb5.c | 3 ++- client/options.c | 2 +- client/remctl.c | 3 ++- client/srvtab.c | 3 ++- client/wallet-rekey.c | 3 ++- client/wallet.c | 2 +- configure.ac | 4 +--- contrib/convert-srvtab-db | 3 ++- contrib/used-principals | 3 ++- contrib/wallet-contacts | 3 ++- contrib/wallet-summary | 3 ++- contrib/wallet-unknown-hosts | 3 ++- examples/stanford.conf | 3 ++- perl/Wallet/ACL.pm | 3 ++- perl/Wallet/ACL/Base.pm | 3 ++- perl/Wallet/ACL/Krb5.pm | 3 ++- perl/Wallet/ACL/Krb5/Regex.pm | 3 ++- perl/Wallet/ACL/NetDB.pm | 3 ++- perl/Wallet/ACL/NetDB/Root.pm | 3 ++- perl/Wallet/Config.pm | 3 ++- perl/Wallet/Database.pm | 3 ++- perl/Wallet/Kadmin.pm | 3 ++- perl/Wallet/Kadmin/Heimdal.pm | 3 ++- perl/Wallet/Kadmin/MIT.pm | 2 +- perl/Wallet/Object/File.pm | 3 ++- perl/Wallet/Object/Keytab.pm | 4 ++-- perl/Wallet/Report.pm | 3 ++- perl/create-ddl | 3 ++- perl/t/acl.t | 3 ++- perl/t/config.t | 3 ++- perl/t/file.t | 3 ++- perl/t/init.t | 3 ++- perl/t/keytab.t | 2 +- perl/t/lib/Util.pm | 3 ++- perl/t/pod.t | 3 ++- perl/t/report.t | 3 ++- perl/t/verifier-netdb.t | 3 ++- perl/t/verifier.t | 3 ++- server/keytab-backend | 2 +- server/wallet-report | 3 ++- tests/client/basic-t.in | 2 +- tests/client/full-t.in | 3 ++- tests/client/prompt-t.in | 3 ++- tests/client/rekey-t.in | 2 +- tests/data/cmd-fake | 4 +++- tests/data/fake-kadmin | 3 ++- tests/server/keytab-t | 3 ++- tests/server/report-t | 3 ++- 51 files changed, 95 insertions(+), 54 deletions(-) (limited to 'client/keytab.c') diff --git a/client/file.c b/client/file.c index 861da6a..c171969 100644 --- a/client/file.c +++ b/client/file.c @@ -2,7 +2,8 @@ * File handling for the wallet client. * * Written by Russ Allbery - * Copyright 2007, 2008, 2010 Board of Trustees, Leland Stanford Jr. University + * Copyright 2007, 2008, 2010 + * The Board of Trustees of the Leland Stanford Junior University * * See LICENSE for licensing terms. */ diff --git a/client/internal.h b/client/internal.h index c8e5802..24dd875 100644 --- a/client/internal.h +++ b/client/internal.h @@ -2,7 +2,8 @@ * Internal support functions for the wallet client. * * Written by Russ Allbery - * Copyright 2007, 2008, 2010 Board of Trustees, Leland Stanford Jr. University + * Copyright 2007, 2008, 2010 + * The Board of Trustees of the Leland Stanford Junior University * * See LICENSE for licensing terms. */ diff --git a/client/keytab.c b/client/keytab.c index 6614c4b..0a3e419 100644 --- a/client/keytab.c +++ b/client/keytab.c @@ -2,7 +2,8 @@ * Implementation of keytab handling for the wallet client. * * Written by Russ Allbery - * Copyright 2007, 2008, 2010 Board of Trustees, Leland Stanford Jr. University + * Copyright 2007, 2008, 2010, 2013 + * The Board of Trustees of the Leland Stanford Junior University * * See LICENSE for licensing terms. */ diff --git a/client/krb5.c b/client/krb5.c index aad39f6..e86a225 100644 --- a/client/krb5.c +++ b/client/krb5.c @@ -6,7 +6,8 @@ * client. * * Written by Russ Allbery - * Copyright 2007, 2008, 2010 Board of Trustees, Leland Stanford Jr. University + * Copyright 2007, 2008, 2010 + * The Board of Trustees of the Leland Stanford Junior University */ #include diff --git a/client/options.c b/client/options.c index 2f1de70..67ecb7f 100644 --- a/client/options.c +++ b/client/options.c @@ -6,7 +6,7 @@ * * Written by Russ Allbery * Copyright 2006, 2007, 2008, 2010 - * Board of Trustees, Leland Stanford Jr. University + * The Board of Trustees of the Leland Stanford Junior University * * See LICENSE for licensing terms. */ diff --git a/client/remctl.c b/client/remctl.c index 5a541d5..071e410 100644 --- a/client/remctl.c +++ b/client/remctl.c @@ -2,7 +2,8 @@ * remctl interface for the wallet client. * * Written by Russ Allbery - * Copyright 2007, 2010 Board of Trustees, Leland Stanford Jr. University + * Copyright 2007, 2010 + * The Board of Trustees of the Leland Stanford Junior University * * See LICENSE for licensing terms. */ diff --git a/client/srvtab.c b/client/srvtab.c index b26e6fc..73277e9 100644 --- a/client/srvtab.c +++ b/client/srvtab.c @@ -2,7 +2,8 @@ * Implementation of srvtab handling for the wallet client. * * Written by Russ Allbery - * Copyright 2007, 2008, 2010 Board of Trustees, Leland Stanford Jr. University + * Copyright 2007, 2008, 2010 + * The Board of Trustees of the Leland Stanford Junior University * * See LICENSE for licensing terms. */ diff --git a/client/wallet-rekey.c b/client/wallet-rekey.c index 3a9687c..5007f41 100644 --- a/client/wallet-rekey.c +++ b/client/wallet-rekey.c @@ -3,7 +3,8 @@ * * Written by Russ Allbery * and Jon Robertson - * Copyright 2010 Board of Trustees, Leland Stanford Jr. University + * Copyright 2010 + * The Board of Trustees of the Leland Stanford Junior University * * See LICENSE for licensing terms. */ diff --git a/client/wallet.c b/client/wallet.c index dc04dcd..c5a7877 100644 --- a/client/wallet.c +++ b/client/wallet.c @@ -3,7 +3,7 @@ * * Written by Russ Allbery * Copyright 2006, 2007, 2008, 2010 - * Board of Trustees, Leland Stanford Jr. University + * The Board of Trustees of the Leland Stanford Junior University * * See LICENSE for licensing terms. */ diff --git a/configure.ac b/configure.ac index a79e42d..4fc218b 100644 --- a/configure.ac +++ b/configure.ac @@ -2,12 +2,10 @@ dnl Autoconf configuration for wallet. dnl dnl Written by Russ Allbery dnl Copyright 2006, 2007, 2008, 2010 -dnl Board of Trustees, Leland Stanford Jr. University +dnl The Board of Trustees of the Leland Stanford Junior University dnl dnl See LICENSE for licensing terms. -dnl We cannot use -Wall -Werror with AM_INIT_AUTOMAKE since we override -dnl distuninstallcheck (not supported by Perl). AC_PREREQ([2.64]) AC_INIT([wallet], [0.12], [rra@stanford.edu]) AC_CONFIG_AUX_DIR([build-aux]) diff --git a/contrib/convert-srvtab-db b/contrib/convert-srvtab-db index 8d3b31e..6263472 100755 --- a/contrib/convert-srvtab-db +++ b/contrib/convert-srvtab-db @@ -3,7 +3,8 @@ # convert-srvtab-db -- Converts a leland_srvtab database to wallet # # Written by Russ Allbery -# Copyright 2008 Board of Trustees, Leland Stanford Jr. University +# Copyright 2008 +# The Board of Trustees of the Leland Stanford Junior University # # See LICENSE for licensing terms. diff --git a/contrib/used-principals b/contrib/used-principals index aa838fe..ca431e3 100755 --- a/contrib/used-principals +++ b/contrib/used-principals @@ -3,7 +3,8 @@ # used-principals -- Report which Kerberos v5 principals are in use. # # Written by Russ Allbery -# Copyright 2008 Board of Trustees, Leland Stanford Jr. University +# Copyright 2008 +# The Board of Trustees of the Leland Stanford Junior University # # See LICENSE for licensing terms. diff --git a/contrib/wallet-contacts b/contrib/wallet-contacts index 177fc76..907c161 100755 --- a/contrib/wallet-contacts +++ b/contrib/wallet-contacts @@ -3,7 +3,8 @@ # wallet-contacts -- Report contact addresses for matching wallet objects. # # Written by Russ Allbery -# Copyright 2009 Board of Trustees, Leland Stanford Jr. University +# Copyright 2009 +# The Board of Trustees of the Leland Stanford Junior University # # See LICENSE for licensing terms. diff --git a/contrib/wallet-summary b/contrib/wallet-summary index aba8406..2237351 100755 --- a/contrib/wallet-summary +++ b/contrib/wallet-summary @@ -3,7 +3,8 @@ # wallet-summary -- Summarize keytabs in the wallet database. # # Written by Russ Allbery -# Copyright 2003, 2008, 2010 Board of Trustees, Leland Stanford Jr. University +# Copyright 2003, 2008, 2010 +# The Board of Trustees of the Leland Stanford Junior University # # See LICENSE for licensing terms. diff --git a/contrib/wallet-unknown-hosts b/contrib/wallet-unknown-hosts index da972b2..e19dcf0 100755 --- a/contrib/wallet-unknown-hosts +++ b/contrib/wallet-unknown-hosts @@ -3,7 +3,8 @@ # wallet-unknown-hosts -- Report host keytabs in wallet for unknown hosts. # # Written by Russ Allbery -# Copyright 2010 Board of Trustees, Leland Stanford Jr. University +# Copyright 2010 +# The Board of Trustees of the Leland Stanford Junior University # # See LICENSE for licensing terms. diff --git a/examples/stanford.conf b/examples/stanford.conf index becfc6e..1d14796 100644 --- a/examples/stanford.conf +++ b/examples/stanford.conf @@ -6,7 +6,8 @@ # ACL rules. # # Written by Russ Allbery -# Copyright 2007, 2008 Board of Trustees, Leland Stanford Jr. University +# Copyright 2007, 2008 +# The Board of Trustees of the Leland Stanford Junior University # # See LICENSE for licensing terms. diff --git a/perl/Wallet/ACL.pm b/perl/Wallet/ACL.pm index 1e62e7b..5d9e8f2 100644 --- a/perl/Wallet/ACL.pm +++ b/perl/Wallet/ACL.pm @@ -1,7 +1,8 @@ # Wallet::ACL -- Implementation of ACLs in the wallet system. # # Written by Russ Allbery -# Copyright 2007, 2008, 2010 Board of Trustees, Leland Stanford Jr. University +# Copyright 2007, 2008, 2010, 2013 +# The Board of Trustees of the Leland Stanford Junior University # # See LICENSE for licensing terms. diff --git a/perl/Wallet/ACL/Base.pm b/perl/Wallet/ACL/Base.pm index 85eaefa..5112c2f 100644 --- a/perl/Wallet/ACL/Base.pm +++ b/perl/Wallet/ACL/Base.pm @@ -1,7 +1,8 @@ # Wallet::ACL::Base -- Parent class for wallet ACL verifiers. # # Written by Russ Allbery -# Copyright 2007, 2010 Board of Trustees, Leland Stanford Jr. University +# Copyright 2007, 2010 +# The Board of Trustees of the Leland Stanford Junior University # # See LICENSE for licensing terms. diff --git a/perl/Wallet/ACL/Krb5.pm b/perl/Wallet/ACL/Krb5.pm index 12be141..716a223 100644 --- a/perl/Wallet/ACL/Krb5.pm +++ b/perl/Wallet/ACL/Krb5.pm @@ -1,7 +1,8 @@ # Wallet::ACL::Krb5 -- Wallet Kerberos v5 principal ACL verifier. # # Written by Russ Allbery -# Copyright 2007, 2010 Board of Trustees, Leland Stanford Jr. University +# Copyright 2007, 2010 +# The Board of Trustees of the Leland Stanford Junior University # # See LICENSE for licensing terms. diff --git a/perl/Wallet/ACL/Krb5/Regex.pm b/perl/Wallet/ACL/Krb5/Regex.pm index 8f9702e..ce2fe48 100644 --- a/perl/Wallet/ACL/Krb5/Regex.pm +++ b/perl/Wallet/ACL/Krb5/Regex.pm @@ -1,7 +1,8 @@ # Wallet::ACL::Krb5::Regex -- Wallet Kerberos v5 principal regex ACL verifier # # Written by Russ Allbery -# Copyright 2007, 2010 Board of Trustees, Leland Stanford Jr. University +# Copyright 2007, 2010 +# The Board of Trustees of the Leland Stanford Junior University # # See LICENSE for licensing terms. diff --git a/perl/Wallet/ACL/NetDB.pm b/perl/Wallet/ACL/NetDB.pm index 0aa8958..2d35f49 100644 --- a/perl/Wallet/ACL/NetDB.pm +++ b/perl/Wallet/ACL/NetDB.pm @@ -1,7 +1,8 @@ # Wallet::ACL::NetDB -- Wallet NetDB role ACL verifier. # # Written by Russ Allbery -# Copyright 2007, 2010 Board of Trustees, Leland Stanford Jr. University +# Copyright 2007, 2010 +# The Board of Trustees of the Leland Stanford Junior University # # See LICENSE for licensing terms. diff --git a/perl/Wallet/ACL/NetDB/Root.pm b/perl/Wallet/ACL/NetDB/Root.pm index c28bb1e..ea79d79 100644 --- a/perl/Wallet/ACL/NetDB/Root.pm +++ b/perl/Wallet/ACL/NetDB/Root.pm @@ -1,7 +1,8 @@ # Wallet::ACL::NetDB::Root -- Wallet NetDB role ACL verifier (root instances). # # Written by Russ Allbery -# Copyright 2007, 2010 Board of Trustees, Leland Stanford Jr. University +# Copyright 2007, 2010 +# The Board of Trustees of the Leland Stanford Junior University # # See LICENSE for licensing terms. diff --git a/perl/Wallet/Config.pm b/perl/Wallet/Config.pm index 9649c6c..af153e7 100644 --- a/perl/Wallet/Config.pm +++ b/perl/Wallet/Config.pm @@ -1,7 +1,8 @@ # Wallet::Config -- Configuration handling for the wallet server. # # Written by Russ Allbery -# Copyright 2007, 2008, 2010 Board of Trustees, Leland Stanford Jr. University +# Copyright 2007, 2008, 2010, 2013 +# The Board of Trustees of the Leland Stanford Junior University # # See LICENSE for licensing terms. diff --git a/perl/Wallet/Database.pm b/perl/Wallet/Database.pm index 8df338a..61de0ba 100644 --- a/perl/Wallet/Database.pm +++ b/perl/Wallet/Database.pm @@ -6,7 +6,8 @@ # like DBIx::Class objects in the rest of the code. # # Written by Russ Allbery -# Copyright 2008-2012 Board of Trustees, Leland Stanford Jr. University +# Copyright 2008, 2009, 2010, 2012, 2013 +# The Board of Trustees of the Leland Stanford Junior University # # See LICENSE for licensing terms. diff --git a/perl/Wallet/Kadmin.pm b/perl/Wallet/Kadmin.pm index 074dd1e..bfff3ef 100644 --- a/perl/Wallet/Kadmin.pm +++ b/perl/Wallet/Kadmin.pm @@ -1,7 +1,8 @@ # Wallet::Kadmin -- Kerberos administration API for wallet keytab backend. # # Written by Jon Robertson -# Copyright 2009, 2010 Board of Trustees, Leland Stanford Jr. University +# Copyright 2009, 2010 +# The Board of Trustees of the Leland Stanford Junior University # # See LICENSE for licensing terms. diff --git a/perl/Wallet/Kadmin/Heimdal.pm b/perl/Wallet/Kadmin/Heimdal.pm index 6c91b1d..bb07b93 100644 --- a/perl/Wallet/Kadmin/Heimdal.pm +++ b/perl/Wallet/Kadmin/Heimdal.pm @@ -1,7 +1,8 @@ # Wallet::Kadmin::Heimdal -- Wallet Kerberos administration API for Heimdal. # # Written by Jon Robertson -# Copyright 2009, 2010 Board of Trustees, Leland Stanford Jr. University +# Copyright 2009, 2010 +# The Board of Trustees of the Leland Stanford Junior University # # See LICENSE for licensing terms. diff --git a/perl/Wallet/Kadmin/MIT.pm b/perl/Wallet/Kadmin/MIT.pm index c191bc9..b633e67 100644 --- a/perl/Wallet/Kadmin/MIT.pm +++ b/perl/Wallet/Kadmin/MIT.pm @@ -3,7 +3,7 @@ # Written by Russ Allbery # Pulled into a module by Jon Robertson # Copyright 2007, 2008, 2009, 2010 -# Board of Trustees, Leland Stanford Jr. University +# The Board of Trustees of the Leland Stanford Junior University # # See LICENSE for licensing terms. diff --git a/perl/Wallet/Object/File.pm b/perl/Wallet/Object/File.pm index 69468e1..49589f1 100644 --- a/perl/Wallet/Object/File.pm +++ b/perl/Wallet/Object/File.pm @@ -1,7 +1,8 @@ # Wallet::Object::File -- File object implementation for the wallet. # # Written by Russ Allbery -# Copyright 2008, 2010 Board of Trustees, Leland Stanford Jr. University +# Copyright 2008, 2010 +# The Board of Trustees of the Leland Stanford Junior University # # See LICENSE for licensing terms. diff --git a/perl/Wallet/Object/Keytab.pm b/perl/Wallet/Object/Keytab.pm index 962c19b..e00747b 100644 --- a/perl/Wallet/Object/Keytab.pm +++ b/perl/Wallet/Object/Keytab.pm @@ -1,8 +1,8 @@ # Wallet::Object::Keytab -- Keytab object implementation for the wallet. # # Written by Russ Allbery -# Copyright 2007, 2008, 2009, 2010 -# Board of Trustees, Leland Stanford Jr. University +# Copyright 2007, 2008, 2009, 2010, 2013 +# The Board of Trustees of the Leland Stanford Junior University # # See LICENSE for licensing terms. diff --git a/perl/Wallet/Report.pm b/perl/Wallet/Report.pm index ff25b3a..b27a998 100644 --- a/perl/Wallet/Report.pm +++ b/perl/Wallet/Report.pm @@ -1,7 +1,8 @@ # Wallet::Report -- Wallet system reporting interface. # # Written by Russ Allbery -# Copyright 2008, 2009, 2010 Board of Trustees, Leland Stanford Jr. University +# Copyright 2008, 2009, 2010, 2013 +# The Board of Trustees of the Leland Stanford Junior University # # See LICENSE for licensing terms. diff --git a/perl/create-ddl b/perl/create-ddl index 62deb86..10f126a 100755 --- a/perl/create-ddl +++ b/perl/create-ddl @@ -3,7 +3,8 @@ # create-ddl - Create DDL files for Wallet # # Written by Jon Robertson -# Copyright 2012 Board of Trustees, Leland Stanford Jr. University +# Copyright 2012 +# The Board of Trustees of the Leland Stanford Junior University ############################################################################# # Modules and declarations diff --git a/perl/t/acl.t b/perl/t/acl.t index 62eb411..26b4903 100755 --- a/perl/t/acl.t +++ b/perl/t/acl.t @@ -3,7 +3,8 @@ # Tests for the wallet ACL API. # # Written by Russ Allbery -# Copyright 2007, 2008 Board of Trustees, Leland Stanford Jr. University +# Copyright 2007, 2008 +# The Board of Trustees of the Leland Stanford Junior University # # See LICENSE for licensing terms. diff --git a/perl/t/config.t b/perl/t/config.t index 6b9f226..543e5d6 100755 --- a/perl/t/config.t +++ b/perl/t/config.t @@ -3,7 +3,8 @@ # Tests for the wallet server configuration. # # Written by Russ Allbery -# Copyright 2008, 2010 Board of Trustees, Leland Stanford Jr. University +# Copyright 2008, 2010 +# The Board of Trustees of the Leland Stanford Junior University # # See LICENSE for licensing terms. diff --git a/perl/t/file.t b/perl/t/file.t index f902fba..5cb7c35 100755 --- a/perl/t/file.t +++ b/perl/t/file.t @@ -3,7 +3,8 @@ # Tests for the file object implementation. # # Written by Russ Allbery -# Copyright 2008 Board of Trustees, Leland Stanford Jr. University +# Copyright 2008 +# The Board of Trustees of the Leland Stanford Junior University # # See LICENSE for licensing terms. diff --git a/perl/t/init.t b/perl/t/init.t index aa028e3..142f54c 100755 --- a/perl/t/init.t +++ b/perl/t/init.t @@ -3,7 +3,8 @@ # Tests for database initialization. # # Written by Russ Allbery -# Copyright 2007, 2008 Board of Trustees, Leland Stanford Jr. University +# Copyright 2007, 2008 +# The Board of Trustees of the Leland Stanford Junior University # # See LICENSE for licensing terms. diff --git a/perl/t/keytab.t b/perl/t/keytab.t index 561f130..3ced592 100755 --- a/perl/t/keytab.t +++ b/perl/t/keytab.t @@ -4,7 +4,7 @@ # # Written by Russ Allbery # Copyright 2007, 2008, 2009, 2010 -# Board of Trustees, Leland Stanford Jr. University +# The Board of Trustees of the Leland Stanford Junior University # # See LICENSE for licensing terms. diff --git a/perl/t/lib/Util.pm b/perl/t/lib/Util.pm index c15ccfe..3e606fe 100644 --- a/perl/t/lib/Util.pm +++ b/perl/t/lib/Util.pm @@ -1,7 +1,8 @@ # Utility class for wallet tests. # # Written by Russ Allbery -# Copyright 2007, 2008 Board of Trustees, Leland Stanford Jr. University +# Copyright 2007, 2008 +# The Board of Trustees of the Leland Stanford Junior University # # See LICENSE for licensing terms. diff --git a/perl/t/pod.t b/perl/t/pod.t index c467b82..dc5f468 100755 --- a/perl/t/pod.t +++ b/perl/t/pod.t @@ -3,7 +3,8 @@ # Test POD formatting for the wallet Perl modules. # # Written by Russ Allbery -# Copyright 2007, 2010 Board of Trustees, Leland Stanford Jr. University +# Copyright 2007, 2010 +# The Board of Trustees of the Leland Stanford Junior University # # See LICENSE for licensing terms. diff --git a/perl/t/report.t b/perl/t/report.t index 13ef7b6..a6b85df 100755 --- a/perl/t/report.t +++ b/perl/t/report.t @@ -3,7 +3,8 @@ # Tests for the wallet reporting interface. # # Written by Russ Allbery -# Copyright 2008, 2009, 2010 Board of Trustees, Leland Stanford Jr. University +# Copyright 2008, 2009, 2010 +# The Board of Trustees of the Leland Stanford Junior University # # See LICENSE for licensing terms. diff --git a/perl/t/verifier-netdb.t b/perl/t/verifier-netdb.t index 6bd4e73..398cc6a 100755 --- a/perl/t/verifier-netdb.t +++ b/perl/t/verifier-netdb.t @@ -7,7 +7,8 @@ # environments. # # Written by Russ Allbery -# Copyright 2008 Board of Trustees, Leland Stanford Jr. University +# Copyright 2008 +# The Board of Trustees of the Leland Stanford Junior University # # See LICENSE for licensing terms. diff --git a/perl/t/verifier.t b/perl/t/verifier.t index f56f5fa..75f1afa 100755 --- a/perl/t/verifier.t +++ b/perl/t/verifier.t @@ -3,7 +3,8 @@ # Tests for the basic wallet ACL verifiers. # # Written by Russ Allbery -# Copyright 2007, 2008, 2010 Board of Trustees, Leland Stanford Jr. University +# Copyright 2007, 2008, 2010 +# The Board of Trustees of the Leland Stanford Junior University # # See LICENSE for licensing terms. diff --git a/server/keytab-backend b/server/keytab-backend index 7b6adb4..3ea3df0 100755 --- a/server/keytab-backend +++ b/server/keytab-backend @@ -18,7 +18,7 @@ # # Written by Russ Allbery # Copyright 2006, 2007, 2008, 2010 -# Board of Trustees, Leland Stanford Jr. University +# The Board of Trustees of the Leland Stanford Junior University # # See LICENSE for licensing terms. diff --git a/server/wallet-report b/server/wallet-report index 992f5b8..0fd8aa9 100755 --- a/server/wallet-report +++ b/server/wallet-report @@ -3,7 +3,8 @@ # wallet-report -- Wallet server reporting interface. # # Written by Russ Allbery -# Copyright 2008, 2009, 2010 Board of Trustees, Leland Stanford Jr. University +# Copyright 2008, 2009, 2010 +# The Board of Trustees of the Leland Stanford Junior University # # See LICENSE for licensing terms. diff --git a/tests/client/basic-t.in b/tests/client/basic-t.in index 11f0bce..836f394 100644 --- a/tests/client/basic-t.in +++ b/tests/client/basic-t.in @@ -4,7 +4,7 @@ # # Written by Russ Allbery # Copyright 2006, 2007, 2008, 2010 -# Board of Trustees, Leland Stanford Jr. University +# The Board of Trustees of the Leland Stanford Junior University # # See LICENSE for licensing terms. diff --git a/tests/client/full-t.in b/tests/client/full-t.in index 680e78f..ebdba03 100644 --- a/tests/client/full-t.in +++ b/tests/client/full-t.in @@ -3,7 +3,8 @@ # End-to-end tests for the wallet client. # # Written by Russ Allbery -# Copyright 2008, 2010 Board of Trustees, Leland Stanford Jr. University +# Copyright 2008, 2010 +# The Board of Trustees of the Leland Stanford Junior University # # See LICENSE for licensing terms. diff --git a/tests/client/prompt-t.in b/tests/client/prompt-t.in index 682cd70..06991cc 100644 --- a/tests/client/prompt-t.in +++ b/tests/client/prompt-t.in @@ -3,7 +3,8 @@ # Password prompting tests for the wallet client. # # Written by Russ Allbery -# Copyright 2008, 2010 Board of Trustees, Leland Stanford Jr. University +# Copyright 2008, 2010 +# The Board of Trustees of the Leland Stanford Junior University # # See LICENSE for licensing terms. diff --git a/tests/client/rekey-t.in b/tests/client/rekey-t.in index 390a362..0cfcb5d 100644 --- a/tests/client/rekey-t.in +++ b/tests/client/rekey-t.in @@ -4,7 +4,7 @@ # # Written by Russ Allbery # Copyright 2006, 2007, 2008, 2010 -# Board of Trustees, Leland Stanford Jr. University +# The Board of Trustees of the Leland Stanford Junior University # # See LICENSE for licensing terms. diff --git a/tests/data/cmd-fake b/tests/data/cmd-fake index add72fc..11791a6 100755 --- a/tests/data/cmd-fake +++ b/tests/data/cmd-fake @@ -4,7 +4,9 @@ # the client test suite. It doesn't test any of the wallet server code. # # Written by Russ Allbery -# Copyright 2007, 2008, 2010 Board of Trustees, Leland Stanford Jr. University +# Copyright 2007, 2008, 2010 +# The Board of Trustees of the Leland Stanford Junior University +# # See LICENSE for licensing terms. command="$1" diff --git a/tests/data/fake-kadmin b/tests/data/fake-kadmin index 4c0ceac..c073ea5 100755 --- a/tests/data/fake-kadmin +++ b/tests/data/fake-kadmin @@ -3,7 +3,8 @@ # Fake kadmin.local used to test the keytab backend. # # Written by Russ Allbery -# Copyright 2007 Board of Trustees, Leland Stanford Jr. University +# Copyright 2007 +# The Board of Trustees of the Leland Stanford Junior University # # See LICENSE for licensing terms. diff --git a/tests/server/keytab-t b/tests/server/keytab-t index 2a0ceed..a9f5450 100755 --- a/tests/server/keytab-t +++ b/tests/server/keytab-t @@ -3,7 +3,8 @@ # Tests for the keytab-backend dispatch code. # # Written by Russ Allbery -# Copyright 2006, 2007, 2010 Board of Trustees, Leland Stanford Jr. University +# Copyright 2006, 2007, 2010 +# The Board of Trustees of the Leland Stanford Junior University # # See LICENSE for licensing terms. diff --git a/tests/server/report-t b/tests/server/report-t index 0771946..43ec9d1 100755 --- a/tests/server/report-t +++ b/tests/server/report-t @@ -3,7 +3,8 @@ # Tests for the wallet-report dispatch code. # # Written by Russ Allbery -# Copyright 2008, 2009, 2010 Board of Trustees, Leland Stanford Jr. University +# Copyright 2008, 2009, 2010 +# The Board of Trustees of the Leland Stanford Junior University # # See LICENSE for licensing terms. -- cgit v1.2.3 From 93e566f6f9ae8a767d2188ad1fb1520c9c2d303a Mon Sep 17 00:00:00 2001 From: Russ Allbery Date: Wed, 27 Feb 2013 14:54:05 -0800 Subject: Drop use of concat in favor of xasprintf Change-Id: I6a84920b0c0dc1849af8a34ecf8f3fb70b45e17c Reviewed-on: https://gerrit.stanford.edu/843 Reviewed-by: Russ Allbery Tested-by: Russ Allbery --- .gitignore | 1 - Makefile.am | 18 +++++------ client/file.c | 5 ++- client/keytab.c | 9 +++--- tests/TESTS | 1 - tests/util/concat-t.c | 46 ---------------------------- util/concat.c | 85 --------------------------------------------------- util/concat.h | 36 ---------------------- 8 files changed, 14 insertions(+), 187 deletions(-) delete mode 100644 tests/util/concat-t.c delete mode 100644 util/concat.c delete mode 100644 util/concat.h (limited to 'client/keytab.c') diff --git a/.gitignore b/.gitignore index 23ffe53..21fba4a 100644 --- a/.gitignore +++ b/.gitignore @@ -32,7 +32,6 @@ /tests/portable/strlcat-t /tests/portable/strlcpy-t /tests/runtests -/tests/util/concat-t /tests/util/messages-krb5-t /tests/util/messages-t /tests/util/xmalloc diff --git a/Makefile.am b/Makefile.am index 772a71e..fa70b4f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -56,9 +56,9 @@ portable_libportable_a_SOURCES = portable/dummy.c portable/krb5-extra.c \ portable/system.h portable/uio.h portable_libportable_a_CPPFLAGS = $(KRB5_CPPFLAGS) portable_libportable_a_LIBADD = $(LIBOBJS) -util_libutil_a_SOURCES = util/concat.c util/concat.h util/macros.h \ - util/messages-krb5.c util/messages-krb5.h util/messages.c \ - util/messages.h util/xmalloc.c util/xmalloc.h +util_libutil_a_SOURCES = util/macros.h util/messages-krb5.c \ + util/messages-krb5.h util/messages.c util/messages.h util/xmalloc.c \ + util/xmalloc.h util_libutil_a_CPPFLAGS = $(KRB5_CPPFLAGS) noinst_LIBRARIES += client/libwallet.a @@ -155,11 +155,11 @@ distclean-local: fi # The bits below are for the test suite, not for the main package. -check_PROGRAMS = tests/runtests tests/portable/asprintf-t \ - tests/portable/mkstemp-t tests/portable/setenv-t \ - tests/portable/snprintf-t tests/portable/strlcat-t \ - tests/portable/strlcpy-t tests/util/concat-t \ - tests/util/messages-krb5-t tests/util/messages-t tests/util/xmalloc +check_PROGRAMS = tests/runtests tests/portable/asprintf-t \ + tests/portable/mkstemp-t tests/portable/setenv-t \ + tests/portable/snprintf-t tests/portable/strlcat-t \ + tests/portable/strlcpy-t tests/util/messages-krb5-t \ + tests/util/messages-t tests/util/xmalloc tests_runtests_CPPFLAGS = -DSOURCE='"$(abs_top_srcdir)/tests"' \ -DBUILD='"$(abs_top_builddir)/tests"' check_LIBRARIES = tests/tap/libtap.a @@ -188,8 +188,6 @@ tests_portable_strlcat_t_LDADD = tests/tap/libtap.a portable/libportable.a tests_portable_strlcpy_t_SOURCES = tests/portable/strlcpy-t.c \ tests/portable/strlcpy.c tests_portable_strlcpy_t_LDADD = tests/tap/libtap.a portable/libportable.a -tests_util_concat_t_LDADD = tests/tap/libtap.a util/libutil.a \ - portable/libportable.a tests_util_messages_krb5_t_CPPFLAGS = $(KRB5_CPPFLAGS) tests_util_messages_krb5_t_LDFLAGS = $(KRB5_LDFLAGS) tests_util_messages_krb5_t_LDADD = tests/tap/libtap.a util/libutil.a \ diff --git a/client/file.c b/client/file.c index c171969..511c995 100644 --- a/client/file.c +++ b/client/file.c @@ -16,7 +16,6 @@ #include #include -#include #include #include @@ -83,8 +82,8 @@ write_file(const char *name, const void *data, size_t length) { char *temp, *backup; - temp = concat(name, ".new", (char *) 0); - backup = concat(name, ".bak", (char *) 0); + xasprintf(&temp, "%s.new", name); + xasprintf(&backup, "%s.bak", name); overwrite_file(temp, data, length); if (access(name, F_OK) == 0) { if (access(backup, F_OK) == 0) diff --git a/client/keytab.c b/client/keytab.c index 0a3e419..d7106e1 100644 --- a/client/keytab.c +++ b/client/keytab.c @@ -15,7 +15,6 @@ #include #include -#include #include #include #include @@ -107,7 +106,7 @@ merge_keytab(krb5_context ctx, const char *newfile, const char *file) krb5_error_code status; memset(&entry, 0, sizeof(entry)); - oldfile = concat("WRFILE:", file, (char *) 0); + xasprintf(&oldfile, "WRFILE:%s", file); status = krb5_kt_resolve(ctx, oldfile, &old); if (status != 0) die_krb5(ctx, status, "cannot open keytab %s", file); @@ -189,7 +188,7 @@ get_keytab(struct remctl *r, krb5_context ctx, const char *type, return 255; } if (access(file, F_OK) == 0) { - tempfile = concat(file, ".new", (char *) 0); + xasprintf(&tempfile, "%s.new", file); overwrite_file(tempfile, data, length); if (srvtab != NULL) write_srvtab(ctx, srvtab, name, tempfile); @@ -225,7 +224,7 @@ rekey_keytab(struct remctl *r, krb5_context ctx, const char *type, bool error = false, rekeyed = false; struct principal_name *names, *current; - tempfile = concat(file, ".new", (char *) 0); + xasprintf(&tempfile, "%s.new", file); krb5_get_default_realm(ctx, &realm); names = keytab_principals(ctx, file, realm); for (current = names; current != NULL; current = current->next) { @@ -260,7 +259,7 @@ rekey_keytab(struct remctl *r, krb5_context ctx, const char *type, } else { if (error) { data = read_file(file, &length); - backupfile = concat(file, ".old", (char *) 0); + xasprintf(&backupfile, "%s.old", file); overwrite_file(backupfile, data, length); warn("partial failure to rekey keytab %s, old keytab left in %s", file, backupfile); diff --git a/tests/TESTS b/tests/TESTS index 54b8190..807d944 100644 --- a/tests/TESTS +++ b/tests/TESTS @@ -13,7 +13,6 @@ portable/strlcpy server/admin server/backend server/keytab -util/concat util/messages util/messages-krb5 util/xmalloc diff --git a/tests/util/concat-t.c b/tests/util/concat-t.c deleted file mode 100644 index ca7de2c..0000000 --- a/tests/util/concat-t.c +++ /dev/null @@ -1,46 +0,0 @@ -/* - * concat test suite. - * - * Written by Russ Allbery - * Copyright 2009 Board of Trustees, Leland Stanford Jr. University - * Copyright (c) 2004, 2005, 2006 - * by Internet Systems Consortium, Inc. ("ISC") - * Copyright (c) 1991, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, - * 2002, 2003 by The Internet Software Consortium and Rich Salz - * - * See LICENSE for licensing terms. - */ - -#include -#include - -#include -#include - -#define END (char *) 0 - -/* - * Memory leaks everywhere! Whoo-hoo! - */ -int -main(void) -{ - plan(13); - - is_string("a", concat("a", END), "concat 1"); - is_string("ab", concat("a", "b", END), "concat 2"); - is_string("ab", concat("ab", "", END), "concat 3"); - is_string("ab", concat("", "ab", END), "concat 4"); - is_string("", concat("", END), "concat 5"); - is_string("abcde", concat("ab", "c", "", "de", END), "concat 6"); - is_string("abcde", concat("abc", "de", END, "f", END), "concat 7"); - - is_string("/foo", concatpath("/bar", "/foo"), "path 1"); - is_string("/foo/bar", concatpath("/foo", "bar"), "path 2"); - is_string("./bar", concatpath("/foo", "./bar"), "path 3"); - is_string("/bar/baz/foo/bar", concatpath("/bar/baz", "foo/bar"), "path 4"); - is_string("./foo", concatpath(NULL, "foo"), "path 5"); - is_string("/foo/bar", concatpath(NULL, "/foo/bar"), "path 6"); - - return 0; -} diff --git a/util/concat.c b/util/concat.c deleted file mode 100644 index bdbd836..0000000 --- a/util/concat.c +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Concatenate strings with dynamic memory allocation. - * - * Usage: - * - * string = concat(string1, string2, ..., (char *) 0); - * path = concatpath(base, name); - * - * Dynamically allocates (using xmalloc) sufficient memory to hold all of the - * strings given and then concatenates them together into that allocated - * memory, returning a pointer to it. Caller is responsible for freeing. - * Assumes xmalloc is available. The last argument must be a null pointer (to - * a char *, if you actually find a platform where it matters). - * - * concatpath is similar, except that it only takes two arguments. If the - * second argument begins with / or ./, a copy of it is returned; otherwise, - * the first argument, a slash, and the second argument are concatenated - * together and returned. This is useful for building file names where names - * that aren't fully qualified are qualified with some particular directory. - * - * Written by Russ Allbery - * This work is hereby placed in the public domain by its author. - */ - -#include -#include - -#include -#include - -/* Abbreviation for cleaner code. */ -#define VA_NEXT(var, type) ((var) = (type) va_arg(args, type)) - - -/* - * Concatenate all of the arguments into a newly allocated string. ANSI C - * requires at least one named parameter, but it's not treated any different - * than the rest. - */ -char * -concat(const char *first, ...) -{ - va_list args; - char *result, *p; - const char *string; - size_t length = 0; - - /* Find the total memory required. */ - va_start(args, first); - for (string = first; string != NULL; VA_NEXT(string, const char *)) - length += strlen(string); - va_end(args); - length++; - - /* - * Create the string. Doing the copy ourselves avoids useless string - * traversals of result, if using strcat, or string, if using strlen to - * increment a pointer into result, at the cost of losing the native - * optimization of strcat if any. - */ - result = xmalloc(length); - p = result; - va_start(args, first); - for (string = first; string != NULL; VA_NEXT(string, const char *)) - while (*string != '\0') - *p++ = *string++; - va_end(args); - *p = '\0'; - - return result; -} - - -/* - * Concatenate name with base, unless name begins with / or ./. Return the - * new string in newly allocated memory. - */ -char * -concatpath(const char *base, const char *name) -{ - if (name[0] == '/' || (name[0] == '.' && name[1] == '/')) - return xstrdup(name); - else - return concat(base != NULL ? base : ".", "/", name, (char *) 0); -} diff --git a/util/concat.h b/util/concat.h deleted file mode 100644 index ef8b38d..0000000 --- a/util/concat.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Prototypes for string concatenation with dynamic memory allocation. - * - * Written by Russ Allbery - * This work is hereby placed in the public domain by its author. - */ - -#ifndef UTIL_CONCAT_H -#define UTIL_CONCAT_H 1 - -#include -#include - -BEGIN_DECLS - -/* Default to a hidden visibility for all util functions. */ -#pragma GCC visibility push(hidden) - -/* Concatenate NULL-terminated strings into a newly allocated string. */ -char *concat(const char *first, ...) - __attribute__((__malloc__, __nonnull__(1))); - -/* - * Given a base path and a file name, create a newly allocated path string. - * The name will be appended to base with a / between them. Exceptionally, if - * name begins with a slash, it will be strdup'd and returned as-is. - */ -char *concatpath(const char *base, const char *name) - __attribute__((__malloc__, __nonnull__(2))); - -/* Undo default visibility change. */ -#pragma GCC visibility pop - -END_DECLS - -#endif /* UTIL_CONCAT_H */ -- cgit v1.2.3