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 *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) {

View File

@ -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;
}

View File

@ -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;

View File

@ -22,6 +22,7 @@
#include "config.h"
#include "ipa_hostname.h"
#include "ipa_kdb.h"
#include "ipa_mspac.h"
#include <talloc.h>
@ -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;

View File

@ -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);

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)
{
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;
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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 = (

View File

@ -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]

View File

@ -7,37 +7,25 @@
#define _GNU_SOURCE
#endif
#include <netdb.h>
#include <errno.h>
#include <netdb.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.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
_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;
}

View File

@ -2,18 +2,14 @@
* Copyright (C) 2020 FreeIPA Contributors see COPYING for license
*/
#include <limits.h>
#include <unistd.h>
/*
* 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);