diff options
-rw-r--r-- | freeipa.spec.in | 1 | ||||
-rw-r--r-- | ipa-client/Makefile.am | 4 | ||||
-rw-r--r-- | ipa-client/configure.ac | 28 | ||||
-rw-r--r-- | ipa-client/ipa-getkeytab.c | 93 | ||||
-rw-r--r-- | ipa-client/man/ipa-getkeytab.1 | 12 |
5 files changed, 132 insertions, 6 deletions
diff --git a/freeipa.spec.in b/freeipa.spec.in index 0011aa05f..a60d9b63f 100644 --- a/freeipa.spec.in +++ b/freeipa.spec.in @@ -97,6 +97,7 @@ BuildRequires: python-kdcproxy >= 0.3 BuildRequires: python-six BuildRequires: python-jwcrypto BuildRequires: custodia +BuildRequires: libini_config-devel >= 1.2.0 # Build dependencies for unit tests BuildRequires: libcmocka-devel diff --git a/ipa-client/Makefile.am b/ipa-client/Makefile.am index 0da351c6a..6c4267795 100644 --- a/ipa-client/Makefile.am +++ b/ipa-client/Makefile.am @@ -15,6 +15,7 @@ export AM_CFLAGS KRB5_UTIL_DIR=../util KRB5_UTIL_SRCS=$(KRB5_UTIL_DIR)/ipa_krb5.c ASN1_UTIL_DIR=../asn1 +IPA_CONF_FILE=$(sysconfdir)/ipa/default.conf AM_CPPFLAGS = \ -I. \ @@ -27,11 +28,13 @@ AM_CPPFLAGS = \ -DLIBEXECDIR=\""$(libexecdir)"\" \ -DDATADIR=\""$(datadir)"\" \ -DLOCALEDIR=\""$(localedir)"\" \ + -DIPACONFFILE=\""$(IPA_CONF_FILE)"\" \ $(KRB5_CFLAGS) \ $(OPENLDAP_CFLAGS) \ $(SASL_CFLAGS) \ $(POPT_CFLAGS) \ $(WARN_CFLAGS) \ + $(INI_CFLAGS) \ $(NULL) sbin_PROGRAMS = \ @@ -53,6 +56,7 @@ ipa_getkeytab_LDADD = \ $(SASL_LIBS) \ $(POPT_LIBS) \ $(LIBINTL_LIBS) \ + $(INI_LIBS) \ $(NULL) ipa_rmkeytab_SOURCES = \ diff --git a/ipa-client/configure.ac b/ipa-client/configure.ac index 78da8e6e4..943c3f1b6 100644 --- a/ipa-client/configure.ac +++ b/ipa-client/configure.ac @@ -192,6 +192,34 @@ LIBS="$SAVELIBS" AC_SUBST(LIBINTL_LIBS) dnl --------------------------------------------------------------------------- +dnl - Check for libini_config +dnl --------------------------------------------------------------------------- +PKG_CHECK_MODULES([LIBINI_CONFIG], [ini_config >= 1.2.0], [have_libini_config=1], [have_libini_config=]) +if test x$have_libini_config = x; then + AC_MSG_WARN([Could not find LIBINI_CONFIG headers]) +else + INI_CONFIG_CFLAGS="`$PKG_CONFIG --cflags ini_config`" + INI_CONFIG_LIBS="`$PKG_CONFIG --libs ini_config`" + AC_CHECK_LIB(ini_config, ini_config_file_open, [], + [AC_MSG_WARN([ini_config library must support ini_config_file_open])], + [$INI_CONFIG_LIBS]) + AC_CHECK_LIB(ini_config, ini_config_augment, [], + [AC_MSG_WARN([ini_config library must support ini_config_augment])], + [$INI_CONFIG_LIBS]) +fi + +if test x$have_libini_config = x1; then + INI_CFLAGS="$INI_CONFIG_CFLAGS" + INI_LIBS="$INI_CONFIG_LIBS" +else + AC_MSG_ERROR([ini_config development packages not available]) +fi + +AC_SUBST(INI_LIBS) +AC_SUBST(INI_CFLAGS) + + +dnl --------------------------------------------------------------------------- dnl - Set the data install directory since we don't use pkgdatadir dnl --------------------------------------------------------------------------- diff --git a/ipa-client/ipa-getkeytab.c b/ipa-client/ipa-getkeytab.c index a006b78a8..3592d9970 100644 --- a/ipa-client/ipa-getkeytab.c +++ b/ipa-client/ipa-getkeytab.c @@ -36,6 +36,7 @@ #include <ldap.h> #include <sasl/sasl.h> #include <popt.h> +#include <ini_configobj.h> #include "config.h" @@ -596,6 +597,81 @@ static char *ask_password(krb5_context krbctx) return password; } +struct ipa_config { + const char *server_name; +}; + +static int config_from_file(struct ini_cfgobj *cfgctx) +{ + struct ini_cfgfile *fctx = NULL; + char **errors = NULL; + int ret; + + ret = ini_config_file_open(IPACONFFILE, 0, &fctx); + if (ret) { + fprintf(stderr, _("Failed to open config file %s\n"), IPACONFFILE); + return ret; + } + + ret = ini_config_parse(fctx, + INI_STOP_ON_ANY, + INI_MS_MERGE | INI_MV1S_ALLOW | INI_MV2S_ALLOW, + INI_PARSE_NOWRAP, + cfgctx); + if (ret) { + fprintf(stderr, _("Failed to parse config file %s\n"), IPACONFFILE); + if (ini_config_error_count(cfgctx)) { + ini_config_get_errors(cfgctx, &errors); + if (errors) { + ini_config_print_errors(stderr, errors); + ini_config_free_errors(errors); + } + } + ini_config_file_destroy(fctx); + return ret; + } + + ini_config_file_destroy(fctx); + return 0; +} + +int read_ipa_config(struct ipa_config **ipacfg) +{ + struct ini_cfgobj *cfgctx = NULL; + struct value_obj *obj = NULL; + int ret; + + *ipacfg = calloc(1, sizeof(struct ipa_config)); + if (!*ipacfg) { + return ENOMEM; + } + + ret = ini_config_create(&cfgctx); + if (ret) { + return ENOENT; + } + + ret = config_from_file(cfgctx); + if (ret) { + ini_config_destroy(cfgctx); + return EINVAL; + } + + ret = ini_get_config_valueobj("global", "server", cfgctx, + INI_GET_LAST_VALUE, &obj); + if (ret != 0 || obj == NULL) { + /* if called on an IPA server we need to look for 'host' instead */ + ret = ini_get_config_valueobj("global", "host", cfgctx, + INI_GET_LAST_VALUE, &obj); + } + + if (ret == 0 && obj != NULL) { + (*ipacfg)->server_name = ini_get_string_config_value(obj, &ret); + } + + return 0; +} + int main(int argc, const char *argv[]) { static const char *server = NULL; @@ -688,7 +764,7 @@ int main(int argc, const char *argv[]) exit (0); } - if (ret != -1 || !server || !principal || !keytab || permitted_enctypes) { + if (ret != -1 || !principal || !keytab || permitted_enctypes) { if (!quiet) { poptPrintUsage(pc, stderr, 0); } @@ -703,6 +779,21 @@ int main(int argc, const char *argv[]) exit(10); } + if (!server) { + struct ipa_config *ipacfg = NULL; + + ret = read_ipa_config(&ipacfg); + if (ret == 0) { + server = ipacfg->server_name; + ipacfg->server_name = NULL; + } + free(ipacfg); + if (!server) { + fprintf(stderr, _("Server name not provided and unavailable\n")); + exit(2); + } + } + if (askpass && retrieve) { fprintf(stderr, _("Incompatible options provided (-r and -P)\n")); exit(2); diff --git a/ipa-client/man/ipa-getkeytab.1 b/ipa-client/man/ipa-getkeytab.1 index bb84ad8f2..1c270729e 100644 --- a/ipa-client/man/ipa-getkeytab.1 +++ b/ipa-client/man/ipa-getkeytab.1 @@ -21,7 +21,7 @@ .SH "NAME" ipa\-getkeytab \- Get a keytab for a Kerberos principal .SH "SYNOPSIS" -ipa\-getkeytab \fB\-s\fR \fIipaserver\fR \fB\-p\fR \fIprincipal\-name\fR \fB\-k\fR \fIkeytab\-file\fR [ \fB\-e\fR encryption\-types ] [ \fB\-q\fR ] [ \fB\-D\fR|\fB\-\-binddn\fR \fIBINDDN\fR ] [ \fB\-w|\-\-bindpw\fR ] [ \fB\-P\fR|\fB\-\-password\fR \fIPASSWORD\fR ] [ \fB\-r\fR ] +ipa\-getkeytab \fB\-p\fR \fIprincipal\-name\fR \fB\-k\fR \fIkeytab\-file\fR [ \fB\-e\fR \fIencryption\-types\fR ] [ \fB\-s\fR \fIipaserver\fR ] [ \fB\-q\fR ] [ \fB\-D\fR|\fB\-\-binddn\fR \fIBINDDN\fR ] [ \fB\-w|\-\-bindpw\fR ] [ \fB\-P\fR|\fB\-\-password\fR \fIPASSWORD\fR ] [ \fB\-r\fR ] .SH "DESCRIPTION" Retrieves a Kerberos \fIkeytab\fR. @@ -50,9 +50,6 @@ This renders all other keytabs for that principal invalid. This is used during IPA client enrollment to retrieve a host service principal and store it in /etc/krb5.keytab. It is possible to retrieve the keytab without Kerberos credentials if the host was pre\-created with a one\-time password. The keytab can be retrieved by binding as the host and authenticating with this one\-time password. The \fB\-D|\-\-binddn\fR and \fB\-w|\-\-bindpw\fR options are used for this authentication. .SH "OPTIONS" .TP -\fB\-s ipaserver\fR -The IPA server to retrieve the keytab from (FQDN). -.TP \fB\-p principal\-name\fR The non\-realm part of the full principal name. .TP @@ -73,6 +70,11 @@ des\-hmac\-sha1 des\-cbc\-md5 des\-cbc\-crc .TP +\fB\-s ipaserver\fR +The IPA server to retrieve the keytab from (FQDN). If this option is not +provided the server name is read from the IPA configuration file +(/etc/ipa/default.conf) +.TP \fB\-q\fR Quiet mode. Only errors are displayed. .TP @@ -105,7 +107,7 @@ keytab must have access to the keys for this operation to succeed. Add and retrieve a keytab for the NFS service principal on the host foo.example.com and save it in the file /tmp/nfs.keytab and retrieve just the des\-cbc\-crc key. - # ipa\-getkeytab \-s ipaserver.example.com \-p nfs/foo.example.com \-k /tmp/nfs.keytab \-e des\-cbc\-crc + # ipa\-getkeytab \-p nfs/foo.example.com \-k /tmp/nfs.keytab \-e des\-cbc\-crc Add and retrieve a keytab for the ldap service principal on the host foo.example.com and save it in the file /tmp/ldap.keytab. |