TIP: Click on subject to list as thread! ANSI
echo: os2prog
to: All
from: david nugent
date: 1994-06-28 08:26:40
subject: Serious flaw in NetWare Client 2.1

* Crossposted in area OS2PROG
 * Crossposted in area OS2_Z3

/*
 * dbug.c
 *
 * This program documents and demonstrates what appears to be a a serious
 * defect in the Novell NetWare Client for OS/2 version 2.10. This defect
 * may well cause serious data loss and prevent some data from being
 * backed up, depending on how the software searches for files on the
 * file server.
 *
 * The bug occurs in Dos16FindNext() and Dos32FindNext() calls when used
 * to read a directory on a file server using buffered mode; that is,
 * when reading multiple directories entries into a buffer instead of
 * single entries at a time.
 * When an entry would overflow the buffer, DosFindFirst[2] and
 * DosFindNext() both return and set the number of entries found
 * correctly, except that the entry which would have caused the overflow
 * is effectively "lost", and on next calling DosFindNext() the search
 * is not restarted from the point of overflow, but the directory entry
 * immediately following.
 *
 * To see this in action, select any large directory on the network and
 * issue a "dbug \*", and compare the output with a listing
 * from "dir \*".
 *
 * Author: davidn{at}csource.pronet.com
 *   Date: 28 Jun 1994
 */

# include 
# include 
# define INCL_DOS
# include 

    /* Field difference between 16- and 32-bit builds */

# if defined( __FLAT__ ) || defined( __EMX__ )
# define UINT           ULONG
# define FFINDBUF       FILEFINDBUF4
# define PFFINDBUF      PFILEFINDBUF4
# if !defined( DosFindFirst2 )
# define DosFindFirst2  DosFindFirst
# endif
# define DFFEXTRA
# define _32BIT
# else
# define UINT           USHORT
# define FFINDBUF       FILEFINDBUF2
# define PFFINDBUF      PFILEFINDBUF2
# define DFFEXTRA       ,0
# endif

typedef struct myfindbuf
{
    HDIR    dirhandle;
    UINT    direntries;
    UINT    bufsize;
    FFINDBUF * currentry;
    FFINDBUF * findbuffer;
}
    myfindbuf;


    /* myfindclose()
     * deallocate the find buffer and directory handle
     */

void
myfindclose (myfindbuf * fbuf)
{
    DosFindClose (fbuf->dirhandle);
    if (fbuf->findbuffer)
    {
        free(fbuf->findbuffer);
        fbuf->findbuffer = fbuf->currentry = NULL;
    }
}


    /* myfindfirst()
     * Initialise file searching, search for first set of entries
     * spec    File specification (eg. "c:\os2\*")
     * attr    Attributes to search on (OS/2 conventions)
     * fbuf    Structure used to manage searching
     * bufsize How large a buffer to use for searching
     */

int
myfindfirst (char const * spec, UINT attr, myfindbuf * fbuf, UINT bufsize)
{
    UINT rc;
    fbuf->dirhandle = HDIR_CREATE;
    fbuf->direntries = 1024;
    fbuf->bufsize = bufsize;
    fbuf->currentry =
    fbuf->findbuffer = (FFINDBUF *)malloc(bufsize);
    if (fbuf->findbuffer == (FFINDBUF*)NULL)
        return -1;
    rc = DosFindFirst2 ((PSZ)spec,
                        &fbuf->dirhandle,
                        attr,
                        fbuf->findbuffer,
                        fbuf->bufsize,
                        &fbuf->direntries,
                        FIL_QUERYEASIZE
                        DFFEXTRA);
    if (rc != 0)
        myfindclose(fbuf);
    return rc;
}

    /* myfindnext()
     * Continue searching for files; moves to next entry in buffer, or
     * if buffer is empty, attempts to refill the buffer.
     */

int
myfindnext (myfindbuf * fbuf)
{
    UINT rc;
    if (--fbuf->direntries > 0)
    {
        FFINDBUF * cur = fbuf->currentry;
# ifdef _32BIT
        fbuf->currentry = (FFINDBUF *)((char *)cur + cur->oNextEntryOffset);
# else
        fbuf->currentry = (FFINDBUF *)(cur->achName + cur->cchName + 1);
# endif
        rc = 0;
    }
    else
    {
        fbuf->direntries = 1024;
        fbuf->currentry = fbuf->findbuffer;
        rc = DosFindNext(fbuf->dirhandle,
                        (PFILEFINDBUF)fbuf->findbuffer,
                        fbuf->bufsize,
                        &fbuf->direntries);
        if (rc != 0)
            myfindclose(fbuf);
    }
    return rc;
}

    /* Printing functions */

char const *
pDate (FDATE d)
{
    int mon = d.month;
    static char dbuf[16];
    static char const *months[] =
    {
        "???",
       
"Jan","Feb","Mar","Apr","May","Jun",
       
"Jul","Aug","Sep","Oct","Nov","Dec"
    };
    sprintf (dbuf, "%02u-%s-%04u", d.day, months[mon], d.year+1980);
    return dbuf;
}

char const *
pTime (FTIME t)
{
    static char tbuf[16];
    sprintf(tbuf,"%02u:%02u:%02u", t.hours, t.minutes, t.twosecs*2);
    return tbuf;
}

char const *
pSize (ULONG sz, UINT attr)
{
    static char sbuf[16];
    if (attr & FILE_DIRECTORY)
        return "";
    sprintf(sbuf, "%ld", sz);
    return sbuf;
}

int
main(int argc, char * argv[])
{
    int rc;
    int filecount;
    myfindbuf ff;
    char const * filespec = (argc > 1) ? argv[1] : "*";

    rc = myfindfirst (filespec, FILE_NORMAL|FILE_DIRECTORY, &ff, 256);
    if (rc != 0)
        printf ("No matching files found.\n");
    else
    {
        filecount = 0;
        while (rc == 0)
        {
            FFINDBUF * curr = ff.currentry;
            printf("%s %s %10s %10ld %s\n", pDate(curr->fdateLastWrite),
                    pTime(curr->ftimeLastWrite),
                    pSize(curr->cbFile, curr->attrFile),
                    (curr->cbList==4) ? 0L : curr->cbList,
                    curr->achName);
            ++filecount;
            rc = myfindnext (&ff);
        }
        printf("      %u file(s)\n", filecount);
        myfindclose (&ff);
    }
    return 0;
}

---

* Origin: Unique Computing Pty Ltd (3:632/348)
SEEN-BY: 54/54 620/243 624/102 632/301 348 365 633/379 635/503 640/820
SEEN-BY: 690/660 711/409 413 430 807 808 809 934 712/353 623 713/888 800/1
SEEN-BY: 2442/0
@PATH: 632/348 711/409 54/54 711/808 809 934

SOURCE: echomail via fidonet.ozzmosis.com

Email questions or comments to sysop@ipingthereforeiam.com
All parts of this website painstakingly hand-crafted in the U.S.A.!
IPTIA BBS/MUD/Terminal/Game Server List, © 2025 IPTIA Consulting™.