summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/lib/interfaces.c17
-rw-r--r--source3/lib/system.c24
-rw-r--r--source3/lib/util.c18
-rw-r--r--source3/lib/util_sock.c7
-rw-r--r--source3/smbd/reply.c20
-rw-r--r--source3/utils/net_lookup.c2
6 files changed, 66 insertions, 22 deletions
diff --git a/source3/lib/interfaces.c b/source3/lib/interfaces.c
index 38abb9299b..01481c50e9 100644
--- a/source3/lib/interfaces.c
+++ b/source3/lib/interfaces.c
@@ -696,6 +696,16 @@ int get_interfaces(struct iface_struct *ifaces, int max_interfaces)
#ifdef AUTOCONF_TEST
/* this is the autoconf driver to test get_interfaces() */
+static socklen_t calc_sa_size(struct sockaddr *psa)
+{
+ socklen_t sl = sizeof(struct sockaddr_in);
+#if defined(HAVE_IPV6)
+ if (psa->sa_family == AF_INET6) {
+ salen = sizeof(struct sockaddr_in6);
+ }
+#endif
+}
+
int main()
{
struct iface_struct ifaces[MAX_INTERFACES];
@@ -710,22 +720,23 @@ int get_interfaces(struct iface_struct *ifaces, int max_interfaces)
for (i=0;i<total;i++) {
char addr[INET6_ADDRSTRLEN];
int ret;
+ socklen_t sl;
printf("%-10s ", ifaces[i].name);
addr[0] = '\0';
ret = getnameinfo((struct sockaddr *)&ifaces[i].ip,
- sizeof(ifaces[i].ip),
+ calc_sa_size(&ifaces[i].ip),
addr, sizeof(addr),
NULL, 0, NI_NUMERICHOST);
printf("IP=%s ", addr);
addr[0] = '\0';
ret = getnameinfo((struct sockaddr *)&ifaces[i].netmask,
- sizeof(ifaces[i].netmask),
+ calc_sa_size(&ifaces[i].netmask),
addr, sizeof(addr),
NULL, 0, NI_NUMERICHOST);
printf("NETMASK=%s ", addr);
addr[0] = '\0';
ret = getnameinfo((struct sockaddr *)&ifaces[i].bcast,
- sizeof(ifaces[i].bcast),
+ calc_sa_size(&ifaces[i].bcast),
addr, sizeof(addr),
NULL, 0, NI_NUMERICHOST);
printf("BCAST=%s\n", addr);
diff --git a/source3/lib/system.c b/source3/lib/system.c
index 604228233c..fe4e700176 100644
--- a/source3/lib/system.c
+++ b/source3/lib/system.c
@@ -2545,3 +2545,27 @@ int sys_getpeereid( int s, uid_t *uid)
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);
+}
diff --git a/source3/lib/util.c b/source3/lib/util.c
index c8f0c3121f..0ae80c1f9e 100644
--- a/source3/lib/util.c
+++ b/source3/lib/util.c
@@ -550,7 +550,7 @@ int set_message(char *buf,int num_words,int num_bytes,bool zero)
int set_message_bcc(char *buf,int num_bytes)
{
int num_words = CVAL(buf,smb_wct);
- SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
+ SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4);
return (smb_size + num_words*2 + num_bytes);
}
@@ -2450,21 +2450,25 @@ char *data_path(const char *name)
/*****************************************************************
a useful function for returning a path in the Samba state directory
*****************************************************************/
-char *state_path(char *name)
+
+char *state_path(const char *name)
{
- pstring fname;
+ TALLOC_CTX *ctx = talloc_tos();
+ char *fname = talloc_strdup(ctx, dyn_STATEDIR());
- pstrcpy(fname,dyn_STATEDIR());
+ if (!fname) {
+ smb_panic("state_path: out of memory");
+ }
trim_string(fname,"","/");
if (!directory_exist(fname,NULL)) {
mkdir(fname,0755);
}
- pstrcat(fname,"/");
- pstrcat(fname,name);
+ fname = talloc_asprintf(ctx, "%s/%s",
+ fname, name);
- return talloc_strdup(talloc_tos(), fname);
+ return fname;
}
/**
diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c
index bbcbcacb4a..b4fda54ebd 100644
--- a/source3/lib/util_sock.c
+++ b/source3/lib/util_sock.c
@@ -495,7 +495,7 @@ bool is_address_any(const struct sockaddr_storage *psa)
Print out an IPv4 or IPv6 address from a struct sockaddr_storage.
****************************************************************************/
-char *print_sockaddr_len(char *dest,
+static char *print_sockaddr_len(char *dest,
size_t destlen,
const struct sockaddr_storage *psa,
socklen_t psalen)
@@ -503,7 +503,7 @@ char *print_sockaddr_len(char *dest,
if (destlen > 0) {
dest[0] = '\0';
}
- (void)getnameinfo((const struct sockaddr *)psa,
+ (void)sys_getnameinfo((const struct sockaddr *)psa,
psalen,
dest, destlen,
NULL, 0,
@@ -519,7 +519,8 @@ char *print_sockaddr(char *dest,
size_t destlen,
const struct sockaddr_storage *psa)
{
- return print_sockaddr_len(dest, destlen, psa, sizeof(*psa));
+ return print_sockaddr_len(dest, destlen, psa,
+ sizeof(struct sockaddr_storage));
}
/****************************************************************************
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index d2aa6c6929..84c1892560 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -3912,7 +3912,6 @@ void reply_write_and_X(connection_struct *conn, struct smb_request *req)
unsigned int smb_doff;
unsigned int smblen;
char *data;
- bool large_writeX;
NTSTATUS status;
START_PROFILE(SMBwriteX);
@@ -3926,11 +3925,11 @@ void reply_write_and_X(connection_struct *conn, struct smb_request *req)
numtowrite = SVAL(req->inbuf,smb_vwv10);
smb_doff = SVAL(req->inbuf,smb_vwv11);
smblen = smb_len(req->inbuf);
- large_writeX = ((req->wct == 14) && (smblen > 0xFFFF));
- /* Deal with possible LARGE_WRITEX */
- if (large_writeX) {
- numtowrite |= ((((size_t)SVAL(req->inbuf,smb_vwv9)) & 1 )<<16);
+ if (req->unread_bytes > 0xFFFF ||
+ (smblen > smb_doff &&
+ smblen - smb_doff > 0xFFFF)) {
+ numtowrite |= (((size_t)SVAL(req->inbuf,smb_vwv9))<<16);
}
if (req->unread_bytes) {
@@ -3940,7 +3939,8 @@ void reply_write_and_X(connection_struct *conn, struct smb_request *req)
return;
}
} else {
- if (smb_doff > smblen || smb_doff + numtowrite > smblen) {
+ if (smb_doff > smblen || smb_doff + numtowrite < numtowrite ||
+ smb_doff + numtowrite > smblen) {
reply_doserror(req, ERRDOS, ERRbadmem);
END_PROFILE(SMBwriteX);
return;
@@ -3949,6 +3949,11 @@ void reply_write_and_X(connection_struct *conn, struct smb_request *req)
/* If it's an IPC, pass off the pipe handler. */
if (IS_IPC(conn)) {
+ if (req->unread_bytes) {
+ reply_doserror(req, ERRDOS, ERRbadmem);
+ END_PROFILE(SMBwriteX);
+ return;
+ }
reply_pipe_write_and_X(req);
END_PROFILE(SMBwriteX);
return;
@@ -4031,8 +4036,7 @@ void reply_write_and_X(connection_struct *conn, struct smb_request *req)
reply_outbuf(req, 6, 0);
SSVAL(req->outbuf,smb_vwv2,nwritten);
- if (large_writeX)
- SSVAL(req->outbuf,smb_vwv4,(nwritten>>16)&1);
+ SSVAL(req->outbuf,smb_vwv4,nwritten>>16);
if (nwritten < (ssize_t)numtowrite) {
SCVAL(req->outbuf,smb_rcls,ERRHRD);
diff --git a/source3/utils/net_lookup.c b/source3/utils/net_lookup.c
index f7af1f2bb3..5e3551b781 100644
--- a/source3/utils/net_lookup.c
+++ b/source3/utils/net_lookup.c
@@ -131,7 +131,7 @@ static int net_lookup_ldap(int argc, const char **argv)
return -1;
}
- ret = getnameinfo((struct sockaddr *)&ss,
+ ret = sys_getnameinfo((struct sockaddr *)&ss,
sizeof(struct sockaddr_storage),
h_name, sizeof(h_name),
NULL, 0,