diff --git a/client/ipa-join.c b/client/ipa-join.c index 5e8b91dfe..d98739a9a 100644 --- a/client/ipa-join.c +++ b/client/ipa-join.c @@ -1445,7 +1445,6 @@ 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; @@ -1498,12 +1497,12 @@ main(int argc, const char **argv) { /* auto-detect and verify hostname */ if (!hostname) { - if (ipa_gethostname(fqdn) != 0) { + hostname = ipa_gethostfqdn(); + if (hostname == NULL) { if (!quiet) fprintf(stderr, _("Cannot get host's FQDN!\n")); exit(22); } - hostname = fqdn; } if (NULL == strstr(hostname, ".")) { if (!quiet) { diff --git a/daemons/ipa-kdb/ipa_kdb.c b/daemons/ipa-kdb/ipa_kdb.c index aee463c48..43ba955ac 100644 --- a/daemons/ipa-kdb/ipa_kdb.c +++ b/daemons/ipa-kdb/ipa_kdb.c @@ -53,7 +53,7 @@ static void ipadb_context_free(krb5_context kcontext, free((*ctx)->base); free((*ctx)->realm_base); free((*ctx)->accounts_base); - free((*ctx)->kdc_hostname); + /* kdc_hostname is a pointer to a static char[] */ /* ldap free lcontext */ if ((*ctx)->lcontext) { ldap_unbind_ext_s((*ctx)->lcontext, NULL, NULL); @@ -536,7 +536,6 @@ 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; @@ -604,14 +603,9 @@ static krb5_error_code ipadb_init_module(krb5_context kcontext, goto fail; } - ret = ipa_gethostfqdn(hostname); - if (ret != 0) { - ret = errno; - goto fail; - } - ipactx->kdc_hostname = strdup(hostname); + ipactx->kdc_hostname = ipa_gethostfqdn(); if (!ipactx->kdc_hostname) { - ret = ENOMEM; + ret = errno; goto fail; } diff --git a/daemons/ipa-kdb/ipa_kdb.h b/daemons/ipa-kdb/ipa_kdb.h index 3e9b24a53..66a1d74f1 100644 --- a/daemons/ipa-kdb/ipa_kdb.h +++ b/daemons/ipa-kdb/ipa_kdb.h @@ -49,10 +49,6 @@ #include "ipa_krb5.h" #include "ipa_pwd.h" -#ifndef MAXHOSTNAMELEN -#define MAXHOSTNAMELEN 64 -#endif - /* easier to copy the defines here than to mess with kadm5/admin.h * for now */ #define KMASK_PRINCIPAL 0x000001 @@ -119,7 +115,7 @@ struct ipadb_context { char *realm; char *realm_base; char *accounts_base; - char *kdc_hostname; + const char *kdc_hostname; LDAP *lcontext; krb5_context kcontext; bool override_restrictions; diff --git a/daemons/ipa-kdb/ipa_kdb_mspac.c b/daemons/ipa-kdb/ipa_kdb_mspac.c index 2f1480a95..498bef7a7 100644 --- a/daemons/ipa-kdb/ipa_kdb_mspac.c +++ b/daemons/ipa-kdb/ipa_kdb_mspac.c @@ -22,6 +22,7 @@ #include "config.h" +#include "ipa_hostname.h" #include "ipa_kdb.h" #include "ipa_mspac.h" #include @@ -2351,12 +2352,10 @@ done: static char *get_server_netbios_name(struct ipadb_context *ipactx) { - char hostname[MAXHOSTNAMELEN + 1]; /* NOTE: this is 64, too little ? */ + char hostname[IPA_HOST_FQDN_LEN]; /* NOTE: long enough for DNS name */ char *p; - strncpy(hostname, ipactx->kdc_hostname, MAXHOSTNAMELEN); - /* May miss termination */ - hostname[MAXHOSTNAMELEN] = '\0'; + strncpy(hostname, ipactx->kdc_hostname, IPA_HOST_FQDN_LEN); for (p = hostname; *p; p++) { if (*p == '.') { *p = 0; diff --git a/daemons/ipa-otpd/main.c b/daemons/ipa-otpd/main.c index 1538cb861..2efb371ee 100644 --- a/daemons/ipa-otpd/main.c +++ b/daemons/ipa-otpd/main.c @@ -213,7 +213,8 @@ static krb5_error_code setup_ldap(const char *uri, krb5_boolean bind, int main(int argc, char **argv) { - char hostname[IPA_HOST_NAME_LEN]; + const char *hostname; + char fqdn[IPA_HOST_FQDN_LEN]; krb5_error_code retval; krb5_data hndata; verto_ev *sig; @@ -228,10 +229,12 @@ int main(int argc, char **argv) memset(&ctx, 0, sizeof(ctx)); ctx.exitstatus = 1; - if (ipa_gethostfqdn(hostname) < 0) { + hostname = ipa_gethostfqdn(); + if (hostname == NULL) { otpd_log_err(errno, "Unable to get hostname"); goto error; } + strncpy(fqdn, hostname, IPA_HOST_FQDN_LEN); retval = krb5_init_context(&ctx.kctx); if (retval != 0) { @@ -253,7 +256,7 @@ int main(int argc, char **argv) } /* Set NAS-Identifier. */ - hndata.data = hostname; + hndata.data = fqdn; hndata.length = strlen(hndata.data); retval = krad_attrset_add(ctx.attrs, krad_attr_name2num("NAS-Identifier"), &hndata); diff --git a/daemons/ipa-sam/ipa_sam.c b/daemons/ipa-sam/ipa_sam.c index 7741955fd..6993152e7 100644 --- a/daemons/ipa-sam/ipa_sam.c +++ b/daemons/ipa-sam/ipa_sam.c @@ -4441,8 +4441,7 @@ static char *sec_key(TALLOC_CTX *mem_ctx, const char *d) static NTSTATUS save_sid_to_secret(struct ipasam_private *ipasam_state) { - char hostname[IPA_HOST_NAME_LEN]; - int ret; + const char *hostname; char *p; TALLOC_CTX *tmp_ctx; NTSTATUS status = NT_STATUS_UNSUCCESSFUL; @@ -4467,8 +4466,8 @@ static NTSTATUS save_sid_to_secret(struct ipasam_private *ipasam_state) goto done; } - ret = ipa_gethostfqdn(hostname); - if (ret == -1) { + hostname = ipa_gethostfqdn(); + if (hostname == NULL) { DEBUG(1, ("ipa_gethostfqdn failed.\n")); status = NT_STATUS_UNSUCCESSFUL; goto done; @@ -4721,10 +4720,9 @@ static int bind_callback(LDAP *ldap_struct, struct smbldap_state *ldap_state, vo static NTSTATUS ipasam_generate_principals(struct ipasam_private *ipasam_state) { krb5_error_code rc; - int ret; krb5_context context; NTSTATUS status = NT_STATUS_UNSUCCESSFUL; - char hostname[IPA_HOST_NAME_LEN]; + const char *hostname; char *default_realm = NULL; if (!ipasam_state) { @@ -4736,8 +4734,8 @@ static NTSTATUS ipasam_generate_principals(struct ipasam_private *ipasam_state) return status; } - ret = ipa_gethostfqdn(hostname); - if (ret == -1) { + hostname = ipa_gethostfqdn(); + if (hostname == NULL) { DEBUG(1, ("ipa_gethostfqdn failed.\n")); goto done; } diff --git a/daemons/ipa-slapi-plugins/ipa-cldap/ipa_cldap.h b/daemons/ipa-slapi-plugins/ipa-cldap/ipa_cldap.h index a3ebfbfe2..bbed80fd3 100644 --- a/daemons/ipa-slapi-plugins/ipa-cldap/ipa_cldap.h +++ b/daemons/ipa-slapi-plugins/ipa-cldap/ipa_cldap.h @@ -61,10 +61,6 @@ #define MAX_DG_SIZE 4096 #define NETBIOS_NAME_MAX 15 -#ifndef MAXHOSTNAMELEN -#define MAXHOSTNAMELEN 64 -#endif - struct ipa_cldap_ctx { Slapi_ComponentId *plugin_id; pthread_t tid; diff --git a/daemons/ipa-slapi-plugins/ipa-cldap/ipa_cldap_netlogon.c b/daemons/ipa-slapi-plugins/ipa-cldap/ipa_cldap_netlogon.c index eb0d18315..6cfe1e3f5 100644 --- a/daemons/ipa-slapi-plugins/ipa-cldap/ipa_cldap_netlogon.c +++ b/daemons/ipa-slapi-plugins/ipa-cldap/ipa_cldap_netlogon.c @@ -157,7 +157,7 @@ char *make_netbios_name(TALLOC_CTX *mem_ctx, const char *s) #define NETLOGON_SAM_LOGON_RESPONSE_EX_pusher \ (ndr_push_flags_fn_t)ndr_push_NETLOGON_SAM_LOGON_RESPONSE_EX_with_flags -static int ipa_cldap_encode_netlogon(char *fq_hostname, char *domain, +static int ipa_cldap_encode_netlogon(const char *fq_hostname, char *domain, char *guid, char *sid, char *name, uint32_t ntver, struct berval *reply) { @@ -237,7 +237,7 @@ int ipa_cldap_netlogon(struct ipa_cldap_ctx *ctx, struct ipa_cldap_req *req, struct berval *reply) { - char hostname[IPA_HOST_NAME_LEN]; + const char *hostname; char *domain = NULL; char *our_domain = NULL; char *guid = NULL; @@ -322,8 +322,8 @@ int ipa_cldap_netlogon(struct ipa_cldap_ctx *ctx, goto done; } - ret = ipa_gethostfqdn(hostname); - if (ret == -1) { + hostname = ipa_gethostfqdn(); + if (hostname == NULL) { ret = errno; goto done; } diff --git a/ipalib/constants.py b/ipalib/constants.py index ae5291c04..a622f640b 100644 --- a/ipalib/constants.py +++ b/ipalib/constants.py @@ -313,7 +313,10 @@ RA_AGENT_PROFILE = 'caSubsystemCert' CA_DBUS_TIMEOUT = 120 # Maximum hostname length in Linux +# It's the max length of uname's nodename and return value of gethostname(). MAXHOSTNAMELEN = 64 +# DNS name is 255 octets, effectively 253 ASCII characters. +MAXHOSTFQDNLEN = 253 # regexp definitions PATTERN_GROUPUSER_NAME = ( diff --git a/ipapython/fqdn.py b/ipapython/fqdn.py index 37c9291c4..321e86dd1 100644 --- a/ipapython/fqdn.py +++ b/ipapython/fqdn.py @@ -9,6 +9,9 @@ import socket def gethostfqdn(): """Get the fully qualified domain name of current host from glibc + This function may return an FQDN with up to MAXHOSTFQDNLEN characters + (253). The effective hostname is still limited to MAXHOSTNAMELEN (64). + :return: FQDN as str """ hostname = socket.gethostname() @@ -26,4 +29,5 @@ def gethostfqdn(): flags=socket.AI_CANONNAME | socket.AI_ADDRCONFIG ) # first addrinfo struct, fourth field is canonical name + # getaddrinfo() either raises an exception or returns at least one entry return gai[0][3] diff --git a/util/ipa_hostname.c b/util/ipa_hostname.c index 97fe54cc6..29c939b9e 100644 --- a/util/ipa_hostname.c +++ b/util/ipa_hostname.c @@ -7,37 +7,25 @@ #define _GNU_SOURCE #endif -#include #include +#include #include #include #include +#include #include "ipa_hostname.h" -int -ipa_gethostname(char *name) -{ - int ret; - - ret = gethostname(name, IPA_HOST_NAME_LEN - 1); - - /* Make double sure it is terminated */ - name[IPA_HOST_NAME_LEN - 1] = '\0'; - - return ret; -} - static int _get_fqdn(char *fqdn) { - char hostname[IPA_HOST_NAME_LEN]; + char hostname[IPA_HOST_FQDN_LEN]; char *canonname = NULL; struct addrinfo hints; struct addrinfo *ai = NULL; int r; - r = ipa_gethostname(hostname); + r = gethostname(hostname, IPA_HOST_FQDN_LEN - 1); if (r != 0) { goto error; } @@ -69,7 +57,7 @@ _get_fqdn(char *fqdn) errno = ENOENT; goto error; } - if (strlen(canonname) >= IPA_HOST_NAME_LEN) { + if (strlen(canonname) > (IPA_HOST_FQDN_LEN - 1)) { errno = ENAMETOOLONG; goto error; } @@ -82,30 +70,29 @@ _get_fqdn(char *fqdn) } #endif - strcpy(fqdn, canonname); + strncpy(fqdn, canonname, IPA_HOST_FQDN_LEN); /* Make double sure it is terminated */ - fqdn[IPA_HOST_NAME_LEN - 1] = '\0'; + fqdn[IPA_HOST_FQDN_LEN - 1] = '\0'; freeaddrinfo(ai); return 0; error: - fqdn[0] = '\0'; if (ai != NULL) { freeaddrinfo(ai); } return -1; } -int ipa_gethostfqdn(char *name) -{ - static char cached_fqdn[IPA_HOST_NAME_LEN] = {0}; - if (!cached_fqdn) { +const char* ipa_gethostfqdn() +{ + static char cached_fqdn[IPA_HOST_FQDN_LEN] = {0}; + + if (*cached_fqdn == '\0') { int res = _get_fqdn(cached_fqdn); if (res != 0) { - return -1; + return NULL; } } - strcpy(name, cached_fqdn); - return 0; + return (const char*)cached_fqdn; } diff --git a/util/ipa_hostname.h b/util/ipa_hostname.h index 75c10a5dc..f98da69a4 100644 --- a/util/ipa_hostname.h +++ b/util/ipa_hostname.h @@ -2,18 +2,14 @@ * Copyright (C) 2020 FreeIPA Contributors see COPYING for license */ -#include -#include - -/* - * host name length including NULL byte +/* FQDN host name length including trailing NULL byte * - * NOTE: length hardcoded in kernel + * This may be longer than HOST_NAME_MAX. The hostname (effectively uname()'s + * node name) is limited to 64 characters on Linux. ipa_gethostfqdn() returns + * a FQDN from NSS which can be up to 255 octets including NULL byte. + * Effectively the FQDN is 253 ASCII characters. */ -#define IPA_HOST_NAME_LEN (HOST_NAME_MAX + 1) +#define IPA_HOST_FQDN_LEN 255 -int -ipa_gethostname(char *name); - -int -ipa_gethostfqdn(char *name); +const char* +ipa_gethostfqdn(void);