From 9ea40ebfb783de143076cbc5264e40cf67c2cca6 Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Mon, 18 Oct 2004 05:09:25 +0000 Subject: [PATCH] STABLE14-windows-cumulative-20041017 Cummulative update of changes including: * Add code to block the issuance of AFS tokens by aklog.exe or afscreds.exe when the Kerberos 5 principal name contains a dot. * Modify the IsAdmin() function to always treat the local SYSTEM account as an AFS client administrator. Affects fs.exe and afs_config.exe. * Modify the internal handling of Quota Exceeded errors * Upgrade all reference count fields in the Windows cache manager and the osi library to use unsigned long instead of signed short. A similar fix has been applied to the afs rpc (rx) library. * fix the Windows cache manager to prevent it from replacing the rx_connection object associated with the cm_conn_t object on each and every operation if "fs crypt" was set. This explains the dramatic performance difference when crypt is used vs clear. The problem: 'cryptall', a boolean flag indicating whether or not "fs crypt" is set, was being compared to the rx_connection cryptlevel which is either rxkad_clear:0 or rxkad_crypt:2. 1 != 2 and therefore the rx_connection was always destroyed and replaced on each and every operation. Lock the cm_conn_t object around every call to RXAFS_xxxx functions. It is not safe for the cm_conn_t object to not be locked because rx_DestroyConnection might be called from another thread if: - the user's tokens have changed or expired - the crypt mode has changed This fix appears to have also taken care of the problems associated with Overlapped Writes resulting in Delayed Write errors. * fix NSIS installer's AdminGroup.exe to properly create and remove groups when given -create or -remove. The string comparison test was wrong. * fs sysname now accepts a list of sysname values * added a new registry value HKLM\SOFTWARE\OpenAFS\Client "IoctlDebug" DWORD which when set to a non-zero value will cause error message text to be output to stderr from the pioctl() routine. Useful in debugging failures of fs.exe, tokens.exe, etc. * added a test to the power management code to only perform a flush operation if there is at least one network adapter which is not a loopback adapter. * Fix bug in loading of registry value HKLM\SOFTWARE\OpenAFS\Client "EnableKFW". This value will not be read if the key HKCU\SOFTWARE\OpenAFS\Client exists; even if the "EnableKFW" value under that key does not. * provide mechanisms to force the use of krb524d for Kerberos 5 ticket to AFS token conversion. For afslogon.dll and afscreds.exe there is a new registry value "Use524" and for aklog.exe a new command line parameter "-m". * Fix the pattern matching algorithm to properly match patterns ending with a '*'. * smb_ReceiveCoreRename() was factored to produce smb_Rename() which is used by both the original function and the new smb_ReceiveNTRename(). smb_ReceiveNTRename() supports the creation of HardLinks in addition to Renaming. smb_Link() is a new function which creates HardLinks via cm_Link(). cm_Link() is a new vnodeops function which creates links using RXAFS_Link(). smb_ReceiveNTRename() does not support the File Copy and Move Cluster Information operations described in its interface. ReceiveNTRename is under documented in CIFS-TR-1p00_FINAL.pdf. * When opening files via symlinks, we should follow the symlinks until we reach the actual file stat cache entry. The stat cache entry of the file should then be stored in the FID instead of stat scache entry of the symlink. * return bad operation errors for all unimplemented functions even if we do not know the functions exist. * Log bad packets and unknown operation packets to the trace log * Map CM_ERROR_BADOP to STATUS_NOT_SUPPORTED instead of 0xC09820FF * Update list of known CIFS operations to include all those listed in CIFS-TR-1p00_FINAL.pdf. * Modify the handling of HKLM\SOFTWARE\OpenAFS\Client\Submounts to support the REG_EXPAND_SZ type. --- src/WINNT/afsd/afsd_init.c | 36 +- src/WINNT/afsd/afsd_service.c | 77 +- src/WINNT/afsd/afskfw.c | 24 +- src/WINNT/afsd/cm_buf.h | 2 +- src/WINNT/afsd/cm_callback.c | 8 +- src/WINNT/afsd/cm_conn.c | 14 +- src/WINNT/afsd/cm_conn.h | 5 +- src/WINNT/afsd/cm_dcache.c | 15 +- src/WINNT/afsd/cm_diskcache95.h | 2 +- src/WINNT/afsd/cm_freelance.c | 599 +-- src/WINNT/afsd/cm_freelance.h | 4 +- src/WINNT/afsd/cm_ioctl.c | 32 +- src/WINNT/afsd/cm_scache.h | 2 +- src/WINNT/afsd/cm_server.c | 7 +- src/WINNT/afsd/cm_server.h | 4 +- src/WINNT/afsd/cm_user.h | 2 +- src/WINNT/afsd/cm_vnodeops.c | 110 +- src/WINNT/afsd/cm_vnodeops.h | 2 +- src/WINNT/afsd/cm_volume.h | 2 +- src/WINNT/afsd/ctokens.c | 3 +- src/WINNT/afsd/fs.c | 85 +- src/WINNT/afsd/smb.c | 7356 +++++++++++++------------- src/WINNT/afsd/smb.h | 16 +- src/WINNT/afsd/smb3.c | 3749 ++++++------- src/WINNT/aklog/aklog.c | 16 +- src/WINNT/client_config/drivemap.cpp | 2 +- src/WINNT/client_config/isadmin.cpp | 85 +- src/WINNT/client_osi/osisleep.h | 2 +- src/WINNT/client_osi/osistatl.h | 6 +- src/WINNT/pthread/pthread.c | 20 +- 30 files changed, 6243 insertions(+), 6044 deletions(-) diff --git a/src/WINNT/afsd/afsd_init.c b/src/WINNT/afsd/afsd_init.c index 92e561703a..a11118b945 100644 --- a/src/WINNT/afsd/afsd_init.c +++ b/src/WINNT/afsd/afsd_init.c @@ -373,7 +373,7 @@ int afsd_InitCM(char **reasonP) static struct rx_securityClass *nullServerSecurityClassp; struct hostent *thp; char *msgBuf; - char buf[200]; + char buf[1024]; HKEY parmKey; DWORD dummyLen; DWORD regType; @@ -645,15 +645,37 @@ int afsd_InitCM(char **reasonP) } cm_sysName = cm_sysNameList[0]; - dummyLen = MAXSYSNAME; - code = RegQueryValueEx(parmKey, "SysName", NULL, NULL, cm_sysName, &dummyLen); - if (code == ERROR_SUCCESS) - afsi_log("Sys name %s", cm_sysName); - else { + dummyLen = sizeof(buf); + code = RegQueryValueEx(parmKey, "SysName", NULL, NULL, buf, &dummyLen); + if (code == ERROR_SUCCESS && buf[0]) { + char * p, *q; + afsi_log("Sys name %s", buf); + + for (p = q = buf; p < cm_sysName + dummyLen; p++) + { + if (*p == '\0' || isspace(*p)) { + memcpy(cm_sysNameList[cm_sysNameCount],q,p-q); + cm_sysNameList[cm_sysNameCount][p-q] = '\0'; + cm_sysNameCount++; + + do { + if (*p == '\0') + goto done_sysname; + + p++; + } while (*p == '\0' || isspace(*p)); + q = p; + p--; + } + } + done_sysname: + StringCbCopyA(cm_sysName, MAXSYSNAME, cm_sysNameList[0]); + } else { + cm_sysNameCount = 1; StringCbCopyA(cm_sysName, MAXSYSNAME, "i386_nt40"); + StringCbCopyA(cm_sysNameList[0], MAXSYSNAME, "i386_nt40"); afsi_log("Default sys name %s", cm_sysName); } - cm_sysNameCount = 1; dummyLen = sizeof(cryptall); code = RegQueryValueEx(parmKey, "SecurityLevel", NULL, NULL, diff --git a/src/WINNT/afsd/afsd_service.c b/src/WINNT/afsd/afsd_service.c index c69da6593f..43fcb783f1 100644 --- a/src/WINNT/afsd/afsd_service.c +++ b/src/WINNT/afsd/afsd_service.c @@ -55,6 +55,8 @@ jmp_buf notifier_jmp; extern int traceOnPanic; extern HANDLE afsi_file; +int powerEventsRegistered = 0; + /* * Notifier function for use by osi_panic */ @@ -271,32 +273,34 @@ afsd_ServiceControlHandlerEx( ** Return any error code to deny request, ** i.e. as if returning BROADCAST_QUERY_DENY */ - switch((int) dwEventType) - { - case PBT_APMQUERYSUSPEND: - case PBT_APMQUERYSTANDBY: + if (powerEventsRegistered) { + switch((int) dwEventType) + { + case PBT_APMQUERYSUSPEND: + case PBT_APMQUERYSTANDBY: #ifdef FLUSH_VOLUME - /* handle event */ - dwRet = afsd_ServiceFlushVolume((DWORD) lpEventData); + /* handle event */ + dwRet = afsd_ServiceFlushVolume((DWORD) lpEventData); #else - dwRet = NO_ERROR; + dwRet = NO_ERROR; #endif - break; + break; - /* allow remaining case PBT_WhatEver */ - case PBT_APMSUSPEND: - case PBT_APMSTANDBY: - case PBT_APMRESUMECRITICAL: - case PBT_APMRESUMESUSPEND: - case PBT_APMRESUMESTANDBY: - case PBT_APMBATTERYLOW: - case PBT_APMPOWERSTATUSCHANGE: - case PBT_APMOEMEVENT: - case PBT_APMRESUMEAUTOMATIC: - default: - dwRet = NO_ERROR; - } + /* allow remaining case PBT_WhatEver */ + case PBT_APMSUSPEND: + case PBT_APMSTANDBY: + case PBT_APMRESUMECRITICAL: + case PBT_APMRESUMESUSPEND: + case PBT_APMRESUMESTANDBY: + case PBT_APMBATTERYLOW: + case PBT_APMPOWERSTATUSCHANGE: + case PBT_APMOEMEVENT: + case PBT_APMRESUMEAUTOMATIC: + default: + dwRet = NO_ERROR; + } + } } } /* end switch(ctrlCode) */ return dwRet; @@ -308,7 +312,7 @@ afsd_ServiceControlHandlerEx( */ /* DEE Could check first if we are run as SYSTEM */ #define MAX_RETRIES 30 -static void MountGlobalDrives() +static void MountGlobalDrives(void) { char szAfsPath[_MAX_PATH]; char szDriveToMapTo[5]; @@ -492,8 +496,30 @@ void afsd_Main(DWORD argc, LPTSTR *argv) } #ifdef REGISTER_POWER_NOTIFICATIONS - /* create thread used to flush cache */ - PowerNotificationThreadCreate(); + { + HKEY hkParm; + DWORD code; + DWORD dummyLen; + int bpower = TRUE; + + /* see if we should handle power notifications */ + code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSConfigKeyName, 0, KEY_QUERY_VALUE, &hkParm); + if (code == ERROR_SUCCESS) { + dummyLen = sizeof(bpower); + code = RegQueryValueEx(hkParm, "FlushOnHibernate", NULL, NULL, + (BYTE *) &bpower, &dummyLen); + + if(code != ERROR_SUCCESS) + bpower = TRUE; + + RegCloseKey(hkParm); + } + /* create thread used to flush cache */ + if (bpower) { + PowerNotificationThreadCreate(); + powerEventsRegistered = 1; + } + } #endif /* allow an exit to be called prior to any initialization */ @@ -609,7 +635,8 @@ void afsd_Main(DWORD argc, LPTSTR *argv) #ifdef REGISTER_POWER_NOTIFICATIONS /* terminate thread used to flush cache */ - PowerNotificationThreadExit(); + if (powerEventsRegistered) + PowerNotificationThreadExit(); #endif /* Remove the ExceptionFilter */ diff --git a/src/WINNT/afsd/afskfw.c b/src/WINNT/afsd/afskfw.c index 823c60cf19..743374a28b 100644 --- a/src/WINNT/afsd/afskfw.c +++ b/src/WINNT/afsd/afskfw.c @@ -927,11 +927,11 @@ KFW_import_windows_lsa(void) princ_realm = krb5_princ_realm(ctx, princ); for ( i=0; ilength; i++ ) { - realm[i] = princ_realm->data[i]; + realm[i] = princ_realm->data[i]; cell[i] = tolower(princ_realm->data[i]); } - cell[i] = '\0'; - realm[i] = '\0'; + cell[i] = '\0'; + realm[i] = '\0'; code = KFW_AFS_klog(ctx, cc, "afs", cell, realm, pLeash_get_default_lifetime(),NULL); if ( IsDebuggerPresent() ) { @@ -2583,10 +2583,10 @@ KFW_AFS_klog( memset(ServiceName, '\0', sizeof(ServiceName)); memset(realm_of_user, '\0', sizeof(realm_of_user)); memset(realm_of_cell, '\0', sizeof(realm_of_cell)); - if (cell && cell[0]) - strcpy(Dmycell, cell); - else - memset(Dmycell, '\0', sizeof(Dmycell)); + if (cell && cell[0]) + strcpy(Dmycell, cell); + else + memset(Dmycell, '\0', sizeof(Dmycell)); // NULL or empty cell returns information on local cell if (rc = KFW_AFS_get_cellconfig(Dmycell, &ak_cellconfig, local_cell)) @@ -2612,13 +2612,21 @@ KFW_AFS_klog( memset((char *)&increds, 0, sizeof(increds)); code = pkrb5_cc_get_principal(ctx, cc, &client_principal); - if (code) { + if (code) { if ( code == KRB5_CC_NOTFOUND && IsDebuggerPresent() ) { OutputDebugString("Principal Not Found for ccache\n"); } goto skip_krb5_init; } + + if ( strchr(krb5_princ_component(ctx,client_principal,0),'.') != NULL ) + { + OutputDebugString("Illegal Principal name contains dot in first component\n"); + rc = KRB5KRB_ERR_GENERIC; + goto cleanup; + } + i = krb5_princ_realm(ctx, client_principal)->length; if (i > REALM_SZ-1) i = REALM_SZ-1; diff --git a/src/WINNT/afsd/cm_buf.h b/src/WINNT/afsd/cm_buf.h index 8826e1d74d..4ca977ad4c 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_callback.c b/src/WINNT/afsd/cm_callback.c index 3f77df26e3..14dac4286f 100644 --- a/src/WINNT/afsd/cm_callback.c +++ b/src/WINNT/afsd/cm_callback.c @@ -808,6 +808,7 @@ long cm_GetCallback(cm_scache_t *scp, struct cm_user *userp, int mustCall; long sflags; cm_fid_t sfid; + struct rx_connection * callp; osi_Log2(afsd_logp, "GetCallback scp %x flags %lX", scp, flags); @@ -871,10 +872,11 @@ long cm_GetCallback(cm_scache_t *scp, struct cm_user *userp, code = cm_Conn(&sfid, userp, reqp, &connp); if (code) continue; - lock_ObtainMutex(&connp->mx); - code = RXAFS_FetchStatus(connp->callp, &tfid, + callp = cm_GetRxConn(connp); + code = RXAFS_FetchStatus(callp, &tfid, &afsStatus, &callback, &volSync); - lock_ReleaseMutex(&connp->mx); + rx_PutConnection(callp); + } while (cm_Analyze(connp, userp, reqp, &sfid, &volSync, NULL, &cbr, code)); code = cm_MapRPCError(code, reqp); diff --git a/src/WINNT/afsd/cm_conn.c b/src/WINNT/afsd/cm_conn.c index b0ac57f533..32e748ad1d 100644 --- a/src/WINNT/afsd/cm_conn.c +++ b/src/WINNT/afsd/cm_conn.c @@ -565,7 +565,7 @@ long cm_ConnByServer(cm_server_t *serverp, cm_user_t *userp, cm_conn_t **connpp) tcp->refCount = 1; lock_ReleaseMutex(&tcp->mx); } else { - if ((tcp->ucgen < ucellp->gen) || + if ((tcp->ucgen < ucellp->gen) || (tcp->cryptlevel != (cryptall ? rxkad_crypt : rxkad_clear))) { lock_ObtainMutex(&tcp->mx); @@ -602,3 +602,15 @@ long cm_Conn(struct cm_fid *fidp, struct cm_user *userp, cm_req_t *reqp, cm_FreeServerList(serverspp); return code; } + +extern struct rx_connection * +cm_GetRxConn(cm_conn_t *connp) +{ + struct rx_connection * rxconn; + lock_ObtainMutex(&connp->mx); + rxconn = connp->callp; + rx_GetConnection(rxconn); + lock_ReleaseMutex(&connp->mx); + return rxconn; +} + diff --git a/src/WINNT/afsd/cm_conn.h b/src/WINNT/afsd/cm_conn.h index 6f2f2e3851..0e9e0234f7 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 */ @@ -83,6 +83,7 @@ typedef struct cm_req { cache managers treat it as "server is down"*/ #include "cm_server.h" +#include "rx.h" extern void cm_InitConn(void); @@ -106,4 +107,6 @@ extern void cm_PutConn(cm_conn_t *connp); extern void cm_GCConnections(cm_server_t *serverp); +extern struct rx_connection * cm_GetRxConn(cm_conn_t *connp); + #endif /* __CM_CONN_H_ENV__ */ diff --git a/src/WINNT/afsd/cm_dcache.c b/src/WINNT/afsd/cm_dcache.c index 40f3cb470b..550fa2278c 100644 --- a/src/WINNT/afsd/cm_dcache.c +++ b/src/WINNT/afsd/cm_dcache.c @@ -129,12 +129,13 @@ long cm_BufWrite(void *vfidp, osi_hyper_t *offsetp, long length, long flags, if (code) continue; + lock_ObtainMutex(&connp->mx); callp = rx_NewCall(connp->callp); + lock_ReleaseMutex(&connp->mx); osi_Log3(afsd_logp, "CALL StoreData vp %x, off 0x%x, size 0x%x", (long) scp, biod.offset.LowPart, nbytes); - lock_ObtainMutex(&connp->mx); code = StartRXAFS_StoreData(callp, &tfid, &inStatus, biod.offset.LowPart, nbytes, truncPos); @@ -174,8 +175,6 @@ long cm_BufWrite(void *vfidp, osi_hyper_t *offsetp, long length, long flags, osi_Log1(afsd_logp, "EndRXAFS_StoreData failed (%lX)",code); } code = rx_EndCall(callp, code); - lock_ReleaseMutex(&connp->mx); - osi_Log0(afsd_logp, "CALL StoreData DONE"); } while (cm_Analyze(connp, userp, reqp, &scp->fid, &volSync, NULL, NULL, code)); @@ -263,9 +262,10 @@ long cm_StoreMini(cm_scache_t *scp, cm_user_t *userp, cm_req_t *reqp) if (code) continue; - callp = rx_NewCall(connp->callp); - lock_ObtainMutex(&connp->mx); + callp = rx_NewCall(connp->callp); + lock_ReleaseMutex(&connp->mx); + code = StartRXAFS_StoreData(callp, &tfid, &inStatus, 0, 0, truncPos); @@ -273,8 +273,6 @@ long cm_StoreMini(cm_scache_t *scp, cm_user_t *userp, cm_req_t *reqp) code = EndRXAFS_StoreData(callp, &outStatus, &volSync); code = rx_EndCall(callp, code); - lock_ReleaseMutex(&connp->mx); - } while (cm_Analyze(connp, userp, reqp, &scp->fid, &volSync, NULL, NULL, code)); code = cm_MapRPCError(code, reqp); @@ -1241,6 +1239,7 @@ long cm_GetBuffer(cm_scache_t *scp, cm_buf_t *bufp, int *cpffp, cm_user_t *up, lock_ObtainMutex(&connp->mx); callp = rx_NewCall(connp->callp); + lock_ReleaseMutex(&connp->mx); osi_Log3(afsd_logp, "CALL FetchData vp %x, off 0x%x, size 0x%x", (long) scp, biod.offset.LowPart, biod.length); @@ -1353,8 +1352,6 @@ long cm_GetBuffer(cm_scache_t *scp, cm_buf_t *bufp, int *cpffp, cm_user_t *up, osi_Log0(afsd_logp, "CALL EndCall returns RXKADUNKNOWNKEY"); osi_Log0(afsd_logp, "CALL FetchData DONE"); - lock_ReleaseMutex(&connp->mx); - } while (cm_Analyze(connp, up, reqp, &scp->fid, &volSync, NULL, NULL, code)); fetchingcompleted: diff --git a/src/WINNT/afsd/cm_diskcache95.h b/src/WINNT/afsd/cm_diskcache95.h index f8721e0f01..fa8c78367b 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_freelance.c b/src/WINNT/afsd/cm_freelance.c index f0caaf3db9..2933c0f50a 100644 --- a/src/WINNT/afsd/cm_freelance.c +++ b/src/WINNT/afsd/cm_freelance.c @@ -30,7 +30,7 @@ cm_localMountPoint_t* cm_localMountPoints; osi_mutex_t cm_Freelance_Lock; int cm_localMountPointChangeFlag = 0; int cm_freelanceEnabled = 0; -afs_uint32 FakeFreelanceModTime = 0x3b49f6e2; +time_t FakeFreelanceModTime = 0x3b49f6e2; void cm_InitFakeRootDir(); @@ -81,23 +81,23 @@ void cm_InitFreelance() { int lpid; #endif - lock_InitializeMutex(&cm_Freelance_Lock, "Freelance Lock"); + lock_InitializeMutex(&cm_Freelance_Lock, "Freelance Lock"); - // yj: first we make a call to cm_initLocalMountPoints - // to read all the local mount points from an ini file - cm_InitLocalMountPoints(); + // yj: first we make a call to cm_initLocalMountPoints + // to read all the local mount points from an ini file + cm_InitLocalMountPoints(); - // then we make a call to InitFakeRootDir to create - // a fake root directory based on the local mount points - cm_InitFakeRootDir(); - // --- end of yj code + // then we make a call to InitFakeRootDir to create + // a fake root directory based on the local mount points + cm_InitFakeRootDir(); + // --- end of yj code #if !defined(DJGPP) /* Start the registry monitor */ phandle = thrd_Create(NULL, 65536, (ThreadFunc) cm_FreelanceChangeNotifier, NULL, 0, &lpid, "cm_FreelanceChangeNotifier"); - osi_assert(phandle != NULL); - thrd_CloseHandle(phandle); + osi_assert(phandle != NULL); + thrd_CloseHandle(phandle); #endif } @@ -105,186 +105,186 @@ void cm_InitFreelance() { /* to be called while holding freelance lock unless during init. */ void cm_InitFakeRootDir() { - int i, t1, t2; - char* currentPos; - int noChunks; + int i, t1, t2; + char* currentPos; + int noChunks; - // allocate space for the fake info - cm_dirHeader_t fakeDirHeader; - cm_dirEntry_t fakeEntry; - cm_pageHeader_t fakePageHeader; + // allocate space for the fake info + cm_dirHeader_t fakeDirHeader; + cm_dirEntry_t fakeEntry; + cm_pageHeader_t fakePageHeader; - // i'm going to calculate how much space is needed for - // this fake root directory. we have these rules: - // 1. there are cm_noLocalMountPoints number of entries - // 2. each page is CM_DIR_PAGESIZE in size - // 3. the first 13 chunks of the first page are used for - // some header stuff - // 4. the first chunk of all subsequent pages are used - // for page header stuff - // 5. a max of CM_DIR_EPP entries are allowed per page - // 6. each entry takes 1 or more chunks, depending on - // the size of the mount point string, as determined - // by cm_NameEntries - // 7. each chunk is CM_DIR_CHUNKSIZE bytes + // i'm going to calculate how much space is needed for + // this fake root directory. we have these rules: + // 1. there are cm_noLocalMountPoints number of entries + // 2. each page is CM_DIR_PAGESIZE in size + // 3. the first 13 chunks of the first page are used for + // some header stuff + // 4. the first chunk of all subsequent pages are used + // for page header stuff + // 5. a max of CM_DIR_EPP entries are allowed per page + // 6. each entry takes 1 or more chunks, depending on + // the size of the mount point string, as determined + // by cm_NameEntries + // 7. each chunk is CM_DIR_CHUNKSIZE bytes - int CPP = CM_DIR_PAGESIZE / CM_DIR_CHUNKSIZE; - int curChunk = 13; // chunks 0 - 12 are used for header stuff - // of the first page in the directory - int curPage = 0; - int curDirEntry = 0; - int curDirEntryInPage = 0; - int sizeOfCurEntry; - int dirSize; + int CPP = CM_DIR_PAGESIZE / CM_DIR_CHUNKSIZE; + int curChunk = 13; // chunks 0 - 12 are used for header stuff + // of the first page in the directory + int curPage = 0; + int curDirEntry = 0; + int curDirEntryInPage = 0; + int sizeOfCurEntry; + int dirSize; - /* Reserve 2 directory chunks for "." and ".." */ - curChunk += 2; + /* Reserve 2 directory chunks for "." and ".." */ + curChunk += 2; - while (curDirEntry!=cm_noLocalMountPoints) { - sizeOfCurEntry = cm_NameEntries((cm_localMountPoints+curDirEntry)->namep, 0); - if ((curChunk + sizeOfCurEntry >= CPP) || - (curDirEntryInPage + 1 >= CM_DIR_EPP)) { - curPage++; - curDirEntryInPage = 0; - curChunk = 1; - } - curChunk += sizeOfCurEntry; - curDirEntry++; - curDirEntryInPage++; - } + while (curDirEntry!=cm_noLocalMountPoints) { + sizeOfCurEntry = cm_NameEntries((cm_localMountPoints+curDirEntry)->namep, 0); + if ((curChunk + sizeOfCurEntry >= CPP) || + (curDirEntryInPage + 1 >= CM_DIR_EPP)) { + curPage++; + curDirEntryInPage = 0; + curChunk = 1; + } + curChunk += sizeOfCurEntry; + curDirEntry++; + curDirEntryInPage++; + } - dirSize = (curPage+1) * CM_DIR_PAGESIZE; - cm_FakeRootDir = malloc(dirSize); - cm_fakeDirSize = dirSize; + dirSize = (curPage+1) * CM_DIR_PAGESIZE; + cm_FakeRootDir = malloc(dirSize); + cm_fakeDirSize = dirSize; - // yj: when we get here, we've figured out how much memory we need and - // allocated the appropriate space for it. we now prceed to fill - // it up with entries. - curPage = 0; - curDirEntry = 0; - curDirEntryInPage = 0; - curChunk = 0; - - // fields in the directory entry that are unused. - fakeEntry.flag = 1; - fakeEntry.length = 0; - fakeEntry.next = 0; - fakeEntry.fid.unique = htonl(1); + // yj: when we get here, we've figured out how much memory we need and + // allocated the appropriate space for it. we now prceed to fill + // it up with entries. + curPage = 0; + curDirEntry = 0; + curDirEntryInPage = 0; + curChunk = 0; - // the first page is special, it uses fakeDirHeader instead of fakePageHeader - // we fill up the page with dirEntries that belong there and we make changes - // to the fakeDirHeader.header.freeBitmap along the way. Then when we're done - // filling up the dirEntries in this page, we copy the fakeDirHeader into - // the top of the page. + // fields in the directory entry that are unused. + fakeEntry.flag = 1; + fakeEntry.length = 0; + fakeEntry.next = 0; + fakeEntry.fid.unique = htonl(1); - // init the freeBitmap array - for (i=0; i<8; i++) - fakeDirHeader.header.freeBitmap[i]=0; + // the first page is special, it uses fakeDirHeader instead of fakePageHeader + // we fill up the page with dirEntries that belong there and we make changes + // to the fakeDirHeader.header.freeBitmap along the way. Then when we're done + // filling up the dirEntries in this page, we copy the fakeDirHeader into + // the top of the page. - fakeDirHeader.header.freeBitmap[0] = 0xff; - fakeDirHeader.header.freeBitmap[1] = 0x7f; - + // init the freeBitmap array + for (i=0; i<8; i++) + fakeDirHeader.header.freeBitmap[i]=0; - // we start counting at 13 because the 0th to 12th chunks are used for header - curChunk = 13; + fakeDirHeader.header.freeBitmap[0] = 0xff; + fakeDirHeader.header.freeBitmap[1] = 0x7f; - // stick the first 2 entries "." and ".." in - fakeEntry.fid.unique = htonl(1); - fakeEntry.fid.vnode = htonl(1); - strcpy(fakeEntry.name, "."); - currentPos = cm_FakeRootDir + curPage * CM_DIR_PAGESIZE + curChunk * CM_DIR_CHUNKSIZE; - memcpy(currentPos, &fakeEntry, CM_DIR_CHUNKSIZE); - curChunk++; curDirEntryInPage++; - strcpy(fakeEntry.name, ".."); - currentPos = cm_FakeRootDir + curPage * CM_DIR_PAGESIZE + curChunk * CM_DIR_CHUNKSIZE; - memcpy(currentPos, &fakeEntry, CM_DIR_CHUNKSIZE); - curChunk++; curDirEntryInPage++; - // keep putting stuff into page 0 if - // 1. we're not done with all entries - // 2. we have less than CM_DIR_EPP entries in page 0 - // 3. we're not out of chunks in page 0 + // we start counting at 13 because the 0th to 12th chunks are used for header + curChunk = 13; - while( (curDirEntry!=cm_noLocalMountPoints) && - (curDirEntryInPage < CM_DIR_EPP) && - (curChunk + cm_NameEntries((cm_localMountPoints+curDirEntry)->namep, 0) <= CPP)) - { + // stick the first 2 entries "." and ".." in + fakeEntry.fid.unique = htonl(1); + fakeEntry.fid.vnode = htonl(1); + strcpy(fakeEntry.name, "."); + currentPos = cm_FakeRootDir + curPage * CM_DIR_PAGESIZE + curChunk * CM_DIR_CHUNKSIZE; + memcpy(currentPos, &fakeEntry, CM_DIR_CHUNKSIZE); + curChunk++; curDirEntryInPage++; + strcpy(fakeEntry.name, ".."); + currentPos = cm_FakeRootDir + curPage * CM_DIR_PAGESIZE + curChunk * CM_DIR_CHUNKSIZE; + memcpy(currentPos, &fakeEntry, CM_DIR_CHUNKSIZE); + curChunk++; curDirEntryInPage++; - noChunks = cm_NameEntries((cm_localMountPoints+curDirEntry)->namep, 0); - fakeEntry.fid.vnode = htonl(curDirEntry + 2); - currentPos = cm_FakeRootDir + curPage * CM_DIR_PAGESIZE + curChunk * CM_DIR_CHUNKSIZE; + // keep putting stuff into page 0 if + // 1. we're not done with all entries + // 2. we have less than CM_DIR_EPP entries in page 0 + // 3. we're not out of chunks in page 0 - memcpy(currentPos, &fakeEntry, CM_DIR_CHUNKSIZE); - strcpy(currentPos + 12, (cm_localMountPoints+curDirEntry)->namep); - curDirEntry++; - curDirEntryInPage++; - for (i=0; inamep, 0) <= CPP)) + { - // when we get here, we're done with filling in the entries for page 0 - // copy in the header info + noChunks = cm_NameEntries((cm_localMountPoints+curDirEntry)->namep, 0); + fakeEntry.fid.vnode = htonl(curDirEntry + 2); + currentPos = cm_FakeRootDir + curPage * CM_DIR_PAGESIZE + curChunk * CM_DIR_CHUNKSIZE; - memcpy(cm_FakeRootDir, &fakeDirHeader, 13 * CM_DIR_CHUNKSIZE); + memcpy(currentPos, &fakeEntry, CM_DIR_CHUNKSIZE); + strcpy(currentPos + 12, (cm_localMountPoints+curDirEntry)->namep); + curDirEntry++; + curDirEntryInPage++; + for (i=0; inamep, 0) <= CPP)) - { - // add an entry to this page + memcpy(cm_FakeRootDir, &fakeDirHeader, 13 * CM_DIR_CHUNKSIZE); - noChunks = cm_NameEntries((cm_localMountPoints+curDirEntry)->namep, 0); - fakeEntry.fid.vnode=htonl(curDirEntry+2); - currentPos = cm_FakeRootDir + curPage * CM_DIR_PAGESIZE + curChunk * CM_DIR_CHUNKSIZE; - memcpy(currentPos, &fakeEntry, CM_DIR_CHUNKSIZE); - strcpy(currentPos + 12, (cm_localMountPoints+curDirEntry)->namep); - curDirEntry++; - curDirEntryInPage++; - for (i=0; inamep, 0) <= CPP)) + { + // add an entry to this page + + noChunks = cm_NameEntries((cm_localMountPoints+curDirEntry)->namep, 0); + fakeEntry.fid.vnode=htonl(curDirEntry+2); + currentPos = cm_FakeRootDir + curPage * CM_DIR_PAGESIZE + curChunk * CM_DIR_CHUNKSIZE; + memcpy(currentPos, &fakeEntry, CM_DIR_CHUNKSIZE); + strcpy(currentPos + 12, (cm_localMountPoints+curDirEntry)->namep); + curDirEntry++; + curDirEntryInPage++; + for (i=0; icell = AFS_FAKE_ROOT_CELL_ID; /* root cell */ - fidp->volume = AFS_FAKE_ROOT_VOL_ID; /* root.afs ? */ - fidp->vnode = 0x1; - fidp->unique = 0x1; - return 0; + fidp->cell = AFS_FAKE_ROOT_CELL_ID; /* root cell */ + fidp->volume = AFS_FAKE_ROOT_VOL_ID; /* root.afs ? */ + fidp->vnode = 0x1; + fidp->unique = 0x1; + return 0; } /* called directly from ioctl */ @@ -307,83 +307,80 @@ int cm_clearLocalMountPointChange() { } int cm_reInitLocalMountPoints() { - cm_fid_t aFid; - int i, hash; - cm_scache_t *scp, **lscpp, *tscp; + cm_fid_t aFid; + int i, hash; + cm_scache_t *scp, **lscpp, *tscp; - osi_Log0(afsd_logp,"----- freelance reinitialization starts ----- "); + osi_Log0(afsd_logp,"----- freelance reinitialization starts ----- "); - // first we invalidate all the SCPs that were created - // for the local mount points + // first we invalidate all the SCPs that were created + // for the local mount points - osi_Log0(afsd_logp,"Invalidating local mount point scp... "); + osi_Log0(afsd_logp,"Invalidating local mount point scp... "); - aFid.cell = AFS_FAKE_ROOT_CELL_ID; - aFid.volume=AFS_FAKE_ROOT_VOL_ID; - aFid.unique=0x1; - aFid.vnode=0x2; + aFid.cell = AFS_FAKE_ROOT_CELL_ID; + aFid.volume=AFS_FAKE_ROOT_VOL_ID; + aFid.unique=0x1; + aFid.vnode=0x2; - lock_ObtainWrite(&cm_scacheLock); - lock_ObtainMutex(&cm_Freelance_Lock); /* always scache then freelance lock */ - for (i=0; inextp) { - if (scp->fid.volume == aFid.volume && - scp->fid.vnode == aFid.vnode && - scp->fid.unique == aFid.unique - ) { + lock_ObtainWrite(&cm_scacheLock); + lock_ObtainMutex(&cm_Freelance_Lock); /* always scache then freelance lock */ + for (i=0; inextp) { + if (scp->fid.volume == aFid.volume && + scp->fid.vnode == aFid.vnode && + scp->fid.unique == aFid.unique + ) { - // mark the scp to be reused - lock_ReleaseWrite(&cm_scacheLock); - lock_ObtainMutex(&scp->mx); - cm_DiscardSCache(scp); - lock_ReleaseMutex(&scp->mx); - cm_CallbackNotifyChange(scp); - lock_ObtainWrite(&cm_scacheLock); - scp->refCount--; + // mark the scp to be reused + lock_ReleaseWrite(&cm_scacheLock); + lock_ObtainMutex(&scp->mx); + cm_DiscardSCache(scp); + lock_ReleaseMutex(&scp->mx); + cm_CallbackNotifyChange(scp); + lock_ObtainWrite(&cm_scacheLock); + scp->refCount--; - // take the scp out of the hash - lscpp = &cm_hashTablep[hash]; - for (tscp=*lscpp; tscp; lscpp = &tscp->nextp, tscp = *lscpp) { - if (tscp == scp) break; - } - *lscpp = scp->nextp; - scp->flags &= ~CM_SCACHEFLAG_INHASH; + // take the scp out of the hash + lscpp = &cm_hashTablep[hash]; + for (tscp=*lscpp; tscp; lscpp = &tscp->nextp, tscp = *lscpp) { + if (tscp == scp) break; + } + *lscpp = scp->nextp; + scp->flags &= ~CM_SCACHEFLAG_INHASH; + } + } + aFid.vnode = aFid.vnode + 1; + } + lock_ReleaseWrite(&cm_scacheLock); + osi_Log0(afsd_logp,"\tall old scp cleared!"); + // we must free the memory that was allocated in the prev + // cm_InitLocalMountPoints call + osi_Log0(afsd_logp,"Removing old localmountpoints... "); + free(cm_localMountPoints); + osi_Log0(afsd_logp,"\tall old localmountpoints cleared!"); - } - } - aFid.vnode = aFid.vnode + 1; - } - lock_ReleaseWrite(&cm_scacheLock); - osi_Log0(afsd_logp,"\tall old scp cleared!"); + // now re-init the localmountpoints + osi_Log0(afsd_logp,"Creating new localmountpoints... "); + cm_InitLocalMountPoints(); + osi_Log0(afsd_logp,"\tcreated new set of localmountpoints!"); - // we must free the memory that was allocated in the prev - // cm_InitLocalMountPoints call - osi_Log0(afsd_logp,"Removing old localmountpoints... "); - free(cm_localMountPoints); - osi_Log0(afsd_logp,"\tall old localmountpoints cleared!"); + // now we have to free the memory allocated in cm_initfakerootdir + osi_Log0(afsd_logp,"Removing old fakedir... "); + free(cm_FakeRootDir); + osi_Log0(afsd_logp,"\t\told fakedir removed!"); - // now re-init the localmountpoints - osi_Log0(afsd_logp,"Creating new localmountpoints... "); - cm_InitLocalMountPoints(); - osi_Log0(afsd_logp,"\tcreated new set of localmountpoints!"); - - - // now we have to free the memory allocated in cm_initfakerootdir - osi_Log0(afsd_logp,"Removing old fakedir... "); - free(cm_FakeRootDir); - osi_Log0(afsd_logp,"\t\told fakedir removed!"); + // then we re-create that dir + osi_Log0(afsd_logp,"Creating new fakedir... "); + cm_InitFakeRootDir(); + osi_Log0(afsd_logp,"\t\tcreated new fakedir!"); - // then we re-create that dir - osi_Log0(afsd_logp,"Creating new fakedir... "); - cm_InitFakeRootDir(); - osi_Log0(afsd_logp,"\t\tcreated new fakedir!"); + lock_ReleaseMutex(&cm_Freelance_Lock); - lock_ReleaseMutex(&cm_Freelance_Lock); - - osi_Log0(afsd_logp,"----- freelance reinit complete -----"); - return 0; + osi_Log0(afsd_logp,"----- freelance reinit complete -----"); + return 0; } @@ -392,12 +389,12 @@ int cm_reInitLocalMountPoints() { // process for the freelance client. /* to be called while holding freelance lock unless during init. */ long cm_InitLocalMountPoints() { - FILE *fp; + FILE *fp; int i; - char line[512]; - char* t; - cm_localMountPoint_t* aLocalMountPoint; - char hdir[120]; + char line[512]; + char*t, *t2; + cm_localMountPoint_t* aLocalMountPoint; + char hdir[120]; long code; char rootCellName[256]; #if !defined(DJGPP) @@ -465,6 +462,11 @@ long cm_InitLocalMountPoints() { RegEnumValue( hkFreelance, dwIndex, szValueName, &dwValueSize, NULL, &dwType, line, &dwSize); + /* find the trailing dot; null terminate after it */ + t2 = strrchr(line, '.'); + if (t2) + *(t2+1) = '\0'; + // line is not empty, so let's parse it t = strchr(line, '#'); if (!t) @@ -477,12 +479,13 @@ long cm_InitLocalMountPoints() { continue; } aLocalMountPoint->namep=malloc(t-line+1); - memcpy(aLocalMountPoint->namep, line, t-line); - *(aLocalMountPoint->namep + (t-line)) = 0; + strncpy(aLocalMountPoint->namep, line, t-line); + aLocalMountPoint->namep[t-line] = '\0'; - aLocalMountPoint->mountPointStringp=malloc(strlen(line) - (t-line) + 1); - memcpy(aLocalMountPoint->mountPointStringp, t, strlen(line)-(t-line)-2); - *(aLocalMountPoint->mountPointStringp + (strlen(line)-(t-line)-2)) = 0; + /* copy the mount point string without the trailing dot */ + aLocalMountPoint->mountPointStringp=malloc(strlen(t)); + strncpy(aLocalMountPoint->mountPointStringp, t, strlen(t)-1); + aLocalMountPoint->mountPointStringp[strlen(t)-1] = '\0'; osi_Log2(afsd_logp,"found mount point: name %s, string %s", osi_LogSaveString(afsd_logp,aLocalMountPoint->namep), @@ -499,13 +502,13 @@ long cm_InitLocalMountPoints() { /* What follows is the old code to read freelance mount points * out of a text file modified to copy the data into the registry */ - cm_GetConfigDir(hdir); - strcat(hdir, AFS_FREELANCE_INI); - // open the ini file for reading - fp = fopen(hdir, "r"); + cm_GetConfigDir(hdir); + strcat(hdir, AFS_FREELANCE_INI); + // open the ini file for reading + fp = fopen(hdir, "r"); - // if we fail to open the file, create an empty one - if (!fp) { + // if we fail to open the file, create an empty one + if (!fp) { fp = fopen(hdir, "w"); code = cm_GetRootCellName(rootCellName); if (code == 0) { @@ -519,10 +522,10 @@ long cm_InitLocalMountPoints() { fclose(fp); return 0; /* success */ } - } + } - // we successfully opened the file - osi_Log0(afsd_logp,"opened afs_freelance.ini"); + // we successfully opened the file + osi_Log0(afsd_logp,"opened afs_freelance.ini"); #if !defined(DJGPP) RegCreateKeyEx( HKEY_LOCAL_MACHINE, @@ -537,41 +540,41 @@ long cm_InitLocalMountPoints() { dwIndex = 0; #endif - // now we read the first line to see how many entries - // there are - fgets(line, sizeof(line), fp); + // now we read the first line to see how many entries + // there are + fgets(line, sizeof(line), fp); - // if the line is empty at any point when we're reading - // we're screwed. report error and return. - if (*line==0) { - afsi_log("error occurred while reading afs_freelance.ini"); - fprintf(stderr, "error occurred while reading afs_freelance.ini"); - return -1; - } + // if the line is empty at any point when we're reading + // we're screwed. report error and return. + if (*line==0) { + afsi_log("error occurred while reading afs_freelance.ini"); + fprintf(stderr, "error occurred while reading afs_freelance.ini"); + return -1; + } - // get the number of entries there are from the first line - // that we read - cm_noLocalMountPoints = atoi(line); + // get the number of entries there are from the first line + // that we read + cm_noLocalMountPoints = atoi(line); - // create space to store the local mount points - cm_localMountPoints = malloc(sizeof(cm_localMountPoint_t) * cm_noLocalMountPoints); - aLocalMountPoint = cm_localMountPoints; - - // now we read n lines and parse them into local mount points - // where n is the number of local mount points there are, as - // determined above. - // Each line in the ini file represents 1 local mount point and - // is in the format xxx#yyy:zzz, where xxx is the directory - // entry name, yyy is the cell name and zzz is the volume name. - // #yyy:zzz together make up the mount point. - for (i=0; inamep=malloc(t-line+1); - memcpy(aLocalMountPoint->namep, line, t-line); - *(aLocalMountPoint->namep + (t-line)) = 0; - + // make sure that there is a '#' or '%' separator in the line + if (!t) { + afsi_log("error occurred while parsing entry in %s: no # or %% separator in line %d", AFS_FREELANCE_INI, i); + fprintf(stderr, "error occurred while parsing entry in afs_freelance.ini: no # or %% separator in line %d", i); + return -1; + } + aLocalMountPoint->namep=malloc(t-line+1); + memcpy(aLocalMountPoint->namep, line, t-line); + *(aLocalMountPoint->namep + (t-line)) = 0; + aLocalMountPoint->mountPointStringp=malloc(strlen(line) - (t-line) + 1); - memcpy(aLocalMountPoint->mountPointStringp, t, strlen(line)-(t-line)-2); - *(aLocalMountPoint->mountPointStringp + (strlen(line)-(t-line)-2)) = 0; - + memcpy(aLocalMountPoint->mountPointStringp, t, strlen(line)-(t-line)-2); + *(aLocalMountPoint->mountPointStringp + (strlen(line)-(t-line)-2)) = 0; + osi_Log2(afsd_logp,"found mount point: name %s, string %s", aLocalMountPoint->namep, aLocalMountPoint->mountPointStringp); aLocalMountPoint++; - } - fclose(fp); + } + fclose(fp); #if !defined(DJGPP) if ( hkFreelance ) { RegCloseKey(hkFreelance); DeleteFile(hdir); } #endif - return 0; + return 0; } int cm_getNoLocalMountPoints() { - return cm_noLocalMountPoints; + return cm_noLocalMountPoints; } cm_localMountPoint_t* cm_getLocalMountPoint(int vnode) { - return 0; + return 0; } long cm_FreelanceAddMount(char *filename, char *cellname, char *volume, int rw, cm_fid_t *fidp) diff --git a/src/WINNT/afsd/cm_freelance.h b/src/WINNT/afsd/cm_freelance.h index b7d90e3e7e..3d02b9e092 100644 --- a/src/WINNT/afsd/cm_freelance.h +++ b/src/WINNT/afsd/cm_freelance.h @@ -17,11 +17,11 @@ extern void cm_InitFreelance(); extern long cm_FreelanceRemoveMount(char *toremove); extern long cm_FreelanceAddMount(char *filename, char *cellname, char *volume, int rw, cm_fid_t *fidp); extern int cm_clearLocalMountPointChange(); - +extern int cm_FakeRootFid(cm_fid_t *fidp); #define AFS_FREELANCE_INI "afs_freelance.ini" #define AFS_FAKE_ROOT_CELL_ID 0xFFFFFFFF #define AFS_FAKE_ROOT_VOL_ID 0xFFFFFFFF -extern afs_uint32 FakeFreelanceModTime; +extern time_t FakeFreelanceModTime; #endif // _CM_FREELANCE_H diff --git a/src/WINNT/afsd/cm_ioctl.c b/src/WINNT/afsd/cm_ioctl.c index 2922d17d0b..13bd7a48f6 100644 --- a/src/WINNT/afsd/cm_ioctl.c +++ b/src/WINNT/afsd/cm_ioctl.c @@ -411,6 +411,7 @@ long cm_IoctlGetACL(smb_ioctl_t *ioctlp, cm_user_t *userp) AFSFid fid; int tlen; cm_req_t req; + struct rx_connection * callp; cm_InitReq(&req); @@ -427,9 +428,10 @@ long cm_IoctlGetACL(smb_ioctl_t *ioctlp, cm_user_t *userp) code = cm_Conn(&scp->fid, userp, &req, &connp); if (code) continue; - lock_ObtainMutex(&connp->mx); - code = RXAFS_FetchACL(connp->callp, &fid, &acl, &fileStatus, &volSync); - lock_ReleaseMutex(&connp->mx); + callp = cm_GetRxConn(connp); + code = RXAFS_FetchACL(callp, &fid, &acl, &fileStatus, &volSync); + rx_PutConnection(callp); + } while (cm_Analyze(connp, userp, &req, &scp->fid, &volSync, NULL, NULL, code)); code = cm_MapRPCError(code, &req); cm_ReleaseSCache(scp); @@ -478,6 +480,7 @@ long cm_IoctlSetACL(struct smb_ioctl *ioctlp, struct cm_user *userp) long code; AFSFid fid; cm_req_t req; + struct rx_connection * callp; cm_InitReq(&req); @@ -494,9 +497,10 @@ long cm_IoctlSetACL(struct smb_ioctl *ioctlp, struct cm_user *userp) code = cm_Conn(&scp->fid, userp, &req, &connp); if (code) continue; - lock_ObtainMutex(&connp->mx); - code = RXAFS_StoreACL(connp->callp, &fid, &acl, &fileStatus, &volSync); - lock_ReleaseMutex(&connp->mx); + callp = cm_GetRxConn(connp); + code = RXAFS_StoreACL(callp, &fid, &acl, &fileStatus, &volSync); + rx_PutConnection(callp); + } while (cm_Analyze(connp, userp, &req, &scp->fid, &volSync, NULL, NULL, code)); code = cm_MapRPCError(code, &req); @@ -578,6 +582,7 @@ long cm_IoctlSetVolumeStatus(struct smb_ioctl *ioctlp, struct cm_user *userp) char *cp; cm_cell_t *cellp; cm_req_t req; + struct rx_connection * callp; cm_InitReq(&req); @@ -621,10 +626,11 @@ long cm_IoctlSetVolumeStatus(struct smb_ioctl *ioctlp, struct cm_user *userp) code = cm_Conn(&scp->fid, userp, &req, &tcp); if (code) continue; - lock_ObtainMutex(&tcp->mx); - code = RXAFS_SetVolumeStatus(tcp->callp, scp->fid.volume, + callp = cm_GetRxConn(tcp); + code = RXAFS_SetVolumeStatus(callp, scp->fid.volume, &storeStat, volName, offLineMsg, motd); - lock_ReleaseMutex(&tcp->mx); + rx_PutConnection(callp); + } while (cm_Analyze(tcp, userp, &req, &scp->fid, NULL, NULL, NULL, code)); code = cm_MapRPCError(code, &req); @@ -668,6 +674,7 @@ long cm_IoctlGetVolumeStatus(struct smb_ioctl *ioctlp, struct cm_user *userp) char *OfflineMsg; char *MOTD; cm_req_t req; + struct rx_connection * callp; cm_InitReq(&req); @@ -681,10 +688,11 @@ long cm_IoctlGetVolumeStatus(struct smb_ioctl *ioctlp, struct cm_user *userp) code = cm_Conn(&scp->fid, userp, &req, &tcp); if (code) continue; - lock_ObtainMutex(&tcp->mx); - code = RXAFS_GetVolumeStatus(tcp->callp, scp->fid.volume, + callp = cm_GetRxConn(tcp); + code = RXAFS_GetVolumeStatus(callp, scp->fid.volume, &volStat, &Name, &OfflineMsg, &MOTD); - lock_ReleaseMutex(&tcp->mx); + rx_PutConnection(callp); + } while (cm_Analyze(tcp, userp, &req, &scp->fid, NULL, NULL, NULL, code)); code = cm_MapRPCError(code, &req); diff --git a/src/WINNT/afsd/cm_scache.h b/src/WINNT/afsd/cm_scache.h index aeeeeeeb4b..18b3450332 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.c b/src/WINNT/afsd/cm_server.c index c6af94d27e..fa2eb85601 100644 --- a/src/WINNT/afsd/cm_server.c +++ b/src/WINNT/afsd/cm_server.c @@ -50,6 +50,7 @@ void cm_CheckServers(long flags, cm_cell_t *cellp) long now; int wasDown; cm_conn_t *connp; + struct rx_connection * callp; lock_ObtainWrite(&cm_serverLock); for (tsp = cm_allServersp; tsp; tsp = tsp->allNextp) { @@ -95,9 +96,9 @@ void cm_CheckServers(long flags, cm_cell_t *cellp) } else { /* file server */ - lock_ObtainMutex(&connp->mx); - code = RXAFS_GetTime(connp->callp, &secs, &usecs); - lock_ReleaseMutex(&connp->mx); + callp = cm_GetRxConn(connp); + code = RXAFS_GetTime(callp, &secs, &usecs); + rx_PutConnection(callp); } if (wasDown) rx_SetConnDeadTime(connp->callp, ConnDeadtimeout); diff --git a/src/WINNT/afsd/cm_server.h b/src/WINNT/afsd/cm_server.h index fc766c3169..0ea6e6787f 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 3a160d7b0b..1e586498b8 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_vnodeops.c b/src/WINNT/afsd/cm_vnodeops.c index bd011791a7..17511447fa 100644 --- a/src/WINNT/afsd/cm_vnodeops.c +++ b/src/WINNT/afsd/cm_vnodeops.c @@ -1128,6 +1128,7 @@ long cm_Unlink(cm_scache_t *dscp, char *namep, cm_user_t *userp, cm_req_t *reqp) int sflags; AFSFetchStatus newDirStatus; AFSVolSync volSync; + struct rx_connection * callp; #ifdef AFS_FREELANCE_CLIENT if (cm_freelanceEnabled && dscp == cm_rootSCachep) { @@ -1154,10 +1155,11 @@ long cm_Unlink(cm_scache_t *dscp, char *namep, cm_user_t *userp, cm_req_t *reqp) if (code) continue; - lock_ObtainMutex(&connp->mx); - code = RXAFS_RemoveFile(connp->callp, &afsFid, namep, + callp = cm_GetRxConn(connp); + code = RXAFS_RemoveFile(callp, &afsFid, namep, &newDirStatus, &volSync); - lock_ReleaseMutex(&connp->mx); + rx_PutConnection(callp); + } while (cm_Analyze(connp, userp, reqp, &dscp->fid, &volSync, NULL, NULL, code)); code = cm_MapRPCError(code, reqp); @@ -1647,6 +1649,7 @@ void cm_TryBulkStat(cm_scache_t *dscp, osi_hyper_t *offsetp, cm_user_t *userp, long j; cm_scache_t *scp; cm_fid_t tfid; + struct rx_connection * callp; osi_Log1(afsd_logp, "cm_TryBulkStat dir 0x%x", (long) dscp); @@ -1685,10 +1688,11 @@ void cm_TryBulkStat(cm_scache_t *dscp, osi_hyper_t *offsetp, cm_user_t *userp, if (code) continue; - lock_ObtainMutex(&connp->mx); - code = RXAFS_BulkStatus(connp->callp, &fidStruct, + callp = cm_GetRxConn(connp); + code = RXAFS_BulkStatus(callp, &fidStruct, &statStruct, &callbackStruct, &volSync); - lock_ReleaseMutex(&connp->mx); + rx_PutConnection(callp); + } while (cm_Analyze(connp, userp, reqp, &dscp->fid, &volSync, NULL, &cbReq, code)); code = cm_MapRPCError(code, reqp); @@ -1884,6 +1888,7 @@ long cm_SetAttr(cm_scache_t *scp, cm_attr_t *attrp, cm_user_t *userp, cm_conn_t *connp; AFSFid tfid; AFSStoreStatus afsInStatus; + struct rx_connection * callp; /* handle file length setting */ if (attrp->mask & CM_ATTRMASK_LENGTH) @@ -1912,10 +1917,11 @@ long cm_SetAttr(cm_scache_t *scp, cm_attr_t *attrp, cm_user_t *userp, if (code) continue; - lock_ObtainMutex(&connp->mx); - code = RXAFS_StoreStatus(connp->callp, &tfid, + callp = cm_GetRxConn(connp); + code = RXAFS_StoreStatus(callp, &tfid, &afsInStatus, &afsOutStatus, &volSync); - lock_ReleaseMutex(&connp->mx); + rx_PutConnection(callp); + } while (cm_Analyze(connp, userp, reqp, &scp->fid, &volSync, NULL, NULL, code)); code = cm_MapRPCError(code, reqp); @@ -1952,6 +1958,7 @@ long cm_Create(cm_scache_t *dscp, char *namep, long flags, cm_attr_t *attrp, AFSFetchStatus newFileStatus; AFSCallBack newFileCallback; AFSVolSync volSync; + struct rx_connection * callp; /* can't create names with @sys in them; must expand it manually first. * return "invalid request" if they try. @@ -1986,12 +1993,14 @@ long cm_Create(cm_scache_t *dscp, char *namep, long flags, cm_attr_t *attrp, dirAFSFid.Volume = dscp->fid.volume; dirAFSFid.Vnode = dscp->fid.vnode; dirAFSFid.Unique = dscp->fid.unique; - lock_ObtainMutex(&connp->mx); + + callp = cm_GetRxConn(connp); code = RXAFS_CreateFile(connp->callp, &dirAFSFid, namep, &inStatus, &newAFSFid, &newFileStatus, &updatedDirStatus, &newFileCallback, &volSync); - lock_ReleaseMutex(&connp->mx); + rx_PutConnection(callp); + } while (cm_Analyze(connp, userp, reqp, &dscp->fid, &volSync, NULL, &cbReq, code)); code = cm_MapRPCError(code, reqp); @@ -2071,6 +2080,7 @@ long cm_MakeDir(cm_scache_t *dscp, char *namep, long flags, cm_attr_t *attrp, AFSFetchStatus newDirStatus; AFSCallBack newDirCallback; AFSVolSync volSync; + struct rx_connection * callp; /* can't create names with @sys in them; must expand it manually first. * return "invalid request" if they try. @@ -2105,12 +2115,14 @@ long cm_MakeDir(cm_scache_t *dscp, char *namep, long flags, cm_attr_t *attrp, dirAFSFid.Volume = dscp->fid.volume; dirAFSFid.Vnode = dscp->fid.vnode; dirAFSFid.Unique = dscp->fid.unique; - lock_ObtainMutex(&connp->mx); + + callp = cm_GetRxConn(connp); code = RXAFS_MakeDir(connp->callp, &dirAFSFid, namep, &inStatus, &newAFSFid, &newDirStatus, &updatedDirStatus, &newDirCallback, &volSync); - lock_ReleaseMutex(&connp->mx); + rx_PutConnection(callp); + } while (cm_Analyze(connp, userp, reqp, &dscp->fid, &volSync, NULL, &cbReq, code)); code = cm_MapRPCError(code, reqp); @@ -2165,6 +2177,7 @@ long cm_Link(cm_scache_t *dscp, char *namep, cm_scache_t *sscp, long flags, AFSFetchStatus updatedDirStatus; AFSFetchStatus newLinkStatus; AFSVolSync volSync; + struct rx_connection * callp; if (dscp->fid.cell != sscp->fid.cell || dscp->fid.volume != sscp->fid.volume) { @@ -2190,12 +2203,12 @@ long cm_Link(cm_scache_t *dscp, char *namep, cm_scache_t *sscp, long flags, existingAFSFid.Vnode = sscp->fid.vnode; existingAFSFid.Unique = sscp->fid.unique; - lock_ObtainMutex(&connp->mx); - code = RXAFS_Link(connp->callp, &dirAFSFid, namep, &existingAFSFid, + callp = cm_GetRxConn(connp); + code = RXAFS_Link(callp, &dirAFSFid, namep, &existingAFSFid, &newLinkStatus, &updatedDirStatus, &volSync); - lock_ReleaseMutex(&connp->mx); - + rx_PutConnection(callp); osi_Log1(smb_logp," RXAFS_Link returns %d", code); + } while (cm_Analyze(connp, userp, reqp, &dscp->fid, &volSync, NULL, NULL, code)); @@ -2224,6 +2237,7 @@ long cm_SymLink(cm_scache_t *dscp, char *namep, char *contentsp, long flags, AFSFetchStatus updatedDirStatus; AFSFetchStatus newLinkStatus; AFSVolSync volSync; + struct rx_connection * callp; /* before starting the RPC, mark that we're changing the directory data, * so that someone who does a chmod on the dir will wait until our @@ -2247,11 +2261,13 @@ long cm_SymLink(cm_scache_t *dscp, char *namep, char *contentsp, long flags, dirAFSFid.Volume = dscp->fid.volume; dirAFSFid.Vnode = dscp->fid.vnode; dirAFSFid.Unique = dscp->fid.unique; - lock_ObtainMutex(&connp->mx); - code = RXAFS_Symlink(connp->callp, &dirAFSFid, namep, contentsp, + + callp = cm_GetRxConn(connp); + code = RXAFS_Symlink(callp, &dirAFSFid, namep, contentsp, &inStatus, &newAFSFid, &newLinkStatus, &updatedDirStatus, &volSync); - lock_ReleaseMutex(&connp->mx); + rx_PutConnection(callp); + } while (cm_Analyze(connp, userp, reqp, &dscp->fid, &volSync, NULL, NULL, code)); code = cm_MapRPCError(code, reqp); @@ -2298,6 +2314,7 @@ long cm_RemoveDir(cm_scache_t *dscp, char *namep, cm_user_t *userp, int didEnd; AFSFetchStatus updatedDirStatus; AFSVolSync volSync; + struct rx_connection * callp; /* before starting the RPC, mark that we're changing the directory data, * so that someone who does a chmod on the dir will wait until our @@ -2320,10 +2337,12 @@ long cm_RemoveDir(cm_scache_t *dscp, char *namep, cm_user_t *userp, dirAFSFid.Volume = dscp->fid.volume; dirAFSFid.Vnode = dscp->fid.vnode; dirAFSFid.Unique = dscp->fid.unique; - lock_ObtainMutex(&connp->mx); - code = RXAFS_RemoveDir(connp->callp, &dirAFSFid, namep, + + callp = cm_GetRxConn(connp); + code = RXAFS_RemoveDir(callp, &dirAFSFid, namep, &updatedDirStatus, &volSync); - lock_ReleaseMutex(&connp->mx); + rx_PutConnection(callp); + } while (cm_Analyze(connp, userp, reqp, &dscp->fid, &volSync, NULL, NULL, code)); code = cm_MapRPCErrorRmdir(code, reqp); @@ -2370,6 +2389,7 @@ long cm_Rename(cm_scache_t *oldDscp, char *oldNamep, cm_scache_t *newDscp, AFSFetchStatus updatedNewDirStatus; AFSVolSync volSync; int oneDir; + struct rx_connection * callp; /* before starting the RPC, mark that we're changing the directory data, * so that someone who does a chmod on the dir will wait until our call @@ -2461,12 +2481,14 @@ long cm_Rename(cm_scache_t *oldDscp, char *oldNamep, cm_scache_t *newDscp, newDirAFSFid.Volume = newDscp->fid.volume; newDirAFSFid.Vnode = newDscp->fid.vnode; newDirAFSFid.Unique = newDscp->fid.unique; - lock_ObtainMutex(&connp->mx); - code = RXAFS_Rename(connp->callp, &oldDirAFSFid, oldNamep, + + callp = cm_GetRxConn(connp); + code = RXAFS_Rename(callp, &oldDirAFSFid, oldNamep, &newDirAFSFid, newNamep, &updatedOldDirStatus, &updatedNewDirStatus, &volSync); - lock_ReleaseMutex(&connp->mx); + rx_PutConnection(callp); + } while (cm_Analyze(connp, userp, reqp, &oldDscp->fid, &volSync, NULL, NULL, code)); code = cm_MapRPCError(code, reqp); @@ -2508,6 +2530,7 @@ long cm_Lock(cm_scache_t *scp, unsigned char LockType, cm_file_lock_t *fileLock; osi_queue_t *q; int found = 0; + struct rx_connection * callp; /* Look for a conflict. Also, if we are asking for a shared lock, * look for another shared lock, so we don't have to do an RPC. @@ -2538,10 +2561,12 @@ long cm_Lock(cm_scache_t *scp, unsigned char LockType, code = cm_Conn(&scp->fid, userp, reqp, &connp); if (code) break; - lock_ObtainMutex(&connp->mx); - code = RXAFS_SetLock(connp->callp, &tfid, Which, + + callp = cm_GetRxConn(connp); + code = RXAFS_SetLock(callp, &tfid, Which, &volSync); - lock_ReleaseMutex(&connp->mx); + rx_PutConnection(callp); + } while (cm_Analyze(connp, userp, reqp, &scp->fid, &volSync, NULL, NULL, code)); lock_ObtainMutex(&scp->mx); @@ -2581,6 +2606,7 @@ long cm_Unlock(cm_scache_t *scp, unsigned char LockType, int anotherReader = 0; int smallLock = 0; int found = 0; + struct rx_connection * callp; if (LargeIntegerLessThan(LLength, scp->length)) smallLock = 1; @@ -2633,9 +2659,11 @@ long cm_Unlock(cm_scache_t *scp, unsigned char LockType, code = cm_Conn(&scp->fid, userp, reqp, &connp); if (code) break; - lock_ObtainMutex(&connp->mx); - code = RXAFS_ReleaseLock(connp->callp, &tfid, &volSync); - lock_ReleaseMutex(&connp->mx); + + callp = cm_GetRxConn(connp); + code = RXAFS_ReleaseLock(callp, &tfid, &volSync); + rx_PutConnection(callp); + } while (cm_Analyze(connp, userp, reqp, &scp->fid, &volSync, NULL, NULL, code)); code = cm_MapRPCError(code, reqp); @@ -2654,6 +2682,7 @@ void cm_CheckLocks() AFSVolSync volSync; cm_conn_t *connp; long code; + struct rx_connection * callp; cm_InitReq(&req); @@ -2676,10 +2705,12 @@ void cm_CheckLocks() &req, &connp); if (code) break; - lock_ObtainMutex(&connp->mx); - code = RXAFS_ExtendLock(connp->callp, &tfid, + + callp = cm_GetRxConn(connp); + code = RXAFS_ExtendLock(callp, &tfid, &volSync); - lock_ReleaseMutex(&connp->mx); + rx_PutConnection(callp); + } while (cm_Analyze(connp, fileLock->userp, &req, &fileLock->fid, &volSync, NULL, NULL, code)); @@ -2703,6 +2734,7 @@ long cm_RetryLock(cm_file_lock_t *oldFileLock, int vcp_is_dead) osi_queue_t *q; cm_req_t req; int found = 0; + struct rx_connection * callp; if (vcp_is_dead) { code = CM_ERROR_TIMEDOUT; @@ -2746,10 +2778,12 @@ long cm_RetryLock(cm_file_lock_t *oldFileLock, int vcp_is_dead) &req, &connp); if (code) break; - lock_ObtainMutex(&connp->mx); - code = RXAFS_SetLock(connp->callp, &tfid, Which, + + callp = cm_GetRxConn(connp); + code = RXAFS_SetLock(callp, &tfid, Which, &volSync); - lock_ReleaseMutex(&connp->mx); + rx_PutConnection(callp); + } while (cm_Analyze(connp, oldFileLock->userp, &req, &oldFileLock->fid, &volSync, NULL, NULL, code)); diff --git a/src/WINNT/afsd/cm_vnodeops.h b/src/WINNT/afsd/cm_vnodeops.h index 004aa0b0aa..9f2a7a641a 100644 --- a/src/WINNT/afsd/cm_vnodeops.h +++ b/src/WINNT/afsd/cm_vnodeops.h @@ -15,7 +15,7 @@ extern unsigned int cm_mountRootGen; /* parms for attribute setting call */ typedef struct cm_attr { int mask; - unsigned long clientModTime; + time_t clientModTime; osi_hyper_t length; int unixModeBits; long owner; diff --git a/src/WINNT/afsd/cm_volume.h b/src/WINNT/afsd/cm_volume.h index 89547d7f9e..0d017003fc 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/ctokens.c b/src/WINNT/afsd/ctokens.c index 9b357d9ae6..5d74150fdd 100644 --- a/src/WINNT/afsd/ctokens.c +++ b/src/WINNT/afsd/ctokens.c @@ -88,7 +88,8 @@ main(argc, argv) if (tokenExpireTime <= current_time) printf("[>> Expired <<]\n"); else { - expireString = ctime(&tokenExpireTime); + time_t t = tokenExpireTime; + expireString = ctime(&t); expireString += 4; /* Skip day of week */ expireString[12] = '\0'; /* Omit secs & year */ printf("[Expires %s]\n", expireString); diff --git a/src/WINNT/afsd/fs.c b/src/WINNT/afsd/fs.c index fce9129868..1f3630eec0 100644 --- a/src/WINNT/afsd/fs.c +++ b/src/WINNT/afsd/fs.c @@ -609,8 +609,6 @@ BOOL IsAdmin (void) return FALSE; } - fTested = TRUE; - dwSize = 0; dwSize2 = 0; @@ -645,39 +643,76 @@ BOOL IsAdmin (void) if (OpenProcessToken (GetCurrentProcess(), TOKEN_QUERY, &hToken)) { - /* We'll have to allocate a chunk of memory to store the list of - * groups to which this user belongs; find out how much memory - * we'll need. - */ - DWORD dwSize = 0; - PTOKEN_GROUPS pGroups; - - GetTokenInformation (hToken, TokenGroups, NULL, dwSize, &dwSize); - - pGroups = (PTOKEN_GROUPS)malloc(dwSize); - - /* Allocate that buffer, and read in the list of groups. */ - if (GetTokenInformation (hToken, TokenGroups, pGroups, dwSize, &dwSize)) - { - /* Look through the list of group SIDs and see if any of them - * matches the AFS Client Admin group SID. + + if (!CheckTokenMembership(hToken, psidAdmin, &fAdmin)) { + /* We'll have to allocate a chunk of memory to store the list of + * groups to which this user belongs; find out how much memory + * we'll need. */ - size_t iGroup = 0; - for (; (!fAdmin) && (iGroup < pGroups->GroupCount); ++iGroup) + DWORD dwSize = 0; + PTOKEN_GROUPS pGroups; + + GetTokenInformation (hToken, TokenGroups, NULL, dwSize, &dwSize); + + pGroups = (PTOKEN_GROUPS)malloc(dwSize); + + /* Allocate that buffer, and read in the list of groups. */ + if (GetTokenInformation (hToken, TokenGroups, pGroups, dwSize, &dwSize)) { - if (EqualSid (psidAdmin, pGroups->Groups[ iGroup ].Sid)) { - fAdmin = TRUE; + /* Look through the list of group SIDs and see if any of them + * matches the AFS Client Admin group SID. + */ + size_t iGroup = 0; + for (; (!fAdmin) && (iGroup < pGroups->GroupCount); ++iGroup) + { + if (EqualSid (psidAdmin, pGroups->Groups[ iGroup ].Sid)) { + fAdmin = TRUE; + } } } + + if (pGroups) + free(pGroups); } - if (pGroups) - free(pGroups); + /* if do not have permission because we were not explicitly listed + * in the Admin Client Group let's see if we are the SYSTEM account + */ + if (!fAdmin) { + PTOKEN_USER pTokenUser; + SID_IDENTIFIER_AUTHORITY SIDAuth = SECURITY_NT_AUTHORITY; + PSID pSidLocalSystem = 0; + DWORD gle; + + GetTokenInformation(hToken, TokenUser, NULL, 0, &dwSize); + + pTokenUser = (PTOKEN_USER)malloc(dwSize); + + if (!GetTokenInformation(hToken, TokenUser, pTokenUser, dwSize, &dwSize)) + gle = GetLastError(); + + if (AllocateAndInitializeSid( &SIDAuth, 1, + SECURITY_LOCAL_SYSTEM_RID, + 0, 0, 0, 0, 0, 0, 0, + &pSidLocalSystem)) + { + if (EqualSid(pTokenUser->User.Sid, pSidLocalSystem)) { + fAdmin = TRUE; + } + + FreeSid(pSidLocalSystem); + } + + if ( pTokenUser ) + free(pTokenUser); + } } } free(psidAdmin); free(pszRefDomain); + + fTested = TRUE; } return fAdmin; @@ -2447,7 +2482,7 @@ struct afsconf_cell *info; } else { /* got a ticket */ - if (ttoken.kvno >= 0 && ttoken.kvno <= 255) scIndex = 2; /* kerberos */ + if (ttoken.kvno >= 0 && ttoken.kvno <= 256) scIndex = 2; /* kerberos */ else { fprintf (stderr, "fs: funny kvno (%d) in ticket, proceeding\n", ttoken.kvno); diff --git a/src/WINNT/afsd/smb.c b/src/WINNT/afsd/smb.c index 390df160bc..fb3e1aefd5 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; + unsigned int attrs; - if (scp->fileType == CM_SCACHETYPE_DIRECTORY - || scp->fileType == CM_SCACHETYPE_MOUNTPOINT) - attrs = SMB_ATTR_DIRECTORY; - else - attrs = 0; + 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. - */ + /* + * 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]; + smb_LargeSearchTimeFromUnixTime(&ft, unixTime); - day = ExtractBits(wDate, 0, 5); - month = ExtractBits(wDate, 5, 4); - year = ExtractBits(wDate, 9, 7) + 1980; + 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]; - sec = ExtractBits(wTime, 0, 5); - min = ExtractBits(wTime, 5, 6); - hour = ExtractBits(wTime, 11, 5); + day = ExtractBits(wDate, 0, 5); + month = ExtractBits(wDate, 5, 4); + year = ExtractBits(wDate, 9, 7) + 1980; - 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)); - } -} + 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; + /* Get the time zone info. NT uses this to calc if we are in DST. */ + GetTimeZoneInformation(&timeZoneInformation); - /* Return the bias */ - *pBias = timeZoneInformation.Bias; + /* Return the daylight bias */ + *pDstBias = timeZoneInformation.DaylightBias; - /* Now determine if DST is being observed */ + /* Return the bias */ + *pBias = timeZoneInformation.Bias; - /* Get the UTC (GMT) time */ - GetSystemTime(&utc); + /* Now determine if DST is being observed */ - /* 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); + /* Get the UTC (GMT) time */ + GetSystemTime(&utc); - /* 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 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); - /* Convert the utc time to local time again, but this time without any - adjustment for daylight savings time. - */ - SystemTimeToTzSpecificLocalTime(&timeZoneInformation, &utc, &local); + /* 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; - /* 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; -} + /* 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 */ + 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. - */ + /* + * 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); + GetTimeZoneInfo(&dst, &dstBias, &bias); - /* First adjust for DST */ - if (dst) - *pLastWriteTime -= (-dstBias * 60); /* Convert dstBias to seconds */ + /* 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 */ -} + /* 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; + 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); + /* + * 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; - } + /* 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; + 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); + 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 */ + /* 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); + /* 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); -} + /* 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; + SYSTEMTIME stm; + struct tm lt; + long save_timezone; - FileTimeToSystemTime(largeTimep, &stm); + 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; + 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; -} + 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; + /* 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); + /* 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); + /* subtract it from ft */ + a = LargeIntegerSubtract(*ft, a); - /* divide down to seconds */ - *unixTimep = LargeIntegerDivideByLong(a, 10000000); -} + /* 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 */ + dosDate = searchTime & 0xffff; + dosTime = (searchTime >> 16) & 0xffff; - *unixTimep = mktime(&localTm); + 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; + 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)); + 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; + 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; + 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; + 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; + 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; + 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; + 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; + 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); + smbp = (smb_t *) inp; + uidp = smb_FindUID(vcp, smbp->uid, 0); + if ((!uidp) || (!uidp->unp)) + return NULL; - smb_ReleaseUID(uidp); - - return up; + 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; - } + 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++; + 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; + 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); + /*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; - } + 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) + 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; + 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); + 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); -} + /* 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++; - } + 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; - } + /* 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; + smb_dirSearch_t *dsp; + int counter; + int maxAllowed; - lock_ObtainWrite(&smb_globalLock); - counter = 0; + 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; + /* 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; + 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; + 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; - } + /* 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; + 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 */ + /* 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; -} + /* 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; + 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; - } + /* 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); -} + *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; + unsigned short EchoCount, i; + char *data, *outdata; + int dataSize; - EchoCount = (unsigned short) smb_GetSMBParm(inp, 0); + 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); - } + 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; + 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; - } - } - } + dead_vcp = active_vcp; + dead_vcp->flags |= SMB_VCFLAG_ALREADYDEAD; + } + } + } - inp->flags |= SMB_PACKETFLAG_PROFILE_UPDATE_OK; + 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 = 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; - } + /* 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); + /* 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 (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 (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 */ + 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 */ + 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 ) { + 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)); + datap = smb_GetSMBData(outp, NULL); + memcpy(datap, &smb_ServerGUID, sizeof(smb_ServerGUID)); - if (secBlob) { - datap += sizeof(smb_ServerGUID); - memcpy(datap, secBlob, secBlobLength); - free(secBlob); - } + 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 */ + 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 */ + 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; + 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(); + 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); + /* 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); + /* 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); - } + /* 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"); + 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; + 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; + 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"); + 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); + /* 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); + userp = smb_GetUser(vcp, inp); - lock_ObtainMutex(&vcp->mx); - newTid = vcp->tidCounter++; - lock_ReleaseMutex(&vcp->mx); - - tidp = smb_FindTID(vcp, newTid, SMB_FLAG_CREATE); + 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 (chainpp) { + *chainpp = inp + tlen; + } + + if (lengthp) *lengthp = 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; + char *tp; + char *up; + int i; + int tc; + int valid8Dot3; - /* starts off valid */ - valid8Dot3 = 1; + /* starts off valid */ + valid8Dot3 = 1; - /* mask starts out all blanks */ - memset(maskp, ' ', 11); + /* 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 */ + /* 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; + 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 */ + /* XXX redo this, calling smb_V3MatchMask with a converted mask */ - valid = smb_Get8Dot3MaskFromPath(umask, unixNamep); - if (!valid) - return 0; + 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; - } + /* 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; + /* 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; + 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"); + 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; - } + /* 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; + } - /* 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 */ + /* for returning to caller */ + smb_Get8Dot3MaskFromPath(mask, pathp); - /* now marshall the dir entry, starting with the search status */ - *tp++ = statBlockp[0]; /* Reserved */ - memcpy(tp, mask, 11); tp += 11; /* FileName */ + 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 pass back server use info, with 1st byte non-zero */ - *tp++ = 1; - memset(tp, 0, 4); tp += 4; /* reserved for server use */ + /* now marshall the dir entry, starting with the search status */ + *tp++ = statBlockp[0]; /* Reserved */ + memcpy(tp, mask, 11); tp += 11; /* FileName */ - memcpy(tp, statBlockp+17, 4); tp += 4; /* reserved for consumer */ + /* now pass back server use info, with 1st byte non-zero */ + *tp++ = 1; + memset(tp, 0, 4); tp += 4; /* reserved for server use */ - *tp++ = 0x8; /* attribute: volume */ + memcpy(tp, statBlockp+17, 4); tp += 4; /* reserved for consumer */ - /* copy out time */ - *tp++ = 0; - *tp++ = 0; + *tp++ = 0x8; /* attribute: volume */ - /* copy out date */ - *tp++ = 18; - *tp++ = 178; + /* copy out time */ + *tp++ = 0; + *tp++ = 0; - /* 4 byte file size */ - *tp++ = 0; - *tp++ = 0; - *tp++ = 0; - *tp++ = 0; + /* copy out date */ + *tp++ = 18; + *tp++ = 178; - /* finally, null-terminated 8.3 pathname, which we set to AFS */ - memset(tp, ' ', 13); - strcpy(tp, "AFS"); + /* 4 byte file size */ + *tp++ = 0; + *tp++ = 0; + *tp++ = 0; + *tp++ = 0; - /* 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; -} + /* 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; + 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)) { + 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; + /* 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; + /* 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; + 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); + cm_InitReq(&req); - maxCount = smb_GetSMBParm(inp, 0); + maxCount = smb_GetSMBParm(inp, 0); - dirListPatchesp = NULL; + dirListPatchesp = NULL; - caseFold = CM_FLAG_CASEFOLD; + caseFold = CM_FLAG_CASEFOLD; - tp = smb_GetSMBData(inp, NULL); - pathp = smb_ParseASCIIBlock(tp, &tp); - inCookiep = smb_ParseVblBlock(tp, &tp, &dataLength); + 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; - } + /* 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 */ + /* 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); + /* 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); + /* 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)); + 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; - } + 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); + 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]; + /* 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); + /* 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); + memcpy(mask, dsp->mask, 11); - /* assume we're doing a star match if it has continued for more - * than one call. - */ - starPattern = 1; - } + /* 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); + osi_Log3(smb_logp, "SMB dir search cookie 0x%x, connection %d, attr 0x%x", + nextCookie, dsp->cookie, attribute); - userp = smb_GetUser(vcp, inp); + 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) { + /* 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; - } + 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; - } + /* 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); + 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; + } - /* now put temp bits back ito curOffset.LowPart */ - curOffset.LowPart &= ~(2048-1); - curOffset.LowPart |= temp; + /* make sure the low order 5 bits are zero */ + temp &= ~(32-1); - /* check if we've returned all the names that will fit in the - * response packet. - */ - if (returnedNames >= maxCount) - break; + /* 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; + /* 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); + /* 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); - } - } + /* 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; + 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; + /* 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; + 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) ... */ + /* 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); + /* 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); + /* 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; - } + /* 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 */ + 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); + /* 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 8.3 name if necessary */ - actualName = dep->name; - if (dep->fid.vnode != 0 && !cm_Is8Dot3(actualName)) { - cm_Gen8Dot3Name(dep, shortName, &shortNameEnd); - actualName = shortName; - } + /* compute the offset of the cookie representing the next entry */ + nextEntryCookie = curOffset.LowPart + (CM_DIR_CHUNKSIZE * numDirChunks); - 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. - */ + /* Compute 8.3 name if necessary */ + actualName = dep->name; + if (dep->fid.vnode != 0 && !cm_Is8Dot3(actualName)) { + cm_Gen8Dot3Name(dep, shortName, &shortNameEnd); + actualName = shortName; + } - /* Eliminate entries that don't match requested - attributes */ + 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. + */ - /* no hidden files */ - if(smb_hideDotFiles && !(dsp->attribute & SMB_ATTR_HIDDEN) && smb_IsDotFile(actualName)) - goto nextEntry; + /* Eliminate entries that don't match requested + * attributes */ - 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; - } + /* no hidden files */ + if(smb_hideDotFiles && !(dsp->attribute & SMB_ATTR_HIDDEN) && smb_IsDotFile(actualName)) + 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; + 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; + } - /* 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); + *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; - /* do hidden attribute here since name won't be around when applying - * dir list patches - */ + /* 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); - if ( smb_hideDotFiles && smb_IsDotFile(actualName) ) - curPatchp->flags = SMB_DIRLISTPATCH_DOTFILE; - else - curPatchp->flags = 0; + /* do hidden attribute here since name won't be around when applying + * dir list patches + */ - op += 9; /* skip attr, time, date and size */ + if ( smb_hideDotFiles && smb_IsDotFile(actualName) ) + curPatchp->flags = SMB_DIRLISTPATCH_DOTFILE; + else + curPatchp->flags = 0; - /* zero out name area. The spec says to pad with - * spaces, but Samba doesn't, and neither do we. - */ - memset(op, 0, 13); + op += 9; /* skip attr, time, date and size */ - /* 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); + /* zero out name area. The spec says to pad with + * spaces, but Samba doesn't, and neither do we. + */ + memset(op, 0, 13); - /* Uppercase if requested by client */ - if ((((smb_t *)inp)->flg2 & 1) == 0) - _strupr(op); + /* 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); - op += 13; + /* Uppercase if requested by client */ + if ((((smb_t *)inp)->flg2 & 1) == 0) + _strupr(op); - /* 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 */ + op += 13; - /* release the mutex */ - lock_ReleaseMutex(&scp->mx); - if (bufferp) buf_Release(bufferp); + /* now, adjust the # of entries copied */ + returnedNames++; + } /* if we're including this name */ - /* 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); + 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 */ - /* special return code for unsuccessful search */ - if (code == 0 && dataLength < 21 && returnedNames == 0) - code = CM_ERROR_NOFILES; + /* release the mutex */ + lock_ReleaseMutex(&scp->mx); + if (bufferp) buf_Release(bufferp); - osi_Log2(smb_logp, "SMB search dir done, %d names, code %d", - returnedNames, code); + /* 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); - if (code != 0) { - smb_DeleteDirSearch(dsp); - smb_ReleaseDirSearch(dsp); - cm_ReleaseSCache(scp); - cm_ReleaseUser(userp); - return code; - } + /* special return code for unsuccessful search */ + if (code == 0 && dataLength < 21 && returnedNames == 0) + code = CM_ERROR_NOFILES; - /* finalize the output buffer */ - smb_SetSMBParm(outp, 0, returnedNames); - temp = (long) (op - origOp); - smb_SetSMBDataLength(outp, temp); + osi_Log2(smb_logp, "SMB search dir done, %d names, code %d", + returnedNames, code); - /* 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 (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; + 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); + 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)); + 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; - } + 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; - } + /* 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); + attrs = smb_Attributes(newScp); - if (!(attrs & 0x10)) - code = CM_ERROR_NOTDIR; + if (!(attrs & 0x10)) + code = CM_ERROR_NOTDIR; - lock_ReleaseMutex(&newScp->mx); + lock_ReleaseMutex(&newScp->mx); - cm_ReleaseSCache(newScp); - cm_ReleaseUser(userp); - return code; + 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; + 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); + cm_InitReq(&req); - /* decode basic attributes we're passed */ - attribute = smb_GetSMBParm(inp, 0); - dosTime = smb_GetSMBParm(inp, 1) | (smb_GetSMBParm(inp, 2) << 16); + /* 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); + pathp = smb_GetSMBData(inp, NULL); + pathp = smb_ParseASCIIBlock(pathp, NULL); + + if (!pathp) { + return CM_ERROR_BADSMB; + } - if (!pathp) { - return CM_ERROR_BADSMB; - } + osi_Log2(smb_logp, "SMB receive setfile attributes time %d, attr 0x%x", + dosTime, attribute); + + rootScp = cm_rootSCachep; - osi_Log2(smb_logp, "SMB receive setfile attributes time %d, attr 0x%x", - dosTime, attribute); + userp = smb_GetUser(vcp, inp); - rootScp = cm_rootSCachep; - - 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; - } + /* 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; - } + /* 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); + /* 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 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; + 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); + cm_InitReq(&req); - pathp = smb_GetSMBData(inp, NULL); - pathp = smb_ParseASCIIBlock(pathp, NULL); + pathp = smb_GetSMBData(inp, NULL); + pathp = smb_ParseASCIIBlock(pathp, NULL); + + if (!pathp) { + return CM_ERROR_BADSMB; + } - if (!pathp) { - return CM_ERROR_BADSMB; - } + if (*pathp == 0) /* null path */ + pathp = "\\"; + + osi_Log1(smb_logp, "SMB receive getfile attributes path %s", + osi_LogSaveString(smb_logp, pathp)); + + rootScp = cm_rootSCachep; - if (*pathp == 0) /* null path */ - pathp = "\\"; + userp = smb_GetUser(vcp, inp); - osi_Log1(smb_logp, "SMB receive getfile attributes path %s", - osi_LogSaveString(smb_logp, pathp)); + /* we shouldn't need this for V3 requests, but we seem to */ + caseFold = CM_FLAG_CASEFOLD; - rootScp = cm_rootSCachep; - - userp = smb_GetUser(vcp, inp); - - /* 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; - } - } - } + /* + * 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; - } + 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; - } + /* 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_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); + 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; + 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"); + 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); - } + /* 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; + 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; - } - - code = cm_CheckOpen(scp, share & 0x7, 0, userp, &req); - if (code) { - cm_ReleaseSCache(scp); - cm_ReleaseUser(userp); - return code; - } + 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. + 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 (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; + 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); + cm_InitReq(&req); - attribute = smb_GetSMBParm(inp, 0); + 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; - } + 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 = 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; + 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; + 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; + 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; + 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; + 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); + 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; + 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); - - osi_Log1(smb_logp, "SMB flush fid %d", fid); + fid = smb_GetSMBParm(inp, 0); - fid = smb_ChainFID(fid, inp); + osi_Log1(smb_logp, "SMB flush fid %d", fid); + + 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; + char shortName[13]; + struct smb_FullNameRock *vrockp; - vrockp = (struct smb_FullNameRock *)rockp; + vrockp = (struct smb_FullNameRock *)rockp; - if (!cm_Is8Dot3(dep->name)) { - cm_Gen8Dot3Name(dep, shortName, NULL); + 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; + 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; + struct smb_FullNameRock rock; + long code = 0; - rock.name = pathp; - rock.vnode = scp; + 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); + 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); - fid = smb_ChainFID(fid, inp); + osi_Log1(smb_logp, "SMB close fid %d", fid); + + 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; + 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); + cm_InitReq(&req); - bufferp = NULL; - offset = *offsetp; + bufferp = NULL; + offset = *offsetp; - lock_ObtainMutex(&fidp->mx); - scp = fidp->scp; - lock_ObtainMutex(&scp->mx); + 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; - } + 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; + /* 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; + /* 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); + /* 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; - } + /* if we are past EOF, read 0 bytes */ + if (LargeIntegerLessThanZero(thyper)) + count = 0; + else + count = thyper.LowPart; + } - *readp = count; + *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); + /* 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; - lock_ObtainRead(&scp->bufCreateLock); - code = buf_Get(scp, &thyper, &bufferp); - lock_ReleaseRead(&scp->bufCreateLock); + /* 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_ObtainMutex(&scp->mx); - if (code) goto done; - bufferOffset = thyper; + lock_ObtainRead(&scp->bufCreateLock); + code = buf_Get(scp, &thyper, &bufferp); + lock_ReleaseRead(&scp->bufCreateLock); - /* 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; + 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; + 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); + /* 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) ... */ - /* 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 */ + /* 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; - bufferp = NULL; - doWriteBack = 0; - offset = *offsetp; + cm_InitReq(&req); - lock_ObtainMutex(&fidp->mx); - scp = fidp->scp; - lock_ObtainMutex(&scp->mx); + bufferp = NULL; + doWriteBack = 0; + offset = *offsetp; - /* start by looking up the file's end */ + lock_ObtainMutex(&fidp->mx); + scp = fidp->scp; + lock_ObtainMutex(&scp->mx); + + /* 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; + 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; + /* make sure we have a writable FD */ + if (!(fidp->flags & SMB_FID_OPENWRITE)) { + code = CM_ERROR_BADFDOP; + goto done; + } - /* 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 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); + } - /* 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; + *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; + /* 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); + /* handle over quota or out of space */ + if (scp->flags & (CM_SCACHEFLAG_OVERQUOTA | CM_SCACHEFLAG_OUTOFSPACE)) { + *writtenp = written; + code = CM_ERROR_QUOTA; + break; + } - lock_ObtainRead(&scp->bufCreateLock); - code = buf_Get(scp, &thyper, &bufferp); - lock_ReleaseRead(&scp->bufCreateLock); + /* 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_ObtainMutex(&bufferp->mx); - lock_ObtainMutex(&scp->mx); - if (code) goto done; + lock_ObtainRead(&scp->bufCreateLock); + code = buf_Get(scp, &thyper, &bufferp); + lock_ReleaseRead(&scp->bufCreateLock); - bufferOffset = thyper; + lock_ObtainMutex(&bufferp->mx); + lock_ObtainMutex(&scp->mx); + if (code) goto done; - /* now get the data in the cache */ - while (1) { + 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 (code) + goto done; - if (cm_HaveBuffer(scp, bufferp, 1)) break; + /* 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; + } - /* 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); + if (cm_HaveBuffer(scp, bufferp, 1)) break; - /* 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 */ + /* 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); - } + 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 && 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) { + 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); - } + 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; + 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; + 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); - } + 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); + /* 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); + 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); - } + /* + * 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; + if (code == 0 && written == 0) + 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; + 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); - } + /* 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); + 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; - } + 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 = written; + 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, + /* 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); + 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; + 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; + 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_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; - } - 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; - - 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); -#endif /* !DJGPP */ - osi_Log1(smb_logp, - "dispatch smb recv failed, message incomplete, ncb_length %d", - ncbp->ncb_length); + 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, - "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; + "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; } - else { - thrd_Sleep(1000); - thrd_SetEvent(SessionEvents[idx_session]); - } - continue; - } + 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; - /* Success, so now dispatch on all the data in the packet */ + case NRC_INCOMP: + /* Treat as transient error */ + { +#ifndef DJGPP + EVENT_HANDLE h; + char *ptbuf[1]; + char s[100]; - smb_concurrentCalls++; - if (smb_concurrentCalls > smb_maxObsConcurrentCalls) - smb_maxObsConcurrentCalls = smb_concurrentCalls; + 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; + } + + /* Success, so now dispatch on all the data in the packet */ + + 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]; + * 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); + 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; + 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); - } + 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); + /* 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; - } + /* 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; + 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]; + /* 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"; + 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); - } + 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; -} + 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]; + 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); + 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; - 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 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(); + /* 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'}; + 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; + if (!packet) return; - osi_Log0(smb_logp, "*** SMB packet dump ***"); + osi_Log0(smb_logp, "*** SMB packet dump ***"); - vp = (BYTE *) packet->data; + vp = (BYTE *) packet->data; - datalen = *((WORD*)(vp + (paramlen = ((unsigned)*(vp+20)) << 1))); - length = paramlen + 2 + datalen; + 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; + for (i=0;i < length; i+=16) + { + memset( buf, ' ', 80 ); + buf[80] = 0; - itoa( i, buf, 16 ); + itoa( i, buf, 16 ); - buf[strlen(buf)] = ' '; + buf[strlen(buf)] = ' '; - cp = (BYTE*) buf + 7; + cp = (BYTE*) buf + 7; - for(j=0;j < 16 && (i+j)> 4]; - *(cp++) = hex[vp[i+j] & 0xf]; - *(cp++) = ' '; + for (j=0;j < 16 && (i+j)> 4]; + *(cp++) = hex[vp[i+j] & 0xf]; + *(cp++) = ' '; - if(j==7) - { - *(cp++) = '-'; - *(cp++) = ' '; - } - } + if (j==7) + { + *(cp++) = '-'; + *(cp++) = ' '; + } + } - for(j=0;j < 16 && (i+j) vp[i+j] )? vp[i+j]:'.'; - if(j==7) - { - *(cp++) = ' '; - *(cp++) = '-'; - *(cp++) = ' '; - } - } + for (j=0;j < 16 && (i+j) vp[i+j] )? vp[i+j]:'.'; + if (j==7) + { + *(cp++) = ' '; + *(cp++) = '-'; + *(cp++) = ' '; + } + } - *cp = 0; + *cp = 0; - osi_Log0( smb_logp, osi_LogSaveString(smb_logp, buf)); - } - - 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 4e83730fa1..9271bcb4ce 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 dc0dd0a50c..9c8691f64a 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; + 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. - */ + 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); - } + 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); + 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; - } + 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; - } + ctx.dwLower = 0; + ctx.dwUpper = 0; + } secBufIn.cBuffers = 1; - secBufIn.pBuffers = &secTokIn; - secBufIn.ulVersion = SECBUFFER_VERSION; + 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; - } + 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; + secBufOut.cBuffers = 1; + secBufOut.pBuffers = &secTokOut; + secBufOut.ulVersion = SECBUFFER_VERSION; - secTokOut.BufferType = SECBUFFER_TOKEN; - secTokOut.cbBuffer = 0; - secTokOut.pvBuffer = NULL; + 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 - ); + 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 (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) { +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; - 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); - 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; + } - 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.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.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.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); + 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.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.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.lmlogon.ParameterControl = 0; - lmAuth.tgroups.GroupCount = 0; - lmAuth.tgroups.Groups[0].Sid = NULL; - lmAuth.tgroups.Groups[0].Attributes = 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 */ + 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); + 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); + OutputDebugF("Return from LsaLogonUser is 0x%lX", nts); + OutputDebugF("Extended status is 0x%lX", ntsEx); - if (nts == ERROR_SUCCESS) { - /* free the token */ - LsaFreeReturnBuffer(lmprofilep); + 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) { +long smb_GetNormalizedUsername(char * usern, const char * accountName, const char * domainName) +{ + char * atsign; + const char * domain; - char * atsign; - const char * domain; + /* check if we have sane input */ + if ((strlen(accountName) + strlen(domainName) + 1) > SMB_MAX_USERNAME_LENGTH) + return 1; - /* 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][?] + [][]/[][?] */ - /* we could get : [accountName][domainName] - [user][domain] - [user@domain][] - [user][]/[user][?] - [][]/[][?] */ + atsign = strchr(accountName, '@'); - atsign = strchr(accountName, '@'); + if (atsign) /* [user@domain][] -> [user@domain][domain] */ + domain = atsign + 1; + else + domain = domainName; - 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); + } - /* 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); - strlwr(usern); - - return 0; + 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; + 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]; + 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 */ - } + 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); - } + 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; - } + 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; - } + 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->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; + 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); + 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; + 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; + 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); + 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(!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; + if (allSubmount) + shareFound = TRUE; - } else { - rv = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\OpenAFS\\Client\\Submounts", 0, - KEY_QUERY_VALUE, &hkSubmount); - if(rv == ERROR_SUCCESS) { + } 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; + 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++; + 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; - } + 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); + cstrp = (char *) (info + 1); - info->wki10_computername = (DWORD) (cstrp - outp->datap); - strcpy(cstrp, smb_localNamep); - cstrp += strlen(cstrp) + 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; + 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; - info->wki10_langroup = (DWORD) (cstrp - outp->datap); - strcpy(cstrp, "WORKGROUP"); - cstrp += strlen(cstrp) + 1; + info->wki10_langroup = (DWORD) (cstrp - outp->datap); + strcpy(cstrp, "WORKGROUP"); + 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; + /* TODO: Not sure what values these should take, but these work */ + info->wki10_ver_major = 5; + info->wki10_ver_minor = 1; - info->wki10_logon_domain = (DWORD) (cstrp - outp->datap); - strcpy(cstrp, smb_ServerDomainName); - cstrp += strlen(cstrp) + 1; + info->wki10_logon_domain = (DWORD) (cstrp - outp->datap); + strcpy(cstrp, smb_ServerDomainName); + cstrp += strlen(cstrp) + 1; - info->wki10_oth_domains = (DWORD) (cstrp - outp->datap); - cstrp ++; /* no other domains */ + info->wki10_oth_domains = (DWORD) (cstrp - outp->datap); + cstrp ++; /* no other domains */ - outp->totalData = (unsigned short) (cstrp - outp->datap); /* actual data size */ - outp->parmsp[2] = outp->totalData; - outp->totalParms = totalParams; + outp->totalData = (unsigned short) (cstrp - outp->datap); /* actual data size */ + outp->parmsp[2] = outp->totalData; + outp->totalParms = totalParams; - smb_SendTran2Packet(vcp,outp,op); - smb_FreeTran2Packet(outp); + smb_SendTran2Packet(vcp,outp,op); + smb_FreeTran2Packet(outp); - return code; + 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) @@ -2006,7 +2001,7 @@ long smb_ReceiveTran2Open(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *op) smb_fid_t *fidp; int attributes; char *lastNamep; - long dosTime; + time_t dosTime; int openFun; int trunc; int openMode; @@ -2425,132 +2420,133 @@ long smb_ReceiveTran2QFSInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t * long smb_ReceiveTran2SetFSInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *outp) { + osi_Log0(smb_logp,"ReceiveTran2SetFSInfo - NOT_SUPPORTED"); return CM_ERROR_BADOP; } struct smb_ShortNameRock { - char *maskp; - unsigned int vnode; - char *shortName; - size_t shortNameLen; -}; + char *maskp; + unsigned int vnode; + char *shortName; + size_t shortNameLen; +}; int cm_GetShortNameProc(cm_scache_t *scp, cm_dirEntry_t *dep, void *vrockp, - osi_hyper_t *offp) -{ - struct smb_ShortNameRock *rockp; - char *shortNameEnd; + osi_hyper_t *offp) +{ + struct smb_ShortNameRock *rockp; + char *shortNameEnd; - rockp = vrockp; - /* compare both names and vnodes, though probably just comparing vnodes - * would be safe enough. - */ - if (cm_stricmp(dep->name, rockp->maskp) != 0) - return 0; - if (ntohl(dep->fid.vnode) != rockp->vnode) - return 0; - /* This is the entry */ - cm_Gen8Dot3Name(dep, rockp->shortName, &shortNameEnd); - rockp->shortNameLen = shortNameEnd - rockp->shortName; - return CM_ERROR_STOPNOW; -} + rockp = vrockp; + /* compare both names and vnodes, though probably just comparing vnodes + * would be safe enough. + */ + if (cm_stricmp(dep->name, rockp->maskp) != 0) + return 0; + if (ntohl(dep->fid.vnode) != rockp->vnode) + return 0; + /* This is the entry */ + cm_Gen8Dot3Name(dep, rockp->shortName, &shortNameEnd); + rockp->shortNameLen = shortNameEnd - rockp->shortName; + return CM_ERROR_STOPNOW; +} long cm_GetShortName(char *pathp, cm_user_t *userp, cm_req_t *reqp, char *tidPathp, int vnode, char *shortName, size_t *shortNameLenp) { - struct smb_ShortNameRock rock; - char *lastNamep; - cm_space_t *spacep; - cm_scache_t *dscp; - int caseFold = CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD; - long code = 0; - osi_hyper_t thyper; + struct smb_ShortNameRock rock; + char *lastNamep; + cm_space_t *spacep; + cm_scache_t *dscp; + int caseFold = CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD; + long code = 0; + osi_hyper_t thyper; - spacep = cm_GetSpace(); - smb_StripLastComponent(spacep->data, &lastNamep, pathp); + spacep = cm_GetSpace(); + smb_StripLastComponent(spacep->data, &lastNamep, pathp); - code = cm_NameI(cm_rootSCachep, spacep->data, caseFold, userp, tidPathp, + code = cm_NameI(cm_rootSCachep, spacep->data, caseFold, userp, tidPathp, reqp, &dscp); - cm_FreeSpace(spacep); - if (code) return code; + cm_FreeSpace(spacep); + if (code) return code; - if (!lastNamep) lastNamep = pathp; - else lastNamep++; - thyper.LowPart = 0; - thyper.HighPart = 0; - rock.shortName = shortName; - rock.vnode = vnode; - rock.maskp = lastNamep; - code = cm_ApplyDir(dscp, cm_GetShortNameProc, &rock, &thyper, userp, + if (!lastNamep) lastNamep = pathp; + else lastNamep++; + thyper.LowPart = 0; + thyper.HighPart = 0; + rock.shortName = shortName; + rock.vnode = vnode; + rock.maskp = lastNamep; + code = cm_ApplyDir(dscp, cm_GetShortNameProc, &rock, &thyper, userp, reqp, NULL); - cm_ReleaseSCache(dscp); + cm_ReleaseSCache(dscp); - if (code == 0) - return CM_ERROR_NOSUCHFILE; - if (code == CM_ERROR_STOPNOW) { - *shortNameLenp = rock.shortNameLen; - return 0; - } - return code; + if (code == 0) + return CM_ERROR_NOSUCHFILE; + if (code == CM_ERROR_STOPNOW) { + *shortNameLenp = rock.shortNameLen; + return 0; + } + return code; } long smb_ReceiveTran2QPathInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *opx) { - smb_tran2Packet_t *outp; - unsigned long dosTime; - FILETIME ft; + smb_tran2Packet_t *outp; + time_t dosTime; + FILETIME ft; unsigned short infoLevel; int nbytesRequired; unsigned short attributes; - unsigned long extAttributes; - char shortName[13]; - unsigned int len; + unsigned long extAttributes; + char shortName[13]; + unsigned int len; cm_user_t *userp; - cm_space_t *spacep; + cm_space_t *spacep; cm_scache_t *scp, *dscp; long code = 0; char *op; - char *tidPathp; - char *lastComp; - cm_req_t req; + char *tidPathp; + char *lastComp; + cm_req_t req; - cm_InitReq(&req); + cm_InitReq(&req); - infoLevel = p->parmsp[0]; + infoLevel = p->parmsp[0]; if (infoLevel == 6) nbytesRequired = 0; else if (infoLevel == 1) nbytesRequired = 22; else if (infoLevel == 2) nbytesRequired = 26; - else if (infoLevel == 0x101) nbytesRequired = 40; - else if (infoLevel == 0x102) nbytesRequired = 24; - else if (infoLevel == 0x103) nbytesRequired = 4; - else if (infoLevel == 0x108) nbytesRequired = 30; + else if (infoLevel == 0x101) nbytesRequired = 40; + else if (infoLevel == 0x102) nbytesRequired = 24; + else if (infoLevel == 0x103) nbytesRequired = 4; + else if (infoLevel == 0x108) nbytesRequired = 30; else { - osi_Log2(smb_logp, "Bad Tran2 op 0x%x infolevel 0x%x", + osi_Log2(smb_logp, "Bad Tran2 op 0x%x infolevel 0x%x", p->opcode, infoLevel); - smb_SendTran2Error(vcp, p, opx, CM_ERROR_INVAL); + smb_SendTran2Error(vcp, p, opx, CM_ERROR_INVAL); return 0; } - osi_Log2(smb_logp, "T2 QPathInfo type 0x%x path %s", infoLevel, - osi_LogSaveString(smb_logp, (char *)(&p->parmsp[3]))); + osi_Log2(smb_logp, "T2 QPathInfo type 0x%x path %s", infoLevel, + osi_LogSaveString(smb_logp, (char *)(&p->parmsp[3]))); outp = smb_GetTran2ResponsePacket(vcp, p, opx, 2, nbytesRequired); - if (infoLevel > 0x100) - outp->totalParms = 2; - else - outp->totalParms = 0; - outp->totalData = nbytesRequired; + if (infoLevel > 0x100) + outp->totalParms = 2; + else + outp->totalParms = 0; + outp->totalData = nbytesRequired; /* now, if we're at infoLevel 6, we're only being asked to check * the syntax, so we just OK things now. In particular, we're *not* * being asked to verify anything about the state of any parent dirs. */ - if (infoLevel == 6) { - smb_SendTran2Packet(vcp, outp, opx); + if (infoLevel == 6) { + smb_SendTran2Packet(vcp, outp, opx); smb_FreeTran2Packet(outp); - return 0; - } + return 0; + } userp = smb_GetTran2User(vcp, p); if (!userp) { @@ -2709,304 +2705,344 @@ long smb_ReceiveTran2QPathInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t long smb_ReceiveTran2SetPathInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *outp) { + osi_Log0(smb_logp,"ReceiveTran2SetPathInfo - NOT_SUPPORTED"); return CM_ERROR_BADOP; } long smb_ReceiveTran2QFileInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *opx) { - smb_tran2Packet_t *outp; - FILETIME ft; - unsigned long attributes; - unsigned short infoLevel; - int nbytesRequired; - unsigned short fid; - cm_user_t *userp; + smb_tran2Packet_t *outp; + FILETIME ft; + unsigned long attributes; + unsigned short infoLevel; + int nbytesRequired; + unsigned short fid; + cm_user_t *userp; smb_fid_t *fidp; - cm_scache_t *scp; - char *op; - long code = 0; - cm_req_t req; + cm_scache_t *scp; + char *op; + long code = 0; + cm_req_t req; - cm_InitReq(&req); + cm_InitReq(&req); fid = p->parmsp[0]; fidp = smb_FindFID(vcp, fid, 0); - if (fidp == NULL) { - smb_SendTran2Error(vcp, p, opx, CM_ERROR_BADFD); - return 0; - } + if (fidp == NULL) { + smb_SendTran2Error(vcp, p, opx, CM_ERROR_BADFD); + return 0; + } - infoLevel = p->parmsp[1]; - if (infoLevel == 0x101) nbytesRequired = 40; - else if (infoLevel == 0x102) nbytesRequired = 24; - else if (infoLevel == 0x103) nbytesRequired = 4; - else if (infoLevel == 0x104) nbytesRequired = 6; - else { - osi_Log2(smb_logp, "Bad Tran2 op 0x%x infolevel 0x%x", - p->opcode, infoLevel); - smb_SendTran2Error(vcp, p, opx, CM_ERROR_INVAL); + infoLevel = p->parmsp[1]; + if (infoLevel == 0x101) nbytesRequired = 40; + else if (infoLevel == 0x102) nbytesRequired = 24; + else if (infoLevel == 0x103) nbytesRequired = 4; + else if (infoLevel == 0x104) nbytesRequired = 6; + else { + osi_Log2(smb_logp, "Bad Tran2 op 0x%x infolevel 0x%x", + p->opcode, infoLevel); + smb_SendTran2Error(vcp, p, opx, CM_ERROR_INVAL); smb_ReleaseFID(fidp); - return 0; - } - osi_Log2(smb_logp, "T2 QFileInfo type 0x%x fid %d", infoLevel, fid); + return 0; + } + osi_Log2(smb_logp, "T2 QFileInfo type 0x%x fid %d", infoLevel, fid); - outp = smb_GetTran2ResponsePacket(vcp, p, opx, 2, nbytesRequired); + outp = smb_GetTran2ResponsePacket(vcp, p, opx, 2, nbytesRequired); - if (infoLevel > 0x100) - outp->totalParms = 2; - else - outp->totalParms = 0; - outp->totalData = nbytesRequired; + if (infoLevel > 0x100) + outp->totalParms = 2; + else + outp->totalParms = 0; + outp->totalData = nbytesRequired; - userp = smb_GetTran2User(vcp, p); + userp = smb_GetTran2User(vcp, p); if (!userp) { osi_Log1(smb_logp, "ReceiveTran2QFileInfo unable to resolve user [%d]", p->uid); code = CM_ERROR_BADSMB; goto done; + } + + scp = fidp->scp; + lock_ObtainMutex(&scp->mx); + code = cm_SyncOp(scp, NULL, userp, &req, 0, + CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); + if (code) + goto done; + + /* now we have the status in the cache entry, and everything is locked. + * Marshall the output data. + */ + op = outp->datap; + if (infoLevel == 0x101) { + smb_LargeSearchTimeFromUnixTime(&ft, scp->clientModTime); + *((FILETIME *)op) = ft; op += 8; /* creation time */ + *((FILETIME *)op) = ft; op += 8; /* last access time */ + *((FILETIME *)op) = ft; op += 8; /* last write time */ + *((FILETIME *)op) = ft; op += 8; /* last change time */ + attributes = smb_ExtAttributes(scp); + *((u_long *)op) = attributes; op += 4; + *((u_long *)op) = 0; op += 4; + } + else if (infoLevel == 0x102) { + *((LARGE_INTEGER *)op) = scp->length; op += 8; /* alloc size */ + *((LARGE_INTEGER *)op) = scp->length; op += 8; /* EOF */ + *((u_long *)op) = scp->linkCount; op += 4; + *op++ = ((fidp->flags & SMB_FID_DELONCLOSE) ? 1 : 0); + *op++ = (scp->fileType == CM_SCACHETYPE_DIRECTORY ? 1 : 0); + *op++ = 0; + *op++ = 0; + } + else if (infoLevel == 0x103) { + *((u_long *)op) = 0; op += 4; + } + else if (infoLevel == 0x104) { + unsigned long len; + char *name; + + if (fidp->NTopen_wholepathp) + name = fidp->NTopen_wholepathp; + else + name = "\\"; /* probably can't happen */ + len = strlen(name); + outp->totalData = (len*2) + 4; /* this is actually what we want to return */ + *((u_long *)op) = len * 2; op += 4; + mbstowcs((unsigned short *)op, name, len); op += (len * 2); } - scp = fidp->scp; - lock_ObtainMutex(&scp->mx); - code = cm_SyncOp(scp, NULL, userp, &req, 0, - CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); - if (code) goto done; - - /* now we have the status in the cache entry, and everything is locked. - * Marshall the output data. - */ - op = outp->datap; - if (infoLevel == 0x101) { - smb_LargeSearchTimeFromUnixTime(&ft, scp->clientModTime); - *((FILETIME *)op) = ft; op += 8; /* creation time */ - *((FILETIME *)op) = ft; op += 8; /* last access time */ - *((FILETIME *)op) = ft; op += 8; /* last write time */ - *((FILETIME *)op) = ft; op += 8; /* last change time */ - attributes = smb_ExtAttributes(scp); - *((u_long *)op) = attributes; op += 4; - *((u_long *)op) = 0; op += 4; - } - else if (infoLevel == 0x102) { - *((LARGE_INTEGER *)op) = scp->length; op += 8; /* alloc size */ - *((LARGE_INTEGER *)op) = scp->length; op += 8; /* EOF */ - *((u_long *)op) = scp->linkCount; op += 4; - *op++ = ((fidp->flags & SMB_FID_DELONCLOSE) ? 1 : 0); - *op++ = (scp->fileType == CM_SCACHETYPE_DIRECTORY ? 1 : 0); - *op++ = 0; - *op++ = 0; - } - else if (infoLevel == 0x103) { - *((u_long *)op) = 0; op += 4; - } - else if (infoLevel == 0x104) { - unsigned long len; - char *name; - - if (fidp->NTopen_wholepathp) - name = fidp->NTopen_wholepathp; - else - name = "\\"; /* probably can't happen */ - len = strlen(name); - outp->totalData = (len*2) + 4; /* this is actually what we want to return */ - *((u_long *)op) = len * 2; op += 4; - mbstowcs((unsigned short *)op, name, len); op += (len * 2); - } - - /* send and free the packets */ + /* send and free the packets */ done: - lock_ReleaseMutex(&scp->mx); - cm_ReleaseUser(userp); - smb_ReleaseFID(fidp); - if (code == 0) smb_SendTran2Packet(vcp, outp, opx); - else smb_SendTran2Error(vcp, p, opx, code); - smb_FreeTran2Packet(outp); + lock_ReleaseMutex(&scp->mx); + cm_ReleaseUser(userp); + smb_ReleaseFID(fidp); + if (code == 0) + smb_SendTran2Packet(vcp, outp, opx); + else + smb_SendTran2Error(vcp, p, opx, code); + smb_FreeTran2Packet(outp); - return 0; -} + return 0; +} long smb_ReceiveTran2SetFileInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *op) { - long code = 0; - unsigned short fid; - smb_fid_t *fidp; - unsigned short infoLevel; - smb_tran2Packet_t *outp; - cm_user_t *userp; - cm_scache_t *scp; - cm_req_t req; + long code = 0; + unsigned short fid; + smb_fid_t *fidp; + unsigned short infoLevel; + smb_tran2Packet_t *outp; + cm_user_t *userp; + cm_scache_t *scp; + cm_req_t req; - cm_InitReq(&req); + cm_InitReq(&req); fid = p->parmsp[0]; - fidp = smb_FindFID(vcp, fid, 0); + fidp = smb_FindFID(vcp, fid, 0); - if (fidp == NULL) { - smb_SendTran2Error(vcp, p, op, CM_ERROR_BADFD); - return 0; - } + if (fidp == NULL) { + smb_SendTran2Error(vcp, p, op, CM_ERROR_BADFD); + return 0; + } - infoLevel = p->parmsp[1]; - if (infoLevel > 0x104 || infoLevel < 0x101) { - osi_Log2(smb_logp, "Bad Tran2 op 0x%x infolevel 0x%x", - p->opcode, infoLevel); - smb_SendTran2Error(vcp, p, op, CM_ERROR_INVAL); + infoLevel = p->parmsp[1]; + osi_Log2(smb_logp,"ReceiveTran2SetFileInfo type=[%x] fid=[%x]", infoLevel, fid); + if (infoLevel > 0x104 || infoLevel < 0x101) { + osi_Log2(smb_logp, "Bad Tran2 op 0x%x infolevel 0x%x", + p->opcode, infoLevel); + smb_SendTran2Error(vcp, p, op, CM_ERROR_INVAL); smb_ReleaseFID(fidp); - return 0; - } + return 0; + } - if (infoLevel == 0x102 && !(fidp->flags & SMB_FID_OPENDELETE)) { - smb_SendTran2Error(vcp, p, op, CM_ERROR_NOACCESS); + if (infoLevel == 0x102 && !(fidp->flags & SMB_FID_OPENDELETE)) { + smb_SendTran2Error(vcp, p, op, CM_ERROR_NOACCESS); smb_ReleaseFID(fidp); - return 0; - } - if ((infoLevel == 0x103 || infoLevel == 0x104) - && !(fidp->flags & SMB_FID_OPENWRITE)) { - smb_SendTran2Error(vcp, p, op, CM_ERROR_NOACCESS); + return 0; + } + if ((infoLevel == 0x103 || infoLevel == 0x104) + && !(fidp->flags & SMB_FID_OPENWRITE)) { + smb_SendTran2Error(vcp, p, op, CM_ERROR_NOACCESS); smb_ReleaseFID(fidp); - return 0; - } + return 0; + } - osi_Log1(smb_logp, "T2 SFileInfo type 0x%x", infoLevel); + osi_Log1(smb_logp, "T2 SFileInfo type 0x%x", infoLevel); - outp = smb_GetTran2ResponsePacket(vcp, p, op, 2, 0); + outp = smb_GetTran2ResponsePacket(vcp, p, op, 2, 0); - outp->totalParms = 2; - outp->totalData = 0; + outp->totalParms = 2; + outp->totalData = 0; - userp = smb_GetTran2User(vcp, p); + userp = smb_GetTran2User(vcp, p); if (!userp) { osi_Log1(smb_logp,"ReceiveTran2SetFileInfo unable to resolve user [%d]", p->uid); code = CM_ERROR_BADSMB; goto done; - } + } - scp = fidp->scp; + scp = fidp->scp; - if (infoLevel == 0x101) { - FILETIME lastMod; - unsigned int attribute; - cm_attr_t attr; + if (infoLevel == 0x101) { + FILETIME lastMod; + unsigned int attribute; + cm_attr_t attr; - /* lock the vnode with a callback; we need the current status - * to determine what the new status is, in some cases. - */ - lock_ObtainMutex(&scp->mx); - code = cm_SyncOp(scp, NULL, userp, &req, 0, - CM_SCACHESYNC_GETSTATUS + /* lock the vnode with a callback; we need the current status + * to determine what the new status is, in some cases. + */ + lock_ObtainMutex(&scp->mx); + code = cm_SyncOp(scp, NULL, userp, &req, 0, + CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_NEEDCALLBACK); - if (code) { - lock_ReleaseMutex(&scp->mx); - goto done; - } + if (code) { + lock_ReleaseMutex(&scp->mx); + goto done; + } - /* prepare for setattr call */ - attr.mask = 0; - - lastMod = *((FILETIME *)(p->datap + 16)); - /* when called as result of move a b, lastMod is (-1, -1). + /* prepare for setattr call */ + attr.mask = 0; + + lastMod = *((FILETIME *)(p->datap + 16)); + /* when called as result of move a b, lastMod is (-1, -1). * If the check for -1 is not present, timestamp - * of the resulting file will be 1969 (-1) - */ - if (LargeIntegerNotEqualToZero(*((LARGE_INTEGER *)&lastMod)) && - lastMod.dwLowDateTime != -1 && lastMod.dwHighDateTime != -1) { - attr.mask |= CM_ATTRMASK_CLIENTMODTIME; - smb_UnixTimeFromLargeSearchTime(&attr.clientModTime, - &lastMod); - fidp->flags |= SMB_FID_MTIMESETDONE; - } + * of the resulting file will be 1969 (-1) + */ + if (LargeIntegerNotEqualToZero(*((LARGE_INTEGER *)&lastMod)) && + lastMod.dwLowDateTime != -1 && lastMod.dwHighDateTime != -1) { + attr.mask |= CM_ATTRMASK_CLIENTMODTIME; + smb_UnixTimeFromLargeSearchTime(&attr.clientModTime, + &lastMod); + fidp->flags |= SMB_FID_MTIMESETDONE; + } - attribute = *((u_long *)(p->datap + 32)); - if (attribute != 0) { - if ((scp->unixModeBits & 0222) - && (attribute & 1) != 0) { - /* make a writable file read-only */ - attr.mask |= CM_ATTRMASK_UNIXMODEBITS; - attr.unixModeBits = scp->unixModeBits & ~0222; - } - else if ((scp->unixModeBits & 0222) == 0 - && (attribute & 1) == 0) { - /* make a read-only file writable */ - attr.mask |= CM_ATTRMASK_UNIXMODEBITS; - attr.unixModeBits = scp->unixModeBits | 0222; - } - } - lock_ReleaseMutex(&scp->mx); + attribute = *((u_long *)(p->datap + 32)); + if (attribute != 0) { + if ((scp->unixModeBits & 0222) + && (attribute & 1) != 0) { + /* make a writable file read-only */ + attr.mask |= CM_ATTRMASK_UNIXMODEBITS; + attr.unixModeBits = scp->unixModeBits & ~0222; + } + else if ((scp->unixModeBits & 0222) == 0 + && (attribute & 1) == 0) { + /* make a read-only file writable */ + attr.mask |= CM_ATTRMASK_UNIXMODEBITS; + attr.unixModeBits = scp->unixModeBits | 0222; + } + } + lock_ReleaseMutex(&scp->mx); - /* call setattr */ - if (attr.mask) - code = cm_SetAttr(scp, &attr, userp, &req); - else - code = 0; - } - else if (infoLevel == 0x103 || infoLevel == 0x104) { - LARGE_INTEGER size = *((LARGE_INTEGER *)(p->datap)); - cm_attr_t attr; + /* call setattr */ + if (attr.mask) + code = cm_SetAttr(scp, &attr, userp, &req); + else + code = 0; + } + else if (infoLevel == 0x103 || infoLevel == 0x104) { + LARGE_INTEGER size = *((LARGE_INTEGER *)(p->datap)); + cm_attr_t attr; + + attr.mask = CM_ATTRMASK_LENGTH; + attr.length.LowPart = size.LowPart; + attr.length.HighPart = size.HighPart; + code = cm_SetAttr(scp, &attr, userp, &req); + } + else if (infoLevel == 0x102) { + if (*((char *)(p->datap))) { + code = cm_CheckNTDelete(fidp->NTopen_dscp, scp, userp, + &req); + if (code == 0) + fidp->flags |= SMB_FID_DELONCLOSE; + } + else { + code = 0; + fidp->flags &= ~SMB_FID_DELONCLOSE; + } + } - attr.mask = CM_ATTRMASK_LENGTH; - attr.length.LowPart = size.LowPart; - attr.length.HighPart = size.HighPart; - code = cm_SetAttr(scp, &attr, userp, &req); - } - else if (infoLevel == 0x102) { - if (*((char *)(p->datap))) { - code = cm_CheckNTDelete(fidp->NTopen_dscp, scp, userp, - &req); - if (code == 0) - fidp->flags |= SMB_FID_DELONCLOSE; - } - else { - code = 0; - fidp->flags &= ~SMB_FID_DELONCLOSE; - } - } done: - cm_ReleaseUser(userp); - smb_ReleaseFID(fidp); - if (code == 0) smb_SendTran2Packet(vcp, outp, op); - else smb_SendTran2Error(vcp, p, op, code); - smb_FreeTran2Packet(outp); + cm_ReleaseUser(userp); + smb_ReleaseFID(fidp); + if (code == 0) + smb_SendTran2Packet(vcp, outp, op); + else + smb_SendTran2Error(vcp, p, op, code); + smb_FreeTran2Packet(outp); - return 0; + return 0; } -long smb_ReceiveTran2FSCTL(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *outp) +long +smb_ReceiveTran2FSCTL(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *outp) { + osi_Log0(smb_logp,"ReceiveTran2FSCTL - NOT_SUPPORTED"); return CM_ERROR_BADOP; } -long smb_ReceiveTran2IOCTL(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *outp) +long +smb_ReceiveTran2IOCTL(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *outp) { + osi_Log0(smb_logp,"ReceiveTran2IOCTL - NOT_SUPPORTED"); return CM_ERROR_BADOP; } -long smb_ReceiveTran2FindNotifyFirst(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *outp) +long +smb_ReceiveTran2FindNotifyFirst(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *outp) { + osi_Log0(smb_logp,"ReceiveTran2FindNotifyFirst - NOT_SUPPORTED"); return CM_ERROR_BADOP; } -long smb_ReceiveTran2FindNotifyNext(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *outp) +long +smb_ReceiveTran2FindNotifyNext(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *outp) { + osi_Log0(smb_logp,"ReceiveTran2FindNotifyNext - NOT_SUPPORTED"); return CM_ERROR_BADOP; } -long smb_ReceiveTran2MKDir(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *outp) +long +smb_ReceiveTran2CreateDirectory(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *outp) { + osi_Log0(smb_logp,"ReceiveTran2CreateDirectory - NOT_SUPPORTED"); return CM_ERROR_BADOP; } -long smb_ApplyV3DirListPatches(cm_scache_t *dscp, +long +smb_ReceiveTran2SessionSetup(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *outp) +{ + osi_Log0(smb_logp,"ReceiveTran2SessionSetup - NOT_SUPPORTED"); + return CM_ERROR_BADOP; +} + +long +smb_ReceiveTran2GetDFSReferral(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *outp) +{ + osi_Log0(smb_logp,"ReceiveTran2GetDFSReferral - NOT_SUPPORTED"); + return CM_ERROR_BADOP; +} + +long +smb_ReceiveTran2ReportDFSInconsistency(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *outp) +{ + osi_Log0(smb_logp,"ReceiveTran2ReportDFSInconsistency - NOT_SUPPORTED"); + return CM_ERROR_BADOP; +} + +long +smb_ApplyV3DirListPatches(cm_scache_t *dscp, smb_dirListPatch_t **dirPatchespp, int infoLevel, cm_user_t *userp, cm_req_t *reqp) { - long code = 0; + long code = 0; cm_scache_t *scp; cm_scache_t *targetScp; /* target if scp is a symlink */ char *dptr; - long dosTime; - FILETIME ft; + time_t dosTime; + FILETIME ft; int shortTemp; unsigned short attr; - unsigned long lattr; + unsigned long lattr; smb_dirListPatch_t *patchp; smb_dirListPatch_t *npatchp; @@ -3017,9 +3053,9 @@ long 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; @@ -3030,69 +3066,69 @@ long 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; + /* 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; + /* 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 */ @@ -3113,102 +3149,102 @@ long 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); + 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; + /* 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; - - /* 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; - /* 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 access 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; + /* and copy out date */ + shortTemp = (dosTime>>16) & 0xffff; + *((u_short *)dptr) = shortTemp; + dptr += 2; - /* finally copy out attributes as short */ - attr = smb_Attributes(scp); + /* 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; @@ -3270,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; @@ -3339,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++; + /* loop */ + while (1) { + /* Next pattern character */ + tcp1 = *maskp++; - /* Next name character */ - tcn1 = *namep; + /* 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++; + 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; + /* 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; + /* No match */ + if ((req8dot3 && tcn1 == '.') || tcn1 == 0) + return 0; - /* Remember where we are */ - sawStar = 1; - starMaskp = maskp; - starNamep = namep; + /* Remember where we are */ + sawStar = 1; + starMaskp = maskp; + starNamep = namep; - namep++; - continue; - } - } - else { - /* tcp1 is not a wildcard */ + 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; @@ -3497,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 */ @@ -3515,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]; @@ -3541,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; @@ -3558,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 @@ -3584,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", @@ -3597,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); @@ -3608,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, @@ -3635,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; } @@ -3683,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; } @@ -3740,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; @@ -3776,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; @@ -3790,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) && @@ -3875,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; @@ -4008,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 @@ -4024,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; @@ -4059,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); @@ -4101,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 */ @@ -4133,25 +4167,25 @@ long smb_ReceiveV3OpenX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) smb_fid_t *fidp; int attributes; char *lastNamep; - long dosTime; + time_t dosTime; int openFun; int trunc; int openMode; 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); @@ -4163,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 @@ -4177,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++; @@ -4192,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; } @@ -4217,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); @@ -4249,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); @@ -4265,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++; @@ -4371,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_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); + cm_InitReq(&req); - fid = smb_GetSMBParm(inp, 2); - fid = smb_ChainFID(fid, inp); + 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 */ + 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; @@ -4436,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; + 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; - } + 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); + 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; + 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; - long searchTime; + 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); @@ -4543,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 */ @@ -4566,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 */ @@ -4574,46 +4608,46 @@ 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; - long searchTime; - long unixTime; + time_t searchTime; + 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; @@ -4627,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; @@ -4651,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); @@ -4687,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); @@ -4971,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"); @@ -5003,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); @@ -5064,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); @@ -5888,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) { @@ -5904,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)); @@ -5924,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; + 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; + 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]; + fid = sparmp[0]; + securityInformation = lparmp[1]; - maxData = smb_GetSMBOffsetParm(inp, 7, 1) - | (smb_GetSMBOffsetParm(inp, 8, 1) << 16); + maxData = smb_GetSMBOffsetParm(inp, 7, 1) + | (smb_GetSMBOffsetParm(inp, 8, 1) << 16); - if (maxData < 36) - dataCount = 0; - else - dataCount = 36; + if (maxData < 36) + dataCount = 0; + else + dataCount = 36; - /* out parms */ - parmOffset = 8*4 + 39; - parmOffset += 1; /* pad to 4 */ - parmCount = 4; - dataOffset = parmOffset + parmCount; + /* 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); + 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 */ + 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; + 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/aklog/aklog.c b/src/WINNT/aklog/aklog.c index 27ce5b08ff..a226d3a156 100644 --- a/src/WINNT/aklog/aklog.c +++ b/src/WINNT/aklog/aklog.c @@ -390,11 +390,11 @@ static int get_v5cred(krb5_context context, memset((char *)&increds, 0, sizeof(increds)); - if ((r = krb5_build_principal(context, &increds.server, - strlen(realm), realm, - name, - (inst && strlen(inst)) ? inst : 0, - 0))) { + if ((r = krb5_build_principal(context, &increds.server, + strlen(realm), realm, + name, + (inst && strlen(inst)) ? inst : 0, + 0))) { return((int)r); } @@ -624,6 +624,12 @@ static int auth_to_cell(krb5_context context, char *cell, char *realm) { /* using krb5 */ int retry = 1; + if ( strchr(name,'.') != NULL ) { + fprintf(stderr, "%s: Can't support principal names including a dot.\n", + progname); + return(AKLOG_MISC); + } + try_v5: if (dflag) printf("Getting v5 tickets: %s/%s@%s\n", name, instance, realm_of_cell); diff --git a/src/WINNT/client_config/drivemap.cpp b/src/WINNT/client_config/drivemap.cpp index 9716c4a108..5305f3c651 100644 --- a/src/WINNT/client_config/drivemap.cpp +++ b/src/WINNT/client_config/drivemap.cpp @@ -523,7 +523,7 @@ void QueryDriveMapList_ReadMappings (PDRIVEMAPLIST pList) &dwType, (LPBYTE)mapping, &mappingLen); if ( dwType == REG_EXPAND_SZ ) { TCHAR buf[MAX_PATH]; - DWORD dummyLen = ExpandEnvironmentStrings(buf, mapping, MAX_PATH); + DWORD dummyLen = ExpandEnvironmentStrings(mapping, buf, MAX_PATH); if (dummyLen > MAX_PATH) continue; _tcsncpy(mapping, buf, MAX_PATH); diff --git a/src/WINNT/client_config/isadmin.cpp b/src/WINNT/client_config/isadmin.cpp index 2013b7b9ca..8cf1dafeb7 100644 --- a/src/WINNT/client_config/isadmin.cpp +++ b/src/WINNT/client_config/isadmin.cpp @@ -76,8 +76,6 @@ BOOL IsAdmin (void) return FALSE; } - fTested = TRUE; - dwSize = 0; dwSize2 = 0; @@ -99,7 +97,7 @@ BOOL IsAdmin (void) return TRUE; } - psidAdmin = (PSID) malloc(dwSize); memset(psidAdmin,0,dwSize); + psidAdmin = (PSID)malloc(dwSize); memset(psidAdmin,0,dwSize); pszRefDomain = (char *)malloc(dwSize2); if (!LookupAccountName(NULL, pszAdminGroup, psidAdmin, &dwSize, pszRefDomain, &dwSize2, &snu)) { @@ -112,39 +110,76 @@ BOOL IsAdmin (void) if (OpenProcessToken (GetCurrentProcess(), TOKEN_QUERY, &hToken)) { - /* We'll have to allocate a chunk of memory to store the list of - * groups to which this user belongs; find out how much memory - * we'll need. - */ - DWORD dwSize = 0; - PTOKEN_GROUPS pGroups; - - GetTokenInformation (hToken, TokenGroups, NULL, dwSize, &dwSize); - - pGroups = (PTOKEN_GROUPS)malloc(dwSize); - - /* Allocate that buffer, and read in the list of groups. */ - if (GetTokenInformation (hToken, TokenGroups, pGroups, dwSize, &dwSize)) - { - /* Look through the list of group SIDs and see if any of them - * matches the AFS Client Admin group SID. + + if (!CheckTokenMembership(hToken, psidAdmin, &fAdmin)) { + /* We'll have to allocate a chunk of memory to store the list of + * groups to which this user belongs; find out how much memory + * we'll need. */ - size_t iGroup = 0; - for (; (!fAdmin) && (iGroup < pGroups->GroupCount); ++iGroup) + DWORD dwSize = 0; + PTOKEN_GROUPS pGroups; + + GetTokenInformation (hToken, TokenGroups, NULL, dwSize, &dwSize); + + pGroups = (PTOKEN_GROUPS)malloc(dwSize); + + /* Allocate that buffer, and read in the list of groups. */ + if (GetTokenInformation (hToken, TokenGroups, pGroups, dwSize, &dwSize)) { - if (EqualSid (psidAdmin, pGroups->Groups[ iGroup ].Sid)) { - fAdmin = TRUE; + /* Look through the list of group SIDs and see if any of them + * matches the AFS Client Admin group SID. + */ + size_t iGroup = 0; + for (; (!fAdmin) && (iGroup < pGroups->GroupCount); ++iGroup) + { + if (EqualSid (psidAdmin, pGroups->Groups[ iGroup ].Sid)) { + fAdmin = TRUE; + } } } + + if (pGroups) + free(pGroups); } - if (pGroups) - free(pGroups); + /* if do not have permission because we were not explicitly listed + * in the Admin Client Group let's see if we are the SYSTEM account + */ + if (!fAdmin) { + PTOKEN_USER pTokenUser; + SID_IDENTIFIER_AUTHORITY SIDAuth = SECURITY_NT_AUTHORITY; + PSID pSidLocalSystem = 0; + DWORD gle; + + GetTokenInformation(hToken, TokenUser, NULL, 0, &dwSize); + + pTokenUser = (PTOKEN_USER)malloc(dwSize); + + if (!GetTokenInformation(hToken, TokenUser, pTokenUser, dwSize, &dwSize)) + gle = GetLastError(); + + if (AllocateAndInitializeSid( &SIDAuth, 1, + SECURITY_LOCAL_SYSTEM_RID, + 0, 0, 0, 0, 0, 0, 0, + &pSidLocalSystem)) + { + if (EqualSid(pTokenUser->User.Sid, pSidLocalSystem)) { + fAdmin = TRUE; + } + + FreeSid(pSidLocalSystem); + } + + if ( pTokenUser ) + free(pTokenUser); + } } } free(psidAdmin); free(pszRefDomain); + + fTested = TRUE; } return fAdmin; diff --git a/src/WINNT/client_osi/osisleep.h b/src/WINNT/client_osi/osisleep.h index 0fb873d002..4bf61751d0 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 0bcfa6da38..e2dd99f4c3 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 */ diff --git a/src/WINNT/pthread/pthread.c b/src/WINNT/pthread/pthread.c index 33a17a4a03..4c72ab6c17 100644 --- a/src/WINNT/pthread/pthread.c +++ b/src/WINNT/pthread/pthread.c @@ -590,14 +590,11 @@ static void pthread_sync_terminate_thread(void) { (pthread_cache_done || pthread_once(&pthread_cache_once, create_once)); if (terminate_thread_handle == INVALID_HANDLE_VALUE) { - CHAR eventName[MAX_PATH]; - static eventCount = 0; - sprintf(eventName, "terminate_thread_wakeup_event %d::%d", _getpid(), eventCount++); - terminate_thread_wakeup_event = CreateEvent((LPSECURITY_ATTRIBUTES) 0, - TRUE, FALSE, (LPCTSTR) eventName); - terminate_thread_handle = CreateThread((LPSECURITY_ATTRIBUTES) 0, 0, - terminate_thread_routine, (LPVOID) 0, 0, - &terminate_thread_id); + terminate_thread_wakeup_event = CreateEvent((LPSECURITY_ATTRIBUTES) 0, + TRUE, FALSE, (LPCTSTR) 0); + terminate_thread_handle = CreateThread((LPSECURITY_ATTRIBUTES) 0, 0, + terminate_thread_routine, (LPVOID) 0, 0, + &terminate_thread_id); } else { SetEvent (terminate_thread_wakeup_event); } @@ -714,11 +711,8 @@ static cond_waiters_t *get_waiter() { if (queue_IsEmpty(&waiter_cache)) { new = (cond_waiters_t *) malloc(sizeof(cond_waiters_t)); if (new != NULL) { - CHAR eventName[MAX_PATH]; - static eventCount = 0; - sprintf(eventName, "cond_waiters_t %d::%d", _getpid(), eventCount++); - new->event = CreateEvent((LPSECURITY_ATTRIBUTES) 0, FALSE, - FALSE, (LPCTSTR) eventName); + new->event = CreateEvent((LPSECURITY_ATTRIBUTES) 0, FALSE, + FALSE, (LPCTSTR) 0); if (new->event == NULL) { free(new); new = NULL;