On Tue, 2015-11-24 at 17:34 +0100, Jan Cholasta wrote:
> On 24.11.2015 17:30, Simo Sorce wrote:
> > On Tue, 2015-11-24 at 09:14 +0100, Jan Cholasta wrote:
> >> On 24.11.2015 09:06, Petr Spacek wrote:
> >>> On 24.11.2015 07:32, Jan Cholasta wrote:
> >>>> On 23.11.2015 21:18, Simo Sorce wrote:
> >>>>> Fixes #2203 by reading the server name from /etc/ipa/default.conf if not
> >>>>> provided on the command line.
> >>>>>
> >>>>> Simo.
> >>>>
> >>>> Just a thought: it would be nice if we had libipaconfig and used it 
> >>>> everywhere
> >>>> (the framework, ipa-getkeytab, certmonger, ...). I don't like that there 
> >>>> are
> >>>> at least 3 ipa config parser implementations now, each with its own 
> >>>> quirks.
> >>>
> >>> Yeah, define a Augeas grammar for IPA config and call it. There is C and
> >>> Python binding in RHEL 7.2 already.
> >>
> >> This won't be sufficient, as it should go beyond just parsing the config
> >> file - there are dynamic defaults and backward compatiblity support
> >> which should be the same everywhere too.
> >
> > This is a much bigger task, that someone keen on big refactoring may
> > undertake, but I do not think we should delay this useful feature for
> > that. It will be really easy to change this code to use whatever other
> > ipa library when it materializes.
> >
> > For now this patch stands IMHO.
> 
> Sure, I'm not suggesting otherwise.

Rebased patch that includes proper spec file buildrequires.

Simo.

-- 
Simo Sorce * Red Hat, Inc * New York
From 45700a2704d5aaa2574a5fa56fde637d4a4777f1 Mon Sep 17 00:00:00 2001
From: Simo Sorce <s...@redhat.com>
Date: Mon, 23 Nov 2015 14:50:04 -0500
Subject: [PATCH] Support sourcing the IPA server name from config

Use ding-libs to parse /etc/ipa/default.conf to find the IPA server
to contact by default.

Signed-off-by: Simo Sorce <s...@redhat.com>

Ticket: https://fedorahosted.org/freeipa/ticket/2203
---
 freeipa.spec.in            |  1 +
 ipa-client/Makefile.am     |  4 ++
 ipa-client/configure.ac    | 28 ++++++++++++++
 ipa-client/ipa-getkeytab.c | 93 +++++++++++++++++++++++++++++++++++++++++++++-
 4 files changed, 125 insertions(+), 1 deletion(-)

diff --git a/freeipa.spec.in b/freeipa.spec.in
index d66b0ffe9eeb061c19642995aa19459673d61dec..5524576054ad77f7263e02642d1ae795aeb7077e 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 0da351c6a28a4e2a216bec3f85d0500e4aef47ff..6c426779530f216b11dff0764132221ea2793289 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 78da8e6e413b8becbd4c75422abffb670050f446..943c3f1b62f6a4947335178e9bcf1d45434a7e90 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 15255d6a33c8c298f138868ac545d4ebea415fe5..9670d980fd1c2f00e28cf177425e9affee8c4097 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);
-- 
2.5.0

-- 
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code

Reply via email to