1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-13 13:18:06 +03:00

r18640: move to socket_wrapper to lib/socket_wrapper/

and sync it with samba4

metze
This commit is contained in:
Stefan Metzmacher 2006-09-18 22:12:56 +00:00 committed by Gerald (Jerry) Carter
parent fa53ad6571
commit 9c0e5b29f1
6 changed files with 230 additions and 101 deletions

View File

@ -207,8 +207,6 @@ ERRORMAP_OBJ = libsmb/errormap.o
PASSCHANGE_OBJ = libsmb/passchange.o
SOCKET_WRAPPER_OBJ = lib/socket_wrapper.o
LIBNDR_OBJ = librpc/ndr/ndr_basic.o librpc/ndr/ndr.o librpc/ndr/ndr_misc.o \
librpc/ndr/ndr_sec_helper.o librpc/ndr/ndr_string.o librpc/ndr/sid.o
@ -221,10 +219,12 @@ RPC_PARSE_OBJ0 = rpc_parse/parse_prs.o rpc_parse/parse_misc.o
TALLOC_OBJ = lib/talloc.o
LIB_OBJ = $(VERSION_OBJ) lib/charcnv.o lib/debug.o lib/fault.o \
lib/getsmbpass.o lib/interface.o lib/md4.o \
lib/interfaces.o lib/pidfile.o lib/replace.o lib/replace1.o lib/repdir.o lib/timegm.o \
lib/signal.o lib/system.o lib/sendfile.o lib/time.o \
LIB_WITHOUT_PROTO_OBJ = @SOCKET_WRAPPER_OBJS@
LIB_WITH_PROTO_OBJ = $(VERSION_OBJ) lib/charcnv.o lib/debug.o lib/fault.o \
lib/getsmbpass.o lib/interface.o lib/md4.o \
lib/interfaces.o lib/pidfile.o lib/replace.o lib/replace1.o lib/repdir.o lib/timegm.o \
lib/signal.o lib/system.o lib/sendfile.o lib/time.o \
lib/ufc.o lib/genrand.o lib/username.o \
lib/util_pw.o lib/access.o lib/smbrun.o \
lib/bitmap.o lib/crc32.o $(SNPRINTF_OBJ) lib/dprintf.o \
@ -240,9 +240,11 @@ LIB_OBJ = $(VERSION_OBJ) lib/charcnv.o lib/debug.o lib/fault.o \
lib/pam_errors.o intl/lang_tdb.o \
lib/adt_tree.o lib/gencache.o $(TDB_OBJ) \
lib/module.o lib/events.o lib/ldap_escape.o @CHARSET_STATIC@ \
lib/secdesc.o lib/util_seaccess.o lib/secace.o lib/secacl.o @SOCKWRAP@ \
lib/secdesc.o lib/util_seaccess.o lib/secace.o lib/secacl.o \
libads/krb5_errs.o lib/system_smbd.o lib/audit.o $(TALLOC_OBJ)
LIB_OBJ = $(LIB_WITHOUT_PROTO_OBJ) $(LIB_WITH_PROTO_OBJ)
LIB_DUMMY_OBJ = lib/dummysmbd.o lib/dummyroot.o
LIB_NONSMBD_OBJ = $(LIB_OBJ) $(LIB_DUMMY_OBJ)
@ -621,9 +623,9 @@ CUPS_OBJ = client/smbspool.o $(PARAM_OBJ) $(LIBSMB_OBJ) \
MOUNT_OBJ = client/smbmount.o \
$(PARAM_OBJ) $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) $(LIB_NONSMBD_OBJ) $(SECRETS_OBJ)
MNT_OBJ = client/smbmnt.o lib/replace.o lib/timegm.o $(VERSION_OBJ) $(SNPRINTF_OBJ) @SOCKWRAP@
MNT_OBJ = client/smbmnt.o lib/replace.o lib/timegm.o $(VERSION_OBJ) $(SNPRINTF_OBJ) @SOCKET_WRAPPER_OBJS@
UMOUNT_OBJ = client/smbumount.o @SOCKWRAP@
UMOUNT_OBJ = client/smbumount.o @SOCKET_WRAPPER_OBJS@
CIFS_MOUNT_OBJ = client/mount.cifs.o
@ -707,9 +709,10 @@ SMBFILTER_OBJ = utils/smbfilter.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(SECRETS_OBJ) \
$(LIB_NONSMBD_OBJ) $(KRBCLIENT_OBJ)
PROTO_OBJ = $(SMBD_OBJ_MAIN) $(LIBNDR_OBJ) $(LIBNDR_GEN_OBJ) \
$(SMBD_OBJ_SRV) $(NMBD_OBJ1) $(SWAT_OBJ1) $(LIB_OBJ) $(LIBSMB_OBJ) \
$(SMBD_OBJ_SRV) $(NMBD_OBJ1) $(SWAT_OBJ1) $(LIBSMB_OBJ) \
$(SMBTORTURE_OBJ1) $(RPCCLIENT_OBJ1) \
$(LIBMSRPC_OBJ) @SMBWRAP_OBJS@ \
$(LIB_WITH_PROTO_OBJ) \
$(RPC_PIPE_OBJ) $(RPC_PARSE_OBJ) $(KRBCLIENT_OBJ) \
$(AUTH_OBJ) $(PARAM_OBJ) $(LOCKING_OBJ) $(SECRETS_OBJ) \
$(PRINTING_OBJ) $(PRINTBACKEND_OBJ) $(OPLOCK_OBJ) $(NOTIFY_OBJ) \
@ -1485,15 +1488,15 @@ bin/pam_smbpass.@SHLIBEXT@: $(PAM_SMBPASS_PICOOBJ)
bin/tdbbackup@EXEEXT@: $(TDBBACKUP_OBJ) bin/.dummy
@echo Linking $@
@$(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(LDFLAGS) $(DYNEXP) $(LIBS) $(TDBBACKUP_OBJ) @SOCKWRAP@
@$(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(LDFLAGS) $(DYNEXP) $(LIBS) $(TDBBACKUP_OBJ) @SOCKET_WRAPPER_OBJS@
bin/tdbtool@EXEEXT@: $(TDBTOOL_OBJ) bin/.dummy
@echo Linking $@
@$(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(LDFLAGS) $(DYNEXP) $(LIBS) $(TDBTOOL_OBJ) @SOCKWRAP@
@$(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(LDFLAGS) $(DYNEXP) $(LIBS) $(TDBTOOL_OBJ) @SOCKET_WRAPPER_OBJS@
bin/tdbdump@EXEEXT@: $(TDBDUMP_OBJ) bin/.dummy
@echo Linking $@
@$(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(LDFLAGS) $(DYNEXP) $(LIBS) $(TDBDUMP_OBJ) @SOCKWRAP@
@$(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(LDFLAGS) $(DYNEXP) $(LIBS) $(TDBDUMP_OBJ) @SOCKET_WRAPPER_OBJS@
bin/t_strcmp@EXEEXT@: bin/libbigballofmud.@SHLIBEXT@ torture/t_strcmp.o
$(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(DYNEXP) $(LIBS) torture/t_strcmp.o -L ./bin -lbigballofmud

View File

@ -334,13 +334,7 @@ AC_ARG_ENABLE(debug,
CFLAGS="${CFLAGS} -g"
fi])
AC_SUBST(SOCKWRAP)
AC_ARG_ENABLE(socket-wrapper,
[ --enable-socket-wrapper Turn on socket wrapper library (default=no)],
[if eval "test x$enable_socket_wrapper = xyes"; then
AC_DEFINE(SOCKET_WRAPPER,1,[Use socket wrapper library])
SOCKWRAP="\$(SOCKET_WRAPPER_OBJ)"
fi])
m4_include(lib/socket_wrapper/config.m4)
#################################################
# set prefix for 'make test'

View File

@ -941,7 +941,7 @@ extern int errno;
#ifdef SOCKET_WRAPPER
#define SOCKET_WRAPPER_REPLACE
#include "include/socket_wrapper.h"
#include "lib/socket_wrapper/socket_wrapper.h"
#endif
/* Our own pstrings and fstrings */

View File

@ -0,0 +1,22 @@
AC_ARG_ENABLE(socket-wrapper,
[ --enable-socket-wrapper Turn on socket wrapper library (default=no)])
DEFAULT_TEST_TARGET=test-noswrap
HAVE_SOCKET_WRAPPER=no
if eval "test x$developer = xyes"; then
enable_socket_wrapper=yes
fi
if eval "test x$enable_socket_wrapper = xyes"; then
AC_DEFINE(SOCKET_WRAPPER,1,[Use socket wrapper library])
DEFAULT_TEST_TARGET=test-swrap
HAVE_SOCKET_WRAPPER=yes
# this is only used for samba3
SOCKET_WRAPPER_OBJS="lib/socket_wrapper/socket_wrapper.o"
fi
AC_SUBST(DEFAULT_TEST_TARGET)
AC_SUBST(HAVE_SOCKET_WRAPPER)
AC_SUBST(SOCKET_WRAPPER_OBJS)

View File

@ -3,6 +3,7 @@
unix domain sockets if the environment variable SOCKET_WRAPPER_DIR
is set.
Copyright (C) Jelmer Vernooij 2005
Copyright (C) Stefan Metzmacher 2006
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
@ -19,25 +20,44 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifdef _SAMBA_BUILD_
#define SOCKET_WRAPPER_NOT_REPLACE
#include "includes.h"
#ifdef _PUBLIC_
#undef _PUBLIC_
/*
#include "system/network.h"
#include "system/filesys.h"
*/
#ifndef _DLINKLIST_H
#include "lib/util/dlinklist.h"
#endif
#define _PUBLIC_
#ifdef SOCKET_WRAPPER_REPLACE
#undef accept
#undef connect
#undef bind
#undef getpeername
#undef getsockname
#undef getsockopt
#undef setsockopt
#undef recvfrom
#undef sendto
#undef socket
#undef close
#ifdef malloc
#undef malloc
#endif
#ifdef calloc
#undef calloc
#endif
#ifdef strdup
#undef strdup
#endif
#else /* _SAMBA_BUILD_ */
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <errno.h>
#include <sys/un.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#error "dlinklist.h missing"
#endif
/* LD_PRELOAD doesn't work yet, so REWRITE_CALLS is all we support
@ -54,13 +74,12 @@
#define real_setsockopt setsockopt
#define real_recvfrom recvfrom
#define real_sendto sendto
#define real_recv recv
#define real_send send
#define real_socket socket
#define real_close close
#endif
#undef malloc
#undef calloc
#undef strdup
/* we need to use a very terse format here as IRIX 6.4 silently
truncates names to 16 chars, so if we use a longer name then we
can't tell which port a packet came from with recvfrom()
@ -82,7 +101,7 @@ struct socket_info
{
int fd;
int domain;
int family;
int type;
int protocol;
int bound;
@ -100,7 +119,7 @@ struct socket_info
struct socket_info *prev, *next;
};
static struct socket_info *sockets = NULL;
static struct socket_info *sockets;
static const char *socket_wrapper_dir(void)
@ -115,6 +134,23 @@ static const char *socket_wrapper_dir(void)
return s;
}
static const char *socket_wrapper_dump_dir(void)
{
const char *s = getenv("SOCKET_WRAPPER_DUMP_DIR");
if (!socket_wrapper_dir()) {
return NULL;
}
if (s == NULL) {
return NULL;
}
if (strncmp(s, "./", 2) == 0) {
s += 2;
}
return s;
}
static unsigned int socket_wrapper_default_iface(void)
{
const char *s = getenv("SOCKET_WRAPPER_DEFAULT_IFACE");
@ -346,9 +382,6 @@ static int sockaddr_convert_to_un(struct socket_info *si, const struct sockaddr
} else {
return convert_in_un_remote(si, (const struct sockaddr_in *)in_addr, out_addr, bcast);
}
case AF_UNIX:
memcpy(out_addr, in_addr, sizeof(*out_addr));
return 0;
default:
break;
}
@ -390,10 +423,6 @@ static int sockaddr_convert_from_un(const struct socket_info *si,
return -1;
}
return convert_un_in(in_addr, (struct sockaddr_in *)out_addr, _out_addrlen);
case AF_UNIX:
memcpy(out_addr, in_addr, out_addrlen);
*_out_addrlen = out_addrlen;
return 0;
default:
break;
}
@ -402,26 +431,52 @@ static int sockaddr_convert_from_un(const struct socket_info *si,
return -1;
}
_PUBLIC_ int swrap_socket(int domain, int type, int protocol)
enum swrap_packet_type {
SWRAP_CONNECT,
SWRAP_ACCEPT,
SWRAP_RECVFROM,
SWRAP_SENDTO,
SWRAP_RECV,
SWRAP_SEND,
SWRAP_CLOSE
};
static void swrap_dump_packet(struct socket_info *si, const struct sockaddr *addr,
enum swrap_packet_type type,
const void *buf, size_t len, ssize_t ret)
{
if (!socket_wrapper_dump_dir()) {
return;
}
}
_PUBLIC_ int swrap_socket(int family, int type, int protocol)
{
struct socket_info *si;
int fd;
if (!socket_wrapper_dir()) {
return real_socket(domain, type, protocol);
}
si = (struct socket_info *)calloc(1, sizeof(struct socket_info));
if (si == NULL) {
errno = ENOMEM;
return -1;
return real_socket(family, type, protocol);
}
switch (family) {
case AF_INET:
break;
case AF_UNIX:
return real_socket(family, type, protocol);
default:
errno = EAFNOSUPPORT;
return -1;
}
fd = real_socket(AF_UNIX, type, 0);
if (fd == -1) return -1;
si->domain = domain;
si = calloc(1, sizeof(struct socket_info));
si->family = family;
si->type = type;
si->protocol = protocol;
si->fd = fd;
@ -458,29 +513,35 @@ _PUBLIC_ int swrap_accept(int s, struct sockaddr *addr, socklen_t *addrlen)
fd = ret;
ret = sockaddr_convert_from_un(parent_si, &un_addr, un_addrlen,
parent_si->domain, addr, addrlen);
if (ret == -1) return ret;
child_si = (struct socket_info *)malloc(sizeof(struct socket_info));
if (child_si == NULL) {
parent_si->family, addr, addrlen);
if (ret == -1) {
close(fd);
errno = ENOMEM;
return -1;
return ret;
}
child_si = malloc(sizeof(struct socket_info));
memset(child_si, 0, sizeof(*child_si));
child_si->fd = fd;
child_si->domain = parent_si->domain;
child_si->family = parent_si->family;
child_si->type = parent_si->type;
child_si->protocol = parent_si->protocol;
child_si->bound = 1;
ret = real_getsockname(fd, (struct sockaddr *)&un_my_addr, &un_my_addrlen);
if (ret == -1) return ret;
if (ret == -1) {
free(child_si);
close(fd);
return ret;
}
ret = sockaddr_convert_from_un(child_si, &un_my_addr, un_my_addrlen,
child_si->domain, &my_addr, &my_addrlen);
if (ret == -1) return ret;
child_si->family, &my_addr, &my_addrlen);
if (ret == -1) {
free(child_si);
close(fd);
return ret;
}
child_si->myname_len = my_addrlen;
child_si->myname = sockaddr_dup(&my_addr, my_addrlen);
@ -490,6 +551,8 @@ _PUBLIC_ int swrap_accept(int s, struct sockaddr *addr, socklen_t *addrlen)
DLIST_ADD(sockets, child_si);
swrap_dump_packet(child_si, addr, SWRAP_ACCEPT, NULL, 0, 0);
return fd;
}
@ -504,6 +567,7 @@ static int swrap_auto_bind(struct socket_info *si)
int i;
char type;
int ret;
int port;
struct stat st;
un_addr.sun_family = AF_UNIX;
@ -521,9 +585,10 @@ static int swrap_auto_bind(struct socket_info *si)
}
for (i=0;i<1000;i++) {
port = 10000 + i;
snprintf(un_addr.sun_path, sizeof(un_addr.sun_path),
"%s/"SOCKET_FORMAT, socket_wrapper_dir(),
type, socket_wrapper_default_iface(), i + 10000);
type, socket_wrapper_default_iface(), port);
if (stat(un_addr.sun_path, &st) == 0) continue;
ret = real_bind(si->fd, (struct sockaddr *)&un_addr, sizeof(un_addr));
@ -540,7 +605,7 @@ static int swrap_auto_bind(struct socket_info *si)
memset(&in, 0, sizeof(in));
in.sin_family = AF_INET;
in.sin_port = htons(i);
in.sin_port = htons(port);
in.sin_addr.s_addr = htonl(127<<24 | socket_wrapper_default_iface());
si->myname_len = sizeof(in);
@ -560,7 +625,7 @@ _PUBLIC_ int swrap_connect(int s, const struct sockaddr *serv_addr, socklen_t ad
return real_connect(s, serv_addr, addrlen);
}
if (si->bound == 0 && si->domain != AF_UNIX) {
if (si->bound == 0) {
ret = swrap_auto_bind(si);
if (ret == -1) return -1;
}
@ -572,10 +637,8 @@ _PUBLIC_ int swrap_connect(int s, const struct sockaddr *serv_addr, socklen_t ad
sizeof(struct sockaddr_un));
/* to give better errors */
if (serv_addr->sa_family == AF_INET) {
if (ret == -1 && errno == ENOENT) {
errno = EHOSTUNREACH;
}
if (ret == -1 && errno == ENOENT) {
errno = EHOSTUNREACH;
}
if (ret == 0) {
@ -583,6 +646,8 @@ _PUBLIC_ int swrap_connect(int s, const struct sockaddr *serv_addr, socklen_t ad
si->peername = sockaddr_dup(serv_addr, addrlen);
}
swrap_dump_packet(si, serv_addr, SWRAP_CONNECT, NULL, 0, ret);
return ret;
}
@ -660,13 +725,8 @@ _PUBLIC_ int swrap_getsockopt(int s, int level, int optname, void *optval, sockl
return real_getsockopt(s, level, optname, optval, optlen);
}
switch (si->domain) {
case AF_UNIX:
return real_getsockopt(s, level, optname, optval, optlen);
default:
errno = ENOPROTOOPT;
return -1;
}
errno = ENOPROTOOPT;
return -1;
}
_PUBLIC_ int swrap_setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen)
@ -681,15 +741,9 @@ _PUBLIC_ int swrap_setsockopt(int s, int level, int optname, const void *o
return real_setsockopt(s, level, optname, optval, optlen);
}
switch (si->domain) {
case AF_UNIX:
return real_setsockopt(s, level, optname, optval, optlen);
switch (si->family) {
case AF_INET:
/* Silence some warnings */
#ifdef TCP_NODELAY
if (optname == TCP_NODELAY)
return 0;
#endif
return 0;
default:
errno = ENOPROTOOPT;
return -1;
@ -714,15 +768,17 @@ _PUBLIC_ ssize_t swrap_recvfrom(int s, void *buf, size_t len, int flags, struct
return ret;
if (sockaddr_convert_from_un(si, &un_addr, un_addrlen,
si->domain, from, fromlen) == -1) {
si->family, from, fromlen) == -1) {
return -1;
}
swrap_dump_packet(si, from, SWRAP_RECVFROM, buf, len, ret);
return ret;
}
_PUBLIC_ ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags, const struct sockaddr *to, socklen_t tolen)
_PUBLIC_ ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags, const struct sockaddr *to, socklen_t tolen)
{
struct sockaddr_un un_addr;
int ret;
@ -733,7 +789,7 @@ _PUBLIC_ ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags,
return real_sendto(s, buf, len, flags, to, tolen);
}
if (si->bound == 0 && si->domain != AF_UNIX) {
if (si->bound == 0) {
ret = swrap_auto_bind(si);
if (ret == -1) return -1;
}
@ -757,18 +813,58 @@ _PUBLIC_ ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags,
/* ignore the any errors in broadcast sends */
real_sendto(s, buf, len, flags, (struct sockaddr *)&un_addr, sizeof(un_addr));
}
swrap_dump_packet(si, to, SWRAP_SENDTO, buf, len, len);
return len;
}
ret = real_sendto(s, buf, len, flags, (struct sockaddr *)&un_addr, sizeof(un_addr));
/* to give better errors */
if (to->sa_family == AF_INET) {
if (ret == -1 && errno == ENOENT) {
errno = EHOSTUNREACH;
}
if (ret == -1 && errno == ENOENT) {
errno = EHOSTUNREACH;
}
swrap_dump_packet(si, to, SWRAP_SENDTO, buf, len, ret);
return ret;
}
_PUBLIC_ ssize_t swrap_recv(int s, void *buf, size_t len, int flags)
{
int ret;
struct socket_info *si = find_socket_info(s);
if (!si) {
return real_recv(s, buf, len, flags);
}
ret = real_recv(s, buf, len, flags);
if (ret == -1)
return ret;
swrap_dump_packet(si, NULL, SWRAP_RECV, buf, len, ret);
return ret;
}
_PUBLIC_ ssize_t swrap_send(int s, const void *buf, size_t len, int flags)
{
int ret;
struct socket_info *si = find_socket_info(s);
if (!si) {
return real_send(s, buf, len, flags);
}
ret = real_send(s, buf, len, flags);
if (ret == -1)
return ret;
swrap_dump_packet(si, NULL, SWRAP_SEND, buf, len, ret);
return ret;
}
@ -779,6 +875,8 @@ _PUBLIC_ int swrap_close(int fd)
if (si) {
DLIST_REMOVE(sockets, si);
swrap_dump_packet(si, NULL, SWRAP_CLOSE, NULL, 0, 0);
free(si->path);
free(si->myname);
free(si->peername);

View File

@ -19,7 +19,7 @@
#ifndef __SOCKET_WRAPPER_H__
#define __SOCKET_WRAPPER_H__
int swrap_socket(int domain, int type, int protocol);
int swrap_socket(int family, int type, int protocol);
int swrap_accept(int s, struct sockaddr *addr, socklen_t *addrlen);
int swrap_connect(int s, const struct sockaddr *serv_addr, socklen_t addrlen);
int swrap_bind(int s, const struct sockaddr *myaddr, socklen_t addrlen);
@ -28,7 +28,9 @@ int swrap_getsockname(int s, struct sockaddr *name, socklen_t *addrlen);
int swrap_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen);
int swrap_setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen);
ssize_t swrap_recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen);
ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags, const struct sockaddr *to, socklen_t tolen);
ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags, const struct sockaddr *to, socklen_t tolen);
ssize_t swrap_recv(int s, void *buf, size_t len, int flags);
ssize_t swrap_send(int s, const void *buf, size_t len, int flags);
int swrap_close(int);
#ifdef SOCKET_WRAPPER_REPLACE
@ -78,6 +80,16 @@ int swrap_close(int);
#endif
#define sendto(s,buf,len,flags,to,tolen) swrap_sendto(s,buf,len,flags,to,tolen)
#ifdef recv
#undef recv
#endif
#define recv(s,buf,len,flags) swrap_recv(s,buf,len,flags)
#ifdef send
#undef send
#endif
#define send(s,buf,len,flags) swrap_send(s,buf,len,flags)
#ifdef socket
#undef socket
#endif