mirror of
https://github.com/samba-team/samba.git
synced 2025-01-11 05:18:09 +03:00
r25492: Start adding IPv6 compatible code to lib/util_sock.c and deal with
the ripple effects this causes. utmp has to change etc. Remove some global varables and store address/port in the unexpected db. Jeremy.
This commit is contained in:
parent
2cab825634
commit
18c6a2211d
@ -36,7 +36,7 @@ struct sessionid {
|
||||
fstring id_str;
|
||||
uint32 id_num;
|
||||
struct server_id pid;
|
||||
fstring ip_addr;
|
||||
fstring ip_addr_str;
|
||||
time_t connect_start;
|
||||
};
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
Samba utility functions
|
||||
Copyright (C) Andrew Tridgell 1992-1998
|
||||
Copyright (C) Tim Potter 2000-2001
|
||||
Copyright (C) Jeremy Allison 1992-2005
|
||||
Copyright (C) Jeremy Allison 1992-2007
|
||||
|
||||
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
|
||||
@ -26,7 +26,35 @@
|
||||
particular modules */
|
||||
static int client_fd = -1;
|
||||
/* What to print out on a client disconnect error. */
|
||||
static char client_ip_string[16];
|
||||
static char client_ip_string[INET6_ADDRSTRLEN];
|
||||
|
||||
/****************************************************************************
|
||||
Pritn out an IPv4 or IPv6 address from a struct sockaddr_storage.
|
||||
****************************************************************************/
|
||||
|
||||
char *print_sockaddr(char *dest,
|
||||
size_t destlen,
|
||||
struct sockaddr_storage *psa)
|
||||
{
|
||||
if (destlen > 0) {
|
||||
dest[0] = '\0';
|
||||
}
|
||||
#ifdef AF_INET6
|
||||
if (psa->ss_family == AF_INET6) {
|
||||
inet_ntop(AF_INET6,
|
||||
&((struct sockaddr_in6 *)psa)->sin6_addr,
|
||||
dest,
|
||||
destlen);
|
||||
}
|
||||
#endif
|
||||
if (psa->ss_family == AF_INET) {
|
||||
inet_ntop(AF_INET,
|
||||
&((struct sockaddr_in *)psa)->sin_addr,
|
||||
dest,
|
||||
destlen);
|
||||
}
|
||||
return dest;
|
||||
}
|
||||
|
||||
void client_setfd(int fd)
|
||||
{
|
||||
@ -38,44 +66,49 @@ void client_setfd(int fd)
|
||||
|
||||
static char *get_socket_addr(int fd)
|
||||
{
|
||||
struct sockaddr sa;
|
||||
struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);
|
||||
struct sockaddr_storage sa;
|
||||
socklen_t length = sizeof(sa);
|
||||
static fstring addr_buf;
|
||||
static char addr_buf[INET6_ADDRSTRLEN];
|
||||
|
||||
fstrcpy(addr_buf,"0.0.0.0");
|
||||
addr_buf[0] = '\0';
|
||||
|
||||
if (fd == -1) {
|
||||
return addr_buf;
|
||||
}
|
||||
|
||||
if (getsockname(fd, &sa, &length) < 0) {
|
||||
if (getsockname(fd, (struct sockaddr *)&sa, &length) < 0) {
|
||||
DEBUG(0,("getsockname failed. Error was %s\n",
|
||||
strerror(errno) ));
|
||||
return addr_buf;
|
||||
}
|
||||
|
||||
fstrcpy(addr_buf,(char *)inet_ntoa(sockin->sin_addr));
|
||||
|
||||
return addr_buf;
|
||||
return print_sockaddr(addr_buf, sizeof(addr_buf), &sa);
|
||||
}
|
||||
|
||||
static int get_socket_port(int fd)
|
||||
{
|
||||
struct sockaddr sa;
|
||||
struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);
|
||||
struct sockaddr_storage sa;
|
||||
socklen_t length = sizeof(sa);
|
||||
|
||||
if (fd == -1)
|
||||
if (fd == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (getsockname(fd, &sa, &length) < 0) {
|
||||
if (getsockname(fd, (struct sockaddr *)&sa, &length) < 0) {
|
||||
DEBUG(0,("getpeername failed. Error was %s\n",
|
||||
strerror(errno) ));
|
||||
return -1;
|
||||
}
|
||||
|
||||
return ntohs(sockin->sin_port);
|
||||
#ifdef AF_INET6
|
||||
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;
|
||||
}
|
||||
|
||||
char *client_name(void)
|
||||
@ -98,26 +131,6 @@ int client_socket_port(void)
|
||||
return get_socket_port(client_fd);
|
||||
}
|
||||
|
||||
struct in_addr *client_inaddr(struct sockaddr *sa)
|
||||
{
|
||||
struct sockaddr_in *sockin = (struct sockaddr_in *) (sa);
|
||||
socklen_t length = sizeof(*sa);
|
||||
|
||||
if (getpeername(client_fd, sa, &length) < 0) {
|
||||
DEBUG(0,("getpeername failed. Error was %s\n",
|
||||
strerror(errno) ));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &sockin->sin_addr;
|
||||
}
|
||||
|
||||
/* the last IP received from */
|
||||
struct in_addr lastip;
|
||||
|
||||
/* the last port received from */
|
||||
int lastport=0;
|
||||
|
||||
int smb_read_error = 0;
|
||||
|
||||
/****************************************************************************
|
||||
@ -281,35 +294,42 @@ void set_socket_options(int fd, const char *options)
|
||||
Read from a socket.
|
||||
****************************************************************************/
|
||||
|
||||
ssize_t read_udp_socket(int fd,char *buf,size_t len)
|
||||
ssize_t read_udp_v4_socket(int fd,
|
||||
char *buf,
|
||||
size_t len,
|
||||
struct sockaddr_storage *psa)
|
||||
{
|
||||
ssize_t ret;
|
||||
struct sockaddr_in sock;
|
||||
socklen_t socklen = sizeof(sock);
|
||||
socklen_t socklen = sizeof(*psa);
|
||||
struct sockaddr_in *si = (struct sockaddr_in *)psa;
|
||||
|
||||
memset((char *)psa,'\0',socklen);
|
||||
|
||||
memset((char *)&sock,'\0',socklen);
|
||||
memset((char *)&lastip,'\0',sizeof(lastip));
|
||||
ret = (ssize_t)sys_recvfrom(fd,buf,len,0,
|
||||
(struct sockaddr *)&sock,&socklen);
|
||||
(struct sockaddr *)psa,&socklen);
|
||||
if (ret <= 0) {
|
||||
/* Don't print a low debug error for a non-blocking socket. */
|
||||
if (errno == EAGAIN) {
|
||||
DEBUG(10,("read socket returned EAGAIN. ERRNO=%s\n",
|
||||
strerror(errno)));
|
||||
DEBUG(10,("read_udp_v4_socket: returned EAGAIN\n"));
|
||||
} else {
|
||||
DEBUG(2,("read socket failed. ERRNO=%s\n",
|
||||
DEBUG(2,("read_udp_v4_socket: failed. errno=%s\n",
|
||||
strerror(errno)));
|
||||
}
|
||||
return(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
lastip = sock.sin_addr;
|
||||
lastport = ntohs(sock.sin_port);
|
||||
if (psa->ss_family != AF_INET) {
|
||||
DEBUG(2,("read_udp_v4_socket:: invalid address family %d "
|
||||
"(not IPv4)\n", (int)psa->ss_family));
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEBUG(10,("read_udp_socket: lastip %s lastport %d read: %lu\n",
|
||||
inet_ntoa(lastip), lastport, (unsigned long)ret));
|
||||
DEBUG(10,("read_udp_socket: ip %s port %d read: %lu\n",
|
||||
inet_ntoa(si->sin_addr),
|
||||
si->sin_port,
|
||||
(unsigned long)ret));
|
||||
|
||||
return(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -1232,7 +1252,6 @@ int open_udp_socket(const char *host, int port)
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
Matchname - determine if host name matches IP address. Used to
|
||||
confirm a hostname lookup to prevent spoof attacks.
|
||||
|
@ -2,6 +2,7 @@
|
||||
Unix SMB/CIFS implementation.
|
||||
NBT netbios library routines
|
||||
Copyright (C) Andrew Tridgell 1994-1998
|
||||
Copyright (C) Jeremy Allison 2007
|
||||
|
||||
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
|
||||
@ -20,9 +21,6 @@
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
extern struct in_addr lastip;
|
||||
extern int lastport;
|
||||
|
||||
int num_good_sends = 0;
|
||||
int num_good_receives = 0;
|
||||
|
||||
@ -109,19 +107,22 @@ void debug_nmb_packet(struct packet_struct *p)
|
||||
struct nmb_packet *nmb = &p->packet.nmb;
|
||||
|
||||
if( DEBUGLVL( 4 ) ) {
|
||||
dbgtext( "nmb packet from %s(%d) header: id=%d opcode=%s(%d) response=%s\n",
|
||||
dbgtext( "nmb packet from %s(%d) header: id=%d "
|
||||
"opcode=%s(%d) response=%s\n",
|
||||
inet_ntoa(p->ip), p->port,
|
||||
nmb->header.name_trn_id,
|
||||
lookup_opcode_name(nmb->header.opcode),
|
||||
nmb->header.opcode,
|
||||
BOOLSTR(nmb->header.response) );
|
||||
dbgtext( " header: flags: bcast=%s rec_avail=%s rec_des=%s trunc=%s auth=%s\n",
|
||||
dbgtext( " header: flags: bcast=%s rec_avail=%s "
|
||||
"rec_des=%s trunc=%s auth=%s\n",
|
||||
BOOLSTR(nmb->header.nm_flags.bcast),
|
||||
BOOLSTR(nmb->header.nm_flags.recursion_available),
|
||||
BOOLSTR(nmb->header.nm_flags.recursion_desired),
|
||||
BOOLSTR(nmb->header.nm_flags.trunc),
|
||||
BOOLSTR(nmb->header.nm_flags.authoritative) );
|
||||
dbgtext( " header: rcode=%d qdcount=%d ancount=%d nscount=%d arcount=%d\n",
|
||||
dbgtext( " header: rcode=%d qdcount=%d ancount=%d "
|
||||
"nscount=%d arcount=%d\n",
|
||||
nmb->header.rcode,
|
||||
nmb->header.qdcount,
|
||||
nmb->header.ancount,
|
||||
@ -161,11 +162,12 @@ static BOOL handle_name_ptrs(unsigned char *ubuf,int *offset,int length,
|
||||
(*ret) += 2;
|
||||
(*got_pointer)=True;
|
||||
(*offset) = ((ubuf[*offset] & ~0xC0)<<8) | ubuf[(*offset)+1];
|
||||
if (loop_count++ == 10 || (*offset) < 0 || (*offset)>(length-2)) {
|
||||
return(False);
|
||||
if (loop_count++ == 10 ||
|
||||
(*offset) < 0 || (*offset)>(length-2)) {
|
||||
return False;
|
||||
}
|
||||
}
|
||||
return(True);
|
||||
return True;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
@ -214,7 +216,8 @@ static int parse_nmb_name(char *inbuf,int ofs,int length, struct nmb_name *name)
|
||||
name->name[n] = 0;
|
||||
|
||||
if (n==MAX_NETBIOSNAME_LEN) {
|
||||
/* parse out the name type, its always in the 16th byte of the name */
|
||||
/* parse out the name type, its always
|
||||
* in the 16th byte of the name */
|
||||
name->name_type = ((unsigned char)name->name[15]) & 0xff;
|
||||
|
||||
/* remove trailing spaces */
|
||||
@ -268,7 +271,8 @@ void put_name(char *dest, const char *name, int pad, unsigned int name_type)
|
||||
{
|
||||
size_t len = strlen(name);
|
||||
|
||||
memcpy(dest, name, (len < MAX_NETBIOSNAME_LEN) ? len : MAX_NETBIOSNAME_LEN - 1);
|
||||
memcpy(dest, name, (len < MAX_NETBIOSNAME_LEN) ?
|
||||
len : MAX_NETBIOSNAME_LEN - 1);
|
||||
if (len < MAX_NETBIOSNAME_LEN - 1) {
|
||||
memset(dest + len, pad, MAX_NETBIOSNAME_LEN - 1 - len);
|
||||
}
|
||||
@ -282,6 +286,8 @@ void put_name(char *dest, const char *name, int pad, unsigned int name_type)
|
||||
Compressed names are really weird. The "compression" doubles the
|
||||
size. The idea is that it also means that compressed names conform
|
||||
to the doman name system. See RFC1002.
|
||||
|
||||
If buf == NULL this is a length calculation.
|
||||
******************************************************************/
|
||||
|
||||
static int put_nmb_name(char *buf,int offset,struct nmb_name *name)
|
||||
@ -297,22 +303,30 @@ static int put_nmb_name(char *buf,int offset,struct nmb_name *name)
|
||||
put_name(buf1, name->name, ' ', name->name_type);
|
||||
}
|
||||
|
||||
if (buf) {
|
||||
buf[offset] = 0x20;
|
||||
}
|
||||
|
||||
ret = 34;
|
||||
|
||||
for (m=0;m<MAX_NETBIOSNAME_LEN;m++) {
|
||||
if (buf) {
|
||||
buf[offset+1+2*m] = 'A' + ((buf1[m]>>4)&0xF);
|
||||
buf[offset+2+2*m] = 'A' + (buf1[m]&0xF);
|
||||
}
|
||||
}
|
||||
offset += 33;
|
||||
|
||||
if (buf) {
|
||||
buf[offset] = 0;
|
||||
}
|
||||
|
||||
if (name->scope[0]) {
|
||||
/* XXXX this scope handling needs testing */
|
||||
ret += strlen(name->scope) + 1;
|
||||
safe_strcpy(&buf[offset+1],name->scope,sizeof(name->scope));
|
||||
if (buf) {
|
||||
safe_strcpy(&buf[offset+1],name->scope,
|
||||
sizeof(name->scope));
|
||||
|
||||
p = &buf[offset+1];
|
||||
while ((p = strchr_m(p,'.'))) {
|
||||
@ -322,8 +336,9 @@ static int put_nmb_name(char *buf,int offset,struct nmb_name *name)
|
||||
}
|
||||
buf[offset] = strlen(&buf[offset+1]);
|
||||
}
|
||||
}
|
||||
|
||||
return(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
@ -341,7 +356,8 @@ char *nmb_namestr(const struct nmb_name *n)
|
||||
if (!n->scope[0])
|
||||
slprintf(p,sizeof(fstring)-1, "%s<%02x>",name,n->name_type);
|
||||
else
|
||||
slprintf(p,sizeof(fstring)-1, "%s<%02x>.%s",name,n->name_type,n->scope);
|
||||
slprintf(p,sizeof(fstring)-1, "%s<%02x>.%s",
|
||||
name,n->name_type,n->scope);
|
||||
|
||||
i = (i+1)%4;
|
||||
return(p);
|
||||
@ -363,7 +379,8 @@ static BOOL parse_alloc_res_rec(char *inbuf,int *offset,int length,
|
||||
memset((char *)*recs,'\0',sizeof(**recs)*count);
|
||||
|
||||
for (i=0;i<count;i++) {
|
||||
int l = parse_nmb_name(inbuf,*offset,length,&(*recs)[i].rr_name);
|
||||
int l = parse_nmb_name(inbuf,*offset,length,
|
||||
&(*recs)[i].rr_name);
|
||||
(*offset) += l;
|
||||
if (!l || (*offset)+10 > length) {
|
||||
SAFE_FREE(*recs);
|
||||
@ -387,6 +404,7 @@ static BOOL parse_alloc_res_rec(char *inbuf,int *offset,int length,
|
||||
|
||||
/*******************************************************************
|
||||
Put a resource record into a packet.
|
||||
If buf == NULL this is a length calculation.
|
||||
******************************************************************/
|
||||
|
||||
static int put_res_rec(char *buf,int offset,struct res_rec *recs,int count)
|
||||
@ -398,38 +416,48 @@ static int put_res_rec(char *buf,int offset,struct res_rec *recs,int count)
|
||||
int l = put_nmb_name(buf,offset,&recs[i].rr_name);
|
||||
offset += l;
|
||||
ret += l;
|
||||
if (buf) {
|
||||
RSSVAL(buf,offset,recs[i].rr_type);
|
||||
RSSVAL(buf,offset+2,recs[i].rr_class);
|
||||
RSIVAL(buf,offset+4,recs[i].ttl);
|
||||
RSSVAL(buf,offset+8,recs[i].rdlength);
|
||||
memcpy(buf+offset+10,recs[i].rdata,recs[i].rdlength);
|
||||
}
|
||||
offset += 10+recs[i].rdlength;
|
||||
ret += 10+recs[i].rdlength;
|
||||
}
|
||||
|
||||
return(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Put a compressed name pointer record into a packet.
|
||||
If buf == NULL this is a length calculation.
|
||||
******************************************************************/
|
||||
|
||||
static int put_compressed_name_ptr(unsigned char *buf,int offset,struct res_rec *rec,int ptr_offset)
|
||||
static int put_compressed_name_ptr(unsigned char *buf,
|
||||
int offset,
|
||||
struct res_rec *rec,
|
||||
int ptr_offset)
|
||||
{
|
||||
int ret=0;
|
||||
if (buf) {
|
||||
buf[offset] = (0xC0 | ((ptr_offset >> 8) & 0xFF));
|
||||
buf[offset+1] = (ptr_offset & 0xFF);
|
||||
}
|
||||
offset += 2;
|
||||
ret += 2;
|
||||
if (buf) {
|
||||
RSSVAL(buf,offset,rec->rr_type);
|
||||
RSSVAL(buf,offset+2,rec->rr_class);
|
||||
RSIVAL(buf,offset+4,rec->ttl);
|
||||
RSSVAL(buf,offset+8,rec->rdlength);
|
||||
memcpy(buf+offset+10,rec->rdata,rec->rdlength);
|
||||
}
|
||||
offset += 10+rec->rdlength;
|
||||
ret += 10+rec->rdlength;
|
||||
|
||||
return(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
@ -467,8 +495,10 @@ static BOOL parse_dgram(char *inbuf,int length,struct dgram_packet *dgram)
|
||||
if (dgram->header.msg_type == 0x10 ||
|
||||
dgram->header.msg_type == 0x11 ||
|
||||
dgram->header.msg_type == 0x12) {
|
||||
offset += parse_nmb_name(inbuf,offset,length,&dgram->source_name);
|
||||
offset += parse_nmb_name(inbuf,offset,length,&dgram->dest_name);
|
||||
offset += parse_nmb_name(inbuf,offset,length,
|
||||
&dgram->source_name);
|
||||
offset += parse_nmb_name(inbuf,offset,length,
|
||||
&dgram->dest_name);
|
||||
}
|
||||
|
||||
if (offset >= length || (length-offset > sizeof(dgram->data)))
|
||||
@ -478,7 +508,8 @@ static BOOL parse_dgram(char *inbuf,int length,struct dgram_packet *dgram)
|
||||
memcpy(dgram->data,inbuf+offset,dgram->datasize);
|
||||
|
||||
/* Paranioa. Ensure the last 2 bytes in the dgram buffer are
|
||||
zero. This should be true anyway, just enforce it for paranioa sake. JRA. */
|
||||
zero. This should be true anyway, just enforce it for
|
||||
paranioa sake. JRA. */
|
||||
SMB_ASSERT(dgram->datasize <= (sizeof(dgram->data)-2));
|
||||
memset(&dgram->data[sizeof(dgram->data)-2], '\0', 2);
|
||||
|
||||
@ -519,7 +550,8 @@ static BOOL parse_nmb(char *inbuf,int length,struct nmb_packet *nmb)
|
||||
nmb->header.arcount = RSVAL(inbuf,10);
|
||||
|
||||
if (nmb->header.qdcount) {
|
||||
offset = parse_nmb_name(inbuf,12,length,&nmb->question.question_name);
|
||||
offset = parse_nmb_name(inbuf,12,length,
|
||||
&nmb->question.question_name);
|
||||
if (!offset)
|
||||
return(False);
|
||||
|
||||
@ -534,16 +566,19 @@ static BOOL parse_nmb(char *inbuf,int length,struct nmb_packet *nmb)
|
||||
}
|
||||
|
||||
/* and any resource records */
|
||||
if (nmb->header.ancount && !parse_alloc_res_rec(inbuf,&offset,length,&nmb->answers,
|
||||
if (nmb->header.ancount &&
|
||||
!parse_alloc_res_rec(inbuf,&offset,length,&nmb->answers,
|
||||
nmb->header.ancount))
|
||||
return(False);
|
||||
|
||||
if (nmb->header.nscount && !parse_alloc_res_rec(inbuf,&offset,length,&nmb->nsrecs,
|
||||
if (nmb->header.nscount &&
|
||||
!parse_alloc_res_rec(inbuf,&offset,length,&nmb->nsrecs,
|
||||
nmb->header.nscount))
|
||||
return(False);
|
||||
|
||||
if (nmb->header.arcount && !parse_alloc_res_rec(inbuf,&offset,length,&nmb->additional,
|
||||
nmb->header.arcount))
|
||||
if (nmb->header.arcount &&
|
||||
!parse_alloc_res_rec(inbuf,&offset,length,
|
||||
&nmb->additional, nmb->header.arcount))
|
||||
return(False);
|
||||
|
||||
return(True);
|
||||
@ -582,19 +617,22 @@ static struct packet_struct *copy_nmb_packet(struct packet_struct *packet)
|
||||
/* Now copy any resource records. */
|
||||
|
||||
if (nmb->answers) {
|
||||
if((copy_nmb->answers = SMB_MALLOC_ARRAY(struct res_rec,nmb->header.ancount)) == NULL)
|
||||
if((copy_nmb->answers = SMB_MALLOC_ARRAY(
|
||||
struct res_rec,nmb->header.ancount)) == NULL)
|
||||
goto free_and_exit;
|
||||
memcpy((char *)copy_nmb->answers, (char *)nmb->answers,
|
||||
nmb->header.ancount * sizeof(struct res_rec));
|
||||
}
|
||||
if (nmb->nsrecs) {
|
||||
if((copy_nmb->nsrecs = SMB_MALLOC_ARRAY(struct res_rec, nmb->header.nscount)) == NULL)
|
||||
if((copy_nmb->nsrecs = SMB_MALLOC_ARRAY(
|
||||
struct res_rec, nmb->header.nscount)) == NULL)
|
||||
goto free_and_exit;
|
||||
memcpy((char *)copy_nmb->nsrecs, (char *)nmb->nsrecs,
|
||||
nmb->header.nscount * sizeof(struct res_rec));
|
||||
}
|
||||
if (nmb->additional) {
|
||||
if((copy_nmb->additional = SMB_MALLOC_ARRAY(struct res_rec, nmb->header.arcount)) == NULL)
|
||||
if((copy_nmb->additional = SMB_MALLOC_ARRAY(
|
||||
struct res_rec, nmb->header.arcount)) == NULL)
|
||||
goto free_and_exit;
|
||||
memcpy((char *)copy_nmb->additional, (char *)nmb->additional,
|
||||
nmb->header.arcount * sizeof(struct res_rec));
|
||||
@ -692,7 +730,9 @@ void free_packet(struct packet_struct *packet)
|
||||
******************************************************************/
|
||||
|
||||
struct packet_struct *parse_packet(char *buf,int length,
|
||||
enum packet_type packet_type)
|
||||
enum packet_type packet_type,
|
||||
struct in_addr ip,
|
||||
int port)
|
||||
{
|
||||
struct packet_struct *p;
|
||||
BOOL ok=False;
|
||||
@ -703,8 +743,8 @@ struct packet_struct *parse_packet(char *buf,int length,
|
||||
|
||||
p->next = NULL;
|
||||
p->prev = NULL;
|
||||
p->ip = lastip;
|
||||
p->port = lastport;
|
||||
p->ip = ip;
|
||||
p->port = port;
|
||||
p->locked = False;
|
||||
p->timestamp = time(NULL);
|
||||
p->packet_type = packet_type;
|
||||
@ -735,14 +775,21 @@ struct packet_struct *parse_packet(char *buf,int length,
|
||||
struct packet_struct *read_packet(int fd,enum packet_type packet_type)
|
||||
{
|
||||
struct packet_struct *packet;
|
||||
struct sockaddr_storage sa;
|
||||
struct sockaddr_in *si = (struct sockaddr_in *)&sa;
|
||||
char buf[MAX_DGRAM_SIZE];
|
||||
int length;
|
||||
|
||||
length = read_udp_socket(fd,buf,sizeof(buf));
|
||||
if (length < MIN_DGRAM_SIZE)
|
||||
return(NULL);
|
||||
length = read_udp_v4_socket(fd,buf,sizeof(buf),&sa);
|
||||
if (length < MIN_DGRAM_SIZE || sa.ss_family != AF_INET) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
packet = parse_packet(buf, length, packet_type);
|
||||
packet = parse_packet(buf,
|
||||
length,
|
||||
packet_type,
|
||||
si->sin_addr,
|
||||
si->sin_port);
|
||||
if (!packet)
|
||||
return NULL;
|
||||
|
||||
@ -780,7 +827,8 @@ static BOOL send_udp(int fd,char *buf,int len,struct in_addr ip,int port)
|
||||
*/
|
||||
|
||||
for (i = 0; i < 5; i++) {
|
||||
ret = (sendto(fd,buf,len,0,(struct sockaddr *)&sock_out, sizeof(sock_out)) >= 0);
|
||||
ret = (sendto(fd,buf,len,0,(struct sockaddr *)&sock_out,
|
||||
sizeof(sock_out)) >= 0);
|
||||
if (ret || errno != ECONNREFUSED)
|
||||
break;
|
||||
}
|
||||
@ -797,27 +845,17 @@ static BOOL send_udp(int fd,char *buf,int len,struct in_addr ip,int port)
|
||||
|
||||
/*******************************************************************
|
||||
Build a dgram packet ready for sending.
|
||||
|
||||
XXXX This currently doesn't handle packets too big for one
|
||||
datagram. It should split them and use the packet_offset, more and
|
||||
first flags to handle the fragmentation. Yuck.
|
||||
|
||||
[...but it isn't clear that we would ever need to send a
|
||||
a fragmented NBT Datagram. The IP layer does its own
|
||||
fragmentation to ensure that messages can fit into the path
|
||||
MTU. It *is* important to be able to receive and rebuild
|
||||
fragmented NBT datagrams, just in case someone out there
|
||||
really has implemented this 'feature'. crh -)------ ]
|
||||
|
||||
If buf == NULL this is a length calculation.
|
||||
******************************************************************/
|
||||
|
||||
static int build_dgram(char *buf,struct packet_struct *p)
|
||||
static int build_dgram(char *buf, size_t len, struct packet_struct *p)
|
||||
{
|
||||
struct dgram_packet *dgram = &p->packet.dgram;
|
||||
unsigned char *ubuf = (unsigned char *)buf;
|
||||
int offset=0;
|
||||
|
||||
/* put in the header */
|
||||
if (buf) {
|
||||
ubuf[0] = dgram->header.msg_type;
|
||||
ubuf[1] = (((int)dgram->header.flags.node_type)<<2);
|
||||
if (dgram->header.flags.more)
|
||||
@ -828,6 +866,7 @@ static int build_dgram(char *buf,struct packet_struct *p)
|
||||
putip(ubuf+4,(char *)&dgram->header.source_ip);
|
||||
RSSVAL(ubuf,8,dgram->header.source_port);
|
||||
RSSVAL(ubuf,12,dgram->header.packet_offset);
|
||||
}
|
||||
|
||||
offset = 14;
|
||||
|
||||
@ -838,7 +877,9 @@ static int build_dgram(char *buf,struct packet_struct *p)
|
||||
offset += put_nmb_name((char *)ubuf,offset,&dgram->dest_name);
|
||||
}
|
||||
|
||||
if (buf) {
|
||||
memcpy(ubuf+offset,dgram->data,dgram->datasize);
|
||||
}
|
||||
offset += dgram->datasize;
|
||||
|
||||
/* automatically set the dgm_length
|
||||
@ -846,9 +887,11 @@ static int build_dgram(char *buf,struct packet_struct *p)
|
||||
* include the fourteen-byte header. crh
|
||||
*/
|
||||
dgram->header.dgm_length = (offset - 14);
|
||||
if (buf) {
|
||||
RSSVAL(ubuf,10,dgram->header.dgm_length);
|
||||
}
|
||||
|
||||
return(offset);
|
||||
return offset;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
@ -879,20 +922,21 @@ BOOL nmb_name_equal(struct nmb_name *n1, struct nmb_name *n2)
|
||||
|
||||
/*******************************************************************
|
||||
Build a nmb packet ready for sending.
|
||||
|
||||
XXXX this currently relies on not being passed something that expands
|
||||
to a packet too big for the buffer. Eventually this should be
|
||||
changed to set the trunc bit so the receiver can request the rest
|
||||
via tcp (when that becomes supported)
|
||||
If buf == NULL this is a length calculation.
|
||||
******************************************************************/
|
||||
|
||||
static int build_nmb(char *buf,struct packet_struct *p)
|
||||
static int build_nmb(char *buf, size_t len, struct packet_struct *p)
|
||||
{
|
||||
struct nmb_packet *nmb = &p->packet.nmb;
|
||||
unsigned char *ubuf = (unsigned char *)buf;
|
||||
int offset=0;
|
||||
|
||||
if (len && len < 12) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* put in the header */
|
||||
if (buf) {
|
||||
RSSVAL(ubuf,offset,nmb->header.name_trn_id);
|
||||
ubuf[offset+2] = (nmb->header.opcode & 0xF) << 3;
|
||||
if (nmb->header.response)
|
||||
@ -915,23 +959,53 @@ static int build_nmb(char *buf,struct packet_struct *p)
|
||||
RSSVAL(ubuf,offset+6,nmb->header.ancount);
|
||||
RSSVAL(ubuf,offset+8,nmb->header.nscount);
|
||||
RSSVAL(ubuf,offset+10,nmb->header.arcount);
|
||||
}
|
||||
|
||||
offset += 12;
|
||||
if (nmb->header.qdcount) {
|
||||
/* XXXX this doesn't handle a qdcount of > 1 */
|
||||
offset += put_nmb_name((char *)ubuf,offset,&nmb->question.question_name);
|
||||
if (len) {
|
||||
/* Length check. */
|
||||
int extra = put_nmb_name(NULL,offset,
|
||||
&nmb->question.question_name);
|
||||
if (offset + extra > len) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
offset += put_nmb_name((char *)ubuf,offset,
|
||||
&nmb->question.question_name);
|
||||
if (buf) {
|
||||
RSSVAL(ubuf,offset,nmb->question.question_type);
|
||||
RSSVAL(ubuf,offset+2,nmb->question.question_class);
|
||||
}
|
||||
offset += 4;
|
||||
}
|
||||
|
||||
if (nmb->header.ancount)
|
||||
if (nmb->header.ancount) {
|
||||
if (len) {
|
||||
/* Length check. */
|
||||
int extra = put_res_rec(NULL,offset,nmb->answers,
|
||||
nmb->header.ancount);
|
||||
if (offset + extra > len) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
offset += put_res_rec((char *)ubuf,offset,nmb->answers,
|
||||
nmb->header.ancount);
|
||||
}
|
||||
|
||||
if (nmb->header.nscount)
|
||||
if (nmb->header.nscount) {
|
||||
if (len) {
|
||||
/* Length check. */
|
||||
int extra = put_res_rec(NULL,offset,nmb->nsrecs,
|
||||
nmb->header.nscount);
|
||||
if (offset + extra > len) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
offset += put_res_rec((char *)ubuf,offset,nmb->nsrecs,
|
||||
nmb->header.nscount);
|
||||
}
|
||||
|
||||
/*
|
||||
* The spec says we must put compressed name pointers
|
||||
@ -948,30 +1022,46 @@ static int build_nmb(char *buf,struct packet_struct *p)
|
||||
(nmb->header.opcode == NMB_NAME_MULTIHOMED_REG_OPCODE)) &&
|
||||
(nmb->header.arcount == 1)) {
|
||||
|
||||
offset += put_compressed_name_ptr(ubuf,offset,nmb->additional,12);
|
||||
|
||||
if (len) {
|
||||
/* Length check. */
|
||||
int extra = put_compressed_name_ptr(NULL,offset,
|
||||
nmb->additional,12);
|
||||
if (offset + extra > len) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
offset += put_compressed_name_ptr(ubuf,offset,
|
||||
nmb->additional,12);
|
||||
} else if (nmb->header.arcount) {
|
||||
if (len) {
|
||||
/* Length check. */
|
||||
int extra = put_res_rec(NULL,offset,nmb->additional,
|
||||
nmb->header.arcount);
|
||||
if (offset + extra > len) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
offset += put_res_rec((char *)ubuf,offset,nmb->additional,
|
||||
nmb->header.arcount);
|
||||
}
|
||||
return(offset);
|
||||
return offset;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Linearise a packet.
|
||||
******************************************************************/
|
||||
|
||||
int build_packet(char *buf, struct packet_struct *p)
|
||||
int build_packet(char *buf, size_t buflen, struct packet_struct *p)
|
||||
{
|
||||
int len = 0;
|
||||
|
||||
switch (p->packet_type) {
|
||||
case NMB_PACKET:
|
||||
len = build_nmb(buf,p);
|
||||
len = build_nmb(buf,buflen,p);
|
||||
break;
|
||||
|
||||
case DGRAM_PACKET:
|
||||
len = build_dgram(buf,p);
|
||||
len = build_dgram(buf,buflen,p);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -989,7 +1079,7 @@ BOOL send_packet(struct packet_struct *p)
|
||||
|
||||
memset(buf,'\0',sizeof(buf));
|
||||
|
||||
len = build_packet(buf, p);
|
||||
len = build_packet(buf, sizeof(buf), p);
|
||||
|
||||
if (!len)
|
||||
return(False);
|
||||
@ -1015,7 +1105,8 @@ struct packet_struct *receive_packet(int fd,enum packet_type type,int t)
|
||||
|
||||
if ((ret = sys_select_intr(fd+1,&fds,NULL,NULL,&timeout)) == -1) {
|
||||
/* errno should be EBADF or EINVAL. */
|
||||
DEBUG(0,("select returned -1, errno = %s (%d)\n", strerror(errno), errno));
|
||||
DEBUG(0,("select returned -1, errno = %s (%d)\n",
|
||||
strerror(errno), errno));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -1057,7 +1148,8 @@ struct packet_struct *receive_nmb_packet(int fd, int t, int trn_id)
|
||||
The timeout is in milliseconds.
|
||||
***************************************************************************/
|
||||
|
||||
struct packet_struct *receive_dgram_packet(int fd, int t, const char *mailslot_name)
|
||||
struct packet_struct *receive_dgram_packet(int fd, int t,
|
||||
const char *mailslot_name)
|
||||
{
|
||||
struct packet_struct *p;
|
||||
|
||||
@ -1127,7 +1219,8 @@ static unsigned char sort_ip[4];
|
||||
|
||||
static int name_query_comp(unsigned char *p1, unsigned char *p2)
|
||||
{
|
||||
return matching_quad_bits(p2+2, sort_ip) - matching_quad_bits(p1+2, sort_ip);
|
||||
return matching_quad_bits(p2+2, sort_ip) -
|
||||
matching_quad_bits(p1+2, sort_ip);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -29,13 +29,12 @@ struct unexpected_key {
|
||||
int count;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
all unexpected packets are passed in here, to be stored in a unexpected
|
||||
All unexpected packets are passed in here, to be stored in a unexpected
|
||||
packet database. This allows nmblookup and other tools to receive packets
|
||||
erroneoously sent to the wrong port by broken MS systems
|
||||
**************************************************************************/
|
||||
erroneoously sent to the wrong port by broken MS systems.
|
||||
**************************************************************************/
|
||||
|
||||
void unexpected_packet(struct packet_struct *p)
|
||||
{
|
||||
static int count;
|
||||
@ -43,6 +42,7 @@ void unexpected_packet(struct packet_struct *p)
|
||||
struct unexpected_key key;
|
||||
char buf[1024];
|
||||
int len=0;
|
||||
uint32_t enc_ip;
|
||||
|
||||
if (!tdbd) {
|
||||
tdbd = tdb_open_log(lock_path("unexpected.tdb"), 0,
|
||||
@ -56,7 +56,12 @@ void unexpected_packet(struct packet_struct *p)
|
||||
|
||||
memset(buf,'\0',sizeof(buf));
|
||||
|
||||
len = build_packet(buf, p);
|
||||
/* Encode the ip addr and port. */
|
||||
enc_ip = ntohl(p->ip.s_addr);
|
||||
SIVAL(buf,0,enc_ip);
|
||||
SSVAL(buf,4,p->port);
|
||||
|
||||
len = build_packet(&buf[6], sizeof(buf)-6, p) + 6;
|
||||
|
||||
key.packet_type = p->packet_type;
|
||||
key.timestamp = p->timestamp;
|
||||
@ -74,8 +79,9 @@ void unexpected_packet(struct packet_struct *p)
|
||||
static time_t lastt;
|
||||
|
||||
/****************************************************************************
|
||||
delete the record if it is too old
|
||||
**************************************************************************/
|
||||
Delete the record if it is too old.
|
||||
**************************************************************************/
|
||||
|
||||
static int traverse_fn(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void *state)
|
||||
{
|
||||
struct unexpected_key key;
|
||||
@ -91,8 +97,9 @@ static int traverse_fn(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void *st
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
delete all old unexpected packets
|
||||
**************************************************************************/
|
||||
Delete all old unexpected packets.
|
||||
**************************************************************************/
|
||||
|
||||
void clear_unexpected(time_t t)
|
||||
{
|
||||
if (!tdbd) return;
|
||||
@ -112,18 +119,35 @@ static enum packet_type match_type;
|
||||
static const char *match_name;
|
||||
|
||||
/****************************************************************************
|
||||
tdb traversal fn to find a matching 137 packet
|
||||
**************************************************************************/
|
||||
tdb traversal fn to find a matching 137 packet.
|
||||
**************************************************************************/
|
||||
|
||||
static int traverse_match(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void *state)
|
||||
{
|
||||
struct unexpected_key key;
|
||||
struct in_addr ip;
|
||||
uint32_t enc_ip;
|
||||
int port;
|
||||
struct packet_struct *p;
|
||||
|
||||
memcpy(&key, kbuf.dptr, sizeof(key));
|
||||
|
||||
if (key.packet_type != match_type) return 0;
|
||||
|
||||
p = parse_packet((char *)dbuf.dptr, dbuf.dsize, match_type);
|
||||
if (dbuf.dsize < 6) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Decode the ip addr and port. */
|
||||
enc_ip = IVAL(dbuf.dptr,0);
|
||||
ip.s_addr = htonl(enc_ip);
|
||||
port = SVAL(dbuf.dptr,4);
|
||||
|
||||
p = parse_packet((char *)&dbuf.dptr[6],
|
||||
dbuf.dsize-6,
|
||||
match_type,
|
||||
ip,
|
||||
port);
|
||||
|
||||
if ((match_type == NMB_PACKET &&
|
||||
p->packet.nmb.header.name_trn_id == match_id) ||
|
||||
@ -138,10 +162,10 @@ static int traverse_match(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
check for a particular packet in the unexpected packet queue
|
||||
**************************************************************************/
|
||||
Check for a particular packet in the unexpected packet queue.
|
||||
**************************************************************************/
|
||||
|
||||
struct packet_struct *receive_unexpected(enum packet_type packet_type, int id,
|
||||
const char *mailslot_name)
|
||||
{
|
||||
|
@ -62,8 +62,6 @@ BOOL session_claim(user_struct *vuser)
|
||||
{
|
||||
TDB_DATA key, data;
|
||||
int i = 0;
|
||||
struct sockaddr sa;
|
||||
struct in_addr *client_ip;
|
||||
struct sessionid sessionid;
|
||||
struct server_id pid = procid_self();
|
||||
fstring keystr;
|
||||
@ -172,11 +170,9 @@ BOOL session_claim(user_struct *vuser)
|
||||
sessionid.uid = vuser->uid;
|
||||
sessionid.gid = vuser->gid;
|
||||
fstrcpy(sessionid.remote_machine, get_remote_machine_name());
|
||||
fstrcpy(sessionid.ip_addr, client_addr());
|
||||
fstrcpy(sessionid.ip_addr_str, client_addr());
|
||||
sessionid.connect_start = time(NULL);
|
||||
|
||||
client_ip = client_inaddr(&sa);
|
||||
|
||||
if (!smb_pam_claim_session(sessionid.username, sessionid.id_str,
|
||||
sessionid.hostname)) {
|
||||
DEBUG(1,("pam_session rejected the session for %s [%s]\n",
|
||||
@ -201,7 +197,7 @@ BOOL session_claim(user_struct *vuser)
|
||||
|
||||
if (lp_utmp()) {
|
||||
sys_utmp_claim(sessionid.username, sessionid.hostname,
|
||||
client_ip,
|
||||
sessionid.ip_addr_str,
|
||||
sessionid.id_str, sessionid.id_num);
|
||||
}
|
||||
|
||||
@ -224,7 +220,6 @@ void session_yield(user_struct *vuser)
|
||||
{
|
||||
TDB_DATA key;
|
||||
struct sessionid sessionid;
|
||||
struct in_addr *client_ip;
|
||||
struct db_context *ctx;
|
||||
struct db_record *rec;
|
||||
|
||||
@ -245,11 +240,9 @@ void session_yield(user_struct *vuser)
|
||||
|
||||
memcpy(&sessionid, rec->value.dptr, sizeof(sessionid));
|
||||
|
||||
client_ip = interpret_addr2(sessionid.ip_addr);
|
||||
|
||||
if (lp_utmp()) {
|
||||
sys_utmp_yield(sessionid.username, sessionid.hostname,
|
||||
client_ip,
|
||||
sessionid.ip_addr_str,
|
||||
sessionid.id_str, sessionid.id_num);
|
||||
}
|
||||
|
||||
|
@ -56,16 +56,23 @@ static int init_sockets_smbd(const char *smb_ports, int listenset[FD_SETSIZE])
|
||||
const char *ptr;
|
||||
|
||||
if(ifip == NULL) {
|
||||
DEBUG(0,("init_sockets_smbd: interface %d has NULL IP address !\n", i));
|
||||
DEBUG(0,("init_sockets_smbd: interface %d has "
|
||||
"NULL IP address !\n", i));
|
||||
continue;
|
||||
}
|
||||
|
||||
for (ptr=ports; next_token(&ptr, tok, " \t,", sizeof(tok)); ) {
|
||||
for (ptr=ports; next_token(&ptr, tok, " \t,",
|
||||
sizeof(tok)); ) {
|
||||
unsigned port = atoi(tok);
|
||||
if (port == 0 || port > 0xffff) {
|
||||
continue;
|
||||
}
|
||||
s = listenset[num_sockets] = open_socket_in(SOCK_STREAM, port, 0, ifip->s_addr, True);
|
||||
s = listenset[num_sockets] =
|
||||
open_socket_in(SOCK_STREAM,
|
||||
port,
|
||||
0,
|
||||
ifip->s_addr,
|
||||
True);
|
||||
if(s == -1)
|
||||
return 0;
|
||||
|
||||
@ -73,18 +80,21 @@ static int init_sockets_smbd(const char *smb_ports, int listenset[FD_SETSIZE])
|
||||
set_socket_options(s,"SO_KEEPALIVE");
|
||||
set_socket_options(s,user_socket_options);
|
||||
|
||||
/* Set server socket to non-blocking for the accept. */
|
||||
/* Set server socket to non-blocking
|
||||
* for the accept. */
|
||||
set_blocking(s,False);
|
||||
|
||||
if (listen(s, SMBD_LISTEN_BACKLOG) == -1) {
|
||||
DEBUG(0,("listen: %s\n",strerror(errno)));
|
||||
DEBUG(0,("listen: %s\n",
|
||||
strerror(errno)));
|
||||
close(s);
|
||||
return 0;
|
||||
}
|
||||
|
||||
num_sockets++;
|
||||
if (num_sockets >= FD_SETSIZE) {
|
||||
DEBUG(0,("init_sockets_smbd: Too many sockets to bind to\n"));
|
||||
DEBUG(0,("init_sockets_smbd: "
|
||||
"Too many sockets to bind to\n"));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -103,7 +113,8 @@ static int init_sockets_smbd(const char *smb_ports, int listenset[FD_SETSIZE])
|
||||
if (port == 0 || port > 0xffff) continue;
|
||||
/* open an incoming socket */
|
||||
s = open_socket_in(SOCK_STREAM, port, 0,
|
||||
interpret_addr(lp_socket_address()),True);
|
||||
interpret_addr(lp_socket_address()),
|
||||
True);
|
||||
if (s == -1)
|
||||
return 0;
|
||||
|
||||
@ -125,7 +136,8 @@ static int init_sockets_smbd(const char *smb_ports, int listenset[FD_SETSIZE])
|
||||
num_sockets++;
|
||||
|
||||
if (num_sockets >= FD_SETSIZE) {
|
||||
DEBUG(0,("init_sockets_smbd: Too many sockets to bind to\n"));
|
||||
DEBUG(0,("init_sockets_smbd: "
|
||||
"Too many sockets to bind to\n"));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -197,4 +209,3 @@ int smbd_sockinit(const char *cmdline_ports, int listenset[FD_SETSIZE],
|
||||
|
||||
return num_sockets;
|
||||
}
|
||||
|
||||
|
@ -113,12 +113,12 @@ Notes:
|
||||
*/
|
||||
|
||||
void sys_utmp_claim(const char *username, const char *hostname,
|
||||
struct in_addr *ipaddr,
|
||||
const char *ip_addr_str,
|
||||
const char *id_str, int id_num)
|
||||
{}
|
||||
|
||||
void sys_utmp_yield(const char *username, const char *hostname,
|
||||
struct in_addr *ipaddr,
|
||||
const char *ip_addr_str,
|
||||
const char *id_str, int id_num)
|
||||
{}
|
||||
|
||||
@ -474,7 +474,7 @@ static int ut_id_encode(int i, char *fourbyte)
|
||||
*/
|
||||
static BOOL sys_utmp_fill(struct utmp *u,
|
||||
const char *username, const char *hostname,
|
||||
struct in_addr *ipaddr,
|
||||
const char *ip_addr_str,
|
||||
const char *id_str, int id_num)
|
||||
{
|
||||
struct timeval timeval;
|
||||
@ -525,9 +525,22 @@ static BOOL sys_utmp_fill(struct utmp *u,
|
||||
#if defined(HAVE_UT_UT_HOST)
|
||||
utmp_strcpy(u->ut_host, hostname, sizeof(u->ut_host));
|
||||
#endif
|
||||
#if defined(HAVE_UT_UT_ADDR)
|
||||
if (ipaddr)
|
||||
u->ut_addr = ipaddr->s_addr;
|
||||
#if defined(AF_INET6) && defined(HAVE_UT_UT_ADDR_V6)
|
||||
memset(&u->ut_addr_v6, '\0', sizeof(u->ut_addr_v6));
|
||||
if (ip_addr_str) {
|
||||
struct in6_addr addr;
|
||||
if (inet_pton(AF_INET6, ip_addr_str, &addr) > 0) {
|
||||
memcpy(&u->ut_addr_v6, &addr, sizeof(addr));
|
||||
}
|
||||
}
|
||||
#elif defined(HAVE_UT_UT_ADDR)
|
||||
memset(&u->ut_addr, '\0', sizeof(u->ut_addr));
|
||||
if (ip_addr_str) {
|
||||
struct in_addr addr;
|
||||
if (inet_pton(AF_INET, ip_addr_str, &addr) > 0) {
|
||||
memcpy(&u->ut_addr, &addr, sizeof(addr));
|
||||
}
|
||||
}
|
||||
/*
|
||||
* "(unsigned long) ut_addr" apparently exists on at least HP-UX 10.20.
|
||||
* Volunteer to implement, please ...
|
||||
@ -549,7 +562,7 @@ static BOOL sys_utmp_fill(struct utmp *u,
|
||||
****************************************************************************/
|
||||
|
||||
void sys_utmp_yield(const char *username, const char *hostname,
|
||||
struct in_addr *ipaddr,
|
||||
const char *ip_addr_str,
|
||||
const char *id_str, int id_num)
|
||||
{
|
||||
struct utmp u;
|
||||
@ -565,7 +578,8 @@ void sys_utmp_yield(const char *username, const char *hostname,
|
||||
u.ut_type = DEAD_PROCESS;
|
||||
#endif
|
||||
|
||||
if (!sys_utmp_fill(&u, username, hostname, ipaddr, id_str, id_num)) return;
|
||||
if (!sys_utmp_fill(&u, username, hostname, ip_addr_str, id_str, id_num))
|
||||
return;
|
||||
|
||||
sys_utmp_update(&u, NULL, False);
|
||||
}
|
||||
@ -575,7 +589,7 @@ void sys_utmp_yield(const char *username, const char *hostname,
|
||||
****************************************************************************/
|
||||
|
||||
void sys_utmp_claim(const char *username, const char *hostname,
|
||||
struct in_addr *ipaddr,
|
||||
const char *ip_addr_str,
|
||||
const char *id_str, int id_num)
|
||||
{
|
||||
struct utmp u;
|
||||
@ -586,7 +600,8 @@ void sys_utmp_claim(const char *username, const char *hostname,
|
||||
u.ut_type = USER_PROCESS;
|
||||
#endif
|
||||
|
||||
if (!sys_utmp_fill(&u, username, hostname, ipaddr, id_str, id_num)) return;
|
||||
if (!sys_utmp_fill(&u, username, hostname, ip_addr_str, id_str, id_num))
|
||||
return;
|
||||
|
||||
sys_utmp_update(&u, hostname, True);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user