summaryrefslogtreecommitdiff
path: root/lib/util
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2009-09-15 07:42:54 -0700
committerAndrew Bartlett <abartlet@samba.org>2009-09-15 07:42:54 -0700
commit668470c9923364c6c43afbf94162b549c8baef9a (patch)
tree43584485ac1a94195b201bc7fd5f2da80acfacda /lib/util
parentf07e77e13ff86c76644660e2d574e663c9ffdeb8 (diff)
downloadsamba-668470c9923364c6c43afbf94162b549c8baef9a.tar.gz
samba-668470c9923364c6c43afbf94162b549c8baef9a.tar.bz2
samba-668470c9923364c6c43afbf94162b549c8baef9a.zip
libcli:nbt make the lmhosts parsing code and dependicies common
This starts the process to have Samba4 use lmhosts. Andrew Bartlett
Diffstat (limited to 'lib/util')
-rw-r--r--lib/util/util.h22
-rw-r--r--lib/util/util_net.c118
2 files changed, 138 insertions, 2 deletions
diff --git a/lib/util/util.h b/lib/util/util.h
index c0e87a2705..8438602cc6 100644
--- a/lib/util/util.h
+++ b/lib/util/util.h
@@ -21,7 +21,7 @@
#ifndef _SAMBA_UTIL_H_
#define _SAMBA_UTIL_H_
-#include <netinet/in.h>
+#include "system/network.h"
#if _SAMBA_BUILD_ == 4
#include "../lib/util/charset/charset.h"
@@ -842,4 +842,24 @@ bool add_uid_to_array_unique(TALLOC_CTX *mem_ctx, uid_t uid,
bool add_gid_to_array_unique(TALLOC_CTX *mem_ctx, gid_t gid,
gid_t **gids, size_t *num_gids);
+/* The following definitions come from lib/util/util_net.c */
+
+void zero_sockaddr(struct sockaddr_storage *pss);
+
+bool interpret_string_addr_internal(struct addrinfo **ppres,
+ const char *str, int flags);
+
+bool interpret_string_addr(struct sockaddr_storage *pss,
+ const char *str,
+ int flags);
+
+/*******************************************************************
+ Map a text hostname or IP address (IPv4 or IPv6) into a
+ struct sockaddr_storage. Version that prefers IPv4.
+******************************************************************/
+
+bool interpret_string_addr_prefer_ipv4(struct sockaddr_storage *pss,
+ const char *str,
+ int flags);
+
#endif /* _SAMBA_UTIL_H_ */
diff --git a/lib/util/util_net.c b/lib/util/util_net.c
index d1dadc2494..0ce495e57c 100644
--- a/lib/util/util_net.c
+++ b/lib/util/util_net.c
@@ -3,10 +3,11 @@
Samba utility functions
Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2008
Copyright (C) Andrew Tridgell 1992-1998
- Copyright (C) Jeremy Allison 2001-2007
+ Copyright (C) Jeremy Allison 1992-2007
Copyright (C) Simo Sorce 2001
Copyright (C) Jim McDonough (jmcd@us.ibm.com) 2003.
Copyright (C) James J Myers 2003
+ Copyright (C) Tim Potter 2000-2001
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -28,6 +29,17 @@
#include "system/filesys.h"
#undef strcasecmp
+/*******************************************************************
+ Set an address to INADDR_ANY.
+******************************************************************/
+
+void zero_sockaddr(struct sockaddr_storage *pss)
+{
+ memset(pss, '\0', sizeof(*pss));
+ /* Ensure we're at least a valid sockaddr-storage. */
+ pss->ss_family = AF_INET;
+}
+
/**
* Wrap getaddrinfo...
*/
@@ -59,6 +71,110 @@ bool interpret_string_addr_internal(struct addrinfo **ppres,
return true;
}
+/*******************************************************************
+ Map a text hostname or IP address (IPv4 or IPv6) into a
+ struct sockaddr_storage. Takes a flag which allows it to
+ prefer an IPv4 address (needed for DC's).
+******************************************************************/
+
+static bool interpret_string_addr_pref(struct sockaddr_storage *pss,
+ const char *str,
+ int flags,
+ bool prefer_ipv4)
+{
+ struct addrinfo *res = NULL;
+#if defined(HAVE_IPV6)
+ char addr[INET6_ADDRSTRLEN];
+ unsigned int scope_id = 0;
+
+ if (strchr_m(str, ':')) {
+ char *p = strchr_m(str, '%');
+
+ /*
+ * Cope with link-local.
+ * This is IP:v6:addr%ifname.
+ */
+
+ if (p && (p > str) && ((scope_id = if_nametoindex(p+1)) != 0)) {
+ strlcpy(addr, str,
+ MIN(PTR_DIFF(p,str)+1,
+ sizeof(addr)));
+ str = addr;
+ }
+ }
+#endif
+
+ zero_sockaddr(pss);
+
+ if (!interpret_string_addr_internal(&res, str, flags|AI_ADDRCONFIG)) {
+ return false;
+ }
+ if (!res) {
+ return false;
+ }
+
+ if (prefer_ipv4) {
+ struct addrinfo *p;
+
+ for (p = res; p; p = p->ai_next) {
+ if (p->ai_family == AF_INET) {
+ memcpy(pss, p->ai_addr, p->ai_addrlen);
+ break;
+ }
+ }
+ if (p == NULL) {
+ /* Copy the first sockaddr. */
+ memcpy(pss, res->ai_addr, res->ai_addrlen);
+ }
+ } else {
+ /* Copy the first sockaddr. */
+ memcpy(pss, res->ai_addr, res->ai_addrlen);
+ }
+
+#if defined(HAVE_IPV6)
+ if (pss->ss_family == AF_INET6 && scope_id) {
+ struct sockaddr_in6 *ps6 = (struct sockaddr_in6 *)pss;
+ if (IN6_IS_ADDR_LINKLOCAL(&ps6->sin6_addr) &&
+ ps6->sin6_scope_id == 0) {
+ ps6->sin6_scope_id = scope_id;
+ }
+ }
+#endif
+
+ freeaddrinfo(res);
+ return true;
+}
+
+/*******************************************************************
+ Map a text hostname or IP address (IPv4 or IPv6) into a
+ struct sockaddr_storage. Address agnostic version.
+******************************************************************/
+
+bool interpret_string_addr(struct sockaddr_storage *pss,
+ const char *str,
+ int flags)
+{
+ return interpret_string_addr_pref(pss,
+ str,
+ flags,
+ false);
+}
+
+/*******************************************************************
+ Map a text hostname or IP address (IPv4 or IPv6) into a
+ struct sockaddr_storage. Version that prefers IPv4.
+******************************************************************/
+
+bool interpret_string_addr_prefer_ipv4(struct sockaddr_storage *pss,
+ const char *str,
+ int flags)
+{
+ return interpret_string_addr_pref(pss,
+ str,
+ flags,
+ true);
+}
+
/**
* Interpret an internet address or name into an IP address in 4 byte form.
* RETURNS IN NETWORK BYTE ORDER (big endian).