From c94b2898cd5d1174181add198a462ab232f5aba6 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 1 Nov 2007 21:51:45 -0700 Subject: Ensure we detect a large writeX when using recvfile. More changes needed to make the UNIX_LARGE_WRITEX_CAP writes work (I'll add these tomorrow). Jeremy. (This used to be commit 1c71546b6152d2930b98f766311bbd161ee0ee4e) --- source3/smbd/reply.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index d2aa6c6929..d4f3f1f255 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -3926,7 +3926,8 @@ 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)); + large_writeX = (req->wct == 14 && + (smblen > 0xFFFF || req->unread_bytes > 0xFFFF)); /* Deal with possible LARGE_WRITEX */ if (large_writeX) { -- cgit From bece9609cd633d69c2c8dc72fcb6c26c4f11f9f2 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 1 Nov 2007 22:24:39 -0700 Subject: Be careful and take care of the correct lengths in large writeX calls. Jeremy. (This used to be commit 2d3ff9c502105f92720131355b41e48be8d656c2) --- source3/smbd/reply.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index d4f3f1f255..c83066d41e 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,12 +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 || req->unread_bytes > 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 + 4 && + smblen - smb_doff + 4 > 0xFFFF)) { + numtowrite |= (((size_t)SVAL(req->inbuf,smb_vwv9))<<16); } if (req->unread_bytes) { @@ -3941,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 + 4 > smblen || smb_doff + 4 + numtowrite < numtowrite || + smb_doff + 4 + numtowrite > smblen) { reply_doserror(req, ERRDOS, ERRbadmem); END_PROFILE(SMBwriteX); return; @@ -4032,8 +4031,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); -- cgit From 10500184bf7aac4c1036a807ad4f57d2016d7bd0 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 1 Nov 2007 22:42:21 -0700 Subject: Ensure we can't accidently do a pipe write with unread bytes in the socket buffer. Jeremy (This used to be commit 84d22f7747126608b9460f9591bb5967d871b82d) --- source3/smbd/reply.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index c83066d41e..de0e852e2a 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -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; -- cgit From 78cdd6e7eca44346377346fa6d84a9b59a8f5624 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 2 Nov 2007 09:27:04 -0700 Subject: Fix state_path to take a const string, not use pstring. Jeremy. (This used to be commit 8c73e19f51d6e3f520cf44dd22f9b9584d4b460f) --- source3/lib/util.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) 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; } /** -- cgit From e075b3692bb2c9507231f0662010fc55c1b506c4 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 2 Nov 2007 10:25:34 -0700 Subject: Fix Solaris by ensuring we use the IPv4 or IPv6 length in any getnameinfo calls. Jeremy (This used to be commit 4d7badb0c44f287034f58d9a412e662c0fbecdc9) --- source3/lib/interfaces.c | 17 ++++++++++++++--- source3/lib/system.c | 24 ++++++++++++++++++++++++ source3/lib/util_sock.c | 7 ++++--- source3/utils/net_lookup.c | 2 +- 4 files changed, 43 insertions(+), 7 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;isa_family == AF_INET6) { + salen = sizeof(struct sockaddr_in6); + } +#endif + } + return getnameinfo(psa, salen, host, hostlen, service, servlen, flags); +} 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/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, -- cgit From 414ab2ce46dd62d0119f03eca93783bc489af896 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 2 Nov 2007 10:35:10 -0700 Subject: Argggh. smblen doesn't include the +4, so my smb_doff calculations shouldn't either :-). Jeremy. (This used to be commit c3de44b6b063e126095b30536fdcb643c70e395e) --- source3/smbd/reply.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index de0e852e2a..84c1892560 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -3927,8 +3927,8 @@ void reply_write_and_X(connection_struct *conn, struct smb_request *req) smblen = smb_len(req->inbuf); if (req->unread_bytes > 0xFFFF || - (smblen > smb_doff + 4 && - smblen - smb_doff + 4 > 0xFFFF)) { + (smblen > smb_doff && + smblen - smb_doff > 0xFFFF)) { numtowrite |= (((size_t)SVAL(req->inbuf,smb_vwv9))<<16); } @@ -3939,8 +3939,8 @@ void reply_write_and_X(connection_struct *conn, struct smb_request *req) return; } } else { - if (smb_doff + 4 > smblen || smb_doff + 4 + numtowrite < numtowrite || - smb_doff + 4 + numtowrite > smblen) { + if (smb_doff > smblen || smb_doff + numtowrite < numtowrite || + smb_doff + numtowrite > smblen) { reply_doserror(req, ERRDOS, ERRbadmem); END_PROFILE(SMBwriteX); return; -- cgit