Easier to use ipa_gethostfqdn()

ipa_gethostfqdn() now returns a pointer to a statically allocated buffer
or NULL in case of an error. The caller no longer has to supply a
correctly allocated buffer.

Rename IPA_HOST_HOST to_LEN IPA_HOST_FQDN_LEN and use IPA_HOST_FQDN_LEN
wherever code copies a hostname supplied from ipa_gethostfqdn().

Clarify that MAXHOSTNAMELEN and MAXHOSTFQDNLEN are different things.

Signed-off-by: Christian Heimes <cheimes@redhat.com>
Reviewed-By: Fraser Tweedale <ftweedal@redhat.com>
This commit is contained in:
Christian Heimes 2020-09-18 13:11:28 +02:00 committed by Fraser Tweedale
parent 3d796a7e51
commit 727a2ffb93
12 changed files with 54 additions and 79 deletions

View File

@ -1445,7 +1445,6 @@ main(int argc, const char **argv) {
static const char *keytab = NULL; static const char *keytab = NULL;
static const char *bindpw = NULL; static const char *bindpw = NULL;
static const char *basedn = NULL; static const char *basedn = NULL;
char fqdn[IPA_HOST_NAME_LEN];
int quiet = 0; int quiet = 0;
int unenroll = 0; int unenroll = 0;
int force = 0; int force = 0;
@ -1498,12 +1497,12 @@ main(int argc, const char **argv) {
/* auto-detect and verify hostname */ /* auto-detect and verify hostname */
if (!hostname) { if (!hostname) {
if (ipa_gethostname(fqdn) != 0) { hostname = ipa_gethostfqdn();
if (hostname == NULL) {
if (!quiet) if (!quiet)
fprintf(stderr, _("Cannot get host's FQDN!\n")); fprintf(stderr, _("Cannot get host's FQDN!\n"));
exit(22); exit(22);
} }
hostname = fqdn;
} }
if (NULL == strstr(hostname, ".")) { if (NULL == strstr(hostname, ".")) {
if (!quiet) { if (!quiet) {

View File

@ -53,7 +53,7 @@ static void ipadb_context_free(krb5_context kcontext,
free((*ctx)->base); free((*ctx)->base);
free((*ctx)->realm_base); free((*ctx)->realm_base);
free((*ctx)->accounts_base); free((*ctx)->accounts_base);
free((*ctx)->kdc_hostname); /* kdc_hostname is a pointer to a static char[] */
/* ldap free lcontext */ /* ldap free lcontext */
if ((*ctx)->lcontext) { if ((*ctx)->lcontext) {
ldap_unbind_ext_s((*ctx)->lcontext, NULL, NULL); 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; struct ipadb_context *ipactx;
krb5_error_code kerr; krb5_error_code kerr;
char hostname[IPA_HOST_NAME_LEN];
int ret; int ret;
int i; int i;
@ -604,14 +603,9 @@ static krb5_error_code ipadb_init_module(krb5_context kcontext,
goto fail; goto fail;
} }
ret = ipa_gethostfqdn(hostname); ipactx->kdc_hostname = ipa_gethostfqdn();
if (ret != 0) {
ret = errno;
goto fail;
}
ipactx->kdc_hostname = strdup(hostname);
if (!ipactx->kdc_hostname) { if (!ipactx->kdc_hostname) {
ret = ENOMEM; ret = errno;
goto fail; goto fail;
} }

View File

@ -49,10 +49,6 @@
#include "ipa_krb5.h" #include "ipa_krb5.h"
#include "ipa_pwd.h" #include "ipa_pwd.h"
#ifndef MAXHOSTNAMELEN
#define MAXHOSTNAMELEN 64
#endif
/* easier to copy the defines here than to mess with kadm5/admin.h /* easier to copy the defines here than to mess with kadm5/admin.h
* for now */ * for now */
#define KMASK_PRINCIPAL 0x000001 #define KMASK_PRINCIPAL 0x000001
@ -119,7 +115,7 @@ struct ipadb_context {
char *realm; char *realm;
char *realm_base; char *realm_base;
char *accounts_base; char *accounts_base;
char *kdc_hostname; const char *kdc_hostname;
LDAP *lcontext; LDAP *lcontext;
krb5_context kcontext; krb5_context kcontext;
bool override_restrictions; bool override_restrictions;

View File

@ -22,6 +22,7 @@
#include "config.h" #include "config.h"
#include "ipa_hostname.h"
#include "ipa_kdb.h" #include "ipa_kdb.h"
#include "ipa_mspac.h" #include "ipa_mspac.h"
#include <talloc.h> #include <talloc.h>
@ -2351,12 +2352,10 @@ done:
static char *get_server_netbios_name(struct ipadb_context *ipactx) 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; char *p;
strncpy(hostname, ipactx->kdc_hostname, MAXHOSTNAMELEN); strncpy(hostname, ipactx->kdc_hostname, IPA_HOST_FQDN_LEN);
/* May miss termination */
hostname[MAXHOSTNAMELEN] = '\0';
for (p = hostname; *p; p++) { for (p = hostname; *p; p++) {
if (*p == '.') { if (*p == '.') {
*p = 0; *p = 0;

View File

@ -213,7 +213,8 @@ static krb5_error_code setup_ldap(const char *uri, krb5_boolean bind,
int main(int argc, char **argv) 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_error_code retval;
krb5_data hndata; krb5_data hndata;
verto_ev *sig; verto_ev *sig;
@ -228,10 +229,12 @@ int main(int argc, char **argv)
memset(&ctx, 0, sizeof(ctx)); memset(&ctx, 0, sizeof(ctx));
ctx.exitstatus = 1; ctx.exitstatus = 1;
if (ipa_gethostfqdn(hostname) < 0) { hostname = ipa_gethostfqdn();
if (hostname == NULL) {
otpd_log_err(errno, "Unable to get hostname"); otpd_log_err(errno, "Unable to get hostname");
goto error; goto error;
} }
strncpy(fqdn, hostname, IPA_HOST_FQDN_LEN);
retval = krb5_init_context(&ctx.kctx); retval = krb5_init_context(&ctx.kctx);
if (retval != 0) { if (retval != 0) {
@ -253,7 +256,7 @@ int main(int argc, char **argv)
} }
/* Set NAS-Identifier. */ /* Set NAS-Identifier. */
hndata.data = hostname; hndata.data = fqdn;
hndata.length = strlen(hndata.data); hndata.length = strlen(hndata.data);
retval = krad_attrset_add(ctx.attrs, krad_attr_name2num("NAS-Identifier"), retval = krad_attrset_add(ctx.attrs, krad_attr_name2num("NAS-Identifier"),
&hndata); &hndata);

View File

@ -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) static NTSTATUS save_sid_to_secret(struct ipasam_private *ipasam_state)
{ {
char hostname[IPA_HOST_NAME_LEN]; const char *hostname;
int ret;
char *p; char *p;
TALLOC_CTX *tmp_ctx; TALLOC_CTX *tmp_ctx;
NTSTATUS status = NT_STATUS_UNSUCCESSFUL; NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
@ -4467,8 +4466,8 @@ static NTSTATUS save_sid_to_secret(struct ipasam_private *ipasam_state)
goto done; goto done;
} }
ret = ipa_gethostfqdn(hostname); hostname = ipa_gethostfqdn();
if (ret == -1) { if (hostname == NULL) {
DEBUG(1, ("ipa_gethostfqdn failed.\n")); DEBUG(1, ("ipa_gethostfqdn failed.\n"));
status = NT_STATUS_UNSUCCESSFUL; status = NT_STATUS_UNSUCCESSFUL;
goto done; 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) { static NTSTATUS ipasam_generate_principals(struct ipasam_private *ipasam_state) {
krb5_error_code rc; krb5_error_code rc;
int ret;
krb5_context context; krb5_context context;
NTSTATUS status = NT_STATUS_UNSUCCESSFUL; NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
char hostname[IPA_HOST_NAME_LEN]; const char *hostname;
char *default_realm = NULL; char *default_realm = NULL;
if (!ipasam_state) { if (!ipasam_state) {
@ -4736,8 +4734,8 @@ static NTSTATUS ipasam_generate_principals(struct ipasam_private *ipasam_state)
return status; return status;
} }
ret = ipa_gethostfqdn(hostname); hostname = ipa_gethostfqdn();
if (ret == -1) { if (hostname == NULL) {
DEBUG(1, ("ipa_gethostfqdn failed.\n")); DEBUG(1, ("ipa_gethostfqdn failed.\n"));
goto done; goto done;
} }

View File

@ -61,10 +61,6 @@
#define MAX_DG_SIZE 4096 #define MAX_DG_SIZE 4096
#define NETBIOS_NAME_MAX 15 #define NETBIOS_NAME_MAX 15
#ifndef MAXHOSTNAMELEN
#define MAXHOSTNAMELEN 64
#endif
struct ipa_cldap_ctx { struct ipa_cldap_ctx {
Slapi_ComponentId *plugin_id; Slapi_ComponentId *plugin_id;
pthread_t tid; pthread_t tid;

View File

@ -157,7 +157,7 @@ char *make_netbios_name(TALLOC_CTX *mem_ctx, const char *s)
#define NETLOGON_SAM_LOGON_RESPONSE_EX_pusher \ #define NETLOGON_SAM_LOGON_RESPONSE_EX_pusher \
(ndr_push_flags_fn_t)ndr_push_NETLOGON_SAM_LOGON_RESPONSE_EX_with_flags (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, char *guid, char *sid, char *name,
uint32_t ntver, struct berval *reply) 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 ipa_cldap_req *req,
struct berval *reply) struct berval *reply)
{ {
char hostname[IPA_HOST_NAME_LEN]; const char *hostname;
char *domain = NULL; char *domain = NULL;
char *our_domain = NULL; char *our_domain = NULL;
char *guid = NULL; char *guid = NULL;
@ -322,8 +322,8 @@ int ipa_cldap_netlogon(struct ipa_cldap_ctx *ctx,
goto done; goto done;
} }
ret = ipa_gethostfqdn(hostname); hostname = ipa_gethostfqdn();
if (ret == -1) { if (hostname == NULL) {
ret = errno; ret = errno;
goto done; goto done;
} }

View File

@ -313,7 +313,10 @@ RA_AGENT_PROFILE = 'caSubsystemCert'
CA_DBUS_TIMEOUT = 120 CA_DBUS_TIMEOUT = 120
# Maximum hostname length in Linux # Maximum hostname length in Linux
# It's the max length of uname's nodename and return value of gethostname().
MAXHOSTNAMELEN = 64 MAXHOSTNAMELEN = 64
# DNS name is 255 octets, effectively 253 ASCII characters.
MAXHOSTFQDNLEN = 253
# regexp definitions # regexp definitions
PATTERN_GROUPUSER_NAME = ( PATTERN_GROUPUSER_NAME = (

View File

@ -9,6 +9,9 @@ import socket
def gethostfqdn(): def gethostfqdn():
"""Get the fully qualified domain name of current host from glibc """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 :return: FQDN as str
""" """
hostname = socket.gethostname() hostname = socket.gethostname()
@ -26,4 +29,5 @@ def gethostfqdn():
flags=socket.AI_CANONNAME | socket.AI_ADDRCONFIG flags=socket.AI_CANONNAME | socket.AI_ADDRCONFIG
) )
# first addrinfo struct, fourth field is canonical name # first addrinfo struct, fourth field is canonical name
# getaddrinfo() either raises an exception or returns at least one entry
return gai[0][3] return gai[0][3]

View File

@ -7,37 +7,25 @@
#define _GNU_SOURCE #define _GNU_SOURCE
#endif #endif
#include <netdb.h>
#include <errno.h> #include <errno.h>
#include <netdb.h>
#include <string.h> #include <string.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <unistd.h>
#include "ipa_hostname.h" #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 static int
_get_fqdn(char *fqdn) _get_fqdn(char *fqdn)
{ {
char hostname[IPA_HOST_NAME_LEN]; char hostname[IPA_HOST_FQDN_LEN];
char *canonname = NULL; char *canonname = NULL;
struct addrinfo hints; struct addrinfo hints;
struct addrinfo *ai = NULL; struct addrinfo *ai = NULL;
int r; int r;
r = ipa_gethostname(hostname); r = gethostname(hostname, IPA_HOST_FQDN_LEN - 1);
if (r != 0) { if (r != 0) {
goto error; goto error;
} }
@ -69,7 +57,7 @@ _get_fqdn(char *fqdn)
errno = ENOENT; errno = ENOENT;
goto error; goto error;
} }
if (strlen(canonname) >= IPA_HOST_NAME_LEN) { if (strlen(canonname) > (IPA_HOST_FQDN_LEN - 1)) {
errno = ENAMETOOLONG; errno = ENAMETOOLONG;
goto error; goto error;
} }
@ -82,30 +70,29 @@ _get_fqdn(char *fqdn)
} }
#endif #endif
strcpy(fqdn, canonname); strncpy(fqdn, canonname, IPA_HOST_FQDN_LEN);
/* Make double sure it is terminated */ /* Make double sure it is terminated */
fqdn[IPA_HOST_NAME_LEN - 1] = '\0'; fqdn[IPA_HOST_FQDN_LEN - 1] = '\0';
freeaddrinfo(ai); freeaddrinfo(ai);
return 0; return 0;
error: error:
fqdn[0] = '\0';
if (ai != NULL) { if (ai != NULL) {
freeaddrinfo(ai); freeaddrinfo(ai);
} }
return -1; 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); int res = _get_fqdn(cached_fqdn);
if (res != 0) { if (res != 0) {
return -1; return NULL;
} }
} }
strcpy(name, cached_fqdn); return (const char*)cached_fqdn;
return 0;
} }

View File

@ -2,18 +2,14 @@
* Copyright (C) 2020 FreeIPA Contributors see COPYING for license * Copyright (C) 2020 FreeIPA Contributors see COPYING for license
*/ */
#include <limits.h> /* FQDN host name length including trailing NULL byte
#include <unistd.h>
/*
* host name length including 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 const char*
ipa_gethostname(char *name); ipa_gethostfqdn(void);
int
ipa_gethostfqdn(char *name);