diff options
-rw-r--r-- | source/libsmb/nmblib.c | 38 | ||||
-rw-r--r-- | source/nmbd/nmbd.c | 15 | ||||
-rw-r--r-- | source/smbd/reply.c | 40 | ||||
-rw-r--r-- | source/smbd/server.c | 3 |
4 files changed, 70 insertions, 26 deletions
diff --git a/source/libsmb/nmblib.c b/source/libsmb/nmblib.c index 06ef935e167..fdbb50fab1f 100644 --- a/source/libsmb/nmblib.c +++ b/source/libsmb/nmblib.c @@ -180,26 +180,32 @@ static int parse_nmb_name(char *inbuf,int offset,int length, struct nmb_name *na int ret = 0; BOOL got_pointer=False; - if (length - offset < 2) return(0); + if (length - offset < 2) + return(0); /* handle initial name pointers */ - if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret)) return(0); + if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret)) + return(0); m = ubuf[offset]; - if (!m) return(0); - if ((m & 0xC0) || offset+m+2 > length) return(0); + if (!m) + return(0); + if ((m & 0xC0) || offset+m+2 > length) + return(0); memset((char *)name,'\0',sizeof(*name)); /* the "compressed" part */ - if (!got_pointer) ret += m + 2; + if (!got_pointer) + ret += m + 2; offset++; - while (m) { + while (m > 0) { unsigned char c1,c2; c1 = ubuf[offset++]-'A'; c2 = ubuf[offset++]-'A'; - if ((c1 & 0xF0) || (c2 & 0xF0) || (n > sizeof(name->name)-1)) return(0); + if ((c1 & 0xF0) || (c2 & 0xF0) || (n > sizeof(name->name)-1)) + return(0); name->name[n++] = (c1<<4) | c2; m -= 2; } @@ -213,21 +219,27 @@ static int parse_nmb_name(char *inbuf,int offset,int length, struct nmb_name *na /* remove trailing spaces */ name->name[15] = 0; n = 14; - while (n && name->name[n]==' ') name->name[n--] = 0; + while (n && name->name[n]==' ') + name->name[n--] = 0; } /* now the domain parts (if any) */ n = 0; while (ubuf[offset]) { /* we can have pointers within the domain part as well */ - if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret)) return(0); + if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret)) + return(0); m = ubuf[offset]; - if (!got_pointer) ret += m+1; - if (n) name->scope[n++] = '.'; - if (m+2+offset>length || n+m+1>sizeof(name->scope)) return(0); + if (!got_pointer) + ret += m+1; + if (n) + name->scope[n++] = '.'; + if (m+2+offset>length || n+m+1>sizeof(name->scope)) + return(0); offset++; - while (m--) name->scope[n++] = (char)ubuf[offset++]; + while (m--) + name->scope[n++] = (char)ubuf[offset++]; } name->scope[n++] = 0; diff --git a/source/nmbd/nmbd.c b/source/nmbd/nmbd.c index 33c4a5882c4..f9de3ca834a 100644 --- a/source/nmbd/nmbd.c +++ b/source/nmbd/nmbd.c @@ -86,6 +86,8 @@ static void sig_term(int sig) /**************************************************************************** ** catch a sighup **************************************************************************** */ +static VOLATILE SIG_ATOMIC_T reload_after_sighup = False; + static void sig_hup(int sig) { BlockSignals( True, SIGHUP ); @@ -95,9 +97,8 @@ static void sig_hup(int sig) write_browse_list( 0, True ); dump_all_namelists(); - reload_services( True ); - set_samba_nb_type(); + reload_after_sighup = True; BlockSignals(False,SIGHUP); @@ -395,6 +396,16 @@ static void process(void) * regularly sync with any other DMBs we know about */ sync_all_dmbs(t); + + /* + * Reload the services file if we got a sighup. + */ + + if(reload_after_sighup) { + reload_services( True ); + reload_after_sighup = False; + } + } } /* process */ diff --git a/source/smbd/reply.c b/source/smbd/reply.c index 70fd3d859c6..2c8e4a62a09 100644 --- a/source/smbd/reply.c +++ b/source/smbd/reply.c @@ -3803,7 +3803,7 @@ int reply_setdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size SMB_OFF_T get_lock_count( char *data, int data_offset, BOOL large_file_format, BOOL *err) { - SMB_OFF_T count; + SMB_OFF_T count = 0; *err = False; @@ -3824,11 +3824,21 @@ SMB_OFF_T get_lock_count( char *data, int data_offset, BOOL large_file_format, B DEBUG(0,("get_lock_count: Error : a large file count (%x << 32) was sent and we don't \ support large counts.\n", (unsigned int)IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset)) )); - *err = True; - return (SMB_OFF_T)-1; - } + /* + * Before we error out, see if we can sensibly map the top bits + * down to the lower bits. It seems that NT has this horrible bug + * where it will send 64 bit lock requests even if told not to. JRA. + */ - count = (SMB_OFF_T)IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(data_offset)); + if(IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(data_offset)) == (uint32)0xFFFFFFFF) + count = (SMB_OFF_T)IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset)); + else { + *err = True; + return (SMB_OFF_T)-1; + } + } + else + count = (SMB_OFF_T)IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(data_offset)); #endif /* LARGE_SMB_OFF_T */ } @@ -3841,7 +3851,7 @@ support large counts.\n", (unsigned int)IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(da SMB_OFF_T get_lock_offset( char *data, int data_offset, BOOL large_file_format, BOOL *err) { - SMB_OFF_T offset; + SMB_OFF_T offset = 0; *err = False; @@ -3862,11 +3872,21 @@ SMB_OFF_T get_lock_offset( char *data, int data_offset, BOOL large_file_format, DEBUG(0,("get_lock_count: Error : a large file offset (%x << 32) was sent and we don't \ support large offsets.\n", (unsigned int)IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset)) )); - *err = True; - return (SMB_OFF_T)-1; - } + /* + * Before we error out, see if we can sensibly map the top bits + * down to the lower bits. It seems that NT has this horrible bug + * where it will send 64 bit lock requests even if told not to. JRA. + */ - offset = (SMB_OFF_T)IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset)); + if(IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset)) == (uint32)0xFFFFFFFF) + offset = (SMB_OFF_T)IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset)); + else { + *err = True; + return (SMB_OFF_T)-1; + } + } + else + offset = (SMB_OFF_T)IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset)); #endif /* LARGE_SMB_OFF_T */ } diff --git a/source/smbd/server.c b/source/smbd/server.c index 32869bfd2d8..9ddaf5ac158 100644 --- a/source/smbd/server.c +++ b/source/smbd/server.c @@ -329,8 +329,9 @@ BOOL reload_services(BOOL test) /**************************************************************************** -this prevents zombie child processes + Catch a sighup. ****************************************************************************/ + VOLATILE SIG_ATOMIC_T reload_after_sighup = False; static void sig_hup(int sig) |