1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-23 17:34:34 +03:00

r8310: replace the heimdal networking interface scanning code with glue code that uses the Samba

interfaces list. This makes heimdal obey the 'interfaces=' smb.conf option, and should also
fix the portability problems with the heimdal code
This commit is contained in:
Andrew Tridgell 2005-07-11 03:52:31 +00:00 committed by Gerald (Jerry) Carter
parent b5e8409e3b
commit ba621d1c55
4 changed files with 59 additions and 1481 deletions

View File

@ -1,291 +0,0 @@
/*
* Copyright (c) 1997 - 2002 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include "krb5_locl.h"
RCSID("$Id: get_addrs.c,v 1.46 2004/05/25 21:26:05 lha Exp $");
#ifdef __osf__
/* hate */
struct rtentry;
struct mbuf;
#endif
#ifdef HAVE_NET_IF_H
#include <net/if.h>
#endif
#include <ifaddrs.h>
static krb5_error_code
gethostname_fallback (krb5_context context, krb5_addresses *res)
{
krb5_error_code ret;
char hostname[MAXHOSTNAMELEN];
struct hostent *hostent;
if (gethostname (hostname, sizeof(hostname))) {
ret = errno;
krb5_set_error_string (context, "gethostname: %s", strerror(ret));
return ret;
}
hostent = roken_gethostbyname (hostname);
if (hostent == NULL) {
ret = errno;
krb5_set_error_string (context, "gethostbyname %s: %s",
hostname, strerror(ret));
return ret;
}
res->len = 1;
res->val = malloc (sizeof(*res->val));
if (res->val == NULL) {
krb5_set_error_string(context, "malloc: out of memory");
return ENOMEM;
}
res->val[0].addr_type = hostent->h_addrtype;
res->val[0].address.data = NULL;
res->val[0].address.length = 0;
ret = krb5_data_copy (&res->val[0].address,
hostent->h_addr,
hostent->h_length);
if (ret) {
free (res->val);
return ret;
}
return 0;
}
enum {
LOOP = 1, /* do include loopback interfaces */
LOOP_IF_NONE = 2, /* include loopback if no other if's */
EXTRA_ADDRESSES = 4, /* include extra addresses */
SCAN_INTERFACES = 8 /* scan interfaces for addresses */
};
/*
* Try to figure out the addresses of all configured interfaces with a
* lot of magic ioctls.
*/
static krb5_error_code
find_all_addresses (krb5_context context, krb5_addresses *res, int flags)
{
struct sockaddr sa_zero;
struct ifaddrs *ifa0, *ifa;
krb5_error_code ret = ENXIO;
int num, idx;
krb5_addresses ignore_addresses;
res->val = NULL;
if (getifaddrs(&ifa0) == -1) {
ret = errno;
krb5_set_error_string(context, "getifaddrs: %s", strerror(ret));
return (ret);
}
memset(&sa_zero, 0, sizeof(sa_zero));
/* First, count all the ifaddrs. */
for (ifa = ifa0, num = 0; ifa != NULL; ifa = ifa->ifa_next, num++)
/* nothing */;
if (num == 0) {
freeifaddrs(ifa0);
krb5_set_error_string(context, "no addresses found");
return (ENXIO);
}
if (flags & EXTRA_ADDRESSES) {
/* we'll remove the addresses we don't care about */
ret = krb5_get_ignore_addresses(context, &ignore_addresses);
if(ret)
return ret;
}
/* Allocate storage for them. */
res->val = calloc(num, sizeof(*res->val));
if (res->val == NULL) {
krb5_free_addresses(context, &ignore_addresses);
freeifaddrs(ifa0);
krb5_set_error_string (context, "malloc: out of memory");
return (ENOMEM);
}
/* Now traverse the list. */
for (ifa = ifa0, idx = 0; ifa != NULL; ifa = ifa->ifa_next) {
if ((ifa->ifa_flags & IFF_UP) == 0)
continue;
if (ifa->ifa_addr == NULL)
continue;
if (memcmp(ifa->ifa_addr, &sa_zero, sizeof(sa_zero)) == 0)
continue;
if (krb5_sockaddr_uninteresting(ifa->ifa_addr))
continue;
if ((ifa->ifa_flags & IFF_LOOPBACK) != 0) {
/* We'll deal with the LOOP_IF_NONE case later. */
if ((flags & LOOP) == 0)
continue;
}
ret = krb5_sockaddr2address(context, ifa->ifa_addr, &res->val[idx]);
if (ret) {
/*
* The most likely error here is going to be "Program
* lacks support for address type". This is no big
* deal -- just continue, and we'll listen on the
* addresses who's type we *do* support.
*/
continue;
}
/* possibly skip this address? */
if((flags & EXTRA_ADDRESSES) &&
krb5_address_search(context, &res->val[idx], &ignore_addresses)) {
krb5_free_address(context, &res->val[idx]);
flags &= ~LOOP_IF_NONE; /* we actually found an address,
so don't add any loop-back
addresses */
continue;
}
idx++;
}
/*
* If no addresses were found, and LOOP_IF_NONE is set, then find
* the loopback addresses and add them to our list.
*/
if ((flags & LOOP_IF_NONE) != 0 && idx == 0) {
for (ifa = ifa0; ifa != NULL; ifa = ifa->ifa_next) {
if ((ifa->ifa_flags & IFF_UP) == 0)
continue;
if (ifa->ifa_addr == NULL)
continue;
if (memcmp(ifa->ifa_addr, &sa_zero, sizeof(sa_zero)) == 0)
continue;
if (krb5_sockaddr_uninteresting(ifa->ifa_addr))
continue;
if ((ifa->ifa_flags & IFF_LOOPBACK) != 0) {
ret = krb5_sockaddr2address(context,
ifa->ifa_addr, &res->val[idx]);
if (ret) {
/*
* See comment above.
*/
continue;
}
if((flags & EXTRA_ADDRESSES) &&
krb5_address_search(context, &res->val[idx],
&ignore_addresses)) {
krb5_free_address(context, &res->val[idx]);
continue;
}
idx++;
}
}
}
if (flags & EXTRA_ADDRESSES)
krb5_free_addresses(context, &ignore_addresses);
freeifaddrs(ifa0);
if (ret)
free(res->val);
else
res->len = idx; /* Now a count. */
return (ret);
}
static krb5_error_code
get_addrs_int (krb5_context context, krb5_addresses *res, int flags)
{
krb5_error_code ret = -1;
if (flags & SCAN_INTERFACES) {
ret = find_all_addresses (context, res, flags);
if(ret || res->len == 0)
ret = gethostname_fallback (context, res);
} else {
res->len = 0;
res->val = NULL;
ret = 0;
}
if(ret == 0 && (flags & EXTRA_ADDRESSES)) {
krb5_addresses a;
/* append user specified addresses */
ret = krb5_get_extra_addresses(context, &a);
if(ret) {
krb5_free_addresses(context, res);
return ret;
}
ret = krb5_append_addresses(context, res, &a);
if(ret) {
krb5_free_addresses(context, res);
return ret;
}
krb5_free_addresses(context, &a);
}
if(res->len == 0) {
free(res->val);
res->val = NULL;
}
return ret;
}
/*
* Try to get all addresses, but return the one corresponding to
* `hostname' if we fail.
*
* Only include loopback address if there are no other.
*/
krb5_error_code KRB5_LIB_FUNCTION
krb5_get_all_client_addrs (krb5_context context, krb5_addresses *res)
{
int flags = LOOP_IF_NONE | EXTRA_ADDRESSES;
if (context->scan_interfaces)
flags |= SCAN_INTERFACES;
return get_addrs_int (context, res, flags);
}
/*
* Try to get all local addresses that a server should listen to.
* If that fails, we return the address corresponding to `hostname'.
*/
krb5_error_code KRB5_LIB_FUNCTION
krb5_get_all_server_addrs (krb5_context context, krb5_addresses *res)
{
return get_addrs_int (context, res, LOOP | SCAN_INTERFACES);
}

File diff suppressed because it is too large Load Diff

View File

@ -114,7 +114,6 @@ ADD_OBJ_FILES = \
heimdal/lib/krb5/free_host_realm.o \
heimdal/lib/krb5/generate_seq_number.o \
heimdal/lib/krb5/generate_subkey.o \
heimdal/lib/krb5/get_addrs.o \
heimdal/lib/krb5/get_cred.o \
heimdal/lib/krb5/get_default_principal.o \
heimdal/lib/krb5/get_default_realm.o \
@ -285,12 +284,18 @@ ADD_OBJ_FILES = \
heimdal/lib/roken/strlwr.o \
heimdal/lib/roken/strsep_copy.o \
heimdal/lib/roken/strupr.o \
heimdal/lib/roken/strpool.o \
heimdal/lib/roken/getifaddrs.o
heimdal/lib/roken/strpool.o
NOPROTO = YES
# End SUBSYSTEM HEIMDAL_ROKEN
#######################
#######################
# Start SUBSYSTEM HEIMDAL_GLUE
[SUBSYSTEM::HEIMDAL_GLUE]
ADD_OBJ_FILES = heimdal_build/glue.o
# End SUBSYSTEM HEIMDAL_GLUE
#######################
#######################
# Start SUBSYSTEM HEIMDAL_COM_ERR
[SUBSYSTEM::HEIMDAL_COM_ERR]
@ -377,7 +382,7 @@ NOPROTO = YES
TARGET_CFLAGS = -Iheimdal_build -Iheimdal/kdc -Iheimdal/lib/des -Iheimdal/lib/roken -Iheimdal/include
REQUIRED_SUBSYSTEMS = \
HEIMDAL_GSSAPI HEIMDAL_KRB5 \
HEIMDAL_ASN1 HEIMDAL_DES HEIMDAL_ROKEN HEIMDAL_COM_ERR
HEIMDAL_ASN1 HEIMDAL_DES HEIMDAL_ROKEN HEIMDAL_COM_ERR HEIMDAL_GLUE
# End SUBSYSTEM HEIMDAL
#######################

View File

@ -0,0 +1,50 @@
/*
Unix SMB/CIFS implementation.
provide glue functions between heimdal and samba
Copyright (C) Andrew Tridgell 2005
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
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "includes.h"
#include "system/network.h"
#include "system/kerberos.h"
/*
get the list of IP addresses for configured interfaces
*/
krb5_error_code krb5_get_all_client_addrs(krb5_context context, krb5_addresses *res)
{
int i;
res->len = iface_count();
res->val = malloc_array_p(HostAddress, res->len);
if (res->val == NULL) {
return KRB5_CC_NOMEM;
}
for (i=0;i<res->len;i++) {
const char *ip = iface_n_ip(i);
res->val[i].addr_type = AF_INET;
res->val[i].address.length = 4;
res->val[i].address.data = malloc(4);
if (res->val[i].address.data == NULL) {
return KRB5_CC_NOMEM;
}
((struct in_addr *)res->val[i].address.data)->s_addr = sys_inet_addr(ip);
}
return 0;
}