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

lib/util Move more network utility functions from source3 into lib/util

This will help with the merge of the interfaces layer.

Andrew Bartlett
This commit is contained in:
Andrew Bartlett 2011-05-02 15:23:08 +10:00
parent 85fa87ea82
commit fbea52f74a
7 changed files with 275 additions and 238 deletions

View File

@ -117,3 +117,75 @@ _PUBLIC_ pid_t sys_getpid(void)
return mypid;
}
_PUBLIC_ int sys_getpeereid( int s, uid_t *uid)
{
#if defined(HAVE_PEERCRED)
struct ucred cred;
socklen_t cred_len = sizeof(struct ucred);
int ret;
ret = getsockopt(s, SOL_SOCKET, SO_PEERCRED, (void *)&cred, &cred_len);
if (ret != 0) {
return -1;
}
if (cred_len != sizeof(struct ucred)) {
errno = EINVAL;
return -1;
}
*uid = cred.uid;
return 0;
#else
#if defined(HAVE_GETPEEREID)
gid_t gid;
return getpeereid(s, uid, &gid);
#endif
errno = ENOSYS;
return -1;
#endif
}
_PUBLIC_ int sys_getnameinfo(const struct sockaddr *psa,
int salen,
char *host,
size_t hostlen,
char *service,
size_t servlen,
int flags)
{
/*
* For Solaris we must make sure salen is the
* correct length for the incoming sa_family.
*/
if (salen == sizeof(struct sockaddr_storage)) {
salen = sizeof(struct sockaddr_in);
#if defined(HAVE_IPV6)
if (psa->sa_family == AF_INET6) {
salen = sizeof(struct sockaddr_in6);
}
#endif
}
return getnameinfo(psa, salen, host, hostlen, service, servlen, flags);
}
_PUBLIC_ int sys_connect(int fd, const struct sockaddr * addr)
{
socklen_t salen = (socklen_t)-1;
if (addr->sa_family == AF_INET) {
salen = sizeof(struct sockaddr_in);
} else if (addr->sa_family == AF_UNIX) {
salen = sizeof(struct sockaddr_un);
}
#if defined(HAVE_IPV6)
else if (addr->sa_family == AF_INET6) {
salen = sizeof(struct sockaddr_in6);
}
#endif
return connect(fd, addr, salen);
}

View File

@ -131,8 +131,20 @@ _PUBLIC_ pid_t sys_fork(void);
**/
_PUBLIC_ pid_t sys_getpid(void);
/* The following definitions come from lib/util/genrand.c */
_PUBLIC_ int sys_getpeereid( int s, uid_t *uid);
struct sockaddr;
_PUBLIC_ int sys_getnameinfo(const struct sockaddr *psa,
int salen,
char *host,
size_t hostlen,
char *service,
size_t servlen,
int flags);
_PUBLIC_ int sys_connect(int fd, const struct sockaddr * addr);
/* The following definitions come from lib/util/genrand.c */
/**
Copy any user given reseed data.
**/

View File

@ -540,3 +540,158 @@ void set_sockaddr_port(struct sockaddr *psa, uint16_t port)
}
/****************************************************************************
Get a port number in host byte order from a sockaddr_storage.
****************************************************************************/
uint16_t get_sockaddr_port(const struct sockaddr_storage *pss)
{
uint16_t port = 0;
if (pss->ss_family != AF_INET) {
#if defined(HAVE_IPV6)
/* IPv6 */
const struct sockaddr_in6 *sa6 =
(const struct sockaddr_in6 *)pss;
port = ntohs(sa6->sin6_port);
#endif
} else {
const struct sockaddr_in *sa =
(const struct sockaddr_in *)pss;
port = ntohs(sa->sin_port);
}
return port;
}
/****************************************************************************
Print out an IPv4 or IPv6 address from a struct sockaddr_storage.
****************************************************************************/
char *print_sockaddr_len(char *dest,
size_t destlen,
const struct sockaddr *psa,
socklen_t psalen)
{
if (destlen > 0) {
dest[0] = '\0';
}
(void)sys_getnameinfo(psa,
psalen,
dest, destlen,
NULL, 0,
NI_NUMERICHOST);
return dest;
}
/****************************************************************************
Print out an IPv4 or IPv6 address from a struct sockaddr_storage.
****************************************************************************/
char *print_sockaddr(char *dest,
size_t destlen,
const struct sockaddr_storage *psa)
{
return print_sockaddr_len(dest, destlen, (struct sockaddr *)psa,
sizeof(struct sockaddr_storage));
}
/****************************************************************************
Print out a canonical IPv4 or IPv6 address from a struct sockaddr_storage.
****************************************************************************/
char *print_canonical_sockaddr(TALLOC_CTX *ctx,
const struct sockaddr_storage *pss)
{
char addr[INET6_ADDRSTRLEN];
char *dest = NULL;
int ret;
/* Linux getnameinfo() man pages says port is unitialized if
service name is NULL. */
ret = sys_getnameinfo((const struct sockaddr *)pss,
sizeof(struct sockaddr_storage),
addr, sizeof(addr),
NULL, 0,
NI_NUMERICHOST);
if (ret != 0) {
return NULL;
}
if (pss->ss_family != AF_INET) {
#if defined(HAVE_IPV6)
dest = talloc_asprintf(ctx, "[%s]", addr);
#else
return NULL;
#endif
} else {
dest = talloc_asprintf(ctx, "%s", addr);
}
return dest;
}
/****************************************************************************
Return the port number we've bound to on a socket.
****************************************************************************/
int get_socket_port(int fd)
{
struct sockaddr_storage sa;
socklen_t length = sizeof(sa);
if (fd == -1) {
return -1;
}
if (getsockname(fd, (struct sockaddr *)&sa, &length) < 0) {
int level = (errno == ENOTCONN) ? 2 : 0;
DEBUG(level, ("getsockname failed. Error was %s\n",
strerror(errno)));
return -1;
}
#if defined(HAVE_IPV6)
if (sa.ss_family == AF_INET6) {
return ntohs(((struct sockaddr_in6 *)&sa)->sin6_port);
}
#endif
if (sa.ss_family == AF_INET) {
return ntohs(((struct sockaddr_in *)&sa)->sin_port);
}
return -1;
}
/****************************************************************************
Return the string of an IP address (IPv4 or IPv6).
****************************************************************************/
static const char *get_socket_addr(int fd, char *addr_buf, size_t addr_len)
{
struct sockaddr_storage sa;
socklen_t length = sizeof(sa);
/* Ok, returning a hard coded IPv4 address
* is bogus, but it's just as bogus as a
* zero IPv6 address. No good choice here.
*/
strlcpy(addr_buf, "0.0.0.0", addr_len);
if (fd == -1) {
return addr_buf;
}
if (getsockname(fd, (struct sockaddr *)&sa, &length) < 0) {
DEBUG(0,("getsockname failed. Error was %s\n",
strerror(errno) ));
return addr_buf;
}
return print_sockaddr_len(addr_buf, addr_len, (struct sockaddr *)&sa, length);
}
const char *client_socket_addr(int fd, char *addr, size_t addr_len)
{
return get_socket_addr(fd, addr, addr_len);
}

View File

@ -50,6 +50,15 @@ void set_sockaddr_port(struct sockaddr *psa, uint16_t port);
**/
_PUBLIC_ bool is_zero_ip_v4(struct in_addr ip);
void in_addr_to_sockaddr_storage(struct sockaddr_storage *ss,
struct in_addr ip);
#if defined(HAVE_IPV6)
/**
* Convert an IPv6 struct in_addr to a struct sockaddr_storage.
*/
void in6_addr_to_sockaddr_storage(struct sockaddr_storage *ss,
struct in6_addr ip);
#endif
/**
Are two IPs on the same subnet?
**/
@ -60,6 +69,11 @@ _PUBLIC_ bool same_net_v4(struct in_addr ip1,struct in_addr ip2,struct in_addr m
**/
_PUBLIC_ bool is_ipaddress(const char *str);
bool is_broadcast_addr(const struct sockaddr *pss);
bool is_loopback_ip_v4(struct in_addr ip);
bool is_loopback_addr(const struct sockaddr *pss);
bool is_zero_addr(const struct sockaddr_storage *pss);
void zero_ip_v4(struct in_addr *ip);
/**
Interpret an internet address or name into an IP address in 4 byte form.
**/
@ -72,5 +86,26 @@ _PUBLIC_ struct in_addr interpret_addr2(const char *str);
_PUBLIC_ bool is_ipaddress_v4(const char *str);
bool is_address_any(const struct sockaddr *psa);
bool same_net(const struct sockaddr *ip1,
const struct sockaddr *ip2,
const struct sockaddr *mask);
bool sockaddr_equal(const struct sockaddr *ip1,
const struct sockaddr *ip2);
bool is_address_any(const struct sockaddr *psa);
uint16_t get_sockaddr_port(const struct sockaddr_storage *pss);
char *print_sockaddr_len(char *dest,
size_t destlen,
const struct sockaddr *psa,
socklen_t psalen);
char *print_sockaddr(char *dest,
size_t destlen,
const struct sockaddr_storage *psa);
char *print_canonical_sockaddr(TALLOC_CTX *ctx,
const struct sockaddr_storage *pss);
const char *client_name(int fd);
int get_socket_port(int fd);
const char *client_socket_addr(int fd, char *addr, size_t addr_len);
#endif /* _SAMBA_UTIL_NET_H_ */

View File

@ -532,16 +532,6 @@ int sys_aio_cancel(int fd, SMB_STRUCT_AIOCB *aiocb);
int sys_aio_error(const SMB_STRUCT_AIOCB *aiocb);
int sys_aio_fsync(int op, SMB_STRUCT_AIOCB *aiocb);
int sys_aio_suspend(const SMB_STRUCT_AIOCB * const cblist[], int n, const struct timespec *timeout);
int sys_getpeereid( int s, uid_t *uid);
int sys_getnameinfo(const struct sockaddr *psa,
socklen_t salen,
char *host,
size_t hostlen,
char *service,
size_t servlen,
int flags);
int sys_connect(int fd, const struct sockaddr * addr);
/* The following definitions come from lib/system_smbd.c */
bool getgroups_unix_user(TALLOC_CTX *mem_ctx, const char *user,

View File

@ -2633,74 +2633,3 @@ int sys_aio_suspend(const SMB_STRUCT_AIOCB * const cblist[], int n, const struct
return -1;
}
#endif /* WITH_AIO */
int sys_getpeereid( int s, uid_t *uid)
{
#if defined(HAVE_PEERCRED)
struct ucred cred;
socklen_t cred_len = sizeof(struct ucred);
int ret;
ret = getsockopt(s, SOL_SOCKET, SO_PEERCRED, (void *)&cred, &cred_len);
if (ret != 0) {
return -1;
}
if (cred_len != sizeof(struct ucred)) {
errno = EINVAL;
return -1;
}
*uid = cred.uid;
return 0;
#else
#if defined(HAVE_GETPEEREID)
gid_t gid;
return getpeereid(s, uid, &gid);
#endif
errno = ENOSYS;
return -1;
#endif
}
int sys_getnameinfo(const struct sockaddr *psa,
socklen_t salen,
char *host,
size_t hostlen,
char *service,
size_t servlen,
int flags)
{
/*
* For Solaris we must make sure salen is the
* correct length for the incoming sa_family.
*/
if (salen == sizeof(struct sockaddr_storage)) {
salen = sizeof(struct sockaddr_in);
#if defined(HAVE_IPV6)
if (psa->sa_family == AF_INET6) {
salen = sizeof(struct sockaddr_in6);
}
#endif
}
return getnameinfo(psa, salen, host, hostlen, service, servlen, flags);
}
int sys_connect(int fd, const struct sockaddr * addr)
{
socklen_t salen = (socklen_t)-1;
if (addr->sa_family == AF_INET) {
salen = sizeof(struct sockaddr_in);
} else if (addr->sa_family == AF_UNIX) {
salen = sizeof(struct sockaddr_un);
}
#if defined(HAVE_IPV6)
else if (addr->sa_family == AF_INET6) {
salen = sizeof(struct sockaddr_in6);
}
#endif
return connect(fd, addr, salen);
}

View File

@ -28,157 +28,6 @@
#include "../lib/util/tevent_unix.h"
#include "../lib/util/tevent_ntstatus.h"
/****************************************************************************
Get a port number in host byte order from a sockaddr_storage.
****************************************************************************/
uint16_t get_sockaddr_port(const struct sockaddr_storage *pss)
{
uint16_t port = 0;
if (pss->ss_family != AF_INET) {
#if defined(HAVE_IPV6)
/* IPv6 */
const struct sockaddr_in6 *sa6 =
(const struct sockaddr_in6 *)pss;
port = ntohs(sa6->sin6_port);
#endif
} else {
const struct sockaddr_in *sa =
(const struct sockaddr_in *)pss;
port = ntohs(sa->sin_port);
}
return port;
}
/****************************************************************************
Print out an IPv4 or IPv6 address from a struct sockaddr_storage.
****************************************************************************/
static char *print_sockaddr_len(char *dest,
size_t destlen,
const struct sockaddr *psa,
socklen_t psalen)
{
if (destlen > 0) {
dest[0] = '\0';
}
(void)sys_getnameinfo(psa,
psalen,
dest, destlen,
NULL, 0,
NI_NUMERICHOST);
return dest;
}
/****************************************************************************
Print out an IPv4 or IPv6 address from a struct sockaddr_storage.
****************************************************************************/
char *print_sockaddr(char *dest,
size_t destlen,
const struct sockaddr_storage *psa)
{
return print_sockaddr_len(dest, destlen, (struct sockaddr *)psa,
sizeof(struct sockaddr_storage));
}
/****************************************************************************
Print out a canonical IPv4 or IPv6 address from a struct sockaddr_storage.
****************************************************************************/
char *print_canonical_sockaddr(TALLOC_CTX *ctx,
const struct sockaddr_storage *pss)
{
char addr[INET6_ADDRSTRLEN];
char *dest = NULL;
int ret;
/* Linux getnameinfo() man pages says port is unitialized if
service name is NULL. */
ret = sys_getnameinfo((const struct sockaddr *)pss,
sizeof(struct sockaddr_storage),
addr, sizeof(addr),
NULL, 0,
NI_NUMERICHOST);
if (ret != 0) {
return NULL;
}
if (pss->ss_family != AF_INET) {
#if defined(HAVE_IPV6)
dest = talloc_asprintf(ctx, "[%s]", addr);
#else
return NULL;
#endif
} else {
dest = talloc_asprintf(ctx, "%s", addr);
}
return dest;
}
/****************************************************************************
Return the string of an IP address (IPv4 or IPv6).
****************************************************************************/
static const char *get_socket_addr(int fd, char *addr_buf, size_t addr_len)
{
struct sockaddr_storage sa;
socklen_t length = sizeof(sa);
/* Ok, returning a hard coded IPv4 address
* is bogus, but it's just as bogus as a
* zero IPv6 address. No good choice here.
*/
strlcpy(addr_buf, "0.0.0.0", addr_len);
if (fd == -1) {
return addr_buf;
}
if (getsockname(fd, (struct sockaddr *)&sa, &length) < 0) {
DEBUG(0,("getsockname failed. Error was %s\n",
strerror(errno) ));
return addr_buf;
}
return print_sockaddr_len(addr_buf, addr_len, (struct sockaddr *)&sa, length);
}
/****************************************************************************
Return the port number we've bound to on a socket.
****************************************************************************/
int get_socket_port(int fd)
{
struct sockaddr_storage sa;
socklen_t length = sizeof(sa);
if (fd == -1) {
return -1;
}
if (getsockname(fd, (struct sockaddr *)&sa, &length) < 0) {
int level = (errno == ENOTCONN) ? 2 : 0;
DEBUG(level, ("getsockname failed. Error was %s\n",
strerror(errno)));
return -1;
}
#if defined(HAVE_IPV6)
if (sa.ss_family == AF_INET6) {
return ntohs(((struct sockaddr_in6 *)&sa)->sin6_port);
}
#endif
if (sa.ss_family == AF_INET) {
return ntohs(((struct sockaddr_in *)&sa)->sin_port);
}
return -1;
}
const char *client_name(int fd)
{
return get_peer_name(fd,false);
@ -189,11 +38,6 @@ const char *client_addr(int fd, char *addr, size_t addrlen)
return get_peer_addr(fd,addr,addrlen);
}
const char *client_socket_addr(int fd, char *addr, size_t addr_len)
{
return get_socket_addr(fd, addr, addr_len);
}
#if 0
/* Not currently used. JRA. */
int client_socket_port(int fd)