From 5d4ed65b83f6ed8bb7f3da05561698cbea692bb3 Mon Sep 17 00:00:00 2001 From: Christian Heimes Date: Wed, 16 Sep 2020 10:35:15 +0200 Subject: [PATCH] Replace nodename with ipa_gethostfqdn() ipa_kdb and ipa-join now use ipa_gethostfqdn() instead of uname()'s nodename. The code for hostname in ipa-join is simplified. Now the hostname is auto-detected and verified in main(). All sub functions can now use the hostname without additional checks. This removes a bunch of strdup(), NULL checks, and free() calls. Fixes: https://pagure.io/freeipa/issue/8501 Signed-off-by: Christian Heimes Reviewed-By: Fraser Tweedale --- client/ipa-join.c | 120 ++++++++++++-------------------------- client/man/ipa-join.1 | 4 +- daemons/ipa-kdb/ipa_kdb.c | 12 ++-- 3 files changed, 45 insertions(+), 91 deletions(-) diff --git a/client/ipa-join.c b/client/ipa-join.c index 1a86e80e6..5e8b91dfe 100644 --- a/client/ipa-join.c +++ b/client/ipa-join.c @@ -47,6 +47,7 @@ #include "ipa-client-common.h" #include "ipa_ldap.h" +#include "ipa_hostname.h" #define NAME "ipa-join" @@ -401,7 +402,7 @@ done: * the state of the entry. */ static int -join_ldap(const char *ipaserver, char *hostname, char ** binddn, const char *bindpw, const char *basedn, const char **princ, bool quiet) +join_ldap(const char *ipaserver, const char *hostname, char ** binddn, const char *bindpw, const char *basedn, const char **princ, bool quiet) { LDAP *ld; int rval = 0; @@ -497,7 +498,7 @@ done: #ifdef WITH_IPA_JOIN_XML static int -join_krb5_xmlrpc(const char *ipaserver, char *hostname, char **hostdn, const char **princ, bool force, bool quiet) { +join_krb5_xmlrpc(const char *ipaserver, const char *hostname, char **hostdn, const char **princ, bool force, bool quiet) { xmlrpc_env env; xmlrpc_value * argArrayP = NULL; xmlrpc_value * paramArrayP = NULL; @@ -545,15 +546,11 @@ join_krb5_xmlrpc(const char *ipaserver, char *hostname, char **hostdn, const cha argArrayP = xmlrpc_array_new(&env); paramArrayP = xmlrpc_array_new(&env); - - if (hostname == NULL) - paramP = xmlrpc_string_new(&env, uinfo.nodename); - else - paramP = xmlrpc_string_new(&env, hostname); + paramP = xmlrpc_string_new(&env, hostname); xmlrpc_array_append_item(&env, argArrayP, paramP); #ifdef REALM if (!quiet) - printf("Joining %s to IPA realm %s\n", uinfo.nodename, iparealm); + printf("Joining %s to IPA realm %s\n", hostname, iparealm); #endif xmlrpc_array_append_item(&env, paramArrayP, argArrayP); xmlrpc_DECREF(paramP); @@ -918,11 +915,10 @@ cleanup: } static int -join_krb5_jsonrpc(const char *ipaserver, char *hostname, char **hostdn, const char **princ, bool force, bool quiet) { +join_krb5_jsonrpc(const char *ipaserver, const char *hostname, char **hostdn, const char **princ, bool force, bool quiet) { int rval = 0; struct utsname uinfo; - char *host = NULL; curl_buffer cb = {0}; @@ -936,25 +932,11 @@ join_krb5_jsonrpc(const char *ipaserver, char *hostname, char **hostdn, const ch uname(&uinfo); - if (!hostname) { - host = strdup(uinfo.nodename); - } else { - host = strdup(hostname); - } - - if (!host) { - if (!quiet) - fprintf(stderr, _("Out of memory!\n")); - - rval = 3; - goto cleanup; - } - /* create the JSON-RPC payload */ json_req = json_pack_ex(&j_error, 0, "{s:s, s:[[s], {s:s, s:s}]}", "method", "join", "params", - host, + hostname, "nsosversion", uinfo.release, "nshardwareplatform", uinfo.machine); @@ -986,9 +968,6 @@ join_krb5_jsonrpc(const char *ipaserver, char *hostname, char **hostdn, const ch } cleanup: - if (host) - free(host); - json_decref(json_req); if (cb.payload) @@ -1175,10 +1154,8 @@ join(const char *server, const char *hostname, const char *bindpw, const char *b int status = 0; char *ipaserver = NULL; char *iparealm = NULL; - char * host = NULL; const char * princ = NULL; char * hostdn = NULL; - struct utsname uinfo; krb5_context krbctx = NULL; krb5_ccache ccache = NULL; @@ -1197,27 +1174,8 @@ join(const char *server, const char *hostname, const char *bindpw, const char *b free(conf_data); } - if (NULL == hostname) { - uname(&uinfo); - host = strdup(uinfo.nodename); - } else { - host = strdup(hostname); - } - - if (NULL == strstr(host, ".")) { - fprintf(stderr, _("The hostname must be fully-qualified: %s\n"), host); - rval = 16; - goto cleanup; - } - - if ((!strcmp(host, "localhost")) || (!strcmp(host, "localhost.localdomain"))){ - fprintf(stderr, _("The hostname must not be: %s\n"), host); - rval = 16; - goto cleanup; - } - if (bindpw) - rval = join_ldap(ipaserver, host, &hostdn, bindpw, basedn, &princ, quiet); + rval = join_ldap(ipaserver, hostname, &hostdn, bindpw, basedn, &princ, quiet); else { krberr = krb5_init_context(&krbctx); if (krberr) { @@ -1243,9 +1201,9 @@ join(const char *server, const char *hostname, const char *bindpw, const char *b } #ifdef WITH_IPA_JOIN_XML - rval = join_krb5_xmlrpc(ipaserver, host, &hostdn, &princ, force, quiet); + rval = join_krb5_xmlrpc(ipaserver, hostname, &hostdn, &princ, force, quiet); #else - rval = join_krb5_jsonrpc(ipaserver, host, &hostdn, &princ, force, quiet); + rval = join_krb5_jsonrpc(ipaserver, hostname, &hostdn, &princ, force, quiet); #endif } @@ -1308,7 +1266,6 @@ join(const char *server, const char *hostname, const char *bindpw, const char *b cleanup: free((char *)princ); - free(host); if (bindpw) ldap_memfree((void *)hostdn); @@ -1330,10 +1287,6 @@ unenroll_host(const char *server, const char *hostname, const char *ktname, bool int rval = 0; char *ipaserver = NULL; - char *host = NULL; - - struct utsname uinfo; - char *principal = NULL; char *realm = NULL; @@ -1361,28 +1314,6 @@ unenroll_host(const char *server, const char *hostname, const char *ktname, bool free(conf_data); } - if (!hostname) { - host = strdup(uinfo.nodename); - } else { - host = strdup(hostname); - } - - if (!host) { - if (!quiet) - fprintf(stderr, _("Out of memory!\n")); - - rval = 3; - goto cleanup; - } - - if (!strstr(host, ".")) { - if (!quiet) - fprintf(stderr, _("The hostname must be fully-qualified: %s\n"), - host); - rval = 16; - goto cleanup; - } - krberr = krb5_init_context(&krbctx); if (krberr) { if (!quiet) @@ -1410,7 +1341,7 @@ unenroll_host(const char *server, const char *hostname, const char *ktname, bool goto cleanup; } - ASPRINTF(&principal, "host/%s@%s", host, realm); + ASPRINTF(&principal, "host/%s@%s", hostname, realm); krberr = krb5_parse_name(krbctx, principal, &princ); if (krberr != 0) { @@ -1473,14 +1404,12 @@ unenroll_host(const char *server, const char *hostname, const char *ktname, bool putenv("KRB5CCNAME=MEMORY:ipa-join"); #ifdef WITH_IPA_JOIN_XML - rval = xmlrpc_unenroll_host(ipaserver, host, quiet); + rval = xmlrpc_unenroll_host(ipaserver, hostname, quiet); #else - rval = jsonrpc_unenroll_host(ipaserver, host, quiet); + rval = jsonrpc_unenroll_host(ipaserver, hostname, quiet); #endif cleanup: - if (host) - free(host); if (principal) free(principal); if (ipaserver) @@ -1516,6 +1445,7 @@ main(int argc, const char **argv) { static const char *keytab = NULL; static const char *bindpw = NULL; static const char *basedn = NULL; + char fqdn[IPA_HOST_NAME_LEN]; int quiet = 0; int unenroll = 0; int force = 0; @@ -1566,6 +1496,28 @@ main(int argc, const char **argv) { if (!keytab) keytab = "/etc/krb5.keytab"; + /* auto-detect and verify hostname */ + if (!hostname) { + if (ipa_gethostname(fqdn) != 0) { + if (!quiet) + fprintf(stderr, _("Cannot get host's FQDN!\n")); + exit(22); + } + hostname = fqdn; + } + if (NULL == strstr(hostname, ".")) { + if (!quiet) { + fprintf(stderr, _("The hostname must be fully-qualified: %s\n"), hostname); + } + exit(16); + } + if ((!strcmp(hostname, "localhost")) || (!strcmp(hostname, "localhost.localdomain"))){ + if (!quiet) { + fprintf(stderr, _("The hostname must not be: %s\n"), hostname); + } + exit(16); + } + if (unenroll) { ret = unenroll_host(server, hostname, keytab, quiet); } else { diff --git a/client/man/ipa-join.1 b/client/man/ipa-join.1 index 320fc55e8..6e512b875 100644 --- a/client/man/ipa-join.1 +++ b/client/man/ipa-join.1 @@ -50,7 +50,7 @@ Please note, that while the ipa\-join option removes the client from the domain, .SH "OPTIONS" .TP \fB\-h,\-\-hostname hostname\fR -The hostname of this server (FQDN). By default of nodename from uname(2) is used. +The hostname of this server (FQDN). By default the canonical name from getaddrinfo(3) for gethostname(2) is used. .TP \fB\-s,\-\-server server\fR The hostname of the IPA server (FQDN). Note that by default there is no /etc/ipa/default.conf, in most cases it needs to be supplied. @@ -137,6 +137,8 @@ The exit status is 0 on success, nonzero on error. 21 Failed to get default Kerberos realm +22 Unable to auto-detect fully\-qualified hostname + .SH "SEE ALSO" .BR ipa-rmkeytab (1) .BR ipa-client-install (1) diff --git a/daemons/ipa-kdb/ipa_kdb.c b/daemons/ipa-kdb/ipa_kdb.c index 33d2a6773..aee463c48 100644 --- a/daemons/ipa-kdb/ipa_kdb.c +++ b/daemons/ipa-kdb/ipa_kdb.c @@ -25,6 +25,7 @@ #include "ipa_kdb.h" #include "ipa_krb5.h" +#include "ipa_hostname.h" #define IPADB_GLOBAL_CONFIG_CACHE_TIME 60 @@ -535,9 +536,9 @@ static krb5_error_code ipadb_init_module(krb5_context kcontext, { struct ipadb_context *ipactx; krb5_error_code kerr; + char hostname[IPA_HOST_NAME_LEN]; int ret; int i; - struct utsname uname_data; /* make sure the context is freed to avoid leaking it */ ipactx = ipadb_get_context(kcontext); @@ -603,13 +604,12 @@ static krb5_error_code ipadb_init_module(krb5_context kcontext, goto fail; } - ret = uname(&uname_data); - if (ret) { - ret = EINVAL; + ret = ipa_gethostfqdn(hostname); + if (ret != 0) { + ret = errno; goto fail; } - - ipactx->kdc_hostname = strdup(uname_data.nodename); + ipactx->kdc_hostname = strdup(hostname); if (!ipactx->kdc_hostname) { ret = ENOMEM; goto fail;