From: Jeffrey Altman Date: Sun, 17 Oct 2004 03:44:52 +0000 (+0000) Subject: windows-updates-20041016 X-Git-Tag: BP-disconnected~199 X-Git-Url: https://git.openafs.org/?p=openafs.git;a=commitdiff_plain;h=c8feac3a2e8dcd89882aa1d9edf9b08566b162ea windows-updates-20041016 * Correct the handling of Over Quota errors * Update all of the reference count fields to use unsigned long instead of shorts or ints * Reformat touched files ==================== This delta was composed from multiple commits as part of the CVS->Git migration. The checkin message with each commit was inconsistent. The following are the additional commit messages. ==================== * Update reference count fields from short to unsigned long --- diff --git a/src/WINNT/afsd/cm_buf.h b/src/WINNT/afsd/cm_buf.h index 8826e1d..4ca977a 100644 --- a/src/WINNT/afsd/cm_buf.h +++ b/src/WINNT/afsd/cm_buf.h @@ -72,7 +72,7 @@ typedef struct cm_buf { */ struct cm_buf *allp; /* next in all list */ osi_mutex_t mx; /* mutex protecting structure except refcount */ - int refCount; /* reference count (buf_globalLock) */ + unsigned long refCount; /* reference count (buf_globalLock) */ long idCounter; /* counter for softrefs; bumped at each recycle */ long dirtyCounter; /* bumped at each dirty->clean transition */ #ifdef notdef diff --git a/src/WINNT/afsd/cm_conn.h b/src/WINNT/afsd/cm_conn.h index 701561d..0e9e023 100644 --- a/src/WINNT/afsd/cm_conn.h +++ b/src/WINNT/afsd/cm_conn.h @@ -23,7 +23,7 @@ typedef struct cm_conn { struct rx_connection *callp; /* locked by mx */ struct cm_user *userp; /* locked by mx; a held reference */ osi_mutex_t mx; /* mutex for some of these fields */ - int refCount; /* locked by cm_connLock */ + unsigned long refCount; /* locked by cm_connLock */ int ucgen; /* ucellp's generation number */ long flags; /* locked by mx */ int cryptlevel; /* encrytion status */ diff --git a/src/WINNT/afsd/cm_diskcache95.h b/src/WINNT/afsd/cm_diskcache95.h index f8721e0..fa8c783 100644 --- a/src/WINNT/afsd/cm_diskcache95.h +++ b/src/WINNT/afsd/cm_diskcache95.h @@ -51,7 +51,7 @@ typedef struct cm_diskcache { int openfd; /* open file descriptor */ struct cm_diskcache *hash_next; struct cm_diskcache *hash_prev; - int refCount; + unsigned long refCount; osi_mutex_t mx; } cm_diskcache_t; diff --git a/src/WINNT/afsd/cm_scache.h b/src/WINNT/afsd/cm_scache.h index aeeeeee..18b3450 100644 --- a/src/WINNT/afsd/cm_scache.h +++ b/src/WINNT/afsd/cm_scache.h @@ -58,7 +58,7 @@ typedef struct cm_scache { * write-locked to prevent buffers from * being created during a truncate op, etc. */ - int refCount; /* reference count; cm_scacheLock */ + unsigned long refCount; /* reference count; cm_scacheLock */ osi_queueData_t *bufReadsp; /* queue of buffers being read */ osi_queueData_t *bufWritesp; /* queue of buffers being written */ diff --git a/src/WINNT/afsd/cm_server.h b/src/WINNT/afsd/cm_server.h index fc766c3..0ea6e67 100644 --- a/src/WINNT/afsd/cm_server.h +++ b/src/WINNT/afsd/cm_server.h @@ -27,7 +27,7 @@ typedef struct cm_server { struct cm_conn *connsp; /* locked by cm_connLock */ long flags; /* by mx */ struct cm_cell *cellp; /* cell containing this server */ - int refCount; /* locked by cm_serverLock */ + unsigned long refCount; /* locked by cm_serverLock */ osi_mutex_t mx; unsigned short ipRank; /* server priority */ } cm_server_t; @@ -38,7 +38,7 @@ typedef struct cm_serverRef { struct cm_serverRef *next; /* locked by cm_serverLock */ struct cm_server *server; /* locked by cm_serverLock */ enum repstate status; /* locked by cm_serverLock */ - int refCount; /* locked by cm_serverLock */ + unsigned long refCount; /* locked by cm_serverLock */ } cm_serverRef_t; /* types */ diff --git a/src/WINNT/afsd/cm_user.h b/src/WINNT/afsd/cm_user.h index 3a160d7..1e58649 100644 --- a/src/WINNT/afsd/cm_user.h +++ b/src/WINNT/afsd/cm_user.h @@ -39,7 +39,7 @@ typedef struct cm_ucell { #define CM_UCELLFLAG_BADTIX 4 /* tickets are bad or expired */ typedef struct cm_user { - int refCount; /* ref count */ + unsigned long refCount; /* ref count */ cm_ucell_t *cellInfop; /* list of cell info */ osi_mutex_t mx; /* mutex */ int vcRefs; /* count of references from virtual circuits */ diff --git a/src/WINNT/afsd/cm_volume.h b/src/WINNT/afsd/cm_volume.h index 89547d7..0d01700 100644 --- a/src/WINNT/afsd/cm_volume.h +++ b/src/WINNT/afsd/cm_volume.h @@ -20,7 +20,7 @@ typedef struct cm_volume { struct cm_fid *dotdotFidp; /* parent of volume root */ osi_mutex_t mx; long flags; /* by mx */ - int refCount; /* by cm_volumeLock */ + unsigned long refCount; /* by cm_volumeLock */ cm_serverRef_t *rwServersp; /* by mx */ cm_serverRef_t *roServersp; /* by mx */ cm_serverRef_t *bkServersp; /* by mx */ diff --git a/src/WINNT/afsd/smb.c b/src/WINNT/afsd/smb.c index d722b51..fb3e1ae 100644 --- a/src/WINNT/afsd/smb.c +++ b/src/WINNT/afsd/smb.c @@ -205,16 +205,6 @@ int smb_ServerLanManagerLength = sizeof(smb_ServerLanManager); /* Faux server GUID. This is never checked. */ GUID smb_ServerGUID = { 0x40015cb8, 0x058a, 0x44fc, { 0xae, 0x7e, 0xbb, 0x29, 0x52, 0xee, 0x7e, 0xff }}; -/* - * Demo expiration - * - * To build an expiring version, comment out the definition of NOEXPIRE, - * and set the definition of EXPIREDATE to the desired value. - */ -#define NOEXPIRE 1 -#define EXPIREDATE 834000000 /* Wed Jun 5 1996 */ - - char * myCrt_Dispatch(int i) { switch (i) @@ -395,182 +385,185 @@ char * myCrt_RapDispatch(int i) /* scache must be locked */ unsigned int smb_Attributes(cm_scache_t *scp) { - unsigned int attrs; - - if (scp->fileType == CM_SCACHETYPE_DIRECTORY - || scp->fileType == CM_SCACHETYPE_MOUNTPOINT) - attrs = SMB_ATTR_DIRECTORY; - else - attrs = 0; - - /* - * We used to mark a file RO if it was in an RO volume, but that - * turns out to be impolitic in NT. See defect 10007. - */ + unsigned int attrs; + + if (scp->fileType == CM_SCACHETYPE_DIRECTORY + || scp->fileType == CM_SCACHETYPE_MOUNTPOINT) + attrs = SMB_ATTR_DIRECTORY; + else + attrs = 0; + + /* + * We used to mark a file RO if it was in an RO volume, but that + * turns out to be impolitic in NT. See defect 10007. + */ #ifdef notdef - if ((scp->unixModeBits & 0222) == 0 || (scp->flags & CM_SCACHEFLAG_RO)) + if ((scp->unixModeBits & 0222) == 0 || (scp->flags & CM_SCACHEFLAG_RO)) #endif if ((scp->unixModeBits & 0222) == 0) - attrs |= SMB_ATTR_READONLY; /* turn on read-only flag */ + attrs |= SMB_ATTR_READONLY; /* turn on read-only flag */ - return attrs; + return attrs; } /* Check if the named file/dir is a dotfile/dotdir */ /* String pointed to by lastComp can have leading slashes, but otherwise should have no other patch components */ unsigned int smb_IsDotFile(char *lastComp) { - char *s; - if(lastComp) { - /* skip over slashes */ + char *s; + if(lastComp) { + /* skip over slashes */ for(s=lastComp;*s && (*s == '\\' || *s == '/'); s++); - } - else - return 0; + } + else + return 0; /* nulls, curdir and parent dir doesn't count */ - if(!*s) return 0; - if(*s == '.') { - if(!*(s + 1)) return 0; - if(*(s+1) == '.' && !*(s + 2)) return 0; - return 1; - } - return 0; + if (!*s) + return 0; + if (*s == '.') { + if (!*(s + 1)) + return 0; + if(*(s+1) == '.' && !*(s + 2)) + return 0; + return 1; + } + return 0; } static int ExtractBits(WORD bits, short start, short len) { - int end; - WORD num; + int end; + WORD num; - end = start + len; + end = start + len; - num = bits << (16 - end); - num = num >> ((16 - end) + start); + num = bits << (16 - end); + num = num >> ((16 - end) + start); - return (int)num; + return (int)num; } #ifndef DJGPP void ShowUnixTime(char *FuncName, time_t unixTime) { - FILETIME ft; - WORD wDate, wTime; + FILETIME ft; + WORD wDate, wTime; - smb_LargeSearchTimeFromUnixTime(&ft, unixTime); - - if (!FileTimeToDosDateTime(&ft, &wDate, &wTime)) - osi_Log1(smb_logp, "Failed to convert filetime to dos datetime: %d", GetLastError()); - else { - int day, month, year, sec, min, hour; - char msg[256]; - - day = ExtractBits(wDate, 0, 5); - month = ExtractBits(wDate, 5, 4); - year = ExtractBits(wDate, 9, 7) + 1980; - - sec = ExtractBits(wTime, 0, 5); - min = ExtractBits(wTime, 5, 6); - hour = ExtractBits(wTime, 11, 5); - - sprintf(msg, "%s = %02d-%02d-%04d %02d:%02d:%02d", FuncName, month, day, year, hour, min, sec); - osi_Log1(smb_logp, "%s", osi_LogSaveString(smb_logp, msg)); - } -} + smb_LargeSearchTimeFromUnixTime(&ft, unixTime); + + if (!FileTimeToDosDateTime(&ft, &wDate, &wTime)) + osi_Log1(smb_logp, "Failed to convert filetime to dos datetime: %d", GetLastError()); + else { + int day, month, year, sec, min, hour; + char msg[256]; + + day = ExtractBits(wDate, 0, 5); + month = ExtractBits(wDate, 5, 4); + year = ExtractBits(wDate, 9, 7) + 1980; + + sec = ExtractBits(wTime, 0, 5); + min = ExtractBits(wTime, 5, 6); + hour = ExtractBits(wTime, 11, 5); + + sprintf(msg, "%s = %02d-%02d-%04d %02d:%02d:%02d", FuncName, month, day, year, hour, min, sec); + osi_Log1(smb_logp, "%s", osi_LogSaveString(smb_logp, msg)); + } +} #endif /* DJGPP */ #ifndef DJGPP /* Determine if we are observing daylight savings time */ void GetTimeZoneInfo(BOOL *pDST, LONG *pDstBias, LONG *pBias) { - TIME_ZONE_INFORMATION timeZoneInformation; - SYSTEMTIME utc, local, localDST; + TIME_ZONE_INFORMATION timeZoneInformation; + SYSTEMTIME utc, local, localDST; - /* Get the time zone info. NT uses this to calc if we are in DST. */ - GetTimeZoneInformation(&timeZoneInformation); - - /* Return the daylight bias */ - *pDstBias = timeZoneInformation.DaylightBias; - - /* Return the bias */ - *pBias = timeZoneInformation.Bias; - - /* Now determine if DST is being observed */ - - /* Get the UTC (GMT) time */ - GetSystemTime(&utc); - - /* Convert UTC time to local time using the time zone info. If we are - observing DST, the calculated local time will include this. - */ - SystemTimeToTzSpecificLocalTime(&timeZoneInformation, &utc, &localDST); - - /* Set the daylight bias to 0. The daylight bias is the amount of change - in time that we use for daylight savings time. By setting this to 0 - we cause there to be no change in time during daylight savings time. - */ - timeZoneInformation.DaylightBias = 0; - - /* Convert the utc time to local time again, but this time without any - adjustment for daylight savings time. - */ - SystemTimeToTzSpecificLocalTime(&timeZoneInformation, &utc, &local); - - /* If the two times are different, then it means that the localDST that - we calculated includes the daylight bias, and therefore we are - observing daylight savings time. - */ - *pDST = localDST.wHour != local.wHour; -} + /* Get the time zone info. NT uses this to calc if we are in DST. */ + GetTimeZoneInformation(&timeZoneInformation); + + /* Return the daylight bias */ + *pDstBias = timeZoneInformation.DaylightBias; + + /* Return the bias */ + *pBias = timeZoneInformation.Bias; + + /* Now determine if DST is being observed */ + + /* Get the UTC (GMT) time */ + GetSystemTime(&utc); + + /* Convert UTC time to local time using the time zone info. If we are + observing DST, the calculated local time will include this. + */ + SystemTimeToTzSpecificLocalTime(&timeZoneInformation, &utc, &localDST); + + /* Set the daylight bias to 0. The daylight bias is the amount of change + * in time that we use for daylight savings time. By setting this to 0 + * we cause there to be no change in time during daylight savings time. + */ + timeZoneInformation.DaylightBias = 0; + + /* Convert the utc time to local time again, but this time without any + adjustment for daylight savings time. + */ + SystemTimeToTzSpecificLocalTime(&timeZoneInformation, &utc, &local); + + /* If the two times are different, then it means that the localDST that + we calculated includes the daylight bias, and therefore we are + observing daylight savings time. + */ + *pDST = localDST.wHour != local.wHour; +} #else /* Determine if we are observing daylight savings time */ void GetTimeZoneInfo(BOOL *pDST, LONG *pDstBias, LONG *pBias) { - struct timeb t; + struct timeb t; - ftime(&t); - *pDST = t.dstflag; - *pDstBias = -60; /* where can this be different? */ - *pBias = t.timezone; -} + ftime(&t); + *pDST = t.dstflag; + *pDstBias = -60; /* where can this be different? */ + *pBias = t.timezone; +} #endif /* DJGPP */ void CompensateForSmbClientLastWriteTimeBugs(long *pLastWriteTime) { - BOOL dst; /* Will be TRUE if observing DST */ - LONG dstBias; /* Offset from local time if observing DST */ - LONG bias; /* Offset from GMT for local time */ - - /* - * This function will adjust the last write time to compensate - * for two bugs in the smb client: - * - * 1) During Daylight Savings Time, the LastWriteTime is ahead - * in time by the DaylightBias (ignoring the sign - the - * DaylightBias is always stored as a negative number). If - * the DaylightBias is -60, then the LastWriteTime will be - * ahead by 60 minutes. - * - * 2) If the local time zone is a positive offset from GMT, then - * the LastWriteTime will be the correct local time plus the - * Bias (ignoring the sign - a positive offset from GMT is - * always stored as a negative Bias). If the Bias is -120, - * then the LastWriteTime will be ahead by 120 minutes. - * - * These bugs can occur at the same time. - */ - - GetTimeZoneInfo(&dst, &dstBias, &bias); - - /* First adjust for DST */ - if (dst) - *pLastWriteTime -= (-dstBias * 60); /* Convert dstBias to seconds */ - - /* Now adjust for a positive offset from GMT (a negative bias). */ - if (bias < 0) - *pLastWriteTime -= (-bias * 60); /* Convert bias to seconds */ -} + BOOL dst; /* Will be TRUE if observing DST */ + LONG dstBias; /* Offset from local time if observing DST */ + LONG bias; /* Offset from GMT for local time */ + + /* + * This function will adjust the last write time to compensate + * for two bugs in the smb client: + * + * 1) During Daylight Savings Time, the LastWriteTime is ahead + * in time by the DaylightBias (ignoring the sign - the + * DaylightBias is always stored as a negative number). If + * the DaylightBias is -60, then the LastWriteTime will be + * ahead by 60 minutes. + * + * 2) If the local time zone is a positive offset from GMT, then + * the LastWriteTime will be the correct local time plus the + * Bias (ignoring the sign - a positive offset from GMT is + * always stored as a negative Bias). If the Bias is -120, + * then the LastWriteTime will be ahead by 120 minutes. + * + * These bugs can occur at the same time. + */ + + GetTimeZoneInfo(&dst, &dstBias, &bias); + + /* First adjust for DST */ + if (dst) + *pLastWriteTime -= (-dstBias * 60); /* Convert dstBias to seconds */ + + /* Now adjust for a positive offset from GMT (a negative bias). */ + if (bias < 0) + *pLastWriteTime -= (-bias * 60); /* Convert bias to seconds */ +} /* * Calculate the difference (in seconds) between local time and GMT. @@ -579,134 +572,134 @@ void CompensateForSmbClientLastWriteTimeBugs(long *pLastWriteTime) static void smb_CalculateNowTZ() { - time_t t; - struct tm gmt_tm, local_tm; - int days, hours, minutes, seconds; + time_t t; + struct tm gmt_tm, local_tm; + int days, hours, minutes, seconds; - t = time(NULL); - gmt_tm = *(gmtime(&t)); - local_tm = *(localtime(&t)); + t = time(NULL); + gmt_tm = *(gmtime(&t)); + local_tm = *(localtime(&t)); - days = local_tm.tm_yday - gmt_tm.tm_yday; - hours = 24 * days + local_tm.tm_hour - gmt_tm.tm_hour + days = local_tm.tm_yday - gmt_tm.tm_yday; + hours = 24 * days + local_tm.tm_hour - gmt_tm.tm_hour #ifdef COMMENT /* There is a problem with DST immediately after the time change - * which may continue to exist until the machine is rebooted + * which may continue to exist until the machine is rebooted */ - (local_tm.tm_isdst ? 1 : 0) #endif /* COMMENT */ - ; - minutes = 60 * hours + local_tm.tm_min - gmt_tm.tm_min; - seconds = 60 * minutes + local_tm.tm_sec - gmt_tm.tm_sec; + ; + minutes = 60 * hours + local_tm.tm_min - gmt_tm.tm_min; + seconds = 60 * minutes + local_tm.tm_sec - gmt_tm.tm_sec; - smb_NowTZ = seconds; + smb_NowTZ = seconds; } #ifndef DJGPP void smb_LargeSearchTimeFromUnixTime(FILETIME *largeTimep, time_t unixTime) { - struct tm *ltp; - SYSTEMTIME stm; - struct tm localJunk; - time_t ersatz_unixTime; - - /* - * Must use kludge-GMT instead of real GMT. - * kludge-GMT is computed by adding time zone difference to localtime. - * - * real GMT would be: - * ltp = gmtime(&unixTime); - */ - ersatz_unixTime = unixTime - smb_NowTZ; - ltp = localtime(&ersatz_unixTime); - - /* if we fail, make up something */ - if (!ltp) { - ltp = &localJunk; - localJunk.tm_year = 89 - 20; - localJunk.tm_mon = 4; - localJunk.tm_mday = 12; - localJunk.tm_hour = 0; - localJunk.tm_min = 0; - localJunk.tm_sec = 0; - } - - stm.wYear = ltp->tm_year + 1900; - stm.wMonth = ltp->tm_mon + 1; - stm.wDayOfWeek = ltp->tm_wday; - stm.wDay = ltp->tm_mday; - stm.wHour = ltp->tm_hour; - stm.wMinute = ltp->tm_min; - stm.wSecond = ltp->tm_sec; - stm.wMilliseconds = 0; - - SystemTimeToFileTime(&stm, largeTimep); + struct tm *ltp; + SYSTEMTIME stm; + struct tm localJunk; + time_t ersatz_unixTime; + + /* + * Must use kludge-GMT instead of real GMT. + * kludge-GMT is computed by adding time zone difference to localtime. + * + * real GMT would be: + * ltp = gmtime(&unixTime); + */ + ersatz_unixTime = unixTime - smb_NowTZ; + ltp = localtime(&ersatz_unixTime); + + /* if we fail, make up something */ + if (!ltp) { + ltp = &localJunk; + localJunk.tm_year = 89 - 20; + localJunk.tm_mon = 4; + localJunk.tm_mday = 12; + localJunk.tm_hour = 0; + localJunk.tm_min = 0; + localJunk.tm_sec = 0; + } + + stm.wYear = ltp->tm_year + 1900; + stm.wMonth = ltp->tm_mon + 1; + stm.wDayOfWeek = ltp->tm_wday; + stm.wDay = ltp->tm_mday; + stm.wHour = ltp->tm_hour; + stm.wMinute = ltp->tm_min; + stm.wSecond = ltp->tm_sec; + stm.wMilliseconds = 0; + + SystemTimeToFileTime(&stm, largeTimep); } #else /* DJGPP */ void smb_LargeSearchTimeFromUnixTime(FILETIME *largeTimep, time_t unixTime) { - /* unixTime: seconds since 1/1/1970 00:00:00 GMT */ - /* FILETIME: 100ns intervals since 1/1/1601 00:00:00 ??? */ - LARGE_INTEGER *ft = (LARGE_INTEGER *) largeTimep; - LARGE_INTEGER ut; - int leap_years = 89; /* leap years betw 1/1/1601 and 1/1/1970 */ - - /* set ft to number of 100ns intervals betw 1/1/1601 and 1/1/1970 GMT */ - *ft = ConvertLongToLargeInteger(((EPOCH_YEAR-1601) * 365 + leap_years) - * 24 * 60); - *ft = LargeIntegerMultiplyByLong(*ft, 60); - *ft = LargeIntegerMultiplyByLong(*ft, 10000000); - - /* add unix time */ - ut = ConvertLongToLargeInteger(unixTime); - ut = LargeIntegerMultiplyByLong(ut, 10000000); - *ft = LargeIntegerAdd(*ft, ut); -} + /* unixTime: seconds since 1/1/1970 00:00:00 GMT */ + /* FILETIME: 100ns intervals since 1/1/1601 00:00:00 ??? */ + LARGE_INTEGER *ft = (LARGE_INTEGER *) largeTimep; + LARGE_INTEGER ut; + int leap_years = 89; /* leap years betw 1/1/1601 and 1/1/1970 */ + + /* set ft to number of 100ns intervals betw 1/1/1601 and 1/1/1970 GMT */ + *ft = ConvertLongToLargeInteger(((EPOCH_YEAR-1601) * 365 + leap_years) + * 24 * 60); + *ft = LargeIntegerMultiplyByLong(*ft, 60); + *ft = LargeIntegerMultiplyByLong(*ft, 10000000); + + /* add unix time */ + ut = ConvertLongToLargeInteger(unixTime); + ut = LargeIntegerMultiplyByLong(ut, 10000000); + *ft = LargeIntegerAdd(*ft, ut); +} #endif /* !DJGPP */ #ifndef DJGPP void smb_UnixTimeFromLargeSearchTime(time_t *unixTimep, FILETIME *largeTimep) { - SYSTEMTIME stm; - struct tm lt; - long save_timezone; - - FileTimeToSystemTime(largeTimep, &stm); - - lt.tm_year = stm.wYear - 1900; - lt.tm_mon = stm.wMonth - 1; - lt.tm_wday = stm.wDayOfWeek; - lt.tm_mday = stm.wDay; - lt.tm_hour = stm.wHour; - lt.tm_min = stm.wMinute; - lt.tm_sec = stm.wSecond; - lt.tm_isdst = -1; - - save_timezone = _timezone; - _timezone += smb_NowTZ; - *unixTimep = mktime(<); - _timezone = save_timezone; -} + SYSTEMTIME stm; + struct tm lt; + long save_timezone; + + FileTimeToSystemTime(largeTimep, &stm); + + lt.tm_year = stm.wYear - 1900; + lt.tm_mon = stm.wMonth - 1; + lt.tm_wday = stm.wDayOfWeek; + lt.tm_mday = stm.wDay; + lt.tm_hour = stm.wHour; + lt.tm_min = stm.wMinute; + lt.tm_sec = stm.wSecond; + lt.tm_isdst = -1; + + save_timezone = _timezone; + _timezone += smb_NowTZ; + *unixTimep = mktime(<); + _timezone = save_timezone; +} #else /* DJGPP */ void smb_UnixTimeFromLargeSearchTime(time_t *unixTimep, FILETIME *largeTimep) { - /* unixTime: seconds since 1/1/1970 00:00:00 GMT */ - /* FILETIME: 100ns intervals since 1/1/1601 00:00:00 GMT? */ - LARGE_INTEGER *ft = (LARGE_INTEGER *) largeTimep; - LARGE_INTEGER a; - int leap_years = 89; - - /* set to number of 100ns intervals betw 1/1/1601 and 1/1/1970 */ - a = ConvertLongToLargeInteger(((EPOCH_YEAR-1601) * 365 + leap_years) * 24 * 60); - a = LargeIntegerMultiplyByLong(a, 60); - a = LargeIntegerMultiplyByLong(a, 10000000); - - /* subtract it from ft */ - a = LargeIntegerSubtract(*ft, a); - - /* divide down to seconds */ - *unixTimep = LargeIntegerDivideByLong(a, 10000000); -} + /* unixTime: seconds since 1/1/1970 00:00:00 GMT */ + /* FILETIME: 100ns intervals since 1/1/1601 00:00:00 GMT? */ + LARGE_INTEGER *ft = (LARGE_INTEGER *) largeTimep; + LARGE_INTEGER a; + int leap_years = 89; + + /* set to number of 100ns intervals betw 1/1/1601 and 1/1/1970 */ + a = ConvertLongToLargeInteger(((EPOCH_YEAR-1601) * 365 + leap_years) * 24 * 60); + a = LargeIntegerMultiplyByLong(a, 60); + a = LargeIntegerMultiplyByLong(a, 10000000); + + /* subtract it from ft */ + a = LargeIntegerSubtract(*ft, a); + + /* divide down to seconds */ + *unixTimep = LargeIntegerDivideByLong(a, 10000000); +} #endif /* !DJGPP */ void smb_SearchTimeFromUnixTime(long *dosTimep, time_t unixTime) @@ -737,283 +730,283 @@ void smb_SearchTimeFromUnixTime(long *dosTimep, time_t unixTime) void smb_UnixTimeFromSearchTime(time_t *unixTimep, time_t searchTime) { - unsigned short dosDate; - unsigned short dosTime; - struct tm localTm; + unsigned short dosDate; + unsigned short dosTime; + struct tm localTm; - dosDate = searchTime & 0xffff; - dosTime = (searchTime >> 16) & 0xffff; - - localTm.tm_year = 80 + ((dosDate>>9) & 0x3f); - localTm.tm_mon = ((dosDate >> 5) & 0xf) - 1; /* January is 0 in localTm */ - localTm.tm_mday = (dosDate) & 0x1f; - localTm.tm_hour = (dosTime>>11) & 0x1f; - localTm.tm_min = (dosTime >> 5) & 0x3f; - localTm.tm_sec = (dosTime & 0x1f) * 2; - localTm.tm_isdst = -1; /* compute whether DST in effect */ - - *unixTimep = mktime(&localTm); + dosDate = searchTime & 0xffff; + dosTime = (searchTime >> 16) & 0xffff; + + localTm.tm_year = 80 + ((dosDate>>9) & 0x3f); + localTm.tm_mon = ((dosDate >> 5) & 0xf) - 1; /* January is 0 in localTm */ + localTm.tm_mday = (dosDate) & 0x1f; + localTm.tm_hour = (dosTime>>11) & 0x1f; + localTm.tm_min = (dosTime >> 5) & 0x3f; + localTm.tm_sec = (dosTime & 0x1f) * 2; + localTm.tm_isdst = -1; /* compute whether DST in effect */ + + *unixTimep = mktime(&localTm); } void smb_DosUTimeFromUnixTime(time_t *dosUTimep, time_t unixTime) { - *dosUTimep = unixTime - smb_localZero; + *dosUTimep = unixTime - smb_localZero; } void smb_UnixTimeFromDosUTime(time_t *unixTimep, time_t dosTime) { #ifndef DJGPP - *unixTimep = dosTime + smb_localZero; + *unixTimep = dosTime + smb_localZero; #else /* DJGPP */ - /* dosTime seems to be already adjusted for GMT */ - *unixTimep = dosTime; + /* dosTime seems to be already adjusted for GMT */ + *unixTimep = dosTime; #endif /* !DJGPP */ } smb_vc_t *smb_FindVC(unsigned short lsn, int flags, int lana) { - smb_vc_t *vcp; - - lock_ObtainWrite(&smb_rctLock); - for(vcp = smb_allVCsp; vcp; vcp=vcp->nextp) { - if (lsn == vcp->lsn && lana == vcp->lana) { - vcp->refCount++; - break; - } - } - if (!vcp && (flags & SMB_FLAG_CREATE)) { - vcp = malloc(sizeof(*vcp)); - memset(vcp, 0, sizeof(*vcp)); + smb_vc_t *vcp; + + lock_ObtainWrite(&smb_rctLock); + for(vcp = smb_allVCsp; vcp; vcp=vcp->nextp) { + if (lsn == vcp->lsn && lana == vcp->lana) { + vcp->refCount++; + break; + } + } + if (!vcp && (flags & SMB_FLAG_CREATE)) { + vcp = malloc(sizeof(*vcp)); + memset(vcp, 0, sizeof(*vcp)); vcp->vcID = numVCs++; - vcp->refCount = 1; - vcp->tidCounter = 1; - vcp->fidCounter = 1; - vcp->uidCounter = 1; /* UID 0 is reserved for blank user */ - vcp->nextp = smb_allVCsp; - smb_allVCsp = vcp; - lock_InitializeMutex(&vcp->mx, "vc_t mutex"); - vcp->lsn = lsn; - vcp->lana = lana; + vcp->refCount = 1; + vcp->tidCounter = 1; + vcp->fidCounter = 1; + vcp->uidCounter = 1; /* UID 0 is reserved for blank user */ + vcp->nextp = smb_allVCsp; + smb_allVCsp = vcp; + lock_InitializeMutex(&vcp->mx, "vc_t mutex"); + vcp->lsn = lsn; + vcp->lana = lana; vcp->secCtx = NULL; - if (smb_authType == SMB_AUTH_NTLM || smb_authType == SMB_AUTH_EXTENDED) { + if (smb_authType == SMB_AUTH_NTLM || smb_authType == SMB_AUTH_EXTENDED) { /* We must obtain a challenge for extended auth * in case the client negotiates smb v3 */ NTSTATUS nts,ntsEx; - MSV1_0_LM20_CHALLENGE_REQUEST lsaReq; - PMSV1_0_LM20_CHALLENGE_RESPONSE lsaResp; - ULONG lsaRespSize; + MSV1_0_LM20_CHALLENGE_REQUEST lsaReq; + PMSV1_0_LM20_CHALLENGE_RESPONSE lsaResp; + ULONG lsaRespSize; - lsaReq.MessageType = MsV1_0Lm20ChallengeRequest; + lsaReq.MessageType = MsV1_0Lm20ChallengeRequest; - nts = LsaCallAuthenticationPackage( smb_lsaHandle, + nts = LsaCallAuthenticationPackage( smb_lsaHandle, smb_lsaSecPackage, &lsaReq, sizeof(lsaReq), &lsaResp, &lsaRespSize, &ntsEx); - osi_assert(nts == STATUS_SUCCESS); /* this had better work! */ + osi_assert(nts == STATUS_SUCCESS); /* this had better work! */ - memcpy(vcp->encKey, lsaResp->ChallengeToClient, MSV1_0_CHALLENGE_LENGTH); + memcpy(vcp->encKey, lsaResp->ChallengeToClient, MSV1_0_CHALLENGE_LENGTH); LsaFreeReturnBuffer(lsaResp); - } - else - memset(vcp->encKey, 0, MSV1_0_CHALLENGE_LENGTH); - } - lock_ReleaseWrite(&smb_rctLock); - return vcp; + } + else + memset(vcp->encKey, 0, MSV1_0_CHALLENGE_LENGTH); + } + lock_ReleaseWrite(&smb_rctLock); + return vcp; } int smb_IsStarMask(char *maskp) { - int i; - char tc; + int i; + char tc; - for(i=0; i<11; i++) { - tc = *maskp++; - if (tc == '?' || tc == '*' || tc == '>') return 1; - } - return 0; + for(i=0; i<11; i++) { + tc = *maskp++; + if (tc == '?' || tc == '*' || tc == '>') return 1; + } + return 0; } void smb_ReleaseVC(smb_vc_t *vcp) { - lock_ObtainWrite(&smb_rctLock); - osi_assert(vcp->refCount-- > 0); - lock_ReleaseWrite(&smb_rctLock); -} + lock_ObtainWrite(&smb_rctLock); + osi_assert(vcp->refCount-- > 0); + lock_ReleaseWrite(&smb_rctLock); +} void smb_HoldVC(smb_vc_t *vcp) { - lock_ObtainWrite(&smb_rctLock); - vcp->refCount++; - lock_ReleaseWrite(&smb_rctLock); -} + lock_ObtainWrite(&smb_rctLock); + vcp->refCount++; + lock_ReleaseWrite(&smb_rctLock); +} smb_tid_t *smb_FindTID(smb_vc_t *vcp, unsigned short tid, int flags) { - smb_tid_t *tidp; - - lock_ObtainWrite(&smb_rctLock); - for(tidp = vcp->tidsp; tidp; tidp = tidp->nextp) { - if (tid == tidp->tid) { - tidp->refCount++; - break; - } - } - if (!tidp && (flags & SMB_FLAG_CREATE)) { - tidp = malloc(sizeof(*tidp)); - memset(tidp, 0, sizeof(*tidp)); - tidp->nextp = vcp->tidsp; - tidp->refCount = 1; - tidp->vcp = vcp; + smb_tid_t *tidp; + + lock_ObtainWrite(&smb_rctLock); + for (tidp = vcp->tidsp; tidp; tidp = tidp->nextp) { + if (tid == tidp->tid) { + tidp->refCount++; + break; + } + } + if (!tidp && (flags & SMB_FLAG_CREATE)) { + tidp = malloc(sizeof(*tidp)); + memset(tidp, 0, sizeof(*tidp)); + tidp->nextp = vcp->tidsp; + tidp->refCount = 1; + tidp->vcp = vcp; vcp->refCount++; - vcp->tidsp = tidp; - lock_InitializeMutex(&tidp->mx, "tid_t mutex"); - tidp->tid = tid; - } - lock_ReleaseWrite(&smb_rctLock); - return tidp; -} + vcp->tidsp = tidp; + lock_InitializeMutex(&tidp->mx, "tid_t mutex"); + tidp->tid = tid; + } + lock_ReleaseWrite(&smb_rctLock); + return tidp; +} void smb_ReleaseTID(smb_tid_t *tidp) { - smb_tid_t *tp; - smb_tid_t **ltpp; - cm_user_t *userp; + smb_tid_t *tp; + smb_tid_t **ltpp; + cm_user_t *userp; smb_vc_t *vcp; - userp = NULL; + userp = NULL; vcp = NULL; - lock_ObtainWrite(&smb_rctLock); - osi_assert(tidp->refCount-- > 0); - if (tidp->refCount == 0 && (tidp->flags & SMB_TIDFLAG_DELETE)) { - ltpp = &tidp->vcp->tidsp; - for(tp = *ltpp; tp; ltpp = &tp->nextp, tp = *ltpp) { - if (tp == tidp) break; - } - osi_assert(tp != NULL); - *ltpp = tp->nextp; - lock_FinalizeMutex(&tidp->mx); - userp = tidp->userp; /* remember to drop ref later */ + lock_ObtainWrite(&smb_rctLock); + osi_assert(tidp->refCount-- > 0); + if (tidp->refCount == 0 && (tidp->flags & SMB_TIDFLAG_DELETE)) { + ltpp = &tidp->vcp->tidsp; + for(tp = *ltpp; tp; ltpp = &tp->nextp, tp = *ltpp) { + if (tp == tidp) break; + } + osi_assert(tp != NULL); + *ltpp = tp->nextp; + lock_FinalizeMutex(&tidp->mx); + userp = tidp->userp; /* remember to drop ref later */ vcp = tidp->vcp; - } - lock_ReleaseWrite(&smb_rctLock); - if (userp) { - cm_ReleaseUser(userp); - } + } + lock_ReleaseWrite(&smb_rctLock); + if (userp) { + cm_ReleaseUser(userp); + } if (vcp) { smb_ReleaseVC(vcp); - } -} + } +} smb_user_t *smb_FindUID(smb_vc_t *vcp, unsigned short uid, int flags) { - smb_user_t *uidp = NULL; - - lock_ObtainWrite(&smb_rctLock); - for(uidp = vcp->usersp; uidp; uidp = uidp->nextp) { - if (uid == uidp->userID) { - uidp->refCount++; - osi_LogEvent("AFS smb_FindUID (Find by UID)",NULL," VCP[%x] found-uid[%d] name[%s]", - (int)vcp, uidp->userID, - osi_LogSaveString(smb_logp, (uidp->unp) ? uidp->unp->name : "")); - break; - } - } - if (!uidp && (flags & SMB_FLAG_CREATE)) { - uidp = malloc(sizeof(*uidp)); - memset(uidp, 0, sizeof(*uidp)); - uidp->nextp = vcp->usersp; - uidp->refCount = 1; - uidp->vcp = vcp; + smb_user_t *uidp = NULL; + + lock_ObtainWrite(&smb_rctLock); + for(uidp = vcp->usersp; uidp; uidp = uidp->nextp) { + if (uid == uidp->userID) { + uidp->refCount++; + osi_LogEvent("AFS smb_FindUID (Find by UID)",NULL," VCP[%x] found-uid[%d] name[%s]", + (int)vcp, uidp->userID, + osi_LogSaveString(smb_logp, (uidp->unp) ? uidp->unp->name : "")); + break; + } + } + if (!uidp && (flags & SMB_FLAG_CREATE)) { + uidp = malloc(sizeof(*uidp)); + memset(uidp, 0, sizeof(*uidp)); + uidp->nextp = vcp->usersp; + uidp->refCount = 1; + uidp->vcp = vcp; vcp->refCount++; - vcp->usersp = uidp; - lock_InitializeMutex(&uidp->mx, "user_t mutex"); - uidp->userID = uid; - osi_LogEvent("AFS smb_FindUID (Find by UID)",NULL,"VCP[%x] new-uid[%d] name[%s]",(int)vcp,uidp->userID,(uidp->unp ? uidp->unp->name : "")); - } - lock_ReleaseWrite(&smb_rctLock); - return uidp; -} + vcp->usersp = uidp; + lock_InitializeMutex(&uidp->mx, "user_t mutex"); + uidp->userID = uid; + osi_LogEvent("AFS smb_FindUID (Find by UID)",NULL,"VCP[%x] new-uid[%d] name[%s]",(int)vcp,uidp->userID,(uidp->unp ? uidp->unp->name : "")); + } + lock_ReleaseWrite(&smb_rctLock); + return uidp; +} smb_username_t *smb_FindUserByName(char *usern, char *machine, int flags) { - smb_username_t *unp= NULL; - - lock_ObtainWrite(&smb_rctLock); - for(unp = usernamesp; unp; unp = unp->nextp) { - if (stricmp(unp->name, usern) == 0 && - stricmp(unp->machine, machine) == 0) { - unp->refCount++; - break; - } - } - if (!unp && (flags & SMB_FLAG_CREATE)) { - unp = malloc(sizeof(*unp)); - memset(unp, 0, sizeof(*unp)); - unp->refCount = 1; - unp->nextp = usernamesp; - unp->name = strdup(usern); - unp->machine = strdup(machine); - usernamesp = unp; - lock_InitializeMutex(&unp->mx, "username_t mutex"); - } - lock_ReleaseWrite(&smb_rctLock); - return unp; + smb_username_t *unp= NULL; + + lock_ObtainWrite(&smb_rctLock); + for(unp = usernamesp; unp; unp = unp->nextp) { + if (stricmp(unp->name, usern) == 0 && + stricmp(unp->machine, machine) == 0) { + unp->refCount++; + break; + } + } + if (!unp && (flags & SMB_FLAG_CREATE)) { + unp = malloc(sizeof(*unp)); + memset(unp, 0, sizeof(*unp)); + unp->refCount = 1; + unp->nextp = usernamesp; + unp->name = strdup(usern); + unp->machine = strdup(machine); + usernamesp = unp; + lock_InitializeMutex(&unp->mx, "username_t mutex"); + } + lock_ReleaseWrite(&smb_rctLock); + return unp; } smb_user_t *smb_FindUserByNameThisSession(smb_vc_t *vcp, char *usern) { - smb_user_t *uidp= NULL; + smb_user_t *uidp= NULL; - lock_ObtainWrite(&smb_rctLock); - for(uidp = vcp->usersp; uidp; uidp = uidp->nextp) { - if (!uidp->unp) + lock_ObtainWrite(&smb_rctLock); + for(uidp = vcp->usersp; uidp; uidp = uidp->nextp) { + if (!uidp->unp) continue; - if (stricmp(uidp->unp->name, usern) == 0) { + if (stricmp(uidp->unp->name, usern) == 0) { uidp->refCount++; - osi_LogEvent("AFS smb_FindUserByNameThisSession",NULL,"VCP[%x] uid[%d] match-name[%s]",(int)vcp,uidp->userID,usern); + osi_LogEvent("AFS smb_FindUserByNameThisSession",NULL,"VCP[%x] uid[%d] match-name[%s]",(int)vcp,uidp->userID,usern); break; - } else + } else continue; - } - lock_ReleaseWrite(&smb_rctLock); - return uidp; -} + } + lock_ReleaseWrite(&smb_rctLock); + return uidp; +} void smb_ReleaseUID(smb_user_t *uidp) { - smb_user_t *up; - smb_user_t **lupp; - cm_user_t *userp; + smb_user_t *up; + smb_user_t **lupp; + cm_user_t *userp; smb_vc_t *vcp; - userp = NULL; + userp = NULL; vcp = NULL; - lock_ObtainWrite(&smb_rctLock); - osi_assert(uidp->refCount-- > 0); - if (uidp->refCount == 0 && (uidp->flags & SMB_USERFLAG_DELETE)) { - lupp = &uidp->vcp->usersp; - for(up = *lupp; up; lupp = &up->nextp, up = *lupp) { - if (up == uidp) break; - } - osi_assert(up != NULL); - *lupp = up->nextp; - lock_FinalizeMutex(&uidp->mx); - if (uidp->unp) { - userp = uidp->unp->userp; /* remember to drop ref later */ - uidp->unp->userp = NULL; + lock_ObtainWrite(&smb_rctLock); + osi_assert(uidp->refCount-- > 0); + if (uidp->refCount == 0 && (uidp->flags & SMB_USERFLAG_DELETE)) { + lupp = &uidp->vcp->usersp; + for(up = *lupp; up; lupp = &up->nextp, up = *lupp) { + if (up == uidp) break; } + osi_assert(up != NULL); + *lupp = up->nextp; + lock_FinalizeMutex(&uidp->mx); + if (uidp->unp) { + userp = uidp->unp->userp; /* remember to drop ref later */ + uidp->unp->userp = NULL; + } vcp = uidp->vcp; uidp->vcp = NULL; - } - lock_ReleaseWrite(&smb_rctLock); - if (userp) { - cm_ReleaseUserVCRef(userp); - cm_ReleaseUser(userp); - } + } + lock_ReleaseWrite(&smb_rctLock); + if (userp) { + cm_ReleaseUserVCRef(userp); + cm_ReleaseUser(userp); + } if (vcp) { smb_ReleaseVC(vcp); } @@ -1025,23 +1018,23 @@ void smb_ReleaseUID(smb_user_t *uidp) */ cm_user_t *smb_GetUser(smb_vc_t *vcp, smb_packet_t *inp) { - smb_user_t *uidp; - cm_user_t *up; - smb_t *smbp; - - smbp = (smb_t *) inp; - uidp = smb_FindUID(vcp, smbp->uid, 0); - if ((!uidp) || (!uidp->unp)) - return NULL; - - lock_ObtainMutex(&uidp->mx); - up = uidp->unp->userp; - cm_HoldUser(up); - lock_ReleaseMutex(&uidp->mx); + smb_user_t *uidp; + cm_user_t *up; + smb_t *smbp; - smb_ReleaseUID(uidp); - - return up; + smbp = (smb_t *) inp; + uidp = smb_FindUID(vcp, smbp->uid, 0); + if ((!uidp) || (!uidp->unp)) + return NULL; + + lock_ObtainMutex(&uidp->mx); + up = uidp->unp->userp; + cm_HoldUser(up); + lock_ReleaseMutex(&uidp->mx); + + smb_ReleaseUID(uidp); + + return up; } /* @@ -1050,10 +1043,10 @@ cm_user_t *smb_GetUser(smb_vc_t *vcp, smb_packet_t *inp) */ long smb_LookupTIDPath(smb_vc_t *vcp, unsigned short tid, char ** treepath) { - smb_tid_t *tidp; + smb_tid_t *tidp; long code = 0; - tidp = smb_FindTID(vcp, tid, 0); + tidp = smb_FindTID(vcp, tid, 0); if (!tidp) { *treepath = NULL; } else { @@ -1074,16 +1067,16 @@ long smb_LookupTIDPath(smb_vc_t *vcp, unsigned short tid, char ** treepath) */ int smb_ChainFID(int fid, smb_packet_t *inp) { - if (inp->fid == 0 || inp->inCount == 0) - return fid; - else - return inp->fid; + if (inp->fid == 0 || inp->inCount == 0) + return fid; + else + return inp->fid; } /* are we a priv'd user? What does this mean on NT? */ int smb_SUser(cm_user_t *userp) { - return 1; + return 1; } /* find a file ID. If we pass in 0 we select an used File ID. @@ -1092,31 +1085,31 @@ int smb_SUser(cm_user_t *userp) */ smb_fid_t *smb_FindFID(smb_vc_t *vcp, unsigned short fid, int flags) { - smb_fid_t *fidp; - int newFid = 0; + smb_fid_t *fidp; + int newFid = 0; if (fid == 0 && !(flags & SMB_FLAG_CREATE)) return NULL; - lock_ObtainWrite(&smb_rctLock); - /* figure out if we need to allocate a new file ID */ - if (fid == 0) { - newFid = 1; - fid = vcp->fidCounter; - } - -retry: - for(fidp = vcp->fidsp; fidp; fidp = (smb_fid_t *) osi_QNext(&fidp->q)) { - if (fid == fidp->fid) { - if (newFid) { - fid++; + lock_ObtainWrite(&smb_rctLock); + /* figure out if we need to allocate a new file ID */ + if (fid == 0) { + newFid = 1; + fid = vcp->fidCounter; + } + + retry: + for(fidp = vcp->fidsp; fidp; fidp = (smb_fid_t *) osi_QNext(&fidp->q)) { + if (fid == fidp->fid) { + if (newFid) { + fid++; if (fid == 0) - fid = 1; + fid = 1; goto retry; } - fidp->refCount++; + fidp->refCount++; break; - } + } } if (!fidp && (flags & SMB_FLAG_CREATE)) { char eventName[MAX_PATH]; @@ -1132,16 +1125,16 @@ retry: goto retry; } - fidp = malloc(sizeof(*fidp)); + fidp = malloc(sizeof(*fidp)); memset(fidp, 0, sizeof(*fidp)); - osi_QAdd((osi_queue_t **)&vcp->fidsp, &fidp->q); + osi_QAdd((osi_queue_t **)&vcp->fidsp, &fidp->q); fidp->refCount = 1; fidp->vcp = vcp; vcp->refCount++; lock_InitializeMutex(&fidp->mx, "fid_t mutex"); fidp->fid = fid; - fidp->curr_chunk = fidp->prev_chunk = -2; - fidp->raw_write_event = event; + fidp->curr_chunk = fidp->prev_chunk = -2; + fidp->raw_write_event = event; if (newFid) { vcp->fidCounter = fid+1; if (vcp->fidCounter == 0) @@ -1154,43 +1147,43 @@ retry: void smb_ReleaseFID(smb_fid_t *fidp) { - cm_scache_t *scp; + cm_scache_t *scp; smb_vc_t *vcp = NULL; smb_ioctl_t *ioctlp; if (!fidp) return; - scp = NULL; - lock_ObtainWrite(&smb_rctLock); - osi_assert(fidp->refCount-- > 0); + scp = NULL; + lock_ObtainWrite(&smb_rctLock); + osi_assert(fidp->refCount-- > 0); if (fidp->refCount == 0 && (fidp->flags & SMB_FID_DELETE)) { - vcp = fidp->vcp; - if (!(fidp->flags & SMB_FID_IOCTL)) - scp = fidp->scp; - osi_QRemove((osi_queue_t **) &vcp->fidsp, &fidp->q); - thrd_CloseHandle(fidp->raw_write_event); + vcp = fidp->vcp; + if (!(fidp->flags & SMB_FID_IOCTL)) + scp = fidp->scp; + osi_QRemove((osi_queue_t **) &vcp->fidsp, &fidp->q); + thrd_CloseHandle(fidp->raw_write_event); - /* and see if there is ioctl stuff to free */ + /* and see if there is ioctl stuff to free */ ioctlp = fidp->ioctlp; if (ioctlp) { - if (ioctlp->prefix) cm_FreeSpace(ioctlp->prefix); - if (ioctlp->inAllocp) free(ioctlp->inAllocp); - if (ioctlp->outAllocp) free(ioctlp->outAllocp); - free(ioctlp); - } + if (ioctlp->prefix) cm_FreeSpace(ioctlp->prefix); + if (ioctlp->inAllocp) free(ioctlp->inAllocp); + if (ioctlp->outAllocp) free(ioctlp->outAllocp); + free(ioctlp); + } free(fidp); /* do not call smb_ReleaseVC() because we already have the lock */ vcp->refCount--; } - lock_ReleaseWrite(&smb_rctLock); + lock_ReleaseWrite(&smb_rctLock); - /* now release the scache structure */ - if (scp) - cm_ReleaseSCache(scp); -} + /* now release the scache structure */ + if (scp) + cm_ReleaseSCache(scp); +} /* * Case-insensitive search for one string in another; @@ -1198,13 +1191,13 @@ void smb_ReleaseFID(smb_fid_t *fidp) */ static char *smb_stristr(char *str1, char *str2) { - char *cursor; + char *cursor; - for (cursor = str1; *cursor; cursor++) - if (stricmp(cursor, str2) == 0) - return cursor; + for (cursor = str1; *cursor; cursor++) + if (stricmp(cursor, str2) == 0) + return cursor; - return NULL; + return NULL; } /* @@ -1213,14 +1206,14 @@ static char *smb_stristr(char *str1, char *str2) * length (plus one) is in substr_size. Variable value is in newstr. */ static void smb_subst(char *str1, char *substr, unsigned int substr_size, - char *newstr) + char *newstr) { - char temp[1024]; + char temp[1024]; - strcpy(temp, substr + substr_size - 1); - strcpy(substr, newstr); - strcat(str1, temp); -} + strcpy(temp, substr + substr_size - 1); + strcpy(substr, newstr); + strcat(str1, temp); +} char VNUserName[] = "%USERNAME%"; char VNLCUserName[] = "%LCUSERNAME%"; @@ -1231,65 +1224,65 @@ char VNLCComputerName[] = "%LCCOMPUTERNAME%"; /* List available shares */ int smb_ListShares() { - char sbmtpath[256]; - char pathName[256]; - char shareBuf[4096]; - int num_shares=0; - char *this_share; - int len; - char *p; - int print_afs = 0; - int code; - - /*strcpy(shareNameList[num_shares], "all"); - strcpy(pathNameList[num_shares++], "/afs");*/ - fprintf(stderr, "The following shares are available:\n"); - fprintf(stderr, "Share Name (AFS Path)\n"); - fprintf(stderr, "---------------------\n"); - fprintf(stderr, "\\\\%s\\%-16s (%s)\n", smb_localNamep, "ALL", cm_mountRoot); + char sbmtpath[256]; + char pathName[256]; + char shareBuf[4096]; + int num_shares=0; + char *this_share; + int len; + char *p; + int print_afs = 0; + int code; + + /*strcpy(shareNameList[num_shares], "all"); + strcpy(pathNameList[num_shares++], "/afs");*/ + fprintf(stderr, "The following shares are available:\n"); + fprintf(stderr, "Share Name (AFS Path)\n"); + fprintf(stderr, "---------------------\n"); + fprintf(stderr, "\\\\%s\\%-16s (%s)\n", smb_localNamep, "ALL", cm_mountRoot); #ifndef DJGPP - code = GetWindowsDirectory(sbmtpath, sizeof(sbmtpath)); - if (code == 0 || code > sizeof(sbmtpath)) return -1; + code = GetWindowsDirectory(sbmtpath, sizeof(sbmtpath)); + if (code == 0 || code > sizeof(sbmtpath)) return -1; #else - strcpy(sbmtpath, cm_confDir); + strcpy(sbmtpath, cm_confDir); #endif /* !DJGPP */ - strcat(sbmtpath, "/afsdsbmt.ini"); - len = GetPrivateProfileString("AFS Submounts", NULL, NULL, - shareBuf, sizeof(shareBuf), - sbmtpath); - if (len == 0) { - return num_shares; - } - - this_share = shareBuf; - do - { - print_afs = 0; - /*strcpy(shareNameList[num_shares], this_share);*/ - len = GetPrivateProfileString("AFS Submounts", this_share, - NULL, - pathName, 256, - sbmtpath); - if (!len) - return num_shares; - p = pathName; - if (strncmp(p, cm_mountRoot, strlen(cm_mountRoot)) != 0) + strcat(sbmtpath, "/afsdsbmt.ini"); + len = GetPrivateProfileString("AFS Submounts", NULL, NULL, + shareBuf, sizeof(shareBuf), + sbmtpath); + if (len == 0) { + return num_shares; + } + + this_share = shareBuf; + do + { + print_afs = 0; + /*strcpy(shareNameList[num_shares], this_share);*/ + len = GetPrivateProfileString("AFS Submounts", this_share, + NULL, + pathName, 256, + sbmtpath); + if (!len) + return num_shares; + p = pathName; + if (strncmp(p, cm_mountRoot, strlen(cm_mountRoot)) != 0) print_afs = 1; - while (*p) { + while (*p) { if (*p == '\\') *p = '/'; /* change to / */ p++; - } + } - fprintf(stderr, "\\\\%s\\%-16s (%s%s)\n", - smb_localNamep, this_share, (print_afs ? cm_mountRoot : "\0"), - pathName); - num_shares++; - while (*this_share != 0) this_share++; /* find next NUL */ - this_share++; /* skip past the NUL */ - } while (*this_share != 0); /* stop at final NUL */ + fprintf(stderr, "\\\\%s\\%-16s (%s%s)\n", + smb_localNamep, this_share, (print_afs ? cm_mountRoot : "\0"), + pathName); + num_shares++; + while (*this_share != 0) this_share++; /* find next NUL */ + this_share++; /* skip past the NUL */ + } while (*this_share != 0); /* stop at final NUL */ - return num_shares; + return num_shares; } #endif /* DJGPP */ @@ -1303,7 +1296,7 @@ typedef struct smb_findShare_rock { #define SMB_FINDSHARE_PARTIAL_MATCH 2 long smb_FindShareProc(cm_scache_t *scp, cm_dirEntry_t *dep, void *rockp, - osi_hyper_t *offp) + osi_hyper_t *offp) { int matchType = 0; smb_findShare_rock_t * vrock = (smb_findShare_rock_t *) rockp; @@ -1327,17 +1320,17 @@ long smb_FindShareProc(cm_scache_t *scp, cm_dirEntry_t *dep, void *rockp, int smb_FindShare(smb_vc_t *vcp, smb_user_t *uidp, char *shareName, char **pathNamep) { - DWORD len; - char pathName[1024]; - char *var; - char temp[1024]; - DWORD sizeTemp; + DWORD len; + char pathName[1024]; + char *var; + char temp[1024]; + DWORD sizeTemp; #ifdef DJGPP char sbmtpath[MAX_PATH]; #endif char *p, *q; - HKEY parmKey; - DWORD code; + HKEY parmKey; + DWORD code; DWORD allSubmount = 1; /* if allSubmounts == 0, only return the //mountRoot/all share @@ -1345,9 +1338,9 @@ int smb_FindShare(smb_vc_t *vcp, smb_user_t *uidp, char *shareName, * This is to allow sites that want to restrict access to the * world to do so. */ - code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSConfigKeyName, - 0, KEY_QUERY_VALUE, &parmKey); - if (code == ERROR_SUCCESS) { + code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSConfigKeyName, + 0, KEY_QUERY_VALUE, &parmKey); + if (code == ERROR_SUCCESS) { len = sizeof(allSubmount); code = RegQueryValueEx(parmKey, "AllSubmount", NULL, NULL, (BYTE *) &allSubmount, &len); @@ -1355,49 +1348,49 @@ int smb_FindShare(smb_vc_t *vcp, smb_user_t *uidp, char *shareName, allSubmount = 1; } RegCloseKey (parmKey); - } + } - if (allSubmount && _stricmp(shareName, "all") == 0) { - *pathNamep = NULL; - return 1; - } + if (allSubmount && _stricmp(shareName, "all") == 0) { + *pathNamep = NULL; + return 1; + } /* In case, the all share is disabled we need to still be able * to handle ioctl requests */ - if (_stricmp(shareName, "ioctl$") == 0) { - *pathNamep = strdup("/.__ioctl__"); - return 1; - } + if (_stricmp(shareName, "ioctl$") == 0) { + *pathNamep = strdup("/.__ioctl__"); + return 1; + } if (_stricmp(shareName, "IPC$") == 0 || _stricmp(shareName, SMB_IOCTL_FILENAME_NOSLASH) == 0 || _stricmp(shareName, "DESKTOP.INI") == 0 ) { - *pathNamep = NULL; - return 0; - } + *pathNamep = NULL; + return 0; + } #ifndef DJGPP - code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\OpenAFS\\Client\\Submounts", - 0, KEY_QUERY_VALUE, &parmKey); - if (code == ERROR_SUCCESS) { + code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\OpenAFS\\Client\\Submounts", + 0, KEY_QUERY_VALUE, &parmKey); + if (code == ERROR_SUCCESS) { len = sizeof(pathName); code = RegQueryValueEx(parmKey, shareName, NULL, NULL, (BYTE *) pathName, &len); - if (code != ERROR_SUCCESS) - len = 0; + if (code != ERROR_SUCCESS) + len = 0; RegCloseKey (parmKey); - } else { + } else { len = 0; } #else /* DJGPP */ strcpy(sbmtpath, cm_confDir); strcat(sbmtpath, "/afsdsbmt.ini"); - len = GetPrivateProfileString("AFS Submounts", shareName, "", - pathName, sizeof(pathName), sbmtpath); + len = GetPrivateProfileString("AFS Submounts", shareName, "", + pathName, sizeof(pathName), sbmtpath); #endif /* !DJGPP */ - if (len != 0 && len != sizeof(pathName) - 1) { + if (len != 0 && len != sizeof(pathName) - 1) { /* We can accept either unix or PC style AFS pathnames. Convert * Unix-style to PC style here for internal use. */ @@ -1498,7 +1491,7 @@ int smb_FindShare(smb_vc_t *vcp, smb_user_t *uidp, char *shareName, *pathNamep = strdup(strlwr(pathName)); return 1; } - } + } /* failure */ *pathNamep = NULL; return 0; @@ -1547,7 +1540,7 @@ int smb_FindShareCSCPolicy(char *shareName) } RegCloseKey(hkCSCPolicy); - return retval; + return retval; } /* find a dir search structure by cookie value, and return it held. @@ -1555,76 +1548,76 @@ int smb_FindShareCSCPolicy(char *shareName) */ smb_dirSearch_t *smb_FindDirSearchNL(long cookie) { - smb_dirSearch_t *dsp; + smb_dirSearch_t *dsp; - for(dsp = smb_firstDirSearchp; dsp; dsp = (smb_dirSearch_t *) osi_QNext(&dsp->q)) { - if (dsp->cookie == cookie) { - if (dsp != smb_firstDirSearchp) { - /* move to head of LRU queue, too, if we're not already there */ - if (smb_lastDirSearchp == (smb_dirSearch_t *) &dsp->q) - smb_lastDirSearchp = (smb_dirSearch_t *) - osi_QPrev(&dsp->q); - osi_QRemove((osi_queue_t **) &smb_firstDirSearchp, &dsp->q); - osi_QAdd((osi_queue_t **) &smb_firstDirSearchp, &dsp->q); - if (!smb_lastDirSearchp) - smb_lastDirSearchp = (smb_dirSearch_t *) &dsp->q; - } - dsp->refCount++; - break; - } - } - return dsp; -} + for(dsp = smb_firstDirSearchp; dsp; dsp = (smb_dirSearch_t *) osi_QNext(&dsp->q)) { + if (dsp->cookie == cookie) { + if (dsp != smb_firstDirSearchp) { + /* move to head of LRU queue, too, if we're not already there */ + if (smb_lastDirSearchp == (smb_dirSearch_t *) &dsp->q) + smb_lastDirSearchp = (smb_dirSearch_t *) + osi_QPrev(&dsp->q); + osi_QRemove((osi_queue_t **) &smb_firstDirSearchp, &dsp->q); + osi_QAdd((osi_queue_t **) &smb_firstDirSearchp, &dsp->q); + if (!smb_lastDirSearchp) + smb_lastDirSearchp = (smb_dirSearch_t *) &dsp->q; + } + dsp->refCount++; + break; + } + } + return dsp; +} void smb_DeleteDirSearch(smb_dirSearch_t *dsp) { - lock_ObtainWrite(&smb_globalLock); - dsp->flags |= SMB_DIRSEARCH_DELETE; - lock_ReleaseWrite(&smb_globalLock); - lock_ObtainMutex(&dsp->mx); - if(dsp->scp != NULL) { - lock_ObtainMutex(&dsp->scp->mx); - if (dsp->flags & SMB_DIRSEARCH_BULKST) { - dsp->flags &= ~SMB_DIRSEARCH_BULKST; - dsp->scp->flags &= ~CM_SCACHEFLAG_BULKSTATTING; - dsp->scp->bulkStatProgress = hones; - } - lock_ReleaseMutex(&dsp->scp->mx); - } - lock_ReleaseMutex(&dsp->mx); -} + lock_ObtainWrite(&smb_globalLock); + dsp->flags |= SMB_DIRSEARCH_DELETE; + lock_ReleaseWrite(&smb_globalLock); + lock_ObtainMutex(&dsp->mx); + if(dsp->scp != NULL) { + lock_ObtainMutex(&dsp->scp->mx); + if (dsp->flags & SMB_DIRSEARCH_BULKST) { + dsp->flags &= ~SMB_DIRSEARCH_BULKST; + dsp->scp->flags &= ~CM_SCACHEFLAG_BULKSTATTING; + dsp->scp->bulkStatProgress = hones; + } + lock_ReleaseMutex(&dsp->scp->mx); + } + lock_ReleaseMutex(&dsp->mx); +} void smb_ReleaseDirSearch(smb_dirSearch_t *dsp) { - cm_scache_t *scp; + cm_scache_t *scp; - scp = NULL; - - lock_ObtainWrite(&smb_globalLock); - osi_assert(dsp->refCount-- > 0); - if (dsp->refCount == 0 && (dsp->flags & SMB_DIRSEARCH_DELETE)) { - if (&dsp->q == (osi_queue_t *) smb_lastDirSearchp) - smb_lastDirSearchp = (smb_dirSearch_t *) osi_QPrev(&smb_lastDirSearchp->q); - osi_QRemove((osi_queue_t **) &smb_firstDirSearchp, &dsp->q); - lock_FinalizeMutex(&dsp->mx); - scp = dsp->scp; - free(dsp); - } - lock_ReleaseWrite(&smb_globalLock); - - /* do this now to avoid spurious locking hierarchy creation */ - if (scp) cm_ReleaseSCache(scp); -} + scp = NULL; + + lock_ObtainWrite(&smb_globalLock); + osi_assert(dsp->refCount-- > 0); + if (dsp->refCount == 0 && (dsp->flags & SMB_DIRSEARCH_DELETE)) { + if (&dsp->q == (osi_queue_t *) smb_lastDirSearchp) + smb_lastDirSearchp = (smb_dirSearch_t *) osi_QPrev(&smb_lastDirSearchp->q); + osi_QRemove((osi_queue_t **) &smb_firstDirSearchp, &dsp->q); + lock_FinalizeMutex(&dsp->mx); + scp = dsp->scp; + free(dsp); + } + lock_ReleaseWrite(&smb_globalLock); + + /* do this now to avoid spurious locking hierarchy creation */ + if (scp) cm_ReleaseSCache(scp); +} /* find a dir search structure by cookie value, and return it held */ smb_dirSearch_t *smb_FindDirSearch(long cookie) { - smb_dirSearch_t *dsp; + smb_dirSearch_t *dsp; - lock_ObtainWrite(&smb_globalLock); - dsp = smb_FindDirSearchNL(cookie); - lock_ReleaseWrite(&smb_globalLock); - return dsp; + lock_ObtainWrite(&smb_globalLock); + dsp = smb_FindDirSearchNL(cookie); + lock_ReleaseWrite(&smb_globalLock); + return dsp; } /* GC some dir search entries, in the address space expected by the specific protocol. @@ -1633,39 +1626,39 @@ smb_dirSearch_t *smb_FindDirSearch(long cookie) #define SMB_DIRSEARCH_GCMAX 10 /* how many at once */ void smb_GCDirSearches(int isV3) { - smb_dirSearch_t *prevp; - smb_dirSearch_t *tp; - smb_dirSearch_t *victimsp[SMB_DIRSEARCH_GCMAX]; - int victimCount; - int i; + smb_dirSearch_t *prevp; + smb_dirSearch_t *tp; + smb_dirSearch_t *victimsp[SMB_DIRSEARCH_GCMAX]; + int victimCount; + int i; - victimCount = 0; /* how many have we got so far */ - for(tp = smb_lastDirSearchp; tp; tp=prevp) { - /* we'll move tp from queue, so - * do this early. - */ - prevp = (smb_dirSearch_t *) osi_QPrev(&tp->q); - /* if no one is using this guy, and we're either in the new protocol, - * or we're in the old one and this is a small enough ID to be useful - * to the old protocol, GC this guy. - */ - if (tp->refCount == 0 && (isV3 || tp->cookie <= 255)) { - /* hold and delete */ - tp->flags |= SMB_DIRSEARCH_DELETE; - victimsp[victimCount++] = tp; - tp->refCount++; - } - - /* don't do more than this */ - if (victimCount >= SMB_DIRSEARCH_GCMAX) break; - } + victimCount = 0; /* how many have we got so far */ + for(tp = smb_lastDirSearchp; tp; tp=prevp) { + /* we'll move tp from queue, so + * do this early. + */ + prevp = (smb_dirSearch_t *) osi_QPrev(&tp->q); + /* if no one is using this guy, and we're either in the new protocol, + * or we're in the old one and this is a small enough ID to be useful + * to the old protocol, GC this guy. + */ + if (tp->refCount == 0 && (isV3 || tp->cookie <= 255)) { + /* hold and delete */ + tp->flags |= SMB_DIRSEARCH_DELETE; + victimsp[victimCount++] = tp; + tp->refCount++; + } + + /* don't do more than this */ + if (victimCount >= SMB_DIRSEARCH_GCMAX) break; + } - /* now release them */ - lock_ReleaseWrite(&smb_globalLock); - for(i = 0; i < victimCount; i++) { - smb_ReleaseDirSearch(victimsp[i]); - } - lock_ObtainWrite(&smb_globalLock); + /* now release them */ + lock_ReleaseWrite(&smb_globalLock); + for(i = 0; i < victimCount; i++) { + smb_ReleaseDirSearch(victimsp[i]); + } + lock_ObtainWrite(&smb_globalLock); } /* function for allocating a dir search entry. We need these to remember enough context @@ -1676,64 +1669,64 @@ void smb_GCDirSearches(int isV3) */ smb_dirSearch_t *smb_NewDirSearch(int isV3) { - smb_dirSearch_t *dsp; - int counter; - int maxAllowed; - - lock_ObtainWrite(&smb_globalLock); - counter = 0; - - /* what's the biggest ID allowed in this version of the protocol */ - if (isV3) maxAllowed = 65535; - else maxAllowed = 255; - - while(1) { - /* twice so we have enough tries to find guys we GC after one pass; - * 10 extra is just in case I mis-counted. - */ - if (++counter > 2*maxAllowed+10) osi_panic("afsd: dir search cookie leak", - __FILE__, __LINE__); - if (smb_dirSearchCounter > maxAllowed) { - smb_dirSearchCounter = 1; - smb_GCDirSearches(isV3); /* GC some (drops global lock) */ - } - dsp = smb_FindDirSearchNL(smb_dirSearchCounter); - if (dsp) { - /* don't need to watch for refcount zero and deleted, since - * we haven't dropped the global lock. - */ - dsp->refCount--; - ++smb_dirSearchCounter; - continue; - } - - dsp = malloc(sizeof(*dsp)); - memset(dsp, 0, sizeof(*dsp)); - osi_QAdd((osi_queue_t **) &smb_firstDirSearchp, &dsp->q); - if (!smb_lastDirSearchp) smb_lastDirSearchp = (smb_dirSearch_t *) &dsp->q; - dsp->cookie = smb_dirSearchCounter; - ++smb_dirSearchCounter; - dsp->refCount = 1; - lock_InitializeMutex(&dsp->mx, "cm_dirSearch_t"); - dsp->lastTime = osi_Time(); - break; - } - lock_ReleaseWrite(&smb_globalLock); - return dsp; + smb_dirSearch_t *dsp; + int counter; + int maxAllowed; + + lock_ObtainWrite(&smb_globalLock); + counter = 0; + + /* what's the biggest ID allowed in this version of the protocol */ + if (isV3) maxAllowed = 65535; + else maxAllowed = 255; + + while(1) { + /* twice so we have enough tries to find guys we GC after one pass; + * 10 extra is just in case I mis-counted. + */ + if (++counter > 2*maxAllowed+10) osi_panic("afsd: dir search cookie leak", + __FILE__, __LINE__); + if (smb_dirSearchCounter > maxAllowed) { + smb_dirSearchCounter = 1; + smb_GCDirSearches(isV3); /* GC some (drops global lock) */ + } + dsp = smb_FindDirSearchNL(smb_dirSearchCounter); + if (dsp) { + /* don't need to watch for refcount zero and deleted, since + * we haven't dropped the global lock. + */ + dsp->refCount--; + ++smb_dirSearchCounter; + continue; + } + + dsp = malloc(sizeof(*dsp)); + memset(dsp, 0, sizeof(*dsp)); + osi_QAdd((osi_queue_t **) &smb_firstDirSearchp, &dsp->q); + if (!smb_lastDirSearchp) smb_lastDirSearchp = (smb_dirSearch_t *) &dsp->q; + dsp->cookie = smb_dirSearchCounter; + ++smb_dirSearchCounter; + dsp->refCount = 1; + lock_InitializeMutex(&dsp->mx, "cm_dirSearch_t"); + dsp->lastTime = osi_Time(); + break; + } + lock_ReleaseWrite(&smb_globalLock); + return dsp; } static smb_packet_t *GetPacket(void) { - smb_packet_t *tbp; + smb_packet_t *tbp; #ifdef DJGPP - unsigned int npar, seg, tb_sel; + unsigned int npar, seg, tb_sel; #endif - lock_ObtainWrite(&smb_globalLock); - tbp = smb_packetFreeListp; + lock_ObtainWrite(&smb_globalLock); + tbp = smb_packetFreeListp; if (tbp) smb_packetFreeListp = tbp->nextp; - lock_ReleaseWrite(&smb_globalLock); + lock_ReleaseWrite(&smb_globalLock); if (!tbp) { #ifndef DJGPP tbp = calloc(65540,1); @@ -1741,16 +1734,16 @@ static smb_packet_t *GetPacket(void) tbp = malloc(sizeof(smb_packet_t)); #endif /* !DJGPP */ tbp->magic = SMB_PACKETMAGIC; - tbp->ncbp = NULL; - tbp->vcp = NULL; - tbp->resumeCode = 0; - tbp->inCount = 0; - tbp->fid = 0; - tbp->wctp = NULL; - tbp->inCom = 0; - tbp->oddByte = 0; - tbp->ncb_length = 0; - tbp->flags = 0; + tbp->ncbp = NULL; + tbp->vcp = NULL; + tbp->resumeCode = 0; + tbp->inCount = 0; + tbp->fid = 0; + tbp->wctp = NULL; + tbp->inCom = 0; + tbp->oddByte = 0; + tbp->ncb_length = 0; + tbp->flags = 0; tbp->spacep = NULL; #ifdef DJGPP @@ -1772,7 +1765,7 @@ static smb_packet_t *GetPacket(void) tbp->dos_pkt = (seg * 16) + 0; /* DOS physical address */ tbp->dos_pkt_sel = tb_sel; #endif /* DJGPP */ - } + } osi_assert(tbp->magic == SMB_PACKETMAGIC); return tbp; @@ -1780,26 +1773,26 @@ static smb_packet_t *GetPacket(void) smb_packet_t *smb_CopyPacket(smb_packet_t *pkt) { - smb_packet_t *tbp; - tbp = GetPacket(); - memcpy(tbp, pkt, sizeof(smb_packet_t)); - tbp->wctp = tbp->data + ((unsigned int)pkt->wctp - (unsigned int)pkt->data); - return tbp; + smb_packet_t *tbp; + tbp = GetPacket(); + memcpy(tbp, pkt, sizeof(smb_packet_t)); + tbp->wctp = tbp->data + ((unsigned int)pkt->wctp - (unsigned int)pkt->data); + return tbp; } static NCB *GetNCB(void) { - smb_ncb_t *tbp; + smb_ncb_t *tbp; NCB *ncbp; #ifdef DJGPP unsigned int npar, seg, tb_sel; #endif /* DJGPP */ - lock_ObtainWrite(&smb_globalLock); - tbp = smb_ncbFreeListp; + lock_ObtainWrite(&smb_globalLock); + tbp = smb_ncbFreeListp; if (tbp) smb_ncbFreeListp = tbp->nextp; - lock_ReleaseWrite(&smb_globalLock); + lock_ReleaseWrite(&smb_globalLock); if (!tbp) { #ifndef DJGPP tbp = calloc(sizeof(*tbp),1); @@ -1823,11 +1816,11 @@ static NCB *GetNCB(void) tbp->dos_ncb_sel = tb_sel; #endif /* !DJGPP */ tbp->magic = SMB_NCBMAGIC; - } + } osi_assert(tbp->magic == SMB_NCBMAGIC); - memset(&tbp->ncb, 0, sizeof(NCB)); + memset(&tbp->ncb, 0, sizeof(NCB)); ncbp = &tbp->ncb; #ifdef DJGPP dos_memset(tbp->dos_ncb, 0, sizeof(NCB)); @@ -1840,32 +1833,32 @@ void smb_FreePacket(smb_packet_t *tbp) osi_assert(tbp->magic == SMB_PACKETMAGIC); lock_ObtainWrite(&smb_globalLock); - tbp->nextp = smb_packetFreeListp; - smb_packetFreeListp = tbp; - tbp->magic = SMB_PACKETMAGIC; - tbp->ncbp = NULL; - tbp->vcp = NULL; - tbp->resumeCode = 0; - tbp->inCount = 0; - tbp->fid = 0; - tbp->wctp = NULL; - tbp->inCom = 0; - tbp->oddByte = 0; - tbp->ncb_length = 0; - tbp->flags = 0; + tbp->nextp = smb_packetFreeListp; + smb_packetFreeListp = tbp; + tbp->magic = SMB_PACKETMAGIC; + tbp->ncbp = NULL; + tbp->vcp = NULL; + tbp->resumeCode = 0; + tbp->inCount = 0; + tbp->fid = 0; + tbp->wctp = NULL; + tbp->inCom = 0; + tbp->oddByte = 0; + tbp->ncb_length = 0; + tbp->flags = 0; lock_ReleaseWrite(&smb_globalLock); } static void FreeNCB(NCB *bufferp) { - smb_ncb_t *tbp; + smb_ncb_t *tbp; tbp = (smb_ncb_t *) bufferp; osi_assert(tbp->magic == SMB_NCBMAGIC); lock_ObtainWrite(&smb_globalLock); - tbp->nextp = smb_ncbFreeListp; - smb_ncbFreeListp = tbp; + tbp->nextp = smb_ncbFreeListp; + smb_ncbFreeListp = tbp; lock_ReleaseWrite(&smb_globalLock); } @@ -1877,12 +1870,12 @@ unsigned char *smb_GetSMBData(smb_packet_t *smbp, int *nbytesp) unsigned char *afterParmsp; parmBytes = *smbp->wctp << 1; - afterParmsp = smbp->wctp + parmBytes + 1; + afterParmsp = smbp->wctp + parmBytes + 1; dataBytes = afterParmsp[0] + (afterParmsp[1]<<8); if (nbytesp) *nbytesp = dataBytes; - /* don't forget to skip the data byte count, since it follows + /* don't forget to skip the data byte count, since it follows * the parameters; that's where the "2" comes from below. */ return (unsigned char *) (afterParmsp + 2); @@ -1894,268 +1887,271 @@ unsigned char *smb_GetSMBData(smb_packet_t *smbp, int *nbytesp) */ void smb_SetSMBDataLength(smb_packet_t *smbp, unsigned int dsize) { - unsigned char *afterParmsp; + unsigned char *afterParmsp; - afterParmsp = smbp->wctp + ((*smbp->wctp)<<1) + 1; + afterParmsp = smbp->wctp + ((*smbp->wctp)<<1) + 1; - *afterParmsp++ = dsize & 0xff; - *afterParmsp = (dsize>>8) & 0xff; -} + *afterParmsp++ = dsize & 0xff; + *afterParmsp = (dsize>>8) & 0xff; +} /* return the parm'th parameter in the smbp packet */ unsigned int smb_GetSMBParm(smb_packet_t *smbp, int parm) { - int parmCount; - unsigned char *parmDatap; + int parmCount; + unsigned char *parmDatap; - parmCount = *smbp->wctp; + parmCount = *smbp->wctp; - if (parm >= parmCount) { - char s[100]; + if (parm >= parmCount) { + char s[100]; #ifndef DJGPP HANDLE h; - char *ptbuf[1]; - h = RegisterEventSource(NULL, AFS_DAEMON_EVENT_NAME); -#endif - sprintf(s, "Bad SMB param %d out of %d, ncb len %d", - parm, parmCount, smbp->ncb_length); -#ifndef DJGPP - ptbuf[0] = s; - ReportEvent(h, EVENTLOG_ERROR_TYPE, 0, 1006, NULL, - 1, smbp->ncb_length, ptbuf, smbp); - DeregisterEventSource(h); + char *ptbuf[1]; + h = RegisterEventSource(NULL, AFS_DAEMON_EVENT_NAME); +#endif + sprintf(s, "Bad SMB param %d out of %d, ncb len %d", + parm, parmCount, smbp->ncb_length); +#ifndef DJGPP + ptbuf[0] = s; + ReportEvent(h, EVENTLOG_ERROR_TYPE, 0, 1006, NULL, + 1, smbp->ncb_length, ptbuf, smbp); + DeregisterEventSource(h); #endif osi_Log0(smb_logp, osi_LogSaveString(smb_logp, s)); - osi_panic(s, __FILE__, __LINE__); - } - parmDatap = smbp->wctp + (2*parm) + 1; + osi_panic(s, __FILE__, __LINE__); + } + parmDatap = smbp->wctp + (2*parm) + 1; - return parmDatap[0] + (parmDatap[1] << 8); + return parmDatap[0] + (parmDatap[1] << 8); } /* return the parm'th parameter in the smbp packet */ unsigned int smb_GetSMBOffsetParm(smb_packet_t *smbp, int parm, int offset) { - int parmCount; - unsigned char *parmDatap; + int parmCount; + unsigned char *parmDatap; - parmCount = *smbp->wctp; + parmCount = *smbp->wctp; - if (parm * 2 + offset >= parmCount * 2) { - char s[100]; + if (parm * 2 + offset >= parmCount * 2) { + char s[100]; #ifndef DJGPP - HANDLE h; - char *ptbuf[1]; - h = RegisterEventSource(NULL, AFS_DAEMON_EVENT_NAME); + HANDLE h; + char *ptbuf[1]; + h = RegisterEventSource(NULL, AFS_DAEMON_EVENT_NAME); #endif - sprintf(s, "Bad SMB param %d offset %d out of %d, ncb len %d", - parm, offset, parmCount, smbp->ncb_length); + sprintf(s, "Bad SMB param %d offset %d out of %d, ncb len %d", + parm, offset, parmCount, smbp->ncb_length); #ifndef DJGPP ptbuf[0] = s; - ReportEvent(h, EVENTLOG_ERROR_TYPE, 0, 1006, NULL, - 1, smbp->ncb_length, ptbuf, smbp); - DeregisterEventSource(h); + ReportEvent(h, EVENTLOG_ERROR_TYPE, 0, 1006, NULL, + 1, smbp->ncb_length, ptbuf, smbp); + DeregisterEventSource(h); #endif osi_Log0(smb_logp, osi_LogSaveString(smb_logp, s)); - osi_panic(s, __FILE__, __LINE__); - } - parmDatap = smbp->wctp + (2*parm) + 1 + offset; + osi_panic(s, __FILE__, __LINE__); + } + parmDatap = smbp->wctp + (2*parm) + 1 + offset; - return parmDatap[0] + (parmDatap[1] << 8); + return parmDatap[0] + (parmDatap[1] << 8); } void smb_SetSMBParm(smb_packet_t *smbp, int slot, unsigned int parmValue) { - char *parmDatap; + char *parmDatap; - /* make sure we have enough slots */ - if (*smbp->wctp <= slot) *smbp->wctp = slot+1; + /* make sure we have enough slots */ + if (*smbp->wctp <= slot) + *smbp->wctp = slot+1; - parmDatap = smbp->wctp + 2*slot + 1 + smbp->oddByte; - *parmDatap++ = parmValue & 0xff; - *parmDatap = (parmValue>>8) & 0xff; -} + parmDatap = smbp->wctp + 2*slot + 1 + smbp->oddByte; + *parmDatap++ = parmValue & 0xff; + *parmDatap = (parmValue>>8) & 0xff; +} void smb_SetSMBParmLong(smb_packet_t *smbp, int slot, unsigned int parmValue) { - char *parmDatap; + char *parmDatap; - /* make sure we have enough slots */ - if (*smbp->wctp <= slot) *smbp->wctp = slot+2; + /* make sure we have enough slots */ + if (*smbp->wctp <= slot) + *smbp->wctp = slot+2; - parmDatap = smbp->wctp + 2*slot + 1 + smbp->oddByte; - *parmDatap++ = parmValue & 0xff; - *parmDatap++ = (parmValue>>8) & 0xff; - *parmDatap++ = (parmValue>>16) & 0xff; - *parmDatap++ = (parmValue>>24) & 0xff; + parmDatap = smbp->wctp + 2*slot + 1 + smbp->oddByte; + *parmDatap++ = parmValue & 0xff; + *parmDatap++ = (parmValue>>8) & 0xff; + *parmDatap++ = (parmValue>>16) & 0xff; + *parmDatap++ = (parmValue>>24) & 0xff; } void smb_SetSMBParmDouble(smb_packet_t *smbp, int slot, char *parmValuep) { - char *parmDatap; - int i; + char *parmDatap; + int i; - /* make sure we have enough slots */ - if (*smbp->wctp <= slot) *smbp->wctp = slot+4; + /* make sure we have enough slots */ + if (*smbp->wctp <= slot) + *smbp->wctp = slot+4; - parmDatap = smbp->wctp + 2*slot + 1 + smbp->oddByte; - for (i=0; i<8; i++) - *parmDatap++ = *parmValuep++; -} + parmDatap = smbp->wctp + 2*slot + 1 + smbp->oddByte; + for (i=0; i<8; i++) + *parmDatap++ = *parmValuep++; +} void smb_SetSMBParmByte(smb_packet_t *smbp, int slot, unsigned int parmValue) { - char *parmDatap; - - /* make sure we have enough slots */ - if (*smbp->wctp <= slot) { - if (smbp->oddByte) { - smbp->oddByte = 0; - *smbp->wctp = slot+1; - } else - smbp->oddByte = 1; - } - - parmDatap = smbp->wctp + 2*slot + 1 + (1 - smbp->oddByte); - *parmDatap++ = parmValue & 0xff; + char *parmDatap; + + /* make sure we have enough slots */ + if (*smbp->wctp <= slot) { + if (smbp->oddByte) { + smbp->oddByte = 0; + *smbp->wctp = slot+1; + } else + smbp->oddByte = 1; + } + + parmDatap = smbp->wctp + 2*slot + 1 + (1 - smbp->oddByte); + *parmDatap++ = parmValue & 0xff; } void smb_StripLastComponent(char *outPathp, char **lastComponentp, char *inPathp) { - char *lastSlashp; + char *lastSlashp; - lastSlashp = strrchr(inPathp, '\\'); - if (lastComponentp) - *lastComponentp = lastSlashp; - if (lastSlashp) { - while (1) { - if (inPathp == lastSlashp) - break; - *outPathp++ = *inPathp++; - } - *outPathp++ = 0; - } - else { - *outPathp++ = 0; - } + lastSlashp = strrchr(inPathp, '\\'); + if (lastComponentp) + *lastComponentp = lastSlashp; + if (lastSlashp) { + while (1) { + if (inPathp == lastSlashp) + break; + *outPathp++ = *inPathp++; + } + *outPathp++ = 0; + } + else { + *outPathp++ = 0; + } } unsigned char *smb_ParseASCIIBlock(unsigned char *inp, char **chainpp) { - if (*inp++ != 0x4) - return NULL; - if (chainpp) { - *chainpp = inp + strlen(inp) + 1; /* skip over null-terminated string */ - } - return inp; + if (*inp++ != 0x4) + return NULL; + if (chainpp) { + *chainpp = inp + strlen(inp) + 1; /* skip over null-terminated string */ + } + return inp; } unsigned char *smb_ParseVblBlock(unsigned char *inp, char **chainpp, int *lengthp) { - int tlen; + int tlen; + + if (*inp++ != 0x5) + return NULL; + tlen = inp[0] + (inp[1]<<8); + inp += 2; /* skip length field */ - if (*inp++ != 0x5) - return NULL; - tlen = inp[0] + (inp[1]<<8); - inp += 2; /* skip length field */ + if (chainpp) { + *chainpp = inp + tlen; + } - if (chainpp) { - *chainpp = inp + tlen; - } + if (lengthp) + *lengthp = tlen; - if (lengthp) - *lengthp = tlen; - - return inp; + return inp; } /* format a packet as a response */ void smb_FormatResponsePacket(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *op) { - smb_t *outp; - smb_t *inSmbp; + smb_t *outp; + smb_t *inSmbp; - outp = (smb_t *) op; + outp = (smb_t *) op; - /* zero the basic structure through the smb_wct field, and zero the data - * size field, assuming that wct stays zero; otherwise, you have to - * explicitly set the data size field, too. - */ - inSmbp = (smb_t *) inp; - memset(outp, 0, sizeof(smb_t)+2); - outp->id[0] = 0xff; - outp->id[1] = 'S'; - outp->id[2] = 'M'; - outp->id[3] = 'B'; - if (inp) { - outp->com = inSmbp->com; - outp->tid = inSmbp->tid; - outp->pid = inSmbp->pid; - outp->uid = inSmbp->uid; - outp->mid = inSmbp->mid; - outp->res[0] = inSmbp->res[0]; - outp->res[1] = inSmbp->res[1]; - op->inCom = inSmbp->com; - } - outp->reb = 0x80; /* SERVER_RESP */ - outp->flg2 = 0x1; /* KNOWS_LONG_NAMES */ - - /* copy fields in generic packet area */ - op->wctp = &outp->wct; -} + /* zero the basic structure through the smb_wct field, and zero the data + * size field, assuming that wct stays zero; otherwise, you have to + * explicitly set the data size field, too. + */ + inSmbp = (smb_t *) inp; + memset(outp, 0, sizeof(smb_t)+2); + outp->id[0] = 0xff; + outp->id[1] = 'S'; + outp->id[2] = 'M'; + outp->id[3] = 'B'; + if (inp) { + outp->com = inSmbp->com; + outp->tid = inSmbp->tid; + outp->pid = inSmbp->pid; + outp->uid = inSmbp->uid; + outp->mid = inSmbp->mid; + outp->res[0] = inSmbp->res[0]; + outp->res[1] = inSmbp->res[1]; + op->inCom = inSmbp->com; + } + outp->reb = 0x80; /* SERVER_RESP */ + outp->flg2 = 0x1; /* KNOWS_LONG_NAMES */ + + /* copy fields in generic packet area */ + op->wctp = &outp->wct; +} /* send a (probably response) packet; vcp tells us to whom to send it. * we compute the length by looking at wct and bcc fields. */ void smb_SendPacket(smb_vc_t *vcp, smb_packet_t *inp) { - NCB *ncbp; - int extra; - long code = 0; - unsigned char *tp; - int localNCB = 0; + NCB *ncbp; + int extra; + long code = 0; + unsigned char *tp; + int localNCB = 0; #ifdef DJGPP - dos_ptr dos_ncb; + dos_ptr dos_ncb; #endif /* DJGPP */ - ncbp = inp->ncbp; - if (ncbp == NULL) { - ncbp = GetNCB(); - localNCB = 1; - } + ncbp = inp->ncbp; + if (ncbp == NULL) { + ncbp = GetNCB(); + localNCB = 1; + } #ifdef DJGPP - dos_ncb = ((smb_ncb_t *)ncbp)->dos_ncb; + dos_ncb = ((smb_ncb_t *)ncbp)->dos_ncb; #endif /* DJGPP */ - memset((char *)ncbp, 0, sizeof(NCB)); + memset((char *)ncbp, 0, sizeof(NCB)); - extra = 2 * (*inp->wctp); /* space used by parms, in bytes */ - tp = inp->wctp + 1+ extra; /* points to count of data bytes */ - extra += tp[0] + (tp[1]<<8); - extra += ((unsigned int)inp->wctp - (unsigned int)inp->data); /* distance to last wct field */ - extra += 3; /* wct and length fields */ + extra = 2 * (*inp->wctp); /* space used by parms, in bytes */ + tp = inp->wctp + 1+ extra; /* points to count of data bytes */ + extra += tp[0] + (tp[1]<<8); + extra += ((unsigned int)inp->wctp - (unsigned int)inp->data); /* distance to last wct field */ + extra += 3; /* wct and length fields */ - ncbp->ncb_length = extra; /* bytes to send */ - ncbp->ncb_lsn = (unsigned char) vcp->lsn; /* vc to use */ - ncbp->ncb_lana_num = vcp->lana; - ncbp->ncb_command = NCBSEND; /* op means send data */ + ncbp->ncb_length = extra; /* bytes to send */ + ncbp->ncb_lsn = (unsigned char) vcp->lsn; /* vc to use */ + ncbp->ncb_lana_num = vcp->lana; + ncbp->ncb_command = NCBSEND; /* op means send data */ #ifndef DJGPP - ncbp->ncb_buffer = (char *) inp;/* packet */ - code = Netbios(ncbp); + ncbp->ncb_buffer = (char *) inp;/* packet */ + code = Netbios(ncbp); #else /* DJGPP */ - ncbp->ncb_buffer = inp->dos_pkt;/* packet */ - ((smb_ncb_t*)ncbp)->orig_pkt = inp; + ncbp->ncb_buffer = inp->dos_pkt;/* packet */ + ((smb_ncb_t*)ncbp)->orig_pkt = inp; - /* copy header information from virtual to DOS address space */ - dosmemput((char*)inp, SMB_PACKETSIZE, inp->dos_pkt); - code = Netbios(ncbp, dos_ncb); + /* copy header information from virtual to DOS address space */ + dosmemput((char*)inp, SMB_PACKETSIZE, inp->dos_pkt); + code = Netbios(ncbp, dos_ncb); #endif /* !DJGPP */ - if (code != 0) - osi_Log1(smb_logp, "SendPacket failure code %d", code); + if (code != 0) + osi_Log1(smb_logp, "SendPacket failure code %d", code); - if (localNCB) - FreeNCB(ncbp); + if (localNCB) + FreeNCB(ncbp); } void smb_MapNTError(long code, unsigned long *NTStatusp) @@ -2243,7 +2239,11 @@ void smb_MapNTError(long code, unsigned long *NTStatusp) NTStatus = 0xC09820FBL; /* SMB use standard */ } else if (code == CM_ERROR_QUOTA) { +#ifdef COMMENT NTStatus = 0xC0000044L; /* Quota exceeded */ +#else + NTStatus = 0xC000007FL; /* Disk full */ +#endif } else if (code == CM_ERROR_SPACE) { NTStatus = 0xC000007FL; /* Disk full */ @@ -2284,162 +2284,162 @@ void smb_MapNTError(long code, unsigned long *NTStatusp) } void smb_MapCoreError(long code, smb_vc_t *vcp, unsigned short *scodep, - unsigned char *classp) + unsigned char *classp) { - unsigned char class; - unsigned short error; - - /* map CM_ERROR_* errors to SMB errors */ - if (code == CM_ERROR_NOSUCHCELL) { - class = 1; - error = 3; /* bad path */ - } - else if (code == CM_ERROR_NOSUCHVOLUME) { - class = 1; - error = 3; /* bad path */ - } - else if (code == CM_ERROR_TIMEDOUT) { - class = 2; - error = 81; /* server is paused */ - } - else if (code == CM_ERROR_RETRY) { - class = 2; /* shouldn't happen */ - error = 1; - } - else if (code == CM_ERROR_NOACCESS) { - class = 2; - error = 4; /* bad access */ - } - else if (code == CM_ERROR_READONLY) { - class = 3; - error = 19; /* read only */ - } - else if (code == CM_ERROR_NOSUCHFILE) { - class = 1; - error = 2; /* ENOENT! */ - } - else if (code == CM_ERROR_NOSUCHPATH) { - class = 1; - error = 3; /* Bad path */ - } - else if (code == CM_ERROR_TOOBIG) { - class = 1; - error = 11; /* bad format */ - } - else if (code == CM_ERROR_INVAL) { - class = 2; /* server non-specific error code */ - error = 1; - } - else if (code == CM_ERROR_BADFD) { - class = 1; - error = 6; /* invalid file handle */ - } - else if (code == CM_ERROR_BADFDOP) { - class = 1; /* invalid op on FD */ - error = 5; - } - else if (code == CM_ERROR_EXISTS) { - class = 1; - error = 80; /* file already exists */ - } - else if (code == CM_ERROR_NOTEMPTY) { - class = 1; - error = 5; /* delete directory not empty */ - } - else if (code == CM_ERROR_CROSSDEVLINK) { - class = 1; - error = 17; /* EXDEV */ - } - else if (code == CM_ERROR_NOTDIR) { - class = 1; /* bad path */ - error = 3; - } - else if (code == CM_ERROR_ISDIR) { - class = 1; /* access denied; DOS doesn't have a good match */ - error = 5; - } - else if (code == CM_ERROR_BADOP) { - class = 2; - error = 65535; - } - else if (code == CM_ERROR_BADSHARENAME) { - class = 2; - error = 6; - } - else if (code == CM_ERROR_NOIPC) { - class = 2; - error = 4; /* bad access */ - } - else if (code == CM_ERROR_CLOCKSKEW) { - class = 1; /* invalid function */ - error = 1; - } - else if (code == CM_ERROR_BADTID) { - class = 2; - error = 5; - } - else if (code == CM_ERROR_USESTD) { - class = 2; - error = 251; - } - else if (code == CM_ERROR_REMOTECONN) { - class = 2; - error = 82; - } - else if (code == CM_ERROR_QUOTA) { - if (vcp->flags & SMB_VCFLAG_USEV3) { - class = 3; - error = 39; /* disk full */ - } - else { - class = 1; - error = 5; /* access denied */ - } - } - else if (code == CM_ERROR_SPACE) { - if (vcp->flags & SMB_VCFLAG_USEV3) { - class = 3; - error = 39; /* disk full */ - } - else { - class = 1; - error = 5; /* access denied */ - } - } - else if (code == CM_ERROR_PARTIALWRITE) { - class = 3; - error = 39; /* disk full */ - } - else if (code == CM_ERROR_ATSYS) { - class = 1; - error = 2; /* ENOENT */ - } - else if (code == CM_ERROR_WOULDBLOCK) { - class = 1; - error = 33; /* lock conflict */ - } - else if (code == CM_ERROR_NOFILES) { - class = 1; - error = 18; /* no files in search */ - } - else if (code == CM_ERROR_RENAME_IDENTICAL) { - class = 1; - error = 183; /* Samba uses this */ - } - else if (code == CM_ERROR_BADPASSWORD || code == CM_ERROR_BADLOGONTYPE) { - /* we don't have a good way of reporting CM_ERROR_BADLOGONTYPE */ - class = 2; - error = 2; /* bad password */ - } - else { - class = 2; - error = 1; - } - - *scodep = error; - *classp = class; - osi_Log3(smb_logp, "SMB SEND code %lX as SMB %d: %d", code, class, error); -} + unsigned char class; + unsigned short error; + + /* map CM_ERROR_* errors to SMB errors */ + if (code == CM_ERROR_NOSUCHCELL) { + class = 1; + error = 3; /* bad path */ + } + else if (code == CM_ERROR_NOSUCHVOLUME) { + class = 1; + error = 3; /* bad path */ + } + else if (code == CM_ERROR_TIMEDOUT) { + class = 2; + error = 81; /* server is paused */ + } + else if (code == CM_ERROR_RETRY) { + class = 2; /* shouldn't happen */ + error = 1; + } + else if (code == CM_ERROR_NOACCESS) { + class = 2; + error = 4; /* bad access */ + } + else if (code == CM_ERROR_READONLY) { + class = 3; + error = 19; /* read only */ + } + else if (code == CM_ERROR_NOSUCHFILE) { + class = 1; + error = 2; /* ENOENT! */ + } + else if (code == CM_ERROR_NOSUCHPATH) { + class = 1; + error = 3; /* Bad path */ + } + else if (code == CM_ERROR_TOOBIG) { + class = 1; + error = 11; /* bad format */ + } + else if (code == CM_ERROR_INVAL) { + class = 2; /* server non-specific error code */ + error = 1; + } + else if (code == CM_ERROR_BADFD) { + class = 1; + error = 6; /* invalid file handle */ + } + else if (code == CM_ERROR_BADFDOP) { + class = 1; /* invalid op on FD */ + error = 5; + } + else if (code == CM_ERROR_EXISTS) { + class = 1; + error = 80; /* file already exists */ + } + else if (code == CM_ERROR_NOTEMPTY) { + class = 1; + error = 5; /* delete directory not empty */ + } + else if (code == CM_ERROR_CROSSDEVLINK) { + class = 1; + error = 17; /* EXDEV */ + } + else if (code == CM_ERROR_NOTDIR) { + class = 1; /* bad path */ + error = 3; + } + else if (code == CM_ERROR_ISDIR) { + class = 1; /* access denied; DOS doesn't have a good match */ + error = 5; + } + else if (code == CM_ERROR_BADOP) { + class = 2; + error = 65535; + } + else if (code == CM_ERROR_BADSHARENAME) { + class = 2; + error = 6; + } + else if (code == CM_ERROR_NOIPC) { + class = 2; + error = 4; /* bad access */ + } + else if (code == CM_ERROR_CLOCKSKEW) { + class = 1; /* invalid function */ + error = 1; + } + else if (code == CM_ERROR_BADTID) { + class = 2; + error = 5; + } + else if (code == CM_ERROR_USESTD) { + class = 2; + error = 251; + } + else if (code == CM_ERROR_REMOTECONN) { + class = 2; + error = 82; + } + else if (code == CM_ERROR_QUOTA) { + if (vcp->flags & SMB_VCFLAG_USEV3) { + class = 3; + error = 39; /* disk full */ + } + else { + class = 1; + error = 5; /* access denied */ + } + } + else if (code == CM_ERROR_SPACE) { + if (vcp->flags & SMB_VCFLAG_USEV3) { + class = 3; + error = 39; /* disk full */ + } + else { + class = 1; + error = 5; /* access denied */ + } + } + else if (code == CM_ERROR_PARTIALWRITE) { + class = 3; + error = 39; /* disk full */ + } + else if (code == CM_ERROR_ATSYS) { + class = 1; + error = 2; /* ENOENT */ + } + else if (code == CM_ERROR_WOULDBLOCK) { + class = 1; + error = 33; /* lock conflict */ + } + else if (code == CM_ERROR_NOFILES) { + class = 1; + error = 18; /* no files in search */ + } + else if (code == CM_ERROR_RENAME_IDENTICAL) { + class = 1; + error = 183; /* Samba uses this */ + } + else if (code == CM_ERROR_BADPASSWORD || code == CM_ERROR_BADLOGONTYPE) { + /* we don't have a good way of reporting CM_ERROR_BADLOGONTYPE */ + class = 2; + error = 2; /* bad password */ + } + else { + class = 2; + error = 1; + } + + *scodep = error; + *classp = class; + osi_Log3(smb_logp, "SMB SEND code %lX as SMB %d: %d", code, class, error); +} long smb_SendCoreBadOp(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { @@ -2449,32 +2449,32 @@ long smb_SendCoreBadOp(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) long smb_ReceiveCoreEcho(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { - unsigned short EchoCount, i; - char *data, *outdata; - int dataSize; - - EchoCount = (unsigned short) smb_GetSMBParm(inp, 0); - - for (i=1; i<=EchoCount; i++) { - data = smb_GetSMBData(inp, &dataSize); - smb_SetSMBParm(outp, 0, i); - smb_SetSMBDataLength(outp, dataSize); - outdata = smb_GetSMBData(outp, NULL); - memcpy(outdata, data, dataSize); - smb_SendPacket(vcp, outp); - } - - return 0; + unsigned short EchoCount, i; + char *data, *outdata; + int dataSize; + + EchoCount = (unsigned short) smb_GetSMBParm(inp, 0); + + for (i=1; i<=EchoCount; i++) { + data = smb_GetSMBData(inp, &dataSize); + smb_SetSMBParm(outp, 0, i); + smb_SetSMBDataLength(outp, dataSize); + outdata = smb_GetSMBData(outp, NULL); + memcpy(outdata, data, dataSize); + smb_SendPacket(vcp, outp); + } + + return 0; } long smb_ReceiveCoreReadRaw(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { - osi_hyper_t offset; - long count, minCount, finalCount; - unsigned short fd; - smb_fid_t *fidp; - long code = 0; - cm_user_t *userp = NULL; + osi_hyper_t offset; + long count, minCount, finalCount; + unsigned short fd; + smb_fid_t *fidp; + long code = 0; + cm_user_t *userp = NULL; NCB *ncbp; int rc; #ifndef DJGPP @@ -2484,35 +2484,35 @@ long smb_ReceiveCoreReadRaw(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp dos_ptr dos_ncb; #endif /* DJGPP */ - rawBuf = NULL; - finalCount = 0; + rawBuf = NULL; + finalCount = 0; - fd = smb_GetSMBParm(inp, 0); - count = smb_GetSMBParm(inp, 3); - minCount = smb_GetSMBParm(inp, 4); - offset.HighPart = 0; /* too bad */ - offset.LowPart = smb_GetSMBParm(inp, 1) | (smb_GetSMBParm(inp, 2) << 16); + fd = smb_GetSMBParm(inp, 0); + count = smb_GetSMBParm(inp, 3); + minCount = smb_GetSMBParm(inp, 4); + offset.HighPart = 0; /* too bad */ + offset.LowPart = smb_GetSMBParm(inp, 1) | (smb_GetSMBParm(inp, 2) << 16); - osi_Log3(smb_logp, "smb_ReceieveCoreReadRaw fd %d, off 0x%x, size 0x%x", + osi_Log3(smb_logp, "smb_ReceieveCoreReadRaw fd %d, off 0x%x, size 0x%x", fd, offset.LowPart, count); - fidp = smb_FindFID(vcp, fd, 0); - if (!fidp) - goto send1; + fidp = smb_FindFID(vcp, fd, 0); + if (!fidp) + goto send1; - lock_ObtainMutex(&smb_RawBufLock); - if (smb_RawBufs) { - /* Get a raw buf, from head of list */ - rawBuf = smb_RawBufs; + lock_ObtainMutex(&smb_RawBufLock); + if (smb_RawBufs) { + /* Get a raw buf, from head of list */ + rawBuf = smb_RawBufs; #ifndef DJGPP - smb_RawBufs = *(char **)smb_RawBufs; + smb_RawBufs = *(char **)smb_RawBufs; #else /* DJGPP */ smb_RawBufs = _farpeekl(_dos_ds, smb_RawBufs); #endif /* !DJGPP */ - } - lock_ReleaseMutex(&smb_RawBufLock); - if (!rawBuf) - goto send1a; + } + lock_ReleaseMutex(&smb_RawBufLock); + if (!rawBuf) + goto send1a; if (fidp->flags & SMB_FID_IOCTL) { @@ -2541,173 +2541,177 @@ long smb_ReceiveCoreReadRaw(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp userp = smb_GetUser(vcp, inp); #ifndef DJGPP - code = smb_ReadData(fidp, &offset, count, rawBuf, userp, &finalCount); + code = smb_ReadData(fidp, &offset, count, rawBuf, userp, &finalCount); #else /* DJGPP */ /* have to give ReadData flag so it will treat buffer as DOS mem. */ code = smb_ReadData(fidp, &offset, count, (unsigned char *)rawBuf, userp, &finalCount, TRUE /* rawFlag */); #endif /* !DJGPP */ - if (code != 0) - goto send; + if (code != 0) + goto send; send: cm_ReleaseUser(userp); send1a: - smb_ReleaseFID(fidp); + smb_ReleaseFID(fidp); send1: - ncbp = outp->ncbp; + ncbp = outp->ncbp; #ifdef DJGPP dos_ncb = ((smb_ncb_t *)ncbp)->dos_ncb; #endif /* DJGPP */ - memset((char *)ncbp, 0, sizeof(NCB)); + memset((char *)ncbp, 0, sizeof(NCB)); - ncbp->ncb_length = (unsigned short) finalCount; - ncbp->ncb_lsn = (unsigned char) vcp->lsn; - ncbp->ncb_lana_num = vcp->lana; - ncbp->ncb_command = NCBSEND; - ncbp->ncb_buffer = rawBuf; + ncbp->ncb_length = (unsigned short) finalCount; + ncbp->ncb_lsn = (unsigned char) vcp->lsn; + ncbp->ncb_lana_num = vcp->lana; + ncbp->ncb_command = NCBSEND; + ncbp->ncb_buffer = rawBuf; #ifndef DJGPP - code = Netbios(ncbp); + code = Netbios(ncbp); #else /* DJGPP */ - code = Netbios(ncbp, dos_ncb); + code = Netbios(ncbp, dos_ncb); #endif /* !DJGPP */ - if (code != 0) - osi_Log1(smb_logp, "ReadRaw send failure code %d", code); + if (code != 0) + osi_Log1(smb_logp, "ReadRaw send failure code %d", code); - if (rawBuf) { - /* Give back raw buffer */ - lock_ObtainMutex(&smb_RawBufLock); + if (rawBuf) { + /* Give back raw buffer */ + lock_ObtainMutex(&smb_RawBufLock); #ifndef DJGPP - *((char **) rawBuf) = smb_RawBufs; + *((char **) rawBuf) = smb_RawBufs; #else /* DJGPP */ _farpokel(_dos_ds, rawBuf, smb_RawBufs); #endif /* !DJGPP */ - smb_RawBufs = rawBuf; - lock_ReleaseMutex(&smb_RawBufLock); - } + smb_RawBufs = rawBuf; + lock_ReleaseMutex(&smb_RawBufLock); + } - return 0; + return 0; } long smb_ReceiveCoreLockRecord(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { - return 0; + osi_Log1(smb_logp, "SMB receive core lock record (not implemented); %d + 1 ongoing ops", + ongoingOps - 1); + return 0; } long smb_ReceiveCoreUnlockRecord(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { - return 0; + osi_Log1(smb_logp, "SMB receive core unlock record (not implemented); %d + 1 ongoing ops", + ongoingOps - 1); + return 0; } long smb_ReceiveNegotiate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { - char *namep; + char *namep; char *datap; - int coreProtoIndex; - int v3ProtoIndex; - int NTProtoIndex; - int protoIndex; /* index we're using */ - int namex; - int dbytes; - int entryLength; - int tcounter; - char protocol_array[10][1024]; /* protocol signature of the client */ + int coreProtoIndex; + int v3ProtoIndex; + int NTProtoIndex; + int protoIndex; /* index we're using */ + int namex; + int dbytes; + int entryLength; + int tcounter; + char protocol_array[10][1024]; /* protocol signature of the client */ int caps; /* capabilities */ time_t unixTime; - time_t dosTime; - TIME_ZONE_INFORMATION tzi; + time_t dosTime; + TIME_ZONE_INFORMATION tzi; osi_Log1(smb_logp, "SMB receive negotiate; %d + 1 ongoing ops", ongoingOps - 1); - if (!isGateway) { - if (active_vcp) { - DWORD now = GetCurrentTime(); - if (now - last_msg_time >= 30000 - && now - last_msg_time <= 90000) { - osi_Log1(smb_logp, - "Setting dead_vcp %x", active_vcp); + if (!isGateway) { + if (active_vcp) { + DWORD now = GetCurrentTime(); + if (now - last_msg_time >= 30000 + && now - last_msg_time <= 90000) { + osi_Log1(smb_logp, + "Setting dead_vcp %x", active_vcp); if (dead_vcp) { smb_ReleaseVC(dead_vcp); osi_Log1(smb_logp, - "Previous dead_vcp %x", dead_vcp); + "Previous dead_vcp %x", dead_vcp); } smb_HoldVC(active_vcp); - dead_vcp = active_vcp; - dead_vcp->flags |= SMB_VCFLAG_ALREADYDEAD; - } - } - } - - inp->flags |= SMB_PACKETFLAG_PROFILE_UPDATE_OK; - - namep = smb_GetSMBData(inp, &dbytes); - namex = 0; - tcounter = 0; - coreProtoIndex = -1; /* not found */ - v3ProtoIndex = -1; - NTProtoIndex = -1; - while(namex < dbytes) { - osi_Log1(smb_logp, "Protocol %s", - osi_LogSaveString(smb_logp, namep+1)); - strcpy(protocol_array[tcounter], namep+1); - - /* namep points at the first protocol, or really, a 0x02 - * byte preceding the null-terminated ASCII name. - */ - if (strcmp("PC NETWORK PROGRAM 1.0", namep+1) == 0) { - coreProtoIndex = tcounter; - } - else if (smb_useV3 && strcmp("LM1.2X002", namep+1) == 0) { - v3ProtoIndex = tcounter; - } - else if (smb_useV3 && strcmp("NT LM 0.12", namep+1) == 0) { - NTProtoIndex = tcounter; - } - - /* compute size of protocol entry */ - entryLength = strlen(namep+1); + dead_vcp = active_vcp; + dead_vcp->flags |= SMB_VCFLAG_ALREADYDEAD; + } + } + } + + inp->flags |= SMB_PACKETFLAG_PROFILE_UPDATE_OK; + + namep = smb_GetSMBData(inp, &dbytes); + namex = 0; + tcounter = 0; + coreProtoIndex = -1; /* not found */ + v3ProtoIndex = -1; + NTProtoIndex = -1; + while(namex < dbytes) { + osi_Log1(smb_logp, "Protocol %s", + osi_LogSaveString(smb_logp, namep+1)); + strcpy(protocol_array[tcounter], namep+1); + + /* namep points at the first protocol, or really, a 0x02 + * byte preceding the null-terminated ASCII name. + */ + if (strcmp("PC NETWORK PROGRAM 1.0", namep+1) == 0) { + coreProtoIndex = tcounter; + } + else if (smb_useV3 && strcmp("LM1.2X002", namep+1) == 0) { + v3ProtoIndex = tcounter; + } + else if (smb_useV3 && strcmp("NT LM 0.12", namep+1) == 0) { + NTProtoIndex = tcounter; + } + + /* compute size of protocol entry */ + entryLength = strlen(namep+1); entryLength += 2; /* 0x02 bytes and null termination */ - + /* advance over this protocol entry */ - namex += entryLength; + namex += entryLength; namep += entryLength; tcounter++; /* which proto entry we're looking at */ - } - - if (NTProtoIndex != -1) { - protoIndex = NTProtoIndex; - vcp->flags |= (SMB_VCFLAG_USENT | SMB_VCFLAG_USEV3); - } - else if (v3ProtoIndex != -1) { - protoIndex = v3ProtoIndex; - vcp->flags |= SMB_VCFLAG_USEV3; - } - else if (coreProtoIndex != -1) { - protoIndex = coreProtoIndex; - vcp->flags |= SMB_VCFLAG_USECORE; - } - else protoIndex = -1; - - if (protoIndex == -1) - return CM_ERROR_INVAL; - else if (NTProtoIndex != -1) { + } + + if (NTProtoIndex != -1) { + protoIndex = NTProtoIndex; + vcp->flags |= (SMB_VCFLAG_USENT | SMB_VCFLAG_USEV3); + } + else if (v3ProtoIndex != -1) { + protoIndex = v3ProtoIndex; + vcp->flags |= SMB_VCFLAG_USEV3; + } + else if (coreProtoIndex != -1) { + protoIndex = coreProtoIndex; + vcp->flags |= SMB_VCFLAG_USECORE; + } + else protoIndex = -1; + + if (protoIndex == -1) + return CM_ERROR_INVAL; + else if (NTProtoIndex != -1) { smb_SetSMBParm(outp, 0, protoIndex); - if (smb_authType != SMB_AUTH_NONE) { - smb_SetSMBParmByte(outp, 1, - NEGOTIATE_SECURITY_USER_LEVEL | - NEGOTIATE_SECURITY_CHALLENGE_RESPONSE); /* user level security, challenge response */ - } else { + if (smb_authType != SMB_AUTH_NONE) { + smb_SetSMBParmByte(outp, 1, + NEGOTIATE_SECURITY_USER_LEVEL | + NEGOTIATE_SECURITY_CHALLENGE_RESPONSE); /* user level security, challenge response */ + } else { smb_SetSMBParmByte(outp, 1, 0); /* share level auth with plaintext password. */ - } + } smb_SetSMBParm(outp, 1, smb_maxMpxRequests); /* max multiplexed requests */ smb_SetSMBParm(outp, 2, smb_maxVCPerServer); /* max VCs per consumer/server connection */ smb_SetSMBParmLong(outp, 3, SMB_PACKETSIZE); /* xmit buffer size */ - smb_SetSMBParmLong(outp, 5, SMB_MAXRAWSIZE); /* raw buffer size */ + smb_SetSMBParmLong(outp, 5, SMB_MAXRAWSIZE); /* raw buffer size */ /* The session key is not a well documented field however most clients * will echo back the session key to the server. Currently we are using * the same value for all sessions. We should generate a random value @@ -2715,129 +2719,129 @@ long smb_ReceiveNegotiate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) */ smb_SetSMBParm(outp, 7, 1); /* next 2: session key */ smb_SetSMBParm(outp, 8, 1); - /* - * Tried changing the capabilities to support for W2K - defect 117695 - * Maybe something else needs to be changed here? - */ - /* - if (isWindows2000) - smb_SetSMBParmLong(outp, 9, 0x43fd); - else - smb_SetSMBParmLong(outp, 9, 0x251); - */ - /* Capabilities: * - * 32-bit error codes * - * and NT Find * - * and NT SMB's * - * and raw mode */ + /* + * Tried changing the capabilities to support for W2K - defect 117695 + * Maybe something else needs to be changed here? + */ + /* + if (isWindows2000) + smb_SetSMBParmLong(outp, 9, 0x43fd); + else + smb_SetSMBParmLong(outp, 9, 0x251); + */ + /* Capabilities: * + * 32-bit error codes * + * and NT Find * + * and NT SMB's * + * and raw mode */ caps = NTNEGOTIATE_CAPABILITY_NTSTATUS | - NTNEGOTIATE_CAPABILITY_NTFIND | + NTNEGOTIATE_CAPABILITY_NTFIND | NTNEGOTIATE_CAPABILITY_RAWMODE | - NTNEGOTIATE_CAPABILITY_NTSMB; + NTNEGOTIATE_CAPABILITY_NTSMB; if ( smb_authType == SMB_AUTH_EXTENDED ) caps |= NTNEGOTIATE_CAPABILITY_EXTENDED_SECURITY; smb_SetSMBParmLong(outp, 9, caps); - time(&unixTime); - smb_SearchTimeFromUnixTime(&dosTime, unixTime); - smb_SetSMBParmLong(outp, 11, LOWORD(dosTime));/* server time */ - smb_SetSMBParmLong(outp, 13, HIWORD(dosTime));/* server date */ - - GetTimeZoneInformation(&tzi); - smb_SetSMBParm(outp, 15, (unsigned short) tzi.Bias); /* server tzone */ - - if (smb_authType == SMB_AUTH_NTLM) { - smb_SetSMBParmByte(outp, 16, MSV1_0_CHALLENGE_LENGTH);/* Encryption key length */ - smb_SetSMBDataLength(outp, MSV1_0_CHALLENGE_LENGTH + smb_ServerDomainNameLength); - /* paste in encryption key */ - datap = smb_GetSMBData(outp, NULL); - memcpy(datap,vcp->encKey,MSV1_0_CHALLENGE_LENGTH); - /* and the faux domain name */ - strcpy(datap + MSV1_0_CHALLENGE_LENGTH,smb_ServerDomainName); - } else if ( smb_authType == SMB_AUTH_EXTENDED ) { + time(&unixTime); + smb_SearchTimeFromUnixTime(&dosTime, unixTime); + smb_SetSMBParmLong(outp, 11, LOWORD(dosTime));/* server time */ + smb_SetSMBParmLong(outp, 13, HIWORD(dosTime));/* server date */ + + GetTimeZoneInformation(&tzi); + smb_SetSMBParm(outp, 15, (unsigned short) tzi.Bias); /* server tzone */ + + if (smb_authType == SMB_AUTH_NTLM) { + smb_SetSMBParmByte(outp, 16, MSV1_0_CHALLENGE_LENGTH);/* Encryption key length */ + smb_SetSMBDataLength(outp, MSV1_0_CHALLENGE_LENGTH + smb_ServerDomainNameLength); + /* paste in encryption key */ + datap = smb_GetSMBData(outp, NULL); + memcpy(datap,vcp->encKey,MSV1_0_CHALLENGE_LENGTH); + /* and the faux domain name */ + strcpy(datap + MSV1_0_CHALLENGE_LENGTH,smb_ServerDomainName); + } else if ( smb_authType == SMB_AUTH_EXTENDED ) { void * secBlob; - int secBlobLength; + int secBlobLength; - smb_SetSMBParmByte(outp, 16, 0); /* Encryption key length */ + smb_SetSMBParmByte(outp, 16, 0); /* Encryption key length */ - smb_NegotiateExtendedSecurity(&secBlob, &secBlobLength); + smb_NegotiateExtendedSecurity(&secBlob, &secBlobLength); - smb_SetSMBDataLength(outp, secBlobLength + sizeof(smb_ServerGUID)); + smb_SetSMBDataLength(outp, secBlobLength + sizeof(smb_ServerGUID)); - datap = smb_GetSMBData(outp, NULL); - memcpy(datap, &smb_ServerGUID, sizeof(smb_ServerGUID)); - - if (secBlob) { - datap += sizeof(smb_ServerGUID); - memcpy(datap, secBlob, secBlobLength); - free(secBlob); - } + datap = smb_GetSMBData(outp, NULL); + memcpy(datap, &smb_ServerGUID, sizeof(smb_ServerGUID)); + + if (secBlob) { + datap += sizeof(smb_ServerGUID); + memcpy(datap, secBlob, secBlobLength); + free(secBlob); + } } else { - smb_SetSMBParmByte(outp, 16, 0); /* Encryption key length */ - smb_SetSMBDataLength(outp, 0); /* Perhaps we should specify 8 bytes anyway */ - } - } - else if (v3ProtoIndex != -1) { - smb_SetSMBParm(outp, 0, protoIndex); + smb_SetSMBParmByte(outp, 16, 0); /* Encryption key length */ + smb_SetSMBDataLength(outp, 0); /* Perhaps we should specify 8 bytes anyway */ + } + } + else if (v3ProtoIndex != -1) { + smb_SetSMBParm(outp, 0, protoIndex); /* NOTE: Extended authentication cannot be negotiated with v3 * therefore we fail over to NTLM */ if (smb_authType == SMB_AUTH_NTLM || smb_authType == SMB_AUTH_EXTENDED) { - smb_SetSMBParm(outp, 1, - NEGOTIATE_SECURITY_USER_LEVEL | - NEGOTIATE_SECURITY_CHALLENGE_RESPONSE); /* user level security, challenge response */ - } else { - smb_SetSMBParm(outp, 1, 0); /* share level auth with clear password */ - } - smb_SetSMBParm(outp, 2, SMB_PACKETSIZE); - smb_SetSMBParm(outp, 3, smb_maxMpxRequests); /* max multiplexed requests */ - smb_SetSMBParm(outp, 4, smb_maxVCPerServer); /* max VCs per consumer/server connection */ - smb_SetSMBParm(outp, 5, 0); /* no support of block mode for read or write */ - smb_SetSMBParm(outp, 6, 1); /* next 2: session key */ - smb_SetSMBParm(outp, 7, 1); - time(&unixTime); - smb_SearchTimeFromUnixTime(&dosTime, unixTime); - smb_SetSMBParm(outp, 8, LOWORD(dosTime)); /* server time */ - smb_SetSMBParm(outp, 9, HIWORD(dosTime)); /* server date */ - - GetTimeZoneInformation(&tzi); - smb_SetSMBParm(outp, 10, (unsigned short) tzi.Bias); /* server tzone */ + smb_SetSMBParm(outp, 1, + NEGOTIATE_SECURITY_USER_LEVEL | + NEGOTIATE_SECURITY_CHALLENGE_RESPONSE); /* user level security, challenge response */ + } else { + smb_SetSMBParm(outp, 1, 0); /* share level auth with clear password */ + } + smb_SetSMBParm(outp, 2, SMB_PACKETSIZE); + smb_SetSMBParm(outp, 3, smb_maxMpxRequests); /* max multiplexed requests */ + smb_SetSMBParm(outp, 4, smb_maxVCPerServer); /* max VCs per consumer/server connection */ + smb_SetSMBParm(outp, 5, 0); /* no support of block mode for read or write */ + smb_SetSMBParm(outp, 6, 1); /* next 2: session key */ + smb_SetSMBParm(outp, 7, 1); + time(&unixTime); + smb_SearchTimeFromUnixTime(&dosTime, unixTime); + smb_SetSMBParm(outp, 8, LOWORD(dosTime)); /* server time */ + smb_SetSMBParm(outp, 9, HIWORD(dosTime)); /* server date */ + + GetTimeZoneInformation(&tzi); + smb_SetSMBParm(outp, 10, (unsigned short) tzi.Bias); /* server tzone */ /* NOTE: Extended authentication cannot be negotiated with v3 * therefore we fail over to NTLM */ - if (smb_authType == SMB_AUTH_NTLM || smb_authType == SMB_AUTH_EXTENDED) { - smb_SetSMBParm(outp, 11, MSV1_0_CHALLENGE_LENGTH); /* encryption key length */ + if (smb_authType == SMB_AUTH_NTLM || smb_authType == SMB_AUTH_EXTENDED) { + smb_SetSMBParm(outp, 11, MSV1_0_CHALLENGE_LENGTH); /* encryption key length */ smb_SetSMBParm(outp, 12, 0); /* resvd */ - smb_SetSMBDataLength(outp, MSV1_0_CHALLENGE_LENGTH + smb_ServerDomainNameLength); /* perhaps should specify 8 bytes anyway */ - datap = smb_GetSMBData(outp, NULL); - /* paste in a new encryption key */ - memcpy(datap, vcp->encKey, MSV1_0_CHALLENGE_LENGTH); - /* and the faux domain name */ - strcpy(datap + MSV1_0_CHALLENGE_LENGTH, smb_ServerDomainName); - } else { - smb_SetSMBParm(outp, 11, 0); /* encryption key length */ - smb_SetSMBParm(outp, 12, 0); /* resvd */ - smb_SetSMBDataLength(outp, 0); - } - } - else if (coreProtoIndex != -1) { /* not really supported anymore */ - smb_SetSMBParm(outp, 0, protoIndex); - smb_SetSMBDataLength(outp, 0); - } - return 0; + smb_SetSMBDataLength(outp, MSV1_0_CHALLENGE_LENGTH + smb_ServerDomainNameLength); /* perhaps should specify 8 bytes anyway */ + datap = smb_GetSMBData(outp, NULL); + /* paste in a new encryption key */ + memcpy(datap, vcp->encKey, MSV1_0_CHALLENGE_LENGTH); + /* and the faux domain name */ + strcpy(datap + MSV1_0_CHALLENGE_LENGTH, smb_ServerDomainName); + } else { + smb_SetSMBParm(outp, 11, 0); /* encryption key length */ + smb_SetSMBParm(outp, 12, 0); /* resvd */ + smb_SetSMBDataLength(outp, 0); + } + } + else if (coreProtoIndex != -1) { /* not really supported anymore */ + smb_SetSMBParm(outp, 0, protoIndex); + smb_SetSMBDataLength(outp, 0); + } + return 0; } void smb_Daemon(void *parmp) { - afs_uint32 count = 0; + afs_uint32 count = 0; - while(1) { - count++; - thrd_Sleep(10000); - if ((count % 72) == 0) { /* every five minutes */ + while(1) { + count++; + thrd_Sleep(10000); + if ((count % 72) == 0) { /* every five minutes */ struct tm myTime; long old_localZero = smb_localZero; @@ -2858,159 +2862,159 @@ void smb_Daemon(void *parmp) cm_noteLocalMountPointChange(); #endif } - /* XXX GC dir search entries */ - } + /* XXX GC dir search entries */ + } } void smb_WaitingLocksDaemon() { - smb_waitingLock_t *wL, *nwL; - int first; - smb_vc_t *vcp; - smb_packet_t *inp, *outp; - NCB *ncbp; - long code = 0; - - while(1) { - lock_ObtainWrite(&smb_globalLock); - nwL = smb_allWaitingLocks; - if (nwL == NULL) { - osi_SleepW((long)&smb_allWaitingLocks, &smb_globalLock); - thrd_Sleep(1000); - continue; - } - else first = 1; - do { - if (first) - first = 0; - else - lock_ObtainWrite(&smb_globalLock); - wL = nwL; - nwL = (smb_waitingLock_t *) osi_QNext(&wL->q); - lock_ReleaseWrite(&smb_globalLock); - code = cm_RetryLock((cm_file_lock_t *) wL->lockp, - wL->vcp->flags & SMB_VCFLAG_ALREADYDEAD); - if (code == CM_ERROR_WOULDBLOCK) { - /* no progress */ - if (wL->timeRemaining != 0xffffffff - && (wL->timeRemaining -= 1000) < 0) - goto endWait; - continue; - } - endWait: - vcp = wL->vcp; - inp = wL->inp; - outp = wL->outp; - ncbp = GetNCB(); - ncbp->ncb_length = inp->ncb_length; - inp->spacep = cm_GetSpace(); - - /* Remove waitingLock from list */ - lock_ObtainWrite(&smb_globalLock); - osi_QRemove((osi_queue_t **)&smb_allWaitingLocks, - &wL->q); - lock_ReleaseWrite(&smb_globalLock); - - /* Resume packet processing */ - if (code == 0) - smb_SetSMBDataLength(outp, 0); - outp->flags |= SMB_PACKETFLAG_SUSPENDED; - outp->resumeCode = code; - outp->ncbp = ncbp; - smb_DispatchPacket(vcp, inp, outp, ncbp, NULL); - - /* Clean up */ - cm_FreeSpace(inp->spacep); - smb_FreePacket(inp); - smb_FreePacket(outp); - FreeNCB(ncbp); - free(wL); - } while (nwL); - thrd_Sleep(1000); - } + smb_waitingLock_t *wL, *nwL; + int first; + smb_vc_t *vcp; + smb_packet_t *inp, *outp; + NCB *ncbp; + long code = 0; + + while (1) { + lock_ObtainWrite(&smb_globalLock); + nwL = smb_allWaitingLocks; + if (nwL == NULL) { + osi_SleepW((long)&smb_allWaitingLocks, &smb_globalLock); + thrd_Sleep(1000); + continue; + } + else first = 1; + do { + if (first) + first = 0; + else + lock_ObtainWrite(&smb_globalLock); + wL = nwL; + nwL = (smb_waitingLock_t *) osi_QNext(&wL->q); + lock_ReleaseWrite(&smb_globalLock); + code = cm_RetryLock((cm_file_lock_t *) wL->lockp, + wL->vcp->flags & SMB_VCFLAG_ALREADYDEAD); + if (code == CM_ERROR_WOULDBLOCK) { + /* no progress */ + if (wL->timeRemaining != 0xffffffff + && (wL->timeRemaining -= 1000) < 0) + goto endWait; + continue; + } + endWait: + vcp = wL->vcp; + inp = wL->inp; + outp = wL->outp; + ncbp = GetNCB(); + ncbp->ncb_length = inp->ncb_length; + inp->spacep = cm_GetSpace(); + + /* Remove waitingLock from list */ + lock_ObtainWrite(&smb_globalLock); + osi_QRemove((osi_queue_t **)&smb_allWaitingLocks, + &wL->q); + lock_ReleaseWrite(&smb_globalLock); + + /* Resume packet processing */ + if (code == 0) + smb_SetSMBDataLength(outp, 0); + outp->flags |= SMB_PACKETFLAG_SUSPENDED; + outp->resumeCode = code; + outp->ncbp = ncbp; + smb_DispatchPacket(vcp, inp, outp, ncbp, NULL); + + /* Clean up */ + cm_FreeSpace(inp->spacep); + smb_FreePacket(inp); + smb_FreePacket(outp); + FreeNCB(ncbp); + free(wL); + } while (nwL); + thrd_Sleep(1000); + } } long smb_ReceiveCoreGetDiskAttributes(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { - osi_Log0(smb_logp, "SMB receive get disk attributes"); - - smb_SetSMBParm(outp, 0, 32000); - smb_SetSMBParm(outp, 1, 64); - smb_SetSMBParm(outp, 2, 1024); - smb_SetSMBParm(outp, 3, 30000); - smb_SetSMBParm(outp, 4, 0); - smb_SetSMBDataLength(outp, 0); - return 0; + osi_Log0(smb_logp, "SMB receive get disk attributes"); + + smb_SetSMBParm(outp, 0, 32000); + smb_SetSMBParm(outp, 1, 64); + smb_SetSMBParm(outp, 2, 1024); + smb_SetSMBParm(outp, 3, 30000); + smb_SetSMBParm(outp, 4, 0); + smb_SetSMBDataLength(outp, 0); + return 0; } long smb_ReceiveCoreTreeConnect(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *rsp) { - smb_tid_t *tidp; + smb_tid_t *tidp; smb_user_t *uidp; - unsigned short newTid; - char shareName[256]; - char *sharePath; - int shareFound; - char *tp; - char *pathp; - char *passwordp; - cm_user_t *userp; - - osi_Log0(smb_logp, "SMB receive tree connect"); - - /* parse input parameters */ - tp = smb_GetSMBData(inp, NULL); - pathp = smb_ParseASCIIBlock(tp, &tp); - passwordp = smb_ParseASCIIBlock(tp, &tp); - tp = strrchr(pathp, '\\'); - if (!tp) - return CM_ERROR_BADSMB; - strcpy(shareName, tp+1); - - userp = smb_GetUser(vcp, inp); - - lock_ObtainMutex(&vcp->mx); - newTid = vcp->tidCounter++; - lock_ReleaseMutex(&vcp->mx); - - tidp = smb_FindTID(vcp, newTid, SMB_FLAG_CREATE); + unsigned short newTid; + char shareName[256]; + char *sharePath; + int shareFound; + char *tp; + char *pathp; + char *passwordp; + cm_user_t *userp; + + osi_Log0(smb_logp, "SMB receive tree connect"); + + /* parse input parameters */ + tp = smb_GetSMBData(inp, NULL); + pathp = smb_ParseASCIIBlock(tp, &tp); + passwordp = smb_ParseASCIIBlock(tp, &tp); + tp = strrchr(pathp, '\\'); + if (!tp) + return CM_ERROR_BADSMB; + strcpy(shareName, tp+1); + + userp = smb_GetUser(vcp, inp); + + lock_ObtainMutex(&vcp->mx); + newTid = vcp->tidCounter++; + lock_ReleaseMutex(&vcp->mx); + + tidp = smb_FindTID(vcp, newTid, SMB_FLAG_CREATE); uidp = smb_FindUID(vcp, ((smb_t *)inp)->uid, 0); - shareFound = smb_FindShare(vcp, uidp, shareName, &sharePath); + shareFound = smb_FindShare(vcp, uidp, shareName, &sharePath); if (uidp) smb_ReleaseUID(uidp); - if (!shareFound) { - smb_ReleaseTID(tidp); - return CM_ERROR_BADSHARENAME; - } - lock_ObtainMutex(&tidp->mx); - tidp->userp = userp; - tidp->pathname = sharePath; - lock_ReleaseMutex(&tidp->mx); - smb_ReleaseTID(tidp); + if (!shareFound) { + smb_ReleaseTID(tidp); + return CM_ERROR_BADSHARENAME; + } + lock_ObtainMutex(&tidp->mx); + tidp->userp = userp; + tidp->pathname = sharePath; + lock_ReleaseMutex(&tidp->mx); + smb_ReleaseTID(tidp); - smb_SetSMBParm(rsp, 0, SMB_PACKETSIZE); - smb_SetSMBParm(rsp, 1, newTid); - smb_SetSMBDataLength(rsp, 0); + smb_SetSMBParm(rsp, 0, SMB_PACKETSIZE); + smb_SetSMBParm(rsp, 1, newTid); + smb_SetSMBDataLength(rsp, 0); - osi_Log1(smb_logp, "SMB tree connect created ID %d", newTid); - return 0; + osi_Log1(smb_logp, "SMB tree connect created ID %d", newTid); + return 0; } unsigned char *smb_ParseDataBlock(unsigned char *inp, char **chainpp, int *lengthp) { - int tlen; + int tlen; - if (*inp++ != 0x1) return NULL; - tlen = inp[0] + (inp[1]<<8); - inp += 2; /* skip length field */ + if (*inp++ != 0x1) return NULL; + tlen = inp[0] + (inp[1]<<8); + inp += 2; /* skip length field */ - if (chainpp) { - *chainpp = inp + tlen; - } - - if (lengthp) *lengthp = tlen; + if (chainpp) { + *chainpp = inp + tlen; + } + + if (lengthp) *lengthp = tlen; - return inp; + return inp; } /* set maskp to the mask part of the incoming path. @@ -3020,30 +3024,30 @@ unsigned char *smb_ParseDataBlock(unsigned char *inp, char **chainpp, int *lengt */ int smb_Get8Dot3MaskFromPath(unsigned char *maskp, unsigned char *pathp) { - char *tp; - char *up; - int i; - int tc; - int valid8Dot3; - - /* starts off valid */ - valid8Dot3 = 1; - - /* mask starts out all blanks */ - memset(maskp, ' ', 11); - - /* find last backslash, or use whole thing if there is none */ - tp = strrchr(pathp, '\\'); - if (!tp) tp = pathp; - else tp++; /* skip slash */ + char *tp; + char *up; + int i; + int tc; + int valid8Dot3; + + /* starts off valid */ + valid8Dot3 = 1; + + /* mask starts out all blanks */ + memset(maskp, ' ', 11); + + /* find last backslash, or use whole thing if there is none */ + tp = strrchr(pathp, '\\'); + if (!tp) tp = pathp; + else tp++; /* skip slash */ - up = maskp; + up = maskp; - /* names starting with a dot are illegal */ - if (*tp == '.') valid8Dot3 = 0; + /* names starting with a dot are illegal */ + if (*tp == '.') valid8Dot3 = 0; for(i=0;; i++) { - tc = *tp++; + tc = *tp++; if (tc == 0) return valid8Dot3; if (tc == '.' || tc == '"') break; if (i < 8) *up++ = tc; @@ -3055,17 +3059,17 @@ int smb_Get8Dot3MaskFromPath(unsigned char *maskp, unsigned char *pathp) for(i=0;;i++) { tc = *tp++; if (tc == 0) - return valid8Dot3; + return valid8Dot3; /* too many dots */ if (tc == '.' || tc == '"') - valid8Dot3 = 0; + valid8Dot3 = 0; /* copy extension if not too long */ if (i < 3) - *up++ = tc; + *up++ = tc; else - valid8Dot3 = 0; + valid8Dot3 = 0; } /* unreachable */ @@ -3073,137 +3077,137 @@ int smb_Get8Dot3MaskFromPath(unsigned char *maskp, unsigned char *pathp) int smb_Match8Dot3Mask(char *unixNamep, char *maskp) { - char umask[11]; - int valid; - int i; - char tc1; - char tc2; - char *tp1; - char *tp2; - - /* XXX redo this, calling smb_V3MatchMask with a converted mask */ - - valid = smb_Get8Dot3MaskFromPath(umask, unixNamep); - if (!valid) - return 0; + char umask[11]; + int valid; + int i; + char tc1; + char tc2; + char *tp1; + char *tp2; + + /* XXX redo this, calling smb_V3MatchMask with a converted mask */ + + valid = smb_Get8Dot3MaskFromPath(umask, unixNamep); + if (!valid) + return 0; - /* otherwise, we have a valid 8.3 name; see if we have a match, - * treating '?' as a wildcard in maskp (but not in the file name). - */ - tp1 = umask; /* real name, in mask format */ - tp2 = maskp; /* mask, in mask format */ - for(i=0; i<11; i++) { - tc1 = *tp1++; /* char from real name */ - tc2 = *tp2++; /* char from mask */ - tc1 = (char) cm_foldUpper[(unsigned char)tc1]; - tc2 = (char) cm_foldUpper[(unsigned char)tc2]; - if (tc1 == tc2) - continue; - if (tc2 == '?' && tc1 != ' ') - continue; - if (tc2 == '>') - continue; - return 0; - } - - /* we got a match */ - return 1; + /* otherwise, we have a valid 8.3 name; see if we have a match, + * treating '?' as a wildcard in maskp (but not in the file name). + */ + tp1 = umask; /* real name, in mask format */ + tp2 = maskp; /* mask, in mask format */ + for(i=0; i<11; i++) { + tc1 = *tp1++; /* char from real name */ + tc2 = *tp2++; /* char from mask */ + tc1 = (char) cm_foldUpper[(unsigned char)tc1]; + tc2 = (char) cm_foldUpper[(unsigned char)tc2]; + if (tc1 == tc2) + continue; + if (tc2 == '?' && tc1 != ' ') + continue; + if (tc2 == '>') + continue; + return 0; + } + + /* we got a match */ + return 1; } char *smb_FindMask(char *pathp) { - char *tp; + char *tp; - tp = strrchr(pathp, '\\'); /* find last slash */ + tp = strrchr(pathp, '\\'); /* find last slash */ - if (tp) - return tp+1; /* skip the slash */ - else - return pathp; /* no slash, return the entire path */ -} + if (tp) + return tp+1; /* skip the slash */ + else + return pathp; /* no slash, return the entire path */ +} long smb_ReceiveCoreSearchVolume(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { - unsigned char *pathp; - unsigned char *tp; - unsigned char mask[11]; - unsigned char *statBlockp; - unsigned char initStatBlock[21]; - int statLen; - - osi_Log0(smb_logp, "SMB receive search volume"); - - /* pull pathname and stat block out of request */ - tp = smb_GetSMBData(inp, NULL); - pathp = smb_ParseASCIIBlock(tp, (char **) &tp); - osi_assert(pathp != NULL); - statBlockp = smb_ParseVblBlock(tp, (char **) &tp, &statLen); - osi_assert(statBlockp != NULL); - if (statLen == 0) { - statBlockp = initStatBlock; - statBlockp[0] = 8; - } + unsigned char *pathp; + unsigned char *tp; + unsigned char mask[11]; + unsigned char *statBlockp; + unsigned char initStatBlock[21]; + int statLen; - /* for returning to caller */ - smb_Get8Dot3MaskFromPath(mask, pathp); + osi_Log0(smb_logp, "SMB receive search volume"); + + /* pull pathname and stat block out of request */ + tp = smb_GetSMBData(inp, NULL); + pathp = smb_ParseASCIIBlock(tp, (char **) &tp); + osi_assert(pathp != NULL); + statBlockp = smb_ParseVblBlock(tp, (char **) &tp, &statLen); + osi_assert(statBlockp != NULL); + if (statLen == 0) { + statBlockp = initStatBlock; + statBlockp[0] = 8; + } - smb_SetSMBParm(outp, 0, 1); /* we're returning one entry */ - tp = smb_GetSMBData(outp, NULL); - *tp++ = 5; - *tp++ = 43; /* bytes in a dir entry */ - *tp++ = 0; /* high byte in counter */ - - /* now marshall the dir entry, starting with the search status */ - *tp++ = statBlockp[0]; /* Reserved */ - memcpy(tp, mask, 11); tp += 11; /* FileName */ - - /* now pass back server use info, with 1st byte non-zero */ - *tp++ = 1; - memset(tp, 0, 4); tp += 4; /* reserved for server use */ - - memcpy(tp, statBlockp+17, 4); tp += 4; /* reserved for consumer */ - - *tp++ = 0x8; /* attribute: volume */ - - /* copy out time */ - *tp++ = 0; - *tp++ = 0; - - /* copy out date */ - *tp++ = 18; - *tp++ = 178; - - /* 4 byte file size */ - *tp++ = 0; - *tp++ = 0; - *tp++ = 0; - *tp++ = 0; - - /* finally, null-terminated 8.3 pathname, which we set to AFS */ - memset(tp, ' ', 13); - strcpy(tp, "AFS"); - - /* set the length of the data part of the packet to 43 + 3, for the dir - * entry plus the 5 and the length fields. - */ - smb_SetSMBDataLength(outp, 46); - return 0; -} + /* for returning to caller */ + smb_Get8Dot3MaskFromPath(mask, pathp); + + smb_SetSMBParm(outp, 0, 1); /* we're returning one entry */ + tp = smb_GetSMBData(outp, NULL); + *tp++ = 5; + *tp++ = 43; /* bytes in a dir entry */ + *tp++ = 0; /* high byte in counter */ + + /* now marshall the dir entry, starting with the search status */ + *tp++ = statBlockp[0]; /* Reserved */ + memcpy(tp, mask, 11); tp += 11; /* FileName */ + + /* now pass back server use info, with 1st byte non-zero */ + *tp++ = 1; + memset(tp, 0, 4); tp += 4; /* reserved for server use */ + + memcpy(tp, statBlockp+17, 4); tp += 4; /* reserved for consumer */ + + *tp++ = 0x8; /* attribute: volume */ + + /* copy out time */ + *tp++ = 0; + *tp++ = 0; + + /* copy out date */ + *tp++ = 18; + *tp++ = 178; + + /* 4 byte file size */ + *tp++ = 0; + *tp++ = 0; + *tp++ = 0; + *tp++ = 0; + + /* finally, null-terminated 8.3 pathname, which we set to AFS */ + memset(tp, ' ', 13); + strcpy(tp, "AFS"); + + /* set the length of the data part of the packet to 43 + 3, for the dir + * entry plus the 5 and the length fields. + */ + smb_SetSMBDataLength(outp, 46); + return 0; +} long smb_ApplyDirListPatches(smb_dirListPatch_t **dirPatchespp, - cm_user_t *userp, cm_req_t *reqp) + cm_user_t *userp, cm_req_t *reqp) { - long code = 0; - cm_scache_t *scp; - char *dptr; - time_t dosTime; - u_short shortTemp; - char attr; - smb_dirListPatch_t *patchp; - smb_dirListPatch_t *npatchp; - - for(patchp = *dirPatchespp; patchp; patchp = - (smb_dirListPatch_t *) osi_QNext(&patchp->q)) { + long code = 0; + cm_scache_t *scp; + char *dptr; + time_t dosTime; + u_short shortTemp; + char attr; + smb_dirListPatch_t *patchp; + smb_dirListPatch_t *npatchp; + + for (patchp = *dirPatchespp; patchp; patchp = + (smb_dirListPatch_t *) osi_QNext(&patchp->q)) { dptr = patchp->dptr; @@ -3213,542 +3217,542 @@ long smb_ApplyDirListPatches(smb_dirListPatch_t **dirPatchespp, *dptr++ = SMB_ATTR_HIDDEN; continue; } - lock_ObtainMutex(&scp->mx); - code = cm_SyncOp(scp, NULL, userp, reqp, 0, - CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); - if (code) { - lock_ReleaseMutex(&scp->mx); - cm_ReleaseSCache(scp); - if( patchp->flags & SMB_DIRLISTPATCH_DOTFILE ) + lock_ObtainMutex(&scp->mx); + code = cm_SyncOp(scp, NULL, userp, reqp, 0, + CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); + if (code) { + lock_ReleaseMutex(&scp->mx); + cm_ReleaseSCache(scp); + if (patchp->flags & SMB_DIRLISTPATCH_DOTFILE) *dptr++ = SMB_ATTR_HIDDEN; - continue; - } + continue; + } - attr = smb_Attributes(scp); + attr = smb_Attributes(scp); /* check hidden attribute (the flag is only ON when dot file hiding is on ) */ - if( patchp->flags & SMB_DIRLISTPATCH_DOTFILE ) + if (patchp->flags & SMB_DIRLISTPATCH_DOTFILE) attr |= SMB_ATTR_HIDDEN; *dptr++ = attr; /* get dos time */ - smb_SearchTimeFromUnixTime(&dosTime, scp->clientModTime); + smb_SearchTimeFromUnixTime(&dosTime, scp->clientModTime); - /* copy out time */ - shortTemp = dosTime & 0xffff; - *((u_short *)dptr) = shortTemp; - dptr += 2; - - /* and copy out date */ - shortTemp = (dosTime>>16) & 0xffff; - *((u_short *)dptr) = shortTemp; - dptr += 2; + /* copy out time */ + shortTemp = dosTime & 0xffff; + *((u_short *)dptr) = shortTemp; + dptr += 2; + + /* and copy out date */ + shortTemp = (dosTime>>16) & 0xffff; + *((u_short *)dptr) = shortTemp; + dptr += 2; - /* copy out file length */ - *((u_long *)dptr) = scp->length.LowPart; - dptr += 4; - lock_ReleaseMutex(&scp->mx); - cm_ReleaseSCache(scp); - } + /* copy out file length */ + *((u_long *)dptr) = scp->length.LowPart; + dptr += 4; + lock_ReleaseMutex(&scp->mx); + cm_ReleaseSCache(scp); + } - /* now free the patches */ - for(patchp = *dirPatchespp; patchp; patchp = npatchp) { - npatchp = (smb_dirListPatch_t *) osi_QNext(&patchp->q); - free(patchp); - } + /* now free the patches */ + for (patchp = *dirPatchespp; patchp; patchp = npatchp) { + npatchp = (smb_dirListPatch_t *) osi_QNext(&patchp->q); + free(patchp); + } - /* and mark the list as empty */ - *dirPatchespp = NULL; + /* and mark the list as empty */ + *dirPatchespp = NULL; - return code; + return code; } long smb_ReceiveCoreSearchDir(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { - int attribute; - long nextCookie; - char *tp; - long code = 0; - char *pathp; - cm_dirEntry_t *dep; - int maxCount; - smb_dirListPatch_t *dirListPatchesp; - smb_dirListPatch_t *curPatchp; - int dataLength; - cm_buf_t *bufferp; - long temp; - osi_hyper_t dirLength; - osi_hyper_t bufferOffset; - osi_hyper_t curOffset; - osi_hyper_t thyper; - unsigned char *inCookiep; - smb_dirSearch_t *dsp; - cm_scache_t *scp; - long entryInDir; - long entryInBuffer; - unsigned long clientCookie; - cm_pageHeader_t *pageHeaderp; - cm_user_t *userp = NULL; - int slotInPage; - char shortName[13]; - char *actualName; - char *shortNameEnd; - char mask[11]; - int returnedNames; - long nextEntryCookie; - int numDirChunks; /* # of 32 byte dir chunks in this entry */ - char resByte; /* reserved byte from the cookie */ - char *op; /* output data ptr */ - char *origOp; /* original value of op */ - cm_space_t *spacep; /* for pathname buffer */ - int starPattern; - int rootPath = 0; - int caseFold; - char *tidPathp; - cm_req_t req; - cm_fid_t fid; - int fileType; - - cm_InitReq(&req); - - maxCount = smb_GetSMBParm(inp, 0); - - dirListPatchesp = NULL; + int attribute; + long nextCookie; + char *tp; + long code = 0; + char *pathp; + cm_dirEntry_t *dep; + int maxCount; + smb_dirListPatch_t *dirListPatchesp; + smb_dirListPatch_t *curPatchp; + int dataLength; + cm_buf_t *bufferp; + long temp; + osi_hyper_t dirLength; + osi_hyper_t bufferOffset; + osi_hyper_t curOffset; + osi_hyper_t thyper; + unsigned char *inCookiep; + smb_dirSearch_t *dsp; + cm_scache_t *scp; + long entryInDir; + long entryInBuffer; + unsigned long clientCookie; + cm_pageHeader_t *pageHeaderp; + cm_user_t *userp = NULL; + int slotInPage; + char shortName[13]; + char *actualName; + char *shortNameEnd; + char mask[11]; + int returnedNames; + long nextEntryCookie; + int numDirChunks; /* # of 32 byte dir chunks in this entry */ + char resByte; /* reserved byte from the cookie */ + char *op; /* output data ptr */ + char *origOp; /* original value of op */ + cm_space_t *spacep; /* for pathname buffer */ + int starPattern; + int rootPath = 0; + int caseFold; + char *tidPathp; + cm_req_t req; + cm_fid_t fid; + int fileType; + + cm_InitReq(&req); + + maxCount = smb_GetSMBParm(inp, 0); + + dirListPatchesp = NULL; - caseFold = CM_FLAG_CASEFOLD; - - tp = smb_GetSMBData(inp, NULL); - pathp = smb_ParseASCIIBlock(tp, &tp); - inCookiep = smb_ParseVblBlock(tp, &tp, &dataLength); - - /* bail out if request looks bad */ - if (!tp || !pathp) { - return CM_ERROR_BADSMB; - } - - /* We can handle long names */ - if (vcp->flags & SMB_VCFLAG_USENT) - ((smb_t *)outp)->flg2 |= 0x40; /* IS_LONG_NAME */ - - /* make sure we got a whole search status */ - if (dataLength < 21) { - nextCookie = 0; /* start at the beginning of the dir */ - resByte = 0; - clientCookie = 0; - attribute = smb_GetSMBParm(inp, 1); - - /* handle volume info in another function */ - if (attribute & 0x8) - return smb_ReceiveCoreSearchVolume(vcp, inp, outp); - - osi_Log2(smb_logp, "SMB receive search dir count %d [%s]", - maxCount, osi_LogSaveString(smb_logp, pathp)); - - if (*pathp == 0) { /* null pathp, treat as root dir */ - if (!(attribute & SMB_ATTR_DIRECTORY)) /* exclude dirs */ - return CM_ERROR_NOFILES; - rootPath = 1; - } - - dsp = smb_NewDirSearch(0); - dsp->attribute = attribute; - smb_Get8Dot3MaskFromPath(mask, pathp); - memcpy(dsp->mask, mask, 11); - - /* track if this is likely to match a lot of entries */ - if (smb_IsStarMask(mask)) starPattern = 1; - else starPattern = 0; - } - else { - /* pull the next cookie value out of the search status block */ - nextCookie = inCookiep[13] + (inCookiep[14]<<8) + (inCookiep[15]<<16) - + (inCookiep[16]<<24); - dsp = smb_FindDirSearch(inCookiep[12]); - if (!dsp) { - /* can't find dir search status; fatal error */ - return CM_ERROR_BADFD; - } - attribute = dsp->attribute; - resByte = inCookiep[0]; - - /* copy out client cookie, in host byte order. Don't bother - * interpreting it, since we're just passing it through, anyway. - */ - memcpy(&clientCookie, &inCookiep[17], 4); - - memcpy(mask, dsp->mask, 11); - - /* assume we're doing a star match if it has continued for more - * than one call. - */ - starPattern = 1; - } - - osi_Log3(smb_logp, "SMB dir search cookie 0x%x, connection %d, attr 0x%x", - nextCookie, dsp->cookie, attribute); - - userp = smb_GetUser(vcp, inp); - - /* try to get the vnode for the path name next */ - lock_ObtainMutex(&dsp->mx); - if (dsp->scp) { - scp = dsp->scp; - cm_HoldSCache(scp); - code = 0; - } - else { - spacep = inp->spacep; - smb_StripLastComponent(spacep->data, NULL, pathp); - lock_ReleaseMutex(&dsp->mx); - code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &tidPathp); - if(code) { + caseFold = CM_FLAG_CASEFOLD; + + tp = smb_GetSMBData(inp, NULL); + pathp = smb_ParseASCIIBlock(tp, &tp); + inCookiep = smb_ParseVblBlock(tp, &tp, &dataLength); + + /* bail out if request looks bad */ + if (!tp || !pathp) { + return CM_ERROR_BADSMB; + } + + /* We can handle long names */ + if (vcp->flags & SMB_VCFLAG_USENT) + ((smb_t *)outp)->flg2 |= 0x40; /* IS_LONG_NAME */ + + /* make sure we got a whole search status */ + if (dataLength < 21) { + nextCookie = 0; /* start at the beginning of the dir */ + resByte = 0; + clientCookie = 0; + attribute = smb_GetSMBParm(inp, 1); + + /* handle volume info in another function */ + if (attribute & 0x8) + return smb_ReceiveCoreSearchVolume(vcp, inp, outp); + + osi_Log2(smb_logp, "SMB receive search dir count %d [%s]", + maxCount, osi_LogSaveString(smb_logp, pathp)); + + if (*pathp == 0) { /* null pathp, treat as root dir */ + if (!(attribute & SMB_ATTR_DIRECTORY)) /* exclude dirs */ + return CM_ERROR_NOFILES; + rootPath = 1; + } + + dsp = smb_NewDirSearch(0); + dsp->attribute = attribute; + smb_Get8Dot3MaskFromPath(mask, pathp); + memcpy(dsp->mask, mask, 11); + + /* track if this is likely to match a lot of entries */ + if (smb_IsStarMask(mask)) starPattern = 1; + else starPattern = 0; + } + else { + /* pull the next cookie value out of the search status block */ + nextCookie = inCookiep[13] + (inCookiep[14]<<8) + (inCookiep[15]<<16) + + (inCookiep[16]<<24); + dsp = smb_FindDirSearch(inCookiep[12]); + if (!dsp) { + /* can't find dir search status; fatal error */ + return CM_ERROR_BADFD; + } + attribute = dsp->attribute; + resByte = inCookiep[0]; + + /* copy out client cookie, in host byte order. Don't bother + * interpreting it, since we're just passing it through, anyway. + */ + memcpy(&clientCookie, &inCookiep[17], 4); + + memcpy(mask, dsp->mask, 11); + + /* assume we're doing a star match if it has continued for more + * than one call. + */ + starPattern = 1; + } + + osi_Log3(smb_logp, "SMB dir search cookie 0x%x, connection %d, attr 0x%x", + nextCookie, dsp->cookie, attribute); + + userp = smb_GetUser(vcp, inp); + + /* try to get the vnode for the path name next */ + lock_ObtainMutex(&dsp->mx); + if (dsp->scp) { + scp = dsp->scp; + cm_HoldSCache(scp); + code = 0; + } + else { + spacep = inp->spacep; + smb_StripLastComponent(spacep->data, NULL, pathp); + lock_ReleaseMutex(&dsp->mx); + code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &tidPathp); + if (code) { lock_ReleaseMutex(&dsp->mx); cm_ReleaseUser(userp); smb_DeleteDirSearch(dsp); smb_ReleaseDirSearch(dsp); return CM_ERROR_NOFILES; } - code = cm_NameI(cm_rootSCachep, spacep->data, - caseFold | CM_FLAG_FOLLOW, userp, tidPathp, &req, &scp); - lock_ObtainMutex(&dsp->mx); - if (code == 0) { - if (dsp->scp != 0) cm_ReleaseSCache(dsp->scp); - dsp->scp = scp; - /* we need one hold for the entry we just stored into, - * and one for our own processing. When we're done with this - * function, we'll drop the one for our own processing. - * We held it once from the namei call, and so we do another hold - * now. - */ - cm_HoldSCache(scp); - lock_ObtainMutex(&scp->mx); - if ((scp->flags & CM_SCACHEFLAG_BULKSTATTING) == 0 - && LargeIntegerGreaterOrEqualToZero(scp->bulkStatProgress)) { - scp->flags |= CM_SCACHEFLAG_BULKSTATTING; - dsp->flags |= SMB_DIRSEARCH_BULKST; - } - lock_ReleaseMutex(&scp->mx); - } - } - lock_ReleaseMutex(&dsp->mx); - if (code) { - cm_ReleaseUser(userp); - smb_DeleteDirSearch(dsp); - smb_ReleaseDirSearch(dsp); - return code; - } - - /* reserves space for parameter; we'll adjust it again later to the - * real count of the # of entries we returned once we've actually - * assembled the directory listing. - */ - smb_SetSMBParm(outp, 0, 0); - - /* get the directory size */ - lock_ObtainMutex(&scp->mx); - code = cm_SyncOp(scp, NULL, userp, &req, 0, - CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); - if (code) { - lock_ReleaseMutex(&scp->mx); - cm_ReleaseSCache(scp); - cm_ReleaseUser(userp); - smb_DeleteDirSearch(dsp); - smb_ReleaseDirSearch(dsp); - return code; - } + code = cm_NameI(cm_rootSCachep, spacep->data, + caseFold | CM_FLAG_FOLLOW, userp, tidPathp, &req, &scp); + lock_ObtainMutex(&dsp->mx); + if (code == 0) { + if (dsp->scp != 0) cm_ReleaseSCache(dsp->scp); + dsp->scp = scp; + /* we need one hold for the entry we just stored into, + * and one for our own processing. When we're done with this + * function, we'll drop the one for our own processing. + * We held it once from the namei call, and so we do another hold + * now. + */ + cm_HoldSCache(scp); + lock_ObtainMutex(&scp->mx); + if ((scp->flags & CM_SCACHEFLAG_BULKSTATTING) == 0 + && LargeIntegerGreaterOrEqualToZero(scp->bulkStatProgress)) { + scp->flags |= CM_SCACHEFLAG_BULKSTATTING; + dsp->flags |= SMB_DIRSEARCH_BULKST; + } + lock_ReleaseMutex(&scp->mx); + } + } + lock_ReleaseMutex(&dsp->mx); + if (code) { + cm_ReleaseUser(userp); + smb_DeleteDirSearch(dsp); + smb_ReleaseDirSearch(dsp); + return code; + } + + /* reserves space for parameter; we'll adjust it again later to the + * real count of the # of entries we returned once we've actually + * assembled the directory listing. + */ + smb_SetSMBParm(outp, 0, 0); + + /* get the directory size */ + lock_ObtainMutex(&scp->mx); + code = cm_SyncOp(scp, NULL, userp, &req, 0, + CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); + if (code) { + lock_ReleaseMutex(&scp->mx); + cm_ReleaseSCache(scp); + cm_ReleaseUser(userp); + smb_DeleteDirSearch(dsp); + smb_ReleaseDirSearch(dsp); + return code; + } - dirLength = scp->length; - bufferp = NULL; - bufferOffset.LowPart = bufferOffset.HighPart = 0; - curOffset.HighPart = 0; - curOffset.LowPart = nextCookie; - origOp = op = smb_GetSMBData(outp, NULL); - /* and write out the basic header */ - *op++ = 5; /* variable block */ - op += 2; /* skip vbl block length; we'll fill it in later */ - code = 0; - returnedNames = 0; - while (1) { - /* make sure that curOffset.LowPart doesn't point to the first - * 32 bytes in the 2nd through last dir page, and that it doesn't - * point at the first 13 32-byte chunks in the first dir page, - * since those are dir and page headers, and don't contain useful - * information. - */ - temp = curOffset.LowPart & (2048-1); - if (curOffset.HighPart == 0 && curOffset.LowPart < 2048) { - /* we're in the first page */ - if (temp < 13*32) temp = 13*32; - } - else { - /* we're in a later dir page */ - if (temp < 32) temp = 32; - } - - /* make sure the low order 5 bits are zero */ - temp &= ~(32-1); - - /* now put temp bits back ito curOffset.LowPart */ - curOffset.LowPart &= ~(2048-1); - curOffset.LowPart |= temp; - - /* check if we've returned all the names that will fit in the - * response packet. - */ - if (returnedNames >= maxCount) - break; + dirLength = scp->length; + bufferp = NULL; + bufferOffset.LowPart = bufferOffset.HighPart = 0; + curOffset.HighPart = 0; + curOffset.LowPart = nextCookie; + origOp = op = smb_GetSMBData(outp, NULL); + /* and write out the basic header */ + *op++ = 5; /* variable block */ + op += 2; /* skip vbl block length; we'll fill it in later */ + code = 0; + returnedNames = 0; + while (1) { + /* make sure that curOffset.LowPart doesn't point to the first + * 32 bytes in the 2nd through last dir page, and that it doesn't + * point at the first 13 32-byte chunks in the first dir page, + * since those are dir and page headers, and don't contain useful + * information. + */ + temp = curOffset.LowPart & (2048-1); + if (curOffset.HighPart == 0 && curOffset.LowPart < 2048) { + /* we're in the first page */ + if (temp < 13*32) temp = 13*32; + } + else { + /* we're in a later dir page */ + if (temp < 32) temp = 32; + } + + /* make sure the low order 5 bits are zero */ + temp &= ~(32-1); + + /* now put temp bits back ito curOffset.LowPart */ + curOffset.LowPart &= ~(2048-1); + curOffset.LowPart |= temp; + + /* check if we've returned all the names that will fit in the + * response packet. + */ + if (returnedNames >= maxCount) + break; - /* check if we've passed the dir's EOF */ - if (LargeIntegerGreaterThanOrEqualTo(curOffset, dirLength)) break; - - /* see if we can use the bufferp we have now; compute in which page - * the current offset would be, and check whether that's the offset - * of the buffer we have. If not, get the buffer. - */ - thyper.HighPart = curOffset.HighPart; - thyper.LowPart = curOffset.LowPart & ~(buf_bufferSize-1); - if (!bufferp || !LargeIntegerEqualTo(thyper, bufferOffset)) { - /* wrong buffer */ - if (bufferp) { - buf_Release(bufferp); - bufferp = NULL; - } - lock_ReleaseMutex(&scp->mx); - lock_ObtainRead(&scp->bufCreateLock); - code = buf_Get(scp, &thyper, &bufferp); - lock_ReleaseRead(&scp->bufCreateLock); - - /* now, if we're doing a star match, do bulk fetching of all of - * the status info for files in the dir. - */ - if (starPattern) { - smb_ApplyDirListPatches(&dirListPatchesp, userp, - &req); - if ((dsp->flags & SMB_DIRSEARCH_BULKST) - && LargeIntegerGreaterThanOrEqualTo(thyper, - scp->bulkStatProgress)) { - /* Don't bulk stat if risking timeout */ - int now = GetCurrentTime(); - if (now - req.startTime > 5000) { - scp->bulkStatProgress = thyper; - scp->flags &= ~CM_SCACHEFLAG_BULKSTATTING; - dsp->flags &= ~SMB_DIRSEARCH_BULKST; - } else - cm_TryBulkStat(scp, &thyper, userp, &req); - } - } - - lock_ObtainMutex(&scp->mx); - if (code) - break; - bufferOffset = thyper; - - /* now get the data in the cache */ - while (1) { - code = cm_SyncOp(scp, bufferp, userp, &req, - PRSFS_LOOKUP, - CM_SCACHESYNC_NEEDCALLBACK - | CM_SCACHESYNC_READ); - if (code) break; + /* check if we've passed the dir's EOF */ + if (LargeIntegerGreaterThanOrEqualTo(curOffset, dirLength)) break; + + /* see if we can use the bufferp we have now; compute in which page + * the current offset would be, and check whether that's the offset + * of the buffer we have. If not, get the buffer. + */ + thyper.HighPart = curOffset.HighPart; + thyper.LowPart = curOffset.LowPart & ~(buf_bufferSize-1); + if (!bufferp || !LargeIntegerEqualTo(thyper, bufferOffset)) { + /* wrong buffer */ + if (bufferp) { + buf_Release(bufferp); + bufferp = NULL; + } + lock_ReleaseMutex(&scp->mx); + lock_ObtainRead(&scp->bufCreateLock); + code = buf_Get(scp, &thyper, &bufferp); + lock_ReleaseRead(&scp->bufCreateLock); + + /* now, if we're doing a star match, do bulk fetching of all of + * the status info for files in the dir. + */ + if (starPattern) { + smb_ApplyDirListPatches(&dirListPatchesp, userp, + &req); + if ((dsp->flags & SMB_DIRSEARCH_BULKST) && + LargeIntegerGreaterThanOrEqualTo(thyper, + scp->bulkStatProgress)) { + /* Don't bulk stat if risking timeout */ + int now = GetCurrentTime(); + if (now - req.startTime > 5000) { + scp->bulkStatProgress = thyper; + scp->flags &= ~CM_SCACHEFLAG_BULKSTATTING; + dsp->flags &= ~SMB_DIRSEARCH_BULKST; + } else + cm_TryBulkStat(scp, &thyper, userp, &req); + } + } + + lock_ObtainMutex(&scp->mx); + if (code) + break; + bufferOffset = thyper; + + /* now get the data in the cache */ + while (1) { + code = cm_SyncOp(scp, bufferp, userp, &req, + PRSFS_LOOKUP, + CM_SCACHESYNC_NEEDCALLBACK | + CM_SCACHESYNC_READ); + if (code) break; - if (cm_HaveBuffer(scp, bufferp, 0)) break; - - /* otherwise, load the buffer and try again */ - code = cm_GetBuffer(scp, bufferp, NULL, userp, - &req); - if (code) break; - } - if (code) { - buf_Release(bufferp); - bufferp = NULL; - break; - } - } /* if (wrong buffer) ... */ - - /* now we have the buffer containing the entry we're interested in; copy - * it out if it represents a non-deleted entry. - */ - entryInDir = curOffset.LowPart & (2048-1); - entryInBuffer = curOffset.LowPart & (buf_bufferSize - 1); - - /* page header will help tell us which entries are free. Page header - * can change more often than once per buffer, since AFS 3 dir page size - * may be less than (but not more than a buffer package buffer. - */ - temp = curOffset.LowPart & (buf_bufferSize - 1); /* only look intra-buffer */ - temp &= ~(2048 - 1); /* turn off intra-page bits */ - pageHeaderp = (cm_pageHeader_t *) (bufferp->datap + temp); - - /* now determine which entry we're looking at in the page. If it is - * free (there's a free bitmap at the start of the dir), we should - * skip these 32 bytes. - */ - slotInPage = (entryInDir & 0x7e0) >> 5; - if (!(pageHeaderp->freeBitmap[slotInPage>>3] & (1 << (slotInPage & 0x7)))) { - /* this entry is free */ - numDirChunks = 1; /* only skip this guy */ - goto nextEntry; - } - - tp = bufferp->datap + entryInBuffer; - dep = (cm_dirEntry_t *) tp; /* now points to AFS3 dir entry */ - - /* while we're here, compute the next entry's location, too, - * since we'll need it when writing out the cookie into the dir - * listing stream. - * - * XXXX Probably should do more sanity checking. - */ - numDirChunks = cm_NameEntries(dep->name, NULL); - - /* compute the offset of the cookie representing the next entry */ - nextEntryCookie = curOffset.LowPart + (CM_DIR_CHUNKSIZE * numDirChunks); - - /* Compute 8.3 name if necessary */ - actualName = dep->name; - if (dep->fid.vnode != 0 && !cm_Is8Dot3(actualName)) { - cm_Gen8Dot3Name(dep, shortName, &shortNameEnd); - actualName = shortName; - } - - if (dep->fid.vnode != 0 && smb_Match8Dot3Mask(actualName, mask)) { - /* this is one of the entries to use: it is not deleted - * and it matches the star pattern we're looking for. - */ - - /* Eliminate entries that don't match requested - attributes */ - - /* no hidden files */ - if(smb_hideDotFiles && !(dsp->attribute & SMB_ATTR_HIDDEN) && smb_IsDotFile(actualName)) - goto nextEntry; - - if (!(dsp->attribute & SMB_ATTR_DIRECTORY)) /* no directories */ - { - /* We have already done the cm_TryBulkStat above */ - fid.cell = scp->fid.cell; - fid.volume = scp->fid.volume; - fid.vnode = ntohl(dep->fid.vnode); - fid.unique = ntohl(dep->fid.unique); - fileType = cm_FindFileType(&fid); - osi_Log2(smb_logp, "smb_ReceiveCoreSearchDir: file %s " - "has filetype %d", osi_LogSaveString(smb_logp, dep->name), - fileType); - if (fileType == CM_SCACHETYPE_DIRECTORY) - goto nextEntry; - } - - *op++ = resByte; - memcpy(op, mask, 11); op += 11; - *op++ = (char) dsp->cookie; /* they say it must be non-zero */ - *op++ = nextEntryCookie & 0xff; - *op++ = (nextEntryCookie>>8) & 0xff; - *op++ = (nextEntryCookie>>16) & 0xff; - *op++ = (nextEntryCookie>>24) & 0xff; - memcpy(op, &clientCookie, 4); op += 4; - - /* now we emit the attribute. This is sort of tricky, - * since we need to really stat the file to find out - * what type of entry we've got. Right now, we're - * copying out data from a buffer, while holding the - * scp locked, so it isn't really convenient to stat - * something now. We'll put in a place holder now, - * and make a second pass before returning this to get - * the real attributes. So, we just skip the data for - * now, and adjust it later. We allocate a patch - * record to make it easy to find this point later. - * The replay will happen at a time when it is safe to - * unlock the directory. - */ - curPatchp = malloc(sizeof(*curPatchp)); - osi_QAdd((osi_queue_t **) &dirListPatchesp, &curPatchp->q); - curPatchp->dptr = op; - curPatchp->fid.cell = scp->fid.cell; - curPatchp->fid.volume = scp->fid.volume; - curPatchp->fid.vnode = ntohl(dep->fid.vnode); - curPatchp->fid.unique = ntohl(dep->fid.unique); - - /* do hidden attribute here since name won't be around when applying - * dir list patches - */ - - if ( smb_hideDotFiles && smb_IsDotFile(actualName) ) - curPatchp->flags = SMB_DIRLISTPATCH_DOTFILE; - else - curPatchp->flags = 0; - - op += 9; /* skip attr, time, date and size */ - - /* zero out name area. The spec says to pad with - * spaces, but Samba doesn't, and neither do we. - */ - memset(op, 0, 13); - - /* finally, we get to copy out the name; we know that - * it fits in 8.3 or the pattern wouldn't match, but it - * never hurts to be sure. - */ - strncpy(op, actualName, 13); - - /* Uppercase if requested by client */ - if ((((smb_t *)inp)->flg2 & 1) == 0) - _strupr(op); - - op += 13; - - /* now, adjust the # of entries copied */ - returnedNames++; - } /* if we're including this name */ - - nextEntry: - /* and adjust curOffset to be where the new cookie is */ - thyper.HighPart = 0; - thyper.LowPart = CM_DIR_CHUNKSIZE * numDirChunks; - curOffset = LargeIntegerAdd(thyper, curOffset); - } /* while copying data for dir listing */ - - /* release the mutex */ - lock_ReleaseMutex(&scp->mx); - if (bufferp) buf_Release(bufferp); - - /* apply and free last set of patches; if not doing a star match, this - * will be empty, but better safe (and freeing everything) than sorry. - */ - smb_ApplyDirListPatches(&dirListPatchesp, userp, &req); - - /* special return code for unsuccessful search */ - if (code == 0 && dataLength < 21 && returnedNames == 0) - code = CM_ERROR_NOFILES; - - osi_Log2(smb_logp, "SMB search dir done, %d names, code %d", - returnedNames, code); - - if (code != 0) { - smb_DeleteDirSearch(dsp); - smb_ReleaseDirSearch(dsp); - cm_ReleaseSCache(scp); - cm_ReleaseUser(userp); - return code; - } - - /* finalize the output buffer */ - smb_SetSMBParm(outp, 0, returnedNames); - temp = (long) (op - origOp); - smb_SetSMBDataLength(outp, temp); - - /* the data area is a variable block, which has a 5 (already there) - * followed by the length of the # of data bytes. We now know this to - * be "temp," although that includes the 3 bytes of vbl block header. - * Deduct for them and fill in the length field. - */ - temp -= 3; /* deduct vbl block info */ - osi_assert(temp == (43 * returnedNames)); - origOp[1] = temp & 0xff; - origOp[2] = (temp>>8) & 0xff; - if (returnedNames == 0) smb_DeleteDirSearch(dsp); - smb_ReleaseDirSearch(dsp); - cm_ReleaseSCache(scp); - cm_ReleaseUser(userp); - return code; + if (cm_HaveBuffer(scp, bufferp, 0)) break; + + /* otherwise, load the buffer and try again */ + code = cm_GetBuffer(scp, bufferp, NULL, userp, &req); + if (code) break; + } + if (code) { + buf_Release(bufferp); + bufferp = NULL; + break; + } + } /* if (wrong buffer) ... */ + + /* now we have the buffer containing the entry we're interested in; copy + * it out if it represents a non-deleted entry. + */ + entryInDir = curOffset.LowPart & (2048-1); + entryInBuffer = curOffset.LowPart & (buf_bufferSize - 1); + + /* page header will help tell us which entries are free. Page header + * can change more often than once per buffer, since AFS 3 dir page size + * may be less than (but not more than a buffer package buffer. + */ + temp = curOffset.LowPart & (buf_bufferSize - 1); /* only look intra-buffer */ + temp &= ~(2048 - 1); /* turn off intra-page bits */ + pageHeaderp = (cm_pageHeader_t *) (bufferp->datap + temp); + + /* now determine which entry we're looking at in the page. If it is + * free (there's a free bitmap at the start of the dir), we should + * skip these 32 bytes. + */ + slotInPage = (entryInDir & 0x7e0) >> 5; + if (!(pageHeaderp->freeBitmap[slotInPage>>3] & (1 << (slotInPage & 0x7)))) { + /* this entry is free */ + numDirChunks = 1; /* only skip this guy */ + goto nextEntry; + } + + tp = bufferp->datap + entryInBuffer; + dep = (cm_dirEntry_t *) tp; /* now points to AFS3 dir entry */ + + /* while we're here, compute the next entry's location, too, + * since we'll need it when writing out the cookie into the dir + * listing stream. + * + * XXXX Probably should do more sanity checking. + */ + numDirChunks = cm_NameEntries(dep->name, NULL); + + /* compute the offset of the cookie representing the next entry */ + nextEntryCookie = curOffset.LowPart + (CM_DIR_CHUNKSIZE * numDirChunks); + + /* Compute 8.3 name if necessary */ + actualName = dep->name; + if (dep->fid.vnode != 0 && !cm_Is8Dot3(actualName)) { + cm_Gen8Dot3Name(dep, shortName, &shortNameEnd); + actualName = shortName; + } + + if (dep->fid.vnode != 0 && smb_Match8Dot3Mask(actualName, mask)) { + /* this is one of the entries to use: it is not deleted + * and it matches the star pattern we're looking for. + */ + + /* Eliminate entries that don't match requested + * attributes */ + + /* no hidden files */ + if(smb_hideDotFiles && !(dsp->attribute & SMB_ATTR_HIDDEN) && smb_IsDotFile(actualName)) + goto nextEntry; + + if (!(dsp->attribute & SMB_ATTR_DIRECTORY)) /* no directories */ + { + /* We have already done the cm_TryBulkStat above */ + fid.cell = scp->fid.cell; + fid.volume = scp->fid.volume; + fid.vnode = ntohl(dep->fid.vnode); + fid.unique = ntohl(dep->fid.unique); + fileType = cm_FindFileType(&fid); + osi_Log2(smb_logp, "smb_ReceiveCoreSearchDir: file %s " + "has filetype %d", osi_LogSaveString(smb_logp, dep->name), + fileType); + if (fileType == CM_SCACHETYPE_DIRECTORY) + goto nextEntry; + } + + *op++ = resByte; + memcpy(op, mask, 11); op += 11; + *op++ = (char) dsp->cookie; /* they say it must be non-zero */ + *op++ = nextEntryCookie & 0xff; + *op++ = (nextEntryCookie>>8) & 0xff; + *op++ = (nextEntryCookie>>16) & 0xff; + *op++ = (nextEntryCookie>>24) & 0xff; + memcpy(op, &clientCookie, 4); op += 4; + + /* now we emit the attribute. This is sort of tricky, + * since we need to really stat the file to find out + * what type of entry we've got. Right now, we're + * copying out data from a buffer, while holding the + * scp locked, so it isn't really convenient to stat + * something now. We'll put in a place holder now, + * and make a second pass before returning this to get + * the real attributes. So, we just skip the data for + * now, and adjust it later. We allocate a patch + * record to make it easy to find this point later. + * The replay will happen at a time when it is safe to + * unlock the directory. + */ + curPatchp = malloc(sizeof(*curPatchp)); + osi_QAdd((osi_queue_t **) &dirListPatchesp, &curPatchp->q); + curPatchp->dptr = op; + curPatchp->fid.cell = scp->fid.cell; + curPatchp->fid.volume = scp->fid.volume; + curPatchp->fid.vnode = ntohl(dep->fid.vnode); + curPatchp->fid.unique = ntohl(dep->fid.unique); + + /* do hidden attribute here since name won't be around when applying + * dir list patches + */ + + if ( smb_hideDotFiles && smb_IsDotFile(actualName) ) + curPatchp->flags = SMB_DIRLISTPATCH_DOTFILE; + else + curPatchp->flags = 0; + + op += 9; /* skip attr, time, date and size */ + + /* zero out name area. The spec says to pad with + * spaces, but Samba doesn't, and neither do we. + */ + memset(op, 0, 13); + + /* finally, we get to copy out the name; we know that + * it fits in 8.3 or the pattern wouldn't match, but it + * never hurts to be sure. + */ + strncpy(op, actualName, 13); + + /* Uppercase if requested by client */ + if ((((smb_t *)inp)->flg2 & 1) == 0) + _strupr(op); + + op += 13; + + /* now, adjust the # of entries copied */ + returnedNames++; + } /* if we're including this name */ + + nextEntry: + /* and adjust curOffset to be where the new cookie is */ + thyper.HighPart = 0; + thyper.LowPart = CM_DIR_CHUNKSIZE * numDirChunks; + curOffset = LargeIntegerAdd(thyper, curOffset); + } /* while copying data for dir listing */ + + /* release the mutex */ + lock_ReleaseMutex(&scp->mx); + if (bufferp) buf_Release(bufferp); + + /* apply and free last set of patches; if not doing a star match, this + * will be empty, but better safe (and freeing everything) than sorry. + */ + smb_ApplyDirListPatches(&dirListPatchesp, userp, &req); + + /* special return code for unsuccessful search */ + if (code == 0 && dataLength < 21 && returnedNames == 0) + code = CM_ERROR_NOFILES; + + osi_Log2(smb_logp, "SMB search dir done, %d names, code %d", + returnedNames, code); + + if (code != 0) { + smb_DeleteDirSearch(dsp); + smb_ReleaseDirSearch(dsp); + cm_ReleaseSCache(scp); + cm_ReleaseUser(userp); + return code; + } + + /* finalize the output buffer */ + smb_SetSMBParm(outp, 0, returnedNames); + temp = (long) (op - origOp); + smb_SetSMBDataLength(outp, temp); + + /* the data area is a variable block, which has a 5 (already there) + * followed by the length of the # of data bytes. We now know this to + * be "temp," although that includes the 3 bytes of vbl block header. + * Deduct for them and fill in the length field. + */ + temp -= 3; /* deduct vbl block info */ + osi_assert(temp == (43 * returnedNames)); + origOp[1] = temp & 0xff; + origOp[2] = (temp>>8) & 0xff; + if (returnedNames == 0) + smb_DeleteDirSearch(dsp); + smb_ReleaseDirSearch(dsp); + cm_ReleaseSCache(scp); + cm_ReleaseUser(userp); + return code; } /* verify that this is a valid path to a directory. I don't know why they @@ -3756,346 +3760,345 @@ long smb_ReceiveCoreSearchDir(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *ou */ long smb_ReceiveCoreCheckPath(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { - char *pathp; - long code = 0; - cm_scache_t *rootScp; - cm_scache_t *newScp; - cm_user_t *userp; - unsigned int attrs; - int caseFold; - char *tidPathp; - cm_req_t req; - - cm_InitReq(&req); - - pathp = smb_GetSMBData(inp, NULL); - pathp = smb_ParseASCIIBlock(pathp, NULL); - osi_Log1(smb_logp, "SMB receive check path %s", - osi_LogSaveString(smb_logp, pathp)); - - if (!pathp) { - return CM_ERROR_BADFD; - } + char *pathp; + long code = 0; + cm_scache_t *rootScp; + cm_scache_t *newScp; + cm_user_t *userp; + unsigned int attrs; + int caseFold; + char *tidPathp; + cm_req_t req; + + cm_InitReq(&req); + + pathp = smb_GetSMBData(inp, NULL); + pathp = smb_ParseASCIIBlock(pathp, NULL); + osi_Log1(smb_logp, "SMB receive check path %s", + osi_LogSaveString(smb_logp, pathp)); + + if (!pathp) { + return CM_ERROR_BADFD; + } - rootScp = cm_rootSCachep; + rootScp = cm_rootSCachep; - userp = smb_GetUser(vcp, inp); + userp = smb_GetUser(vcp, inp); - caseFold = CM_FLAG_CASEFOLD; + caseFold = CM_FLAG_CASEFOLD; - code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &tidPathp); + code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &tidPathp); if(code) { cm_ReleaseUser(userp); return CM_ERROR_NOSUCHPATH; } - code = cm_NameI(rootScp, pathp, - caseFold | CM_FLAG_FOLLOW | CM_FLAG_CHECKPATH, - userp, tidPathp, &req, &newScp); + code = cm_NameI(rootScp, pathp, + caseFold | CM_FLAG_FOLLOW | CM_FLAG_CHECKPATH, + userp, tidPathp, &req, &newScp); - if (code) { - cm_ReleaseUser(userp); - return code; - } + if (code) { + cm_ReleaseUser(userp); + return code; + } - /* now lock the vnode with a callback; returns with newScp locked */ - lock_ObtainMutex(&newScp->mx); - code = cm_SyncOp(newScp, NULL, userp, &req, PRSFS_LOOKUP, - CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_NEEDCALLBACK); - if (code && code != CM_ERROR_NOACCESS) { - lock_ReleaseMutex(&newScp->mx); - cm_ReleaseSCache(newScp); - cm_ReleaseUser(userp); - return code; - } - - attrs = smb_Attributes(newScp); - - if (!(attrs & 0x10)) - code = CM_ERROR_NOTDIR; - - lock_ReleaseMutex(&newScp->mx); - - cm_ReleaseSCache(newScp); - cm_ReleaseUser(userp); - return code; + /* now lock the vnode with a callback; returns with newScp locked */ + lock_ObtainMutex(&newScp->mx); + code = cm_SyncOp(newScp, NULL, userp, &req, PRSFS_LOOKUP, + CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_NEEDCALLBACK); + if (code && code != CM_ERROR_NOACCESS) { + lock_ReleaseMutex(&newScp->mx); + cm_ReleaseSCache(newScp); + cm_ReleaseUser(userp); + return code; + } + + attrs = smb_Attributes(newScp); + + if (!(attrs & 0x10)) + code = CM_ERROR_NOTDIR; + + lock_ReleaseMutex(&newScp->mx); + + cm_ReleaseSCache(newScp); + cm_ReleaseUser(userp); + return code; } long smb_ReceiveCoreSetFileAttributes(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { - char *pathp; - long code = 0; - cm_scache_t *rootScp; - unsigned short attribute; - cm_attr_t attr; - cm_scache_t *newScp; - time_t dosTime; - cm_user_t *userp; - int caseFold; - char *tidPathp; - cm_req_t req; - - cm_InitReq(&req); - - /* decode basic attributes we're passed */ - attribute = smb_GetSMBParm(inp, 0); - dosTime = smb_GetSMBParm(inp, 1) | (smb_GetSMBParm(inp, 2) << 16); - - pathp = smb_GetSMBData(inp, NULL); - pathp = smb_ParseASCIIBlock(pathp, NULL); - - if (!pathp) { - return CM_ERROR_BADSMB; - } + char *pathp; + long code = 0; + cm_scache_t *rootScp; + unsigned short attribute; + cm_attr_t attr; + cm_scache_t *newScp; + time_t dosTime; + cm_user_t *userp; + int caseFold; + char *tidPathp; + cm_req_t req; + + cm_InitReq(&req); + + /* decode basic attributes we're passed */ + attribute = smb_GetSMBParm(inp, 0); + dosTime = smb_GetSMBParm(inp, 1) | (smb_GetSMBParm(inp, 2) << 16); + + pathp = smb_GetSMBData(inp, NULL); + pathp = smb_ParseASCIIBlock(pathp, NULL); + + if (!pathp) { + return CM_ERROR_BADSMB; + } - osi_Log2(smb_logp, "SMB receive setfile attributes time %d, attr 0x%x", - dosTime, attribute); + osi_Log2(smb_logp, "SMB receive setfile attributes time %d, attr 0x%x", + dosTime, attribute); - rootScp = cm_rootSCachep; + rootScp = cm_rootSCachep; - userp = smb_GetUser(vcp, inp); + userp = smb_GetUser(vcp, inp); - caseFold = CM_FLAG_CASEFOLD; + caseFold = CM_FLAG_CASEFOLD; - code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &tidPathp); - if(code) { + code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &tidPathp); + if (code) { cm_ReleaseUser(userp); return CM_ERROR_NOSUCHFILE; } - code = cm_NameI(rootScp, pathp, caseFold | CM_FLAG_FOLLOW, userp, - tidPathp, &req, &newScp); + code = cm_NameI(rootScp, pathp, caseFold | CM_FLAG_FOLLOW, userp, + tidPathp, &req, &newScp); - if (code) { - cm_ReleaseUser(userp); - return code; - } + if (code) { + cm_ReleaseUser(userp); + return code; + } - /* now lock the vnode with a callback; returns with newScp locked; we - * need the current status to determine what the new status is, in some - * cases. - */ - lock_ObtainMutex(&newScp->mx); - code = cm_SyncOp(newScp, NULL, userp, &req, 0, - CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_NEEDCALLBACK); - if (code) { - lock_ReleaseMutex(&newScp->mx); - cm_ReleaseSCache(newScp); - cm_ReleaseUser(userp); - return code; - } - - /* Check for RO volume */ - if (newScp->flags & CM_SCACHEFLAG_RO) { - lock_ReleaseMutex(&newScp->mx); - cm_ReleaseSCache(newScp); - cm_ReleaseUser(userp); - return CM_ERROR_READONLY; - } - - /* prepare for setattr call */ - attr.mask = 0; - if (dosTime != 0) { - attr.mask |= CM_ATTRMASK_CLIENTMODTIME; - smb_UnixTimeFromDosUTime(&attr.clientModTime, dosTime); - } - if ((newScp->unixModeBits & 0222) && (attribute & 1) != 0) { - /* we're told to make a writable file read-only */ - attr.unixModeBits = newScp->unixModeBits & ~0222; - attr.mask |= CM_ATTRMASK_UNIXMODEBITS; - } - else if ((newScp->unixModeBits & 0222) == 0 && (attribute & 1) == 0) { - /* we're told to make a read-only file writable */ - attr.unixModeBits = newScp->unixModeBits | 0222; - attr.mask |= CM_ATTRMASK_UNIXMODEBITS; - } - lock_ReleaseMutex(&newScp->mx); - - /* now call setattr */ - if (attr.mask) - code = cm_SetAttr(newScp, &attr, userp, &req); - else - code = 0; + /* now lock the vnode with a callback; returns with newScp locked; we + * need the current status to determine what the new status is, in some + * cases. + */ + lock_ObtainMutex(&newScp->mx); + code = cm_SyncOp(newScp, NULL, userp, &req, 0, + CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_NEEDCALLBACK); + if (code) { + lock_ReleaseMutex(&newScp->mx); + cm_ReleaseSCache(newScp); + cm_ReleaseUser(userp); + return code; + } + + /* Check for RO volume */ + if (newScp->flags & CM_SCACHEFLAG_RO) { + lock_ReleaseMutex(&newScp->mx); + cm_ReleaseSCache(newScp); + cm_ReleaseUser(userp); + return CM_ERROR_READONLY; + } + + /* prepare for setattr call */ + attr.mask = 0; + if (dosTime != 0) { + attr.mask |= CM_ATTRMASK_CLIENTMODTIME; + smb_UnixTimeFromDosUTime(&attr.clientModTime, dosTime); + } + if ((newScp->unixModeBits & 0222) && (attribute & 1) != 0) { + /* we're told to make a writable file read-only */ + attr.unixModeBits = newScp->unixModeBits & ~0222; + attr.mask |= CM_ATTRMASK_UNIXMODEBITS; + } + else if ((newScp->unixModeBits & 0222) == 0 && (attribute & 1) == 0) { + /* we're told to make a read-only file writable */ + attr.unixModeBits = newScp->unixModeBits | 0222; + attr.mask |= CM_ATTRMASK_UNIXMODEBITS; + } + lock_ReleaseMutex(&newScp->mx); + + /* now call setattr */ + if (attr.mask) + code = cm_SetAttr(newScp, &attr, userp, &req); + else + code = 0; - cm_ReleaseSCache(newScp); - cm_ReleaseUser(userp); + cm_ReleaseSCache(newScp); + cm_ReleaseUser(userp); - return code; + return code; } long smb_ReceiveCoreGetFileAttributes(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { - char *pathp; - long code = 0; - cm_scache_t *rootScp; - cm_scache_t *newScp, *dscp; - time_t dosTime; - int attrs; - cm_user_t *userp; - int caseFold; - char *tidPathp; - cm_space_t *spacep; - char *lastComp; - cm_req_t req; - - cm_InitReq(&req); - - pathp = smb_GetSMBData(inp, NULL); - pathp = smb_ParseASCIIBlock(pathp, NULL); - - if (!pathp) { - return CM_ERROR_BADSMB; - } + char *pathp; + long code = 0; + cm_scache_t *rootScp; + cm_scache_t *newScp, *dscp; + time_t dosTime; + int attrs; + cm_user_t *userp; + int caseFold; + char *tidPathp; + cm_space_t *spacep; + char *lastComp; + cm_req_t req; + + cm_InitReq(&req); + + pathp = smb_GetSMBData(inp, NULL); + pathp = smb_ParseASCIIBlock(pathp, NULL); + + if (!pathp) { + return CM_ERROR_BADSMB; + } - if (*pathp == 0) /* null path */ - pathp = "\\"; + if (*pathp == 0) /* null path */ + pathp = "\\"; - osi_Log1(smb_logp, "SMB receive getfile attributes path %s", - osi_LogSaveString(smb_logp, pathp)); + osi_Log1(smb_logp, "SMB receive getfile attributes path %s", + osi_LogSaveString(smb_logp, pathp)); - rootScp = cm_rootSCachep; + rootScp = cm_rootSCachep; - userp = smb_GetUser(vcp, inp); + userp = smb_GetUser(vcp, inp); - /* we shouldn't need this for V3 requests, but we seem to */ - caseFold = CM_FLAG_CASEFOLD; + /* we shouldn't need this for V3 requests, but we seem to */ + caseFold = CM_FLAG_CASEFOLD; - code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &tidPathp); - if(code) { + code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &tidPathp); + if (code) { cm_ReleaseUser(userp); return CM_ERROR_NOSUCHFILE; } - /* - * XXX Strange hack XXX - * - * As of Patch 5 (16 July 97), we are having the following problem: - * In NT Explorer 4.0, whenever we click on a directory, AFS gets - * requests to look up "desktop.ini" in all the subdirectories. - * This can cause zillions of timeouts looking up non-existent cells - * and volumes, especially in the top-level directory. - * - * We have not found any way to avoid this or work around it except - * to explicitly ignore the requests for mount points that haven't - * yet been evaluated and for directories that haven't yet been - * fetched. - * - * We should modify this hack to provide a fake desktop.ini file - * http://msdn.microsoft.com/library/en-us/shellcc/platform/shell/programmersguide/shell_basics/shell_basics_extending/custom.asp - */ - spacep = inp->spacep; - smb_StripLastComponent(spacep->data, &lastComp, pathp); - if (lastComp && stricmp(lastComp, "\\desktop.ini") == 0) { - code = cm_NameI(rootScp, spacep->data, - caseFold | CM_FLAG_DIRSEARCH | CM_FLAG_FOLLOW, - userp, tidPathp, &req, &dscp); - if (code == 0) { - if (dscp->fileType == CM_SCACHETYPE_MOUNTPOINT - && !dscp->mountRootFidp) - code = CM_ERROR_NOSUCHFILE; - else if (dscp->fileType == CM_SCACHETYPE_DIRECTORY) { - cm_buf_t *bp = buf_Find(dscp, &hzero); - if (bp) - buf_Release(bp); - else - code = CM_ERROR_NOSUCHFILE; - } - cm_ReleaseSCache(dscp); - if (code) { - cm_ReleaseUser(userp); - return code; - } - } - } - - code = cm_NameI(rootScp, pathp, caseFold | CM_FLAG_FOLLOW, userp, - tidPathp, &req, &newScp); - - if (code) { - cm_ReleaseUser(userp); - return code; - } - - /* now lock the vnode with a callback; returns with newScp locked */ - lock_ObtainMutex(&newScp->mx); - code = cm_SyncOp(newScp, NULL, userp, &req, 0, - CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_NEEDCALLBACK); - if (code) { - lock_ReleaseMutex(&newScp->mx); - cm_ReleaseSCache(newScp); - cm_ReleaseUser(userp); - return code; - } - + /* + * XXX Strange hack XXX + * + * As of Patch 5 (16 July 97), we are having the following problem: + * In NT Explorer 4.0, whenever we click on a directory, AFS gets + * requests to look up "desktop.ini" in all the subdirectories. + * This can cause zillions of timeouts looking up non-existent cells + * and volumes, especially in the top-level directory. + * + * We have not found any way to avoid this or work around it except + * to explicitly ignore the requests for mount points that haven't + * yet been evaluated and for directories that haven't yet been + * fetched. + * + * We should modify this hack to provide a fake desktop.ini file + * http://msdn.microsoft.com/library/en-us/shellcc/platform/shell/programmersguide/shell_basics/shell_basics_extending/custom.asp + */ + spacep = inp->spacep; + smb_StripLastComponent(spacep->data, &lastComp, pathp); + if (lastComp && stricmp(lastComp, "\\desktop.ini") == 0) { + code = cm_NameI(rootScp, spacep->data, + caseFold | CM_FLAG_DIRSEARCH | CM_FLAG_FOLLOW, + userp, tidPathp, &req, &dscp); + if (code == 0) { + if (dscp->fileType == CM_SCACHETYPE_MOUNTPOINT && + !dscp->mountRootFidp) + code = CM_ERROR_NOSUCHFILE; + else if (dscp->fileType == CM_SCACHETYPE_DIRECTORY) { + cm_buf_t *bp = buf_Find(dscp, &hzero); + if (bp) + buf_Release(bp); + else + code = CM_ERROR_NOSUCHFILE; + } + cm_ReleaseSCache(dscp); + if (code) { + cm_ReleaseUser(userp); + return code; + } + } + } + + code = cm_NameI(rootScp, pathp, caseFold | CM_FLAG_FOLLOW, userp, + tidPathp, &req, &newScp); + if (code) { + cm_ReleaseUser(userp); + return code; + } + + /* now lock the vnode with a callback; returns with newScp locked */ + lock_ObtainMutex(&newScp->mx); + code = cm_SyncOp(newScp, NULL, userp, &req, 0, + CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_NEEDCALLBACK); + if (code) { + lock_ReleaseMutex(&newScp->mx); + cm_ReleaseSCache(newScp); + cm_ReleaseUser(userp); + return code; + } + #ifdef undef /* use smb_Attributes instead. Also the fact that a file is - * in a readonly volume doesn't mean it shojuld be marked as RO - */ - if (newScp->fileType == CM_SCACHETYPE_DIRECTORY - || newScp->fileType == CM_SCACHETYPE_MOUNTPOINT) - attrs = SMB_ATTR_DIRECTORY; - else - attrs = 0; - if ((newScp->unixModeBits & 0222) == 0 || (newScp->flags & CM_SCACHEFLAG_RO)) - attrs |= SMB_ATTR_READONLY; /* turn on read-only flag */ + * in a readonly volume doesn't mean it shojuld be marked as RO + */ + if (newScp->fileType == CM_SCACHETYPE_DIRECTORY || + newScp->fileType == CM_SCACHETYPE_MOUNTPOINT) + attrs = SMB_ATTR_DIRECTORY; + else + attrs = 0; + if ((newScp->unixModeBits & 0222) == 0 || (newScp->flags & CM_SCACHEFLAG_RO)) + attrs |= SMB_ATTR_READONLY; /* turn on read-only flag */ #else attrs = smb_Attributes(newScp); #endif - smb_SetSMBParm(outp, 0, attrs); - - smb_DosUTimeFromUnixTime(&dosTime, newScp->clientModTime); - smb_SetSMBParm(outp, 1, dosTime & 0xffff); - smb_SetSMBParm(outp, 2, (dosTime>>16) & 0xffff); - smb_SetSMBParm(outp, 3, newScp->length.LowPart & 0xffff); - smb_SetSMBParm(outp, 4, (newScp->length.LowPart >> 16) & 0xffff); - smb_SetSMBParm(outp, 5, 0); - smb_SetSMBParm(outp, 6, 0); - smb_SetSMBParm(outp, 7, 0); - smb_SetSMBParm(outp, 8, 0); - smb_SetSMBParm(outp, 9, 0); - smb_SetSMBDataLength(outp, 0); - lock_ReleaseMutex(&newScp->mx); - - cm_ReleaseSCache(newScp); - cm_ReleaseUser(userp); + smb_SetSMBParm(outp, 0, attrs); - return 0; + smb_DosUTimeFromUnixTime(&dosTime, newScp->clientModTime); + smb_SetSMBParm(outp, 1, dosTime & 0xffff); + smb_SetSMBParm(outp, 2, (dosTime>>16) & 0xffff); + smb_SetSMBParm(outp, 3, newScp->length.LowPart & 0xffff); + smb_SetSMBParm(outp, 4, (newScp->length.LowPart >> 16) & 0xffff); + smb_SetSMBParm(outp, 5, 0); + smb_SetSMBParm(outp, 6, 0); + smb_SetSMBParm(outp, 7, 0); + smb_SetSMBParm(outp, 8, 0); + smb_SetSMBParm(outp, 9, 0); + smb_SetSMBDataLength(outp, 0); + lock_ReleaseMutex(&newScp->mx); + + cm_ReleaseSCache(newScp); + cm_ReleaseUser(userp); + + return 0; } long smb_ReceiveCoreTreeDisconnect(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { - smb_tid_t *tidp; + smb_tid_t *tidp; - osi_Log0(smb_logp, "SMB receive tree disconnect"); - - /* find the tree and free it */ - tidp = smb_FindTID(vcp, ((smb_t *)inp)->tid, 0); - if (tidp) { - lock_ObtainMutex(&tidp->mx); - tidp->flags |= SMB_TIDFLAG_DELETE; - lock_ReleaseMutex(&tidp->mx); - smb_ReleaseTID(tidp); - } - - return 0; + osi_Log0(smb_logp, "SMB receive tree disconnect"); + + /* find the tree and free it */ + tidp = smb_FindTID(vcp, ((smb_t *)inp)->tid, 0); + if (tidp) { + lock_ObtainMutex(&tidp->mx); + tidp->flags |= SMB_TIDFLAG_DELETE; + lock_ReleaseMutex(&tidp->mx); + smb_ReleaseTID(tidp); + } + + return 0; } long smb_ReceiveCoreOpen(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { - smb_fid_t *fidp; + smb_fid_t *fidp; char *pathp; - char *lastNamep; + char *lastNamep; int share; int attribute; - long code = 0; + long code = 0; cm_user_t *userp; cm_scache_t *scp; time_t dosTime; int caseFold; - cm_space_t *spacep; - char *tidPathp; - cm_req_t req; + cm_space_t *spacep; + char *tidPathp; + cm_req_t req; - cm_InitReq(&req); + cm_InitReq(&req); pathp = smb_GetSMBData(inp, NULL); pathp = smb_ParseASCIIBlock(pathp, NULL); @@ -4112,36 +4115,36 @@ long smb_ReceiveCoreOpen(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) } #endif - share = smb_GetSMBParm(inp, 0); + share = smb_GetSMBParm(inp, 0); attribute = smb_GetSMBParm(inp, 1); - spacep = inp->spacep; - smb_StripLastComponent(spacep->data, &lastNamep, pathp); - if (lastNamep && strcmp(lastNamep, SMB_IOCTL_FILENAME) == 0) { - /* special case magic file name for receiving IOCTL requests + spacep = inp->spacep; + smb_StripLastComponent(spacep->data, &lastNamep, pathp); + if (lastNamep && strcmp(lastNamep, SMB_IOCTL_FILENAME) == 0) { + /* special case magic file name for receiving IOCTL requests * (since IOCTL calls themselves aren't getting through). */ fidp = smb_FindFID(vcp, 0, SMB_FLAG_CREATE); - smb_SetupIoctlFid(fidp, spacep); - smb_SetSMBParm(outp, 0, fidp->fid); + smb_SetupIoctlFid(fidp, spacep); + smb_SetSMBParm(outp, 0, fidp->fid); smb_SetSMBParm(outp, 1, 0); /* attrs */ smb_SetSMBParm(outp, 2, 0); /* next 2 are DOS time */ smb_SetSMBParm(outp, 3, 0); smb_SetSMBParm(outp, 4, 0); /* next 2 are length */ smb_SetSMBParm(outp, 5, 0x7fff); - /* pass the open mode back */ + /* pass the open mode back */ smb_SetSMBParm(outp, 6, (share & 0xf)); smb_SetSMBDataLength(outp, 0); smb_ReleaseFID(fidp); return 0; } - userp = smb_GetUser(vcp, inp); + userp = smb_GetUser(vcp, inp); - caseFold = CM_FLAG_CASEFOLD; + caseFold = CM_FLAG_CASEFOLD; - code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &tidPathp); - if(code) { + code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &tidPathp); + if (code) { cm_ReleaseUser(userp); return CM_ERROR_NOSUCHPATH; } @@ -4150,22 +4153,22 @@ long smb_ReceiveCoreOpen(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) if (code) { cm_ReleaseUser(userp); - return code; - } - + return code; + } + code = cm_CheckOpen(scp, share & 0x7, 0, userp, &req); - if (code) { - cm_ReleaseSCache(scp); - cm_ReleaseUser(userp); - return code; - } - - /* don't need callback to check file type, since file types never - * change, and namei and cm_Lookup all stat the object at least once on - * a successful return. + if (code) { + cm_ReleaseSCache(scp); + cm_ReleaseUser(userp); + return code; + } + + /* don't need callback to check file type, since file types never + * change, and namei and cm_Lookup all stat the object at least once on + * a successful return. */ if (scp->fileType != CM_SCACHETYPE_FILE) { - cm_ReleaseSCache(scp); + cm_ReleaseSCache(scp); cm_ReleaseUser(userp); return CM_ERROR_ISDIR; } @@ -4173,33 +4176,33 @@ long smb_ReceiveCoreOpen(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) fidp = smb_FindFID(vcp, 0, SMB_FLAG_CREATE); osi_assert(fidp); - /* save a pointer to the vnode */ + /* save a pointer to the vnode */ fidp->scp = scp; if ((share & 0xf) == 0) fidp->flags |= SMB_FID_OPENREAD; - else if ((share & 0xf) == 1) + else if ((share & 0xf) == 1) fidp->flags |= SMB_FID_OPENWRITE; - else + else fidp->flags |= (SMB_FID_OPENREAD | SMB_FID_OPENWRITE); - lock_ObtainMutex(&scp->mx); - smb_SetSMBParm(outp, 0, fidp->fid); + lock_ObtainMutex(&scp->mx); + smb_SetSMBParm(outp, 0, fidp->fid); smb_SetSMBParm(outp, 1, smb_Attributes(scp)); - smb_DosUTimeFromUnixTime(&dosTime, scp->clientModTime); + smb_DosUTimeFromUnixTime(&dosTime, scp->clientModTime); smb_SetSMBParm(outp, 2, dosTime & 0xffff); smb_SetSMBParm(outp, 3, (dosTime >> 16) & 0xffff); smb_SetSMBParm(outp, 4, scp->length.LowPart & 0xffff); smb_SetSMBParm(outp, 5, (scp->length.LowPart >> 16) & 0xffff); - /* pass the open mode back; XXXX add access checks */ + /* pass the open mode back; XXXX add access checks */ smb_SetSMBParm(outp, 6, (share & 0xf)); smb_SetSMBDataLength(outp, 0); - lock_ReleaseMutex(&scp->mx); + lock_ReleaseMutex(&scp->mx); - /* notify open */ + /* notify open */ cm_Open(scp, 0, userp); - /* send and free packet */ + /* send and free packet */ smb_ReleaseFID(fidp); cm_ReleaseUser(userp); /* don't release scp, since we've squirreled away the pointer in the fid struct */ @@ -4207,122 +4210,123 @@ long smb_ReceiveCoreOpen(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) } typedef struct smb_unlinkRock { - cm_scache_t *dscp; - cm_user_t *userp; - cm_req_t *reqp; - smb_vc_t *vcp; - char *maskp; /* pointer to the star pattern */ - int flags; - int any; + cm_scache_t *dscp; + cm_user_t *userp; + cm_req_t *reqp; + smb_vc_t *vcp; + char *maskp; /* pointer to the star pattern */ + int flags; + int any; } smb_unlinkRock_t; int smb_UnlinkProc(cm_scache_t *dscp, cm_dirEntry_t *dep, void *vrockp, osi_hyper_t *offp) { - long code = 0; - smb_unlinkRock_t *rockp; - int caseFold; - int match; - char shortName[13]; - char *matchName; + long code = 0; + smb_unlinkRock_t *rockp; + int caseFold; + int match; + char shortName[13]; + char *matchName; - rockp = vrockp; + rockp = vrockp; caseFold = ((rockp->flags & SMB_MASKFLAG_CASEFOLD)? CM_FLAG_CASEFOLD : 0); if (!(rockp->vcp->flags & SMB_VCFLAG_USEV3)) caseFold |= CM_FLAG_8DOT3; - matchName = dep->name; - match = smb_V3MatchMask(matchName, rockp->maskp, caseFold); - if (!match - && (rockp->flags & SMB_MASKFLAG_TILDE) - && !cm_Is8Dot3(dep->name)) { - cm_Gen8Dot3Name(dep, shortName, NULL); - matchName = shortName; + matchName = dep->name; + match = smb_V3MatchMask(matchName, rockp->maskp, caseFold); + if (!match && + (rockp->flags & SMB_MASKFLAG_TILDE) && + !cm_Is8Dot3(dep->name)) { + cm_Gen8Dot3Name(dep, shortName, NULL); + matchName = shortName; /* 8.3 matches are always case insensitive */ match = smb_V3MatchMask(matchName, rockp->maskp, caseFold | CM_FLAG_CASEFOLD); - } - if (match) { - osi_Log1(smb_logp, "Unlinking %s", - osi_LogSaveString(smb_logp, matchName)); - code = cm_Unlink(dscp, dep->name, rockp->userp, rockp->reqp); - if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH)) - smb_NotifyChange(FILE_ACTION_REMOVED, - FILE_NOTIFY_CHANGE_FILE_NAME, - dscp, dep->name, NULL, TRUE); - if (code == 0) { - rockp->any = 1; + } + if (match) { + osi_Log1(smb_logp, "Unlinking %s", + osi_LogSaveString(smb_logp, matchName)); + code = cm_Unlink(dscp, dep->name, rockp->userp, rockp->reqp); + if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH)) + smb_NotifyChange(FILE_ACTION_REMOVED, + FILE_NOTIFY_CHANGE_FILE_NAME, + dscp, dep->name, NULL, TRUE); + if (code == 0) { + rockp->any = 1; + /* If we made a case sensitive exact match, we might as well quit now. */ - if(!(rockp->flags & SMB_MASKFLAG_CASEFOLD) && !strcmp(matchName, rockp->maskp)) + if (!(rockp->flags & SMB_MASKFLAG_CASEFOLD) && !strcmp(matchName, rockp->maskp)) code = CM_ERROR_STOPNOW; } - } - else code = 0; + } + else code = 0; - return code; + return code; } long smb_ReceiveCoreUnlink(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { - int attribute; - long code = 0; - char *pathp; - char *tp; - cm_space_t *spacep; - cm_scache_t *dscp; - char *lastNamep; - smb_unlinkRock_t rock; - cm_user_t *userp; - osi_hyper_t thyper; - int caseFold; - char *tidPathp; - cm_req_t req; - - cm_InitReq(&req); - - attribute = smb_GetSMBParm(inp, 0); + int attribute; + long code = 0; + char *pathp; + char *tp; + cm_space_t *spacep; + cm_scache_t *dscp; + char *lastNamep; + smb_unlinkRock_t rock; + cm_user_t *userp; + osi_hyper_t thyper; + int caseFold; + char *tidPathp; + cm_req_t req; + + cm_InitReq(&req); + + attribute = smb_GetSMBParm(inp, 0); - tp = smb_GetSMBData(inp, NULL); - pathp = smb_ParseASCIIBlock(tp, &tp); + tp = smb_GetSMBData(inp, NULL); + pathp = smb_ParseASCIIBlock(tp, &tp); - osi_Log1(smb_logp, "SMB receive unlink %s", - osi_LogSaveString(smb_logp, pathp)); + osi_Log1(smb_logp, "SMB receive unlink %s", + osi_LogSaveString(smb_logp, pathp)); - spacep = inp->spacep; - smb_StripLastComponent(spacep->data, &lastNamep, pathp); + spacep = inp->spacep; + smb_StripLastComponent(spacep->data, &lastNamep, pathp); - userp = smb_GetUser(vcp, inp); + userp = smb_GetUser(vcp, inp); - caseFold = CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD; + caseFold = CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD; - code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &tidPathp); - if(code) { + code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &tidPathp); + if (code) { cm_ReleaseUser(userp); return CM_ERROR_NOSUCHPATH; } - code = cm_NameI(cm_rootSCachep, spacep->data, caseFold, userp, tidPathp, - &req, &dscp); + code = cm_NameI(cm_rootSCachep, spacep->data, caseFold, userp, tidPathp, + &req, &dscp); - if (code) { - cm_ReleaseUser(userp); - return code; - } - - /* otherwise, scp points to the parent directory. */ - if (!lastNamep) - lastNamep = pathp; - else - lastNamep++; - - rock.any = 0; - rock.maskp = smb_FindMask(pathp); - rock.flags = ((strchr(rock.maskp, '~') != NULL) ? SMB_MASKFLAG_TILDE : 0); + if (code) { + cm_ReleaseUser(userp); + return code; + } - thyper.LowPart = 0; - thyper.HighPart = 0; - rock.userp = userp; - rock.reqp = &req; - rock.dscp = dscp; - rock.vcp = vcp; + /* otherwise, scp points to the parent directory. */ + if (!lastNamep) + lastNamep = pathp; + else + lastNamep++; + + rock.any = 0; + rock.maskp = smb_FindMask(pathp); + rock.flags = ((strchr(rock.maskp, '~') != NULL) ? SMB_MASKFLAG_TILDE : 0); + + thyper.LowPart = 0; + thyper.HighPart = 0; + rock.userp = userp; + rock.reqp = &req; + rock.dscp = dscp; + rock.vcp = vcp; /* Now, if we aren't dealing with a wildcard match, we first try an exact * match. If that fails, we do a case insensitve match. @@ -4330,7 +4334,7 @@ long smb_ReceiveCoreUnlink(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) if (!(rock.flags & SMB_MASKFLAG_TILDE) && !smb_IsStarMask(rock.maskp)) { code = cm_ApplyDir(dscp, smb_UnlinkProc, &rock, &thyper, userp, &req, NULL); - if(!rock.any) { + if (!rock.any) { thyper.LowPart = 0; thyper.HighPart = 0; rock.flags |= SMB_MASKFLAG_CASEFOLD; @@ -4343,60 +4347,60 @@ long smb_ReceiveCoreUnlink(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) if (code == CM_ERROR_STOPNOW) code = 0; - cm_ReleaseUser(userp); + cm_ReleaseUser(userp); - cm_ReleaseSCache(dscp); + cm_ReleaseSCache(dscp); - if (code == 0 && !rock.any) - code = CM_ERROR_NOSUCHFILE; - return code; -} + if (code == 0 && !rock.any) + code = CM_ERROR_NOSUCHFILE; + return code; +} typedef struct smb_renameRock { - cm_scache_t *odscp; /* old dir */ - cm_scache_t *ndscp; /* new dir */ - cm_user_t *userp; /* user */ - cm_req_t *reqp; /* request struct */ - smb_vc_t *vcp; /* virtual circuit */ - char *maskp; /* pointer to star pattern of old file name */ - int flags; /* tilde, casefold, etc */ - char *newNamep; /* ptr to the new file's name */ + cm_scache_t *odscp; /* old dir */ + cm_scache_t *ndscp; /* new dir */ + cm_user_t *userp; /* user */ + cm_req_t *reqp; /* request struct */ + smb_vc_t *vcp; /* virtual circuit */ + char *maskp; /* pointer to star pattern of old file name */ + int flags; /* tilde, casefold, etc */ + char *newNamep; /* ptr to the new file's name */ } smb_renameRock_t; int smb_RenameProc(cm_scache_t *dscp, cm_dirEntry_t *dep, void *vrockp, osi_hyper_t *offp) { - long code = 0; - smb_renameRock_t *rockp; - int caseFold; - int match; - char shortName[13]; - - rockp = (smb_renameRock_t *) vrockp; + long code = 0; + smb_renameRock_t *rockp; + int caseFold; + int match; + char shortName[13]; + + rockp = (smb_renameRock_t *) vrockp; caseFold = ((rockp->flags & SMB_MASKFLAG_CASEFOLD)? CM_FLAG_CASEFOLD : 0); if (!(rockp->vcp->flags & SMB_VCFLAG_USEV3)) caseFold |= CM_FLAG_8DOT3; - match = smb_V3MatchMask(dep->name, rockp->maskp, caseFold); - if (!match - && (rockp->flags & SMB_MASKFLAG_TILDE) - && !cm_Is8Dot3(dep->name)) { - cm_Gen8Dot3Name(dep, shortName, NULL); - match = smb_V3MatchMask(shortName, rockp->maskp, caseFold); - } - if (match) { - code = cm_Rename(rockp->odscp, dep->name, - rockp->ndscp, rockp->newNamep, rockp->userp, - rockp->reqp); - /* if the call worked, stop doing the search now, since we - * really only want to rename one file. - */ - if (code == 0) - code = CM_ERROR_STOPNOW; - } - else code = 0; - - return code; + match = smb_V3MatchMask(dep->name, rockp->maskp, caseFold); + if (!match && + (rockp->flags & SMB_MASKFLAG_TILDE) && + !cm_Is8Dot3(dep->name)) { + cm_Gen8Dot3Name(dep, shortName, NULL); + match = smb_V3MatchMask(shortName, rockp->maskp, caseFold); + } + if (match) { + code = cm_Rename(rockp->odscp, dep->name, + rockp->ndscp, rockp->newNamep, rockp->userp, + rockp->reqp); + /* if the call worked, stop doing the search now, since we + * really only want to rename one file. + */ + if (code == 0) + code = CM_ERROR_STOPNOW; + } + else code = 0; + + return code; } @@ -4430,17 +4434,17 @@ smb_Rename(smb_vc_t *vcp, smb_packet_t *inp, char * oldPathp, char * newPathp, i spacep = inp->spacep; smb_StripLastComponent(spacep->data, &oldLastNamep, oldPathp); - /* - * Changed to use CASEFOLD always. This enables us to rename Foo/baz when - * what actually exists is foo/baz. I don't know why the code used to be - * the way it was. 1/29/96 - * - * caseFold = ((vcp->flags & SMB_VCFLAG_USEV3) ? 0: CM_FLAG_CASEFOLD); - * - * Changed to use CM_FLAG_FOLLOW. 7/24/96 - * - * caseFold = CM_FLAG_CASEFOLD; - */ + /* + * Changed to use CASEFOLD always. This enables us to rename Foo/baz when + * what actually exists is foo/baz. I don't know why the code used to be + * the way it was. 1/29/96 + * + * caseFold = ((vcp->flags & SMB_VCFLAG_USEV3) ? 0: CM_FLAG_CASEFOLD); + * + * Changed to use CM_FLAG_FOLLOW. 7/24/96 + * + * caseFold = CM_FLAG_CASEFOLD; + */ caseFold = CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD; code = cm_NameI(cm_rootSCachep, spacep->data, caseFold, userp, tidPathp, &req, &oldDscp); @@ -4517,7 +4521,7 @@ smb_Rename(smb_vc_t *vcp, smb_packet_t *inp, char * oldPathp, char * newPathp, i code = CM_ERROR_EXISTS; } - if(tmpscp != NULL) + if (tmpscp != NULL) cm_ReleaseSCache(tmpscp); cm_ReleaseSCache(newDscp); cm_ReleaseSCache(oldDscp); @@ -4545,26 +4549,26 @@ smb_Rename(smb_vc_t *vcp, smb_packet_t *inp, char * oldPathp, char * newPathp, i if (oldDscp == newDscp) { if (oldDscp->flags & CM_SCACHEFLAG_ANYWATCH) smb_NotifyChange(FILE_ACTION_RENAMED_OLD_NAME, - filter, oldDscp, oldLastNamep, - newLastNamep, TRUE); + filter, oldDscp, oldLastNamep, + newLastNamep, TRUE); } else { if (oldDscp->flags & CM_SCACHEFLAG_ANYWATCH) smb_NotifyChange(FILE_ACTION_RENAMED_OLD_NAME, - filter, oldDscp, oldLastNamep, - NULL, TRUE); + filter, oldDscp, oldLastNamep, + NULL, TRUE); if (newDscp->flags & CM_SCACHEFLAG_ANYWATCH) smb_NotifyChange(FILE_ACTION_RENAMED_NEW_NAME, - filter, newDscp, newLastNamep, - NULL, TRUE); + filter, newDscp, newLastNamep, + NULL, TRUE); } - if(tmpscp != NULL) + if (tmpscp != NULL) cm_ReleaseSCache(tmpscp); cm_ReleaseUser(userp); cm_ReleaseSCache(oldDscp); cm_ReleaseSCache(newDscp); - return code; -} + return code; +} long smb_Link(smb_vc_t *vcp, smb_packet_t *inp, char * oldPathp, char * newPathp) @@ -4651,7 +4655,7 @@ smb_Link(smb_vc_t *vcp, smb_packet_t *inp, char * oldPathp, char * newPathp) code = cm_Lookup(newDscp,newLastNamep,CM_FLAG_CHECKPATH,userp,&req,&tmpscp); if ((code != CM_ERROR_NOSUCHFILE) && (code != CM_ERROR_NOSUCHPATH) && (code != CM_ERROR_NOSUCHVOLUME) ) { osi_Log2(smb_logp, " lookup returns %ld for [%s]", code, - osi_LogSaveString(afsd_logp, newLastNamep)); + osi_LogSaveString(afsd_logp, newLastNamep)); /* if the existing link is to the same file, then we return success */ if (!code) { @@ -4716,107 +4720,107 @@ smb_ReceiveCoreRename(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) typedef struct smb_rmdirRock { - cm_scache_t *dscp; - cm_user_t *userp; - cm_req_t *reqp; - char *maskp; /* pointer to the star pattern */ - int flags; - int any; + cm_scache_t *dscp; + cm_user_t *userp; + cm_req_t *reqp; + char *maskp; /* pointer to the star pattern */ + int flags; + int any; } smb_rmdirRock_t; int smb_RmdirProc(cm_scache_t *dscp, cm_dirEntry_t *dep, void *vrockp, osi_hyper_t *offp) -{ - long code = 0; - smb_rmdirRock_t *rockp; - int match; - char shortName[13]; - char *matchName; +{ + long code = 0; + smb_rmdirRock_t *rockp; + int match; + char shortName[13]; + char *matchName; - rockp = (smb_rmdirRock_t *) vrockp; + rockp = (smb_rmdirRock_t *) vrockp; - matchName = dep->name; + matchName = dep->name; if (rockp->flags & SMB_MASKFLAG_CASEFOLD) match = (cm_stricmp(matchName, rockp->maskp) == 0); else match = (strcmp(matchName, rockp->maskp) == 0); - if (!match - && (rockp->flags & SMB_MASKFLAG_TILDE) - && !cm_Is8Dot3(dep->name)) { - cm_Gen8Dot3Name(dep, shortName, NULL); - matchName = shortName; - match = (cm_stricmp(matchName, rockp->maskp) == 0); - } - if (match) { - osi_Log1(smb_logp, "Removing directory %s", - osi_LogSaveString(smb_logp, matchName)); - code = cm_RemoveDir(dscp, dep->name, rockp->userp, rockp->reqp); - if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH)) - smb_NotifyChange(FILE_ACTION_REMOVED, - FILE_NOTIFY_CHANGE_DIR_NAME, - dscp, dep->name, NULL, TRUE); - if (code == 0) - rockp->any = 1; - } - else code = 0; - - return code; + if (!match && + (rockp->flags & SMB_MASKFLAG_TILDE) && + !cm_Is8Dot3(dep->name)) { + cm_Gen8Dot3Name(dep, shortName, NULL); + matchName = shortName; + match = (cm_stricmp(matchName, rockp->maskp) == 0); + } + if (match) { + osi_Log1(smb_logp, "Removing directory %s", + osi_LogSaveString(smb_logp, matchName)); + code = cm_RemoveDir(dscp, dep->name, rockp->userp, rockp->reqp); + if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH)) + smb_NotifyChange(FILE_ACTION_REMOVED, + FILE_NOTIFY_CHANGE_DIR_NAME, + dscp, dep->name, NULL, TRUE); + if (code == 0) + rockp->any = 1; + } + else code = 0; + + return code; } long smb_ReceiveCoreRemoveDir(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { - long code = 0; - char *pathp; - char *tp; - cm_space_t *spacep; - cm_scache_t *dscp; - char *lastNamep; - smb_rmdirRock_t rock; - cm_user_t *userp; - osi_hyper_t thyper; - int caseFold; - char *tidPathp; - cm_req_t req; + long code = 0; + char *pathp; + char *tp; + cm_space_t *spacep; + cm_scache_t *dscp; + char *lastNamep; + smb_rmdirRock_t rock; + cm_user_t *userp; + osi_hyper_t thyper; + int caseFold; + char *tidPathp; + cm_req_t req; - cm_InitReq(&req); + cm_InitReq(&req); - tp = smb_GetSMBData(inp, NULL); - pathp = smb_ParseASCIIBlock(tp, &tp); + tp = smb_GetSMBData(inp, NULL); + pathp = smb_ParseASCIIBlock(tp, &tp); - spacep = inp->spacep; - smb_StripLastComponent(spacep->data, &lastNamep, pathp); + spacep = inp->spacep; + smb_StripLastComponent(spacep->data, &lastNamep, pathp); - userp = smb_GetUser(vcp, inp); + userp = smb_GetUser(vcp, inp); - caseFold = CM_FLAG_CASEFOLD; + caseFold = CM_FLAG_CASEFOLD; - code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &tidPathp); - if(code) { + code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &tidPathp); + if (code) { cm_ReleaseUser(userp); return CM_ERROR_NOSUCHPATH; } - code = cm_NameI(cm_rootSCachep, spacep->data, caseFold | CM_FLAG_FOLLOW, - userp, tidPathp, &req, &dscp); + code = cm_NameI(cm_rootSCachep, spacep->data, caseFold | CM_FLAG_FOLLOW, + userp, tidPathp, &req, &dscp); - if (code) { - cm_ReleaseUser(userp); - return code; - } + if (code) { + cm_ReleaseUser(userp); + return code; + } - /* otherwise, scp points to the parent directory. */ - if (!lastNamep) - lastNamep = pathp; - else - lastNamep++; + /* otherwise, scp points to the parent directory. */ + if (!lastNamep) + lastNamep = pathp; + else + lastNamep++; - rock.any = 0; - rock.maskp = lastNamep; - rock.flags = ((strchr(rock.maskp, '~') != NULL) ? SMB_MASKFLAG_TILDE : 0); - - thyper.LowPart = 0; - thyper.HighPart = 0; - rock.userp = userp; - rock.reqp = &req; - rock.dscp = dscp; + rock.any = 0; + rock.maskp = lastNamep; + rock.flags = ((strchr(rock.maskp, '~') != NULL) ? SMB_MASKFLAG_TILDE : 0); + + thyper.LowPart = 0; + thyper.HighPart = 0; + rock.userp = userp; + rock.reqp = &req; + rock.dscp = dscp; /* First do a case sensitive match, and if that fails, do a case insensitive match */ code = cm_ApplyDir(dscp, smb_RmdirProc, &rock, &thyper, userp, &req, NULL); if (code == 0 && !rock.any) { @@ -4826,30 +4830,30 @@ long smb_ReceiveCoreRemoveDir(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *ou code = cm_ApplyDir(dscp, smb_RmdirProc, &rock, &thyper, userp, &req, NULL); } - cm_ReleaseUser(userp); + cm_ReleaseUser(userp); - cm_ReleaseSCache(dscp); + cm_ReleaseSCache(dscp); - if (code == 0 && !rock.any) - code = CM_ERROR_NOSUCHFILE; - return code; + if (code == 0 && !rock.any) + code = CM_ERROR_NOSUCHFILE; + return code; } long smb_ReceiveCoreFlush(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { - unsigned short fid; + unsigned short fid; smb_fid_t *fidp; cm_user_t *userp; long code = 0; cm_req_t req; - cm_InitReq(&req); + cm_InitReq(&req); + + fid = smb_GetSMBParm(inp, 0); - fid = smb_GetSMBParm(inp, 0); - - osi_Log1(smb_logp, "SMB flush fid %d", fid); + osi_Log1(smb_logp, "SMB flush fid %d", fid); - fid = smb_ChainFID(fid, inp); + fid = smb_ChainFID(fid, inp); fidp = smb_FindFID(vcp, fid, 0); if (!fidp || (fidp->flags & SMB_FID_IOCTL)) { if (fidp) @@ -4862,8 +4866,8 @@ long smb_ReceiveCoreFlush(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) lock_ObtainMutex(&fidp->mx); if (fidp->flags & SMB_FID_OPENWRITE) code = cm_FSync(fidp->scp, userp, &req); - else - code = 0; + else + code = 0; lock_ReleaseMutex(&fidp->mx); smb_ReleaseFID(fidp); @@ -4874,137 +4878,137 @@ long smb_ReceiveCoreFlush(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) } struct smb_FullNameRock { - char *name; - cm_scache_t *vnode; - char *fullName; + char *name; + cm_scache_t *vnode; + char *fullName; }; int smb_FullNameProc(cm_scache_t *scp, cm_dirEntry_t *dep, void *rockp, - osi_hyper_t *offp) + osi_hyper_t *offp) { - char shortName[13]; - struct smb_FullNameRock *vrockp; - - vrockp = (struct smb_FullNameRock *)rockp; - - if (!cm_Is8Dot3(dep->name)) { - cm_Gen8Dot3Name(dep, shortName, NULL); - - if (cm_stricmp(shortName, vrockp->name) == 0) { - vrockp->fullName = strdup(dep->name); - return CM_ERROR_STOPNOW; - } - } - if (cm_stricmp(dep->name, vrockp->name) == 0 - && ntohl(dep->fid.vnode) == vrockp->vnode->fid.vnode - && ntohl(dep->fid.unique) == vrockp->vnode->fid.unique) { - vrockp->fullName = strdup(dep->name); - return CM_ERROR_STOPNOW; - } - return 0; + char shortName[13]; + struct smb_FullNameRock *vrockp; + + vrockp = (struct smb_FullNameRock *)rockp; + + if (!cm_Is8Dot3(dep->name)) { + cm_Gen8Dot3Name(dep, shortName, NULL); + + if (cm_stricmp(shortName, vrockp->name) == 0) { + vrockp->fullName = strdup(dep->name); + return CM_ERROR_STOPNOW; + } + } + if (cm_stricmp(dep->name, vrockp->name) == 0 && + ntohl(dep->fid.vnode) == vrockp->vnode->fid.vnode && + ntohl(dep->fid.unique) == vrockp->vnode->fid.unique) { + vrockp->fullName = strdup(dep->name); + return CM_ERROR_STOPNOW; + } + return 0; } void smb_FullName(cm_scache_t *dscp, cm_scache_t *scp, char *pathp, - char **newPathp, cm_user_t *userp, cm_req_t *reqp) + char **newPathp, cm_user_t *userp, cm_req_t *reqp) { - struct smb_FullNameRock rock; - long code = 0; - - rock.name = pathp; - rock.vnode = scp; - - code = cm_ApplyDir(dscp, smb_FullNameProc, &rock, NULL, - userp, reqp, NULL); - if (code == CM_ERROR_STOPNOW) - *newPathp = rock.fullName; - else - *newPathp = strdup(pathp); + struct smb_FullNameRock rock; + long code = 0; + + rock.name = pathp; + rock.vnode = scp; + + code = cm_ApplyDir(dscp, smb_FullNameProc, &rock, NULL, + userp, reqp, NULL); + if (code == CM_ERROR_STOPNOW) + *newPathp = rock.fullName; + else + *newPathp = strdup(pathp); } long smb_ReceiveCoreClose(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { - unsigned short fid; + unsigned short fid; smb_fid_t *fidp; cm_user_t *userp; - long dosTime; + long dosTime; long code = 0; - cm_req_t req; + cm_req_t req; - cm_InitReq(&req); + cm_InitReq(&req); - fid = smb_GetSMBParm(inp, 0); - dosTime = smb_GetSMBParm(inp, 1) | (smb_GetSMBParm(inp, 2) << 16); - - osi_Log1(smb_logp, "SMB close fid %d", fid); + fid = smb_GetSMBParm(inp, 0); + dosTime = smb_GetSMBParm(inp, 1) | (smb_GetSMBParm(inp, 2) << 16); + + osi_Log1(smb_logp, "SMB close fid %d", fid); - fid = smb_ChainFID(fid, inp); + fid = smb_ChainFID(fid, inp); fidp = smb_FindFID(vcp, fid, 0); if (!fidp) { return CM_ERROR_BADFD; } - userp = smb_GetUser(vcp, inp); + userp = smb_GetUser(vcp, inp); lock_ObtainMutex(&fidp->mx); - /* Don't jump the gun on an async raw write */ - while (fidp->raw_writers) { - lock_ReleaseMutex(&fidp->mx); - thrd_WaitForSingleObject_Event(fidp->raw_write_event, RAWTIMEOUT); - lock_ObtainMutex(&fidp->mx); - } + /* Don't jump the gun on an async raw write */ + while (fidp->raw_writers) { + lock_ReleaseMutex(&fidp->mx); + thrd_WaitForSingleObject_Event(fidp->raw_write_event, RAWTIMEOUT); + lock_ObtainMutex(&fidp->mx); + } - fidp->flags |= SMB_FID_DELETE; + fidp->flags |= SMB_FID_DELETE; - /* watch for ioctl closes, and read-only opens */ - if (fidp->scp != NULL - && (fidp->flags & (SMB_FID_OPENWRITE | SMB_FID_DELONCLOSE)) + /* watch for ioctl closes, and read-only opens */ + if (fidp->scp != NULL && + (fidp->flags & (SMB_FID_OPENWRITE | SMB_FID_DELONCLOSE)) == SMB_FID_OPENWRITE) { - if (dosTime != 0 && dosTime != -1) { - fidp->scp->mask |= CM_SCACHEMASK_CLIENTMODTIME; + if (dosTime != 0 && dosTime != -1) { + fidp->scp->mask |= CM_SCACHEMASK_CLIENTMODTIME; /* This fixes defect 10958 */ CompensateForSmbClientLastWriteTimeBugs(&dosTime); - smb_UnixTimeFromDosUTime(&fidp->scp->clientModTime, dosTime); - } + smb_UnixTimeFromDosUTime(&fidp->scp->clientModTime, dosTime); + } code = cm_FSync(fidp->scp, userp, &req); - } - else + } + else code = 0; - if (fidp->flags & SMB_FID_DELONCLOSE) { - cm_scache_t *dscp = fidp->NTopen_dscp; - char *pathp = fidp->NTopen_pathp; - char *fullPathp; + if (fidp->flags & SMB_FID_DELONCLOSE) { + cm_scache_t *dscp = fidp->NTopen_dscp; + char *pathp = fidp->NTopen_pathp; + char *fullPathp; - smb_FullName(dscp, fidp->scp, pathp, &fullPathp, userp, &req); - if (fidp->scp->fileType == CM_SCACHETYPE_DIRECTORY) { - code = cm_RemoveDir(dscp, fullPathp, userp, &req); - if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH)) - smb_NotifyChange(FILE_ACTION_REMOVED, + smb_FullName(dscp, fidp->scp, pathp, &fullPathp, userp, &req); + if (fidp->scp->fileType == CM_SCACHETYPE_DIRECTORY) { + code = cm_RemoveDir(dscp, fullPathp, userp, &req); + if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH)) + smb_NotifyChange(FILE_ACTION_REMOVED, FILE_NOTIFY_CHANGE_DIR_NAME, dscp, fullPathp, NULL, TRUE); - } - else + } + else { - code = cm_Unlink(dscp, fullPathp, userp, &req); - if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH)) - smb_NotifyChange(FILE_ACTION_REMOVED, + code = cm_Unlink(dscp, fullPathp, userp, &req); + if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH)) + smb_NotifyChange(FILE_ACTION_REMOVED, FILE_NOTIFY_CHANGE_FILE_NAME, dscp, fullPathp, NULL, TRUE); - } - free(fullPathp); - } + } + free(fullPathp); + } lock_ReleaseMutex(&fidp->mx); if (fidp->flags & SMB_FID_NTOPEN) { - cm_ReleaseSCache(fidp->NTopen_dscp); - free(fidp->NTopen_pathp); - } - if (fidp->NTopen_wholepathp) - free(fidp->NTopen_wholepathp); + cm_ReleaseSCache(fidp->NTopen_dscp); + free(fidp->NTopen_pathp); + } + if (fidp->NTopen_wholepathp) + free(fidp->NTopen_wholepathp); smb_ReleaseFID(fidp); - cm_ReleaseUser(userp); + cm_ReleaseUser(userp); return code; } @@ -5019,147 +5023,147 @@ long smb_ReadData(smb_fid_t *fidp, osi_hyper_t *offsetp, long count, char *op, cm_user_t *userp, long *readp, int dosflag) #endif /* !DJGPP */ { - osi_hyper_t offset; - long code = 0; - cm_scache_t *scp; - cm_buf_t *bufferp; - osi_hyper_t fileLength; - osi_hyper_t thyper; - osi_hyper_t lastByte; - osi_hyper_t bufferOffset; - long bufIndex, nbytes; - int chunk; - int sequential = 0; - cm_req_t req; - - cm_InitReq(&req); - - bufferp = NULL; - offset = *offsetp; - - lock_ObtainMutex(&fidp->mx); - scp = fidp->scp; - lock_ObtainMutex(&scp->mx); - - if (offset.HighPart == 0) { - chunk = offset.LowPart >> cm_logChunkSize; - if (chunk != fidp->curr_chunk) { - fidp->prev_chunk = fidp->curr_chunk; - fidp->curr_chunk = chunk; - } - if (fidp->curr_chunk == fidp->prev_chunk + 1) - sequential = 1; - } - - /* start by looking up the file's end */ - code = cm_SyncOp(scp, NULL, userp, &req, 0, - CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); - if (code) goto done; - - /* now we have the entry locked, look up the length */ - fileLength = scp->length; - - /* adjust count down so that it won't go past EOF */ - thyper.LowPart = count; - thyper.HighPart = 0; - thyper = LargeIntegerAdd(offset, thyper); /* where read should end */ - lastByte = thyper; - if (LargeIntegerGreaterThan(thyper, fileLength)) { - /* we'd read past EOF, so just stop at fileLength bytes. - * Start by computing how many bytes remain in the file. - */ - thyper = LargeIntegerSubtract(fileLength, offset); - - /* if we are past EOF, read 0 bytes */ - if (LargeIntegerLessThanZero(thyper)) - count = 0; - else - count = thyper.LowPart; - } - - *readp = count; - - /* now, copy the data one buffer at a time, - * until we've filled the request packet - */ - while (1) { - /* if we've copied all the data requested, we're done */ - if (count <= 0) break; - - /* otherwise, load up a buffer of data */ - thyper.HighPart = offset.HighPart; - thyper.LowPart = offset.LowPart & ~(buf_bufferSize-1); - if (!bufferp || !LargeIntegerEqualTo(thyper, bufferOffset)) { - /* wrong buffer */ - if (bufferp) { - buf_Release(bufferp); - bufferp = NULL; - } - lock_ReleaseMutex(&scp->mx); - - lock_ObtainRead(&scp->bufCreateLock); - code = buf_Get(scp, &thyper, &bufferp); - lock_ReleaseRead(&scp->bufCreateLock); - - lock_ObtainMutex(&scp->mx); - if (code) goto done; - bufferOffset = thyper; - - /* now get the data in the cache */ - while (1) { - code = cm_SyncOp(scp, bufferp, userp, &req, 0, - CM_SCACHESYNC_NEEDCALLBACK - | CM_SCACHESYNC_READ); - if (code) goto done; + osi_hyper_t offset; + long code = 0; + cm_scache_t *scp; + cm_buf_t *bufferp; + osi_hyper_t fileLength; + osi_hyper_t thyper; + osi_hyper_t lastByte; + osi_hyper_t bufferOffset; + long bufIndex, nbytes; + int chunk; + int sequential = 0; + cm_req_t req; + + cm_InitReq(&req); + + bufferp = NULL; + offset = *offsetp; + + lock_ObtainMutex(&fidp->mx); + scp = fidp->scp; + lock_ObtainMutex(&scp->mx); + + if (offset.HighPart == 0) { + chunk = offset.LowPart >> cm_logChunkSize; + if (chunk != fidp->curr_chunk) { + fidp->prev_chunk = fidp->curr_chunk; + fidp->curr_chunk = chunk; + } + if (fidp->curr_chunk == fidp->prev_chunk + 1) + sequential = 1; + } + + /* start by looking up the file's end */ + code = cm_SyncOp(scp, NULL, userp, &req, 0, + CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); + if (code) goto done; + + /* now we have the entry locked, look up the length */ + fileLength = scp->length; + + /* adjust count down so that it won't go past EOF */ + thyper.LowPart = count; + thyper.HighPart = 0; + thyper = LargeIntegerAdd(offset, thyper); /* where read should end */ + lastByte = thyper; + if (LargeIntegerGreaterThan(thyper, fileLength)) { + /* we'd read past EOF, so just stop at fileLength bytes. + * Start by computing how many bytes remain in the file. + */ + thyper = LargeIntegerSubtract(fileLength, offset); + + /* if we are past EOF, read 0 bytes */ + if (LargeIntegerLessThanZero(thyper)) + count = 0; + else + count = thyper.LowPart; + } + + *readp = count; + + /* now, copy the data one buffer at a time, + * until we've filled the request packet + */ + while (1) { + /* if we've copied all the data requested, we're done */ + if (count <= 0) break; + + /* otherwise, load up a buffer of data */ + thyper.HighPart = offset.HighPart; + thyper.LowPart = offset.LowPart & ~(buf_bufferSize-1); + if (!bufferp || !LargeIntegerEqualTo(thyper, bufferOffset)) { + /* wrong buffer */ + if (bufferp) { + buf_Release(bufferp); + bufferp = NULL; + } + lock_ReleaseMutex(&scp->mx); + + lock_ObtainRead(&scp->bufCreateLock); + code = buf_Get(scp, &thyper, &bufferp); + lock_ReleaseRead(&scp->bufCreateLock); + + lock_ObtainMutex(&scp->mx); + if (code) goto done; + bufferOffset = thyper; + + /* now get the data in the cache */ + while (1) { + code = cm_SyncOp(scp, bufferp, userp, &req, 0, + CM_SCACHESYNC_NEEDCALLBACK | + CM_SCACHESYNC_READ); + if (code) goto done; - if (cm_HaveBuffer(scp, bufferp, 0)) break; - - /* otherwise, load the buffer and try again */ - code = cm_GetBuffer(scp, bufferp, NULL, userp, &req); - if (code) break; - } - if (code) { - buf_Release(bufferp); - bufferp = NULL; - goto done; - } - } /* if (wrong buffer) ... */ - - /* now we have the right buffer loaded. Copy out the - * data from here to the user's buffer. - */ - bufIndex = offset.LowPart & (buf_bufferSize - 1); - - /* and figure out how many bytes we want from this buffer */ - nbytes = buf_bufferSize - bufIndex; /* what remains in buffer */ - if (nbytes > count) nbytes = count; /* don't go past EOF */ - - /* now copy the data */ + if (cm_HaveBuffer(scp, bufferp, 0)) break; + + /* otherwise, load the buffer and try again */ + code = cm_GetBuffer(scp, bufferp, NULL, userp, &req); + if (code) break; + } + if (code) { + buf_Release(bufferp); + bufferp = NULL; + goto done; + } + } /* if (wrong buffer) ... */ + + /* now we have the right buffer loaded. Copy out the + * data from here to the user's buffer. + */ + bufIndex = offset.LowPart & (buf_bufferSize - 1); + + /* and figure out how many bytes we want from this buffer */ + nbytes = buf_bufferSize - bufIndex; /* what remains in buffer */ + if (nbytes > count) nbytes = count; /* don't go past EOF */ + + /* now copy the data */ #ifdef DJGPP - if (dosflag) - dosmemput(bufferp->datap + bufIndex, nbytes, (dos_ptr)op); - else + if (dosflag) + dosmemput(bufferp->datap + bufIndex, nbytes, (dos_ptr)op); + else #endif /* DJGPP */ - memcpy(op, bufferp->datap + bufIndex, nbytes); + memcpy(op, bufferp->datap + bufIndex, nbytes); - /* adjust counters, pointers, etc. */ - op += nbytes; - count -= nbytes; - thyper.LowPart = nbytes; - thyper.HighPart = 0; - offset = LargeIntegerAdd(thyper, offset); - } /* while 1 */ + /* adjust counters, pointers, etc. */ + op += nbytes; + count -= nbytes; + thyper.LowPart = nbytes; + thyper.HighPart = 0; + offset = LargeIntegerAdd(thyper, offset); + } /* while 1 */ done: - lock_ReleaseMutex(&scp->mx); - lock_ReleaseMutex(&fidp->mx); - if (bufferp) - buf_Release(bufferp); + lock_ReleaseMutex(&scp->mx); + lock_ReleaseMutex(&fidp->mx); + if (bufferp) + buf_Release(bufferp); - if (code == 0 && sequential) - cm_ConsiderPrefetch(scp, &lastByte, userp, &req); + if (code == 0 && sequential) + cm_ConsiderPrefetch(scp, &lastByte, userp, &req); - return code; + return code; } /* @@ -5173,253 +5177,255 @@ long smb_WriteData(smb_fid_t *fidp, osi_hyper_t *offsetp, long count, char *op, cm_user_t *userp, long *writtenp, int dosflag) #endif /* !DJGPP */ { - osi_hyper_t offset; - long code = 0; - long written = 0; - cm_scache_t *scp; - osi_hyper_t fileLength; /* file's length at start of write */ - osi_hyper_t minLength; /* don't read past this */ - long nbytes; /* # of bytes to transfer this iteration */ - cm_buf_t *bufferp; - osi_hyper_t thyper; /* hyper tmp variable */ - osi_hyper_t bufferOffset; - long bufIndex; /* index in buffer where our data is */ - int doWriteBack; - osi_hyper_t writeBackOffset; /* offset of region to write back when - * I/O is done */ - DWORD filter = 0; - cm_req_t req; + osi_hyper_t offset; + long code = 0; + long written = 0; + cm_scache_t *scp; + osi_hyper_t fileLength; /* file's length at start of write */ + osi_hyper_t minLength; /* don't read past this */ + long nbytes; /* # of bytes to transfer this iteration */ + cm_buf_t *bufferp; + osi_hyper_t thyper; /* hyper tmp variable */ + osi_hyper_t bufferOffset; + long bufIndex; /* index in buffer where our data is */ + int doWriteBack; + osi_hyper_t writeBackOffset;/* offset of region to write back when + * I/O is done */ + DWORD filter = 0; + cm_req_t req; osi_Log3(smb_logp, "smb_WriteData fid %d, off 0x%x, size 0x%x", fidp->fid, offsetp->LowPart, count); - cm_InitReq(&req); + *writtenp = 0; + + cm_InitReq(&req); - bufferp = NULL; - doWriteBack = 0; - offset = *offsetp; + bufferp = NULL; + doWriteBack = 0; + offset = *offsetp; - lock_ObtainMutex(&fidp->mx); - scp = fidp->scp; - lock_ObtainMutex(&scp->mx); + lock_ObtainMutex(&fidp->mx); + scp = fidp->scp; + lock_ObtainMutex(&scp->mx); - /* start by looking up the file's end */ + /* start by looking up the file's end */ osi_Log1(smb_logp, "smb_WriteData fid %d calling cm_SyncOp NEEDCALLBACK|SETSTATUS|GETSTATUS", fidp->fid); - code = cm_SyncOp(scp, NULL, userp, &req, 0, - CM_SCACHESYNC_NEEDCALLBACK - | CM_SCACHESYNC_SETSTATUS - | CM_SCACHESYNC_GETSTATUS); + code = cm_SyncOp(scp, NULL, userp, &req, 0, + CM_SCACHESYNC_NEEDCALLBACK + | CM_SCACHESYNC_SETSTATUS + | CM_SCACHESYNC_GETSTATUS); osi_Log2(smb_logp, "smb_WriteData fid %d calling cm_SyncOp NEEDCALLBACK|SETSTATUS|GETSTATUS returns %d", fidp->fid,code); - if (code) - goto done; - - /* make sure we have a writable FD */ - if (!(fidp->flags & SMB_FID_OPENWRITE)) { - code = CM_ERROR_BADFDOP; - goto done; - } - - /* now we have the entry locked, look up the length */ - fileLength = scp->length; - minLength = fileLength; - if (LargeIntegerGreaterThan(minLength, scp->serverLength)) - minLength = scp->serverLength; - - /* adjust file length if we extend past EOF */ - thyper.LowPart = count; - thyper.HighPart = 0; - thyper = LargeIntegerAdd(offset, thyper); /* where write should end */ - if (LargeIntegerGreaterThan(thyper, fileLength)) { - /* we'd write past EOF, so extend the file */ - scp->mask |= CM_SCACHEMASK_LENGTH; - scp->length = thyper; - filter |= (FILE_NOTIFY_CHANGE_LAST_WRITE | FILE_NOTIFY_CHANGE_SIZE); - } else - filter |= FILE_NOTIFY_CHANGE_LAST_WRITE; + if (code) + goto done; - /* now, if the new position (thyper) and the old (offset) are in - * different storeback windows, remember to store back the previous - * storeback window when we're done with the write. - */ - if ((thyper.LowPart & (-cm_chunkSize)) != - (offset.LowPart & (-cm_chunkSize))) { - /* they're different */ - doWriteBack = 1; - writeBackOffset.HighPart = offset.HighPart; - writeBackOffset.LowPart = offset.LowPart & (-cm_chunkSize); - } + /* make sure we have a writable FD */ + if (!(fidp->flags & SMB_FID_OPENWRITE)) { + code = CM_ERROR_BADFDOP; + goto done; + } + + /* now we have the entry locked, look up the length */ + fileLength = scp->length; + minLength = fileLength; + if (LargeIntegerGreaterThan(minLength, scp->serverLength)) + minLength = scp->serverLength; + + /* adjust file length if we extend past EOF */ + thyper.LowPart = count; + thyper.HighPart = 0; + thyper = LargeIntegerAdd(offset, thyper); /* where write should end */ + if (LargeIntegerGreaterThan(thyper, fileLength)) { + /* we'd write past EOF, so extend the file */ + scp->mask |= CM_SCACHEMASK_LENGTH; + scp->length = thyper; + filter |= (FILE_NOTIFY_CHANGE_LAST_WRITE | FILE_NOTIFY_CHANGE_SIZE); + } else + filter |= FILE_NOTIFY_CHANGE_LAST_WRITE; + + /* now, if the new position (thyper) and the old (offset) are in + * different storeback windows, remember to store back the previous + * storeback window when we're done with the write. + */ + if ((thyper.LowPart & (-cm_chunkSize)) != + (offset.LowPart & (-cm_chunkSize))) { + /* they're different */ + doWriteBack = 1; + writeBackOffset.HighPart = offset.HighPart; + writeBackOffset.LowPart = offset.LowPart & (-cm_chunkSize); + } - *writtenp = count; - - /* now, copy the data one buffer at a time, until we've filled the - * request packet */ - while (1) { - /* if we've copied all the data requested, we're done */ - if (count <= 0) break; - - /* handle over quota or out of space */ - if (scp->flags & (CM_SCACHEFLAG_OVERQUOTA | CM_SCACHEFLAG_OUTOFSPACE)) { - *writtenp = written; - break; - } - - /* otherwise, load up a buffer of data */ - thyper.HighPart = offset.HighPart; - thyper.LowPart = offset.LowPart & ~(buf_bufferSize-1); - if (!bufferp || !LargeIntegerEqualTo(thyper, bufferOffset)) { - /* wrong buffer */ - if (bufferp) { - lock_ReleaseMutex(&bufferp->mx); - buf_Release(bufferp); - bufferp = NULL; - } - lock_ReleaseMutex(&scp->mx); - - lock_ObtainRead(&scp->bufCreateLock); - code = buf_Get(scp, &thyper, &bufferp); - lock_ReleaseRead(&scp->bufCreateLock); - - lock_ObtainMutex(&bufferp->mx); - lock_ObtainMutex(&scp->mx); - if (code) goto done; - - bufferOffset = thyper; - - /* now get the data in the cache */ - while (1) { + *writtenp = count; + + /* now, copy the data one buffer at a time, until we've filled the + * request packet */ + while (1) { + /* if we've copied all the data requested, we're done */ + if (count <= 0) + break; + + /* handle over quota or out of space */ + if (scp->flags & (CM_SCACHEFLAG_OVERQUOTA | CM_SCACHEFLAG_OUTOFSPACE)) { + *writtenp = written; + code = CM_ERROR_QUOTA; + break; + } + + /* otherwise, load up a buffer of data */ + thyper.HighPart = offset.HighPart; + thyper.LowPart = offset.LowPart & ~(buf_bufferSize-1); + if (!bufferp || !LargeIntegerEqualTo(thyper, bufferOffset)) { + /* wrong buffer */ + if (bufferp) { + lock_ReleaseMutex(&bufferp->mx); + buf_Release(bufferp); + bufferp = NULL; + } + lock_ReleaseMutex(&scp->mx); + + lock_ObtainRead(&scp->bufCreateLock); + code = buf_Get(scp, &thyper, &bufferp); + lock_ReleaseRead(&scp->bufCreateLock); + + lock_ObtainMutex(&bufferp->mx); + lock_ObtainMutex(&scp->mx); + if (code) goto done; + + bufferOffset = thyper; + + /* now get the data in the cache */ + while (1) { osi_Log1(smb_logp, "smb_WriteData fid %d calling cm_SyncOp NEEDCALLBACK|WRITE|BUFLOCKED", fidp->fid); - code = cm_SyncOp(scp, bufferp, userp, &req, 0, - CM_SCACHESYNC_NEEDCALLBACK - | CM_SCACHESYNC_WRITE - | CM_SCACHESYNC_BUFLOCKED); + code = cm_SyncOp(scp, bufferp, userp, &req, 0, + CM_SCACHESYNC_NEEDCALLBACK + | CM_SCACHESYNC_WRITE + | CM_SCACHESYNC_BUFLOCKED); osi_Log2(smb_logp, "smb_WriteData fid %d calling cm_SyncOp NEEDCALLBACK|WRITE|BUFLOCKED returns %d", fidp->fid,code); - if (code) - goto done; - - /* If we're overwriting the entire buffer, or - * if we're writing at or past EOF, mark the - * buffer as current so we don't call - * cm_GetBuffer. This skips the fetch from the - * server in those cases where we're going to - * obliterate all the data in the buffer anyway, - * or in those cases where there is no useful - * data at the server to start with. - * - * Use minLength instead of scp->length, since - * the latter has already been updated by this - * call. - */ - if (LargeIntegerGreaterThanOrEqualTo( - bufferp->offset, minLength) - || LargeIntegerEqualTo(offset, bufferp->offset) - && (count >= buf_bufferSize - || LargeIntegerGreaterThanOrEqualTo( - LargeIntegerAdd(offset, - ConvertLongToLargeInteger(count)), - minLength))) { - if (count < buf_bufferSize - && bufferp->dataVersion == -1) - memset(bufferp->datap, 0, - buf_bufferSize); - bufferp->dataVersion = scp->dataVersion; - } - - if (cm_HaveBuffer(scp, bufferp, 1)) break; - - /* otherwise, load the buffer and try again */ - lock_ReleaseMutex(&bufferp->mx); - code = cm_GetBuffer(scp, bufferp, NULL, userp, - &req); - lock_ReleaseMutex(&scp->mx); - lock_ObtainMutex(&bufferp->mx); - lock_ObtainMutex(&scp->mx); - if (code) break; - } - if (code) { - lock_ReleaseMutex(&bufferp->mx); - buf_Release(bufferp); - bufferp = NULL; - goto done; - } - } /* if (wrong buffer) ... */ - - /* now we have the right buffer loaded. Copy out the - * data from here to the user's buffer. - */ - bufIndex = offset.LowPart & (buf_bufferSize - 1); - - /* and figure out how many bytes we want from this buffer */ - nbytes = buf_bufferSize - bufIndex; /* what remains in buffer */ - if (nbytes > count) - nbytes = count; /* don't go past end of request */ - - /* now copy the data */ + if (code) + goto done; + + /* If we're overwriting the entire buffer, or + * if we're writing at or past EOF, mark the + * buffer as current so we don't call + * cm_GetBuffer. This skips the fetch from the + * server in those cases where we're going to + * obliterate all the data in the buffer anyway, + * or in those cases where there is no useful + * data at the server to start with. + * + * Use minLength instead of scp->length, since + * the latter has already been updated by this + * call. + */ + if (LargeIntegerGreaterThanOrEqualTo(bufferp->offset, minLength) + || LargeIntegerEqualTo(offset, bufferp->offset) + && (count >= buf_bufferSize + || LargeIntegerGreaterThanOrEqualTo(LargeIntegerAdd(offset, + ConvertLongToLargeInteger(count)), + minLength))) { + if (count < buf_bufferSize + && bufferp->dataVersion == -1) + memset(bufferp->datap, 0, + buf_bufferSize); + bufferp->dataVersion = scp->dataVersion; + } + + if (cm_HaveBuffer(scp, bufferp, 1)) break; + + /* otherwise, load the buffer and try again */ + lock_ReleaseMutex(&bufferp->mx); + code = cm_GetBuffer(scp, bufferp, NULL, userp, + &req); + lock_ReleaseMutex(&scp->mx); + lock_ObtainMutex(&bufferp->mx); + lock_ObtainMutex(&scp->mx); + if (code) break; + } + if (code) { + lock_ReleaseMutex(&bufferp->mx); + buf_Release(bufferp); + bufferp = NULL; + goto done; + } + } /* if (wrong buffer) ... */ + + /* now we have the right buffer loaded. Copy out the + * data from here to the user's buffer. + */ + bufIndex = offset.LowPart & (buf_bufferSize - 1); + + /* and figure out how many bytes we want from this buffer */ + nbytes = buf_bufferSize - bufIndex; /* what remains in buffer */ + if (nbytes > count) + nbytes = count; /* don't go past end of request */ + + /* now copy the data */ #ifdef DJGPP - if (dosflag) - dosmemget((dos_ptr)op, nbytes, bufferp->datap + bufIndex); - else + if (dosflag) + dosmemget((dos_ptr)op, nbytes, bufferp->datap + bufIndex); + else #endif /* DJGPP */ - memcpy(bufferp->datap + bufIndex, op, nbytes); - buf_SetDirty(bufferp); + memcpy(bufferp->datap + bufIndex, op, nbytes); + buf_SetDirty(bufferp); - /* and record the last writer */ - if (bufferp->userp != userp) { - cm_HoldUser(userp); - if (bufferp->userp) + /* and record the last writer */ + if (bufferp->userp != userp) { + cm_HoldUser(userp); + if (bufferp->userp) cm_ReleaseUser(bufferp->userp); - bufferp->userp = userp; - } - - /* adjust counters, pointers, etc. */ - op += nbytes; - count -= nbytes; - written += nbytes; - thyper.LowPart = nbytes; - thyper.HighPart = 0; - offset = LargeIntegerAdd(thyper, offset); - } /* while 1 */ + bufferp->userp = userp; + } + + /* adjust counters, pointers, etc. */ + op += nbytes; + count -= nbytes; + written += nbytes; + thyper.LowPart = nbytes; + thyper.HighPart = 0; + offset = LargeIntegerAdd(thyper, offset); + } /* while 1 */ done: - lock_ReleaseMutex(&scp->mx); - lock_ReleaseMutex(&fidp->mx); - if (bufferp) { - lock_ReleaseMutex(&bufferp->mx); - buf_Release(bufferp); - } - - if (code == 0 && filter != 0 && (fidp->flags & SMB_FID_NTOPEN) - && (fidp->NTopen_dscp->flags & CM_SCACHEFLAG_ANYWATCH)) { - smb_NotifyChange(FILE_ACTION_MODIFIED, filter, - fidp->NTopen_dscp, fidp->NTopen_pathp, - NULL, TRUE); - } - - if (code == 0 && doWriteBack) { + lock_ReleaseMutex(&scp->mx); + lock_ReleaseMutex(&fidp->mx); + if (bufferp) { + lock_ReleaseMutex(&bufferp->mx); + buf_Release(bufferp); + } + + if (code == 0 && filter != 0 && (fidp->flags & SMB_FID_NTOPEN) + && (fidp->NTopen_dscp->flags & CM_SCACHEFLAG_ANYWATCH)) { + smb_NotifyChange(FILE_ACTION_MODIFIED, filter, + fidp->NTopen_dscp, fidp->NTopen_pathp, + NULL, TRUE); + } + + if (code == 0 && doWriteBack) { long code2; - lock_ObtainMutex(&scp->mx); + lock_ObtainMutex(&scp->mx); osi_Log1(smb_logp, "smb_WriteData fid %d calling cm_SyncOp ASYNCSTORE", fidp->fid); - code2 = cm_SyncOp(scp, NULL, userp, &req, 0, CM_SCACHESYNC_ASYNCSTORE); + code2 = cm_SyncOp(scp, NULL, userp, &req, 0, CM_SCACHESYNC_ASYNCSTORE); osi_Log2(smb_logp, "smb_WriteData fid %d calling cm_SyncOp ASYNCSTORE returns %d", fidp->fid,code2); - lock_ReleaseMutex(&scp->mx); - cm_QueueBKGRequest(scp, cm_BkgStore, writeBackOffset.LowPart, - writeBackOffset.HighPart, cm_chunkSize, 0, userp); - } - - osi_Log2(smb_logp, "smb_WriteData fid %d returns %d", - fidp->fid, code); - return code; + lock_ReleaseMutex(&scp->mx); + cm_QueueBKGRequest(scp, cm_BkgStore, writeBackOffset.LowPart, + writeBackOffset.HighPart, cm_chunkSize, 0, userp); + } + + osi_Log2(smb_logp, "smb_WriteData fid %d returns %d written %d", + fidp->fid, code, *writtenp); + return code; } long smb_ReceiveCoreWrite(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { - osi_hyper_t offset; - long count, written = 0; + osi_hyper_t offset; + long count, written = 0, total_written = 0; unsigned short fd; smb_fid_t *fidp; long code = 0; @@ -5434,267 +5440,283 @@ long smb_ReceiveCoreWrite(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) offset.LowPart = smb_GetSMBParm(inp, 2) | (smb_GetSMBParm(inp, 3) << 16); op = smb_GetSMBData(inp, NULL); - op = smb_ParseDataBlock(op, NULL, &inDataBlockCount); + op = smb_ParseDataBlock(op, NULL, &inDataBlockCount); osi_Log3(smb_logp, "smb_ReceiveCoreWrite fid %d, off 0x%x, size 0x%x", fd, offset.LowPart, count); - fd = smb_ChainFID(fd, inp); + fd = smb_ChainFID(fd, inp); fidp = smb_FindFID(vcp, fd, 0); if (!fidp) { - return CM_ERROR_BADFD; + return CM_ERROR_BADFD; } if (fidp->flags & SMB_FID_IOCTL) return smb_IoctlWrite(fidp, vcp, inp, outp); - userp = smb_GetUser(vcp, inp); + userp = smb_GetUser(vcp, inp); /* special case: 0 bytes transferred means truncate to this position */ if (count == 0) { - cm_req_t req; + cm_req_t req; - cm_InitReq(&req); + cm_InitReq(&req); - truncAttr.mask = CM_ATTRMASK_LENGTH; + truncAttr.mask = CM_ATTRMASK_LENGTH; truncAttr.length.LowPart = offset.LowPart; truncAttr.length.HighPart = 0; - lock_ObtainMutex(&fidp->mx); + lock_ObtainMutex(&fidp->mx); code = cm_SetAttr(fidp->scp, &truncAttr, userp, &req); - lock_ReleaseMutex(&fidp->mx); - smb_SetSMBParm(outp, 0, /* count */ 0); + lock_ReleaseMutex(&fidp->mx); + smb_SetSMBParm(outp, 0, /* count */ 0); smb_SetSMBDataLength(outp, 0); - fidp->flags |= SMB_FID_LENGTHSETDONE; + fidp->flags |= SMB_FID_LENGTHSETDONE; goto done; } - /* - * Work around bug in NT client - * - * When copying a file, the NT client should first copy the data, - * then copy the last write time. But sometimes the NT client does - * these in the wrong order, so the data copies would inadvertently - * cause the last write time to be overwritten. We try to detect this, - * and don't set client mod time if we think that would go against the - * intention. - */ - if ((fidp->flags & SMB_FID_MTIMESETDONE) != SMB_FID_MTIMESETDONE) { - fidp->scp->mask |= CM_SCACHEMASK_CLIENTMODTIME; - fidp->scp->clientModTime = time(NULL); - } + /* + * Work around bug in NT client + * + * When copying a file, the NT client should first copy the data, + * then copy the last write time. But sometimes the NT client does + * these in the wrong order, so the data copies would inadvertently + * cause the last write time to be overwritten. We try to detect this, + * and don't set client mod time if we think that would go against the + * intention. + */ + if ((fidp->flags & SMB_FID_MTIMESETDONE) != SMB_FID_MTIMESETDONE) { + fidp->scp->mask |= CM_SCACHEMASK_CLIENTMODTIME; + fidp->scp->clientModTime = time(NULL); + } + code = 0; + while ( code == 0 && count > 0 ) { #ifndef DJGPP code = smb_WriteData(fidp, &offset, count, op, userp, &written); #else /* DJGPP */ code = smb_WriteData(fidp, &offset, count, op, userp, &written, FALSE); #endif /* !DJGPP */ - if (code == 0 && written < count) - code = CM_ERROR_PARTIALWRITE; + if (code == 0 && written == 0) + code = CM_ERROR_PARTIALWRITE; - /* set the packet data length to 3 bytes for the data block header, + offset.LowPart += written; + count -= written; + total_written += written; + written = 0; + } + + /* set the packet data length to 3 bytes for the data block header, * plus the size of the data. */ - smb_SetSMBParm(outp, 0, written); + smb_SetSMBParm(outp, 0, total_written); smb_SetSMBDataLength(outp, 0); done: smb_ReleaseFID(fidp); cm_ReleaseUser(userp); - return code; + return code; } void smb_CompleteWriteRaw(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp, - NCB *ncbp, raw_write_cont_t *rwcp) + NCB *ncbp, raw_write_cont_t *rwcp) { - unsigned short fd; - smb_fid_t *fidp; - cm_user_t *userp; + unsigned short fd; + smb_fid_t *fidp; + cm_user_t *userp; #ifndef DJGPP - char *rawBuf; + char *rawBuf; #else /* DJGPP */ - dos_ptr rawBuf; + dos_ptr rawBuf; #endif /* !DJGPP */ - long written = 0; - long code = 0; + long written = 0; + long code = 0; - fd = smb_GetSMBParm(inp, 0); - fidp = smb_FindFID(vcp, fd, 0); + fd = smb_GetSMBParm(inp, 0); + fidp = smb_FindFID(vcp, fd, 0); - osi_Log2(smb_logp, "Completing Raw Write offset %x count %x", - rwcp->offset.LowPart, rwcp->count); + osi_Log2(smb_logp, "Completing Raw Write offset %x count %x", + rwcp->offset.LowPart, rwcp->count); - userp = smb_GetUser(vcp, inp); + userp = smb_GetUser(vcp, inp); #ifndef DJGPP - rawBuf = rwcp->buf; - code = smb_WriteData(fidp, &rwcp->offset, rwcp->count, rawBuf, userp, + rawBuf = rwcp->buf; + code = smb_WriteData(fidp, &rwcp->offset, rwcp->count, rawBuf, userp, &written); #else /* DJGPP */ - rawBuf = (dos_ptr) rwcp->buf; - code = smb_WriteData(fidp, &rwcp->offset, rwcp->count, + rawBuf = (dos_ptr) rwcp->buf; + code = smb_WriteData(fidp, &rwcp->offset, rwcp->count, (unsigned char *) rawBuf, userp, &written, TRUE); #endif /* !DJGPP */ - if (rwcp->writeMode & 0x1) { /* synchronous */ - smb_t *op; - - smb_FormatResponsePacket(vcp, inp, outp); - op = (smb_t *) outp; - op->com = 0x20; /* SMB_COM_WRITE_COMPLETE */ - smb_SetSMBParm(outp, 0, written + rwcp->alreadyWritten); - smb_SetSMBDataLength(outp, 0); - smb_SendPacket(vcp, outp); - smb_FreePacket(outp); - } - else { /* asynchronous */ - lock_ObtainMutex(&fidp->mx); - fidp->raw_writers--; - if (fidp->raw_writers == 0) - thrd_SetEvent(fidp->raw_write_event); - lock_ReleaseMutex(&fidp->mx); - } - - /* Give back raw buffer */ - lock_ObtainMutex(&smb_RawBufLock); + if (rwcp->writeMode & 0x1) { /* synchronous */ + smb_t *op; + + smb_FormatResponsePacket(vcp, inp, outp); + op = (smb_t *) outp; + op->com = 0x20; /* SMB_COM_WRITE_COMPLETE */ + smb_SetSMBParm(outp, 0, written + rwcp->alreadyWritten); + smb_SetSMBDataLength(outp, 0); + smb_SendPacket(vcp, outp); + smb_FreePacket(outp); + } + else { /* asynchronous */ + lock_ObtainMutex(&fidp->mx); + fidp->raw_writers--; + if (fidp->raw_writers == 0) + thrd_SetEvent(fidp->raw_write_event); + lock_ReleaseMutex(&fidp->mx); + } + + /* Give back raw buffer */ + lock_ObtainMutex(&smb_RawBufLock); #ifndef DJGPP - *((char **)rawBuf) = smb_RawBufs; + *((char **)rawBuf) = smb_RawBufs; #else /* DJGPP */ _farpokel(_dos_ds, rawBuf, smb_RawBufs); #endif /* !DJGPP */ - smb_RawBufs = rawBuf; - lock_ReleaseMutex(&smb_RawBufLock); + smb_RawBufs = rawBuf; + lock_ReleaseMutex(&smb_RawBufLock); - smb_ReleaseFID(fidp); - cm_ReleaseUser(userp); + smb_ReleaseFID(fidp); + cm_ReleaseUser(userp); } long smb_ReceiveCoreWriteRawDummy(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { - return 0; + return 0; } long smb_ReceiveCoreWriteRaw(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp, raw_write_cont_t *rwcp) { - osi_hyper_t offset; - long count, written = 0; - long totalCount; + osi_hyper_t offset; + long count, written = 0, total_written = 0; + long totalCount; unsigned short fd; smb_fid_t *fidp; long code = 0; cm_user_t *userp; char *op; - unsigned short writeMode; + unsigned short writeMode; #ifndef DJGPP - char *rawBuf; + char *rawBuf; #else /* DJGPP */ dos_ptr rawBuf; #endif /* !DJGPP */ fd = smb_GetSMBParm(inp, 0); - totalCount = smb_GetSMBParm(inp, 1); + totalCount = smb_GetSMBParm(inp, 1); count = smb_GetSMBParm(inp, 10); offset.HighPart = 0; /* too bad */ offset.LowPart = smb_GetSMBParm(inp, 3) | (smb_GetSMBParm(inp, 4) << 16); - writeMode = smb_GetSMBParm(inp, 7); + writeMode = smb_GetSMBParm(inp, 7); - op = (char *) inp->data; - op += smb_GetSMBParm(inp, 11); + op = (char *) inp->data; + op += smb_GetSMBParm(inp, 11); osi_Log4(smb_logp, "smb_ReceiveCoreWriteRaw fd %d, off 0x%x, size 0x%x, WriteMode 0x%x", fd, offset.LowPart, count, writeMode); - fd = smb_ChainFID(fd, inp); + fd = smb_ChainFID(fd, inp); fidp = smb_FindFID(vcp, fd, 0); if (!fidp) { - return CM_ERROR_BADFD; + return CM_ERROR_BADFD; } - userp = smb_GetUser(vcp, inp); - - /* - * Work around bug in NT client - * - * When copying a file, the NT client should first copy the data, - * then copy the last write time. But sometimes the NT client does - * these in the wrong order, so the data copies would inadvertently - * cause the last write time to be overwritten. We try to detect this, - * and don't set client mod time if we think that would go against the - * intention. - */ - if ((fidp->flags & SMB_FID_LOOKSLIKECOPY) != SMB_FID_LOOKSLIKECOPY) { - fidp->scp->mask |= CM_SCACHEMASK_CLIENTMODTIME; - fidp->scp->clientModTime = time(NULL); - } + userp = smb_GetUser(vcp, inp); + + /* + * Work around bug in NT client + * + * When copying a file, the NT client should first copy the data, + * then copy the last write time. But sometimes the NT client does + * these in the wrong order, so the data copies would inadvertently + * cause the last write time to be overwritten. We try to detect this, + * and don't set client mod time if we think that would go against the + * intention. + */ + if ((fidp->flags & SMB_FID_LOOKSLIKECOPY) != SMB_FID_LOOKSLIKECOPY) { + fidp->scp->mask |= CM_SCACHEMASK_CLIENTMODTIME; + fidp->scp->clientModTime = time(NULL); + } + code = 0; + while ( code == 0 && count > 0 ) { #ifndef DJGPP code = smb_WriteData(fidp, &offset, count, op, userp, &written); #else /* DJGPP */ code = smb_WriteData(fidp, &offset, count, op, userp, &written, FALSE); #endif /* !DJGPP */ - if (code == 0 && written < count) - code = CM_ERROR_PARTIALWRITE; - - /* Get a raw buffer */ - if (code == 0) { - rawBuf = NULL; - lock_ObtainMutex(&smb_RawBufLock); - if (smb_RawBufs) { - /* Get a raw buf, from head of list */ - rawBuf = smb_RawBufs; + if (code == 0 && written == 0) + code = CM_ERROR_PARTIALWRITE; + + offset.LowPart += written; + count -= written; + total_written += written; + written = 0; + } + + /* Get a raw buffer */ + if (code == 0) { + rawBuf = NULL; + lock_ObtainMutex(&smb_RawBufLock); + if (smb_RawBufs) { + /* Get a raw buf, from head of list */ + rawBuf = smb_RawBufs; #ifndef DJGPP - smb_RawBufs = *(char **)smb_RawBufs; + smb_RawBufs = *(char **)smb_RawBufs; #else /* DJGPP */ smb_RawBufs = _farpeekl(_dos_ds, smb_RawBufs); #endif /* !DJGPP */ - } - else - code = CM_ERROR_USESTD; + } + else + code = CM_ERROR_USESTD; lock_ReleaseMutex(&smb_RawBufLock); - } - - /* Don't allow a premature Close */ - if (code == 0 && (writeMode & 1) == 0) { - lock_ObtainMutex(&fidp->mx); - fidp->raw_writers++; - thrd_ResetEvent(fidp->raw_write_event); - lock_ReleaseMutex(&fidp->mx); - } - - smb_ReleaseFID(fidp); - cm_ReleaseUser(userp); - - if (code) { - smb_SetSMBParm(outp, 0, written); - smb_SetSMBDataLength(outp, 0); - ((smb_t *)outp)->com = 0x20; /* SMB_COM_WRITE_COMPLETE */ - rwcp->code = code; - return code; - } - - rwcp->code = 0; - rwcp->buf = rawBuf; - rwcp->offset.HighPart = 0; - rwcp->offset.LowPart = offset.LowPart + count; - rwcp->count = totalCount - count; - rwcp->writeMode = writeMode; - rwcp->alreadyWritten = written; - - /* set the packet data length to 3 bytes for the data block header, + } + + /* Don't allow a premature Close */ + if (code == 0 && (writeMode & 1) == 0) { + lock_ObtainMutex(&fidp->mx); + fidp->raw_writers++; + thrd_ResetEvent(fidp->raw_write_event); + lock_ReleaseMutex(&fidp->mx); + } + + smb_ReleaseFID(fidp); + cm_ReleaseUser(userp); + + if (code) { + smb_SetSMBParm(outp, 0, total_written); + smb_SetSMBDataLength(outp, 0); + ((smb_t *)outp)->com = 0x20; /* SMB_COM_WRITE_COMPLETE */ + rwcp->code = code; + return code; + } + + rwcp->code = 0; + rwcp->buf = rawBuf; + rwcp->offset.HighPart = 0; + rwcp->offset.LowPart = offset.LowPart + count; + rwcp->count = totalCount - count; + rwcp->writeMode = writeMode; + rwcp->alreadyWritten = total_written; + + /* set the packet data length to 3 bytes for the data block header, * plus the size of the data. */ - smb_SetSMBParm(outp, 0, 0xffff); + smb_SetSMBParm(outp, 0, 0xffff); smb_SetSMBDataLength(outp, 0); - return 0; + return 0; } long smb_ReceiveCoreRead(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { - osi_hyper_t offset; + osi_hyper_t offset; long count, finalCount; unsigned short fd; smb_fid_t *fidp; @@ -5710,49 +5732,49 @@ long smb_ReceiveCoreRead(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) osi_Log3(smb_logp, "smb_ReceiveCoreRead fd %d, off 0x%x, size 0x%x", fd, offset.LowPart, count); - fd = smb_ChainFID(fd, inp); + fd = smb_ChainFID(fd, inp); fidp = smb_FindFID(vcp, fd, 0); if (!fidp) { - return CM_ERROR_BADFD; + return CM_ERROR_BADFD; } if (fidp->flags & SMB_FID_IOCTL) { - return smb_IoctlRead(fidp, vcp, inp, outp); + return smb_IoctlRead(fidp, vcp, inp, outp); } - userp = smb_GetUser(vcp, inp); + userp = smb_GetUser(vcp, inp); - /* remember this for final results */ + /* remember this for final results */ smb_SetSMBParm(outp, 0, count); smb_SetSMBParm(outp, 1, 0); smb_SetSMBParm(outp, 2, 0); smb_SetSMBParm(outp, 3, 0); smb_SetSMBParm(outp, 4, 0); - /* set the packet data length to 3 bytes for the data block header, + /* set the packet data length to 3 bytes for the data block header, * plus the size of the data. */ smb_SetSMBDataLength(outp, count+3); - /* get op ptr after putting in the parms, since otherwise we don't + /* get op ptr after putting in the parms, since otherwise we don't * know where the data really is. */ op = smb_GetSMBData(outp, NULL); - /* now emit the data block header: 1 byte of type and 2 bytes of length */ + /* now emit the data block header: 1 byte of type and 2 bytes of length */ *op++ = 1; /* data block marker */ *op++ = (unsigned char) (count & 0xff); *op++ = (unsigned char) ((count >> 8) & 0xff); #ifndef DJGPP - code = smb_ReadData(fidp, &offset, count, op, userp, &finalCount); + code = smb_ReadData(fidp, &offset, count, op, userp, &finalCount); #else /* DJGPP */ code = smb_ReadData(fidp, &offset, count, op, userp, &finalCount, FALSE); #endif /* !DJGPP */ - /* fix some things up */ - smb_SetSMBParm(outp, 0, finalCount); - smb_SetSMBDataLength(outp, finalCount+3); + /* fix some things up */ + smb_SetSMBParm(outp, 0, finalCount); + smb_SetSMBDataLength(outp, finalCount+3); smb_ReleaseFID(fidp); @@ -5762,9 +5784,9 @@ long smb_ReceiveCoreRead(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) long smb_ReceiveCoreMakeDir(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { - char *pathp; + char *pathp; long code = 0; - cm_space_t *spacep; + cm_space_t *spacep; char *tp; cm_user_t *userp; cm_scache_t *dscp; /* dir we're dealing with */ @@ -5773,36 +5795,36 @@ long smb_ReceiveCoreMakeDir(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp int initialModeBits; char *lastNamep; int caseFold; - char *tidPathp; - cm_req_t req; + char *tidPathp; + cm_req_t req; - cm_InitReq(&req); + cm_InitReq(&req); scp = NULL; - /* compute initial mode bits based on read-only flag in attributes */ + /* compute initial mode bits based on read-only flag in attributes */ initialModeBits = 0777; - tp = smb_GetSMBData(inp, NULL); + tp = smb_GetSMBData(inp, NULL); pathp = smb_ParseASCIIBlock(tp, &tp); - if (strcmp(pathp, "\\") == 0) - return CM_ERROR_EXISTS; + if (strcmp(pathp, "\\") == 0) + return CM_ERROR_EXISTS; - spacep = inp->spacep; + spacep = inp->spacep; smb_StripLastComponent(spacep->data, &lastNamep, pathp); - userp = smb_GetUser(vcp, inp); + userp = smb_GetUser(vcp, inp); caseFold = CM_FLAG_CASEFOLD; - code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &tidPathp); - if(code) { + code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &tidPathp); + if (code) { cm_ReleaseUser(userp); return CM_ERROR_NOSUCHPATH; } - code = cm_NameI(cm_rootSCachep, spacep->data, + code = cm_NameI(cm_rootSCachep, spacep->data, caseFold | CM_FLAG_FOLLOW | CM_FLAG_CHECKPATH, userp, tidPathp, &req, &dscp); @@ -5812,7 +5834,7 @@ long smb_ReceiveCoreMakeDir(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp } /* otherwise, scp points to the parent directory. Do a lookup, and - * fail if we find it. Otherwise, we do the create. + * fail if we find it. Otherwise, we do the create. */ if (!lastNamep) lastNamep = pathp; @@ -5822,29 +5844,29 @@ long smb_ReceiveCoreMakeDir(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp if (scp) cm_ReleaseSCache(scp); if (code != CM_ERROR_NOSUCHFILE) { if (code == 0) code = CM_ERROR_EXISTS; - cm_ReleaseSCache(dscp); + cm_ReleaseSCache(dscp); cm_ReleaseUser(userp); return code; } - setAttr.mask = CM_ATTRMASK_CLIENTMODTIME; - setAttr.clientModTime = time(NULL); - code = cm_MakeDir(dscp, lastNamep, 0, &setAttr, userp, &req); - if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH)) - smb_NotifyChange(FILE_ACTION_ADDED, + setAttr.mask = CM_ATTRMASK_CLIENTMODTIME; + setAttr.clientModTime = time(NULL); + code = cm_MakeDir(dscp, lastNamep, 0, &setAttr, userp, &req); + if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH)) + smb_NotifyChange(FILE_ACTION_ADDED, FILE_NOTIFY_CHANGE_DIR_NAME, dscp, lastNamep, NULL, TRUE); - /* we don't need this any longer */ - cm_ReleaseSCache(dscp); + /* we don't need this any longer */ + cm_ReleaseSCache(dscp); if (code) { - /* something went wrong creating or truncating the file */ + /* something went wrong creating or truncating the file */ cm_ReleaseUser(userp); return code; } - /* otherwise we succeeded */ + /* otherwise we succeeded */ smb_SetSMBDataLength(outp, 0); cm_ReleaseUser(userp); @@ -5867,9 +5889,9 @@ BOOL smb_IsLegalFilename(char *filename) long smb_ReceiveCoreCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { - char *pathp; + char *pathp; long code = 0; - cm_space_t *spacep; + cm_space_t *spacep; char *tp; int excl; cm_user_t *userp; @@ -5882,10 +5904,10 @@ long smb_ReceiveCoreCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) char *lastNamep; int caseFold; long dosTime; - char *tidPathp; - cm_req_t req; + char *tidPathp; + cm_req_t req; - cm_InitReq(&req); + cm_InitReq(&req); scp = NULL; excl = (inp->inCom == 0x03)? 0 : 1; @@ -5893,26 +5915,26 @@ long smb_ReceiveCoreCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) attributes = smb_GetSMBParm(inp, 0); dosTime = smb_GetSMBParm(inp, 1) | (smb_GetSMBParm(inp, 2) << 16); - /* compute initial mode bits based on read-only flag in attributes */ + /* compute initial mode bits based on read-only flag in attributes */ initialModeBits = 0666; if (attributes & 1) initialModeBits &= ~0222; - tp = smb_GetSMBData(inp, NULL); + tp = smb_GetSMBData(inp, NULL); pathp = smb_ParseASCIIBlock(tp, &tp); - spacep = inp->spacep; + spacep = inp->spacep; smb_StripLastComponent(spacep->data, &lastNamep, pathp); - userp = smb_GetUser(vcp, inp); + userp = smb_GetUser(vcp, inp); caseFold = CM_FLAG_CASEFOLD; - code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &tidPathp); - if(code) { + code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &tidPathp); + if (code) { cm_ReleaseUser(userp); return CM_ERROR_NOSUCHPATH; } - code = cm_NameI(cm_rootSCachep, spacep->data, caseFold | CM_FLAG_FOLLOW, + code = cm_NameI(cm_rootSCachep, spacep->data, caseFold | CM_FLAG_FOLLOW, userp, tidPathp, &req, &dscp); if (code) { @@ -5921,7 +5943,7 @@ long smb_ReceiveCoreCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) } /* otherwise, scp points to the parent directory. Do a lookup, and - * truncate the file if we find it, otherwise we create the file. + * truncate the file if we find it, otherwise we create the file. */ if (!lastNamep) lastNamep = pathp; else lastNamep++; @@ -5941,7 +5963,7 @@ long smb_ReceiveCoreCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) code = cm_Lookup(dscp, lastNamep, 0, userp, &req, &scp); if (code && code != CM_ERROR_NOSUCHFILE) { - cm_ReleaseSCache(dscp); + cm_ReleaseSCache(dscp); cm_ReleaseUser(userp); return code; } @@ -5949,40 +5971,40 @@ long smb_ReceiveCoreCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) /* if we get here, if code is 0, the file exists and is represented by * scp. Otherwise, we have to create it. */ - if (code == 0) { - if (excl) { - /* oops, file shouldn't be there */ + if (code == 0) { + if (excl) { + /* oops, file shouldn't be there */ cm_ReleaseSCache(dscp); cm_ReleaseSCache(scp); cm_ReleaseUser(userp); return CM_ERROR_EXISTS; } - setAttr.mask = CM_ATTRMASK_LENGTH; + setAttr.mask = CM_ATTRMASK_LENGTH; setAttr.length.LowPart = 0; setAttr.length.HighPart = 0; - code = cm_SetAttr(scp, &setAttr, userp, &req); + code = cm_SetAttr(scp, &setAttr, userp, &req); } else { setAttr.mask = CM_ATTRMASK_CLIENTMODTIME; smb_UnixTimeFromDosUTime(&setAttr.clientModTime, dosTime); code = cm_Create(dscp, lastNamep, 0, &setAttr, &scp, userp, &req); - if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH)) - smb_NotifyChange(FILE_ACTION_ADDED, + if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH)) + smb_NotifyChange(FILE_ACTION_ADDED, FILE_NOTIFY_CHANGE_FILE_NAME, dscp, lastNamep, NULL, TRUE); if (!excl && code == CM_ERROR_EXISTS) { - /* not an exclusive create, and someone else tried - * creating it already, then we open it anyway. We - * don't bother retrying after this, since if this next - * fails, that means that the file was deleted after - * we started this call. + /* not an exclusive create, and someone else tried + * creating it already, then we open it anyway. We + * don't bother retrying after this, since if this next + * fails, that means that the file was deleted after + * we started this call. */ code = cm_Lookup(dscp, lastNamep, caseFold, userp, &req, &scp); if (code == 0) { - setAttr.mask = CM_ATTRMASK_LENGTH; + setAttr.mask = CM_ATTRMASK_LENGTH; setAttr.length.LowPart = 0; setAttr.length.HighPart = 0; code = cm_SetAttr(scp, &setAttr, userp, &req); @@ -5990,39 +6012,39 @@ long smb_ReceiveCoreCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) } } - /* we don't need this any longer */ - cm_ReleaseSCache(dscp); + /* we don't need this any longer */ + cm_ReleaseSCache(dscp); if (code) { - /* something went wrong creating or truncating the file */ + /* something went wrong creating or truncating the file */ if (scp) cm_ReleaseSCache(scp); cm_ReleaseUser(userp); return code; } - /* make sure we only open files */ - if (scp->fileType != CM_SCACHETYPE_FILE) { - cm_ReleaseSCache(scp); + /* make sure we only open files */ + if (scp->fileType != CM_SCACHETYPE_FILE) { + cm_ReleaseSCache(scp); cm_ReleaseUser(userp); return CM_ERROR_ISDIR; - } + } /* now all we have to do is open the file itself */ fidp = smb_FindFID(vcp, 0, SMB_FLAG_CREATE); osi_assert(fidp); - /* save a pointer to the vnode */ + /* save a pointer to the vnode */ fidp->scp = scp; - /* always create it open for read/write */ - fidp->flags |= (SMB_FID_OPENREAD | SMB_FID_OPENWRITE); + /* always create it open for read/write */ + fidp->flags |= (SMB_FID_OPENREAD | SMB_FID_OPENWRITE); - smb_ReleaseFID(fidp); + smb_ReleaseFID(fidp); - smb_SetSMBParm(outp, 0, fidp->fid); + smb_SetSMBParm(outp, 0, fidp->fid); smb_SetSMBDataLength(outp, 0); - cm_Open(scp, 0, userp); + cm_Open(scp, 0, userp); cm_ReleaseUser(userp); /* leave scp held since we put it in fidp->scp */ @@ -6038,43 +6060,43 @@ long smb_ReceiveCoreSeek(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) smb_fid_t *fidp; cm_scache_t *scp; cm_user_t *userp; - cm_req_t req; + cm_req_t req; - cm_InitReq(&req); + cm_InitReq(&req); fd = smb_GetSMBParm(inp, 0); - whence = smb_GetSMBParm(inp, 1); + whence = smb_GetSMBParm(inp, 1); offset = smb_GetSMBParm(inp, 2) | (smb_GetSMBParm(inp, 3) << 16); - /* try to find the file descriptor */ - fd = smb_ChainFID(fd, inp); + /* try to find the file descriptor */ + fd = smb_ChainFID(fd, inp); fidp = smb_FindFID(vcp, fd, 0); if (!fidp || (fidp->flags & SMB_FID_IOCTL)) { - return CM_ERROR_BADFD; + return CM_ERROR_BADFD; } - userp = smb_GetUser(vcp, inp); + userp = smb_GetUser(vcp, inp); lock_ObtainMutex(&fidp->mx); scp = fidp->scp; - lock_ObtainMutex(&scp->mx); - code = cm_SyncOp(scp, NULL, userp, &req, 0, + lock_ObtainMutex(&scp->mx); + code = cm_SyncOp(scp, NULL, userp, &req, 0, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); - if (code == 0) { - if (whence == 1) { + if (code == 0) { + if (whence == 1) { /* offset from current offset */ offset += fidp->offset; - } - else if (whence == 2) { + } + else if (whence == 2) { /* offset from current EOF */ offset += scp->length.LowPart; - } + } fidp->offset = offset; smb_SetSMBParm(outp, 0, offset & 0xffff); smb_SetSMBParm(outp, 1, (offset>>16) & 0xffff); smb_SetSMBDataLength(outp, 0); } - lock_ReleaseMutex(&scp->mx); + lock_ReleaseMutex(&scp->mx); lock_ReleaseMutex(&fidp->mx); smb_ReleaseFID(fidp); cm_ReleaseUser(userp); @@ -6085,7 +6107,7 @@ long smb_ReceiveCoreSeek(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) * be more than one request. */ void smb_DispatchPacket(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp, - NCB *ncbp, raw_write_cont_t *rwcp) + NCB *ncbp, raw_write_cont_t *rwcp) { smb_dispatch_t *dp; smb_t *smbp; @@ -6404,14 +6426,14 @@ void smb_DispatchPacket(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp, */ void smb_ClientWaiter(void *parmp) { - DWORD code; + DWORD code; int idx; - while (1) { - code = thrd_WaitForMultipleObjects_Event(numNCBs, NCBevents, - FALSE, INFINITE); - if (code == WAIT_OBJECT_0) - continue; + while (1) { + code = thrd_WaitForMultipleObjects_Event(numNCBs, NCBevents, + FALSE, INFINITE); + if (code == WAIT_OBJECT_0) + continue; /* error checking */ if (code >= WAIT_ABANDONED_0 && code < (WAIT_ABANDONED_0 + numNCBs)) @@ -6446,9 +6468,9 @@ void smb_ClientWaiter(void *parmp) osi_assert(0); } - thrd_ResetEvent(NCBevents[idx]); - thrd_SetEvent(NCBreturns[0][idx]); - } + thrd_ResetEvent(NCBevents[idx]); + thrd_SetEvent(NCBreturns[0][idx]); + } } #endif /* !DJGPP */ @@ -6458,19 +6480,19 @@ void smb_ClientWaiter(void *parmp) */ void smb_ServerWaiter(void *parmp) { - DWORD code; + DWORD code; int idx_session, idx_NCB; - NCB *ncbp; + NCB *ncbp; #ifdef DJGPP dos_ptr dos_ncb; #endif /* DJGPP */ - while (1) { - /* Get a session */ - code = thrd_WaitForMultipleObjects_Event(numSessions, SessionEvents, - FALSE, INFINITE); - if (code == WAIT_OBJECT_0) - continue; + while (1) { + /* Get a session */ + code = thrd_WaitForMultipleObjects_Event(numSessions, SessionEvents, + FALSE, INFINITE); + if (code == WAIT_OBJECT_0) + continue; if (code >= WAIT_ABANDONED_0 && code < (WAIT_ABANDONED_0 + numSessions)) { @@ -6506,10 +6528,10 @@ void smb_ServerWaiter(void *parmp) /* Get an NCB */ NCBretry: - code = thrd_WaitForMultipleObjects_Event(numNCBs, NCBavails, - FALSE, INFINITE); - if (code == WAIT_OBJECT_0) - goto NCBretry; + code = thrd_WaitForMultipleObjects_Event(numNCBs, NCBavails, + FALSE, INFINITE); + if (code == WAIT_OBJECT_0) + goto NCBretry; /* error checking */ if (code >= WAIT_ABANDONED_0 && code < (WAIT_ABANDONED_0 + numNCBs)) @@ -6544,30 +6566,30 @@ void smb_ServerWaiter(void *parmp) osi_assert(0); } - /* Link them together */ - NCBsessions[idx_NCB] = idx_session; + /* Link them together */ + NCBsessions[idx_NCB] = idx_session; - /* Fire it up */ - ncbp = NCBs[idx_NCB]; + /* Fire it up */ + ncbp = NCBs[idx_NCB]; #ifdef DJGPP dos_ncb = ((smb_ncb_t *)ncbp)->dos_ncb; #endif /* DJGPP */ - ncbp->ncb_lsn = (unsigned char) LSNs[idx_session]; - ncbp->ncb_command = NCBRECV | ASYNCH; - ncbp->ncb_lana_num = lanas[idx_session]; + ncbp->ncb_lsn = (unsigned char) LSNs[idx_session]; + ncbp->ncb_command = NCBRECV | ASYNCH; + ncbp->ncb_lana_num = lanas[idx_session]; #ifndef DJGPP - ncbp->ncb_buffer = (unsigned char *) bufs[idx_NCB]; - ncbp->ncb_event = NCBevents[idx_NCB]; - ncbp->ncb_length = SMB_PACKETSIZE; - Netbios(ncbp); + ncbp->ncb_buffer = (unsigned char *) bufs[idx_NCB]; + ncbp->ncb_event = NCBevents[idx_NCB]; + ncbp->ncb_length = SMB_PACKETSIZE; + Netbios(ncbp); #else /* DJGPP */ - ncbp->ncb_buffer = bufs[idx_NCB]->dos_pkt; - ((smb_ncb_t*)ncbp)->orig_pkt = bufs[idx_NCB]; - ncbp->ncb_event = NCBreturns[0][idx_NCB]; - ncbp->ncb_length = SMB_PACKETSIZE; - Netbios(ncbp, dos_ncb); + ncbp->ncb_buffer = bufs[idx_NCB]->dos_pkt; + ((smb_ncb_t*)ncbp)->orig_pkt = bufs[idx_NCB]; + ncbp->ncb_event = NCBreturns[0][idx_NCB]; + ncbp->ncb_length = SMB_PACKETSIZE; + Netbios(ncbp, dos_ncb); #endif /* !DJGPP */ - } + } } /* @@ -6582,42 +6604,29 @@ void smb_ServerWaiter(void *parmp) */ void smb_Server(VOID *parmp) { - int myIdx = (int) parmp; - NCB *ncbp; - NCB *outncbp; + int myIdx = (int) parmp; + NCB *ncbp; + NCB *outncbp; smb_packet_t *bufp; - smb_packet_t *outbufp; + smb_packet_t *outbufp; DWORD code, rcode; int idx_NCB, idx_session; - UCHAR rc; - smb_vc_t *vcp = NULL; - smb_t *smbp; + UCHAR rc; + smb_vc_t *vcp = NULL; + smb_t *smbp; #ifdef DJGPP dos_ptr dos_ncb; #endif /* DJGPP */ - outncbp = GetNCB(); - outbufp = GetPacket(); - outbufp->ncbp = outncbp; - - while (1) { -#ifndef NOEXPIRE - /* check for demo expiration */ - { - unsigned long tod = time((void *) 0); - if (tod > EXPIREDATE) { - (*smb_MBfunc)(NULL, "AFS demo expiration", - "afsd dispatcher", - MB_OK|MB_ICONSTOP|MB_SETFOREGROUND|MB_SERVICE_NOTIFICATION); - trhd_Exit(1); - } - } -#endif /* !NOEXPIRE */ - - code = thrd_WaitForMultipleObjects_Event(numNCBs, NCBreturns[myIdx], - FALSE, INFINITE); - if (code == WAIT_OBJECT_0) { - continue; + outncbp = GetNCB(); + outbufp = GetPacket(); + outbufp->ncbp = outncbp; + + while (1) { + code = thrd_WaitForMultipleObjects_Event(numNCBs, NCBreturns[myIdx], + FALSE, INFINITE); + if (code == WAIT_OBJECT_0) { + continue; } /* error checking */ @@ -6653,183 +6662,182 @@ void smb_Server(VOID *parmp) osi_assert(0); } - ncbp = NCBs[idx_NCB]; + ncbp = NCBs[idx_NCB]; #ifdef DJGPP - dos_ncb = ((smb_ncb_t *)ncbp)->dos_ncb; + dos_ncb = ((smb_ncb_t *)ncbp)->dos_ncb; #endif /* DJGPP */ - idx_session = NCBsessions[idx_NCB]; - rc = ncbp->ncb_retcode; + idx_session = NCBsessions[idx_NCB]; + rc = ncbp->ncb_retcode; - if (rc != NRC_PENDING && rc != NRC_GOODRET) - osi_Log1(smb_logp, "NCBRECV failure code %d", rc); + if (rc != NRC_PENDING && rc != NRC_GOODRET) + osi_Log1(smb_logp, "NCBRECV failure code %d", rc); - switch (rc) { - case NRC_GOODRET: break; + switch (rc) { + case NRC_GOODRET: break; - case NRC_PENDING: - /* Can this happen? Or is it just my - * UNIX paranoia? - */ - continue; - - case NRC_SCLOSED: - case NRC_SNUMOUT: - /* Client closed session */ - if (reportSessionStartups) - { - osi_Log1(smb_logp, "session [ %d ] closed", idx_session); + case NRC_PENDING: + /* Can this happen? Or is it just my + * UNIX paranoia? + */ + continue; + + case NRC_SCLOSED: + case NRC_SNUMOUT: + /* Client closed session */ + if (reportSessionStartups) + { + osi_Log1(smb_logp, "session [ %d ] closed", idx_session); + } + dead_sessions[idx_session] = TRUE; + if (vcp) + smb_ReleaseVC(vcp); + vcp = smb_FindVC(ncbp->ncb_lsn, 0, lanas[idx_session]); + /* Should also release vcp. [done] 2004-05-11 jaltman + * Also, should do + * sanity check that all TID's are gone. + * + * TODO: check if we could use LSNs[idx_session] instead, + * also cleanup after dead vcp + */ + if (vcp) { + if (dead_vcp) + osi_Log1(smb_logp, + "dead_vcp already set, %x", + dead_vcp); + if (!dead_vcp && !(vcp->flags & SMB_VCFLAG_ALREADYDEAD)) { + osi_Log2(smb_logp, + "setting dead_vcp %x, user struct %x", + vcp, vcp->usersp); + smb_HoldVC(vcp); + dead_vcp = vcp; + vcp->flags |= SMB_VCFLAG_ALREADYDEAD; } - dead_sessions[idx_session] = TRUE; - if (vcp) - smb_ReleaseVC(vcp); - vcp = smb_FindVC(ncbp->ncb_lsn, 0, lanas[idx_session]); - /* Should also release vcp. [done] 2004-05-11 jaltman - * Also, should do - * sanity check that all TID's are gone. - * - * TODO: check if we could use LSNs[idx_session] instead, - * also cleanup after dead vcp - */ - if (vcp) { - if (dead_vcp) - osi_Log1(smb_logp, - "dead_vcp already set, %x", - dead_vcp); - if (!dead_vcp && !(vcp->flags & SMB_VCFLAG_ALREADYDEAD)) { - osi_Log2(smb_logp, - "setting dead_vcp %x, user struct %x", - vcp, vcp->usersp); - smb_HoldVC(vcp); - dead_vcp = vcp; - vcp->flags |= SMB_VCFLAG_ALREADYDEAD; - } - if (vcp->justLoggedOut) { - loggedOut = 1; - loggedOutTime = vcp->logoffTime; - loggedOutName = - strdup(vcp->justLoggedOut->unp->name); - loggedOutUserp = vcp->justLoggedOut; - lock_ObtainWrite(&smb_rctLock); - loggedOutUserp->refCount++; - lock_ReleaseWrite(&smb_rctLock); - } + if (vcp->justLoggedOut) { + loggedOut = 1; + loggedOutTime = vcp->logoffTime; + loggedOutName = strdup(vcp->justLoggedOut->unp->name); + loggedOutUserp = vcp->justLoggedOut; + lock_ObtainWrite(&smb_rctLock); + loggedOutUserp->refCount++; + lock_ReleaseWrite(&smb_rctLock); } - goto doneWithNCB; + } + goto doneWithNCB; - case NRC_INCOMP: - /* Treat as transient error */ - { + case NRC_INCOMP: + /* Treat as transient error */ + { #ifndef DJGPP - EVENT_HANDLE h; - char *ptbuf[1]; - char s[100]; - - h = RegisterEventSource(NULL, AFS_DAEMON_EVENT_NAME); - sprintf(s, "SMB message incomplete, length %d", - ncbp->ncb_length); - ptbuf[0] = s; - ReportEvent(h, EVENTLOG_WARNING_TYPE, 0, - 1001, NULL, 1, - ncbp->ncb_length, ptbuf, - bufp); - DeregisterEventSource(h); + EVENT_HANDLE h; + char *ptbuf[1]; + char s[100]; + + h = RegisterEventSource(NULL, AFS_DAEMON_EVENT_NAME); + sprintf(s, "SMB message incomplete, length %d", + ncbp->ncb_length); + ptbuf[0] = s; + ReportEvent(h, EVENTLOG_WARNING_TYPE, 0, + 1001, NULL, 1, + ncbp->ncb_length, ptbuf, + bufp); + DeregisterEventSource(h); #endif /* !DJGPP */ - osi_Log1(smb_logp, - "dispatch smb recv failed, message incomplete, ncb_length %d", - ncbp->ncb_length); - osi_Log1(smb_logp, - "SMB message incomplete, " - "length %d", ncbp->ncb_length); - - /* - * We used to discard the packet. - * Instead, try handling it normally. - * - continue; - */ - break; - } - - default: - /* A weird error code. Log it, sleep, and - * continue. */ - if (vcp && vcp->errorCount++ > 3) { - osi_Log2(smb_logp, "session [ %d ] closed, vcp->errorCount = %d", idx_session, vcp->errorCount); - dead_sessions[idx_session] = TRUE; - } - else { - thrd_Sleep(1000); - thrd_SetEvent(SessionEvents[idx_session]); - } - continue; - } + osi_Log1(smb_logp, + "dispatch smb recv failed, message incomplete, ncb_length %d", + ncbp->ncb_length); + osi_Log1(smb_logp, + "SMB message incomplete, " + "length %d", ncbp->ncb_length); + + /* + * We used to discard the packet. + * Instead, try handling it normally. + * + continue; + */ + break; + } + + default: + /* A weird error code. Log it, sleep, and + * continue. */ + if (vcp && vcp->errorCount++ > 3) { + osi_Log2(smb_logp, "session [ %d ] closed, vcp->errorCount = %d", idx_session, vcp->errorCount); + dead_sessions[idx_session] = TRUE; + } + else { + thrd_Sleep(1000); + thrd_SetEvent(SessionEvents[idx_session]); + } + continue; + } - /* Success, so now dispatch on all the data in the packet */ + /* Success, so now dispatch on all the data in the packet */ - smb_concurrentCalls++; - if (smb_concurrentCalls > smb_maxObsConcurrentCalls) - smb_maxObsConcurrentCalls = smb_concurrentCalls; + smb_concurrentCalls++; + if (smb_concurrentCalls > smb_maxObsConcurrentCalls) + smb_maxObsConcurrentCalls = smb_concurrentCalls; if (vcp) smb_ReleaseVC(vcp); - vcp = smb_FindVC(ncbp->ncb_lsn, 0, ncbp->ncb_lana_num); + vcp = smb_FindVC(ncbp->ncb_lsn, 0, ncbp->ncb_lana_num); /* - * If at this point vcp is NULL (implies that packet was invalid) - * then we are in big trouble. This means either : - * a) we have the wrong NCB. - * b) Netbios screwed up the call. - * Obviously this implies that - * ( LSNs[idx_session] != ncbp->ncb_lsn || - * lanas[idx_session] != ncbp->ncb_lana_num ) - * Either way, we can't do anything with this packet. - * Log, sleep and resume. - */ - if(!vcp) { - HANDLE h; - char buf[1000]; - char *ptbuf[1]; - - sprintf(buf, - "Bad vcp!! : " - "LSNs[idx_session]=[%d]," - "lanas[idx_session]=[%d]," - "ncbp->ncb_lsn=[%d]," - "ncbp->ncb_lana_num=[%d]", - LSNs[idx_session], - lanas[idx_session], - ncbp->ncb_lsn, - ncbp->ncb_lana_num); - - ptbuf[0] = buf; - - h = RegisterEventSource(NULL,AFS_DAEMON_EVENT_NAME); - if(h) { - ReportEvent(h, EVENTLOG_ERROR_TYPE, 0, 1001, NULL,1,sizeof(*ncbp),ptbuf,(void*)ncbp); - DeregisterEventSource(h); - } - - /* Also log in the trace log. */ - osi_Log4(smb_logp, "Server: BAD VCP!" - "LSNs[idx_session]=[%d]," - "lanas[idx_session]=[%d]," - "ncbp->ncb_lsn=[%d]," - "ncbp->ncb_lana_num=[%d]", - LSNs[idx_session], - lanas[idx_session], - ncbp->ncb_lsn, - ncbp->ncb_lana_num); - - /* thrd_Sleep(1000); Don't bother sleeping */ - thrd_SetEvent(SessionEvents[idx_session]); - smb_concurrentCalls--; - continue; - } - - - vcp->errorCount = 0; - bufp = (struct smb_packet *) ncbp->ncb_buffer; + * If at this point vcp is NULL (implies that packet was invalid) + * then we are in big trouble. This means either : + * a) we have the wrong NCB. + * b) Netbios screwed up the call. + * Obviously this implies that + * ( LSNs[idx_session] != ncbp->ncb_lsn || + * lanas[idx_session] != ncbp->ncb_lana_num ) + * Either way, we can't do anything with this packet. + * Log, sleep and resume. + */ + if(!vcp) { + HANDLE h; + char buf[1000]; + char *ptbuf[1]; + + sprintf(buf, + "Bad vcp!! : " + "LSNs[idx_session]=[%d]," + "lanas[idx_session]=[%d]," + "ncbp->ncb_lsn=[%d]," + "ncbp->ncb_lana_num=[%d]", + LSNs[idx_session], + lanas[idx_session], + ncbp->ncb_lsn, + ncbp->ncb_lana_num); + + ptbuf[0] = buf; + + h = RegisterEventSource(NULL,AFS_DAEMON_EVENT_NAME); + if(h) { + ReportEvent(h, EVENTLOG_ERROR_TYPE, 0, 1001, NULL,1,sizeof(*ncbp),ptbuf,(void*)ncbp); + DeregisterEventSource(h); + } + + /* Also log in the trace log. */ + osi_Log4(smb_logp, "Server: BAD VCP!" + "LSNs[idx_session]=[%d]," + "lanas[idx_session]=[%d]," + "ncbp->ncb_lsn=[%d]," + "ncbp->ncb_lana_num=[%d]", + LSNs[idx_session], + lanas[idx_session], + ncbp->ncb_lsn, + ncbp->ncb_lana_num); + + /* thrd_Sleep(1000); Don't bother sleeping */ + thrd_SetEvent(SessionEvents[idx_session]); + smb_concurrentCalls--; + continue; + } + + + vcp->errorCount = 0; + bufp = (struct smb_packet *) ncbp->ncb_buffer; #ifdef DJGPP - bufp = ((smb_ncb_t *) ncbp)->orig_pkt; + bufp = ((smb_ncb_t *) ncbp)->orig_pkt; /* copy whole packet to virtual memory */ /*fprintf(stderr, "smb_Server: copying dos packet at 0x%x, " "bufp=0x%x\n", @@ -6837,64 +6845,65 @@ void smb_Server(VOID *parmp) fflush(stderr); dosmemget(bufp->dos_pkt, ncbp->ncb_length, bufp->data); #endif /* DJGPP */ - smbp = (smb_t *)bufp->data; - outbufp->flags = 0; + smbp = (smb_t *)bufp->data; + outbufp->flags = 0; #if !defined(DJGPP) && !defined(AFS_WIN32_ENV) __try { #endif - if (smbp->com == 0x1d) { - /* Special handling for Write Raw */ - raw_write_cont_t rwc; - EVENT_HANDLE rwevent; - char eventName[MAX_PATH]; + if (smbp->com == 0x1d) { + /* Special handling for Write Raw */ + raw_write_cont_t rwc; + EVENT_HANDLE rwevent; + char eventName[MAX_PATH]; - smb_DispatchPacket(vcp, bufp, outbufp, ncbp, &rwc); - if (rwc.code == 0) { - rwevent = thrd_CreateEvent(NULL, FALSE, FALSE, TEXT("smb_Server() rwevent")); - if ( GetLastError() == ERROR_ALREADY_EXISTS ) - osi_Log1(smb_logp, "Event Object Already Exists: %s", osi_LogSaveString(smb_logp, eventName)); - ncbp->ncb_command = NCBRECV | ASYNCH; - ncbp->ncb_lsn = (unsigned char) vcp->lsn; - ncbp->ncb_lana_num = vcp->lana; - ncbp->ncb_buffer = rwc.buf; - ncbp->ncb_length = 65535; - ncbp->ncb_event = rwevent; + smb_DispatchPacket(vcp, bufp, outbufp, ncbp, &rwc); + if (rwc.code == 0) { + rwevent = thrd_CreateEvent(NULL, FALSE, FALSE, TEXT("smb_Server() rwevent")); + if ( GetLastError() == ERROR_ALREADY_EXISTS ) + osi_Log1(smb_logp, "Event Object Already Exists: %s", osi_LogSaveString(smb_logp, eventName)); + ncbp->ncb_command = NCBRECV | ASYNCH; + ncbp->ncb_lsn = (unsigned char) vcp->lsn; + ncbp->ncb_lana_num = vcp->lana; + ncbp->ncb_buffer = rwc.buf; + ncbp->ncb_length = 65535; + ncbp->ncb_event = rwevent; #ifndef DJGPP - Netbios(ncbp); + Netbios(ncbp); #else - Netbios(ncbp, dos_ncb); + Netbios(ncbp, dos_ncb); #endif /* !DJGPP */ - rcode = thrd_WaitForSingleObject_Event(rwevent, RAWTIMEOUT); - thrd_CloseHandle(rwevent); - } - thrd_SetEvent(SessionEvents[idx_session]); - if (rwc.code == 0) - smb_CompleteWriteRaw(vcp, bufp, outbufp, ncbp, &rwc); - } else if (smbp->com == 0xa0) { - /* - * Serialize the handling for NT Transact - * (defect 11626) - */ - smb_DispatchPacket(vcp, bufp, outbufp, ncbp, NULL); - thrd_SetEvent(SessionEvents[idx_session]); - } else { - thrd_SetEvent(SessionEvents[idx_session]); - /* TODO: what else needs to be serialized? */ - smb_DispatchPacket(vcp, bufp, outbufp, ncbp, NULL); - } + rcode = thrd_WaitForSingleObject_Event(rwevent, RAWTIMEOUT); + thrd_CloseHandle(rwevent); + } + thrd_SetEvent(SessionEvents[idx_session]); + if (rwc.code == 0) + smb_CompleteWriteRaw(vcp, bufp, outbufp, ncbp, &rwc); + } + else if (smbp->com == 0xa0) { + /* + * Serialize the handling for NT Transact + * (defect 11626) + */ + smb_DispatchPacket(vcp, bufp, outbufp, ncbp, NULL); + thrd_SetEvent(SessionEvents[idx_session]); + } else { + thrd_SetEvent(SessionEvents[idx_session]); + /* TODO: what else needs to be serialized? */ + smb_DispatchPacket(vcp, bufp, outbufp, ncbp, NULL); + } #if !defined(DJGPP) && !defined(AFS_WIN95_ENV) } __except( smb_ServerExceptionFilter() ) { } #endif - smb_concurrentCalls--; + smb_concurrentCalls--; doneWithNCB: - thrd_SetEvent(NCBavails[idx_NCB]); - } + thrd_SetEvent(NCBavails[idx_NCB]); + } if (vcp) smb_ReleaseVC(vcp); } @@ -6907,24 +6916,24 @@ doneWithNCB: */ #if !defined(DJGPP) && !defined(AFS_WIN95_ENV) DWORD smb_ServerExceptionFilter(void) { - /* While this is not the best time to do a trace, if it succeeds, then - * we have a trace (assuming tracing was enabled). Otherwise, this should - * throw a second exception. - */ - HANDLE h; - char *ptbuf[1]; - - ptbuf[0] = "Unhandled exception forcing trace"; - - h = RegisterEventSource(NULL,AFS_DAEMON_EVENT_NAME); - if(h) { - ReportEvent(h, EVENTLOG_ERROR_TYPE, 0, 1001, NULL,1,0,ptbuf,NULL); - DeregisterEventSource(h); - } - - afsd_ForceTrace(TRUE); - return EXCEPTION_CONTINUE_SEARCH; -} + /* While this is not the best time to do a trace, if it succeeds, then + * we have a trace (assuming tracing was enabled). Otherwise, this should + * throw a second exception. + */ + HANDLE h; + char *ptbuf[1]; + + ptbuf[0] = "Unhandled exception forcing trace"; + + h = RegisterEventSource(NULL,AFS_DAEMON_EVENT_NAME); + if(h) { + ReportEvent(h, EVENTLOG_ERROR_TYPE, 0, 1001, NULL,1,0,ptbuf,NULL); + DeregisterEventSource(h); + } + + afsd_ForceTrace(TRUE); + return EXCEPTION_CONTINUE_SEARCH; +} #endif /* @@ -6935,54 +6944,54 @@ DWORD smb_ServerExceptionFilter(void) { */ void InitNCBslot(int idx) { - struct smb_packet *bufp; - EVENT_HANDLE retHandle; - int i; + struct smb_packet *bufp; + EVENT_HANDLE retHandle; + int i; char eventName[MAX_PATH]; osi_assert( idx < (sizeof(NCBs) / sizeof(NCBs[0])) ); - NCBs[idx] = GetNCB(); + NCBs[idx] = GetNCB(); sprintf(eventName,"NCBavails[%d]", idx); - NCBavails[idx] = thrd_CreateEvent(NULL, FALSE, TRUE, eventName); + NCBavails[idx] = thrd_CreateEvent(NULL, FALSE, TRUE, eventName); if ( GetLastError() == ERROR_ALREADY_EXISTS ) osi_Log1(smb_logp, "Event Object Already Exists: %s", osi_LogSaveString(smb_logp, eventName)); #ifndef DJGPP sprintf(eventName,"NCBevents[%d]", idx); - NCBevents[idx] = thrd_CreateEvent(NULL, TRUE, FALSE, eventName); + NCBevents[idx] = thrd_CreateEvent(NULL, TRUE, FALSE, eventName); if ( GetLastError() == ERROR_ALREADY_EXISTS ) osi_Log1(smb_logp, "Event Object Already Exists: %s", osi_LogSaveString(smb_logp, eventName)); #endif /* !DJGPP */ sprintf(eventName,"NCBReturns[0<=ispacep = cm_GetSpace(); - bufs[idx] = bufp; + for (i=0; ispacep = cm_GetSpace(); + bufs[idx] = bufp; } /* listen for new connections */ void smb_Listener(void *parmp) { - NCB *ncbp; + NCB *ncbp; long code = 0; long len; - long i, j; + long i, j; smb_vc_t *vcp; - int flags = 0; - char rname[NCBNAMSZ+1]; - char cname[MAX_COMPUTERNAME_LENGTH+1]; - int cnamelen = MAX_COMPUTERNAME_LENGTH+1; + int flags = 0; + char rname[NCBNAMSZ+1]; + char cname[MAX_COMPUTERNAME_LENGTH+1]; + int cnamelen = MAX_COMPUTERNAME_LENGTH+1; #ifdef DJGPP dos_ptr dos_ncb; time_t now; #endif /* DJGPP */ - int lana = (int) parmp; + int lana = (int) parmp; - ncbp = GetNCB(); + ncbp = GetNCB(); #ifdef DJGPP dos_ncb = ((smb_ncb_t *)ncbp)->dos_ncb; #endif /* DJGPP */ @@ -6991,40 +7000,23 @@ void smb_Listener(void *parmp) GetComputerName(cname, &cnamelen); _strupr(cname); - while (1) { - memset(ncbp, 0, sizeof(NCB)); - flags = 0; - -#ifndef NOEXPIRE - /* check for demo expiration */ - { - unsigned long tod = time((void *) 0); - if (tod > EXPIREDATE) { - (*smb_MBfunc)(NULL, "AFS demo expiration", - "afsd listener", - MB_OK|MB_ICONSTOP|MB_SETFOREGROUND|MB_SERVICE_NOTIFICATION); -#ifndef DJGPP - ExitThread(1); -#else - thrd_Exit(1); -#endif - } - } -#endif /* !NOEXPIRE */ + while (1) { + memset(ncbp, 0, sizeof(NCB)); + flags = 0; ncbp->ncb_command = NCBLISTEN; ncbp->ncb_rto = 0; /* No receive timeout */ ncbp->ncb_sto = 0; /* No send timeout */ - /* pad out with spaces instead of null termination */ - len = strlen(smb_localNamep); + /* pad out with spaces instead of null termination */ + len = strlen(smb_localNamep); strncpy(ncbp->ncb_name, smb_localNamep, NCBNAMSZ); - for(i=len; incb_name[i] = ' '; + for (i=len; incb_name[i] = ' '; strcpy(ncbp->ncb_callname, "*"); - for(i=1; incb_callname[i] = ' '; + for (i=1; incb_callname[i] = ' '; - ncbp->ncb_lana_num = lana; + ncbp->ncb_lana_num = lana; #ifndef DJGPP code = Netbios(ncbp); @@ -7039,13 +7031,13 @@ void smb_Listener(void *parmp) #endif /* terminate silently if shutdown flag is set */ - if (smbShutdownFlag == 1) { + if (smbShutdownFlag == 1) { #ifndef DJGPP - ExitThread(1); + ExitThread(1); #else - thrd_Exit(1); + thrd_Exit(1); #endif - } + } osi_Log2(smb_logp, "NCBLISTEN lana=%d failed with code %d", @@ -7058,9 +7050,9 @@ void smb_Listener(void *parmp) "Client exiting due to network failure. Please restart client.\n" "NCBLISTEN lana=%d failed with code %d", ncbp->ncb_lana_num, code); - if (showErrors) + if (showErrors) code = (*smb_MBfunc)(NULL, tbuffer, "AFS Client Service: Fatal Error", - MB_OK|MB_SERVICE_NOTIFICATION); + MB_OK|MB_SERVICE_NOTIFICATION); osi_assert(tbuffer); ExitThread(1); #else @@ -7069,79 +7061,79 @@ void smb_Listener(void *parmp) fprintf(stderr, "\nClient exiting due to network failure " "(possibly due to power-saving mode)\n"); fprintf(stderr, "Please restart client.\n"); - afs_exit(AFS_EXITCODE_NETWORK_FAILURE); + afs_exit(AFS_EXITCODE_NETWORK_FAILURE); #endif /* !DJGPP */ } - /* check for remote conns */ - /* first get remote name and insert null terminator */ - memcpy(rname, ncbp->ncb_callname, NCBNAMSZ); - for (i=NCBNAMSZ; i>0; i--) { - if (rname[i-1] != ' ' && rname[i-1] != 0) { - rname[i] = 0; - break; - } - } + /* check for remote conns */ + /* first get remote name and insert null terminator */ + memcpy(rname, ncbp->ncb_callname, NCBNAMSZ); + for (i=NCBNAMSZ; i>0; i--) { + if (rname[i-1] != ' ' && rname[i-1] != 0) { + rname[i] = 0; + break; + } + } /* compare with local name */ - if (!isGateway) - if (strncmp(rname, cname, NCBNAMSZ) != 0) - flags |= SMB_VCFLAG_REMOTECONN; + if (!isGateway) + if (strncmp(rname, cname, NCBNAMSZ) != 0) + flags |= SMB_VCFLAG_REMOTECONN; - osi_Log1(smb_logp, "New session lsn %d", ncbp->ncb_lsn); - /* lock */ - lock_ObtainMutex(&smb_ListenerLock); + osi_Log1(smb_logp, "New session lsn %d", ncbp->ncb_lsn); + /* lock */ + lock_ObtainMutex(&smb_ListenerLock); - /* New generation */ - sessionGen++; + /* New generation */ + sessionGen++; - /* Log session startup */ + /* Log session startup */ #ifdef NOTSERVICE fprintf(stderr, "New session(ncb_lsn,ncb_lana_num) %d,%d starting from host " - "%s\n", - ncbp->ncb_lsn,ncbp->ncb_lana_num, rname); + "%s\n", + ncbp->ncb_lsn,ncbp->ncb_lana_num, rname); #endif /* NOTSERVICE */ osi_Log4(smb_logp, "New session(ncb_lsn,ncb_lana_num) (%d,%d) starting from host %s, %d ongoing ops", ncbp->ncb_lsn,ncbp->ncb_lana_num, osi_LogSaveString(smb_logp, rname), ongoingOps); if (reportSessionStartups) { #ifndef DJGPP - HANDLE h; - char *ptbuf[1]; - char s[100]; - - h = RegisterEventSource(NULL, AFS_DAEMON_EVENT_NAME); - sprintf(s, "SMB session startup, %d ongoing ops", ongoingOps); - ptbuf[0] = s; - ReportEvent(h, EVENTLOG_WARNING_TYPE, 0, 1004, NULL, - 1, 0, ptbuf, NULL); - DeregisterEventSource(h); + HANDLE h; + char *ptbuf[1]; + char s[100]; + + h = RegisterEventSource(NULL, AFS_DAEMON_EVENT_NAME); + sprintf(s, "SMB session startup, %d ongoing ops", ongoingOps); + ptbuf[0] = s; + ReportEvent(h, EVENTLOG_WARNING_TYPE, 0, 1004, NULL, + 1, 0, ptbuf, NULL); + DeregisterEventSource(h); #else /* DJGPP */ time(&now); fprintf(stderr, "%s: New session %d starting from host %s\n", asctime(localtime(&now)), ncbp->ncb_lsn, rname); fflush(stderr); #endif /* !DJGPP */ - } - osi_Log1(smb_logp, "NCBLISTEN completed, call from %s", osi_LogSaveString(smb_logp, rname)); - osi_Log1(smb_logp, "SMB session startup, %d ongoing ops", - ongoingOps); + } + osi_Log1(smb_logp, "NCBLISTEN completed, call from %s", osi_LogSaveString(smb_logp, rname)); + osi_Log1(smb_logp, "SMB session startup, %d ongoing ops", + ongoingOps); /* now ncbp->ncb_lsn is the connection ID */ vcp = smb_FindVC(ncbp->ncb_lsn, SMB_FLAG_CREATE, ncbp->ncb_lana_num); - vcp->flags |= flags; + vcp->flags |= flags; strcpy(vcp->rname, rname); - /* Allocate slot in session arrays */ - /* Re-use dead session if possible, otherwise add one more */ + /* Allocate slot in session arrays */ + /* Re-use dead session if possible, otherwise add one more */ /* But don't look at session[0], it is reserved */ - for (i = 1; i < numSessions; i++) { - if (dead_sessions[i]) { + for (i = 1; i < numSessions; i++) { + if (dead_sessions[i]) { osi_Log1(smb_logp, "connecting to dead session [ %d ]", i); - dead_sessions[i] = FALSE; - break; - } - } + dead_sessions[i] = FALSE; + break; + } + } /* assert that we do not exceed the maximum number of sessions or NCBs. * we should probably want to wait for a session to be freed in case @@ -7151,34 +7143,34 @@ void smb_Listener(void *parmp) osi_assert(i < Sessionmax - 1); osi_assert(numNCBs < NCBmax - 1); /* if we pass this test we can allocate one more */ - LSNs[i] = ncbp->ncb_lsn; - lanas[i] = ncbp->ncb_lana_num; + LSNs[i] = ncbp->ncb_lsn; + lanas[i] = ncbp->ncb_lana_num; - if (i == numSessions) { - /* Add new NCB for new session */ + if (i == numSessions) { + /* Add new NCB for new session */ char eventName[MAX_PATH]; osi_Log1(smb_logp, "smb_Listener creating new session %d", i); - InitNCBslot(numNCBs); - numNCBs++; - thrd_SetEvent(NCBavails[0]); - thrd_SetEvent(NCBevents[0]); - for (j = 0; j < smb_NumServerThreads; j++) - thrd_SetEvent(NCBreturns[j][0]); - /* Also add new session event */ + InitNCBslot(numNCBs); + numNCBs++; + thrd_SetEvent(NCBavails[0]); + thrd_SetEvent(NCBevents[0]); + for (j = 0; j < smb_NumServerThreads; j++) + thrd_SetEvent(NCBreturns[j][0]); + /* Also add new session event */ sprintf(eventName, "SessionEvents[%d]", i); SessionEvents[i] = thrd_CreateEvent(NULL, FALSE, TRUE, eventName); if ( GetLastError() == ERROR_ALREADY_EXISTS ) osi_Log1(smb_logp, "Event Object Already Exists: %s", osi_LogSaveString(smb_logp, eventName)); - numSessions++; + numSessions++; osi_Log2(smb_logp, "increasing numNCBs [ %d ] numSessions [ %d ]", numNCBs, numSessions); - thrd_SetEvent(SessionEvents[0]); - } else { - thrd_SetEvent(SessionEvents[i]); - } - /* unlock */ - lock_ReleaseMutex(&smb_ListenerLock); + thrd_SetEvent(SessionEvents[0]); + } else { + thrd_SetEvent(SessionEvents[i]); + } + /* unlock */ + lock_ReleaseMutex(&smb_ListenerLock); } /* dispatch while loop */ } @@ -7320,7 +7312,8 @@ void smb_NetbiosInit() #else code = Netbios(ncbp, dos_ncb); #endif /* DJGPP */ - if (code == 0) code = ncbp->ncb_retcode; + if (code == 0) + code = ncbp->ncb_retcode; else { sprintf(s, "Netbios NCBDELNAME lana %d error code %d\n", lana, code); osi_Log0(smb_logp, s); @@ -7369,11 +7362,11 @@ void smb_Init(osi_log_t *logp, char *snamep, int useV3, int LANadapt, ) { - thread_t phandle; + thread_t phandle; int lpid; int i; int len; - struct tm myTime; + struct tm myTime; #ifdef DJGPP int npar, seg, sel; dos_ptr rawBuf; @@ -7382,74 +7375,57 @@ void smb_Init(osi_log_t *logp, char *snamep, int useV3, int LANadapt, char eventName[MAX_PATH]; #ifndef DJGPP - smb_MBfunc = aMBfunc; + smb_MBfunc = aMBfunc; #endif /* DJGPP */ -#ifndef NOEXPIRE - /* check for demo expiration */ - { - unsigned long tod = time((void *) 0); - if (tod > EXPIREDATE) { -#ifndef DJGPP - (*smb_MBfunc)(NULL, "AFS demo expiration", "afsd", - MB_OK|MB_ICONSTOP|MB_SETFOREGROUND|MB_SERVICE_NOTIFICATION); - exit(1); -#else /* DJGPP */ - fprintf(stderr, "AFS demo expiration\n"); - afs_exit(0); -#endif /* !DJGPP */ - } - } -#endif /* !NOEXPIRE */ - - smb_useV3 = useV3; - smb_LANadapter = LANadapt; - - /* Initialize smb_localZero */ - myTime.tm_isdst = -1; /* compute whether on DST or not */ - myTime.tm_year = 70; - myTime.tm_mon = 0; - myTime.tm_mday = 1; - myTime.tm_hour = 0; - myTime.tm_min = 0; - myTime.tm_sec = 0; - smb_localZero = mktime(&myTime); - - /* Initialize kludge-GMT */ - smb_CalculateNowTZ(); + smb_useV3 = useV3; + smb_LANadapter = LANadapt; + + /* Initialize smb_localZero */ + myTime.tm_isdst = -1; /* compute whether on DST or not */ + myTime.tm_year = 70; + myTime.tm_mon = 0; + myTime.tm_mday = 1; + myTime.tm_hour = 0; + myTime.tm_min = 0; + myTime.tm_sec = 0; + smb_localZero = mktime(&myTime); + + /* Initialize kludge-GMT */ + smb_CalculateNowTZ(); #ifdef AFS_FREELANCE_CLIENT /* Make sure the root.afs volume has the correct time */ cm_noteLocalMountPointChange(); #endif - /* initialize the remote debugging log */ - smb_logp = logp; + /* initialize the remote debugging log */ + smb_logp = logp; /* remember the name */ - len = strlen(snamep); + len = strlen(snamep); smb_localNamep = malloc(len+1); strcpy(smb_localNamep, snamep); afsi_log("smb_localNamep is >%s<", smb_localNamep); - /* and the global lock */ + /* and the global lock */ lock_InitializeRWLock(&smb_globalLock, "smb global lock"); lock_InitializeRWLock(&smb_rctLock, "smb refct and tree struct lock"); - /* Raw I/O data structures */ - lock_InitializeMutex(&smb_RawBufLock, "smb raw buffer lock"); + /* Raw I/O data structures */ + lock_InitializeMutex(&smb_RawBufLock, "smb raw buffer lock"); - lock_InitializeMutex(&smb_ListenerLock, "smb listener lock"); + lock_InitializeMutex(&smb_ListenerLock, "smb listener lock"); - /* 4 Raw I/O buffers */ + /* 4 Raw I/O buffers */ #ifndef DJGPP - smb_RawBufs = calloc(65536,1); - *((char **)smb_RawBufs) = NULL; - for (i=0; i<3; i++) { - char *rawBuf = calloc(65536,1); - *((char **)rawBuf) = smb_RawBufs; - smb_RawBufs = rawBuf; - } + smb_RawBufs = calloc(65536,1); + *((char **)smb_RawBufs) = NULL; + for (i=0; i<3; i++) { + char *rawBuf = calloc(65536,1); + *((char **)rawBuf) = smb_RawBufs; + smb_RawBufs = rawBuf; + } #else /* DJGPP */ npar = 65536 >> 4; /* number of paragraphs */ seg = __dpmi_allocate_dos_memory(npar, &smb_RawBufSel[0]); @@ -7484,30 +7460,30 @@ void smb_Init(osi_log_t *logp, char *snamep, int useV3, int LANadapt, } #endif /* !DJGPP */ - /* global free lists */ - smb_ncbFreeListp = NULL; + /* global free lists */ + smb_ncbFreeListp = NULL; smb_packetFreeListp = NULL; smb_NetbiosInit(); - /* Initialize listener and server structures */ + /* Initialize listener and server structures */ numVCs = 0; - memset(dead_sessions, 0, sizeof(dead_sessions)); + memset(dead_sessions, 0, sizeof(dead_sessions)); sprintf(eventName, "SessionEvents[0]"); - SessionEvents[0] = thrd_CreateEvent(NULL, FALSE, FALSE, eventName); + SessionEvents[0] = thrd_CreateEvent(NULL, FALSE, FALSE, eventName); if ( GetLastError() == ERROR_ALREADY_EXISTS ) afsi_log("Event Object Already Exists: %s", eventName); - numSessions = 1; - smb_NumServerThreads = nThreads; + numSessions = 1; + smb_NumServerThreads = nThreads; sprintf(eventName, "NCBavails[0]"); - NCBavails[0] = thrd_CreateEvent(NULL, FALSE, FALSE, eventName); + NCBavails[0] = thrd_CreateEvent(NULL, FALSE, FALSE, eventName); if ( GetLastError() == ERROR_ALREADY_EXISTS ) afsi_log("Event Object Already Exists: %s", eventName); sprintf(eventName, "NCBevents[0]"); - NCBevents[0] = thrd_CreateEvent(NULL, FALSE, FALSE, eventName); + NCBevents[0] = thrd_CreateEvent(NULL, FALSE, FALSE, eventName); if ( GetLastError() == ERROR_ALREADY_EXISTS ) afsi_log("Event Object Already Exists: %s", eventName); - NCBreturns = malloc(nThreads * sizeof(EVENT_HANDLE *)); + NCBreturns = malloc(nThreads * sizeof(EVENT_HANDLE *)); sprintf(eventName, "NCBreturns[0<=incb_command = NCBDELNAME; - ncbp->ncb_lana_num = lana_list.lana[i]; - memcpy(ncbp->ncb_name,smb_sharename,NCBNAMSZ); + for (i = 0; i < lana_list.length; i++) { + if (lana_list.lana[i] == 255) continue; + ncbp->ncb_command = NCBDELNAME; + ncbp->ncb_lana_num = lana_list.lana[i]; + memcpy(ncbp->ncb_name,smb_sharename,NCBNAMSZ); #ifndef DJGPP code = Netbios(ncbp); #else - code = Netbios(ncbp, dos_ncb); + code = Netbios(ncbp, dos_ncb); #endif - if (code == 0) code = ncbp->ncb_retcode; - if (code != 0) { - fprintf(stderr, "Netbios NCBDELNAME lana %d error code %d", - ncbp->ncb_lana_num, code); - } - fflush(stderr); - } + if (code == 0) + code = ncbp->ncb_retcode; + if (code != 0) { + fprintf(stderr, "Netbios NCBDELNAME lana %d error code %d", + ncbp->ncb_lana_num, code); + } + fflush(stderr); + } } /* Get the UNC \\\ prefix. */ @@ -7816,9 +7793,9 @@ char *smb_GetSharename() { char *name; - /* Make sure we have been properly initialized. */ - if (smb_localNamep == NULL) - return NULL; + /* Make sure we have been properly initialized. */ + if (smb_localNamep == NULL) + return NULL; /* Allocate space for \\\, plus the * terminator. @@ -7832,63 +7809,62 @@ char *smb_GetSharename() #ifdef LOG_PACKET void smb_LogPacket(smb_packet_t *packet) { - BYTE *vp, *cp; - unsigned length, paramlen, datalen, i, j; - char buf[81]; - char hex[]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'}; - - if(!packet) return; + BYTE *vp, *cp; + unsigned length, paramlen, datalen, i, j; + char buf[81]; + char hex[]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'}; - osi_Log0(smb_logp, "*** SMB packet dump ***"); + if (!packet) return; - vp = (BYTE *) packet->data; + osi_Log0(smb_logp, "*** SMB packet dump ***"); - datalen = *((WORD*)(vp + (paramlen = ((unsigned)*(vp+20)) << 1))); - length = paramlen + 2 + datalen; + vp = (BYTE *) packet->data; + datalen = *((WORD*)(vp + (paramlen = ((unsigned)*(vp+20)) << 1))); + length = paramlen + 2 + datalen; - for(i=0;i < length; i+=16) - { - memset( buf, ' ', 80 ); - buf[80] = 0; - itoa( i, buf, 16 ); + for (i=0;i < length; i+=16) + { + memset( buf, ' ', 80 ); + buf[80] = 0; - buf[strlen(buf)] = ' '; + itoa( i, buf, 16 ); - cp = (BYTE*) buf + 7; + buf[strlen(buf)] = ' '; - for(j=0;j < 16 && (i+j)> 4]; - *(cp++) = hex[vp[i+j] & 0xf]; - *(cp++) = ' '; + cp = (BYTE*) buf + 7; - if(j==7) - { - *(cp++) = '-'; - *(cp++) = ' '; - } - } + for (j=0;j < 16 && (i+j)> 4]; + *(cp++) = hex[vp[i+j] & 0xf]; + *(cp++) = ' '; - for(j=0;j < 16 && (i+j) vp[i+j] )? vp[i+j]:'.'; - if(j==7) - { - *(cp++) = ' '; - *(cp++) = '-'; - *(cp++) = ' '; - } - } + if (j==7) + { + *(cp++) = '-'; + *(cp++) = ' '; + } + } - *cp = 0; + for (j=0;j < 16 && (i+j) vp[i+j] )? vp[i+j]:'.'; + if (j==7) + { + *(cp++) = ' '; + *(cp++) = '-'; + *(cp++) = ' '; + } + } - osi_Log0( smb_logp, osi_LogSaveString(smb_logp, buf)); - } + *cp = 0; - osi_Log0(smb_logp, "*** End SMB packet dump ***"); + osi_Log0( smb_logp, osi_LogSaveString(smb_logp, buf)); + } + osi_Log0(smb_logp, "*** End SMB packet dump ***"); } #endif /* LOG_PACKET */ diff --git a/src/WINNT/afsd/smb.h b/src/WINNT/afsd/smb.h index 4e83730..9271bcb 100644 --- a/src/WINNT/afsd/smb.h +++ b/src/WINNT/afsd/smb.h @@ -141,7 +141,7 @@ typedef struct myncb { /* one per virtual circuit */ typedef struct smb_vc { struct smb_vc *nextp; /* not used */ - int refCount; /* the reference count */ + unsigned long refCount; /* the reference count */ long flags; /* the flags, if any; locked by mx */ osi_mutex_t mx; /* the mutex */ long vcID; /* VC id */ @@ -177,7 +177,7 @@ typedef struct smb_vc { /* one per user session */ typedef struct smb_user { struct smb_user *nextp; /* next sibling */ - long refCount; /* ref count */ + unsigned long refCount; /* ref count */ long flags; /* flags; locked by mx */ osi_mutex_t mx; long userID; /* the session identifier */ @@ -187,7 +187,7 @@ typedef struct smb_user { typedef struct smb_username { struct smb_username *nextp; /* next sibling */ - long refCount; /* ref count */ + unsigned long refCount; /* ref count */ long flags; /* flags; locked by mx */ osi_mutex_t mx; struct cm_user *userp; /* CM user structure */ @@ -202,7 +202,7 @@ typedef struct smb_username { /* one per tree-connect */ typedef struct smb_tid { struct smb_tid *nextp; /* next sibling */ - long refCount; + unsigned long refCount; long flags; osi_mutex_t mx; /* for non-tree-related stuff */ unsigned short tid; /* the tid */ @@ -218,7 +218,7 @@ typedef struct smb_tid { /* one per process ID */ typedef struct smb_pid { struct smb_pid *nextp; /* next sibling */ - long refCount; + unsigned long refCount; long flags; osi_mutex_t mx; /* for non-tree-related stuff */ unsigned short pid; /* the pid */ @@ -260,8 +260,8 @@ typedef struct smb_ioctl { /* one per file ID; these are really file descriptors */ typedef struct smb_fid { osi_queue_t q; - long refCount; - long flags; + unsigned long refCount; + unsigned long flags; osi_mutex_t mx; /* for non-tree-related stuff */ unsigned short fid; /* the file ID */ struct smb_vc *vcp; /* back ptr */ @@ -313,7 +313,7 @@ typedef struct smb_fid { typedef struct smb_dirSearch { osi_queue_t q; /* queue of all outstanding cookies */ osi_mutex_t mx; /* just in case the caller screws up */ - int refCount; /* reference count */ + unsigned long refCount; /* reference count */ long cookie; /* value returned to the caller */ struct cm_scache *scp; /* vnode of the dir we're searching */ time_t lastTime; /* last time we used this */ diff --git a/src/WINNT/afsd/smb3.c b/src/WINNT/afsd/smb3.c index 4e56d16..9c8691f 100644 --- a/src/WINNT/afsd/smb3.c +++ b/src/WINNT/afsd/smb3.c @@ -44,18 +44,18 @@ smb_tran2Packet_t *smb_tran2AssemblyQueuep; * request */ cm_user_t *smb_GetTran2User(smb_vc_t *vcp, smb_tran2Packet_t *inp) { - smb_user_t *uidp; + smb_user_t *uidp; cm_user_t *up = NULL; uidp = smb_FindUID(vcp, inp->uid, 0); if (!uidp) return NULL; - lock_ObtainMutex(&uidp->mx); + lock_ObtainMutex(&uidp->mx); if (uidp->unp) { up = uidp->unp->userp; cm_HoldUser(up); } - lock_ReleaseMutex(&uidp->mx); + lock_ReleaseMutex(&uidp->mx); smb_ReleaseUID(uidp); @@ -69,44 +69,44 @@ cm_user_t *smb_GetTran2User(smb_vc_t *vcp, smb_tran2Packet_t *inp) */ unsigned long smb_ExtAttributes(cm_scache_t *scp) { - unsigned long attrs; - - if (scp->fileType == CM_SCACHETYPE_DIRECTORY - || scp->fileType == CM_SCACHETYPE_MOUNTPOINT) - attrs = SMB_ATTR_DIRECTORY; - else - attrs = 0; - /* - * We used to mark a file RO if it was in an RO volume, but that - * turns out to be impolitic in NT. See defect 10007. - */ + unsigned long attrs; + + if (scp->fileType == CM_SCACHETYPE_DIRECTORY || + scp->fileType == CM_SCACHETYPE_MOUNTPOINT) + attrs = SMB_ATTR_DIRECTORY; + else + attrs = 0; + /* + * We used to mark a file RO if it was in an RO volume, but that + * turns out to be impolitic in NT. See defect 10007. + */ #ifdef notdef - if ((scp->unixModeBits & 0222) == 0 || (scp->flags & CM_SCACHEFLAG_RO)) + if ((scp->unixModeBits & 0222) == 0 || (scp->flags & CM_SCACHEFLAG_RO)) #endif if ((scp->unixModeBits & 0222) == 0) - attrs |= SMB_ATTR_READONLY; /* Read-only */ + attrs |= SMB_ATTR_READONLY; /* Read-only */ - if (attrs == 0) - attrs = SMB_ATTR_NORMAL; /* FILE_ATTRIBUTE_NORMAL */ + if (attrs == 0) + attrs = SMB_ATTR_NORMAL; /* FILE_ATTRIBUTE_NORMAL */ - return attrs; + return attrs; } int smb_V3IsStarMask(char *maskp) { char tc; - while (tc = *maskp++) + while (tc = *maskp++) if (tc == '?' || tc == '*') return 1; - return 0; + return 0; } unsigned char *smb_ParseString(unsigned char *inp, char **chainpp) { if (chainpp) { - /* skip over null-terminated string */ - *chainpp = inp + strlen(inp) + 1; + /* skip over null-terminated string */ + *chainpp = inp + strlen(inp) + 1; } return inp; } @@ -135,7 +135,7 @@ void OutputDebugHexDump(unsigned char * buffer, int len) { OutputDebugF("Hexdump length [%d]",len); - for(i=0;iflags & SMB_VCFLAG_AUTH_IN_PROGRESS) { - secCtx = vcp->secCtx; - lock_ObtainMutex(&vcp->mx); - vcp->flags &= ~SMB_VCFLAG_AUTH_IN_PROGRESS; - vcp->secCtx = NULL; - lock_ReleaseMutex(&vcp->mx); - } + CredHandle creds; + TimeStamp expiry; + long code = 0; + SecBufferDesc secBufIn; + SecBuffer secTokIn; + SecBufferDesc secBufOut; + SecBuffer secTokOut; + CtxtHandle ctx; + struct smb_ext_context * secCtx = NULL; + struct smb_ext_context * newSecCtx = NULL; + void * assembledBlob = NULL; + int assembledBlobLength = 0; + ULONG flags; + + OutputDebugF("In smb_AuthenticateUserExt"); + + *secBlobOut = NULL; + *secBlobOutLength = 0; + + if (vcp->flags & SMB_VCFLAG_AUTH_IN_PROGRESS) { + secCtx = vcp->secCtx; + lock_ObtainMutex(&vcp->mx); + vcp->flags &= ~SMB_VCFLAG_AUTH_IN_PROGRESS; + vcp->secCtx = NULL; + lock_ReleaseMutex(&vcp->mx); + } if (secBlobIn) { OutputDebugF("Received incoming token:"); @@ -296,130 +294,128 @@ long smb_AuthenticateUserExt(smb_vc_t * vcp, char * usern, char * secBlobIn, int creds = secCtx->creds; ctx = secCtx->ctx; - if (secCtx->partialToken) { - assembledBlobLength = secCtx->partialTokenLen + secBlobInLength; - assembledBlob = malloc(assembledBlobLength); + if (secCtx->partialToken) { + assembledBlobLength = secCtx->partialTokenLen + secBlobInLength; + assembledBlob = malloc(assembledBlobLength); memcpy(assembledBlob,secCtx->partialToken, secCtx->partialTokenLen); - memcpy(((BYTE *)assembledBlob) + secCtx->partialTokenLen, secBlobIn, secBlobInLength); - } - } else { - status = AcquireCredentialsHandle( - NULL, - SMB_EXT_SEC_PACKAGE_NAME, - SECPKG_CRED_INBOUND, - NULL, - NULL, - NULL, - NULL, - &creds, - &expiry); - - if (status != SEC_E_OK) { - OutputDebugF("Can't acquire Credentials handle [%lX]", status); - code = CM_ERROR_BADPASSWORD; /* means "try again when I'm sober" */ - goto aue_0; - } - - ctx.dwLower = 0; - ctx.dwUpper = 0; - } + memcpy(((BYTE *)assembledBlob) + secCtx->partialTokenLen, secBlobIn, secBlobInLength); + } + } else { + status = AcquireCredentialsHandle( NULL, + SMB_EXT_SEC_PACKAGE_NAME, + SECPKG_CRED_INBOUND, + NULL, + NULL, + NULL, + NULL, + &creds, + &expiry); + + if (status != SEC_E_OK) { + OutputDebugF("Can't acquire Credentials handle [%lX]", status); + code = CM_ERROR_BADPASSWORD; /* means "try again when I'm sober" */ + goto aue_0; + } + + ctx.dwLower = 0; + ctx.dwUpper = 0; + } secBufIn.cBuffers = 1; - secBufIn.pBuffers = &secTokIn; - secBufIn.ulVersion = SECBUFFER_VERSION; - - secTokIn.BufferType = SECBUFFER_TOKEN; - if (assembledBlob) { - secTokIn.cbBuffer = assembledBlobLength; - secTokIn.pvBuffer = assembledBlob; - } else { - secTokIn.cbBuffer = secBlobInLength; - secTokIn.pvBuffer = secBlobIn; - } + secBufIn.pBuffers = &secTokIn; + secBufIn.ulVersion = SECBUFFER_VERSION; + + secTokIn.BufferType = SECBUFFER_TOKEN; + if (assembledBlob) { + secTokIn.cbBuffer = assembledBlobLength; + secTokIn.pvBuffer = assembledBlob; + } else { + secTokIn.cbBuffer = secBlobInLength; + secTokIn.pvBuffer = secBlobIn; + } - secBufOut.cBuffers = 1; - secBufOut.pBuffers = &secTokOut; - secBufOut.ulVersion = SECBUFFER_VERSION; - - secTokOut.BufferType = SECBUFFER_TOKEN; - secTokOut.cbBuffer = 0; - secTokOut.pvBuffer = NULL; - - status = AcceptSecurityContext( - &creds, - ((secCtx)?&ctx:NULL), - &secBufIn, - ASC_REQ_CONNECTION | ASC_REQ_EXTENDED_ERROR | ASC_REQ_ALLOCATE_MEMORY, - SECURITY_NETWORK_DREP, - &ctx, - &secBufOut, - &flags, - &expiry - ); - - if (status == SEC_I_COMPLETE_NEEDED || status == SEC_I_COMPLETE_AND_CONTINUE) { - OutputDebugF("Completing token..."); - istatus = CompleteAuthToken(&ctx, &secBufOut); + secBufOut.cBuffers = 1; + secBufOut.pBuffers = &secTokOut; + secBufOut.ulVersion = SECBUFFER_VERSION; + + secTokOut.BufferType = SECBUFFER_TOKEN; + secTokOut.cbBuffer = 0; + secTokOut.pvBuffer = NULL; + + status = AcceptSecurityContext( &creds, + ((secCtx)?&ctx:NULL), + &secBufIn, + ASC_REQ_CONNECTION | ASC_REQ_EXTENDED_ERROR | ASC_REQ_ALLOCATE_MEMORY, + SECURITY_NETWORK_DREP, + &ctx, + &secBufOut, + &flags, + &expiry + ); + + if (status == SEC_I_COMPLETE_NEEDED || status == SEC_I_COMPLETE_AND_CONTINUE) { + OutputDebugF("Completing token..."); + istatus = CompleteAuthToken(&ctx, &secBufOut); if ( istatus != SEC_E_OK ) OutputDebugF("Token completion failed: %lX", istatus); - } + } - if (status == SEC_I_COMPLETE_AND_CONTINUE || status == SEC_I_CONTINUE_NEEDED) { - OutputDebugF("Continue needed"); + if (status == SEC_I_COMPLETE_AND_CONTINUE || status == SEC_I_CONTINUE_NEEDED) { + OutputDebugF("Continue needed"); - newSecCtx = malloc(sizeof(*newSecCtx)); + newSecCtx = malloc(sizeof(*newSecCtx)); - newSecCtx->creds = creds; - newSecCtx->ctx = ctx; - newSecCtx->partialToken = NULL; - newSecCtx->partialTokenLen = 0; + newSecCtx->creds = creds; + newSecCtx->ctx = ctx; + newSecCtx->partialToken = NULL; + newSecCtx->partialTokenLen = 0; - lock_ObtainMutex( &vcp->mx ); - vcp->flags |= SMB_VCFLAG_AUTH_IN_PROGRESS; - vcp->secCtx = newSecCtx; - lock_ReleaseMutex( &vcp->mx ); + lock_ObtainMutex( &vcp->mx ); + vcp->flags |= SMB_VCFLAG_AUTH_IN_PROGRESS; + vcp->secCtx = newSecCtx; + lock_ReleaseMutex( &vcp->mx ); - code = CM_ERROR_GSSCONTINUE; - } + code = CM_ERROR_GSSCONTINUE; + } - if ((status == SEC_I_COMPLETE_NEEDED || status == SEC_E_OK || - status == SEC_I_COMPLETE_AND_CONTINUE || status == SEC_I_CONTINUE_NEEDED) && - secTokOut.pvBuffer) { - OutputDebugF("Need to send token back to client"); + if ((status == SEC_I_COMPLETE_NEEDED || status == SEC_E_OK || + status == SEC_I_COMPLETE_AND_CONTINUE || status == SEC_I_CONTINUE_NEEDED) && + secTokOut.pvBuffer) { + OutputDebugF("Need to send token back to client"); - *secBlobOutLength = secTokOut.cbBuffer; - *secBlobOut = malloc(secTokOut.cbBuffer); - memcpy(*secBlobOut, secTokOut.pvBuffer, secTokOut.cbBuffer); + *secBlobOutLength = secTokOut.cbBuffer; + *secBlobOut = malloc(secTokOut.cbBuffer); + memcpy(*secBlobOut, secTokOut.pvBuffer, secTokOut.cbBuffer); OutputDebugF("Outgoing token:"); OutputDebugHexDump(*secBlobOut,*secBlobOutLength); - } else if (status == SEC_E_INCOMPLETE_MESSAGE) { - OutputDebugF("Incomplete message"); + } else if (status == SEC_E_INCOMPLETE_MESSAGE) { + OutputDebugF("Incomplete message"); - newSecCtx = malloc(sizeof(*newSecCtx)); + newSecCtx = malloc(sizeof(*newSecCtx)); - newSecCtx->creds = creds; - newSecCtx->ctx = ctx; - newSecCtx->partialToken = malloc(secTokOut.cbBuffer); - memcpy(newSecCtx->partialToken, secTokOut.pvBuffer, secTokOut.cbBuffer); - newSecCtx->partialTokenLen = secTokOut.cbBuffer; + newSecCtx->creds = creds; + newSecCtx->ctx = ctx; + newSecCtx->partialToken = malloc(secTokOut.cbBuffer); + memcpy(newSecCtx->partialToken, secTokOut.pvBuffer, secTokOut.cbBuffer); + newSecCtx->partialTokenLen = secTokOut.cbBuffer; - lock_ObtainMutex( &vcp->mx ); - vcp->flags |= SMB_VCFLAG_AUTH_IN_PROGRESS; - vcp->secCtx = newSecCtx; - lock_ReleaseMutex( &vcp->mx ); + lock_ObtainMutex( &vcp->mx ); + vcp->flags |= SMB_VCFLAG_AUTH_IN_PROGRESS; + vcp->secCtx = newSecCtx; + lock_ReleaseMutex( &vcp->mx ); - code = CM_ERROR_GSSCONTINUE; - } + code = CM_ERROR_GSSCONTINUE; + } - if (status == SEC_E_OK || status == SEC_I_COMPLETE_NEEDED) { - /* woo hoo! */ - SecPkgContext_Names names; + if (status == SEC_E_OK || status == SEC_I_COMPLETE_NEEDED) { + /* woo hoo! */ + SecPkgContext_Names names; - OutputDebugF("Authentication completed"); + OutputDebugF("Authentication completed"); OutputDebugF("Returned flags : [%lX]", flags); - if (!QueryContextAttributes(&ctx, SECPKG_ATTR_NAMES, &names)) { + if (!QueryContextAttributes(&ctx, SECPKG_ATTR_NAMES, &names)) { OutputDebugF("Received name [%s]", names.sUserName); strcpy(usern, names.sUserName); strlwr(usern); /* in tandem with smb_GetNormalizedUsername */ @@ -429,7 +425,7 @@ long smb_AuthenticateUserExt(smb_vc_t * vcp, char * usern, char * secBlobIn, int OutputDebugF("QueryContextAttributes Names failed [%x]", GetLastError()); code = CM_ERROR_BADPASSWORD; } - } else if (!code) { + } else if (!code) { switch ( status ) { case SEC_E_INVALID_TOKEN: OutputDebugF("Returning bad password :: INVALID_TOKEN"); @@ -461,28 +457,28 @@ long smb_AuthenticateUserExt(smb_vc_t * vcp, char * usern, char * secBlobIn, int default: OutputDebugF("Returning bad password :: Status == %lX", status); } - code = CM_ERROR_BADPASSWORD; - } + code = CM_ERROR_BADPASSWORD; + } - if (secCtx) { - if (secCtx->partialToken) free(secCtx->partialToken); - free(secCtx); - } + if (secCtx) { + if (secCtx->partialToken) free(secCtx->partialToken); + free(secCtx); + } - if (assembledBlob) { - free(assembledBlob); - } + if (assembledBlob) { + free(assembledBlob); + } - if (secTokOut.pvBuffer) - FreeContextBuffer(secTokOut.pvBuffer); + if (secTokOut.pvBuffer) + FreeContextBuffer(secTokOut.pvBuffer); - if (code != CM_ERROR_GSSCONTINUE) { - DeleteSecurityContext(&ctx); - FreeCredentialsHandle(&creds); - } + if (code != CM_ERROR_GSSCONTINUE) { + DeleteSecurityContext(&ctx); + FreeCredentialsHandle(&creds); + } aue_0: - return code; + return code; } #define P_LEN 256 @@ -491,153 +487,152 @@ long smb_AuthenticateUserExt(smb_vc_t * vcp, char * usern, char * secBlobIn, int /* LsaLogonUser expects input parameters to be in a contiguous block of memory. So put stuff in a struct. */ struct Lm20AuthBlob { - MSV1_0_LM20_LOGON lmlogon; - BYTE ciResponse[P_RESP_LEN]; /* Unicode representation */ - BYTE csResponse[P_RESP_LEN]; /* ANSI representation */ - WCHAR accountNameW[P_LEN]; - WCHAR primaryDomainW[P_LEN]; - WCHAR workstationW[MAX_COMPUTERNAME_LENGTH + 1]; - TOKEN_GROUPS tgroups; - TOKEN_SOURCE tsource; + MSV1_0_LM20_LOGON lmlogon; + BYTE ciResponse[P_RESP_LEN]; /* Unicode representation */ + BYTE csResponse[P_RESP_LEN]; /* ANSI representation */ + WCHAR accountNameW[P_LEN]; + WCHAR primaryDomainW[P_LEN]; + WCHAR workstationW[MAX_COMPUTERNAME_LENGTH + 1]; + TOKEN_GROUPS tgroups; + TOKEN_SOURCE tsource; }; -long smb_AuthenticateUserLM(smb_vc_t *vcp, char * accountName, char * primaryDomain, char * ciPwd, unsigned ciPwdLength, char * csPwd, unsigned csPwdLength) { - - NTSTATUS nts, ntsEx; - struct Lm20AuthBlob lmAuth; - PMSV1_0_LM20_LOGON_PROFILE lmprofilep; - QUOTA_LIMITS quotaLimits; - DWORD size; - ULONG lmprofilepSize; - LUID lmSession; - HANDLE lmToken; - - OutputDebugF("In smb_AuthenticateUser for user [%s] domain [%s]", accountName, primaryDomain); - OutputDebugF("ciPwdLength is %d and csPwdLength is %d", ciPwdLength, csPwdLength); - - if (ciPwdLength > P_RESP_LEN || csPwdLength > P_RESP_LEN) { - OutputDebugF("ciPwdLength or csPwdLength is too long"); - return CM_ERROR_BADPASSWORD; - } +long smb_AuthenticateUserLM(smb_vc_t *vcp, char * accountName, char * primaryDomain, char * ciPwd, unsigned ciPwdLength, char * csPwd, unsigned csPwdLength) +{ + NTSTATUS nts, ntsEx; + struct Lm20AuthBlob lmAuth; + PMSV1_0_LM20_LOGON_PROFILE lmprofilep; + QUOTA_LIMITS quotaLimits; + DWORD size; + ULONG lmprofilepSize; + LUID lmSession; + HANDLE lmToken; + + OutputDebugF("In smb_AuthenticateUser for user [%s] domain [%s]", accountName, primaryDomain); + OutputDebugF("ciPwdLength is %d and csPwdLength is %d", ciPwdLength, csPwdLength); + + if (ciPwdLength > P_RESP_LEN || csPwdLength > P_RESP_LEN) { + OutputDebugF("ciPwdLength or csPwdLength is too long"); + return CM_ERROR_BADPASSWORD; + } - memset(&lmAuth,0,sizeof(lmAuth)); + memset(&lmAuth,0,sizeof(lmAuth)); - lmAuth.lmlogon.MessageType = MsV1_0NetworkLogon; + lmAuth.lmlogon.MessageType = MsV1_0NetworkLogon; - lmAuth.lmlogon.LogonDomainName.Buffer = lmAuth.primaryDomainW; - mbstowcs(lmAuth.primaryDomainW, primaryDomain, P_LEN); - lmAuth.lmlogon.LogonDomainName.Length = wcslen(lmAuth.primaryDomainW) * sizeof(WCHAR); - lmAuth.lmlogon.LogonDomainName.MaximumLength = P_LEN * sizeof(WCHAR); - - lmAuth.lmlogon.UserName.Buffer = lmAuth.accountNameW; - mbstowcs(lmAuth.accountNameW, accountName, P_LEN); - lmAuth.lmlogon.UserName.Length = wcslen(lmAuth.accountNameW) * sizeof(WCHAR); - lmAuth.lmlogon.UserName.MaximumLength = P_LEN * sizeof(WCHAR); - - lmAuth.lmlogon.Workstation.Buffer = lmAuth.workstationW; - lmAuth.lmlogon.Workstation.MaximumLength = (MAX_COMPUTERNAME_LENGTH + 1) * sizeof(WCHAR); - size = MAX_COMPUTERNAME_LENGTH + 1; - GetComputerNameW(lmAuth.workstationW, &size); + lmAuth.lmlogon.LogonDomainName.Buffer = lmAuth.primaryDomainW; + mbstowcs(lmAuth.primaryDomainW, primaryDomain, P_LEN); + lmAuth.lmlogon.LogonDomainName.Length = wcslen(lmAuth.primaryDomainW) * sizeof(WCHAR); + lmAuth.lmlogon.LogonDomainName.MaximumLength = P_LEN * sizeof(WCHAR); + + lmAuth.lmlogon.UserName.Buffer = lmAuth.accountNameW; + mbstowcs(lmAuth.accountNameW, accountName, P_LEN); + lmAuth.lmlogon.UserName.Length = wcslen(lmAuth.accountNameW) * sizeof(WCHAR); + lmAuth.lmlogon.UserName.MaximumLength = P_LEN * sizeof(WCHAR); + + lmAuth.lmlogon.Workstation.Buffer = lmAuth.workstationW; + lmAuth.lmlogon.Workstation.MaximumLength = (MAX_COMPUTERNAME_LENGTH + 1) * sizeof(WCHAR); + size = MAX_COMPUTERNAME_LENGTH + 1; + GetComputerNameW(lmAuth.workstationW, &size); lmAuth.lmlogon.Workstation.Length = wcslen(lmAuth.workstationW) * sizeof(WCHAR); - memcpy(lmAuth.lmlogon.ChallengeToClient, vcp->encKey, MSV1_0_CHALLENGE_LENGTH); - - lmAuth.lmlogon.CaseInsensitiveChallengeResponse.Buffer = lmAuth.ciResponse; - lmAuth.lmlogon.CaseInsensitiveChallengeResponse.Length = ciPwdLength; - lmAuth.lmlogon.CaseInsensitiveChallengeResponse.MaximumLength = P_RESP_LEN; - memcpy(lmAuth.ciResponse, ciPwd, ciPwdLength); - - lmAuth.lmlogon.CaseSensitiveChallengeResponse.Buffer = lmAuth.csResponse; - lmAuth.lmlogon.CaseSensitiveChallengeResponse.Length = csPwdLength; - lmAuth.lmlogon.CaseSensitiveChallengeResponse.MaximumLength = P_RESP_LEN; - memcpy(lmAuth.csResponse, csPwd, csPwdLength); - - lmAuth.lmlogon.ParameterControl = 0; - - lmAuth.tgroups.GroupCount = 0; - lmAuth.tgroups.Groups[0].Sid = NULL; - lmAuth.tgroups.Groups[0].Attributes = 0; - - lmAuth.tsource.SourceIdentifier.HighPart = 0; - lmAuth.tsource.SourceIdentifier.LowPart = (DWORD) vcp; - strcpy(lmAuth.tsource.SourceName,"OpenAFS"); /* 8 char limit */ - - nts = LsaLogonUser( - smb_lsaHandle, - &smb_lsaLogonOrigin, - Network, /*3*/ - smb_lsaSecPackage, - &lmAuth, - sizeof(lmAuth), - &lmAuth.tgroups, - &lmAuth.tsource, - &lmprofilep, - &lmprofilepSize, - &lmSession, - &lmToken, - "aLimits, - &ntsEx); - - OutputDebugF("Return from LsaLogonUser is 0x%lX", nts); - OutputDebugF("Extended status is 0x%lX", ntsEx); - - if (nts == ERROR_SUCCESS) { - /* free the token */ - LsaFreeReturnBuffer(lmprofilep); + memcpy(lmAuth.lmlogon.ChallengeToClient, vcp->encKey, MSV1_0_CHALLENGE_LENGTH); + + lmAuth.lmlogon.CaseInsensitiveChallengeResponse.Buffer = lmAuth.ciResponse; + lmAuth.lmlogon.CaseInsensitiveChallengeResponse.Length = ciPwdLength; + lmAuth.lmlogon.CaseInsensitiveChallengeResponse.MaximumLength = P_RESP_LEN; + memcpy(lmAuth.ciResponse, ciPwd, ciPwdLength); + + lmAuth.lmlogon.CaseSensitiveChallengeResponse.Buffer = lmAuth.csResponse; + lmAuth.lmlogon.CaseSensitiveChallengeResponse.Length = csPwdLength; + lmAuth.lmlogon.CaseSensitiveChallengeResponse.MaximumLength = P_RESP_LEN; + memcpy(lmAuth.csResponse, csPwd, csPwdLength); + + lmAuth.lmlogon.ParameterControl = 0; + + lmAuth.tgroups.GroupCount = 0; + lmAuth.tgroups.Groups[0].Sid = NULL; + lmAuth.tgroups.Groups[0].Attributes = 0; + + lmAuth.tsource.SourceIdentifier.HighPart = 0; + lmAuth.tsource.SourceIdentifier.LowPart = (DWORD) vcp; + strcpy(lmAuth.tsource.SourceName,"OpenAFS"); /* 8 char limit */ + + nts = LsaLogonUser( smb_lsaHandle, + &smb_lsaLogonOrigin, + Network, /*3*/ + smb_lsaSecPackage, + &lmAuth, + sizeof(lmAuth), + &lmAuth.tgroups, + &lmAuth.tsource, + &lmprofilep, + &lmprofilepSize, + &lmSession, + &lmToken, + "aLimits, + &ntsEx); + + OutputDebugF("Return from LsaLogonUser is 0x%lX", nts); + OutputDebugF("Extended status is 0x%lX", ntsEx); + + if (nts == ERROR_SUCCESS) { + /* free the token */ + LsaFreeReturnBuffer(lmprofilep); CloseHandle(lmToken); - return 0; - } else { - /* No AFS for you */ - if (nts == 0xC000015BL) - return CM_ERROR_BADLOGONTYPE; - else /* our catchall is a bad password though we could be more specific */ - return CM_ERROR_BADPASSWORD; - } + return 0; + } else { + /* No AFS for you */ + if (nts == 0xC000015BL) + return CM_ERROR_BADLOGONTYPE; + else /* our catchall is a bad password though we could be more specific */ + return CM_ERROR_BADPASSWORD; + } } /* The buffer pointed to by usern is assumed to be at least SMB_MAX_USERNAME_LENGTH bytes */ -long smb_GetNormalizedUsername(char * usern, const char * accountName, const char * domainName) { - - char * atsign; - const char * domain; - - /* check if we have sane input */ - if ((strlen(accountName) + strlen(domainName) + 1) > SMB_MAX_USERNAME_LENGTH) - return 1; - - /* we could get : [accountName][domainName] - [user][domain] - [user@domain][] - [user][]/[user][?] - [][]/[][?] */ - - atsign = strchr(accountName, '@'); - - if (atsign) /* [user@domain][] -> [user@domain][domain] */ - domain = atsign + 1; - else - domain = domainName; - - /* if for some reason the client doesn't know what domain to use, - it will either return an empty string or a '?' */ - if (!domain[0] || domain[0] == '?') - /* Empty domains and empty usernames are usually sent from tokenless contexts. - This way such logins will get an empty username (easy to check). I don't know - when a non-empty username would be supplied with an anonymous domain, but *shrug* */ - strcpy(usern,accountName); - else { - /* TODO: what about WIN.MIT.EDU\user vs. WIN\user? */ - strcpy(usern,domain); - strcat(usern,"\\"); - if (atsign) - strncat(usern,accountName,atsign - accountName); - else - strcat(usern,accountName); - } +long smb_GetNormalizedUsername(char * usern, const char * accountName, const char * domainName) +{ + char * atsign; + const char * domain; + + /* check if we have sane input */ + if ((strlen(accountName) + strlen(domainName) + 1) > SMB_MAX_USERNAME_LENGTH) + return 1; - strlwr(usern); + /* we could get : [accountName][domainName] + [user][domain] + [user@domain][] + [user][]/[user][?] + [][]/[][?] */ - return 0; + atsign = strchr(accountName, '@'); + + if (atsign) /* [user@domain][] -> [user@domain][domain] */ + domain = atsign + 1; + else + domain = domainName; + + /* if for some reason the client doesn't know what domain to use, + it will either return an empty string or a '?' */ + if (!domain[0] || domain[0] == '?') + /* Empty domains and empty usernames are usually sent from tokenless contexts. + This way such logins will get an empty username (easy to check). I don't know + when a non-empty username would be supplied with an anonymous domain, but *shrug* */ + strcpy(usern,accountName); + else { + /* TODO: what about WIN.MIT.EDU\user vs. WIN\user? */ + strcpy(usern,domain); + strcat(usern,"\\"); + if (atsign) + strncat(usern,accountName,atsign - accountName); + else + strcat(usern,accountName); + } + + strlwr(usern); + + return 0; } /* When using SMB auth, all SMB sessions have to pass through here first to @@ -739,52 +734,52 @@ long smb_ReceiveV3SessionSetupX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t * } else { /* V3 */ unsigned ciPwdLength; char *ciPwd; - char *accountName; - char *primaryDomain; + char *accountName; + char *primaryDomain; - ciPwdLength = smb_GetSMBParm(inp, 7); + ciPwdLength = smb_GetSMBParm(inp, 7); tp = smb_GetSMBData(inp, NULL); - ciPwd = tp; - tp += ciPwdLength; + ciPwd = tp; + tp += ciPwdLength; - accountName = smb_ParseString(tp, &tp); - primaryDomain = smb_ParseString(tp, NULL); + accountName = smb_ParseString(tp, &tp); + primaryDomain = smb_ParseString(tp, NULL); - if ( smb_GetNormalizedUsername(usern, accountName, primaryDomain)) { - /* shouldn't happen */ - code = CM_ERROR_BADSMB; + if ( smb_GetNormalizedUsername(usern, accountName, primaryDomain)) { + /* shouldn't happen */ + code = CM_ERROR_BADSMB; goto after_read_packet; - } + } /* even if we wanted extended auth, if we only negotiated V3, we have to fallback * to NTLM. */ - if (smb_authType == SMB_AUTH_NTLM || smb_authType == SMB_AUTH_EXTENDED) { - code = smb_AuthenticateUserLM(vcp,accountName,primaryDomain,ciPwd,ciPwdLength,"",0); - } - } + if (smb_authType == SMB_AUTH_NTLM || smb_authType == SMB_AUTH_EXTENDED) { + code = smb_AuthenticateUserLM(vcp,accountName,primaryDomain,ciPwd,ciPwdLength,"",0); + } + } after_read_packet: - /* note down that we received a session setup X and set the capabilities flag */ - if (!(vcp->flags & SMB_VCFLAG_SESSX_RCVD)) { - lock_ObtainMutex(&vcp->mx); - vcp->flags |= SMB_VCFLAG_SESSX_RCVD; + /* note down that we received a session setup X and set the capabilities flag */ + if (!(vcp->flags & SMB_VCFLAG_SESSX_RCVD)) { + lock_ObtainMutex(&vcp->mx); + vcp->flags |= SMB_VCFLAG_SESSX_RCVD; /* for the moment we can only deal with NTSTATUS */ if (caps & NTNEGOTIATE_CAPABILITY_NTSTATUS) { vcp->flags |= SMB_VCFLAG_STATUS32; - } - lock_ReleaseMutex(&vcp->mx); - } + } + lock_ReleaseMutex(&vcp->mx); + } - /* code would be non-zero if there was an authentication failure. - Ideally we would like to invalidate the uid for this session or break - early to avoid accidently stealing someone else's tokens. */ + /* code would be non-zero if there was an authentication failure. + Ideally we would like to invalidate the uid for this session or break + early to avoid accidently stealing someone else's tokens. */ - if (code) { - return code; - } + if (code) { + return code; + } - OutputDebugF("Received username=[%s]", usern); + OutputDebugF("Received username=[%s]", usern); /* On Windows 2000, this function appears to be called more often than it is expected to be called. This resulted in multiple smb_user_t @@ -1105,12 +1100,12 @@ smb_tran2Packet_t *smb_GetTran2ResponsePacket(smb_vc_t *vcp, void smb_FreeTran2Packet(smb_tran2Packet_t *t2p) { if (t2p->vcp) smb_ReleaseVC(t2p->vcp); - if (t2p->flags & SMB_TRAN2PFLAG_ALLOC) { - if (t2p->parmsp) - free(t2p->parmsp); - if (t2p->datap) - free(t2p->datap); - } + if (t2p->flags & SMB_TRAN2PFLAG_ALLOC) { + if (t2p->parmsp) + free(t2p->parmsp); + if (t2p->datap) + free(t2p->datap); + } free(t2p); } @@ -1123,19 +1118,19 @@ void smb_SendTran2Error(smb_vc_t *vcp, smb_tran2Packet_t *t2p, smb_t *smbp; unsigned short errCode; unsigned char errClass; - unsigned long NTStatus; + unsigned long NTStatus; if (vcp->flags & SMB_VCFLAG_STATUS32) - smb_MapNTError(code, &NTStatus); - else - smb_MapCoreError(code, vcp, &errCode, &errClass); + smb_MapNTError(code, &NTStatus); + else + smb_MapCoreError(code, vcp, &errCode, &errClass); smb_FormatResponsePacket(vcp, NULL, tp); smbp = (smb_t *) tp; - /* We can handle long names */ - if (vcp->flags & SMB_VCFLAG_USENT) - smbp->flg2 |= 0x40; /* IS_LONG_NAME */ + /* We can handle long names */ + if (vcp->flags & SMB_VCFLAG_USENT) + smbp->flg2 |= 0x40; /* IS_LONG_NAME */ /* now copy important fields from the tran 2 packet */ smbp->com = t2p->com; @@ -1143,19 +1138,19 @@ void smb_SendTran2Error(smb_vc_t *vcp, smb_tran2Packet_t *t2p, smbp->mid = t2p->mid; smbp->pid = t2p->pid; smbp->uid = t2p->uid; - smbp->res[0] = t2p->res[0]; - if (vcp->flags & SMB_VCFLAG_STATUS32) { - smbp->rcls = (unsigned char) (NTStatus & 0xff); - smbp->reh = (unsigned char) ((NTStatus >> 8) & 0xff); - smbp->errLow = (unsigned char) ((NTStatus >> 16) & 0xff); - smbp->errHigh = (unsigned char) ((NTStatus >> 24) & 0xff); - smbp->flg2 |= 0x4000; - } - else { + smbp->res[0] = t2p->res[0]; + if (vcp->flags & SMB_VCFLAG_STATUS32) { + smbp->rcls = (unsigned char) (NTStatus & 0xff); + smbp->reh = (unsigned char) ((NTStatus >> 8) & 0xff); + smbp->errLow = (unsigned char) ((NTStatus >> 16) & 0xff); + smbp->errHigh = (unsigned char) ((NTStatus >> 24) & 0xff); + smbp->flg2 |= 0x4000; + } + else { smbp->rcls = errClass; - smbp->errLow = (unsigned char) (errCode & 0xff); - smbp->errHigh = (unsigned char) ((errCode >> 8) & 0xff); - } + smbp->errLow = (unsigned char) (errCode & 0xff); + smbp->errHigh = (unsigned char) ((errCode >> 8) & 0xff); + } /* send packet */ smb_SendPacket(vcp, tp); @@ -1165,17 +1160,17 @@ void smb_SendTran2Packet(smb_vc_t *vcp, smb_tran2Packet_t *t2p, smb_packet_t *tp { smb_t *smbp; unsigned short parmOffset; - unsigned short dataOffset; - unsigned short totalLength; - unsigned short dataAlign; + unsigned short dataOffset; + unsigned short totalLength; + unsigned short dataAlign; char *datap; - + smb_FormatResponsePacket(vcp, NULL, tp); smbp = (smb_t *) tp; - /* We can handle long names */ - if (vcp->flags & SMB_VCFLAG_USENT) - smbp->flg2 |= 0x40; /* IS_LONG_NAME */ + /* We can handle long names */ + if (vcp->flags & SMB_VCFLAG_USENT) + smbp->flg2 |= 0x40; /* IS_LONG_NAME */ /* now copy important fields from the tran 2 packet */ smbp->com = t2p->com; @@ -1183,7 +1178,7 @@ void smb_SendTran2Packet(smb_vc_t *vcp, smb_tran2Packet_t *t2p, smb_packet_t *tp smbp->mid = t2p->mid; smbp->pid = t2p->pid; smbp->uid = t2p->uid; - smbp->res[0] = t2p->res[0]; + smbp->res[0] = t2p->res[0]; totalLength = 1 + t2p->totalData + t2p->totalParms; @@ -1192,24 +1187,24 @@ void smb_SendTran2Packet(smb_vc_t *vcp, smb_tran2Packet_t *t2p, smb_packet_t *tp smb_SetSMBParm(tp, 1, t2p->totalData); /* data bytes */ smb_SetSMBParm(tp, 2, 0); /* reserved */ smb_SetSMBParm(tp, 3, t2p->totalParms); /* parm bytes in this packet */ - parmOffset = 10*2 + 35; /* parm offset in packet */ - parmOffset++; /* round to even */ + parmOffset = 10*2 + 35; /* parm offset in packet */ + parmOffset++; /* round to even */ smb_SetSMBParm(tp, 4, parmOffset); /* 11 parm words plus * * hdr, bcc and wct */ smb_SetSMBParm(tp, 5, 0); /* parm displacement */ smb_SetSMBParm(tp, 6, t2p->totalData); /* data in this packet */ - dataOffset = parmOffset + t2p->oldTotalParms; - dataAlign = dataOffset & 2; /* quad-align */ - dataOffset += dataAlign; + dataOffset = parmOffset + t2p->oldTotalParms; + dataAlign = dataOffset & 2; /* quad-align */ + dataOffset += dataAlign; smb_SetSMBParm(tp, 7, dataOffset); /* offset of data */ smb_SetSMBParm(tp, 8, 0); /* data displacement */ smb_SetSMBParm(tp, 9, 0); /* low: setup word count * * high: resvd */ datap = smb_GetSMBData(tp, NULL); - *datap++ = 0; /* we rounded to even */ + *datap++ = 0; /* we rounded to even */ - totalLength += dataAlign; + totalLength += dataAlign; smb_SetSMBDataLength(tp, totalLength); /* next, send the datagram */ @@ -1228,56 +1223,56 @@ long smb_ReceiveV3Trans(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) int parmCount; int dataCount; int firstPacket; - int rapOp; + int rapOp; long code = 0; - /* We sometimes see 0 word count. What to do? */ - if (*inp->wctp == 0) { + /* We sometimes see 0 word count. What to do? */ + if (*inp->wctp == 0) { #ifndef DJGPP - HANDLE h; - char *ptbuf[1]; + HANDLE h; + char *ptbuf[1]; - osi_Log0(smb_logp, "TRANSACTION word count = 0"); + osi_Log0(smb_logp, "TRANSACTION word count = 0"); - h = RegisterEventSource(NULL, AFS_DAEMON_EVENT_NAME); - ptbuf[0] = "Transaction2 word count = 0"; - ReportEvent(h, EVENTLOG_WARNING_TYPE, 0, 1003, NULL, - 1, inp->ncb_length, ptbuf, inp); - DeregisterEventSource(h); + h = RegisterEventSource(NULL, AFS_DAEMON_EVENT_NAME); + ptbuf[0] = "Transaction2 word count = 0"; + ReportEvent(h, EVENTLOG_WARNING_TYPE, 0, 1003, NULL, + 1, inp->ncb_length, ptbuf, inp); + DeregisterEventSource(h); #else /* DJGPP */ - osi_Log0(smb_logp, "TRANSACTION word count = 0"); + osi_Log0(smb_logp, "TRANSACTION word count = 0"); #endif /* !DJGPP */ smb_SetSMBDataLength(outp, 0); smb_SendPacket(vcp, outp); - return 0; - } + return 0; + } totalParms = smb_GetSMBParm(inp, 0); totalData = smb_GetSMBParm(inp, 1); firstPacket = (inp->inCom == 0x25); - /* find the packet we're reassembling */ - lock_ObtainWrite(&smb_globalLock); + /* find the packet we're reassembling */ + lock_ObtainWrite(&smb_globalLock); asp = smb_FindTran2Packet(vcp, inp); if (!asp) { asp = smb_NewTran2Packet(vcp, inp, totalParms, totalData); - } + } lock_ReleaseWrite(&smb_globalLock); /* now merge in this latest packet; start by looking up offsets */ - if (firstPacket) { - parmDisp = dataDisp = 0; + if (firstPacket) { + parmDisp = dataDisp = 0; parmOffset = smb_GetSMBParm(inp, 10); dataOffset = smb_GetSMBParm(inp, 12); parmCount = smb_GetSMBParm(inp, 9); dataCount = smb_GetSMBParm(inp, 11); - asp->maxReturnParms = smb_GetSMBParm(inp, 2); + asp->maxReturnParms = smb_GetSMBParm(inp, 2); asp->maxReturnData = smb_GetSMBParm(inp, 3); - osi_Log3(smb_logp, "SMB3 received Trans init packet total data %d, cur data %d, max return data %d", - totalData, dataCount, asp->maxReturnData); + osi_Log3(smb_logp, "SMB3 received Trans init packet total data %d, cur data %d, max return data %d", + totalData, dataCount, asp->maxReturnData); } else { parmDisp = smb_GetSMBParm(inp, 4); @@ -1309,13 +1304,13 @@ long smb_ReceiveV3Trans(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) asp->curParms > 0 && asp->totalData <= asp->curData && asp->totalParms <= asp->curParms) { - /* we've received it all */ + /* we've received it all */ lock_ObtainWrite(&smb_globalLock); - osi_QRemove((osi_queue_t **) &smb_tran2AssemblyQueuep, &asp->q); + osi_QRemove((osi_queue_t **) &smb_tran2AssemblyQueuep, &asp->q); lock_ReleaseWrite(&smb_globalLock); /* now dispatch it */ - rapOp = asp->parmsp[0]; + rapOp = asp->parmsp[0]; if ( rapOp >= 0 && rapOp < SMB_RAP_NOPCODES && smb_rapDispatchTable[rapOp].procp) { osi_LogEvent("AFS-Dispatch-RAP[%s]",myCrt_RapDispatch(rapOp),"vcp[%x] lana[%d] lsn[%d]",(int)vcp,vcp->lana,vcp->lsn); @@ -1357,416 +1352,416 @@ long smb_ReceiveV3Trans(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) share names, but we don't support unicode yet. */ typedef struct smb_rap_share_info_0 { - char shi0_netname[13]; + char shi0_netname[13]; } smb_rap_share_info_0_t; typedef struct smb_rap_share_info_1 { - char shi1_netname[13]; - char shi1_pad; - WORD shi1_type; - DWORD shi1_remark; /* char *shi1_remark; data offset */ + char shi1_netname[13]; + char shi1_pad; + WORD shi1_type; + DWORD shi1_remark; /* char *shi1_remark; data offset */ } smb_rap_share_info_1_t; typedef struct smb_rap_share_info_2 { - char shi2_netname[13]; - char shi2_pad; - unsigned short shi2_type; - DWORD shi2_remark; /* char *shi2_remark; data offset */ - unsigned short shi2_permissions; - unsigned short shi2_max_uses; - unsigned short shi2_current_uses; - DWORD shi2_path; /* char *shi2_path; data offset */ - unsigned short shi2_passwd[9]; - unsigned short shi2_pad2; + char shi2_netname[13]; + char shi2_pad; + unsigned short shi2_type; + DWORD shi2_remark; /* char *shi2_remark; data offset */ + unsigned short shi2_permissions; + unsigned short shi2_max_uses; + unsigned short shi2_current_uses; + DWORD shi2_path; /* char *shi2_path; data offset */ + unsigned short shi2_passwd[9]; + unsigned short shi2_pad2; } smb_rap_share_info_2_t; #define SMB_RAP_MAX_SHARES 512 typedef struct smb_rap_share_list { - int cShare; - int maxShares; - smb_rap_share_info_0_t * shares; + int cShare; + int maxShares; + smb_rap_share_info_0_t * shares; } smb_rap_share_list_t; int smb_rapCollectSharesProc(cm_scache_t *dscp, cm_dirEntry_t *dep, void *vrockp, osi_hyper_t *offp) { - smb_rap_share_list_t * sp; - char * name; + smb_rap_share_list_t * sp; + char * name; - name = dep->name; + name = dep->name; - if(name[0] == '.' && (!name[1] || (name[1] == '.' && !name[2]))) - return 0; /* skip over '.' and '..' */ + if (name[0] == '.' && (!name[1] || (name[1] == '.' && !name[2]))) + return 0; /* skip over '.' and '..' */ - sp = (smb_rap_share_list_t *) vrockp; + sp = (smb_rap_share_list_t *) vrockp; - strncpy(sp->shares[sp->cShare].shi0_netname, name, 12); - sp->shares[sp->cShare].shi0_netname[12] = 0; + strncpy(sp->shares[sp->cShare].shi0_netname, name, 12); + sp->shares[sp->cShare].shi0_netname[12] = 0; - sp->cShare++; + sp->cShare++; - if(sp->cShare >= sp->maxShares) - return CM_ERROR_STOPNOW; - else - return 0; -} + if (sp->cShare >= sp->maxShares) + return CM_ERROR_STOPNOW; + else + return 0; +} long smb_ReceiveRAPNetShareEnum(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *op) { - smb_tran2Packet_t *outp; - unsigned short * tp; - int len; - int infoLevel; - int bufsize; - int outParmsTotal; /* total parameter bytes */ - int outDataTotal; /* total data bytes */ - int code = 0; - DWORD rv; - DWORD allSubmount; - USHORT nShares; - DWORD nRegShares; - DWORD nSharesRet; - HKEY hkParam; - HKEY hkSubmount = NULL; - smb_rap_share_info_1_t * shares; - USHORT cshare = 0; - char * cstrp; - char thisShare[256]; - int i,j; - int nonrootShares; - smb_rap_share_list_t rootShares; - cm_req_t req; - cm_user_t * userp; - osi_hyper_t thyper; - - tp = p->parmsp + 1; /* skip over function number (always 0) */ - (void) smb_ParseString((char *) tp, (char **) &tp); /* skip over parm descriptor */ - (void) smb_ParseString((char *) tp, (char **) &tp); /* skip over data descriptor */ - infoLevel = tp[0]; + smb_tran2Packet_t *outp; + unsigned short * tp; + int len; + int infoLevel; + int bufsize; + int outParmsTotal; /* total parameter bytes */ + int outDataTotal; /* total data bytes */ + int code = 0; + DWORD rv; + DWORD allSubmount; + USHORT nShares; + DWORD nRegShares; + DWORD nSharesRet; + HKEY hkParam; + HKEY hkSubmount = NULL; + smb_rap_share_info_1_t * shares; + USHORT cshare = 0; + char * cstrp; + char thisShare[256]; + int i,j; + int nonrootShares; + smb_rap_share_list_t rootShares; + cm_req_t req; + cm_user_t * userp; + osi_hyper_t thyper; + + tp = p->parmsp + 1; /* skip over function number (always 0) */ + (void) smb_ParseString((char *) tp, (char **) &tp); /* skip over parm descriptor */ + (void) smb_ParseString((char *) tp, (char **) &tp); /* skip over data descriptor */ + infoLevel = tp[0]; bufsize = tp[1]; - if(infoLevel != 1) { - return CM_ERROR_INVAL; - } + if (infoLevel != 1) { + return CM_ERROR_INVAL; + } - /* first figure out how many shares there are */ + /* first figure out how many shares there are */ rv = RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSConfigKeyName, 0, - KEY_QUERY_VALUE, &hkParam); - if (rv == ERROR_SUCCESS) { + KEY_QUERY_VALUE, &hkParam); + if (rv == ERROR_SUCCESS) { len = sizeof(allSubmount); rv = RegQueryValueEx(hkParam, "AllSubmount", NULL, NULL, - (BYTE *) &allSubmount, &len); - if (rv != ERROR_SUCCESS || allSubmount != 0) { - allSubmount = 1; - } + (BYTE *) &allSubmount, &len); + if (rv != ERROR_SUCCESS || allSubmount != 0) { + allSubmount = 1; + } RegCloseKey (hkParam); - } + } - rv = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\OpenAFS\\Client\\Submounts", - 0, KEY_QUERY_VALUE, &hkSubmount); - if (rv == ERROR_SUCCESS) { + rv = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\OpenAFS\\Client\\Submounts", + 0, KEY_QUERY_VALUE, &hkSubmount); + if (rv == ERROR_SUCCESS) { rv = RegQueryInfoKey(hkSubmount, NULL, NULL, NULL, NULL, - NULL, NULL, &nRegShares, NULL, NULL, NULL, NULL); - if (rv != ERROR_SUCCESS) - nRegShares = 0; - } else { - hkSubmount = NULL; - } + NULL, NULL, &nRegShares, NULL, NULL, NULL, NULL); + if (rv != ERROR_SUCCESS) + nRegShares = 0; + } else { + hkSubmount = NULL; + } - /* fetch the root shares */ - rootShares.maxShares = SMB_RAP_MAX_SHARES; - rootShares.cShare = 0; - rootShares.shares = malloc( sizeof(smb_rap_share_info_0_t) * SMB_RAP_MAX_SHARES ); + /* fetch the root shares */ + rootShares.maxShares = SMB_RAP_MAX_SHARES; + rootShares.cShare = 0; + rootShares.shares = malloc( sizeof(smb_rap_share_info_0_t) * SMB_RAP_MAX_SHARES ); - cm_InitReq(&req); + cm_InitReq(&req); - userp = smb_GetTran2User(vcp,p); + userp = smb_GetTran2User(vcp,p); - thyper.HighPart = 0; - thyper.LowPart = 0; + thyper.HighPart = 0; + thyper.LowPart = 0; - cm_HoldSCache(cm_rootSCachep); - cm_ApplyDir(cm_rootSCachep, smb_rapCollectSharesProc, &rootShares, &thyper, userp, &req, NULL); - cm_ReleaseSCache(cm_rootSCachep); + cm_HoldSCache(cm_rootSCachep); + cm_ApplyDir(cm_rootSCachep, smb_rapCollectSharesProc, &rootShares, &thyper, userp, &req, NULL); + cm_ReleaseSCache(cm_rootSCachep); - cm_ReleaseUser(userp); + cm_ReleaseUser(userp); - nShares = rootShares.cShare + nRegShares + allSubmount; + nShares = rootShares.cShare + nRegShares + allSubmount; #define REMARK_LEN 1 - outParmsTotal = 8; /* 4 dwords */ - outDataTotal = (sizeof(smb_rap_share_info_1_t) + REMARK_LEN) * nShares ; - if(outDataTotal > bufsize) { - nSharesRet = bufsize / (sizeof(smb_rap_share_info_1_t) + REMARK_LEN); - outDataTotal = (sizeof(smb_rap_share_info_1_t) + REMARK_LEN) * nSharesRet; - } - else { - nSharesRet = nShares; - } + outParmsTotal = 8; /* 4 dwords */ + outDataTotal = (sizeof(smb_rap_share_info_1_t) + REMARK_LEN) * nShares ; + if(outDataTotal > bufsize) { + nSharesRet = bufsize / (sizeof(smb_rap_share_info_1_t) + REMARK_LEN); + outDataTotal = (sizeof(smb_rap_share_info_1_t) + REMARK_LEN) * nSharesRet; + } + else { + nSharesRet = nShares; + } - outp = smb_GetTran2ResponsePacket(vcp, p, op, outParmsTotal, outDataTotal); + outp = smb_GetTran2ResponsePacket(vcp, p, op, outParmsTotal, outDataTotal); - /* now for the submounts */ + /* now for the submounts */ shares = (smb_rap_share_info_1_t *) outp->datap; - cstrp = outp->datap + sizeof(smb_rap_share_info_1_t) * nSharesRet; + cstrp = outp->datap + sizeof(smb_rap_share_info_1_t) * nSharesRet; - memset(outp->datap, 0, (sizeof(smb_rap_share_info_1_t) + REMARK_LEN) * nSharesRet); + memset(outp->datap, 0, (sizeof(smb_rap_share_info_1_t) + REMARK_LEN) * nSharesRet); - if(allSubmount) { - strcpy( shares[cshare].shi1_netname, "all" ); - shares[cshare].shi1_remark = cstrp - outp->datap; - /* type and pad are zero already */ - cshare++; - cstrp+=REMARK_LEN; - } + if (allSubmount) { + strcpy( shares[cshare].shi1_netname, "all" ); + shares[cshare].shi1_remark = cstrp - outp->datap; + /* type and pad are zero already */ + cshare++; + cstrp+=REMARK_LEN; + } - if(hkSubmount) { - for(i=0; i < nRegShares && cshare < nSharesRet; i++) { - len = sizeof(thisShare); + if (hkSubmount) { + for (i=0; i < nRegShares && cshare < nSharesRet; i++) { + len = sizeof(thisShare); rv = RegEnumValue(hkSubmount, i, thisShare, &len, NULL, NULL, NULL, NULL); - if(rv == ERROR_SUCCESS && strlen(thisShare) && (!allSubmount || stricmp(thisShare,"all"))) { - strncpy(shares[cshare].shi1_netname, thisShare, sizeof(shares->shi1_netname)-1); - shares[cshare].shi1_netname[sizeof(shares->shi1_netname)-1] = 0; /* unfortunate truncation */ - shares[cshare].shi1_remark = cstrp - outp->datap; - cshare++; - cstrp+=REMARK_LEN; - } - else - nShares--; /* uncount key */ - } - - RegCloseKey(hkSubmount); - } + if (rv == ERROR_SUCCESS && strlen(thisShare) && (!allSubmount || stricmp(thisShare,"all"))) { + strncpy(shares[cshare].shi1_netname, thisShare, sizeof(shares->shi1_netname)-1); + shares[cshare].shi1_netname[sizeof(shares->shi1_netname)-1] = 0; /* unfortunate truncation */ + shares[cshare].shi1_remark = cstrp - outp->datap; + cshare++; + cstrp+=REMARK_LEN; + } + else + nShares--; /* uncount key */ + } + + RegCloseKey(hkSubmount); + } - nonrootShares = cshare; + nonrootShares = cshare; - for(i=0; i < rootShares.cShare && cshare < nSharesRet; i++) { + for (i=0; i < rootShares.cShare && cshare < nSharesRet; i++) { /* in case there are collisions with submounts, submounts have higher priority */ - for(j=0; j < nonrootShares; j++) - if(!stricmp(shares[j].shi1_netname, rootShares.shares[i].shi0_netname)) - break; + for (j=0; j < nonrootShares; j++) + if (!stricmp(shares[j].shi1_netname, rootShares.shares[i].shi0_netname)) + break; - if(j < nonrootShares) { - nShares--; /* uncount */ - continue; - } - - strcpy(shares[cshare].shi1_netname, rootShares.shares[i].shi0_netname); - shares[cshare].shi1_remark = cstrp - outp->datap; - cshare++; - cstrp+=REMARK_LEN; - } + if (j < nonrootShares) { + nShares--; /* uncount */ + continue; + } - outp->parmsp[0] = ((cshare == nShares)? ERROR_SUCCESS : ERROR_MORE_DATA); - outp->parmsp[1] = 0; - outp->parmsp[2] = cshare; - outp->parmsp[3] = nShares; + strcpy(shares[cshare].shi1_netname, rootShares.shares[i].shi0_netname); + shares[cshare].shi1_remark = cstrp - outp->datap; + cshare++; + cstrp+=REMARK_LEN; + } + + outp->parmsp[0] = ((cshare == nShares)? ERROR_SUCCESS : ERROR_MORE_DATA); + outp->parmsp[1] = 0; + outp->parmsp[2] = cshare; + outp->parmsp[3] = nShares; - outp->totalData = cstrp - outp->datap; - outp->totalParms = outParmsTotal; + outp->totalData = cstrp - outp->datap; + outp->totalParms = outParmsTotal; - smb_SendTran2Packet(vcp, outp, op); - smb_FreeTran2Packet(outp); + smb_SendTran2Packet(vcp, outp, op); + smb_FreeTran2Packet(outp); - free(rootShares.shares); + free(rootShares.shares); - return code; + return code; } long smb_ReceiveRAPNetShareGetInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *op) { - smb_tran2Packet_t *outp; - unsigned short * tp; - char * shareName; - BOOL shareFound = FALSE; - unsigned short infoLevel; - unsigned short bufsize; - int totalData; - int totalParam; - DWORD len; - HKEY hkParam; - HKEY hkSubmount; - DWORD allSubmount; - LONG rv; - long code = 0; - - tp = p->parmsp + 1; /* skip over function number (always 1) */ - (void) smb_ParseString( (char *) tp, (char **) &tp); /* skip over param descriptor */ - (void) smb_ParseString( (char *) tp, (char **) &tp); /* skip over data descriptor */ - shareName = smb_ParseString( (char *) tp, (char **) &tp); + smb_tran2Packet_t *outp; + unsigned short * tp; + char * shareName; + BOOL shareFound = FALSE; + unsigned short infoLevel; + unsigned short bufsize; + int totalData; + int totalParam; + DWORD len; + HKEY hkParam; + HKEY hkSubmount; + DWORD allSubmount; + LONG rv; + long code = 0; + + tp = p->parmsp + 1; /* skip over function number (always 1) */ + (void) smb_ParseString( (char *) tp, (char **) &tp); /* skip over param descriptor */ + (void) smb_ParseString( (char *) tp, (char **) &tp); /* skip over data descriptor */ + shareName = smb_ParseString( (char *) tp, (char **) &tp); infoLevel = *tp++; bufsize = *tp++; - totalParam = 6; - - if(infoLevel == 0) - totalData = sizeof(smb_rap_share_info_0_t); - else if(infoLevel == 1) - totalData = sizeof(smb_rap_share_info_1_t) + 1; /* + empty string */ - else if(infoLevel == 2) - totalData = sizeof(smb_rap_share_info_2_t) + 2; /* + two empty strings */ - else - return CM_ERROR_INVAL; - - outp = smb_GetTran2ResponsePacket(vcp, p, op, totalParam, totalData); - - if(!stricmp(shareName,"all")) { - rv = RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSConfigKeyName, 0, - KEY_QUERY_VALUE, &hkParam); - if (rv == ERROR_SUCCESS) { - len = sizeof(allSubmount); - rv = RegQueryValueEx(hkParam, "AllSubmount", NULL, NULL, - (BYTE *) &allSubmount, &len); - if (rv != ERROR_SUCCESS || allSubmount != 0) { - allSubmount = 1; - } - RegCloseKey (hkParam); - } - - if(allSubmount) - shareFound = TRUE; - - } else { - rv = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\OpenAFS\\Client\\Submounts", 0, - KEY_QUERY_VALUE, &hkSubmount); - if(rv == ERROR_SUCCESS) { + totalParam = 6; + + if (infoLevel == 0) + totalData = sizeof(smb_rap_share_info_0_t); + else if(infoLevel == 1) + totalData = sizeof(smb_rap_share_info_1_t) + 1; /* + empty string */ + else if(infoLevel == 2) + totalData = sizeof(smb_rap_share_info_2_t) + 2; /* + two empty strings */ + else + return CM_ERROR_INVAL; + + outp = smb_GetTran2ResponsePacket(vcp, p, op, totalParam, totalData); + + if(!stricmp(shareName,"all")) { + rv = RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSConfigKeyName, 0, + KEY_QUERY_VALUE, &hkParam); + if (rv == ERROR_SUCCESS) { + len = sizeof(allSubmount); + rv = RegQueryValueEx(hkParam, "AllSubmount", NULL, NULL, + (BYTE *) &allSubmount, &len); + if (rv != ERROR_SUCCESS || allSubmount != 0) { + allSubmount = 1; + } + RegCloseKey (hkParam); + } + + if (allSubmount) + shareFound = TRUE; + + } else { + rv = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\OpenAFS\\Client\\Submounts", 0, + KEY_QUERY_VALUE, &hkSubmount); + if (rv == ERROR_SUCCESS) { rv = RegQueryValueEx(hkSubmount, shareName, NULL, NULL, NULL, NULL); - if(rv == ERROR_SUCCESS) { - shareFound = TRUE; - } - RegCloseKey(hkSubmount); - } - } + if (rv == ERROR_SUCCESS) { + shareFound = TRUE; + } + RegCloseKey(hkSubmount); + } + } - if(!shareFound) { - smb_FreeTran2Packet(outp); - return CM_ERROR_BADSHARENAME; - } + if (!shareFound) { + smb_FreeTran2Packet(outp); + return CM_ERROR_BADSHARENAME; + } - memset(outp->datap, 0, totalData); + memset(outp->datap, 0, totalData); - outp->parmsp[0] = 0; - outp->parmsp[1] = 0; - outp->parmsp[2] = totalData; + outp->parmsp[0] = 0; + outp->parmsp[1] = 0; + outp->parmsp[2] = totalData; - if(infoLevel == 0) { - smb_rap_share_info_0_t * info = (smb_rap_share_info_0_t *) outp->datap; - strncpy(info->shi0_netname, shareName, sizeof(info->shi0_netname)-1); - info->shi0_netname[sizeof(info->shi0_netname)-1] = 0; - } else if(infoLevel == 1) { - smb_rap_share_info_1_t * info = (smb_rap_share_info_1_t *) outp->datap; + if (infoLevel == 0) { + smb_rap_share_info_0_t * info = (smb_rap_share_info_0_t *) outp->datap; + strncpy(info->shi0_netname, shareName, sizeof(info->shi0_netname)-1); + info->shi0_netname[sizeof(info->shi0_netname)-1] = 0; + } else if(infoLevel == 1) { + smb_rap_share_info_1_t * info = (smb_rap_share_info_1_t *) outp->datap; strncpy(info->shi1_netname, shareName, sizeof(info->shi1_netname)-1); - info->shi1_netname[sizeof(info->shi1_netname)-1] = 0; - info->shi1_remark = ((unsigned char *) (info + 1)) - outp->datap; - /* type and pad are already zero */ - } else { /* infoLevel==2 */ - smb_rap_share_info_2_t * info = (smb_rap_share_info_2_t *) outp->datap; - strncpy(info->shi2_netname, shareName, sizeof(info->shi2_netname)-1); - info->shi2_netname[sizeof(info->shi2_netname)-1] = 0; - info->shi2_remark = ((unsigned char *) (info + 1)) - outp->datap; + info->shi1_netname[sizeof(info->shi1_netname)-1] = 0; + info->shi1_remark = ((unsigned char *) (info + 1)) - outp->datap; + /* type and pad are already zero */ + } else { /* infoLevel==2 */ + smb_rap_share_info_2_t * info = (smb_rap_share_info_2_t *) outp->datap; + strncpy(info->shi2_netname, shareName, sizeof(info->shi2_netname)-1); + info->shi2_netname[sizeof(info->shi2_netname)-1] = 0; + info->shi2_remark = ((unsigned char *) (info + 1)) - outp->datap; info->shi2_permissions = ACCESS_ALL; - info->shi2_max_uses = (unsigned short) -1; + info->shi2_max_uses = (unsigned short) -1; info->shi2_path = 1 + (((unsigned char *) (info + 1)) - outp->datap); - } + } - outp->totalData = totalData; - outp->totalParms = totalParam; + outp->totalData = totalData; + outp->totalParms = totalParam; - smb_SendTran2Packet(vcp, outp, op); - smb_FreeTran2Packet(outp); + smb_SendTran2Packet(vcp, outp, op); + smb_FreeTran2Packet(outp); - return code; + return code; } typedef struct smb_rap_wksta_info_10 { - DWORD wki10_computername; /*char *wki10_computername;*/ - DWORD wki10_username; /* char *wki10_username; */ - DWORD wki10_langroup; /* char *wki10_langroup;*/ - unsigned char wki10_ver_major; - unsigned char wki10_ver_minor; - DWORD wki10_logon_domain; /*char *wki10_logon_domain;*/ - DWORD wki10_oth_domains; /* char *wki10_oth_domains;*/ + DWORD wki10_computername; /*char *wki10_computername;*/ + DWORD wki10_username; /* char *wki10_username; */ + DWORD wki10_langroup; /* char *wki10_langroup;*/ + unsigned char wki10_ver_major; + unsigned char wki10_ver_minor; + DWORD wki10_logon_domain; /*char *wki10_logon_domain;*/ + DWORD wki10_oth_domains; /* char *wki10_oth_domains;*/ } smb_rap_wksta_info_10_t; long smb_ReceiveRAPNetWkstaGetInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *op) { - smb_tran2Packet_t *outp; + smb_tran2Packet_t *outp; long code = 0; - int infoLevel; - int bufsize; - unsigned short * tp; - int totalData; - int totalParams; - smb_rap_wksta_info_10_t * info; - char * cstrp; - smb_user_t *uidp; - - tp = p->parmsp + 1; /* Skip over function number */ - (void) smb_ParseString((unsigned char*) tp, (char **) &tp); /* skip over param descriptor */ - (void) smb_ParseString((unsigned char*) tp, (char **) &tp); /* skip over data descriptor */ - infoLevel = *tp++; - bufsize = *tp++; - - if(infoLevel != 10) { - return CM_ERROR_INVAL; - } + int infoLevel; + int bufsize; + unsigned short * tp; + int totalData; + int totalParams; + smb_rap_wksta_info_10_t * info; + char * cstrp; + smb_user_t *uidp; + + tp = p->parmsp + 1; /* Skip over function number */ + (void) smb_ParseString((unsigned char*) tp, (char **) &tp); /* skip over param descriptor */ + (void) smb_ParseString((unsigned char*) tp, (char **) &tp); /* skip over data descriptor */ + infoLevel = *tp++; + bufsize = *tp++; + + if (infoLevel != 10) { + return CM_ERROR_INVAL; + } - totalParams = 6; + totalParams = 6; - /* infolevel 10 */ - totalData = sizeof(*info) + /* info */ - MAX_COMPUTERNAME_LENGTH + /* wki10_computername */ - SMB_MAX_USERNAME_LENGTH + /* wki10_username */ - MAX_COMPUTERNAME_LENGTH + /* wki10_langroup */ - MAX_COMPUTERNAME_LENGTH + /* wki10_logon_domain */ - 1; /* wki10_oth_domains (null)*/ + /* infolevel 10 */ + totalData = sizeof(*info) + /* info */ + MAX_COMPUTERNAME_LENGTH + /* wki10_computername */ + SMB_MAX_USERNAME_LENGTH + /* wki10_username */ + MAX_COMPUTERNAME_LENGTH + /* wki10_langroup */ + MAX_COMPUTERNAME_LENGTH + /* wki10_logon_domain */ + 1; /* wki10_oth_domains (null)*/ - outp = smb_GetTran2ResponsePacket(vcp, p, op, totalParams, totalData); + outp = smb_GetTran2ResponsePacket(vcp, p, op, totalParams, totalData); - memset(outp->parmsp,0,totalParams); - memset(outp->datap,0,totalData); + memset(outp->parmsp,0,totalParams); + memset(outp->datap,0,totalData); info = (smb_rap_wksta_info_10_t *) outp->datap; - cstrp = (char *) (info + 1); - - info->wki10_computername = (DWORD) (cstrp - outp->datap); - strcpy(cstrp, smb_localNamep); - cstrp += strlen(cstrp) + 1; - - info->wki10_username = (DWORD) (cstrp - outp->datap); - uidp = smb_FindUID(vcp, p->uid, 0); - if(uidp) { - lock_ObtainMutex(&uidp->mx); - if(uidp->unp && uidp->unp->name) - strcpy(cstrp, uidp->unp->name); - lock_ReleaseMutex(&uidp->mx); - smb_ReleaseUID(uidp); - } - cstrp += strlen(cstrp) + 1; + cstrp = (char *) (info + 1); + + info->wki10_computername = (DWORD) (cstrp - outp->datap); + strcpy(cstrp, smb_localNamep); + cstrp += strlen(cstrp) + 1; - info->wki10_langroup = (DWORD) (cstrp - outp->datap); - strcpy(cstrp, "WORKGROUP"); - cstrp += strlen(cstrp) + 1; + info->wki10_username = (DWORD) (cstrp - outp->datap); + uidp = smb_FindUID(vcp, p->uid, 0); + if (uidp) { + lock_ObtainMutex(&uidp->mx); + if(uidp->unp && uidp->unp->name) + strcpy(cstrp, uidp->unp->name); + lock_ReleaseMutex(&uidp->mx); + smb_ReleaseUID(uidp); + } + cstrp += strlen(cstrp) + 1; - /* TODO: Not sure what values these should take, but these work */ - info->wki10_ver_major = 5; - info->wki10_ver_minor = 1; + info->wki10_langroup = (DWORD) (cstrp - outp->datap); + strcpy(cstrp, "WORKGROUP"); + cstrp += strlen(cstrp) + 1; - info->wki10_logon_domain = (DWORD) (cstrp - outp->datap); - strcpy(cstrp, smb_ServerDomainName); - cstrp += strlen(cstrp) + 1; + /* TODO: Not sure what values these should take, but these work */ + info->wki10_ver_major = 5; + info->wki10_ver_minor = 1; - info->wki10_oth_domains = (DWORD) (cstrp - outp->datap); - cstrp ++; /* no other domains */ + info->wki10_logon_domain = (DWORD) (cstrp - outp->datap); + strcpy(cstrp, smb_ServerDomainName); + cstrp += strlen(cstrp) + 1; - outp->totalData = (unsigned short) (cstrp - outp->datap); /* actual data size */ - outp->parmsp[2] = outp->totalData; - outp->totalParms = totalParams; + info->wki10_oth_domains = (DWORD) (cstrp - outp->datap); + cstrp ++; /* no other domains */ - smb_SendTran2Packet(vcp,outp,op); - smb_FreeTran2Packet(outp); + outp->totalData = (unsigned short) (cstrp - outp->datap); /* actual data size */ + outp->parmsp[2] = outp->totalData; + outp->totalParms = totalParams; - return code; + smb_SendTran2Packet(vcp,outp,op); + smb_FreeTran2Packet(outp); + + return code; } typedef struct smb_rap_server_info_0 { @@ -1790,39 +1785,39 @@ int smb_ServerCommentLen = sizeof(smb_ServerComment); long smb_ReceiveRAPNetServerGetInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *op) { - smb_tran2Packet_t *outp; + smb_tran2Packet_t *outp; long code = 0; - int infoLevel; - int bufsize; - unsigned short * tp; - int totalData; - int totalParams; + int infoLevel; + int bufsize; + unsigned short * tp; + int totalData; + int totalParams; smb_rap_server_info_0_t * info0; smb_rap_server_info_1_t * info1; char * cstrp; - tp = p->parmsp + 1; /* Skip over function number */ - (void) smb_ParseString((unsigned char*) tp, (char **) &tp); /* skip over param descriptor */ - (void) smb_ParseString((unsigned char*) tp, (char **) &tp); /* skip over data descriptor */ - infoLevel = *tp++; - bufsize = *tp++; + tp = p->parmsp + 1; /* Skip over function number */ + (void) smb_ParseString((unsigned char*) tp, (char **) &tp); /* skip over param descriptor */ + (void) smb_ParseString((unsigned char*) tp, (char **) &tp); /* skip over data descriptor */ + infoLevel = *tp++; + bufsize = *tp++; - if(infoLevel != 0 && infoLevel != 1) { + if (infoLevel != 0 && infoLevel != 1) { return CM_ERROR_INVAL; } - totalParams = 6; - - totalData = + totalParams = 6; + + totalData = (infoLevel == 0) ? sizeof(smb_rap_server_info_0_t) : (sizeof(smb_rap_server_info_1_t) + smb_ServerCommentLen); - outp = smb_GetTran2ResponsePacket(vcp, p, op, totalParams, totalData); + outp = smb_GetTran2ResponsePacket(vcp, p, op, totalParams, totalData); - memset(outp->parmsp,0,totalParams); - memset(outp->datap,0,totalData); + memset(outp->parmsp,0,totalParams); + memset(outp->datap,0,totalData); - if(infoLevel == 0) { + if (infoLevel == 0) { info0 = (smb_rap_server_info_0_t *) outp->datap; cstrp = (char *) (info0 + 1); strcpy(info0->sv0_name, "AFS"); @@ -1846,13 +1841,13 @@ long smb_ReceiveRAPNetServerGetInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_pac } totalData = cstrp - outp->datap; - outp->totalData = min(bufsize,totalData); /* actual data size */ + outp->totalData = min(bufsize,totalData); /* actual data size */ outp->parmsp[0] = (outp->totalData == totalData)? 0 : ERROR_MORE_DATA; - outp->parmsp[2] = totalData; - outp->totalParms = totalParams; + outp->parmsp[2] = totalData; + outp->totalParms = totalParams; - smb_SendTran2Packet(vcp,outp,op); - smb_FreeTran2Packet(outp); + smb_SendTran2Packet(vcp,outp,op); + smb_FreeTran2Packet(outp); return code; } @@ -1871,52 +1866,52 @@ long smb_ReceiveV3Tran2A(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) int firstPacket; long code = 0; - /* We sometimes see 0 word count. What to do? */ - if (*inp->wctp == 0) { + /* We sometimes see 0 word count. What to do? */ + if (*inp->wctp == 0) { #ifndef DJGPP - HANDLE h; - char *ptbuf[1]; + HANDLE h; + char *ptbuf[1]; - osi_Log0(smb_logp, "TRANSACTION2 word count = 0"); + osi_Log0(smb_logp, "TRANSACTION2 word count = 0"); - h = RegisterEventSource(NULL, AFS_DAEMON_EVENT_NAME); - ptbuf[0] = "Transaction2 word count = 0"; - ReportEvent(h, EVENTLOG_WARNING_TYPE, 0, 1003, NULL, - 1, inp->ncb_length, ptbuf, inp); - DeregisterEventSource(h); + h = RegisterEventSource(NULL, AFS_DAEMON_EVENT_NAME); + ptbuf[0] = "Transaction2 word count = 0"; + ReportEvent(h, EVENTLOG_WARNING_TYPE, 0, 1003, NULL, + 1, inp->ncb_length, ptbuf, inp); + DeregisterEventSource(h); #else /* DJGPP */ - osi_Log0(smb_logp, "TRANSACTION2 word count = 0"); + osi_Log0(smb_logp, "TRANSACTION2 word count = 0"); #endif /* !DJGPP */ smb_SetSMBDataLength(outp, 0); smb_SendPacket(vcp, outp); - return 0; - } + return 0; + } totalParms = smb_GetSMBParm(inp, 0); totalData = smb_GetSMBParm(inp, 1); firstPacket = (inp->inCom == 0x32); - /* find the packet we're reassembling */ - lock_ObtainWrite(&smb_globalLock); + /* find the packet we're reassembling */ + lock_ObtainWrite(&smb_globalLock); asp = smb_FindTran2Packet(vcp, inp); if (!asp) { asp = smb_NewTran2Packet(vcp, inp, totalParms, totalData); - } + } lock_ReleaseWrite(&smb_globalLock); /* now merge in this latest packet; start by looking up offsets */ - if (firstPacket) { - parmDisp = dataDisp = 0; + if (firstPacket) { + parmDisp = dataDisp = 0; parmOffset = smb_GetSMBParm(inp, 10); dataOffset = smb_GetSMBParm(inp, 12); parmCount = smb_GetSMBParm(inp, 9); dataCount = smb_GetSMBParm(inp, 11); - asp->maxReturnParms = smb_GetSMBParm(inp, 2); + asp->maxReturnParms = smb_GetSMBParm(inp, 2); asp->maxReturnData = smb_GetSMBParm(inp, 3); - osi_Log3(smb_logp, "SMB3 received T2 init packet total data %d, cur data %d, max return data %d", + osi_Log3(smb_logp, "SMB3 received T2 init packet total data %d, cur data %d, max return data %d", totalData, dataCount, asp->maxReturnData); } else { @@ -1949,9 +1944,9 @@ long smb_ReceiveV3Tran2A(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) asp->curParms > 0 && asp->totalData <= asp->curData && asp->totalParms <= asp->curParms) { - /* we've received it all */ + /* we've received it all */ lock_ObtainWrite(&smb_globalLock); - osi_QRemove((osi_queue_t **) &smb_tran2AssemblyQueuep, &asp->q); + osi_QRemove((osi_queue_t **) &smb_tran2AssemblyQueuep, &asp->q); lock_ReleaseWrite(&smb_globalLock); /* now dispatch it */ @@ -1966,7 +1961,7 @@ long smb_ReceiveV3Tran2A(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) code = CM_ERROR_BADOP; } - /* if an error is returned, we're supposed to send an error packet, + /* if an error is returned, we're supposed to send an error packet, * otherwise the dispatched function already did the data sending. * We give dispatched proc the responsibility since it knows how much * space to allocate. @@ -1975,20 +1970,20 @@ long smb_ReceiveV3Tran2A(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) smb_SendTran2Error(vcp, asp, outp, code); } - /* free the input tran 2 packet */ - lock_ObtainWrite(&smb_globalLock); + /* free the input tran 2 packet */ + lock_ObtainWrite(&smb_globalLock); smb_FreeTran2Packet(asp); - lock_ReleaseWrite(&smb_globalLock); + lock_ReleaseWrite(&smb_globalLock); } else if (firstPacket) { - /* the first packet in a multi-packet request, we need to send an + /* the first packet in a multi-packet request, we need to send an * ack to get more data. */ smb_SetSMBDataLength(outp, 0); smb_SendPacket(vcp, outp); } - return 0; + return 0; } long smb_ReceiveTran2Open(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *op) @@ -3058,9 +3053,9 @@ smb_ApplyV3DirListPatches(cm_scache_t *dscp, lock_ObtainMutex(&scp->mx); code = cm_SyncOp(scp, NULL, userp, reqp, 0, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); - if (code) { - lock_ReleaseMutex(&scp->mx); - cm_ReleaseSCache(scp); + if (code) { + lock_ReleaseMutex(&scp->mx); + cm_ReleaseSCache(scp); dptr = patchp->dptr; @@ -3071,69 +3066,69 @@ smb_ApplyV3DirListPatches(cm_scache_t *dscp, ft.dwHighDateTime = 0x19DB200; ft.dwLowDateTime = 0x5BB78980; - /* copy to Creation Time */ - *((FILETIME *)dptr) = ft; - dptr += 8; + /* copy to Creation Time */ + *((FILETIME *)dptr) = ft; + dptr += 8; - /* copy to Last Access Time */ - *((FILETIME *)dptr) = ft; - dptr += 8; + /* copy to Last Access Time */ + *((FILETIME *)dptr) = ft; + dptr += 8; - /* copy to Last Write Time */ - *((FILETIME *)dptr) = ft; - dptr += 8; + /* copy to Last Write Time */ + *((FILETIME *)dptr) = ft; + dptr += 8; - /* copy to Change Time */ - *((FILETIME *)dptr) = ft; + /* copy to Change Time */ + *((FILETIME *)dptr) = ft; dptr += 24; /* merge in hidden attribute */ if ( patchp->flags & SMB_DIRLISTPATCH_DOTFILE ) { - *((u_long *)dptr) = SMB_ATTR_HIDDEN; + *((u_long *)dptr) = SMB_ATTR_HIDDEN; } - dptr += 4; + dptr += 4; } else { /* 1969-12-31 23:59:58 +00*/ dosTime = 0xEBBFBF7D; - /* and copy out date */ - shortTemp = (dosTime>>16) & 0xffff; - *((u_short *)dptr) = shortTemp; - dptr += 2; + /* and copy out date */ + shortTemp = (dosTime>>16) & 0xffff; + *((u_short *)dptr) = shortTemp; + dptr += 2; - /* copy out creation time */ - shortTemp = dosTime & 0xffff; - *((u_short *)dptr) = shortTemp; - dptr += 2; + /* copy out creation time */ + shortTemp = dosTime & 0xffff; + *((u_short *)dptr) = shortTemp; + dptr += 2; - /* and copy out date */ - shortTemp = (dosTime>>16) & 0xffff; - *((u_short *)dptr) = shortTemp; - dptr += 2; + /* and copy out date */ + shortTemp = (dosTime>>16) & 0xffff; + *((u_short *)dptr) = shortTemp; + dptr += 2; - /* copy out access time */ - shortTemp = dosTime & 0xffff; - *((u_short *)dptr) = shortTemp; - dptr += 2; - - /* and copy out date */ - shortTemp = (dosTime>>16) & 0xffff; - *((u_short *)dptr) = shortTemp; - dptr += 2; + /* copy out access time */ + shortTemp = dosTime & 0xffff; + *((u_short *)dptr) = shortTemp; + dptr += 2; + + /* and copy out date */ + shortTemp = (dosTime>>16) & 0xffff; + *((u_short *)dptr) = shortTemp; + dptr += 2; - /* copy out mod time */ - shortTemp = dosTime & 0xffff; - *((u_short *)dptr) = shortTemp; - dptr += 10; + /* copy out mod time */ + shortTemp = dosTime & 0xffff; + *((u_short *)dptr) = shortTemp; + dptr += 10; /* merge in hidden (dot file) attribute */ if ( patchp->flags & SMB_DIRLISTPATCH_DOTFILE ) { attr = SMB_ATTR_HIDDEN; - *dptr++ = attr & 0xff; - *dptr++ = (attr >> 8) & 0xff; - } + *dptr++ = attr & 0xff; + *dptr++ = (attr >> 8) & 0xff; + } } - continue; + continue; } /* now watch for a symlink */ @@ -3154,102 +3149,102 @@ smb_ApplyV3DirListPatches(cm_scache_t *dscp, lock_ObtainMutex(&scp->mx); } - dptr = patchp->dptr; + dptr = patchp->dptr; - if (infoLevel >= 0x101) { - /* get filetime */ - smb_LargeSearchTimeFromUnixTime(&ft, scp->clientModTime); + if (infoLevel >= 0x101) { + /* get filetime */ + smb_LargeSearchTimeFromUnixTime(&ft, scp->clientModTime); - /* copy to Creation Time */ - *((FILETIME *)dptr) = ft; - dptr += 8; + /* copy to Creation Time */ + *((FILETIME *)dptr) = ft; + dptr += 8; - /* copy to Last Access Time */ - *((FILETIME *)dptr) = ft; - dptr += 8; + /* copy to Last Access Time */ + *((FILETIME *)dptr) = ft; + dptr += 8; - /* copy to Last Write Time */ - *((FILETIME *)dptr) = ft; - dptr += 8; + /* copy to Last Write Time */ + *((FILETIME *)dptr) = ft; + dptr += 8; - /* copy to Change Time */ - *((FILETIME *)dptr) = ft; - dptr += 8; + /* copy to Change Time */ + *((FILETIME *)dptr) = ft; + dptr += 8; - /* Use length for both file length and alloc length */ - *((LARGE_INTEGER *)dptr) = scp->length; - dptr += 8; - *((LARGE_INTEGER *)dptr) = scp->length; - dptr += 8; + /* Use length for both file length and alloc length */ + *((LARGE_INTEGER *)dptr) = scp->length; + dptr += 8; + *((LARGE_INTEGER *)dptr) = scp->length; + dptr += 8; - /* Copy attributes */ - lattr = smb_ExtAttributes(scp); + /* Copy attributes */ + lattr = smb_ExtAttributes(scp); /* merge in hidden (dot file) attribute */ - if ( patchp->flags & SMB_DIRLISTPATCH_DOTFILE ) - lattr |= SMB_ATTR_HIDDEN; - *((u_long *)dptr) = lattr; - dptr += 4; - } - else { - /* get dos time */ - smb_SearchTimeFromUnixTime(&dosTime, scp->clientModTime); - - /* and copy out date */ - shortTemp = (dosTime>>16) & 0xffff; - *((u_short *)dptr) = shortTemp; - dptr += 2; - - /* copy out creation time */ - shortTemp = dosTime & 0xffff; - *((u_short *)dptr) = shortTemp; - dptr += 2; - - /* and copy out date */ - shortTemp = (dosTime>>16) & 0xffff; - *((u_short *)dptr) = shortTemp; - dptr += 2; - - /* copy out access time */ - shortTemp = dosTime & 0xffff; - *((u_short *)dptr) = shortTemp; - dptr += 2; - - /* and copy out date */ - shortTemp = (dosTime>>16) & 0xffff; - *((u_short *)dptr) = shortTemp; - dptr += 2; - - /* copy out mod time */ - shortTemp = dosTime & 0xffff; - *((u_short *)dptr) = shortTemp; - dptr += 2; - - /* copy out file length and alloc length, - * using the same for both - */ - *((u_long *)dptr) = scp->length.LowPart; - dptr += 4; - *((u_long *)dptr) = scp->length.LowPart; - dptr += 4; - - /* finally copy out attributes as short */ - attr = smb_Attributes(scp); + if ( patchp->flags & SMB_DIRLISTPATCH_DOTFILE ) + lattr |= SMB_ATTR_HIDDEN; + *((u_long *)dptr) = lattr; + dptr += 4; + } + else { + /* get dos time */ + smb_SearchTimeFromUnixTime(&dosTime, scp->clientModTime); + + /* and copy out date */ + shortTemp = (dosTime>>16) & 0xffff; + *((u_short *)dptr) = shortTemp; + dptr += 2; + + /* copy out creation time */ + shortTemp = dosTime & 0xffff; + *((u_short *)dptr) = shortTemp; + dptr += 2; + + /* and copy out date */ + shortTemp = (dosTime>>16) & 0xffff; + *((u_short *)dptr) = shortTemp; + dptr += 2; + + /* copy out access time */ + shortTemp = dosTime & 0xffff; + *((u_short *)dptr) = shortTemp; + dptr += 2; + + /* and copy out date */ + shortTemp = (dosTime>>16) & 0xffff; + *((u_short *)dptr) = shortTemp; + dptr += 2; + + /* copy out mod time */ + shortTemp = dosTime & 0xffff; + *((u_short *)dptr) = shortTemp; + dptr += 2; + + /* copy out file length and alloc length, + * using the same for both + */ + *((u_long *)dptr) = scp->length.LowPart; + dptr += 4; + *((u_long *)dptr) = scp->length.LowPart; + dptr += 4; + + /* finally copy out attributes as short */ + attr = smb_Attributes(scp); /* merge in hidden (dot file) attribute */ if ( patchp->flags & SMB_DIRLISTPATCH_DOTFILE ) attr |= SMB_ATTR_HIDDEN; - *dptr++ = attr & 0xff; - *dptr++ = (attr >> 8) & 0xff; - } + *dptr++ = attr & 0xff; + *dptr++ = (attr >> 8) & 0xff; + } lock_ReleaseMutex(&scp->mx); cm_ReleaseSCache(scp); - } + } /* now free the patches */ - for(patchp = *dirPatchespp; patchp; patchp = npatchp) { - npatchp = (smb_dirListPatch_t *) osi_QNext(&patchp->q); + for (patchp = *dirPatchespp; patchp; patchp = npatchp) { + npatchp = (smb_dirListPatch_t *) osi_QNext(&patchp->q); free(patchp); - } + } /* and mark the list as empty */ *dirPatchespp = NULL; @@ -3311,8 +3306,8 @@ szWildCardMatchFileName(PSZ pattern, PSZ name) return FALSE; ++pattern, ++name; break; - } /* endswitch */ - } /* endwhile */ + } /* endswitch */ + } /* endwhile */ if (*pattern == '\0' || *pattern == '*' && *(pattern+1) == '\0') return TRUE; @@ -3380,143 +3375,143 @@ int smb_V3MatchMask(char *namep, char *maskp, int flags) */ int smb_V3MatchMask(char *namep, char *maskp, int flags) { - unsigned char tcp1, tcp2; /* Pattern characters */ + unsigned char tcp1, tcp2; /* Pattern characters */ unsigned char tcn1; /* Name characters */ - int sawDot = 0, sawStar = 0, req8dot3 = 0; - char *starNamep, *starMaskp; - static char nullCharp[] = {0}; + int sawDot = 0, sawStar = 0, req8dot3 = 0; + char *starNamep, *starMaskp; + static char nullCharp[] = {0}; int casefold = flags & CM_FLAG_CASEFOLD; - /* make sure we only match 8.3 names, if requested */ + /* make sure we only match 8.3 names, if requested */ req8dot3 = (flags & CM_FLAG_8DOT3); - if (req8dot3 && !cm_Is8Dot3(namep)) + if (req8dot3 && !cm_Is8Dot3(namep)) return 0; - /* loop */ - while (1) { - /* Next pattern character */ - tcp1 = *maskp++; - - /* Next name character */ - tcn1 = *namep; - - if (tcp1 == 0) { - /* 0 - end of pattern */ - if (tcn1 == 0) - return 1; - else - return 0; - } - else if (tcp1 == '.' || tcp1 == '"') { - if (sawDot) { - if (tcn1 == '.') { - namep++; - continue; - } else - return 0; - } - else { - /* - * first dot in pattern; - * must match dot or end of name - */ - sawDot = 1; - if (tcn1 == 0) - continue; - else if (tcn1 == '.') { - sawStar = 0; - namep++; - continue; - } - else - return 0; - } - } - else if (tcp1 == '?') { - if (tcn1 == 0 || tcn1 == '.') - return 0; - namep++; - continue; - } - else if (tcp1 == '>') { - if (tcn1 != 0 && tcn1 != '.') - namep++; - continue; - } - else if (tcp1 == '*' || tcp1 == '<') { - tcp2 = *maskp++; - if (tcp2 == 0) - return 1; - else if ((req8dot3 && tcp2 == '.') || tcp2 == '"') { - while (req8dot3 && tcn1 != '.' && tcn1 != 0) - tcn1 = *++namep; - if (tcn1 == 0) { - if (sawDot) - return 0; - else - continue; - } - else { - namep++; - continue; - } - } - else { - /* - * pattern character after '*' is not null or - * period. If it is '?' or '>', we are not - * going to understand it. If it is '*' or - * '<', we are going to skip over it. None of - * these are likely, I hope. - */ - /* skip over '*' and '<' */ - while (tcp2 == '*' || tcp2 == '<') - tcp2 = *maskp++; - - /* skip over characters that don't match tcp2 */ - while (req8dot3 && tcn1 != '.' && tcn1 != 0 && - ((casefold && cm_foldUpper[tcn1] != cm_foldUpper[tcp2]) || - (!casefold && tcn1 != tcp2))) - tcn1 = *++namep; - - /* No match */ - if ((req8dot3 && tcn1 == '.') || tcn1 == 0) - return 0; - - /* Remember where we are */ - sawStar = 1; - starMaskp = maskp; - starNamep = namep; - - namep++; - continue; - } - } - else { - /* tcp1 is not a wildcard */ + /* loop */ + while (1) { + /* Next pattern character */ + tcp1 = *maskp++; + + /* Next name character */ + tcn1 = *namep; + + if (tcp1 == 0) { + /* 0 - end of pattern */ + if (tcn1 == 0) + return 1; + else + return 0; + } + else if (tcp1 == '.' || tcp1 == '"') { + if (sawDot) { + if (tcn1 == '.') { + namep++; + continue; + } else + return 0; + } + else { + /* + * first dot in pattern; + * must match dot or end of name + */ + sawDot = 1; + if (tcn1 == 0) + continue; + else if (tcn1 == '.') { + sawStar = 0; + namep++; + continue; + } + else + return 0; + } + } + else if (tcp1 == '?') { + if (tcn1 == 0 || tcn1 == '.') + return 0; + namep++; + continue; + } + else if (tcp1 == '>') { + if (tcn1 != 0 && tcn1 != '.') + namep++; + continue; + } + else if (tcp1 == '*' || tcp1 == '<') { + tcp2 = *maskp++; + if (tcp2 == 0) + return 1; + else if ((req8dot3 && tcp2 == '.') || tcp2 == '"') { + while (req8dot3 && tcn1 != '.' && tcn1 != 0) + tcn1 = *++namep; + if (tcn1 == 0) { + if (sawDot) + return 0; + else + continue; + } + else { + namep++; + continue; + } + } + else { + /* + * pattern character after '*' is not null or + * period. If it is '?' or '>', we are not + * going to understand it. If it is '*' or + * '<', we are going to skip over it. None of + * these are likely, I hope. + */ + /* skip over '*' and '<' */ + while (tcp2 == '*' || tcp2 == '<') + tcp2 = *maskp++; + + /* skip over characters that don't match tcp2 */ + while (req8dot3 && tcn1 != '.' && tcn1 != 0 && + ((casefold && cm_foldUpper[tcn1] != cm_foldUpper[tcp2]) || + (!casefold && tcn1 != tcp2))) + tcn1 = *++namep; + + /* No match */ + if ((req8dot3 && tcn1 == '.') || tcn1 == 0) + return 0; + + /* Remember where we are */ + sawStar = 1; + starMaskp = maskp; + starNamep = namep; + + namep++; + continue; + } + } + else { + /* tcp1 is not a wildcard */ if ((casefold && cm_foldUpper[tcn1] == cm_foldUpper[tcp1]) || - (!casefold && tcn1 == tcp1)) { - /* they match */ - namep++; - continue; - } - /* if trying to match a star pattern, go back */ - if (sawStar) { - maskp = starMaskp - 2; - namep = starNamep + 1; - sawStar = 0; - continue; - } - /* that's all */ - return 0; - } - } + (!casefold && tcn1 == tcp1)) { + /* they match */ + namep++; + continue; + } + /* if trying to match a star pattern, go back */ + if (sawStar) { + maskp = starMaskp - 2; + namep = starNamep + 1; + sawStar = 0; + continue; + } + /* that's all */ + return 0; + } + } } #endif /* USE_OLD_MATCHING */ long smb_ReceiveTran2SearchDir(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *opx) { - int attribute; + int attribute; long nextCookie; char *tp; long code = 0; @@ -3538,14 +3533,14 @@ long smb_ReceiveTran2SearchDir(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t cm_scache_t *scp; long entryInDir; long entryInBuffer; - cm_pageHeader_t *pageHeaderp; + cm_pageHeader_t *pageHeaderp; cm_user_t *userp = NULL; int slotInPage; int returnedNames; long nextEntryCookie; int numDirChunks; /* # of 32 byte dir chunks in this entry */ char *op; /* output data ptr */ - char *origOp; /* original value of op */ + char *origOp; /* original value of op */ cm_space_t *spacep; /* for pathname buffer */ long maxReturnData; /* max # of return data */ long maxReturnParms; /* max # of return parms */ @@ -3556,22 +3551,21 @@ long smb_ReceiveTran2SearchDir(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t int searchFlags; int eos; smb_tran2Packet_t *outp; /* response packet */ - char *tidPathp; - int align; - char shortName[13]; /* 8.3 name if needed */ - int NeedShortName; + char *tidPathp; + int align; + char shortName[13]; /* 8.3 name if needed */ + int NeedShortName; int foundInexact; - char *shortNameEnd; + char *shortNameEnd; int fileType; cm_fid_t fid; - cm_req_t req; - cm_InitReq(&req); + cm_InitReq(&req); - eos = 0; - if (p->opcode == 1) { - /* find first; obtain basic parameters from request */ + eos = 0; + if (p->opcode == 1) { + /* find first; obtain basic parameters from request */ attribute = p->parmsp[0]; maxCount = p->parmsp[1]; infoLevel = p->parmsp[3]; @@ -3582,13 +3576,13 @@ long smb_ReceiveTran2SearchDir(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t nextCookie = 0; maskp = strrchr(pathp, '\\'); if (maskp == NULL) maskp = pathp; - else maskp++; /* skip over backslash */ + else maskp++; /* skip over backslash */ strcpy(dsp->mask, maskp); /* and save mask */ - /* track if this is likely to match a lot of entries */ + /* track if this is likely to match a lot of entries */ starPattern = smb_V3IsStarMask(maskp); - } + } else { - osi_assert(p->opcode == 2); + osi_assert(p->opcode == 2); /* find next; obtain basic parameters from request or open dir file */ dsp = smb_FindDirSearch(p->parmsp[0]); if (!dsp) return CM_ERROR_BADFD; @@ -3599,25 +3593,25 @@ long smb_ReceiveTran2SearchDir(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t pathp = NULL; nextCookie = p->parmsp[3] | (p->parmsp[4] << 16); maskp = dsp->mask; - starPattern = 1; /* assume, since required a Find Next */ + starPattern = 1; /* assume, since required a Find Next */ } - osi_Log4(smb_logp, + osi_Log4(smb_logp, "T2 search dir attr 0x%x, info level %d, max count %d, flags 0x%x", attribute, infoLevel, maxCount, searchFlags); - osi_Log2(smb_logp, "...T2 search op %d, nextCookie 0x%x", + osi_Log2(smb_logp, "...T2 search op %d, nextCookie 0x%x", p->opcode, nextCookie); - if (infoLevel >= 0x101) - searchFlags &= ~4; /* no resume keys */ + if (infoLevel >= 0x101) + searchFlags &= ~4; /* no resume keys */ dirListPatchesp = NULL; - maxReturnData = p->maxReturnData; + maxReturnData = p->maxReturnData; if (p->opcode == 1) /* find first */ maxReturnParms = 10; /* bytes */ - else + else maxReturnParms = 8; /* bytes */ #ifndef CM_CONFIG_MULTITRAN2RESPONSES @@ -3625,7 +3619,7 @@ long smb_ReceiveTran2SearchDir(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t maxReturnData = 6000; #endif /* CM_CONFIG_MULTITRAN2RESPONSES */ - outp = smb_GetTran2ResponsePacket(vcp, p, opx, maxReturnParms, + outp = smb_GetTran2ResponsePacket(vcp, p, opx, maxReturnParms, maxReturnData); osi_Log1(smb_logp, "T2 receive search dir %s", @@ -3638,10 +3632,10 @@ long smb_ReceiveTran2SearchDir(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t return CM_ERROR_BADSMB; } - osi_Log2(smb_logp, "T2 dir search cookie 0x%x, connection %d", + osi_Log2(smb_logp, "T2 dir search cookie 0x%x, connection %d", nextCookie, dsp->cookie); - userp = smb_GetTran2User(vcp, p); + userp = smb_GetTran2User(vcp, p); if (!userp) { osi_Log1(smb_logp, "T2 dir search unable to resolve user [%d]", p->uid); smb_ReleaseDirSearch(dsp); @@ -3649,25 +3643,25 @@ long smb_ReceiveTran2SearchDir(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t return CM_ERROR_BADSMB; } - /* try to get the vnode for the path name next */ - lock_ObtainMutex(&dsp->mx); - if (dsp->scp) { - scp = dsp->scp; + /* try to get the vnode for the path name next */ + lock_ObtainMutex(&dsp->mx); + if (dsp->scp) { + scp = dsp->scp; cm_HoldSCache(scp); code = 0; } else { - spacep = cm_GetSpace(); + spacep = cm_GetSpace(); smb_StripLastComponent(spacep->data, NULL, pathp); lock_ReleaseMutex(&dsp->mx); - code = smb_LookupTIDPath(vcp, p->tid, &tidPathp); - if(code) { - cm_ReleaseUser(userp); + code = smb_LookupTIDPath(vcp, p->tid, &tidPathp); + if (code) { + cm_ReleaseUser(userp); smb_SendTran2Error(vcp, p, opx, CM_ERROR_NOFILES); smb_FreeTran2Packet(outp); - smb_DeleteDirSearch(dsp); - smb_ReleaseDirSearch(dsp); + smb_DeleteDirSearch(dsp); + smb_ReleaseDirSearch(dsp); return 0; } code = cm_NameI(cm_rootSCachep, spacep->data, @@ -3676,45 +3670,45 @@ long smb_ReceiveTran2SearchDir(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t cm_FreeSpace(spacep); lock_ObtainMutex(&dsp->mx); - if (code == 0) { + if (code == 0) { if (dsp->scp != 0) cm_ReleaseSCache(dsp->scp); - dsp->scp = scp; - /* we need one hold for the entry we just stored into, + dsp->scp = scp; + /* we need one hold for the entry we just stored into, * and one for our own processing. When we're done - * with this function, we'll drop the one for our own - * processing. We held it once from the namei call, - * and so we do another hold now. + * with this function, we'll drop the one for our own + * processing. We held it once from the namei call, + * and so we do another hold now. */ cm_HoldSCache(scp); - lock_ObtainMutex(&scp->mx); - if ((scp->flags & CM_SCACHEFLAG_BULKSTATTING) == 0 - && LargeIntegerGreaterOrEqualToZero(scp->bulkStatProgress)) { + lock_ObtainMutex(&scp->mx); + if ((scp->flags & CM_SCACHEFLAG_BULKSTATTING) == 0 && + LargeIntegerGreaterOrEqualToZero(scp->bulkStatProgress)) { scp->flags |= CM_SCACHEFLAG_BULKSTATTING; - dsp->flags |= SMB_DIRSEARCH_BULKST; - } - lock_ReleaseMutex(&scp->mx); - } + dsp->flags |= SMB_DIRSEARCH_BULKST; + } + lock_ReleaseMutex(&scp->mx); + } } - lock_ReleaseMutex(&dsp->mx); + lock_ReleaseMutex(&dsp->mx); if (code) { - cm_ReleaseUser(userp); + cm_ReleaseUser(userp); smb_FreeTran2Packet(outp); - smb_DeleteDirSearch(dsp); - smb_ReleaseDirSearch(dsp); + smb_DeleteDirSearch(dsp); + smb_ReleaseDirSearch(dsp); return code; - } + } /* get the directory size */ - lock_ObtainMutex(&scp->mx); + lock_ObtainMutex(&scp->mx); code = cm_SyncOp(scp, NULL, userp, &req, 0, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); - if (code) { - lock_ReleaseMutex(&scp->mx); + if (code) { + lock_ReleaseMutex(&scp->mx); cm_ReleaseSCache(scp); cm_ReleaseUser(userp); smb_FreeTran2Packet(outp); - smb_DeleteDirSearch(dsp); - smb_ReleaseDirSearch(dsp); + smb_DeleteDirSearch(dsp); + smb_ReleaseDirSearch(dsp); return code; } @@ -3724,31 +3718,31 @@ long smb_ReceiveTran2SearchDir(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t bufferOffset.LowPart = bufferOffset.HighPart = 0; curOffset.HighPart = 0; curOffset.LowPart = nextCookie; - origOp = outp->datap; + origOp = outp->datap; foundInexact = 0; code = 0; returnedNames = 0; bytesInBuffer = 0; while (1) { - op = origOp; - if (searchFlags & 4) - /* skip over resume key */ - op += 4; + op = origOp; + if (searchFlags & 4) + /* skip over resume key */ + op += 4; - /* make sure that curOffset.LowPart doesn't point to the first + /* make sure that curOffset.LowPart doesn't point to the first * 32 bytes in the 2nd through last dir page, and that it doesn't * point at the first 13 32-byte chunks in the first dir page, * since those are dir and page headers, and don't contain useful * information. */ - temp = curOffset.LowPart & (2048-1); + temp = curOffset.LowPart & (2048-1); if (curOffset.HighPart == 0 && curOffset.LowPart < 2048) { - /* we're in the first page */ + /* we're in the first page */ if (temp < 13*32) temp = 13*32; - } - else { - /* we're in a later dir page */ + } + else { + /* we're in a later dir page */ if (temp < 32) temp = 32; } @@ -3781,35 +3775,35 @@ long smb_ReceiveTran2SearchDir(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t thyper.HighPart = curOffset.HighPart; thyper.LowPart = curOffset.LowPart & ~(buf_bufferSize-1); if (!bufferp || !LargeIntegerEqualTo(thyper, bufferOffset)) { - /* wrong buffer */ + /* wrong buffer */ if (bufferp) { buf_Release(bufferp); bufferp = NULL; - } - lock_ReleaseMutex(&scp->mx); - lock_ObtainRead(&scp->bufCreateLock); + } + lock_ReleaseMutex(&scp->mx); + lock_ObtainRead(&scp->bufCreateLock); code = buf_Get(scp, &thyper, &bufferp); - lock_ReleaseRead(&scp->bufCreateLock); + lock_ReleaseRead(&scp->bufCreateLock); - /* now, if we're doing a star match, do bulk fetching - * of all of the status info for files in the dir. + /* now, if we're doing a star match, do bulk fetching + * of all of the status info for files in the dir. */ if (starPattern) { - smb_ApplyV3DirListPatches(scp, &dirListPatchesp, - infoLevel, userp, - &req); - if ((dsp->flags & SMB_DIRSEARCH_BULKST) - && LargeIntegerGreaterThanOrEqualTo(thyper, scp->bulkStatProgress)) { - /* Don't bulk stat if risking timeout */ - int now = GetCurrentTime(); - if (now - req.startTime > 5000) { - scp->bulkStatProgress = thyper; - scp->flags &= ~CM_SCACHEFLAG_BULKSTATTING; - dsp->flags &= ~SMB_DIRSEARCH_BULKST; - } else + smb_ApplyV3DirListPatches(scp, &dirListPatchesp, + infoLevel, userp, + &req); + if ((dsp->flags & SMB_DIRSEARCH_BULKST) && + LargeIntegerGreaterThanOrEqualTo(thyper, scp->bulkStatProgress)) { + /* Don't bulk stat if risking timeout */ + int now = GetCurrentTime(); + if (now - req.startTime > 5000) { + scp->bulkStatProgress = thyper; + scp->flags &= ~CM_SCACHEFLAG_BULKSTATTING; + dsp->flags &= ~SMB_DIRSEARCH_BULKST; + } else cm_TryBulkStat(scp, &thyper, userp, &req); - } - } + } + } lock_ObtainMutex(&scp->mx); if (code) break; @@ -3817,11 +3811,11 @@ long smb_ReceiveTran2SearchDir(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t /* now get the data in the cache */ while (1) { - code = cm_SyncOp(scp, bufferp, userp, &req, + code = cm_SyncOp(scp, bufferp, userp, &req, PRSFS_LOOKUP, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_READ); - if (code) break; + if (code) break; if (cm_HaveBuffer(scp, bufferp, 0)) break; @@ -3831,70 +3825,70 @@ long smb_ReceiveTran2SearchDir(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t if (code) break; } if (code) { - buf_Release(bufferp); + buf_Release(bufferp); bufferp = NULL; break; - } + } } /* if (wrong buffer) ... */ /* now we have the buffer containing the entry we're interested * in; copy it out if it represents a non-deleted entry. */ - entryInDir = curOffset.LowPart & (2048-1); + entryInDir = curOffset.LowPart & (2048-1); entryInBuffer = curOffset.LowPart & (buf_bufferSize - 1); - /* page header will help tell us which entries are free. Page - * header can change more often than once per buffer, since - * AFS 3 dir page size may be less than (but not more than) - * a buffer package buffer. + /* page header will help tell us which entries are free. Page + * header can change more often than once per buffer, since + * AFS 3 dir page size may be less than (but not more than) + * a buffer package buffer. */ - /* only look intra-buffer */ - temp = curOffset.LowPart & (buf_bufferSize - 1); + /* only look intra-buffer */ + temp = curOffset.LowPart & (buf_bufferSize - 1); temp &= ~(2048 - 1); /* turn off intra-page bits */ - pageHeaderp = (cm_pageHeader_t *) (bufferp->datap + temp); + pageHeaderp = (cm_pageHeader_t *) (bufferp->datap + temp); - /* now determine which entry we're looking at in the page. - * If it is free (there's a free bitmap at the start of the - * dir), we should skip these 32 bytes. + /* now determine which entry we're looking at in the page. + * If it is free (there's a free bitmap at the start of the + * dir), we should skip these 32 bytes. */ slotInPage = (entryInDir & 0x7e0) >> 5; - if (!(pageHeaderp->freeBitmap[slotInPage>>3] - & (1 << (slotInPage & 0x7)))) { - /* this entry is free */ + if (!(pageHeaderp->freeBitmap[slotInPage>>3] & + (1 << (slotInPage & 0x7)))) { + /* this entry is free */ numDirChunks = 1; /* only skip this guy */ goto nextEntry; } - tp = bufferp->datap + entryInBuffer; + tp = bufferp->datap + entryInBuffer; dep = (cm_dirEntry_t *) tp; /* now points to AFS3 dir entry */ /* while we're here, compute the next entry's location, too, - * since we'll need it when writing out the cookie into the dir - * listing stream. + * since we'll need it when writing out the cookie into the dir + * listing stream. * * XXXX Probably should do more sanity checking. */ - numDirChunks = cm_NameEntries(dep->name, &onbytes); + numDirChunks = cm_NameEntries(dep->name, &onbytes); /* compute offset of cookie representing next entry */ nextEntryCookie = curOffset.LowPart + (CM_DIR_CHUNKSIZE * numDirChunks); - /* Need 8.3 name? */ - NeedShortName = 0; - if (infoLevel == 0x104 - && dep->fid.vnode != 0 - && !cm_Is8Dot3(dep->name)) { - cm_Gen8Dot3Name(dep, shortName, &shortNameEnd); - NeedShortName = 1; - } + /* Need 8.3 name? */ + NeedShortName = 0; + if (infoLevel == 0x104 + && dep->fid.vnode != 0 + && !cm_Is8Dot3(dep->name)) { + cm_Gen8Dot3Name(dep, shortName, &shortNameEnd); + NeedShortName = 1; + } /* When matching, we are using doing a case fold if we have a wildcard mask. * If we get a non-wildcard match, it's a lookup for a specific file. */ if (dep->fid.vnode != 0 && - (smb_V3MatchMask(dep->name, maskp, (starPattern? CM_FLAG_CASEFOLD : 0)) - || (NeedShortName - && smb_V3MatchMask(shortName, maskp, CM_FLAG_CASEFOLD)))) { + (smb_V3MatchMask(dep->name, maskp, (starPattern? CM_FLAG_CASEFOLD : 0)) || + (NeedShortName && + smb_V3MatchMask(shortName, maskp, CM_FLAG_CASEFOLD)))) { /* Eliminate entries that don't match requested attributes */ if (smb_hideDotFiles && !(dsp->attribute & SMB_ATTR_HIDDEN) && @@ -3916,132 +3910,131 @@ long smb_ReceiveTran2SearchDir(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t goto nextEntry; } - /* finally check if this name will fit */ + /* finally check if this name will fit */ - /* standard dir entry stuff */ - if (infoLevel < 0x101) - ohbytes = 23; /* pre-NT */ - else if (infoLevel == 0x103) - ohbytes = 12; /* NT names only */ - else - ohbytes = 64; /* NT */ + /* standard dir entry stuff */ + if (infoLevel < 0x101) + ohbytes = 23; /* pre-NT */ + else if (infoLevel == 0x103) + ohbytes = 12; /* NT names only */ + else + ohbytes = 64; /* NT */ - if (infoLevel == 0x104) - ohbytes += 26; /* Short name & length */ + if (infoLevel == 0x104) + ohbytes += 26; /* Short name & length */ if (searchFlags & 4) { ohbytes += 4; /* if resume key required */ - } + } if (infoLevel != 1 && infoLevel != 0x101 && infoLevel != 0x103) - ohbytes += 4; /* EASIZE */ + ohbytes += 4; /* EASIZE */ - /* add header to name & term. null */ - orbytes = onbytes + ohbytes + 1; + /* add header to name & term. null */ + orbytes = onbytes + ohbytes + 1; - /* now, we round up the record to a 4 byte alignment, - * and we make sure that we have enough room here for - * even the aligned version (so we don't have to worry - * about an * overflow when we pad things out below). - * That's the reason for the alignment arithmetic below. + /* now, we round up the record to a 4 byte alignment, + * and we make sure that we have enough room here for + * even the aligned version (so we don't have to worry + * about an * overflow when we pad things out below). + * That's the reason for the alignment arithmetic below. */ - if (infoLevel >= 0x101) - align = (4 - (orbytes & 3)) & 3; - else - align = 0; - if (orbytes + bytesInBuffer + align > maxReturnData) + if (infoLevel >= 0x101) + align = (4 - (orbytes & 3)) & 3; + else + align = 0; + if (orbytes + bytesInBuffer + align > maxReturnData) break; - /* this is one of the entries to use: it is not deleted - * and it matches the star pattern we're looking for. - * Put out the name, preceded by its length. + /* this is one of the entries to use: it is not deleted + * and it matches the star pattern we're looking for. + * Put out the name, preceded by its length. */ - /* First zero everything else */ - memset(origOp, 0, ohbytes); + /* First zero everything else */ + memset(origOp, 0, ohbytes); - if (infoLevel <= 0x101) + if (infoLevel <= 0x101) *(origOp + ohbytes - 1) = (unsigned char) onbytes; - else if (infoLevel == 0x103) - *((u_long *)(op + 8)) = onbytes; - else - *((u_long *)(op + 60)) = onbytes; + else if (infoLevel == 0x103) + *((u_long *)(op + 8)) = onbytes; + else + *((u_long *)(op + 60)) = onbytes; strcpy(origOp+ohbytes, dep->name); - /* Short name if requested and needed */ + /* Short name if requested and needed */ if (infoLevel == 0x104) { - if (NeedShortName) { - strcpy(op + 70, shortName); - *(op + 68) = shortNameEnd - shortName; - } - } + if (NeedShortName) { + strcpy(op + 70, shortName); + *(op + 68) = shortNameEnd - shortName; + } + } /* now, adjust the # of entries copied */ returnedNames++; - /* NextEntryOffset and FileIndex */ - if (infoLevel >= 101) { - int entryOffset = orbytes + align; - *((u_long *)op) = entryOffset; - *((u_long *)(op+4)) = nextEntryCookie; - } + /* NextEntryOffset and FileIndex */ + if (infoLevel >= 101) { + int entryOffset = orbytes + align; + *((u_long *)op) = entryOffset; + *((u_long *)(op+4)) = nextEntryCookie; + } /* now we emit the attribute. This is tricky, since * we need to really stat the file to find out what - * type of entry we've got. Right now, we're copying - * out data from * a buffer, while holding the scp - * locked, so it isn't really convenient to stat - * something now. We'll put in a place holder + * type of entry we've got. Right now, we're copying + * out data from * a buffer, while holding the scp + * locked, so it isn't really convenient to stat + * something now. We'll put in a place holder * now, and make a second pass before returning this - * to get the real attributes. So, we just skip the - * data for now, and adjust it later. We allocate a - * patch record to make it easy to find this point - * later. The replay will happen at a time when it is - * safe to unlock the directory. + * to get the real attributes. So, we just skip the + * data for now, and adjust it later. We allocate a + * patch record to make it easy to find this point + * later. The replay will happen at a time when it is + * safe to unlock the directory. */ - if (infoLevel != 0x103) { - curPatchp = malloc(sizeof(*curPatchp)); + if (infoLevel != 0x103) { + curPatchp = malloc(sizeof(*curPatchp)); osi_QAdd((osi_queue_t **) &dirListPatchesp, &curPatchp->q); - curPatchp->dptr = op; - if (infoLevel >= 0x101) - curPatchp->dptr += 8; + curPatchp->dptr = op; + if (infoLevel >= 0x101) + curPatchp->dptr += 8; if (smb_hideDotFiles && smb_IsDotFile(dep->name)) { curPatchp->flags = SMB_DIRLISTPATCH_DOTFILE; - } - else + } + else curPatchp->flags = 0; - curPatchp->fid.cell = scp->fid.cell; - curPatchp->fid.volume = scp->fid.volume; - curPatchp->fid.vnode = ntohl(dep->fid.vnode); - curPatchp->fid.unique = ntohl(dep->fid.unique); + curPatchp->fid.cell = scp->fid.cell; + curPatchp->fid.volume = scp->fid.volume; + curPatchp->fid.vnode = ntohl(dep->fid.vnode); + curPatchp->fid.unique = ntohl(dep->fid.unique); /* temp */ curPatchp->dep = dep; - } + } - if (searchFlags & 4) - /* put out resume key */ - *((u_long *)origOp) = nextEntryCookie; + if (searchFlags & 4) + /* put out resume key */ + *((u_long *)origOp) = nextEntryCookie; - /* Adjust byte ptr and count */ - origOp += orbytes; /* skip entire record */ + /* Adjust byte ptr and count */ + origOp += orbytes; /* skip entire record */ bytesInBuffer += orbytes; - /* and pad the record out */ + /* and pad the record out */ while (--align >= 0) { - *origOp++ = 0; + *origOp++ = 0; bytesInBuffer++; } - - } /* if we're including this name */ + } /* if we're including this name */ else if (!NeedShortName && !starPattern && !foundInexact && - dep->fid.vnode != 0 && + dep->fid.vnode != 0 && smb_V3MatchMask(dep->name, maskp, CM_FLAG_CASEFOLD)) { /* We were looking for exact matches, but here's an inexact one*/ foundInexact = 1; @@ -4049,10 +4042,10 @@ long smb_ReceiveTran2SearchDir(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t nextEntry: /* and adjust curOffset to be where the new cookie is */ - thyper.HighPart = 0; + thyper.HighPart = 0; thyper.LowPart = CM_DIR_CHUNKSIZE * numDirChunks; curOffset = LargeIntegerAdd(thyper, curOffset); - } /* while copying data for dir listing */ + } /* while copying data for dir listing */ /* If we didn't get a star pattern, we did an exact match during the first pass. * If there were no exact matches found, we fail over to inexact matches by @@ -4065,20 +4058,20 @@ long smb_ReceiveTran2SearchDir(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t goto startsearch; } - /* release the mutex */ - lock_ReleaseMutex(&scp->mx); + /* release the mutex */ + lock_ReleaseMutex(&scp->mx); if (bufferp) buf_Release(bufferp); - /* apply and free last set of patches; if not doing a star match, this - * will be empty, but better safe (and freeing everything) than sorry. + /* apply and free last set of patches; if not doing a star match, this + * will be empty, but better safe (and freeing everything) than sorry. */ smb_ApplyV3DirListPatches(scp, &dirListPatchesp, infoLevel, userp, &req); /* now put out the final parameters */ - if (returnedNames == 0) eos = 1; + if (returnedNames == 0) eos = 1; if (p->opcode == 1) { - /* find first */ + /* find first */ outp->parmsp[0] = (unsigned short) dsp->cookie; outp->parmsp[1] = returnedNames; outp->parmsp[2] = eos; @@ -4100,30 +4093,30 @@ long smb_ReceiveTran2SearchDir(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t outp->totalParms = 8; /* in bytes */ } - /* return # of bytes in the buffer */ + /* return # of bytes in the buffer */ outp->totalData = bytesInBuffer; - osi_Log2(smb_logp, "T2 search dir done, %d names, code %d", - returnedNames, code); + osi_Log2(smb_logp, "T2 search dir done, %d names, code %d", + returnedNames, code); - /* Return error code if unsuccessful on first request */ - if (code == 0 && p->opcode == 1 && returnedNames == 0) - code = CM_ERROR_NOSUCHFILE; + /* Return error code if unsuccessful on first request */ + if (code == 0 && p->opcode == 1 && returnedNames == 0) + code = CM_ERROR_NOSUCHFILE; - /* if we're supposed to close the search after this request, or if + /* if we're supposed to close the search after this request, or if * we're supposed to close the search if we're done, and we're done, * or if something went wrong, close the search. */ /* ((searchFlags & 1) || ((searchFlags & 2) && eos) */ - if ((searchFlags & 1) || (returnedNames == 0) || + if ((searchFlags & 1) || (returnedNames == 0) || ((searchFlags & 2) && eos) || code != 0) - smb_DeleteDirSearch(dsp); - if (code) + smb_DeleteDirSearch(dsp); + if (code) smb_SendTran2Error(vcp, p, opx, code); - else { + else { smb_SendTran2Packet(vcp, outp, opx); - } - smb_FreeTran2Packet(outp); + } + smb_FreeTran2Packet(outp); smb_ReleaseDirSearch(dsp); cm_ReleaseSCache(scp); cm_ReleaseUser(userp); @@ -4142,29 +4135,29 @@ long smb_ReceiveV3FindClose(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp dsp = smb_FindDirSearch(dirHandle); if (!dsp) - return CM_ERROR_BADFD; + return CM_ERROR_BADFD; /* otherwise, we have an FD to destroy */ smb_DeleteDirSearch(dsp); smb_ReleaseDirSearch(dsp); - /* and return results */ - smb_SetSMBDataLength(outp, 0); + /* and return results */ + smb_SetSMBDataLength(outp, 0); return 0; } long smb_ReceiveV3FindNotifyClose(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { - smb_SetSMBDataLength(outp, 0); + smb_SetSMBDataLength(outp, 0); return 0; } long smb_ReceiveV3OpenX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { - char *pathp; + char *pathp; long code = 0; - cm_space_t *spacep; + cm_space_t *spacep; int excl; cm_user_t *userp; cm_scache_t *dscp; /* dir we're dealing with */ @@ -4181,18 +4174,18 @@ long smb_ReceiveV3OpenX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) int extraInfo; int openAction; int parmSlot; /* which parm we're dealing with */ - char *tidPathp; - cm_req_t req; + char *tidPathp; + cm_req_t req; - cm_InitReq(&req); + cm_InitReq(&req); scp = NULL; - extraInfo = (smb_GetSMBParm(inp, 2) & 1); /* return extra info */ - openFun = smb_GetSMBParm(inp, 8); /* open function */ + extraInfo = (smb_GetSMBParm(inp, 2) & 1); /* return extra info */ + openFun = smb_GetSMBParm(inp, 8); /* open function */ excl = ((openFun & 3) == 0); trunc = ((openFun & 3) == 2); /* truncate it */ - openMode = (smb_GetSMBParm(inp, 3) & 0x7); + openMode = (smb_GetSMBParm(inp, 3) & 0x7); openAction = 0; /* tracks what we did */ attributes = smb_GetSMBParm(inp, 5); @@ -4204,11 +4197,11 @@ long smb_ReceiveV3OpenX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) pathp = smb_GetSMBData(inp, NULL); - spacep = inp->spacep; + spacep = inp->spacep; smb_StripLastComponent(spacep->data, &lastNamep, pathp); - if (lastNamep && strcmp(lastNamep, SMB_IOCTL_FILENAME) == 0) { - /* special case magic file name for receiving IOCTL requests + if (lastNamep && strcmp(lastNamep, SMB_IOCTL_FILENAME) == 0) { + /* special case magic file name for receiving IOCTL requests * (since IOCTL calls themselves aren't getting through). */ #ifdef NOTSERVICE @@ -4218,13 +4211,13 @@ long smb_ReceiveV3OpenX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) fidp = smb_FindFID(vcp, 0, SMB_FLAG_CREATE); smb_SetupIoctlFid(fidp, spacep); - /* set inp->fid so that later read calls in same msg can find fid */ + /* set inp->fid so that later read calls in same msg can find fid */ inp->fid = fidp->fid; /* copy out remainder of the parms */ - parmSlot = 2; - smb_SetSMBParm(outp, parmSlot, fidp->fid); parmSlot++; - if (extraInfo) { + parmSlot = 2; + smb_SetSMBParm(outp, parmSlot, fidp->fid); parmSlot++; + if (extraInfo) { smb_SetSMBParm(outp, parmSlot, /* attrs */ 0); parmSlot++; smb_SetSMBParm(outp, parmSlot, 0); parmSlot++; /* mod time */ smb_SetSMBParm(outp, parmSlot, 0); parmSlot++; @@ -4233,16 +4226,16 @@ long smb_ReceiveV3OpenX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) smb_SetSMBParm(outp, parmSlot, openMode); parmSlot++; smb_SetSMBParm(outp, parmSlot, 0); parmSlot++; /* file type 0 ==> normal file or dir */ smb_SetSMBParm(outp, parmSlot, 0); parmSlot++; /* IPC junk */ - } - /* and the final "always present" stuff */ + } + /* and the final "always present" stuff */ smb_SetSMBParm(outp, parmSlot, /* openAction found existing file */ 1); parmSlot++; - /* next write out the "unique" ID */ - smb_SetSMBParm(outp, parmSlot, 0x1234); parmSlot++; - smb_SetSMBParm(outp, parmSlot, 0x5678); parmSlot++; + /* next write out the "unique" ID */ + smb_SetSMBParm(outp, parmSlot, 0x1234); parmSlot++; + smb_SetSMBParm(outp, parmSlot, 0x5678); parmSlot++; smb_SetSMBParm(outp, parmSlot, 0); parmSlot++; smb_SetSMBDataLength(outp, 0); - /* and clean up fid reference */ + /* and clean up fid reference */ smb_ReleaseFID(fidp); return 0; } @@ -4258,17 +4251,17 @@ long smb_ReceiveV3OpenX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) #endif userp = smb_GetUser(vcp, inp); - dscp = NULL; - code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &tidPathp); - if(code) { + dscp = NULL; + code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &tidPathp); + if (code) { cm_ReleaseUser(userp); return CM_ERROR_NOSUCHPATH; } - code = cm_NameI(cm_rootSCachep, pathp, + code = cm_NameI(cm_rootSCachep, pathp, CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD, userp, tidPathp, &req, &scp); - if (code != 0) { - code = cm_NameI(cm_rootSCachep, spacep->data, + if (code != 0) { + code = cm_NameI(cm_rootSCachep, spacep->data, CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD, userp, tidPathp, &req, &dscp); @@ -4290,14 +4283,14 @@ long smb_ReceiveV3OpenX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) cm_ReleaseUser(userp); return code; } - } + } /* if we get here, if code is 0, the file exists and is represented by * scp. Otherwise, we have to create it. The dir may be represented * by dscp, or we may have found the file directly. If code is non-zero, * scp is NULL. */ - if (code == 0) { + if (code == 0) { code = cm_CheckOpen(scp, openMode, trunc, userp, &req); if (code) { if (dscp) cm_ReleaseSCache(dscp); @@ -4306,105 +4299,105 @@ long smb_ReceiveV3OpenX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) return code; } - if (excl) { - /* oops, file shouldn't be there */ + if (excl) { + /* oops, file shouldn't be there */ if (dscp) cm_ReleaseSCache(dscp); cm_ReleaseSCache(scp); cm_ReleaseUser(userp); return CM_ERROR_EXISTS; } - if (trunc) { - setAttr.mask = CM_ATTRMASK_LENGTH; + if (trunc) { + setAttr.mask = CM_ATTRMASK_LENGTH; setAttr.length.LowPart = 0; setAttr.length.HighPart = 0; - code = cm_SetAttr(scp, &setAttr, userp, &req); + code = cm_SetAttr(scp, &setAttr, userp, &req); openAction = 3; /* truncated existing file */ - } + } else openAction = 1; /* found existing file */ } - else if (!(openFun & 0x10)) { - /* don't create if not found */ + else if (!(openFun & 0x10)) { + /* don't create if not found */ if (dscp) cm_ReleaseSCache(dscp); cm_ReleaseUser(userp); return CM_ERROR_NOSUCHFILE; } else { - osi_assert(dscp != NULL); - osi_Log1(smb_logp, "smb_ReceiveV3OpenX creating file %s", + osi_assert(dscp != NULL); + osi_Log1(smb_logp, "smb_ReceiveV3OpenX creating file %s", osi_LogSaveString(smb_logp, lastNamep)); - openAction = 2; /* created file */ - setAttr.mask = CM_ATTRMASK_CLIENTMODTIME; - smb_UnixTimeFromDosUTime(&setAttr.clientModTime, dosTime); + openAction = 2; /* created file */ + setAttr.mask = CM_ATTRMASK_CLIENTMODTIME; + smb_UnixTimeFromDosUTime(&setAttr.clientModTime, dosTime); code = cm_Create(dscp, lastNamep, 0, &setAttr, &scp, userp, &req); - if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH)) - smb_NotifyChange(FILE_ACTION_ADDED, + if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH)) + smb_NotifyChange(FILE_ACTION_ADDED, FILE_NOTIFY_CHANGE_FILE_NAME, dscp, lastNamep, NULL, TRUE); if (!excl && code == CM_ERROR_EXISTS) { - /* not an exclusive create, and someone else tried - * creating it already, then we open it anyway. We - * don't bother retrying after this, since if this next - * fails, that means that the file was deleted after we - * started this call. + /* not an exclusive create, and someone else tried + * creating it already, then we open it anyway. We + * don't bother retrying after this, since if this next + * fails, that means that the file was deleted after we + * started this call. */ code = cm_Lookup(dscp, lastNamep, CM_FLAG_CASEFOLD, userp, &req, &scp); if (code == 0) { if (trunc) { - setAttr.mask = CM_ATTRMASK_LENGTH; + setAttr.mask = CM_ATTRMASK_LENGTH; setAttr.length.LowPart = 0; setAttr.length.HighPart = 0; code = cm_SetAttr(scp, &setAttr, userp, &req); } - } /* lookup succeeded */ + } /* lookup succeeded */ } } - /* we don't need this any longer */ - if (dscp) cm_ReleaseSCache(dscp); + /* we don't need this any longer */ + if (dscp) cm_ReleaseSCache(dscp); if (code) { - /* something went wrong creating or truncating the file */ + /* something went wrong creating or truncating the file */ if (scp) cm_ReleaseSCache(scp); cm_ReleaseUser(userp); return code; } - /* make sure we're about to open a file */ - if (scp->fileType != CM_SCACHETYPE_FILE) { - cm_ReleaseSCache(scp); - cm_ReleaseUser(userp); - return CM_ERROR_ISDIR; - } + /* make sure we're about to open a file */ + if (scp->fileType != CM_SCACHETYPE_FILE) { + cm_ReleaseSCache(scp); + cm_ReleaseUser(userp); + return CM_ERROR_ISDIR; + } /* now all we have to do is open the file itself */ fidp = smb_FindFID(vcp, 0, SMB_FLAG_CREATE); osi_assert(fidp); - /* save a pointer to the vnode */ + /* save a pointer to the vnode */ fidp->scp = scp; - /* compute open mode */ + /* compute open mode */ if (openMode != 1) fidp->flags |= SMB_FID_OPENREAD; if (openMode == 1 || openMode == 2) fidp->flags |= SMB_FID_OPENWRITE; - smb_ReleaseFID(fidp); + smb_ReleaseFID(fidp); - cm_Open(scp, 0, userp); + cm_Open(scp, 0, userp); - /* set inp->fid so that later read calls in same msg can find fid */ + /* set inp->fid so that later read calls in same msg can find fid */ inp->fid = fidp->fid; /* copy out remainder of the parms */ - parmSlot = 2; - smb_SetSMBParm(outp, parmSlot, fidp->fid); parmSlot++; - lock_ObtainMutex(&scp->mx); - if (extraInfo) { + parmSlot = 2; + smb_SetSMBParm(outp, parmSlot, fidp->fid); parmSlot++; + lock_ObtainMutex(&scp->mx); + if (extraInfo) { smb_SetSMBParm(outp, parmSlot, smb_Attributes(scp)); parmSlot++; - smb_DosUTimeFromUnixTime(&dosTime, scp->clientModTime); + smb_DosUTimeFromUnixTime(&dosTime, scp->clientModTime); smb_SetSMBParm(outp, parmSlot, dosTime & 0xffff); parmSlot++; smb_SetSMBParm(outp, parmSlot, (dosTime>>16) & 0xffff); parmSlot++; smb_SetSMBParm(outp, parmSlot, scp->length.LowPart & 0xffff); parmSlot++; @@ -4412,59 +4405,59 @@ long smb_ReceiveV3OpenX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) smb_SetSMBParm(outp, parmSlot, openMode); parmSlot++; smb_SetSMBParm(outp, parmSlot, 0); parmSlot++; /* file type 0 ==> normal file or dir */ smb_SetSMBParm(outp, parmSlot, 0); parmSlot++; /* IPC junk */ - } - /* and the final "always present" stuff */ + } + /* and the final "always present" stuff */ smb_SetSMBParm(outp, parmSlot, openAction); parmSlot++; - /* next write out the "unique" ID */ - smb_SetSMBParm(outp, parmSlot, scp->fid.vnode & 0xffff); parmSlot++; - smb_SetSMBParm(outp, parmSlot, scp->fid.volume & 0xffff); parmSlot++; + /* next write out the "unique" ID */ + smb_SetSMBParm(outp, parmSlot, scp->fid.vnode & 0xffff); parmSlot++; + smb_SetSMBParm(outp, parmSlot, scp->fid.volume & 0xffff); parmSlot++; smb_SetSMBParm(outp, parmSlot, 0); parmSlot++; - lock_ReleaseMutex(&scp->mx); + lock_ReleaseMutex(&scp->mx); smb_SetSMBDataLength(outp, 0); - osi_Log1(smb_logp, "SMB OpenX opening fid %d", fidp->fid); + osi_Log1(smb_logp, "SMB OpenX opening fid %d", fidp->fid); cm_ReleaseUser(userp); /* leave scp held since we put it in fidp->scp */ return 0; -} +} long smb_ReceiveV3LockingX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { - cm_req_t req; - cm_user_t *userp; - unsigned short fid; - smb_fid_t *fidp; - cm_scache_t *scp; - unsigned char LockType; - unsigned short NumberOfUnlocks, NumberOfLocks; - unsigned long Timeout; - char *op; - LARGE_INTEGER LOffset, LLength; - smb_waitingLock_t *waitingLock; - void *lockp; - long code = 0; - int i; - - cm_InitReq(&req); - - fid = smb_GetSMBParm(inp, 2); - fid = smb_ChainFID(fid, inp); - - fidp = smb_FindFID(vcp, fid, 0); - if (!fidp || (fidp->flags & SMB_FID_IOCTL)) { - return CM_ERROR_BADFD; - } - /* set inp->fid so that later read calls in same msg can find fid */ + cm_req_t req; + cm_user_t *userp; + unsigned short fid; + smb_fid_t *fidp; + cm_scache_t *scp; + unsigned char LockType; + unsigned short NumberOfUnlocks, NumberOfLocks; + unsigned long Timeout; + char *op; + LARGE_INTEGER LOffset, LLength; + smb_waitingLock_t *waitingLock; + void *lockp; + long code = 0; + int i; + + cm_InitReq(&req); + + fid = smb_GetSMBParm(inp, 2); + fid = smb_ChainFID(fid, inp); + + fidp = smb_FindFID(vcp, fid, 0); + if (!fidp || (fidp->flags & SMB_FID_IOCTL)) { + return CM_ERROR_BADFD; + } + /* set inp->fid so that later read calls in same msg can find fid */ inp->fid = fid; - userp = smb_GetUser(vcp, inp); + userp = smb_GetUser(vcp, inp); - scp = fidp->scp; + scp = fidp->scp; - lock_ObtainMutex(&scp->mx); - code = cm_SyncOp(scp, NULL, userp, &req, 0, - CM_SCACHESYNC_NEEDCALLBACK + lock_ObtainMutex(&scp->mx); + code = cm_SyncOp(scp, NULL, userp, &req, 0, + CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_LOCK); if (code) goto doneSync; @@ -4477,106 +4470,106 @@ long smb_ReceiveV3LockingX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) op = smb_GetSMBData(inp, NULL); for (i=0; ilength)) - continue; - - code = cm_Lock(scp, LockType, LOffset, LLength, Timeout, - userp, &req, &lockp); - if (code == CM_ERROR_WOULDBLOCK && Timeout != 0) { - /* Put on waiting list */ - waitingLock = malloc(sizeof(smb_waitingLock_t)); - waitingLock->vcp = vcp; - waitingLock->inp = smb_CopyPacket(inp); - waitingLock->outp = smb_CopyPacket(outp); - waitingLock->timeRemaining = Timeout; - waitingLock->lockp = lockp; - lock_ObtainWrite(&smb_globalLock); - osi_QAdd((osi_queue_t **)&smb_allWaitingLocks, - &waitingLock->q); - osi_Wakeup((long) &smb_allWaitingLocks); - lock_ReleaseWrite(&smb_globalLock); - /* don't send reply immediately */ - outp->flags |= SMB_PACKETFLAG_NOSEND; - } - if (code) break; - } + if (LockType & 0x10) { + /* Large Files */ + LOffset.HighPart = *((LONG *)(op + 4)); + LOffset.LowPart = *((DWORD *)(op + 8)); + LLength.HighPart = *((LONG *)(op + 12)); + LLength.LowPart = *((DWORD *)(op + 16)); + op += 20; + } + else { + /* Not Large Files */ + LOffset.HighPart = 0; + LOffset.LowPart = *((DWORD *)(op + 2)); + LLength.HighPart = 0; + LLength.LowPart = *((DWORD *)(op + 6)); + op += 10; + } + if (LargeIntegerNotEqualToZero(LOffset)) + continue; + if (LargeIntegerLessThan(LOffset, scp->length)) + continue; + + code = cm_Lock(scp, LockType, LOffset, LLength, Timeout, + userp, &req, &lockp); + if (code == CM_ERROR_WOULDBLOCK && Timeout != 0) { + /* Put on waiting list */ + waitingLock = malloc(sizeof(smb_waitingLock_t)); + waitingLock->vcp = vcp; + waitingLock->inp = smb_CopyPacket(inp); + waitingLock->outp = smb_CopyPacket(outp); + waitingLock->timeRemaining = Timeout; + waitingLock->lockp = lockp; + lock_ObtainWrite(&smb_globalLock); + osi_QAdd((osi_queue_t **)&smb_allWaitingLocks, + &waitingLock->q); + osi_Wakeup((long) &smb_allWaitingLocks); + lock_ReleaseWrite(&smb_globalLock); + /* don't send reply immediately */ + outp->flags |= SMB_PACKETFLAG_NOSEND; + } + if (code) break; + } - if (code) { - /* release any locks acquired before the failure */ - } - else - smb_SetSMBDataLength(outp, 0); -done: - cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_LOCK); -doneSync: - lock_ReleaseMutex(&scp->mx); - cm_ReleaseUser(userp); - smb_ReleaseFID(fidp); - - return code; + if (code) { + /* release any locks acquired before the failure */ + } + else + smb_SetSMBDataLength(outp, 0); + done: + cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_LOCK); + doneSync: + lock_ReleaseMutex(&scp->mx); + cm_ReleaseUser(userp); + smb_ReleaseFID(fidp); + + return code; } long smb_ReceiveV3GetAttributes(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { - unsigned short fid; + unsigned short fid; smb_fid_t *fidp; cm_scache_t *scp; long code = 0; time_t searchTime; cm_user_t *userp; - cm_req_t req; + cm_req_t req; - cm_InitReq(&req); + cm_InitReq(&req); fid = smb_GetSMBParm(inp, 0); fid = smb_ChainFID(fid, inp); fidp = smb_FindFID(vcp, fid, 0); if (!fidp || (fidp->flags & SMB_FID_IOCTL)) { - return CM_ERROR_BADFD; + return CM_ERROR_BADFD; } userp = smb_GetUser(vcp, inp); @@ -4584,16 +4577,16 @@ long smb_ReceiveV3GetAttributes(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t * scp = fidp->scp; /* otherwise, stat the file */ - lock_ObtainMutex(&scp->mx); + lock_ObtainMutex(&scp->mx); code = cm_SyncOp(scp, NULL, userp, &req, 0, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); - if (code) goto done; + if (code) goto done; - /* decode times. We need a search time, but the response to this + /* decode times. We need a search time, but the response to this * call provides the date first, not the time, as returned in the * searchTime variable. So we take the high-order bits first. */ - smb_SearchTimeFromUnixTime(&searchTime, scp->clientModTime); + smb_SearchTimeFromUnixTime(&searchTime, scp->clientModTime); smb_SetSMBParm(outp, 0, (searchTime >> 16) & 0xffff); /* ctime */ smb_SetSMBParm(outp, 1, searchTime & 0xffff); smb_SetSMBParm(outp, 2, (searchTime >> 16) & 0xffff); /* atime */ @@ -4607,7 +4600,7 @@ long smb_ReceiveV3GetAttributes(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t * smb_SetSMBParm(outp, 8, scp->length.LowPart & 0xffff); /* alloc size */ smb_SetSMBParm(outp, 9, (scp->length.LowPart >> 16) & 0xffff); - /* file attribute */ + /* file attribute */ smb_SetSMBParm(outp, 10, smb_Attributes(scp)); /* and finalize stuff */ @@ -4615,15 +4608,15 @@ long smb_ReceiveV3GetAttributes(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t * code = 0; done: - lock_ReleaseMutex(&scp->mx); - cm_ReleaseUser(userp); - smb_ReleaseFID(fidp); - return code; -} + lock_ReleaseMutex(&scp->mx); + cm_ReleaseUser(userp); + smb_ReleaseFID(fidp); + return code; +} long smb_ReceiveV3SetAttributes(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { - unsigned short fid; + unsigned short fid; smb_fid_t *fidp; cm_scache_t *scp; long code = 0; @@ -4631,30 +4624,30 @@ long smb_ReceiveV3SetAttributes(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t * time_t unixTime; cm_user_t *userp; cm_attr_t attrs; - cm_req_t req; + cm_req_t req; - cm_InitReq(&req); + cm_InitReq(&req); fid = smb_GetSMBParm(inp, 0); fid = smb_ChainFID(fid, inp); fidp = smb_FindFID(vcp, fid, 0); if (!fidp || (fidp->flags & SMB_FID_IOCTL)) { - return CM_ERROR_BADFD; + return CM_ERROR_BADFD; } userp = smb_GetUser(vcp, inp); scp = fidp->scp; - /* now prepare to call cm_setattr. This message only sets various times, + /* now prepare to call cm_setattr. This message only sets various times, * and AFS only implements mtime, and we'll set the mtime if that's * requested. The others we'll ignore. */ - searchTime = smb_GetSMBParm(inp, 5) | (smb_GetSMBParm(inp, 6) << 16); + searchTime = smb_GetSMBParm(inp, 5) | (smb_GetSMBParm(inp, 6) << 16); if (searchTime != 0) { - smb_UnixTimeFromSearchTime(&unixTime, searchTime); + smb_UnixTimeFromSearchTime(&unixTime, searchTime); if ( unixTime != -1 ) { attrs.mask = CM_ATTRMASK_CLIENTMODTIME; @@ -4668,15 +4661,15 @@ long smb_ReceiveV3SetAttributes(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t * } else code = 0; - cm_ReleaseUser(userp); - smb_ReleaseFID(fidp); - return code; + cm_ReleaseUser(userp); + smb_ReleaseFID(fidp); + return code; } long smb_ReceiveV3ReadX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { - osi_hyper_t offset; + osi_hyper_t offset; long count, finalCount; unsigned short fd; smb_fid_t *fidp; @@ -4692,35 +4685,35 @@ long smb_ReceiveV3ReadX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) osi_Log3(smb_logp, "smb_ReceiveV3Read fd %d, off 0x%x, size 0x%x", fd, offset.LowPart, count); - fd = smb_ChainFID(fd, inp); + fd = smb_ChainFID(fd, inp); fidp = smb_FindFID(vcp, fd, 0); if (!fidp) { - return CM_ERROR_BADFD; + return CM_ERROR_BADFD; } - /* set inp->fid so that later read calls in same msg can find fid */ + /* set inp->fid so that later read calls in same msg can find fid */ inp->fid = fd; if (fidp->flags & SMB_FID_IOCTL) { - return smb_IoctlV3Read(fidp, vcp, inp, outp); + return smb_IoctlV3Read(fidp, vcp, inp, outp); } - userp = smb_GetUser(vcp, inp); + userp = smb_GetUser(vcp, inp); - /* 0 and 1 are reserved for request chaining, were setup by our caller, + /* 0 and 1 are reserved for request chaining, were setup by our caller, * and will be further filled in after we return. */ smb_SetSMBParm(outp, 2, 0); /* remaining bytes, for pipes */ smb_SetSMBParm(outp, 3, 0); /* resvd */ smb_SetSMBParm(outp, 4, 0); /* resvd */ - smb_SetSMBParm(outp, 5, count); /* # of bytes we're going to read */ + smb_SetSMBParm(outp, 5, count); /* # of bytes we're going to read */ /* fill in #6 when we have all the parameters' space reserved */ smb_SetSMBParm(outp, 7, 0); /* resv'd */ smb_SetSMBParm(outp, 8, 0); /* resv'd */ smb_SetSMBParm(outp, 9, 0); /* resv'd */ smb_SetSMBParm(outp, 10, 0); /* resv'd */ - smb_SetSMBParm(outp, 11, 0); /* reserved */ + smb_SetSMBParm(outp, 11, 0); /* reserved */ - /* get op ptr after putting in the parms, since otherwise we don't + /* get op ptr after putting in the parms, since otherwise we don't * know where the data really is. */ op = smb_GetSMBData(outp, NULL); @@ -4728,18 +4721,18 @@ long smb_ReceiveV3ReadX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) /* now fill in offset from start of SMB header to first data byte (to op) */ smb_SetSMBParm(outp, 6, ((int) (op - outp->data))); - /* set the packet data length the count of the # of bytes */ + /* set the packet data length the count of the # of bytes */ smb_SetSMBDataLength(outp, count); #ifndef DJGPP - code = smb_ReadData(fidp, &offset, count, op, userp, &finalCount); + code = smb_ReadData(fidp, &offset, count, op, userp, &finalCount); #else /* DJGPP */ - code = smb_ReadData(fidp, &offset, count, op, userp, &finalCount, FALSE); + code = smb_ReadData(fidp, &offset, count, op, userp, &finalCount, FALSE); #endif /* !DJGPP */ - /* fix some things up */ - smb_SetSMBParm(outp, 5, finalCount); - smb_SetSMBDataLength(outp, finalCount); + /* fix some things up */ + smb_SetSMBParm(outp, 5, finalCount); + smb_SetSMBDataLength(outp, finalCount); smb_ReleaseFID(fidp); @@ -5012,7 +5005,7 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) code = 0; if (baseFid != 0) - smb_ReleaseFID(baseFidp); + smb_ReleaseFID(baseFidp); if (code) { osi_Log0(smb_logp,"NTCreateX parent not found"); @@ -5044,14 +5037,15 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) if (!foundscp && !treeCreate) { if ( createDisp == FILE_CREATE || createDisp == FILE_OVERWRITE || - createDisp == FILE_OVERWRITE_IF) { + createDisp == FILE_OVERWRITE_IF) + { code = cm_Lookup(dscp, lastNamep, CM_FLAG_FOLLOW, userp, &req, &scp); - } else { - code = cm_Lookup(dscp, lastNamep, - CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD, - userp, &req, &scp); - } + } else { + code = cm_Lookup(dscp, lastNamep, + CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD, + userp, &req, &scp); + } if (code && code != CM_ERROR_NOSUCHFILE) { cm_ReleaseSCache(dscp); cm_ReleaseUser(userp); @@ -5105,9 +5099,9 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) openAction = 3; /* truncated existing file */ } else - openAction = 1; /* found existing file */ + openAction = 1; /* found existing file */ - code = cm_CheckNTOpen(scp, desiredAccess, createDisp, userp, + code = cm_CheckNTOpen(scp, desiredAccess, createDisp, userp, &req); if (code) { if (dscp) cm_ReleaseSCache(dscp); @@ -5929,15 +5923,15 @@ long smb_ReceiveNTTranCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *out long smb_ReceiveNTTranNotifyChange(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { - smb_packet_t *savedPacketp; - ULONG filter; USHORT fid, watchtree; - smb_fid_t *fidp; - cm_scache_t *scp; + smb_packet_t *savedPacketp; + ULONG filter; USHORT fid, watchtree; + smb_fid_t *fidp; + cm_scache_t *scp; - filter = smb_GetSMBParm(inp, 19) - | (smb_GetSMBParm(inp, 20) << 16); - fid = smb_GetSMBParm(inp, 21); - watchtree = smb_GetSMBParm(inp, 22) && 0xffff; /* TODO: should this be 0xff ? */ + filter = smb_GetSMBParm(inp, 19) | + (smb_GetSMBParm(inp, 20) << 16); + fid = smb_GetSMBParm(inp, 21); + watchtree = smb_GetSMBParm(inp, 22) && 0xffff; /* TODO: should this be 0xff ? */ fidp = smb_FindFID(vcp, fid, 0); if (!fidp) { @@ -5945,13 +5939,13 @@ long smb_ReceiveNTTranNotifyChange(smb_vc_t *vcp, smb_packet_t *inp, return CM_ERROR_BADFD; } - savedPacketp = smb_CopyPacket(inp); + savedPacketp = smb_CopyPacket(inp); smb_HoldVC(vcp); - savedPacketp->vcp = vcp; - lock_ObtainMutex(&smb_Dir_Watch_Lock); - savedPacketp->nextp = smb_Directory_Watches; - smb_Directory_Watches = savedPacketp; - lock_ReleaseMutex(&smb_Dir_Watch_Lock); + savedPacketp->vcp = vcp; + lock_ObtainMutex(&smb_Dir_Watch_Lock); + savedPacketp->nextp = smb_Directory_Watches; + smb_Directory_Watches = savedPacketp; + lock_ReleaseMutex(&smb_Dir_Watch_Lock); osi_Log4(smb_logp, "Request for NotifyChange filter 0x%x fid %d wtree %d file %s", filter, fid, watchtree, osi_LogSaveString(smb_logp, fidp->NTopen_wholepathp)); @@ -5965,91 +5959,91 @@ long smb_ReceiveNTTranNotifyChange(smb_vc_t *vcp, smb_packet_t *inp, lock_ReleaseMutex(&scp->mx); smb_ReleaseFID(fidp); - outp->flags |= SMB_PACKETFLAG_NOSEND; - return 0; + outp->flags |= SMB_PACKETFLAG_NOSEND; + return 0; } unsigned char nullSecurityDesc[36] = { - 0x01, /* security descriptor revision */ - 0x00, /* reserved, should be zero */ - 0x00, 0x80, /* security descriptor control; - * 0x8000 : self-relative format */ - 0x14, 0x00, 0x00, 0x00, /* offset of owner SID */ - 0x1c, 0x00, 0x00, 0x00, /* offset of group SID */ - 0x00, 0x00, 0x00, 0x00, /* offset of DACL would go here */ - 0x00, 0x00, 0x00, 0x00, /* offset of SACL would go here */ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - /* "null SID" owner SID */ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - /* "null SID" group SID */ -}; + 0x01, /* security descriptor revision */ + 0x00, /* reserved, should be zero */ + 0x00, 0x80, /* security descriptor control; + * 0x8000 : self-relative format */ + 0x14, 0x00, 0x00, 0x00, /* offset of owner SID */ + 0x1c, 0x00, 0x00, 0x00, /* offset of group SID */ + 0x00, 0x00, 0x00, 0x00, /* offset of DACL would go here */ + 0x00, 0x00, 0x00, 0x00, /* offset of SACL would go here */ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* "null SID" owner SID */ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + /* "null SID" group SID */ +}; long smb_ReceiveNTTranQuerySecurityDesc(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { - int parmOffset, parmCount, dataOffset, dataCount; - int parmSlot; - int maxData; - char *outData; - char *parmp; - USHORT *sparmp; - ULONG *lparmp; - USHORT fid; - ULONG securityInformation; - - parmOffset = smb_GetSMBOffsetParm(inp, 11, 1) - | (smb_GetSMBOffsetParm(inp, 12, 1) << 16); - parmp = inp->data + parmOffset; - sparmp = (USHORT *) parmp; - lparmp = (ULONG *) parmp; - - fid = sparmp[0]; - securityInformation = lparmp[1]; - - maxData = smb_GetSMBOffsetParm(inp, 7, 1) - | (smb_GetSMBOffsetParm(inp, 8, 1) << 16); - - if (maxData < 36) - dataCount = 0; - else - dataCount = 36; - - /* out parms */ - parmOffset = 8*4 + 39; - parmOffset += 1; /* pad to 4 */ - parmCount = 4; - dataOffset = parmOffset + parmCount; - - parmSlot = 1; - outp->oddByte = 1; - /* Total Parameter Count */ - smb_SetSMBParmLong(outp, parmSlot, parmCount); parmSlot += 2; - /* Total Data Count */ - smb_SetSMBParmLong(outp, parmSlot, dataCount); parmSlot += 2; - /* Parameter Count */ - smb_SetSMBParmLong(outp, parmSlot, parmCount); parmSlot += 2; - /* Parameter Offset */ - smb_SetSMBParmLong(outp, parmSlot, parmOffset); parmSlot += 2; - /* Parameter Displacement */ - smb_SetSMBParmLong(outp, parmSlot, 0); parmSlot += 2; - /* Data Count */ - smb_SetSMBParmLong(outp, parmSlot, dataCount); parmSlot += 2; - /* Data Offset */ - smb_SetSMBParmLong(outp, parmSlot, dataOffset); parmSlot += 2; - /* Data Displacement */ - smb_SetSMBParmLong(outp, parmSlot, 0); parmSlot += 2; - smb_SetSMBParmByte(outp, parmSlot, 0); /* Setup Count */ - smb_SetSMBDataLength(outp, 1 + parmCount + dataCount); - - outData = smb_GetSMBData(outp, NULL); - outData++; /* round to get to parmOffset */ - *((ULONG *)outData) = 36; outData += 4; /* length */ - - if (maxData >= 36) { - memcpy(outData, nullSecurityDesc, 36); - outData += 36; - return 0; - } else - return CM_ERROR_BUFFERTOOSMALL; + int parmOffset, parmCount, dataOffset, dataCount; + int parmSlot; + int maxData; + char *outData; + char *parmp; + USHORT *sparmp; + ULONG *lparmp; + USHORT fid; + ULONG securityInformation; + + parmOffset = smb_GetSMBOffsetParm(inp, 11, 1) + | (smb_GetSMBOffsetParm(inp, 12, 1) << 16); + parmp = inp->data + parmOffset; + sparmp = (USHORT *) parmp; + lparmp = (ULONG *) parmp; + + fid = sparmp[0]; + securityInformation = lparmp[1]; + + maxData = smb_GetSMBOffsetParm(inp, 7, 1) + | (smb_GetSMBOffsetParm(inp, 8, 1) << 16); + + if (maxData < 36) + dataCount = 0; + else + dataCount = 36; + + /* out parms */ + parmOffset = 8*4 + 39; + parmOffset += 1; /* pad to 4 */ + parmCount = 4; + dataOffset = parmOffset + parmCount; + + parmSlot = 1; + outp->oddByte = 1; + /* Total Parameter Count */ + smb_SetSMBParmLong(outp, parmSlot, parmCount); parmSlot += 2; + /* Total Data Count */ + smb_SetSMBParmLong(outp, parmSlot, dataCount); parmSlot += 2; + /* Parameter Count */ + smb_SetSMBParmLong(outp, parmSlot, parmCount); parmSlot += 2; + /* Parameter Offset */ + smb_SetSMBParmLong(outp, parmSlot, parmOffset); parmSlot += 2; + /* Parameter Displacement */ + smb_SetSMBParmLong(outp, parmSlot, 0); parmSlot += 2; + /* Data Count */ + smb_SetSMBParmLong(outp, parmSlot, dataCount); parmSlot += 2; + /* Data Offset */ + smb_SetSMBParmLong(outp, parmSlot, dataOffset); parmSlot += 2; + /* Data Displacement */ + smb_SetSMBParmLong(outp, parmSlot, 0); parmSlot += 2; + smb_SetSMBParmByte(outp, parmSlot, 0); /* Setup Count */ + smb_SetSMBDataLength(outp, 1 + parmCount + dataCount); + + outData = smb_GetSMBData(outp, NULL); + outData++; /* round to get to parmOffset */ + *((ULONG *)outData) = 36; outData += 4; /* length */ + + if (maxData >= 36) { + memcpy(outData, nullSecurityDesc, 36); + outData += 36; + return 0; + } else + return CM_ERROR_BUFFERTOOSMALL; } long smb_ReceiveNTTransact(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) diff --git a/src/WINNT/client_osi/osisleep.h b/src/WINNT/client_osi/osisleep.h index 0fb873d..4bf6175 100644 --- a/src/WINNT/client_osi/osisleep.h +++ b/src/WINNT/client_osi/osisleep.h @@ -35,7 +35,7 @@ typedef struct osi_sleepInfo { unsigned short states; /* states bits */ unsigned short idx; /* sleep hash table we're in, if in hash */ unsigned short waitFor; /* what are we waiting for; used for bulk wakeups */ - unsigned short refCount;/* reference count from FDs */ + unsigned long refCount;/* reference count from FDs */ } osi_sleepInfo_t; /* first guy is the most recently added process */ diff --git a/src/WINNT/client_osi/osistatl.h b/src/WINNT/client_osi/osistatl.h index 0bcfa6d..e2dd99f 100644 --- a/src/WINNT/client_osi/osistatl.h +++ b/src/WINNT/client_osi/osistatl.h @@ -56,8 +56,8 @@ typedef struct osi_qiStat { */ typedef struct osi_mutexStat { osi_queue_t q; /* queue of all mutexes */ - osi_turnstile_t turn; /* the real turnstile */ - short refCount; /* so we can iterate cleanly */ + osi_turnstile_t turn; /* the real turnstile */ + unsigned long refCount; /* so we can iterate cleanly */ short states; /* track # of lock calls and blocks */ @@ -79,7 +79,7 @@ typedef struct osi_mutexStat { typedef struct osi_rwlockStat { osi_queue_t q; /* queue of all mutexes */ osi_turnstile_t turn; /* the real turnstile */ - short refCount; /* so we can iterate cleanly */ + unsigned long refCount; /* so we can iterate cleanly */ short states; /* statistics */