diff options
author | Jeremy Allison <jra@samba.org> | 2005-07-19 17:38:38 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 11:00:13 -0500 |
commit | 87801bc387e60d8cac74a6fb59af30bfdcc7850d (patch) | |
tree | 883829d753034e331117d9b6e1b5710414b36eac /source3 | |
parent | 638b6940703a3a15100838350a0e064f8b84a960 (diff) | |
download | samba-87801bc387e60d8cac74a6fb59af30bfdcc7850d.tar.gz samba-87801bc387e60d8cac74a6fb59af30bfdcc7850d.tar.bz2 samba-87801bc387e60d8cac74a6fb59af30bfdcc7850d.zip |
r8609: Fix for bugid #2889. I think the problem is that the top 16 bits of the "server state" field must be
non-zero. As we're using the 32 bit field as an offset then normally this field
will be zero. W2K3 fills this field with a counter enumerating the number of
SMBsearch calls on this directory - starting at 1. Add back the 1<<31 bit flag
DPTR_MASK to ensure this is non-zero - with better checks on use.
Jeremy.
(This used to be commit 6415657942c49ea51d4e4f4ee2189c7d70b9c5fa)
Diffstat (limited to 'source3')
-rw-r--r-- | source3/smbd/dir.c | 10 | ||||
-rw-r--r-- | source3/smbd/reply.c | 4 |
2 files changed, 11 insertions, 3 deletions
diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 949e31210f..aeada5968f 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -641,6 +641,8 @@ BOOL dptr_SearchDir(struct dptr_struct *dptr, const char *name, long *poffset, S Fill the 5 byte server reserved dptr field. ****************************************************************************/ +#define DPTR_MASK ((uint32)(((uint32)1)<<31)) + BOOL dptr_fill(char *buf1,unsigned int key) { unsigned char *buf = (unsigned char *)buf1; @@ -653,8 +655,12 @@ BOOL dptr_fill(char *buf1,unsigned int key) offset = (uint32)TellDir(dptr->dir_hnd); DEBUG(6,("fill on key %u dirptr 0x%lx now at %d\n",key, (long)dptr->dir_hnd,(int)offset)); + if (offset != (uint32)-1 && (offset & DPTR_MASK)) { + DEBUG(0,("dptr_fill: Error - offset has bit 32 set. Can't use in server state.\n")); + return False; + } buf[0] = key; - SIVAL(buf,1,offset); + SIVAL(buf,1,offset | DPTR_MASK); return(True); } @@ -678,7 +684,7 @@ struct dptr_struct *dptr_fetch(char *buf,int *num) if (offset == (uint32)-1) { seekoff = -1; } else { - seekoff = (long)offset; + seekoff = (long)(offset & ~DPTR_MASK); } SeekDir(dptr->dir_hnd,seekoff); DEBUG(3,("fetching dirptr %d for path %s at offset %d\n", diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 770e15f276..e96c3dc01f 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -1156,7 +1156,9 @@ int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size memcpy(p,status,21); make_dir_struct(p,mask,fname,size, mode,date, !allow_long_path_components); - dptr_fill(p+12,dptr_num); + if (!dptr_fill(p+12,dptr_num)) { + break; + } numentries++; p += DIR_STRUCT_SIZE; } |