Windows: Redirector interface for afsd_service.exe

Over the last three years the afsd_service sources have been
gradually separated into distinct layers for the SMB server
and the AFS cache.  The eventual goal of this work was to
permit the addition of alternative interfaces to the cache
manager in parallel.

This patchset implements the first alternative interface,
a reverse ioctl model that communicates with a native IFS
redirector driver.  The driver will be submitted in a
subsequent patchset.

Although it is possible to run afsd_service with both the
SMB and RDR interfaces active at the same time.  In practice
it is somewhat impractical because it destroys the uniformity
of the \\AFS name space.  The RDR loads at boot time and claims
all of \\AFS.  The SMB interface if active at the same time
must use the old \\%HOSTNAME%-AFS.  As implemented, if the RDR
interface is functional the SMB interface is not started.  Only
if the RDR interface fails will the SMB interface be activated.

The afsd_service.exe maintains all of its primary responsibilities
for communicating with the AFS servers, processing callbacks,
enforcing permissions, handling afs path ioctls, Windows RPC
service simulation, and object management.  The biggest change
is in the cm_buf_t management.  Data is exchanged with the
RDR by passing control over cm_buf_t->data buffers in the form
of Windows File Extents.  This avoids data copies across a
communication channel which significantly improves performance
at a substantial complexity cost.

Credential management is switched from a Windows username binding
to a GUID binding where the GUIDs represent authentication groups
that are managed by the RDR.

This patchset includes additional changes to support integrated
logon in conjunction with the RDR.  In particular, adding support
for authentication groups.

Change-Id: I7135489421c67a429ec3b2acd4c8ae08b8329f6d
Reviewed-on: http://gerrit.openafs.org/5432
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Tested-by: Rod Widdowson <rdw@steadingsoftware.com>
Reviewed-by: Jeffrey Altman <jaltman@openafs.org>
Tested-by: Jeffrey Altman <jaltman@openafs.org>
This commit is contained in:
Jeffrey Altman 2011-09-15 01:11:15 -04:00 committed by Jeffrey Altman
parent f03cef68fb
commit b91d39edec
42 changed files with 12561 additions and 462 deletions

View File

@ -7,7 +7,7 @@
AFSDEV_AUXCDEFINES = $(AFSDEV_AUXCDEFINES) /D"_AFXDLL" /DSMB_UNICODE -I..\kfw\inc\loadfuncs \ AFSDEV_AUXCDEFINES = $(AFSDEV_AUXCDEFINES) /D"_AFXDLL" /DSMB_UNICODE -I..\kfw\inc\loadfuncs \
-I..\kfw\inc\krb5 -I..\kfw\inc\leash -I$(DESTDIR)\include\afs \ -I..\kfw\inc\krb5 -I..\kfw\inc\leash -I$(DESTDIR)\include\afs \
-I$(DESTDIR)\include\rx -I$(DESTDIR)\include\rx -I..\afsrdr\common -I..\afsrdr\user
AFSDEV_NETGUI = 1 AFSDEV_NETGUI = 1
RELDIR=WINNT\afsd RELDIR=WINNT\afsd
!INCLUDE ..\..\config\NTMakefile.$(SYS_NAME) !INCLUDE ..\..\config\NTMakefile.$(SYS_NAME)
@ -153,10 +153,26 @@ AFSDOBJS=\
$(OUT)\ms-wkssvc_s.obj \ $(OUT)\ms-wkssvc_s.obj \
$(OUT)\rpc_wkssvc.obj \ $(OUT)\rpc_wkssvc.obj \
$(OUT)\rpc_srvsvc.obj \ $(OUT)\rpc_srvsvc.obj \
$(OUT)\AFS_component_version_number.obj $(OUT)\AFS_component_version_number.obj \
$(OUT)\RDRInit.obj \
$(OUT)\RDRFunction.obj \
$(OUT)\RDRIoctl.obj \
$(OUT)\RDRPipe.obj
$(AFSDOBJS): $(AFSDOBJS):
$(OUT)\RDRInit.obj: ..\afsrdr\user\RDRInit.cpp ..\afsrdr\user\RDRPrototypes.h ..\afsrdr\user\RDRIoctl.h
$(CPP2OBJ) ..\afsrdr\user\RDRInit.cpp
$(OUT)\RDRFunction.obj: ..\afsrdr\user\RDRFunction.c ..\afsrdr\user\RDRPrototypes.h ..\afsrdr\user\RDRIoctl.h
$(C2OBJ) ..\afsrdr\user\RDRFunction.c
$(OUT)\RDRIoctl.obj: ..\afsrdr\user\RDRIoctl.c ..\afsrdr\user\RDRIoctl.h
$(C2OBJ) ..\afsrdr\user\RDRIoctl.c
$(OUT)\RDRPipe.obj: ..\afsrdr\user\RDRPipe.c ..\afsrdr\user\RDRPipe.h
$(C2OBJ) ..\afsrdr\user\RDRPipe.c
$(OUT)\cm_conn.obj: cm_conn.c $(OUT)\cm_conn.obj: cm_conn.c
$(C2OBJ) -DAFS_PTHREAD_ENV /Fo$@ $** $(C2OBJ) -DAFS_PTHREAD_ENV /Fo$@ $**
@ -317,7 +333,8 @@ LOGON_DLLSDKLIBS =\
activeds.lib \ activeds.lib \
user32.lib \ user32.lib \
userenv.lib \ userenv.lib \
shell32.lib shell32.lib \
rpcrt4.lib
$(LOGON_DLLFILE): $(LOGON_DLLOBJS) $(LOGON_DLLLIBS) $(LOGON_DLLFILE): $(LOGON_DLLOBJS) $(LOGON_DLLLIBS)
$(DLLGUILINK) $(LOGONLINKFLAGS) -def:afslogon.def $(LOGON_DLLSDKLIBS) $(DLLGUILINK) $(LOGONLINKFLAGS) -def:afslogon.def $(LOGON_DLLSDKLIBS)
@ -450,12 +467,14 @@ AFSD_EXELIBS =\
$(DESTDIR)\lib\afs\mtafsvldb.lib \ $(DESTDIR)\lib\afs\mtafsvldb.lib \
$(DESTDIR)\lib\afs\mtafsint.lib \ $(DESTDIR)\lib\afs\mtafsint.lib \
$(DESTDIR)\lib\afsrpc.lib \ $(DESTDIR)\lib\afsrpc.lib \
$(DESTDIR)\lib\afsrxkad.lib \
$(DESTDIR)\lib\afs\mtafsutil.lib \ $(DESTDIR)\lib\afs\mtafsutil.lib \
$(DESTDIR)\lib\afsauthent.lib \ $(DESTDIR)\lib\afsauthent.lib \
$(DESTDIR)\lib\libafsconf.lib \ $(DESTDIR)\lib\libafsconf.lib \
$(DESTDIR)\lib\afs\afsreg.lib \ $(DESTDIR)\lib\afs\afsreg.lib \
$(DESTDIR)\lib\afspthread.lib \ $(DESTDIR)\lib\afspthread.lib \
$(DESTDIR)\lib\afsroken.lib \ $(DESTDIR)\lib\afsroken.lib \
$(DESTDIR)\lib\afshcrypto.lib \
$(LANAHELPERLIB) $(LANAHELPERLIB)
$(AFSD_EXEFILE): $(OUT)\afsd.obj $(AFSDOBJS) $(OUT)\afsd.res $(RXOBJS) $(AFSD_EXELIBS) $(AFSD_EXEFILE): $(OUT)\afsd.obj $(AFSDOBJS) $(OUT)\afsd.res $(RXOBJS) $(AFSD_EXELIBS)

View File

@ -60,6 +60,7 @@ BOOL APIENTRY About(HWND, unsigned int, unsigned int, long);
#include "cm_memmap.h" #include "cm_memmap.h"
#include "cm_freelance.h" #include "cm_freelance.h"
#include "cm_performance.h" #include "cm_performance.h"
#include "cm_rdr.h"
#include "afsd_init.h" #include "afsd_init.h"
#include "afsd_eventlog.h" #include "afsd_eventlog.h"

View File

@ -103,9 +103,10 @@ BOOL reportSessionStartups = FALSE;
cm_initparams_v1 cm_initParams; cm_initparams_v1 cm_initParams;
clientchar_t *cm_sysName = 0;
unsigned int cm_sysNameCount = 0; unsigned int cm_sysNameCount = 0;
clientchar_t *cm_sysNameList[MAXNUMSYSNAMES]; clientchar_t *cm_sysNameList[MAXNUMSYSNAMES];
unsigned int cm_sysName64Count = 0;
clientchar_t *cm_sysName64List[MAXNUMSYSNAMES];
DWORD TraceOption = 0; DWORD TraceOption = 0;
@ -917,12 +918,15 @@ afsd_InitCM(char **reasonP)
for ( i=0; i < MAXNUMSYSNAMES; i++ ) { for ( i=0; i < MAXNUMSYSNAMES; i++ ) {
cm_sysNameList[i] = osi_Alloc(MAXSYSNAME * sizeof(clientchar_t)); cm_sysNameList[i] = osi_Alloc(MAXSYSNAME * sizeof(clientchar_t));
cm_sysNameList[i][0] = '\0'; cm_sysNameList[i][0] = '\0';
cm_sysName64List[i] = osi_Alloc(MAXSYSNAME * sizeof(clientchar_t));
cm_sysName64List[i][0] = '\0';
} }
cm_sysName = cm_sysNameList[0];
/* Process SysName lists from the registry */
{ {
clientchar_t *p, *q; clientchar_t *p, *q;
clientchar_t * cbuf = (clientchar_t *) buf; clientchar_t * cbuf = (clientchar_t *) buf;
dummyLen = sizeof(buf); dummyLen = sizeof(buf);
code = RegQueryValueExW(parmKey, L"SysName", NULL, NULL, (LPBYTE) cbuf, &dummyLen); code = RegQueryValueExW(parmKey, L"SysName", NULL, NULL, (LPBYTE) cbuf, &dummyLen);
if (code != ERROR_SUCCESS || !cbuf[0]) { if (code != ERROR_SUCCESS || !cbuf[0]) {
@ -934,7 +938,7 @@ afsd_InitCM(char **reasonP)
cm_ClientStrCpy(cbuf, lengthof(buf), _C("x86_win32 i386_w2k i386_nt40")); cm_ClientStrCpy(cbuf, lengthof(buf), _C("x86_win32 i386_w2k i386_nt40"));
#endif #endif
} }
afsi_log("Sys name %S", cbuf); afsi_log("Sys name list: %S", cbuf);
/* breakup buf into individual search string entries */ /* breakup buf into individual search string entries */
for (p = q = cbuf; p < cbuf + dummyLen; p++) { for (p = q = cbuf; p < cbuf + dummyLen; p++) {
@ -944,16 +948,49 @@ afsd_InitCM(char **reasonP)
cm_sysNameCount++; cm_sysNameCount++;
do { do {
if (*p == '\0') if (*p == '\0')
goto done_sysname; goto done_sysname32;
p++; p++;
} while (*p == '\0' || isspace(*p)); } while (*p == '\0' || isspace(*p));
q = p; q = p;
p--; p--;
} }
} }
done_sysname32:
;
#ifdef _WIN64
/*
* If there is a 64-bit list, process it. Otherwise, we will leave
* it undefined which implies that the 32-bit list be used for both.
* The 64-bit list is only used for the native file system driver.
* The SMB redirector interface does not provide any means of indicating
* the source of the request.
*/
dummyLen = sizeof(buf);
code = RegQueryValueExW(parmKey, L"SysName64", NULL, NULL, (LPBYTE) cbuf, &dummyLen);
if (code == ERROR_SUCCESS && cbuf[0]) {
afsi_log("Sys name 64 list: %S", cbuf);
/* breakup buf into individual search string entries */
for (p = q = cbuf; p < cbuf + dummyLen; p++) {
if (*p == '\0' || iswspace(*p)) {
memcpy(cm_sysName64List[cm_sysName64Count],q,(p-q) * sizeof(clientchar_t));
cm_sysName64List[cm_sysName64Count][p-q] = '\0';
cm_sysName64Count++;
do {
if (*p == '\0')
goto done_sysname64;
p++;
} while (*p == '\0' || isspace(*p));
q = p;
p--;
}
}
}
done_sysname64:
;
#endif
} }
done_sysname:
cm_ClientStrCpy(cm_sysName, MAXSYSNAME, cm_sysNameList[0]);
dummyLen = sizeof(cryptall); dummyLen = sizeof(cryptall);
code = RegQueryValueEx(parmKey, "SecurityLevel", NULL, NULL, code = RegQueryValueEx(parmKey, "SecurityLevel", NULL, NULL,
@ -1527,11 +1564,11 @@ int afsd_InitSMB(char **reasonP, void *aMBfunc)
} }
if ( smb_Enabled ) { if ( smb_Enabled ) {
/* Do this last so that we don't handle requests before init is done. /* Do this last so that we don't handle requests before init is done.
* Here we initialize the SMB listener. * Here we initialize the SMB listener.
*/ */
smb_Init(afsd_logp, smb_UseV3, numSvThreads, aMBfunc); smb_Init(afsd_logp, smb_UseV3, numSvThreads, aMBfunc);
afsi_log("smb_Init complete"); afsi_log("smb_Init complete");
} else { } else {
afsi_log("smb_Init skipped"); afsi_log("smb_Init skipped");
} }

View File

@ -1327,6 +1327,21 @@ afsd_Main(DWORD argc, LPTSTR *argv)
/* Notify any volume status handlers that the cache manager has started */ /* Notify any volume status handlers that the cache manager has started */
cm_VolStatus_Service_Started(); cm_VolStatus_Service_Started();
code = RDR_Initialize();
RDR_Initialized = !code;
afsi_log("RDR_Initialize returned: (code = %d)", code);
if (RDR_Initialized) {
if (cm_sysNameCount)
RDR_SysName( AFS_SYSNAME_ARCH_32BIT, cm_sysNameCount, cm_sysNameList );
#ifdef _WIN64
if (cm_sysName64Count)
RDR_SysName( AFS_SYSNAME_ARCH_64BIT, cm_sysName64Count, cm_sysName64List );
else if (cm_sysNameCount)
RDR_SysName( AFS_SYSNAME_ARCH_64BIT, cm_sysNameCount, cm_sysNameList );
#endif
}
/* /*
* Set the default for the SMB interface based upon the state of the * Set the default for the SMB interface based upon the state of the
* Redirector interface. * Redirector interface.
@ -1464,11 +1479,15 @@ afsd_Main(DWORD argc, LPTSTR *argv)
DismountGlobalDrives(); DismountGlobalDrives();
afsi_log("Global Drives dismounted"); afsi_log("Global Drives dismounted");
if (RDR_Initialized) {
RDR_ShutdownNotify();
cm_VolStatus_SetRDRNotifications(FALSE);
afsi_log("RDR notified of shutdown");
}
smb_Shutdown(); smb_Shutdown();
afsi_log("smb shutdown complete"); afsi_log("smb shutdown complete");
RpcShutdown();
cm_ReleaseAllLocks(); cm_ReleaseAllLocks();
cm_DaemonShutdown(); cm_DaemonShutdown();
@ -1479,8 +1498,15 @@ afsd_Main(DWORD argc, LPTSTR *argv)
afsd_ShutdownCM(); afsd_ShutdownCM();
RpcShutdown();
cm_ShutdownMappedMemory(); cm_ShutdownMappedMemory();
if (RDR_Initialized) {
RDR_ShutdownFinal();
afsi_log("RDR shutdown complete");
}
rx_Finalize(); rx_Finalize();
afsi_log("rx finalization complete"); afsi_log("rx finalization complete");

View File

@ -11,16 +11,20 @@
#include <afs/param.h> #include <afs/param.h>
#include <roken.h> #include <roken.h>
#include "afslogon.h"
#include <io.h> #include <io.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/types.h> #include <sys/types.h>
#include <fcntl.h> #include <fcntl.h>
#include <winsock2.h> #include <winsock2.h>
#include <winioctl.h>
#define SECURITY_WIN32
#include <sspi.h>
#include <lm.h> #include <lm.h>
#include <nb30.h> #include <nb30.h>
#include <sddl.h>
#include "afslogon.h"
#include <afs/stds.h> #include <afs/stds.h>
#include <afs/pioctl_nt.h> #include <afs/pioctl_nt.h>
@ -810,7 +814,8 @@ UnicodeStringToANSI(UNICODE_STRING uInputString, LPSTR lpszOutputString, int nOu
return FALSE; return FALSE;
} // UnicodeStringToANSI } // UnicodeStringToANSI
DWORD APIENTRY NPLogonNotify( DWORD APIENTRY
NPLogonNotify(
PLUID lpLogonId, PLUID lpLogonId,
LPCWSTR lpAuthentInfoType, LPCWSTR lpAuthentInfoType,
LPVOID lpAuthentInfo, LPVOID lpAuthentInfo,
@ -850,6 +855,8 @@ DWORD APIENTRY NPLogonNotify(
int retryInterval; int retryInterval;
int sleepInterval; int sleepInterval;
CtxtHandle LogonContext;
/* Are we interactive? */ /* Are we interactive? */
interactive = (wcsicmp(lpStationName, L"WinSta0") == 0); interactive = (wcsicmp(lpStationName, L"WinSta0") == 0);
@ -952,7 +959,7 @@ DWORD APIENTRY NPLogonNotify(
/* Get cell name if doing integrated logon. /* Get cell name if doing integrated logon.
We might overwrite this if we are logging into an AD realm and we find out that We might overwrite this if we are logging into an AD realm and we find out that
the user's home dir is in some other cell. */ the user's home dir is in some other cell. */
DebugEvent("About to call cm_GetRootCellName()"); DebugEvent0("About to call cm_GetRootCellName()");
code = cm_GetRootCellName(cell); code = cm_GetRootCellName(cell);
if (code < 0) { if (code < 0) {
DebugEvent0("Unable to obtain Root Cell"); DebugEvent0("Unable to obtain Root Cell");
@ -972,7 +979,8 @@ DWORD APIENTRY NPLogonNotify(
} }
} }
/* loop until AFS is started. */ AFSCreatePAG(lpLogonId);
if (afsWillAutoStart) { if (afsWillAutoStart) {
/* /*
* If the service is configured for auto start but hasn't started yet, * If the service is configured for auto start but hasn't started yet,
@ -981,12 +989,12 @@ DWORD APIENTRY NPLogonNotify(
if (!(IsServiceRunning() || IsServiceStartPending())) if (!(IsServiceRunning() || IsServiceStartPending()))
StartTheService(); StartTheService();
/* loop until AFS is started or fails. */
while ( IsServiceStartPending() ) { while ( IsServiceStartPending() ) {
Sleep(10); Sleep(10);
} }
while (IsServiceRunning() && code != KTC_NOCM && code != KTC_NOCMRPC && code != KTC_NOCELL) { while (IsServiceRunning() && code != KTC_NOCM && code != KTC_NOCMRPC && code != KTC_NOCELL) {
DebugEvent("while(autostart) LogonOption[%x], Service AutoStart[%d]", DebugEvent("while(autostart) LogonOption[%x], Service AutoStart[%d]",
opt.LogonOption,afsWillAutoStart); opt.LogonOption,afsWillAutoStart);
@ -1004,6 +1012,9 @@ DWORD APIENTRY NPLogonNotify(
/* if Integrated Logon */ /* if Integrated Logon */
if (ISLOGONINTEGRATED(opt.LogonOption)) if (ISLOGONINTEGRATED(opt.LogonOption))
{ {
LogonSSP(lpLogonId, &LogonContext);
ImpersonateSecurityContext(&LogonContext);
if ( KFW_is_available() ) { if ( KFW_is_available() ) {
SetEnvironmentVariable(DO_NOT_REGISTER_VARNAME, ""); SetEnvironmentVariable(DO_NOT_REGISTER_VARNAME, "");
if (opt.realm) { if (opt.realm) {
@ -1077,6 +1088,10 @@ DWORD APIENTRY NPLogonNotify(
DebugEvent("AFS AfsLogon - (INTEGRATED only)ka_UserAuthenticateGeneral2 Code[%x] uname[%s] smbname=[%s] Cell[%s] PwExp=[%d] Reason=[%s]", DebugEvent("AFS AfsLogon - (INTEGRATED only)ka_UserAuthenticateGeneral2 Code[%x] uname[%s] smbname=[%s] Cell[%s] PwExp=[%d] Reason=[%s]",
code,uname,opt.smbName,cell,pw_exp,reason?reason:""); code,uname,opt.smbName,cell,pw_exp,reason?reason:"");
} }
RevertSecurityContext(&LogonContext);
DeleteSecurityContext(&LogonContext);
if ( code && code != KTC_NOCM && code != KTC_NOCMRPC && !lowercased_name ) { if ( code && code != KTC_NOCM && code != KTC_NOCMRPC && !lowercased_name ) {
for ( ctemp = uname; *ctemp ; ctemp++) { for ( ctemp = uname; *ctemp ; ctemp++) {
*ctemp = tolower(*ctemp); *ctemp = tolower(*ctemp);
@ -1128,8 +1143,8 @@ DWORD APIENTRY NPLogonNotify(
Sleep(sleepInterval * 1000); Sleep(sleepInterval * 1000);
retryInterval -= sleepInterval; retryInterval -= sleepInterval;
} }
DebugEvent0("while loop exited");
} }
DebugEvent0("while loop exited");
/* remove any kerberos 5 tickets currently held by the SYSTEM account /* remove any kerberos 5 tickets currently held by the SYSTEM account
* for this user * for this user

View File

@ -26,7 +26,6 @@ SOFTWARE.
/* We only support VC 1200 and above anyway */ /* We only support VC 1200 and above anyway */
#pragma once #pragma once
#include <windows.h>
#include <objbase.h> #include <objbase.h>
#include <npapi.h> #include <npapi.h>
#if (_WIN32_WINNT < 0x0501) #if (_WIN32_WINNT < 0x0501)
@ -132,6 +131,10 @@ DWORD GetAdHomePath(char * homePath, size_t homePathLen, PLUID lpLogonId, LogonO
DWORD QueryAdHomePathFromSid(char * homePath, size_t homePathLen, PSID psid, PWSTR domain); DWORD QueryAdHomePathFromSid(char * homePath, size_t homePathLen, PSID psid, PWSTR domain);
BOOL GetLocalShortDomain(PWSTR Domain, DWORD cbDomain); BOOL GetLocalShortDomain(PWSTR Domain, DWORD cbDomain);
void AFSCreatePAG(PLUID lpLogonId);
DWORD LogonSSP(PLUID lpLogonId, PCtxtHandle outCtx);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -45,6 +45,7 @@
#define LOCK_HIERARCHY_IGNORE 0 #define LOCK_HIERARCHY_IGNORE 0
#define LOCK_HIERARCHY_RDR_GLOBAL 10
#define LOCK_HIERARCHY_SMB_STARTED 20 #define LOCK_HIERARCHY_SMB_STARTED 20
#define LOCK_HIERARCHY_SMB_LISTENER 30 #define LOCK_HIERARCHY_SMB_LISTENER 30
#define LOCK_HIERARCHY_SMB_DIRWATCH 40 #define LOCK_HIERARCHY_SMB_DIRWATCH 40
@ -87,5 +88,8 @@
#define LOCK_HIERARCHY_AFSDBSBMT_GLOBAL 1000 #define LOCK_HIERARCHY_AFSDBSBMT_GLOBAL 1000
#define LOCK_HIERARCHY_TOKEN_EVENT_GLOBAL 2000 #define LOCK_HIERARCHY_TOKEN_EVENT_GLOBAL 2000
#define LOCK_HIERARCHY_SYSCFG_GLOBAL 3000 #define LOCK_HIERARCHY_SYSCFG_GLOBAL 3000
#define LOCK_HIERARCHY_RDR_EXTENTS 0
#endif /* OPENAFS_WINNT_AFSD_CM_H */ #endif /* OPENAFS_WINNT_AFSD_CM_H */

View File

@ -338,6 +338,9 @@ void cm_InvalidateACLUser(cm_scache_t *scp, cm_user_t *userp)
aclp->userp = NULL; aclp->userp = NULL;
aclp->backp = (struct cm_scache *) 0; aclp->backp = (struct cm_scache *) 0;
found = 1; found = 1;
if (RDR_Initialized && cm_HaveCallback(scp))
RDR_InvalidateObject(scp->fid.cell, scp->fid.volume, scp->fid.vnode, scp->fid.unique,
scp->fid.hash, scp->fileType, AFS_INVALIDATE_CREDS);
break; break;
} }
} }
@ -351,6 +354,7 @@ void cm_InvalidateACLUser(cm_scache_t *scp, cm_user_t *userp)
void void
cm_ResetACLCache(cm_cell_t *cellp, cm_user_t *userp) cm_ResetACLCache(cm_cell_t *cellp, cm_user_t *userp)
{ {
cm_volume_t *volp, *nextVolp;
cm_scache_t *scp, *nextScp; cm_scache_t *scp, *nextScp;
afs_uint32 hash; afs_uint32 hash;
@ -369,6 +373,40 @@ cm_ResetACLCache(cm_cell_t *cellp, cm_user_t *userp)
} }
} }
lock_ReleaseRead(&cm_scacheLock); lock_ReleaseRead(&cm_scacheLock);
if (RDR_Initialized) {
lock_ObtainRead(&cm_volumeLock);
for (hash = 0; hash < cm_data.volumeHashTableSize; hash++) {
for ( volp = cm_data.volumeRWIDHashTablep[hash]; volp; volp = nextVolp) {
nextVolp = volp->vol[RWVOL].nextp;
if ((cellp == NULL || cellp->cellID == volp->cellp->cellID) &&
volp->vol[RWVOL].ID) {
lock_ReleaseRead(&cm_volumeLock);
RDR_InvalidateVolume(volp->cellp->cellID, volp->vol[RWVOL].ID, AFS_INVALIDATE_CREDS);
lock_ObtainRead(&cm_volumeLock);
}
}
for ( volp = cm_data.volumeROIDHashTablep[hash]; volp; volp = nextVolp) {
nextVolp = volp->vol[ROVOL].nextp;
if ((cellp == NULL || cellp->cellID == volp->cellp->cellID) &&
volp->vol[ROVOL].ID) {
lock_ReleaseRead(&cm_volumeLock);
RDR_InvalidateVolume(volp->cellp->cellID, volp->vol[ROVOL].ID, AFS_INVALIDATE_CREDS);
lock_ObtainRead(&cm_volumeLock);
}
}
for ( volp = cm_data.volumeBKIDHashTablep[hash]; volp; volp = nextVolp) {
nextVolp = volp->vol[BACKVOL].nextp;
if ((cellp == NULL || cellp->cellID == volp->cellp->cellID) &&
volp->vol[BACKVOL].ID) {
lock_ReleaseRead(&cm_volumeLock);
RDR_InvalidateVolume(volp->cellp->cellID, volp->vol[BACKVOL].ID, AFS_INVALIDATE_CREDS);
lock_ObtainRead(&cm_volumeLock);
}
}
}
lock_ReleaseRead(&cm_volumeLock);
}
} }

File diff suppressed because it is too large Load Diff

View File

@ -42,8 +42,8 @@ extern int buf_cacheType;
/* represents a single buffer */ /* represents a single buffer */
typedef struct cm_buf { typedef struct cm_buf {
osi_queue_t q; /* queue of all zero-refcount buffers */ osi_queue_t q; /* queue: buf_freeList and buf_redirList */
afs_uint32 qFlags; /* queue/hash state flags - buf_globalLock */ afs_uint32 qFlags; /* queue/hash state flags - buf_globalLock */
afs_uint32 magic; afs_uint32 magic;
struct cm_buf *allp; /* next in all list */ struct cm_buf *allp; /* next in all list */
struct cm_buf *hashp; /* hash bucket pointer */ struct cm_buf *hashp; /* hash bucket pointer */
@ -77,7 +77,7 @@ typedef struct cm_buf {
afs_uint32 waitRequests; /* num of thread wait requests */ afs_uint32 waitRequests; /* num of thread wait requests */
afs_uint32 dirty_offset; /* offset from beginning of buffer containing dirty bytes */ afs_uint32 dirty_offset; /* offset from beginning of buffer containing dirty bytes */
afs_uint32 dirty_length; /* number of dirty bytes within the buffer */ afs_uint32 dirty_length; /* number of dirty bytes within the buffer */
#ifdef DISKCACHE95 #ifdef DISKCACHE95
cm_diskcache_t *dcp; /* diskcache structure */ cm_diskcache_t *dcp; /* diskcache structure */
@ -88,8 +88,17 @@ typedef struct cm_buf {
#else #else
void * dummy; void * dummy;
#endif #endif
/* redirector state - protected by buf_globalLock */
osi_queue_t redirq; /* queue: cm_scache_t redirList */
time_t redirLastAccess;/* last time redir accessed the buffer */
time_t redirReleaseRequested;
unsigned char md5cksum[16]; /* md5 checksum of the block pointed to by datap */
} cm_buf_t; } cm_buf_t;
#define redirq_to_cm_buf_t(q) ((q) ? (cm_buf_t *)((char *) (q) - offsetof(cm_buf_t, redirq)) : NULL)
/* values for cmFlags */ /* values for cmFlags */
#define CM_BUF_CMFETCHING 1 /* fetching this buffer */ #define CM_BUF_CMFETCHING 1 /* fetching this buffer */
#define CM_BUF_CMSTORING 2 /* storing this buffer */ #define CM_BUF_CMSTORING 2 /* storing this buffer */
@ -132,8 +141,6 @@ extern long buf_Init(int newFile, cm_buf_ops_t *, afs_uint64 nbuffers);
extern void buf_Shutdown(void); extern void buf_Shutdown(void);
extern long buf_CountFreeList(void);
#ifdef DEBUG_REFCOUNT #ifdef DEBUG_REFCOUNT
extern void buf_ReleaseDbg(cm_buf_t *, char *, long); extern void buf_ReleaseDbg(cm_buf_t *, char *, long);
@ -212,10 +219,51 @@ extern long buf_DirtyBuffersExist(cm_fid_t * fidp);
extern long buf_CleanDirtyBuffers(cm_scache_t *scp); extern long buf_CleanDirtyBuffers(cm_scache_t *scp);
extern long buf_RDRBuffersExist(cm_fid_t *fidp);
extern long buf_ClearRDRFlag(cm_scache_t *scp, char * reason);
extern long buf_ForceDataVersion(cm_scache_t * scp, afs_uint64 fromVersion, afs_uint64 toVersion); extern long buf_ForceDataVersion(cm_scache_t * scp, afs_uint64 fromVersion, afs_uint64 toVersion);
extern int cm_DumpBufHashTable(FILE *outputFile, char *cookie, int lock); extern int cm_DumpBufHashTable(FILE *outputFile, char *cookie, int lock);
extern void buf_ComputeCheckSum(cm_buf_t *bp);
extern int buf_ValidateCheckSum(cm_buf_t *bp);
extern const char *buf_HexCheckSum(cm_buf_t * bp);
extern afs_uint32
buf_RDRShakeSomeExtentsFree(cm_req_t *reqp, afs_uint32 oneFid, afs_uint32 minage);
extern afs_uint32
buf_RDRShakeAnExtentFree(cm_buf_t *bufp, cm_req_t *reqp);
extern afs_uint32
buf_RDRShakeFileExtentsFree(cm_scache_t *scp, cm_req_t *reqp);
extern void
buf_InsertToRedirQueue(cm_scache_t *scp, cm_buf_t *bufp);
extern void
buf_RemoveFromRedirQueue(cm_scache_t *scp, cm_buf_t *bufp);
extern void
buf_MoveToHeadOfRedirQueue(cm_scache_t *scp, cm_buf_t *bufp);
#ifdef _M_IX86
#define buf_IncrementRedirCount() InterlockedIncrement(&cm_data.buf_redirCount)
#define buf_DecrementRedirCount() InterlockedDecrement(&cm_data.buf_redirCount)
#define buf_IncrementFreeCount() InterlockedIncrement(&cm_data.buf_freeCount)
#define buf_DecrementFreeCount() InterlockedDecrement(&cm_data.buf_freeCount)
#else
#define buf_IncrementRedirCount() InterlockedIncrement64(&cm_data.buf_redirCount)
#define buf_DecrementRedirCount() InterlockedDecrement64(&cm_data.buf_redirCount)
#define buf_IncrementFreeCount() InterlockedIncrement64(&cm_data.buf_freeCount)
#define buf_DecrementFreeCount() InterlockedDecrement64(&cm_data.buf_freeCount)
#endif
/* error codes */ /* error codes */
#define CM_BUF_EXISTS 1 /* buffer exists, and shouldn't */ #define CM_BUF_EXISTS 1 /* buffer exists, and shouldn't */
#endif /* OPENAFS_WINNT_AFSD_BUF_H */ #endif /* OPENAFS_WINNT_AFSD_BUF_H */

View File

@ -197,6 +197,10 @@ void cm_RevokeCallback(struct rx_call *callp, cm_cell_t * cellp, AFSFid *fidp)
osi_Log4(afsd_logp, "RevokeCallback Discarding SCache scp 0x%p vol %u vn %u uniq %u", osi_Log4(afsd_logp, "RevokeCallback Discarding SCache scp 0x%p vol %u vn %u uniq %u",
scp, scp->fid.volume, scp->fid.vnode, scp->fid.unique); scp, scp->fid.volume, scp->fid.vnode, scp->fid.unique);
if (RDR_Initialized)
RDR_InvalidateObject(scp->fid.cell, scp->fid.volume, scp->fid.vnode, scp->fid.unique,
scp->fid.hash, scp->fileType, AFS_INVALIDATE_CALLBACK);
lock_ObtainWrite(&scp->rw); lock_ObtainWrite(&scp->rw);
cm_DiscardSCache(scp); cm_DiscardSCache(scp);
lock_ReleaseWrite(&scp->rw); lock_ReleaseWrite(&scp->rw);
@ -241,7 +245,7 @@ void cm_RevokeVolumeCallback(struct rx_call *callp, cm_cell_t *cellp, AFSFid *fi
cm_scache_t *scp; cm_scache_t *scp;
cm_fid_t tfid; cm_fid_t tfid;
osi_Log1(afsd_logp, "RevokeVolumeCallback vol %d", fidp->Volume); osi_Log1(afsd_logp, "RevokeVolumeCallback vol %u", fidp->Volume);
/* do this first, so that if we're executing a callback granting call /* do this first, so that if we're executing a callback granting call
* at this moment, we kill it before it can be merged in. Otherwise, * at this moment, we kill it before it can be merged in. Otherwise,
@ -251,7 +255,6 @@ void cm_RevokeVolumeCallback(struct rx_call *callp, cm_cell_t *cellp, AFSFid *fi
tfid.cell = cellp ? cellp->cellID : 0; tfid.cell = cellp ? cellp->cellID : 0;
tfid.volume = fidp->Volume; tfid.volume = fidp->Volume;
tfid.vnode = tfid.unique = 0; tfid.vnode = tfid.unique = 0;
cm_RecordRacingRevoke(&tfid, CM_RACINGFLAG_CANCELVOL); cm_RecordRacingRevoke(&tfid, CM_RACINGFLAG_CANCELVOL);
lock_ObtainWrite(&cm_scacheLock); lock_ObtainWrite(&cm_scacheLock);
@ -265,11 +268,19 @@ void cm_RevokeVolumeCallback(struct rx_call *callp, cm_cell_t *cellp, AFSFid *fi
lock_ReleaseWrite(&cm_scacheLock); lock_ReleaseWrite(&cm_scacheLock);
lock_ObtainWrite(&scp->rw); lock_ObtainWrite(&scp->rw);
osi_Log4(afsd_logp, "RevokeVolumeCallback Discarding SCache scp 0x%p vol %u vn %u uniq %u", osi_Log5(afsd_logp, "RevokeVolumeCallback Discarding SCache scp 0x%p vol %u vn %u uniq %u",
scp, scp->fid.volume, scp->fid.vnode, scp->fid.unique); scp, scp->fid.cell, scp->fid.volume, scp->fid.vnode, scp->fid.unique);
osi_Log2(afsd_logp, ".... dv 0x%x:%x",
(afs_uint32)((scp->dataVersion >> 32) & 0xFFFFFFFF),
(afs_uint32)(scp->dataVersion & 0xFFFFFFFF));
cm_DiscardSCache(scp); cm_DiscardSCache(scp);
lock_ReleaseWrite(&scp->rw); lock_ReleaseWrite(&scp->rw);
if (RDR_Initialized)
RDR_InvalidateObject(scp->fid.cell, scp->fid.volume, scp->fid.vnode, scp->fid.unique,
scp->fid.hash, scp->fileType, AFS_INVALIDATE_CALLBACK);
cm_CallbackNotifyChange(scp); cm_CallbackNotifyChange(scp);
lock_ObtainWrite(&cm_scacheLock); lock_ObtainWrite(&cm_scacheLock);
cm_ReleaseSCacheNoLock(scp); cm_ReleaseSCacheNoLock(scp);
@ -281,6 +292,9 @@ void cm_RevokeVolumeCallback(struct rx_call *callp, cm_cell_t *cellp, AFSFid *fi
lock_ReleaseWrite(&cm_scacheLock); lock_ReleaseWrite(&cm_scacheLock);
if (cellp && RDR_Initialized)
RDR_InvalidateVolume(cellp->cellID, fidp->Volume, AFS_INVALIDATE_CALLBACK);
osi_Log1(afsd_logp, "RevokeVolumeCallback Complete vol %d", fidp->Volume); osi_Log1(afsd_logp, "RevokeVolumeCallback Complete vol %d", fidp->Volume);
} }
@ -1063,8 +1077,12 @@ SRXAFSCB_InitCallBackState3(struct rx_call *callp, afsUUID* serverUuid)
} }
} }
lock_ReleaseWrite(&scp->rw); lock_ReleaseWrite(&scp->rw);
if (discarded) if (discarded) {
cm_CallbackNotifyChange(scp); cm_CallbackNotifyChange(scp);
if (RDR_Initialized)
RDR_InvalidateObject(scp->fid.cell, scp->fid.volume, scp->fid.vnode, scp->fid.unique,
scp->fid.hash, scp->fileType, AFS_INVALIDATE_EXPIRED);
}
lock_ObtainWrite(&cm_scacheLock); lock_ObtainWrite(&cm_scacheLock);
cm_ReleaseSCacheNoLock(scp); cm_ReleaseSCacheNoLock(scp);
@ -1557,7 +1575,8 @@ int cm_HaveCallback(cm_scache_t *scp)
break; break;
} }
} }
if (!haveCB && if (cm_readonlyVolumeVersioning &&
!haveCB &&
volp->creationDateRO == scp->volumeCreationDate && volp->creationDateRO == scp->volumeCreationDate &&
volp->cbServerpRO != NULL) { volp->cbServerpRO != NULL) {
haveCB = 1; haveCB = 1;
@ -1699,6 +1718,9 @@ void cm_EndCallbackGrantingCall(cm_scache_t *scp, cm_callbackRequest_t *cbrp,
cm_DiscardSCache(scp); cm_DiscardSCache(scp);
lock_ReleaseWrite(&scp->rw); lock_ReleaseWrite(&scp->rw);
cm_CallbackNotifyChange(scp); cm_CallbackNotifyChange(scp);
if (RDR_Initialized)
RDR_InvalidateObject(scp->fid.cell, scp->fid.volume, scp->fid.vnode, scp->fid.unique,
scp->fid.hash, scp->fileType, AFS_INVALIDATE_CALLBACK);
lock_ObtainWrite(&scp->rw); lock_ObtainWrite(&scp->rw);
} else { } else {
if (scp && scp->flags & CM_SCACHEFLAG_PURERO) { if (scp && scp->flags & CM_SCACHEFLAG_PURERO) {
@ -1993,6 +2015,10 @@ void cm_CheckCBExpiration(void)
cm_DiscardSCache(scp); cm_DiscardSCache(scp);
lock_ReleaseWrite(&scp->rw); lock_ReleaseWrite(&scp->rw);
if (RDR_Initialized)
RDR_InvalidateObject(scp->fid.cell, scp->fid.volume, scp->fid.vnode, scp->fid.unique,
scp->fid.hash, scp->fileType, AFS_INVALIDATE_EXPIRED);
cm_CallbackNotifyChange(scp); cm_CallbackNotifyChange(scp);
scp_complete: scp_complete:

View File

@ -79,4 +79,5 @@ extern afs_int32 cm_OfflineROIsValid;
extern afs_int32 cm_giveUpAllCBs; extern afs_int32 cm_giveUpAllCBs;
extern afs_int32 cm_shutdown; extern afs_int32 cm_shutdown;
#endif /* OPENAFS_WINNT_AFSD_CM_CALLBACK_H */ #endif /* OPENAFS_WINNT_AFSD_CM_CALLBACK_H */

View File

@ -156,7 +156,7 @@ void cm_InitConn(void)
if (HardDeadtimeout == 0) { if (HardDeadtimeout == 0) {
HardDeadtimeout = (unsigned short) (RDRtimeout > 125 ? 120 : (RDRtimeout - 5)); HardDeadtimeout = (unsigned short) (RDRtimeout > 125 ? 120 : (RDRtimeout - 5));
afsi_log("HardDeadTimeout is %d", HardDeadtimeout); afsi_log("HardDeadTimeout is %d", HardDeadtimeout);
} }
if (IdleDeadtimeout == 0) { if (IdleDeadtimeout == 0) {
IdleDeadtimeout = (unsigned short) ConnDeadtimeout; IdleDeadtimeout = (unsigned short) ConnDeadtimeout;
afsi_log("IdleDeadTimeout is %d", IdleDeadtimeout); afsi_log("IdleDeadTimeout is %d", IdleDeadtimeout);
@ -696,15 +696,23 @@ cm_Analyze(cm_conn_t *connp, cm_user_t *userp, cm_req_t *reqp,
lock_ReleaseWrite(&cm_scacheLock); lock_ReleaseWrite(&cm_scacheLock);
cm_LockMarkSCacheLost(scp); cm_LockMarkSCacheLost(scp);
lock_ReleaseWrite(&scp->rw); lock_ReleaseWrite(&scp->rw);
if (RDR_Initialized)
RDR_InvalidateObject(scp->fid.cell, scp->fid.volume, scp->fid.vnode, scp->fid.unique,
scp->fid.hash, scp->fileType, AFS_INVALIDATE_DELETED);
cm_ReleaseSCache(scp); cm_ReleaseSCache(scp);
if (pscp) { if (pscp) {
if (cm_HaveCallback(pscp)) { if (cm_HaveCallback(pscp)) {
lock_ObtainWrite(&pscp->rw); lock_ObtainWrite(&pscp->rw);
cm_DiscardSCache(pscp); cm_DiscardSCache(pscp);
lock_ReleaseWrite(&pscp->rw); lock_ReleaseWrite(&pscp->rw);
}
cm_ReleaseSCache(pscp); if (RDR_Initialized)
RDR_InvalidateObject(pscp->fid.cell, pscp->fid.volume, pscp->fid.vnode, pscp->fid.unique,
pscp->fid.hash, pscp->fileType, AFS_INVALIDATE_EXPIRED);
}
cm_ReleaseSCache(pscp);
} }
} }
} else { } else {

View File

@ -53,8 +53,8 @@ typedef struct cm_conn {
* to the cache manager functions. * to the cache manager functions.
*/ */
typedef struct cm_req { typedef struct cm_req {
DWORD startTime; /* Quit before RDR times us out */ DWORD startTime; /* GetTickCount() when this struct was initialized */
int rpcError; /* RPC error code */ int rpcError; /* RPC error code */
int volumeError; /* volume error code */ int volumeError; /* volume error code */
int accessError; /* access error code */ int accessError; /* access error code */
struct cm_server * tokenIdleErrorServp; /* server that reported a token/idle error other than expired */ struct cm_server * tokenIdleErrorServp; /* server that reported a token/idle error other than expired */

View File

@ -40,6 +40,7 @@ long cm_daemonTokenCheckInterval = 180;
long cm_daemonCheckOfflineVolInterval = 600; long cm_daemonCheckOfflineVolInterval = 600;
long cm_daemonPerformanceTuningInterval = 0; long cm_daemonPerformanceTuningInterval = 0;
long cm_daemonRankServerInterval = 600; long cm_daemonRankServerInterval = 600;
long cm_daemonRDRShakeExtentsInterval = 0;
osi_rwlock_t cm_daemonLock; osi_rwlock_t cm_daemonLock;
@ -164,7 +165,8 @@ void cm_BkgDaemon(void * parm)
case CM_ERROR_ALLDOWN: case CM_ERROR_ALLDOWN:
case CM_ERROR_ALLOFFLINE: case CM_ERROR_ALLOFFLINE:
case CM_ERROR_PARTIALWRITE: case CM_ERROR_PARTIALWRITE:
if (rp->procp == cm_BkgStore) { if (rp->procp == cm_BkgStore ||
rp->procp == RDR_BkgFetch) {
osi_Log2(afsd_logp, osi_Log2(afsd_logp,
"cm_BkgDaemon re-queueing failed request 0x%p code 0x%x", "cm_BkgDaemon re-queueing failed request 0x%p code 0x%x",
rp, code); rp, code);
@ -349,6 +351,13 @@ cm_DaemonCheckInit(void)
cm_daemonCheckOfflineVolInterval = dummy; cm_daemonCheckOfflineVolInterval = dummy;
afsi_log("daemonCheckOfflineVolInterval is %d", cm_daemonCheckOfflineVolInterval); afsi_log("daemonCheckOfflineVolInterval is %d", cm_daemonCheckOfflineVolInterval);
dummyLen = sizeof(DWORD);
code = RegQueryValueEx(parmKey, "daemonRDRShakeExtentsInterval", NULL, NULL,
(BYTE *) &dummy, &dummyLen);
if (code == ERROR_SUCCESS && dummy)
cm_daemonRDRShakeExtentsInterval = dummy;
afsi_log("daemonRDRShakeExtentsInterval is %d", cm_daemonRDRShakeExtentsInterval);
dummyLen = sizeof(DWORD); dummyLen = sizeof(DWORD);
code = RegQueryValueEx(parmKey, "daemonPerformanceTuningInterval", NULL, NULL, code = RegQueryValueEx(parmKey, "daemonPerformanceTuningInterval", NULL, NULL,
(BYTE *) &dummy, &dummyLen); (BYTE *) &dummy, &dummyLen);
@ -418,6 +427,7 @@ void cm_Daemon(long parm)
time_t lastBusyVolCheck; time_t lastBusyVolCheck;
time_t lastPerformanceCheck; time_t lastPerformanceCheck;
time_t lastServerRankCheck; time_t lastServerRankCheck;
time_t lastRDRShakeExtents;
char thostName[200]; char thostName[200];
unsigned long code; unsigned long code;
struct hostent *thp; struct hostent *thp;
@ -472,6 +482,8 @@ void cm_Daemon(long parm)
if (cm_daemonPerformanceTuningInterval) if (cm_daemonPerformanceTuningInterval)
lastPerformanceCheck = now - cm_daemonPerformanceTuningInterval/2 * (rand() % cm_daemonPerformanceTuningInterval); lastPerformanceCheck = now - cm_daemonPerformanceTuningInterval/2 * (rand() % cm_daemonPerformanceTuningInterval);
lastServerRankCheck = now - cm_daemonRankServerInterval/2 * (rand() % cm_daemonRankServerInterval); lastServerRankCheck = now - cm_daemonRankServerInterval/2 * (rand() % cm_daemonRankServerInterval);
if (cm_daemonRDRShakeExtentsInterval)
lastRDRShakeExtents = now - cm_daemonRDRShakeExtentsInterval/2 * (rand() % cm_daemonRDRShakeExtentsInterval);
while (daemon_ShutdownFlag == 0) { while (daemon_ShutdownFlag == 0) {
if (powerStateSuspended) { if (powerStateSuspended) {
@ -624,6 +636,20 @@ void cm_Daemon(long parm)
now = osi_Time(); now = osi_Time();
} }
if (cm_daemonRDRShakeExtentsInterval &&
now > lastRDRShakeExtents + cm_daemonRDRShakeExtentsInterval &&
daemon_ShutdownFlag == 0 &&
powerStateSuspended == 0) {
cm_req_t req;
cm_InitReq(&req);
lastRDRShakeExtents = now;
if (cm_data.buf_redirCount > cm_data.buf_freeCount)
buf_RDRShakeSomeExtentsFree(&req, FALSE, 10 /* seconds */);
if (daemon_ShutdownFlag == 1)
break;
now = osi_Time();
}
/* allow an exit to be called prior to stopping the service */ /* allow an exit to be called prior to stopping the service */
hHookDll = cm_LoadAfsdHookLib(); hHookDll = cm_LoadAfsdHookLib();
if (hHookDll) if (hHookDll)

View File

@ -22,6 +22,7 @@
#include <osi.h> #include <osi.h>
#include "afsd.h" #include "afsd.h"
#include "smb.h"
#ifdef DEBUG #ifdef DEBUG
extern void afsi_log(char *pattern, ...); extern void afsi_log(char *pattern, ...);
@ -732,12 +733,12 @@ cm_BkgStore(cm_scache_t *scp, afs_uint32 p1, afs_uint32 p2, afs_uint32 p3, afs_u
osi_hyper_t toffset; osi_hyper_t toffset;
long length; long length;
long code = 0; long code = 0;
afs_uint32 req_flags = reqp->flags;
if (scp->flags & CM_SCACHEFLAG_DELETED) { if (scp->flags & CM_SCACHEFLAG_DELETED) {
osi_Log4(afsd_logp, "Skipping BKG store - Deleted scp 0x%p, offset 0x%x:%08x, length 0x%x", scp, p2, p1, p3); osi_Log4(afsd_logp, "Skipping BKG store - Deleted scp 0x%p, offset 0x%x:%08x, length 0x%x", scp, p2, p1, p3);
} else { } else {
/* Retries will be performed by the BkgDaemon thread if appropriate */ /* Retries will be performed by the BkgDaemon thread if appropriate */
afs_uint32 req_flags = reqp->flags;
reqp->flags |= CM_REQ_NORETRY; reqp->flags |= CM_REQ_NORETRY;
toffset.LowPart = p1; toffset.LowPart = p1;
@ -1420,6 +1421,7 @@ void cm_ReleaseBIOD(cm_bulkIO_t *biop, int isStore, long code, int scp_locked)
osi_queueData_t *qdp; osi_queueData_t *qdp;
osi_queueData_t *nqdp; osi_queueData_t *nqdp;
int flags; int flags;
int reportErrorToRedir = 0;
/* Give back reserved buffers */ /* Give back reserved buffers */
if (biop->reserved) if (biop->reserved)
@ -1477,6 +1479,7 @@ void cm_ReleaseBIOD(cm_bulkIO_t *biop, int isStore, long code, int scp_locked)
bufp->error = code; bufp->error = code;
bufp->dataVersion = CM_BUF_VERSION_BAD; bufp->dataVersion = CM_BUF_VERSION_BAD;
bufp->dirtyCounter++; bufp->dirtyCounter++;
reportErrorToRedir = 1;
break; break;
case CM_ERROR_TIMEDOUT: case CM_ERROR_TIMEDOUT:
case CM_ERROR_ALLDOWN: case CM_ERROR_ALLDOWN:
@ -1501,6 +1504,12 @@ void cm_ReleaseBIOD(cm_bulkIO_t *biop, int isStore, long code, int scp_locked)
buf_Release(bufp); buf_Release(bufp);
bufp = NULL; bufp = NULL;
} }
if (RDR_Initialized && reportErrorToRedir) {
DWORD status;
smb_MapNTError(cm_MapRPCError(code, biop->reqp), &status, TRUE);
RDR_SetFileStatus( &scp->fid, status);
}
} else { } else {
if (!scp_locked) if (!scp_locked)
lock_ObtainWrite(&scp->rw); lock_ObtainWrite(&scp->rw);

View File

@ -397,6 +397,15 @@ int cm_noteLocalMountPointChange(afs_int32 locked) {
lock_ObtainMutex(&cm_Freelance_Lock); lock_ObtainMutex(&cm_Freelance_Lock);
cm_data.fakeDirVersion++; cm_data.fakeDirVersion++;
cm_localMountPointChangeFlag = 1; cm_localMountPointChangeFlag = 1;
if (RDR_Initialized) {
cm_fid_t fid;
cm_FakeRootFid(&fid);
RDR_InvalidateObject( fid.cell, fid.volume, fid.vnode, fid.unique, fid.hash,
CM_SCACHETYPE_DIRECTORY,
AFS_INVALIDATE_DATA_VERSION);
}
if (!locked) if (!locked)
lock_ReleaseMutex(&cm_Freelance_Lock); lock_ReleaseMutex(&cm_Freelance_Lock);
return 1; return 1;
@ -459,6 +468,11 @@ int cm_reInitLocalMountPoints() {
lock_ReleaseWrite(&scp->rw); lock_ReleaseWrite(&scp->rw);
lock_ReleaseWrite(&cm_scacheLock); lock_ReleaseWrite(&cm_scacheLock);
cm_CallbackNotifyChange(scp); cm_CallbackNotifyChange(scp);
if (RDR_Initialized)
RDR_InvalidateObject(scp->fid.cell, scp->fid.volume, scp->fid.vnode, scp->fid.unique,
scp->fid.hash, scp->fileType, AFS_INVALIDATE_CALLBACK);
lock_ObtainWrite(&cm_scacheLock); lock_ObtainWrite(&cm_scacheLock);
cm_ReleaseSCacheNoLock(scp); cm_ReleaseSCacheNoLock(scp);
lock_ObtainMutex(&cm_Freelance_Lock); lock_ObtainMutex(&cm_Freelance_Lock);

View File

@ -78,7 +78,12 @@ cm_CleanFile(cm_scache_t *scp, cm_user_t *userp, cm_req_t *reqp)
{ {
long code; long code;
code = cm_FSync(scp, userp, reqp, FALSE); if (RDR_Initialized &&
RDR_InvalidateObject(scp->fid.cell, scp->fid.volume, scp->fid.vnode, scp->fid.unique,
scp->fid.hash, scp->fileType, AFS_INVALIDATE_FLUSHED))
code = CM_ERROR_WOULDBLOCK;
else
code = cm_FSync(scp, userp, reqp, FALSE);
if (!code) { if (!code) {
lock_ObtainWrite(&scp->rw); lock_ObtainWrite(&scp->rw);
cm_DiscardSCache(scp); cm_DiscardSCache(scp);
@ -104,7 +109,16 @@ cm_FlushFile(cm_scache_t *scp, cm_user_t *userp, cm_req_t *reqp)
} }
#endif #endif
code = buf_FlushCleanPages(scp, userp, reqp); /*
* The file system will forget all knowledge of the object
* when it receives this message.
*/
if (RDR_Initialized &&
RDR_InvalidateObject(scp->fid.cell, scp->fid.volume, scp->fid.vnode, scp->fid.unique,
scp->fid.hash, scp->fileType, AFS_INVALIDATE_FLUSHED))
code = CM_ERROR_WOULDBLOCK;
else
code = buf_FlushCleanPages(scp, userp, reqp);
if (scp->fileType == CM_SCACHETYPE_DIRECTORY) if (scp->fileType == CM_SCACHETYPE_DIRECTORY)
lock_ObtainWrite(&scp->dirlock); lock_ObtainWrite(&scp->dirlock);
@ -530,6 +544,10 @@ cm_IoctlSetACL(struct cm_ioctl *ioctlp, struct cm_user *userp, cm_scache_t *scp,
lock_ObtainWrite(&scp->rw); lock_ObtainWrite(&scp->rw);
cm_DiscardSCache(scp); cm_DiscardSCache(scp);
lock_ReleaseWrite(&scp->rw); lock_ReleaseWrite(&scp->rw);
if (RDR_Initialized)
RDR_InvalidateObject(scp->fid.cell, scp->fid.volume, scp->fid.vnode, scp->fid.unique,
scp->fid.hash, scp->fileType, AFS_INVALIDATE_CREDS);
} }
return code; return code;
@ -1185,6 +1203,11 @@ cm_IoctlDeleteMountPoint(struct cm_ioctl *ioctlp, struct cm_user *userp, cm_scac
lock_ReleaseWrite(&scp->rw); lock_ReleaseWrite(&scp->rw);
cm_ReleaseSCache(scp); cm_ReleaseSCache(scp);
if (RDR_Initialized &&
!RDR_InvalidateObject(scp->fid.cell, scp->fid.volume, scp->fid.vnode, scp->fid.unique,
scp->fid.hash, scp->fileType, AFS_INVALIDATE_DELETED))
buf_ClearRDRFlag(scp, "deleted mp");
done3: done3:
if (originalName != NULL) if (originalName != NULL)
free(originalName); free(originalName);
@ -1409,7 +1432,7 @@ cm_IoctlGetCacheParms(struct cm_ioctl *ioctlp, struct cm_user *userp)
/* and then the actual # of buffers in use (not in the free list, I guess, /* and then the actual # of buffers in use (not in the free list, I guess,
* will be what we do). * will be what we do).
*/ */
parms.parms[1] = (cm_data.buf_nbuffers - buf_CountFreeList()) * (cm_data.buf_blockSize / 1024); parms.parms[1] = (cm_data.buf_nbuffers - cm_data.buf_freeCount) * (cm_data.buf_blockSize / 1024);
memcpy(ioctlp->outDatap, &parms, sizeof(parms)); memcpy(ioctlp->outDatap, &parms, sizeof(parms));
ioctlp->outDatap += sizeof(parms); ioctlp->outDatap += sizeof(parms);
@ -1679,6 +1702,13 @@ cm_IoctlGetWsCell(cm_ioctl_t *ioctlp, cm_user_t *userp)
* VIOC_AFS_SYSNAME internals. * VIOC_AFS_SYSNAME internals.
* *
* Assumes that pioctl path has been parsed or skipped. * Assumes that pioctl path has been parsed or skipped.
*
* In order to support both 32-bit and 64-bit sysname lists
* we will treat bit-31 of the setSysName value as a flag
* indicating which architecture is being indicated. If unset
* the architecture is 32-bit and if set the architecture is
* 64-bit. This change is backward compatible with cache
* managers that do not support this extension.
*/ */
afs_int32 afs_int32
cm_IoctlSysName(struct cm_ioctl *ioctlp, struct cm_user *userp) cm_IoctlSysName(struct cm_ioctl *ioctlp, struct cm_user *userp)
@ -1688,10 +1718,14 @@ cm_IoctlSysName(struct cm_ioctl *ioctlp, struct cm_user *userp)
clientchar_t *inname = NULL; clientchar_t *inname = NULL;
int t; int t;
unsigned int count; unsigned int count;
int arch64 = 0;
memcpy(&setSysName, ioctlp->inDatap, sizeof(afs_uint32)); memcpy(&setSysName, ioctlp->inDatap, sizeof(afs_uint32));
ioctlp->inDatap += sizeof(afs_uint32); ioctlp->inDatap += sizeof(afs_uint32);
arch64 = (setSysName & 0x8000000) ? 1 : 0;
setSysName &= 0x7FFFFFF;
if (setSysName) { if (setSysName) {
/* check my args */ /* check my args */
if ( setSysName < 0 || setSysName > MAXNUMSYSNAMES ) if ( setSysName < 0 || setSysName > MAXNUMSYSNAMES )
@ -1716,46 +1750,57 @@ cm_IoctlSysName(struct cm_ioctl *ioctlp, struct cm_user *userp)
} }
/* Not xlating, so local case */ /* Not xlating, so local case */
if (!cm_sysName)
osi_panic("cm_IoctlSysName: !cm_sysName\n", __FILE__, __LINE__);
if (setSysName) { if (setSysName) {
/* Local guy; only root can change sysname */ /* Local guy; only root can change sysname */
/* clear @sys entries from the dnlc, once afs_lookup can /* clear @sys entries from the dnlc, once afs_lookup can
* do lookups of @sys entries and thinks it can trust them */ * do lookups of @sys entries and thinks it can trust them */
/* privs ok, store the entry, ... */ /* privs ok, store the entry, ... */
cm_ClientStrCpy(cm_sysName, lengthof(cm_sysName), inname); cm_ClientStrCpy(arch64 ? cm_sysName64List[0] : cm_sysNameList[0], MAXSYSNAME, inname);
cm_ClientStrCpy(cm_sysNameList[0], MAXSYSNAME, inname);
if (setSysName > 1) { /* ... or list */ if (setSysName > 1) { /* ... or list */
for (count = 1; count < setSysName; ++count) { for (count = 1; count < setSysName; ++count) {
clientchar_t * newsysname; clientchar_t * newsysname;
if (!cm_sysNameList[count]) if (!(arch64 ? cm_sysName64List[count] : cm_sysNameList[count]))
osi_panic("cm_IoctlSysName: no cm_sysNameList entry to write\n", osi_panic("cm_IoctlSysName: no cm_sysNameList entry to write\n",
__FILE__, __LINE__); __FILE__, __LINE__);
newsysname = cm_ParseIoctlStringAlloc(ioctlp, NULL); newsysname = cm_ParseIoctlStringAlloc(ioctlp, NULL);
cm_ClientStrCpy(cm_sysNameList[count], MAXSYSNAME, newsysname); cm_ClientStrCpy(arch64 ? cm_sysName64List[count] : cm_sysNameList[count], MAXSYSNAME, newsysname);
free(newsysname); free(newsysname);
} }
} }
cm_sysNameCount = setSysName; if ( arch64 ) {
cm_sysName64Count = setSysName;
if (cm_sysName64Count)
RDR_SysName( AFS_SYSNAME_ARCH_64BIT, cm_sysName64Count, cm_sysName64List );
else if (cm_sysNameCount)
RDR_SysName( AFS_SYSNAME_ARCH_64BIT, cm_sysNameCount, cm_sysNameList );
} else {
cm_sysNameCount = setSysName;
RDR_SysName( AFS_SYSNAME_ARCH_32BIT, cm_sysNameCount, cm_sysNameList );
}
} else { } else {
afs_uint32 i32; afs_uint32 i32;
/* return the sysname to the caller */ /* return the sysname list to the caller.
i32 = cm_sysNameCount; * if there is no 64-bit list and 64-bit is requested, use the 32-bit list.
*/
if ( arch64 && cm_sysName64Count == 0 )
arch64 = 0;
i32 = arch64 ? cm_sysName64Count : cm_sysNameCount;
memcpy(ioctlp->outDatap, &i32, sizeof(afs_int32)); memcpy(ioctlp->outDatap, &i32, sizeof(afs_int32));
ioctlp->outDatap += sizeof(afs_int32); /* skip found flag */ ioctlp->outDatap += sizeof(afs_int32); /* skip found flag */
if (cm_sysNameCount) { if (i32) {
for ( count=0; count < cm_sysNameCount ; ++count) { /* ... or list */ for ( count=0; count < i32 ; ++count) { /* ... or list */
if ( !cm_sysNameList[count] || *cm_sysNameList[count] == _C('\0')) if ( !(arch64 ? cm_sysName64List[count] : cm_sysNameList[count]) ||
*(arch64 ? cm_sysName64List[count] : cm_sysNameList[count]) == _C('\0'))
osi_panic("cm_IoctlSysName: no cm_sysNameList entry to read\n", osi_panic("cm_IoctlSysName: no cm_sysNameList entry to read\n",
__FILE__, __LINE__); __FILE__, __LINE__);
cm_UnparseIoctlString(ioctlp, NULL, cm_sysNameList[count], -1); cm_UnparseIoctlString(ioctlp, NULL, arch64 ? cm_sysName64List[count] : cm_sysNameList[count], -1);
} }
} }
} }
@ -2346,6 +2391,11 @@ cm_IoctlDeletelink(struct cm_ioctl *ioctlp, struct cm_user *userp, cm_scache_t *
lock_ReleaseWrite(&scp->rw); lock_ReleaseWrite(&scp->rw);
cm_ReleaseSCache(scp); cm_ReleaseSCache(scp);
if (RDR_Initialized &&
!RDR_InvalidateObject(scp->fid.cell, scp->fid.volume, scp->fid.vnode, scp->fid.unique,
scp->fid.hash, scp->fileType, AFS_INVALIDATE_DELETED))
buf_ClearRDRFlag(scp, "deleted link");
done3: done3:
free(clientp); free(clientp);
@ -2529,8 +2579,14 @@ cm_IoctlSetToken(struct cm_ioctl *ioctlp, struct cm_user *userp)
} }
if (flags & PIOCTL_LOGON) { if (flags & PIOCTL_LOGON) {
userp = smb_FindCMUserByName(smbname, ioctlp->fidp->vcp->rname, clientchar_t *cname;
cname = cm_FsStringToClientStringAlloc(smbname, -1, NULL);
userp = smb_FindCMUserByName(cname, ioctlp->fidp->vcp->rname,
SMB_FLAG_CREATE|SMB_FLAG_AFSLOGON); SMB_FLAG_CREATE|SMB_FLAG_AFSLOGON);
if (cname)
free(cname);
release_userp = 1; release_userp = 1;
} }

View File

@ -118,9 +118,10 @@ typedef struct cm_IoctlQueryOptions {
#define MAXNUMSYSNAMES 16 /* max that current constants allow */ #define MAXNUMSYSNAMES 16 /* max that current constants allow */
#define MAXSYSNAME 128 /* max sysname (i.e. @sys) size */ #define MAXSYSNAME 128 /* max sysname (i.e. @sys) size */
extern clientchar_t *cm_sysName;
extern unsigned int cm_sysNameCount; extern unsigned int cm_sysNameCount;
extern clientchar_t *cm_sysNameList[MAXNUMSYSNAMES]; extern clientchar_t *cm_sysNameList[MAXNUMSYSNAMES];
extern unsigned int cm_sysName64Count;
extern clientchar_t *cm_sysName64List[MAXNUMSYSNAMES];
/* Paths that are passed into pioctl calls can be specified using /* Paths that are passed into pioctl calls can be specified using
UTF-8. These strings are prefixed with UTF8_PREFIX defined below. UTF-8. These strings are prefixed with UTF8_PREFIX defined below.

View File

@ -266,15 +266,15 @@ cm_ShutdownMappedMemory(void)
HeapDestroy(hCacheHeap); HeapDestroy(hCacheHeap);
afsi_log("Memory Heap has been destroyed"); afsi_log("Memory Heap has been destroyed");
} else { } else {
if (cm_ValidateCache == 2) if (cm_ValidateCache == 2)
dirty = !cm_IsCacheValid(); dirty = !cm_IsCacheValid();
*config_data_p = cm_data; *config_data_p = cm_data;
config_data_p->dirty = dirty; config_data_p->dirty = dirty;
UnmapViewOfFile(config_data_p); UnmapViewOfFile(config_data_p);
CloseHandle(hMemoryMappedFile); CloseHandle(hMemoryMappedFile);
hMemoryMappedFile = NULL; hMemoryMappedFile = NULL;
afsi_log("Memory Mapped File has been closed"); afsi_log("Memory Mapped File has been closed");
} }
return 0; return 0;
} }
@ -794,44 +794,44 @@ cm_InitMappedMemory(DWORD virtualCache, char * cachePath, DWORD stats, DWORD max
CloseHandle(hm); CloseHandle(hm);
} }
hm = CreateFileMapping( hf, hm = CreateFileMapping( hf,
NULL, NULL,
PAGE_READWRITE, PAGE_READWRITE,
(DWORD)(mappingSize >> 32), (DWORD)(mappingSize >> 32),
(DWORD)(mappingSize & 0xFFFFFFFF), (DWORD)(mappingSize & 0xFFFFFFFF),
NULL); NULL);
if (hm == NULL) { if (hm == NULL) {
if (GetLastError() == ERROR_DISK_FULL) { if (GetLastError() == ERROR_DISK_FULL) {
afsi_log("Error creating file mapping for \"%s\": disk full [2]", afsi_log("Error creating file mapping for \"%s\": disk full [2]",
cachePath); cachePath);
return CM_ERROR_TOOMANYBUFS; return CM_ERROR_TOOMANYBUFS;
} }
afsi_log("Error creating file mapping for \"%s\": %d", afsi_log("Error creating file mapping for \"%s\": %d",
cachePath, GetLastError()); cachePath, GetLastError());
return CM_ERROR_INVAL;
}
baseAddress = MapViewOfFileEx( hm,
FILE_MAP_ALL_ACCESS,
0,
0,
(SIZE_T)mappingSize,
baseAddress );
if (baseAddress == NULL) {
afsi_log("Error mapping view of file: %d", GetLastError());
baseAddress = MapViewOfFile( hm,
FILE_MAP_ALL_ACCESS,
0,
0,
(SIZE_T)mappingSize);
if (baseAddress == NULL) {
if (hf != INVALID_HANDLE_VALUE)
CloseHandle(hf);
CloseHandle(hm);
return CM_ERROR_INVAL; return CM_ERROR_INVAL;
} }
baseAddress = MapViewOfFileEx( hm,
FILE_MAP_ALL_ACCESS,
0,
0,
(SIZE_T)mappingSize,
baseAddress );
if (baseAddress == NULL) {
afsi_log("Error mapping view of file: %d", GetLastError());
baseAddress = MapViewOfFile( hm,
FILE_MAP_ALL_ACCESS,
0,
0,
(SIZE_T)mappingSize);
if (baseAddress == NULL) {
if (hf != INVALID_HANDLE_VALUE)
CloseHandle(hf);
CloseHandle(hm);
return CM_ERROR_INVAL;
}
newCache = 1; newCache = 1;
} }
CloseHandle(hm); CloseHandle(hm);
hMemoryMappedFile = hf; hMemoryMappedFile = hf;
} }
@ -936,10 +936,18 @@ cm_InitMappedMemory(DWORD virtualCache, char * cachePath, DWORD stats, DWORD max
cm_data.bufEndOfData = (char *) baseAddress; cm_data.bufEndOfData = (char *) baseAddress;
cm_data.buf_dirtyListp = NULL; cm_data.buf_dirtyListp = NULL;
cm_data.buf_dirtyListEndp = NULL; cm_data.buf_dirtyListEndp = NULL;
cm_data.fakeDirVersion = 0x8; /* Make sure the fakeDirVersion is always increasing */
cm_data.fakeDirVersion = time(NULL);
cm_data.fakeUnique = 0;
UuidCreate((UUID *)&cm_data.Uuid); UuidCreate((UUID *)&cm_data.Uuid);
cm_data.volSerialNumber = volumeSerialNumber; cm_data.volSerialNumber = volumeSerialNumber;
memcpy(cm_data.Sid, machineSid, sizeof(machineSid)); memcpy(cm_data.Sid, machineSid, sizeof(machineSid));
/*
* make sure that the file is fully allocated
* by writing a non-zero byte to the end
*/
cm_data.baseAddress[mappingSize-1] = 0xFF;
} else { } else {
int gennew = 0; int gennew = 0;

View File

@ -83,17 +83,30 @@ typedef struct cm_config_data {
cm_buf_t * buf_freeListEndp; cm_buf_t * buf_freeListEndp;
cm_buf_t * buf_dirtyListp; cm_buf_t * buf_dirtyListp;
cm_buf_t * buf_dirtyListEndp; cm_buf_t * buf_dirtyListEndp;
cm_buf_t * buf_redirListp;
cm_buf_t * buf_redirListEndp;
cm_buf_t ** buf_scacheHashTablepp; cm_buf_t ** buf_scacheHashTablepp;
cm_buf_t ** buf_fileHashTablepp; cm_buf_t ** buf_fileHashTablepp;
cm_buf_t * buf_allp; cm_buf_t * buf_allp;
afs_uint64 buf_nbuffers;
afs_uint32 buf_blockSize; afs_uint32 buf_blockSize;
afs_uint32 buf_hashSize; afs_uint32 buf_hashSize;
#ifdef _M_IX86
afs_uint32 buf_nbuffers;
afs_uint32 buf_nOrigBuffers;
afs_uint32 buf_reservedBufs;
afs_uint32 buf_maxReservedBufs;
afs_uint32 buf_reserveWaiting;
afs_uint32 buf_freeCount;
afs_uint32 buf_redirCount;
#else
afs_uint64 buf_nbuffers;
afs_uint64 buf_nOrigBuffers; afs_uint64 buf_nOrigBuffers;
afs_uint64 buf_reservedBufs; afs_uint64 buf_reservedBufs;
afs_uint64 buf_maxReservedBufs; afs_uint64 buf_maxReservedBufs;
afs_uint64 buf_reserveWaiting; afs_uint64 buf_reserveWaiting;
afs_uint64 buf_freeCount;
afs_uint64 buf_redirCount;
#endif
time_t mountRootGen; time_t mountRootGen;
afsUUID Uuid; afsUUID Uuid;
DWORD volSerialNumber; DWORD volSerialNumber;

View File

@ -537,7 +537,7 @@ void cm_PerformancePrintReport(void)
"SIZEs- 0kb=%u 1kb=%u 4kb=%u 64kb=%u 1mb=%u 20m=%u 100mb=%u 1gb=%u 2gb=%u larger=%u\r\n\r\n", "SIZEs- 0kb=%u 1kb=%u 4kb=%u 64kb=%u 1mb=%u 20m=%u 100mb=%u 1gb=%u 2gb=%u larger=%u\r\n\r\n",
t, t,
cm_data.currentSCaches, cm_data.maxSCaches, cm_data.currentVolumes, cm_data.maxVolumes, cm_data.currentSCaches, cm_data.maxSCaches, cm_data.currentVolumes, cm_data.maxVolumes,
cm_data.buf_nbuffers - buf_CountFreeList(), cm_data.buf_nbuffers, cm_data.buf_nbuffers - cm_data.buf_freeCount, cm_data.buf_nbuffers,
fid_cnt, fid_w_vol, fid_w_scache, fid_w_callbacks, fid_w_buffers, fid_cnt, fid_w_vol, fid_w_scache, fid_w_callbacks, fid_w_buffers,
fid_w_scache_no_vol, fid_w_vol_no_scache, fid_w_scache_no_buf, fid_w_buf_no_scache, fid_w_scache_no_vol, fid_w_vol_no_scache, fid_w_scache_no_buf, fid_w_buf_no_scache,
rw_vols, ro_vols, bk_vols, rw_vols, ro_vols, bk_vols,

41
src/WINNT/afsd/cm_rdr.h Normal file
View File

@ -0,0 +1,41 @@
/*
* Copyright (c) 2008 Secure Endpoints Inc.
* Copyright (c) 2009-2011 Your File System Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither the name of Secure Endpoints Inc nor the names of its contributors may be
* used to endorse or promote products derived from this software without
* specific prior written permission from Secure Endpoints Inc and
* Your File System Inc.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef CM_RDR_H
#define CM_RDR_H
#include <..\afsrdr\common\AFSUserDefines.h>
#include <..\afsrdr\common\AFSUserStructs.h>
#include <..\afsrdr\common\AFSUserPrototypes.h>
#endif /* CM_RDR_H */

View File

@ -23,6 +23,7 @@
#include "afsd.h" #include "afsd.h"
#include "cm_btree.h" #include "cm_btree.h"
#include <afs/unified_afs.h>
/*extern void afsi_log(char *pattern, ...);*/ /*extern void afsi_log(char *pattern, ...);*/
@ -154,6 +155,11 @@ long cm_RecycleSCache(cm_scache_t *scp, afs_int32 flags)
return -1; return -1;
} }
if (scp->redirBufCount != 0) {
return -1;
}
cm_RemoveSCacheFromHashTable(scp);
/* invalidate so next merge works fine; /* invalidate so next merge works fine;
* also initialize some flags */ * also initialize some flags */
@ -233,36 +239,64 @@ cm_scache_t *cm_GetNewSCache(void)
/* There were no deleted scache objects that we could use. Try to find /* There were no deleted scache objects that we could use. Try to find
* one that simply hasn't been used in a while. * one that simply hasn't been used in a while.
*/ */
for ( scp = cm_data.scacheLRULastp; for (retry = 0 ; retry < 2; retry++) {
scp; for ( scp = cm_data.scacheLRULastp;
scp = (cm_scache_t *) osi_QPrev(&scp->q)) scp;
{ scp = (cm_scache_t *) osi_QPrev(&scp->q))
/* It is possible for the refCount to be zero and for there still {
* to be outstanding dirty buffers. If there are dirty buffers, /* It is possible for the refCount to be zero and for there still
* we must not recycle the scp. */ * to be outstanding dirty buffers. If there are dirty buffers,
if (scp->refCount == 0 && scp->bufReadsp == NULL && scp->bufWritesp == NULL) { * we must not recycle the scp.
if (!buf_DirtyBuffersExist(&scp->fid)) { *
if (!lock_TryWrite(&scp->rw)) * If the object is in use by the redirector, then avoid recycling
continue; * it unless we have to.
*/
if (scp->refCount == 0 && scp->bufReadsp == NULL && scp->bufWritesp == NULL) {
if (!buf_DirtyBuffersExist(&scp->fid) && !buf_RDRBuffersExist(&scp->fid)) {
cm_fid_t fid;
afs_uint32 fileType;
if (!cm_RecycleSCache(scp, 0)) { if (!lock_TryWrite(&scp->rw))
/* we found an entry, so return it */ continue;
/* now remove from the LRU queue and put it back at the
* head of the LRU queue.
*/
cm_AdjustScacheLRU(scp);
/* and we're done */ /* Found a likely candidate. Save type and fid in case we succeed */
return scp; fid = scp->fid;
fileType = scp->fileType;
if (!cm_RecycleSCache(scp, 0)) {
/* we found an entry, so return it.
* remove from the LRU queue and put it back at the
* head of the LRU queue.
*/
cm_AdjustScacheLRU(scp);
if (RDR_Initialized) {
/*
* We drop the cm_scacheLock because it may be required to
* satisfy an ioctl request from the redirector. It should
* be safe to hold the scp->rw lock here because at this
* point (a) the object has just been recycled so the fid
* is nul and there are no requests that could possibly
* be issued by the redirector that would depend upon it.
*/
lock_ReleaseWrite(&cm_scacheLock);
RDR_InvalidateObject( fid.cell, fid.volume, fid.vnode,
fid.unique, fid.hash,
fileType, AFS_INVALIDATE_EXPIRED);
lock_ObtainWrite(&cm_scacheLock);
}
/* and we're done */
return scp;
}
lock_ReleaseWrite(&scp->rw);
} else {
osi_Log1(afsd_logp,"GetNewSCache dirty buffers exist scp 0x%p", scp);
} }
lock_ReleaseWrite(&scp->rw);
} else {
osi_Log1(afsd_logp,"GetNewSCache dirty buffers exist scp 0x%x", scp);
} }
} }
osi_Log1(afsd_logp, "GetNewSCache all scache entries in use (retry = %d)", retry);
} }
osi_Log1(afsd_logp, "GetNewSCache all scache entries in use (retry = %d)", retry);
return NULL; return NULL;
} }
@ -567,7 +601,11 @@ void cm_InitSCache(int newFile, long maxSCaches)
scp->dirDataVersion = CM_SCACHE_VERSION_BAD; scp->dirDataVersion = CM_SCACHE_VERSION_BAD;
#endif #endif
scp->waitQueueT = NULL; scp->waitQueueT = NULL;
_InterlockedAnd(&scp->flags, ~CM_SCACHEFLAG_WAITING); _InterlockedAnd(&scp->flags, ~(CM_SCACHEFLAG_CALLBACK | CM_SCACHEFLAG_WAITING | CM_SCACHEFLAG_RDR_IN_USE));
scp->redirBufCount = 0;
scp->redirQueueT = NULL;
scp->redirQueueH = NULL;
} }
} }
cm_allFileLocks = NULL; cm_allFileLocks = NULL;
@ -981,6 +1019,9 @@ int cm_SyncOpCheckContinue(cm_scache_t * scp, afs_int32 flags, cm_buf_t * bufp)
* possibly resulting in a bogus truncation. The simplest way to avoid this * possibly resulting in a bogus truncation. The simplest way to avoid this
* is to serialize all StoreData RPC's. This is the reason we defined * is to serialize all StoreData RPC's. This is the reason we defined
* CM_SCACHESYNC_STOREDATA_EXCL and CM_SCACHEFLAG_DATASTORING. * CM_SCACHESYNC_STOREDATA_EXCL and CM_SCACHEFLAG_DATASTORING.
*
* CM_SCACHESYNC_BULKREAD is used to permit synchronization of multiple bulk
* readers which may be requesting overlapping ranges.
*/ */
long cm_SyncOp(cm_scache_t *scp, cm_buf_t *bufp, cm_user_t *userp, cm_req_t *reqp, long cm_SyncOp(cm_scache_t *scp, cm_buf_t *bufp, cm_user_t *userp, cm_req_t *reqp,
afs_uint32 rights, afs_uint32 flags) afs_uint32 rights, afs_uint32 flags)
@ -1208,6 +1249,14 @@ long cm_SyncOp(cm_scache_t *scp, cm_buf_t *bufp, cm_user_t *userp, cm_req_t *req
} }
} }
if (flags & CM_SCACHESYNC_BULKREAD) {
/* Don't allow concurrent fiddling with lock lists */
if (scp->flags & CM_SCACHEFLAG_BULKREADING) {
osi_Log1(afsd_logp, "CM SyncOp scp 0x%p is BULKREADING want BULKREAD", scp);
goto sleep;
}
}
/* if we get here, we're happy */ /* if we get here, we're happy */
break; break;
@ -1276,6 +1325,8 @@ long cm_SyncOp(cm_scache_t *scp, cm_buf_t *bufp, cm_user_t *userp, cm_req_t *req
_InterlockedOr(&scp->flags, CM_SCACHEFLAG_ASYNCSTORING); _InterlockedOr(&scp->flags, CM_SCACHEFLAG_ASYNCSTORING);
if (flags & CM_SCACHESYNC_LOCK) if (flags & CM_SCACHESYNC_LOCK)
_InterlockedOr(&scp->flags, CM_SCACHEFLAG_LOCKING); _InterlockedOr(&scp->flags, CM_SCACHEFLAG_LOCKING);
if (flags & CM_SCACHESYNC_BULKREAD)
_InterlockedOr(&scp->flags, CM_SCACHEFLAG_BULKREADING);
/* now update the buffer pointer */ /* now update the buffer pointer */
if (bufp && (flags & CM_SCACHESYNC_FETCHDATA)) { if (bufp && (flags & CM_SCACHESYNC_FETCHDATA)) {
@ -1347,6 +1398,8 @@ void cm_SyncOpDone(cm_scache_t *scp, cm_buf_t *bufp, afs_uint32 flags)
_InterlockedAnd(&scp->flags, ~CM_SCACHEFLAG_ASYNCSTORING); _InterlockedAnd(&scp->flags, ~CM_SCACHEFLAG_ASYNCSTORING);
if (flags & CM_SCACHESYNC_LOCK) if (flags & CM_SCACHESYNC_LOCK)
_InterlockedAnd(&scp->flags, ~CM_SCACHEFLAG_LOCKING); _InterlockedAnd(&scp->flags, ~CM_SCACHEFLAG_LOCKING);
if (flags & CM_SCACHESYNC_BULKREAD)
_InterlockedAnd(&scp->flags, ~CM_SCACHEFLAG_BULKREADING);
/* now update the buffer pointer */ /* now update the buffer pointer */
if (bufp && (flags & CM_SCACHESYNC_FETCHDATA)) { if (bufp && (flags & CM_SCACHESYNC_FETCHDATA)) {
@ -1468,10 +1521,20 @@ void cm_MergeStatus(cm_scache_t *dscp,
#endif /* AFS_FREELANCE_CLIENT */ #endif /* AFS_FREELANCE_CLIENT */
if (statusp->errorCode != 0) { if (statusp->errorCode != 0) {
_InterlockedOr(&scp->flags, CM_SCACHEFLAG_EACCESS); _InterlockedOr(&scp->flags, CM_SCACHEFLAG_EACCESS);
osi_Log2(afsd_logp, "Merge, Failure scp 0x%p code 0x%x", scp, statusp->errorCode); switch (statusp->errorCode) {
case EACCES:
case UAEACCES:
case EPERM:
case UAEPERM:
_InterlockedOr(&scp->flags, CM_SCACHEFLAG_EACCESS);
}
osi_Log2(afsd_logp, "Merge, Failure scp 0x%p code 0x%x", scp, statusp->errorCode);
scp->fileType = 0; /* unknown */ if (scp->fid.vnode & 0x1)
scp->fileType = CM_SCACHETYPE_DIRECTORY;
else
scp->fileType = 0; /* unknown */
scp->serverModTime = 0; scp->serverModTime = 0;
scp->clientModTime = 0; scp->clientModTime = 0;
@ -1634,7 +1697,8 @@ void cm_MergeStatus(cm_scache_t *dscp,
if (cm_FidCmp(&scp->fid, &bp->fid) == 0 && if (cm_FidCmp(&scp->fid, &bp->fid) == 0 &&
lock_TryMutex(&bp->mx)) { lock_TryMutex(&bp->mx)) {
if (bp->refCount == 0 && if (bp->refCount == 0 &&
!(bp->flags & CM_BUF_READING | CM_BUF_WRITING | CM_BUF_DIRTY)) { !(bp->flags & (CM_BUF_READING | CM_BUF_WRITING | CM_BUF_DIRTY)) &&
!(bp->qFlags & CM_BUF_QREDIR)) {
prevBp = bp->fileHashBackp; prevBp = bp->fileHashBackp;
bp->fileHashBackp = bp->fileHashp = NULL; bp->fileHashBackp = bp->fileHashp = NULL;
if (prevBp) if (prevBp)
@ -1671,9 +1735,19 @@ void cm_MergeStatus(cm_scache_t *dscp,
* does not update a mountpoint or symlink by altering the contents of * does not update a mountpoint or symlink by altering the contents of
* the file data; but the Unix CM does. * the file data; but the Unix CM does.
*/ */
if (scp->dataVersion != dataVersion && !(flags & CM_MERGEFLAG_FETCHDATA)) if (scp->dataVersion != dataVersion && !(flags & CM_MERGEFLAG_FETCHDATA)) {
scp->mountPointStringp[0] = '\0'; scp->mountPointStringp[0] = '\0';
osi_Log5(afsd_logp, "cm_MergeStatus data version change scp 0x%p cell %u vol %u vn %u uniq %u",
scp, scp->fid.cell, scp->fid.volume, scp->fid.vnode, scp->fid.unique);
osi_Log4(afsd_logp, ".... oldDV 0x%x:%x -> newDV 0x%x:%x",
(afs_uint32)((scp->dataVersion >> 32) & 0xFFFFFFFF),
(afs_uint32)(scp->dataVersion & 0xFFFFFFFF),
(afs_uint32)((dataVersion >> 32) & 0xFFFFFFFF),
(afs_uint32)(dataVersion & 0xFFFFFFFF));
}
/* We maintain a range of buffer dataVersion values which are considered /* We maintain a range of buffer dataVersion values which are considered
* valid. This avoids the need to update the dataVersion on each buffer * valid. This avoids the need to update the dataVersion on each buffer
* object during an uncontested storeData operation. As a result this * object during an uncontested storeData operation. As a result this
@ -1685,6 +1759,19 @@ void cm_MergeStatus(cm_scache_t *dscp,
scp->bufDataVersionLow == 0) scp->bufDataVersionLow == 0)
scp->bufDataVersionLow = dataVersion; scp->bufDataVersionLow = dataVersion;
if (RDR_Initialized && scp->dataVersion != CM_SCACHE_VERSION_BAD) {
if ( ( !(reqp->flags & CM_REQ_SOURCE_REDIR) || !(flags & (CM_MERGEFLAG_DIROP|CM_MERGEFLAG_STOREDATA))) &&
scp->dataVersion != dataVersion ) {
RDR_InvalidateObject(scp->fid.cell, scp->fid.volume, scp->fid.vnode,
scp->fid.unique, scp->fid.hash,
scp->fileType, AFS_INVALIDATE_DATA_VERSION);
} else if ( (reqp->flags & CM_REQ_SOURCE_REDIR) && (flags & (CM_MERGEFLAG_DIROP|CM_MERGEFLAG_STOREDATA)) &&
dataVersion - scp->dataVersion > 1) {
RDR_InvalidateObject(scp->fid.cell, scp->fid.volume, scp->fid.vnode,
scp->fid.unique, scp->fid.hash,
scp->fileType, AFS_INVALIDATE_DATA_VERSION);
}
}
scp->dataVersion = dataVersion; scp->dataVersion = dataVersion;
/* /*
@ -1735,7 +1822,7 @@ void cm_DiscardSCache(cm_scache_t *scp)
} }
scp->cbExpires = 0; scp->cbExpires = 0;
scp->volumeCreationDate = 0; scp->volumeCreationDate = 0;
_InterlockedAnd(&scp->flags, ~(CM_SCACHEFLAG_CALLBACK | CM_SCACHEFLAG_LOCAL)); _InterlockedAnd(&scp->flags, ~(CM_SCACHEFLAG_CALLBACK | CM_SCACHEFLAG_LOCAL | CM_SCACHEFLAG_RDR_IN_USE));
cm_dnlcPurgedp(scp); cm_dnlcPurgedp(scp);
cm_dnlcPurgevp(scp); cm_dnlcPurgevp(scp);
cm_FreeAllACLEnts(scp); cm_FreeAllACLEnts(scp);
@ -1965,7 +2052,7 @@ int cm_DumpSCache(FILE *outputFile, char *cookie, int lock)
WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL); WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
for (q = scp->fileLocksH; q; q = osi_QNext(q)) { for (q = scp->fileLocksH; q; q = osi_QNext(q)) {
cm_file_lock_t * lockp = (cm_file_lock_t *)((char *) q - offsetof(cm_file_lock_t, fileq)); cm_file_lock_t * lockp = fileq_to_cm_file_lock_t(q);
sprintf(output, " %s lockp=0x%p scp=0x%p, cm_userp=0x%p offset=0x%I64x len=0x%08I64x type=0x%x " sprintf(output, " %s lockp=0x%p scp=0x%p, cm_userp=0x%p offset=0x%I64x len=0x%08I64x type=0x%x "
"key=0x%I64x flags=0x%x update=0x%I64u\r\n", "key=0x%I64x flags=0x%x update=0x%I64u\r\n",
cookie, lockp, lockp->scp, lockp->userp, lockp->range.offset, lockp->range.length, cookie, lockp, lockp->scp, lockp->userp, lockp->range.offset, lockp->range.length,

View File

@ -62,6 +62,8 @@ typedef struct cm_file_lock {
* cm_scacheLock] */ * cm_scacheLock] */
} cm_file_lock_t; } cm_file_lock_t;
#define fileq_to_cm_file_lock_t(q) ((cm_file_lock_t *)((char *) (q) - offsetof(cm_file_lock_t, fileq)))
#define CM_FILELOCK_FLAG_DELETED 0x01 #define CM_FILELOCK_FLAG_DELETED 0x01
#define CM_FILELOCK_FLAG_LOST 0x02 #define CM_FILELOCK_FLAG_LOST 0x02
@ -223,8 +225,16 @@ typedef struct cm_scache {
Holds queue of Holds queue of
cm_scache_waiter_t cm_scache_waiter_t
objects. Protected by objects. Protected by
cm_cacheLock. */ cm_scacheLock. */
osi_queue_t * waitQueueT; /* locked by cm_scacheLock */ osi_queue_t * waitQueueT; /* locked by cm_scacheLock */
/* redirector state - protected by scp->rw */
osi_queue_t * redirQueueH; /* LRU queue of buffers for this
file that are assigned to the
afsredir kernel module. */
osi_queue_t * redirQueueT;
afs_uint32 redirBufCount; /* Number of buffers held by the redirector */
time_t redirLastAccess; /* last time redir accessed the vnode */
} cm_scache_t; } cm_scache_t;
/* dataVersion */ /* dataVersion */
@ -277,6 +287,8 @@ typedef struct cm_scache {
#define CM_SCACHEFLAG_EACCESS 0x200000 /* Bulk Stat returned EACCES */ #define CM_SCACHEFLAG_EACCESS 0x200000 /* Bulk Stat returned EACCES */
#define CM_SCACHEFLAG_SMB_FID 0x400000 #define CM_SCACHEFLAG_SMB_FID 0x400000
#define CM_SCACHEFLAG_LOCAL 0x800000 /* Locally modified */ #define CM_SCACHEFLAG_LOCAL 0x800000 /* Locally modified */
#define CM_SCACHEFLAG_BULKREADING 0x1000000/* Bulk read in progress */
#define CM_SCACHEFLAG_RDR_IN_USE 0x2000000/* in use by Redirector; advisory */
/* sync flags for calls to the server. The CM_SCACHEFLAG_FETCHING, /* sync flags for calls to the server. The CM_SCACHEFLAG_FETCHING,
* CM_SCACHEFLAG_STORING and CM_SCACHEFLAG_SIZESTORING flags correspond to the * CM_SCACHEFLAG_STORING and CM_SCACHEFLAG_SIZESTORING flags correspond to the
@ -314,6 +326,8 @@ typedef struct cm_scache {
#define CM_SCACHESYNC_FORCECB 0x200000/* when calling cm_GetCallback() #define CM_SCACHESYNC_FORCECB 0x200000/* when calling cm_GetCallback()
* set the force flag */ * set the force flag */
#define CM_SCACHESYNC_BULKREAD 0x400000/* reading many buffers */
/* flags for cm_RecycleSCache */ /* flags for cm_RecycleSCache */
#define CM_SCACHE_RECYCLEFLAG_DESTROY_BUFFERS 0x1 #define CM_SCACHE_RECYCLEFLAG_DESTROY_BUFFERS 0x1

View File

@ -172,13 +172,14 @@ cm_PingServer(cm_server_t *tsp)
} /* got an unauthenticated connection to this server */ } /* got an unauthenticated connection to this server */
lock_ObtainMutex(&tsp->mx); lock_ObtainMutex(&tsp->mx);
if (code >= 0 || code == RXGEN_OPCODE) { if (code >= 0 || code == RXGEN_OPCODE || code == CM_RX_RETRY_BUSY_CALL) {
/* mark server as up */ /* mark server as up */
_InterlockedAnd(&tsp->flags, ~CM_SERVERFLAG_DOWN); _InterlockedAnd(&tsp->flags, ~CM_SERVERFLAG_DOWN);
tsp->downTime = 0; tsp->downTime = 0;
/* we currently handle 32-bits of capabilities */ /* we currently handle 32-bits of capabilities */
if (code != RXGEN_OPCODE && caps.Capabilities_len > 0) { if (code != RXGEN_OPCODE && code != CM_RX_RETRY_BUSY_CALL &&
caps.Capabilities_len > 0) {
tsp->capabilities = caps.Capabilities_val[0]; tsp->capabilities = caps.Capabilities_val[0];
xdr_free((xdrproc_t) xdr_Capabilities, &caps); xdr_free((xdrproc_t) xdr_Capabilities, &caps);
caps.Capabilities_len = 0; caps.Capabilities_len = 0;
@ -455,13 +456,15 @@ static void cm_CheckServersMulti(afs_uint32 flags, cm_cell_t *cellp)
lock_ObtainMutex(&tsp->mx); lock_ObtainMutex(&tsp->mx);
wasDown = tsp->flags & CM_SERVERFLAG_DOWN; wasDown = tsp->flags & CM_SERVERFLAG_DOWN;
if (results[i] >= 0 || results[i] == RXGEN_OPCODE) { if (results[i] >= 0 || results[i] == RXGEN_OPCODE ||
results[i] == CM_RX_RETRY_BUSY_CALL) {
/* mark server as up */ /* mark server as up */
_InterlockedAnd(&tsp->flags, ~CM_SERVERFLAG_DOWN); _InterlockedAnd(&tsp->flags, ~CM_SERVERFLAG_DOWN);
tsp->downTime = 0; tsp->downTime = 0;
/* we currently handle 32-bits of capabilities */ /* we currently handle 32-bits of capabilities */
if (results[i] != RXGEN_OPCODE && caps[i].Capabilities_len > 0) { if (results[i] != RXGEN_OPCODE && results[i] != CM_RX_RETRY_BUSY_CALL &&
caps[i].Capabilities_len > 0) {
tsp->capabilities = caps[i].Capabilities_val[0]; tsp->capabilities = caps[i].Capabilities_val[0];
xdr_free((xdrproc_t) xdr_Capabilities, &caps[i]); xdr_free((xdrproc_t) xdr_Capabilities, &caps[i]);
caps[i].Capabilities_len = 0; caps[i].Capabilities_len = 0;
@ -620,7 +623,7 @@ static void cm_CheckServersMulti(afs_uint32 flags, cm_cell_t *cellp)
lock_ObtainMutex(&tsp->mx); lock_ObtainMutex(&tsp->mx);
wasDown = tsp->flags & CM_SERVERFLAG_DOWN; wasDown = tsp->flags & CM_SERVERFLAG_DOWN;
if (results[i] >= 0) { if (results[i] >= 0 || results[i] == CM_RX_RETRY_BUSY_CALL) {
/* mark server as up */ /* mark server as up */
_InterlockedAnd(&tsp->flags, ~CM_SERVERFLAG_DOWN); _InterlockedAnd(&tsp->flags, ~CM_SERVERFLAG_DOWN);
tsp->downTime = 0; tsp->downTime = 0;

View File

@ -197,6 +197,10 @@ long cm_CheckNTOpen(cm_scache_t *scp, unsigned int desiredAccess,
if (desiredAccess == DELETE) if (desiredAccess == DELETE)
goto done_2; goto done_2;
/* Always allow reading attributes (Hidden, System, Readonly, ...) */
if (desiredAccess == FILE_READ_ATTRIBUTES)
goto done_2;
if (desiredAccess & (AFS_ACCESS_READ|AFS_ACCESS_EXECUTE)) if (desiredAccess & (AFS_ACCESS_READ|AFS_ACCESS_EXECUTE))
rights |= (scp->fileType == CM_SCACHETYPE_DIRECTORY ? PRSFS_LOOKUP : PRSFS_READ); rights |= (scp->fileType == CM_SCACHETYPE_DIRECTORY ? PRSFS_LOOKUP : PRSFS_READ);
@ -1327,10 +1331,16 @@ notfound:
return code; return code;
} }
int cm_ExpandSysName(clientchar_t *inp, clientchar_t *outp, long outSizeCch, unsigned int index) int cm_ExpandSysName(cm_req_t * reqp, clientchar_t *inp, clientchar_t *outp, long outSizeCch, unsigned int index)
{ {
clientchar_t *tp; clientchar_t *tp;
int prefixCount; int prefixCount;
#ifdef _WIN64
int use_sysname64 = 0;
if (cm_sysName64Count > 0 && reqp && (reqp->flags & CM_REQ_WOW64) && (reqp->flags & CM_REQ_SOURCE_REDIR))
use_sysname64 = 1;
#endif
tp = cm_ClientStrRChr(inp, '@'); tp = cm_ClientStrRChr(inp, '@');
if (tp == NULL) if (tp == NULL)
@ -1343,6 +1353,11 @@ int cm_ExpandSysName(clientchar_t *inp, clientchar_t *outp, long outSizeCch, uns
if (outp == NULL) if (outp == NULL)
return 1; return 1;
#ifdef _WIN64
if (use_sysname64 && index >= cm_sysName64Count)
return -1;
else
#endif
if (index >= cm_sysNameCount) if (index >= cm_sysNameCount)
return -1; return -1;
@ -1350,8 +1365,14 @@ int cm_ExpandSysName(clientchar_t *inp, clientchar_t *outp, long outSizeCch, uns
prefixCount = (int)(tp - inp); prefixCount = (int)(tp - inp);
cm_ClientStrCpyN(outp, outSizeCch, inp, prefixCount); /* copy out "a." from "a.@sys" */ cm_ClientStrCpyN(outp, outSizeCch, inp, prefixCount); /* copy out "a." from "a.@sys" */
outp[prefixCount] = 0; /* null terminate the "a." */ outp[prefixCount] = 0; /* null terminate the "a." */
cm_ClientStrCat(outp, outSizeCch, cm_sysNameList[index]);/* append i386_nt40 */ #ifdef _WIN64
if (use_sysname64)
cm_ClientStrCat(outp, outSizeCch, cm_sysName64List[index]);
else
#endif
cm_ClientStrCat(outp, outSizeCch, cm_sysNameList[index]);
return 1; return 1;
} }
@ -1494,9 +1515,9 @@ long cm_Lookup(cm_scache_t *dscp, clientchar_t *namep, long flags, cm_user_t *us
return cm_EvaluateVolumeReference(namep, flags, userp, reqp, outScpp); return cm_EvaluateVolumeReference(namep, flags, userp, reqp, outScpp);
} }
if (cm_ExpandSysName(namep, NULL, 0, 0) > 0) { if (cm_ExpandSysName(reqp, namep, NULL, 0, 0) > 0) {
for ( sysNameIndex = 0; sysNameIndex < MAXNUMSYSNAMES; sysNameIndex++) { for ( sysNameIndex = 0; sysNameIndex < MAXNUMSYSNAMES; sysNameIndex++) {
code = cm_ExpandSysName(namep, tname, lengthof(tname), sysNameIndex); code = cm_ExpandSysName(reqp, namep, tname, lengthof(tname), sysNameIndex);
if (code > 0) { if (code > 0) {
code = cm_LookupInternal(dscp, tname, flags, userp, reqp, &scp); code = cm_LookupInternal(dscp, tname, flags, userp, reqp, &scp);
#ifdef DEBUG_REFCOUNT #ifdef DEBUG_REFCOUNT
@ -1654,6 +1675,11 @@ long cm_Unlink(cm_scache_t *dscp, fschar_t *fnamep, clientchar_t * cnamep,
cm_dnlcRemove(dscp, cnamep); cm_dnlcRemove(dscp, cnamep);
if (code == 0) { if (code == 0) {
cm_MergeStatus(NULL, dscp, &newDirStatus, &volSync, userp, reqp, CM_MERGEFLAG_DIROP); cm_MergeStatus(NULL, dscp, &newDirStatus, &volSync, userp, reqp, CM_MERGEFLAG_DIROP);
if (RDR_Initialized &&
scp->fileType != CM_SCACHETYPE_FILE && scp->fileType != CM_SCACHETYPE_DIRECTORY)
RDR_InvalidateObject(dscp->fid.cell, dscp->fid.volume, dscp->fid.vnode,
dscp->fid.unique, dscp->fid.hash,
dscp->fileType, AFS_INVALIDATE_DATA_VERSION);
} else if (code == CM_ERROR_NOSUCHFILE) { } else if (code == CM_ERROR_NOSUCHFILE) {
/* windows would not have allowed the request to delete the file /* windows would not have allowed the request to delete the file
* if it did not believe the file existed. therefore, we must * if it did not believe the file existed. therefore, we must
@ -1685,6 +1711,11 @@ long cm_Unlink(cm_scache_t *dscp, fschar_t *fnamep, clientchar_t * cnamep,
} }
cm_DiscardSCache(scp); cm_DiscardSCache(scp);
lock_ReleaseWrite(&scp->rw); lock_ReleaseWrite(&scp->rw);
if (RDR_Initialized && !(reqp->flags & CM_REQ_SOURCE_REDIR) &&
!RDR_InvalidateObject(scp->fid.cell, scp->fid.volume, scp->fid.vnode,
scp->fid.unique, scp->fid.hash,
scp->fileType, AFS_INVALIDATE_DELETED))
buf_ClearRDRFlag(scp, "unlink");
} }
} }
@ -2789,7 +2820,7 @@ long cm_Create(cm_scache_t *dscp, clientchar_t *cnamep, long flags, cm_attr_t *a
/* can't create names with @sys in them; must expand it manually first. /* can't create names with @sys in them; must expand it manually first.
* return "invalid request" if they try. * return "invalid request" if they try.
*/ */
if (cm_ExpandSysName(cnamep, NULL, 0, 0)) { if (cm_ExpandSysName(NULL, cnamep, NULL, 0, 0)) {
return CM_ERROR_ATSYS; return CM_ERROR_ATSYS;
} }
@ -2973,7 +3004,7 @@ long cm_MakeDir(cm_scache_t *dscp, clientchar_t *cnamep, long flags, cm_attr_t *
/* can't create names with @sys in them; must expand it manually first. /* can't create names with @sys in them; must expand it manually first.
* return "invalid request" if they try. * return "invalid request" if they try.
*/ */
if (cm_ExpandSysName(cnamep, NULL, 0, 0)) { if (cm_ExpandSysName(NULL, cnamep, NULL, 0, 0)) {
return CM_ERROR_ATSYS; return CM_ERROR_ATSYS;
} }
@ -3171,6 +3202,10 @@ long cm_Link(cm_scache_t *dscp, clientchar_t *cnamep, cm_scache_t *sscp, long fl
lock_ObtainWrite(&dscp->rw); lock_ObtainWrite(&dscp->rw);
if (code == 0) { if (code == 0) {
cm_MergeStatus(NULL, dscp, &updatedDirStatus, &volSync, userp, reqp, CM_MERGEFLAG_DIROP); cm_MergeStatus(NULL, dscp, &updatedDirStatus, &volSync, userp, reqp, CM_MERGEFLAG_DIROP);
if (RDR_Initialized)
RDR_InvalidateObject(dscp->fid.cell, dscp->fid.volume, dscp->fid.vnode,
dscp->fid.unique, dscp->fid.hash,
dscp->fileType, AFS_INVALIDATE_DATA_VERSION);
} }
cm_SyncOpDone(dscp, NULL, CM_SCACHESYNC_STOREDATA); cm_SyncOpDone(dscp, NULL, CM_SCACHESYNC_STOREDATA);
lock_ReleaseWrite(&dscp->rw); lock_ReleaseWrite(&dscp->rw);
@ -3452,6 +3487,11 @@ long cm_RemoveDir(cm_scache_t *dscp, fschar_t *fnamep, clientchar_t *cnamep, cm_
cm_RemoveSCacheFromHashTable(scp); cm_RemoveSCacheFromHashTable(scp);
lock_ReleaseWrite(&cm_scacheLock); lock_ReleaseWrite(&cm_scacheLock);
lock_ReleaseWrite(&scp->rw); lock_ReleaseWrite(&scp->rw);
if (RDR_Initialized && !(reqp->flags & CM_REQ_SOURCE_REDIR) &&
!RDR_InvalidateObject(scp->fid.cell, scp->fid.volume, scp->fid.vnode,
scp->fid.unique, scp->fid.hash,
scp->fileType, AFS_INVALIDATE_DELETED))
buf_ClearRDRFlag(scp, "rmdir");
} }
} }
@ -3830,6 +3870,9 @@ long cm_Rename(cm_scache_t *oldDscp, fschar_t *oldNamep, clientchar_t *cOldNamep
cm_DiscardSCache(oldScp); cm_DiscardSCache(oldScp);
lock_ReleaseWrite(&oldScp->rw); lock_ReleaseWrite(&oldScp->rw);
if (RDR_Initialized)
RDR_InvalidateObject(oldScp->fid.cell, oldScp->fid.volume, oldScp->fid.vnode, oldScp->fid.unique,
oldScp->fid.hash, oldScp->fileType, AFS_INVALIDATE_CALLBACK);
done: done:
if (oldScp) if (oldScp)
cm_ReleaseSCache(oldScp); cm_ReleaseSCache(oldScp);
@ -5108,6 +5151,12 @@ long cm_UnlockByKey(cm_scache_t * scp,
fileLock->flags |= CM_FILELOCK_FLAG_DELETED; fileLock->flags |= CM_FILELOCK_FLAG_DELETED;
cm_ReleaseUser(fileLock->userp);
cm_ReleaseSCacheNoLock(scp);
fileLock->userp = NULL;
fileLock->scp = NULL;
n_unlocks++; n_unlocks++;
} }
} }
@ -5122,9 +5171,9 @@ long cm_UnlockByKey(cm_scache_t * scp,
return 0; return 0;
} }
osi_Log1(afsd_logp, "cm_UnlockByKey done with %d locks", n_unlocks); code = cm_IntUnlock(scp, userp, reqp);
osi_Log1(afsd_logp, "cm_UnlockByKey code 0x%x", code); osi_Log1(afsd_logp, "cm_UnlockByKey code 0x%x", code);
osi_Log4(afsd_logp, " Leaving scp with excl[%d], shared[%d], client[%d], serverLock[%d]", osi_Log4(afsd_logp, " Leaving scp with excl[%d], shared[%d], client[%d], serverLock[%d]",
scp->exclusiveLocks, scp->sharedLocks, scp->clientLocks, scp->exclusiveLocks, scp->sharedLocks, scp->clientLocks,
(int)(signed char) scp->serverLock); (int)(signed char) scp->serverLock);
@ -5132,6 +5181,7 @@ long cm_UnlockByKey(cm_scache_t * scp,
return code; return code;
} }
/* Called with scp->rw held */
long cm_Unlock(cm_scache_t *scp, long cm_Unlock(cm_scache_t *scp,
unsigned char sLockType, unsigned char sLockType,
LARGE_INTEGER LOffset, LARGE_INTEGER LLength, LARGE_INTEGER LOffset, LARGE_INTEGER LLength,
@ -5234,8 +5284,20 @@ long cm_Unlock(cm_scache_t *scp,
} }
fileLock->flags |= CM_FILELOCK_FLAG_DELETED; fileLock->flags |= CM_FILELOCK_FLAG_DELETED;
if (userp != NULL) {
cm_ReleaseUser(fileLock->userp);
} else {
userp = fileLock->userp;
release_userp = TRUE;
}
cm_ReleaseSCacheNoLock(scp);
fileLock->userp = NULL;
fileLock->scp = NULL;
lock_ReleaseWrite(&cm_scacheLock); lock_ReleaseWrite(&cm_scacheLock);
code = cm_IntUnlock(scp, userp, reqp);
if (release_userp) { if (release_userp) {
cm_ReleaseUser(userp); cm_ReleaseUser(userp);
release_userp = FALSE; release_userp = FALSE;
@ -5321,15 +5383,16 @@ void cm_CheckLocks()
fileLock->userp = NULL; fileLock->userp = NULL;
fileLock->scp = NULL; fileLock->scp = NULL;
lock_ReleaseWrite(&cm_scacheLock); if (scp && userp) {
lock_ObtainWrite(&scp->rw); lock_ReleaseWrite(&cm_scacheLock);
code = cm_IntUnlock(scp, userp, &req); lock_ObtainWrite(&scp->rw);
lock_ReleaseWrite(&scp->rw); code = cm_IntUnlock(scp, userp, &req);
lock_ReleaseWrite(&scp->rw);
cm_ReleaseUser(fileLock->userp);
lock_ObtainWrite(&cm_scacheLock);
cm_ReleaseSCacheNoLock(scp);
cm_ReleaseUser(userp);
lock_ObtainWrite(&cm_scacheLock);
cm_ReleaseSCacheNoLock(scp);
}
osi_QRemove(&cm_allFileLocks, q); osi_QRemove(&cm_allFileLocks, q);
cm_PutFileLock(fileLock); cm_PutFileLock(fileLock);
@ -5830,7 +5893,7 @@ cm_key_t cm_GenerateKey(afs_uint16 session_id, afs_offs_t process_id, afs_uint16
int cm_KeyEquals(cm_key_t *k1, cm_key_t *k2, int flags) int cm_KeyEquals(cm_key_t *k1, cm_key_t *k2, int flags)
{ {
return (k1->session_id == k2->session_id) && (k1->file_id == k2->file_id) && return (k1->session_id == k2->session_id) && (k1->file_id == k2->file_id) &&
((flags & CM_UNLOCK_BY_FID) || (k1->process_id == k2->process_id)); ((flags & CM_UNLOCK_FLAG_BY_FID) || (k1->process_id == k2->process_id));
} }
void cm_ReleaseAllLocks(void) void cm_ReleaseAllLocks(void)

View File

@ -149,7 +149,7 @@ extern long cm_AssembleLink(cm_scache_t *linkScp, fschar_t *pathSuffixp,
cm_scache_t **newRootScpp, cm_space_t **newSpaceBufferp, cm_scache_t **newRootScpp, cm_space_t **newSpaceBufferp,
cm_user_t *userp, cm_req_t *reqp); cm_user_t *userp, cm_req_t *reqp);
extern int cm_ExpandSysName(clientchar_t *inp, clientchar_t *outp, long outSizeCch, extern int cm_ExpandSysName(cm_req_t *reqp, clientchar_t *inp, clientchar_t *outp, long outSizeCch,
unsigned int sysNameIndex); unsigned int sysNameIndex);
extern long cm_Open(cm_scache_t *scp, int type, cm_user_t *userp); extern long cm_Open(cm_scache_t *scp, int type, cm_user_t *userp);
@ -197,15 +197,14 @@ extern long cm_Lock(cm_scache_t *scp, unsigned char sLockType,
int allowWait, cm_user_t *userp, cm_req_t *reqp, int allowWait, cm_user_t *userp, cm_req_t *reqp,
cm_file_lock_t **lockpp); cm_file_lock_t **lockpp);
#define CM_UNLOCK_BY_FID 0x0001
extern long cm_UnlockByKey(cm_scache_t * scp, extern long cm_UnlockByKey(cm_scache_t * scp,
cm_key_t key, cm_key_t key,
afs_uint32 flags, afs_uint32 flags,
cm_user_t * userp, cm_user_t * userp,
cm_req_t * reqp); cm_req_t * reqp);
#define CM_UNLOCK_FLAG_MATCH_RANGE 0x01 #define CM_UNLOCK_FLAG_BY_FID 0x0001
#define CM_UNLOCK_FLAG_MATCH_RANGE 0x0002
extern long cm_Unlock(cm_scache_t *scp, unsigned char sLockType, extern long cm_Unlock(cm_scache_t *scp, unsigned char sLockType,
LARGE_INTEGER LOffset, LARGE_INTEGER LLength, cm_key_t key, LARGE_INTEGER LOffset, LARGE_INTEGER LLength, cm_key_t key,

View File

@ -46,12 +46,31 @@
#include "smb.h" #include "smb.h"
#include <WINNT/afsreg.h> #include <WINNT/afsreg.h>
extern DWORD RDR_NetworkAddrChange(void);
extern DWORD RDR_VolumeStatus(ULONG cellID, ULONG volID, BOOLEAN online);
extern DWORD RDR_NetworkStatus(BOOLEAN status);
HMODULE hVolStatus = NULL; HMODULE hVolStatus = NULL;
dll_VolStatus_Funcs_t dll_funcs; dll_VolStatus_Funcs_t dll_funcs;
cm_VolStatus_Funcs_t cm_funcs; cm_VolStatus_Funcs_t cm_funcs;
static char volstat_NetbiosName[64] = ""; static char volstat_NetbiosName[64] = "";
static DWORD RDR_Notifications = 0;
rdr_volstat_evt_t *rdr_evtH = NULL;
rdr_volstat_evt_t *rdr_evtT = NULL;
static EVENT_HANDLE rdr_q_event = NULL;
static osi_mutex_t rdr_evt_lock;
void
cm_VolStatus_SetRDRNotifications(DWORD onoff)
{
RDR_Notifications = onoff;
}
afs_uint32 afs_uint32
cm_VolStatus_Active(void) cm_VolStatus_Active(void)
{ {
@ -77,16 +96,21 @@ cm_VolStatus_Initialization(void)
code = RegQueryValueEx(parmKey, "VolStatusHandler", NULL, NULL, code = RegQueryValueEx(parmKey, "VolStatusHandler", NULL, NULL,
(BYTE *) &wd, &dummyLen); (BYTE *) &wd, &dummyLen);
if (code == 0) { if (code == ERROR_SUCCESS) {
dummyLen = sizeof(volstat_NetbiosName); dummyLen = sizeof(volstat_NetbiosName);
code = RegQueryValueEx(parmKey, "NetbiosName", NULL, NULL, code = RegQueryValueEx(parmKey, "NetbiosName", NULL, NULL,
(BYTE *)volstat_NetbiosName, &dummyLen); (BYTE *)volstat_NetbiosName, &dummyLen);
} }
if (code == ERROR_SUCCESS && wd[0])
hVolStatus = LoadLibrary(wd);
dummyLen = sizeof(wd);
code = RegQueryValueEx(parmKey, "RDRVolStatNotify", NULL, NULL,
(BYTE *) &RDR_Notifications, &dummyLen);
RegCloseKey (parmKey); RegCloseKey (parmKey);
} }
if (code == ERROR_SUCCESS && wd[0])
hVolStatus = LoadLibrary(wd);
if (hVolStatus) { if (hVolStatus) {
(FARPROC) dll_VolStatus_Initialization = GetProcAddress(hVolStatus, "@VolStatus_Initialization@8"); (FARPROC) dll_VolStatus_Initialization = GetProcAddress(hVolStatus, "@VolStatus_Initialization@8");
if (dll_VolStatus_Initialization) { if (dll_VolStatus_Initialization) {
@ -106,6 +130,23 @@ cm_VolStatus_Initialization(void)
} }
} }
if (RDR_Initialized && RDR_Notifications) {
long pid;
thread_t phandle;
lock_InitializeMutex(&rdr_evt_lock, "rdr_evt_lock", LOCK_HIERARCHY_IGNORE);
phandle = thrd_Create((SecurityAttrib) NULL, 0,
(ThreadFunc) cm_VolStatus_DeliverNotifications,
0, 0, &pid, "cm_VolStatus_DeliverNotifications");
osi_assertx(phandle != NULL, "cm_VolStatus_DeliverNotifications thread creation failure");
thrd_CloseHandle(phandle);
rdr_q_event = thrd_CreateEvent(NULL, TRUE, TRUE, "rdr_q_event");
if ( GetLastError() == ERROR_ALREADY_EXISTS )
afsi_log("Event Object Already Exists: rdr_q_event");
}
osi_Log1(afsd_logp,"cm_VolStatus_Initialization 0x%x", code); osi_Log1(afsd_logp,"cm_VolStatus_Initialization 0x%x", code);
return code; return code;
@ -119,6 +160,10 @@ cm_VolStatus_Finalize(void)
{ {
osi_Log1(afsd_logp,"cm_VolStatus_Finalize handle 0x%x", hVolStatus); osi_Log1(afsd_logp,"cm_VolStatus_Finalize handle 0x%x", hVolStatus);
if ( RDR_Initialized && RDR_Notifications ) {
CloseHandle(rdr_q_event);
}
if (hVolStatus == NULL) if (hVolStatus == NULL)
return 0; return 0;
@ -180,6 +225,18 @@ cm_VolStatus_Network_Started(const char * netbios32)
{ {
long code = 0; long code = 0;
if (RDR_Initialized && RDR_Notifications) {
rdr_volstat_evt_t *evp = (rdr_volstat_evt_t *)malloc(sizeof(rdr_volstat_evt_t));
evp->type = netstatus;
evp->netstatus_data.status = TRUE;
lock_ObtainMutex(&rdr_evt_lock);
osi_QAddH((osi_queue_t **) &rdr_evtH, (osi_queue_t **) &rdr_evtT, &evp->q);
lock_ReleaseMutex(&rdr_evt_lock);
thrd_SetEvent(rdr_q_event);
}
if (hVolStatus == NULL) if (hVolStatus == NULL)
return 0; return 0;
@ -205,6 +262,18 @@ cm_VolStatus_Network_Stopped(const char * netbios32)
{ {
long code = 0; long code = 0;
if (RDR_Initialized && RDR_Notifications) {
rdr_volstat_evt_t *evp = (rdr_volstat_evt_t *)malloc(sizeof(rdr_volstat_evt_t));
evp->type = netstatus;
evp->netstatus_data.status = FALSE;
lock_ObtainMutex(&rdr_evt_lock);
osi_QAddH((osi_queue_t **) &rdr_evtH, (osi_queue_t **) &rdr_evtT, &evp->q);
lock_ReleaseMutex(&rdr_evt_lock);
thrd_SetEvent(rdr_q_event);
}
if (hVolStatus == NULL) if (hVolStatus == NULL)
return 0; return 0;
@ -227,6 +296,17 @@ cm_VolStatus_Network_Addr_Change(void)
{ {
long code = 0; long code = 0;
if (RDR_Initialized && RDR_Notifications) {
rdr_volstat_evt_t *evp = (rdr_volstat_evt_t *)malloc(sizeof(rdr_volstat_evt_t));
evp->type = addrchg;
lock_ObtainMutex(&rdr_evt_lock);
osi_QAddH((osi_queue_t **) &rdr_evtH, (osi_queue_t **) &rdr_evtT, &evp->q);
lock_ReleaseMutex(&rdr_evt_lock);
thrd_SetEvent(rdr_q_event);
}
if (hVolStatus == NULL) if (hVolStatus == NULL)
return 0; return 0;
@ -243,6 +323,34 @@ cm_VolStatus_Change_Notification(afs_uint32 cellID, afs_uint32 volID, enum volst
{ {
long code = 0; long code = 0;
if (RDR_Initialized && RDR_Notifications) {
rdr_volstat_evt_t *evp = (rdr_volstat_evt_t *)malloc(sizeof(rdr_volstat_evt_t));
switch (status) {
case vl_alldown:
case vl_offline:
evp->type = volstatus;
evp->volstatus_data.cellID = cellID;
evp->volstatus_data.volID = volID;
evp->volstatus_data.online = FALSE;
lock_ObtainMutex(&rdr_evt_lock);
osi_QAddH((osi_queue_t **) &rdr_evtH, (osi_queue_t **) &rdr_evtT, &evp->q);
lock_ReleaseMutex(&rdr_evt_lock);
break;
default:
evp->type = volstatus;
evp->volstatus_data.cellID = cellID;
evp->volstatus_data.volID = volID;
evp->volstatus_data.online = TRUE;
lock_ObtainMutex(&rdr_evt_lock);
osi_QAddH((osi_queue_t **) &rdr_evtH, (osi_queue_t **) &rdr_evtT, &evp->q);
lock_ReleaseMutex(&rdr_evt_lock);
}
thrd_SetEvent(rdr_q_event);
}
if (hVolStatus == NULL) if (hVolStatus == NULL)
return 0; return 0;
@ -446,3 +554,38 @@ cm_VolStatus_Path_To_DFSlink(const char * share, const char * path, afs_uint32 *
osi_Log1(afsd_logp,"cm_VolStatus_Path_To_DFSlink code 0x%x",code); osi_Log1(afsd_logp,"cm_VolStatus_Path_To_DFSlink code 0x%x",code);
return code; return code;
} }
void
cm_VolStatus_DeliverNotifications(void * dummy)
{
rdr_volstat_evt_t *evp, *evprev;
afs_uint32 code;
while ( TRUE ) {
code = thrd_WaitForSingleObject_Event( rdr_q_event, INFINITE );
lock_ObtainMutex(&rdr_evt_lock);
for (evp = rdr_evtT; evp; evp = evprev)
{
evprev = (rdr_volstat_evt_t *) osi_QPrev(&evp->q);
osi_QRemoveHT((osi_queue_t **) &rdr_evtH, (osi_queue_t **) &rdr_evtT, &evp->q);
lock_ReleaseMutex(&rdr_evt_lock);
switch ( evp->type ) {
case addrchg:
RDR_NetworkAddrChange();
break;
case volstatus:
RDR_VolumeStatus(evp->volstatus_data.cellID, evp->volstatus_data.volID, evp->volstatus_data.online);
break;
case netstatus:
RDR_NetworkStatus(evp->netstatus_data.status);
break;
}
free(evp);
lock_ObtainMutex(&rdr_evt_lock);
}
lock_ReleaseMutex(&rdr_evt_lock);
}
}

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2007 Secure Endpoints Inc. * Copyright (c) 2007-2011 Secure Endpoints Inc.
* *
* All rights reserved. * All rights reserved.
* *
@ -73,6 +73,11 @@ extern long cm_VolStatus_Notify_DFS_Mapping(cm_scache_t *scp,
extern long cm_VolStatus_Invalidate_DFS_Mapping(cm_scache_t *scp); extern long cm_VolStatus_Invalidate_DFS_Mapping(cm_scache_t *scp);
extern void cm_VolStatus_DeliverNotifications(void * dummy);
extern void cm_VolStatus_SetRDRNotifications(DWORD onoff);
#define DLL_VOLSTATUS_FUNCS_VERSION 2 #define DLL_VOLSTATUS_FUNCS_VERSION 2
typedef struct dll_VolStatus_Funcs { typedef struct dll_VolStatus_Funcs {
afs_uint32 version; afs_uint32 version;
@ -112,3 +117,22 @@ struct VolStatTest {
#define VOLSTAT_TEST_NETWORK_UP 4 #define VOLSTAT_TEST_NETWORK_UP 4
#define VOLSTAT_TEST_NETWORK_DOWN 8 #define VOLSTAT_TEST_NETWORK_DOWN 8
/* redirector - native file system */
enum rdr_event_type { addrchg, volstatus, netstatus };
typedef struct rdr_volstat_evt {
osi_queue_t q;
enum rdr_event_type type;
union {
struct {
ULONG cellID;
ULONG volID;
BOOLEAN online;
} volstatus_data;
struct {
BOOLEAN status;
} netstatus_data;
};
} rdr_volstat_evt_t;

View File

@ -312,7 +312,7 @@ long cm_UpdateVolumeLocation(struct cm_cell *cellp, cm_user_t *userp, cm_req_t *
lock_ReleaseWrite(&volp->rw); lock_ReleaseWrite(&volp->rw);
if (cellp->flags & CM_CELLFLAG_VLSERVER_INVALID) if (cellp->flags & CM_CELLFLAG_VLSERVER_INVALID)
cm_UpdateCell(cellp, 0); cm_UpdateCell(cellp, 0);
/* now we have volume structure locked and held; make RPC to fill it */ /* now we have volume structure locked and held; make RPC to fill it */
code = cm_GetEntryByName(cellp, volp->namep, &vldbEntry, &nvldbEntry, code = cm_GetEntryByName(cellp, volp->namep, &vldbEntry, &nvldbEntry,

View File

@ -4839,7 +4839,7 @@ ChGrpCmd(struct cmd_syndesc *as, void *arock)
for(ti=as->parms[1].items; ti; ti=ti->next) { for(ti=as->parms[1].items; ti; ti=ti->next) {
cm_fid_t fid; cm_fid_t fid;
afs_uint32 filetype; afs_uint32 filetype;
char cell[CELL_MAXNAMELEN]; char cell[CELL_MAXNAMELEN];
/* once per file */ /* once per file */
memset(&fid, 0, sizeof(fid)); memset(&fid, 0, sizeof(fid));

View File

@ -24,17 +24,21 @@ SOFTWARE.
*/ */
#include <afsconfig.h>
#include <afs/param.h>
#include <roken.h>
//#pragma keyword("interface",on) //#pragma keyword("interface",on)
//#define interface struct //#define interface struct
#define SECURITY_WIN32 #define SECURITY_WIN32
#include "afslogon.h"
#if (_WIN32_WINNT < 0x0500) #if (_WIN32_WINNT < 0x0500)
#error _WIN32_WINNT < 0x0500 #error _WIN32_WINNT < 0x0500
#endif #endif
/**/ /**/
#include <security.h> #include <security.h>
#include <winioctl.h>
#include <sddl.h> #include <sddl.h>
#include <unknwn.h> #include <unknwn.h>
#include <oaidl.h> #include <oaidl.h>
@ -42,171 +46,177 @@ SOFTWARE.
#include <adshlp.h> #include <adshlp.h>
/**/ /**/
#include "afslogon.h"
#include "..\afsrdr\common\AFSUserDefines.h"
#include "..\afsrdr\common\AFSUserIoctl.h"
#include "..\afsrdr\common\AFSUserStructs.h"
#include "..\afsrdr\common\AFSProvider.h"
#define SEC_ERR_VALUE(v) if (status==v) return #v #define SEC_ERR_VALUE(v) if (status==v) return #v
char * _get_sec_err_text(SECURITY_STATUS status) { char * _get_sec_err_text(SECURITY_STATUS status) {
SEC_ERR_VALUE(SEC_E_OK); SEC_ERR_VALUE(SEC_E_OK);
SEC_ERR_VALUE(SEC_I_CONTINUE_NEEDED); SEC_ERR_VALUE(SEC_I_CONTINUE_NEEDED);
SEC_ERR_VALUE(SEC_I_COMPLETE_NEEDED); SEC_ERR_VALUE(SEC_I_COMPLETE_NEEDED);
SEC_ERR_VALUE(SEC_I_COMPLETE_AND_CONTINUE); SEC_ERR_VALUE(SEC_I_COMPLETE_AND_CONTINUE);
SEC_ERR_VALUE(SEC_E_INCOMPLETE_MESSAGE); SEC_ERR_VALUE(SEC_E_INCOMPLETE_MESSAGE);
SEC_ERR_VALUE(SEC_I_INCOMPLETE_CREDENTIALS); SEC_ERR_VALUE(SEC_I_INCOMPLETE_CREDENTIALS);
SEC_ERR_VALUE(SEC_E_INVALID_HANDLE); SEC_ERR_VALUE(SEC_E_INVALID_HANDLE);
SEC_ERR_VALUE(SEC_E_TARGET_UNKNOWN); SEC_ERR_VALUE(SEC_E_TARGET_UNKNOWN);
SEC_ERR_VALUE(SEC_E_LOGON_DENIED); SEC_ERR_VALUE(SEC_E_LOGON_DENIED);
SEC_ERR_VALUE(SEC_E_INTERNAL_ERROR); SEC_ERR_VALUE(SEC_E_INTERNAL_ERROR);
SEC_ERR_VALUE(SEC_E_NO_CREDENTIALS); SEC_ERR_VALUE(SEC_E_NO_CREDENTIALS);
SEC_ERR_VALUE(SEC_E_NO_AUTHENTICATING_AUTHORITY); SEC_ERR_VALUE(SEC_E_NO_AUTHENTICATING_AUTHORITY);
SEC_ERR_VALUE(SEC_E_INSUFFICIENT_MEMORY); SEC_ERR_VALUE(SEC_E_INSUFFICIENT_MEMORY);
SEC_ERR_VALUE(SEC_E_INVALID_TOKEN); SEC_ERR_VALUE(SEC_E_INVALID_TOKEN);
SEC_ERR_VALUE(SEC_E_UNSUPPORTED_FUNCTION); SEC_ERR_VALUE(SEC_E_UNSUPPORTED_FUNCTION);
SEC_ERR_VALUE(SEC_E_WRONG_PRINCIPAL); SEC_ERR_VALUE(SEC_E_WRONG_PRINCIPAL);
return "Unknown"; return "Unknown";
} }
#undef SEC_ERR_VALUE #undef SEC_ERR_VALUE
DWORD LogonSSP(PLUID lpLogonId, PCtxtHandle outCtx) { DWORD
DWORD code = 1; LogonSSP(PLUID lpLogonId, PCtxtHandle outCtx) {
DWORD code = 1;
SECURITY_STATUS status; SECURITY_STATUS status;
CredHandle creds; CredHandle creds;
CtxtHandle ctxclient,ctxserver; CtxtHandle ctxclient,ctxserver;
TimeStamp expiry; TimeStamp expiry;
BOOL cont = TRUE; BOOL cont = TRUE;
BOOL first = TRUE; BOOL first = TRUE;
SecBufferDesc sdescc,sdescs; SecBufferDesc sdescc,sdescs;
SecBuffer stokc,stoks; SecBuffer stokc,stoks;
ULONG cattrs,sattrs; ULONG cattrs,sattrs;
int iters = 10; int iters = 10;
outCtx->dwLower = 0; outCtx->dwLower = 0;
outCtx->dwUpper = 0; outCtx->dwUpper = 0;
cattrs = 0; cattrs = 0;
sattrs = 0; sattrs = 0;
status = AcquireCredentialsHandle( status = AcquireCredentialsHandle( NULL,
NULL, "Negotiate",
"Negotiate", SECPKG_CRED_BOTH,
SECPKG_CRED_BOTH, lpLogonId,
lpLogonId, NULL,
NULL, NULL,
NULL, NULL,
NULL, &creds,
&creds, &expiry);
&expiry);
if (status != SEC_E_OK) { if (status != SEC_E_OK) {
DebugEvent("AcquireCredentialsHandle failed: %lX", status); DebugEvent("AcquireCredentialsHandle failed: %lX", status);
goto ghp_0; goto ghp_0;
} }
sdescc.cBuffers = 1; sdescc.cBuffers = 1;
sdescc.pBuffers = &stokc; sdescc.pBuffers = &stokc;
sdescc.ulVersion = SECBUFFER_VERSION; sdescc.ulVersion = SECBUFFER_VERSION;
stokc.BufferType = SECBUFFER_TOKEN; stokc.BufferType = SECBUFFER_TOKEN;
stokc.cbBuffer = 0; stokc.cbBuffer = 0;
stokc.pvBuffer = NULL; stokc.pvBuffer = NULL;
sdescs.cBuffers = 1; sdescs.cBuffers = 1;
sdescs.pBuffers = &stoks; sdescs.pBuffers = &stoks;
sdescs.ulVersion = SECBUFFER_VERSION; sdescs.ulVersion = SECBUFFER_VERSION;
stoks.BufferType = SECBUFFER_TOKEN; stoks.BufferType = SECBUFFER_TOKEN;
stoks.cbBuffer = 0; stoks.cbBuffer = 0;
stoks.pvBuffer = NULL; stoks.pvBuffer = NULL;
do { do {
status = InitializeSecurityContext( status = InitializeSecurityContext( &creds,
&creds, ((first)? NULL:&ctxclient),
((first)? NULL:&ctxclient), NULL,
NULL, ISC_REQ_DELEGATE | ISC_REQ_ALLOCATE_MEMORY,
ISC_REQ_DELEGATE | ISC_REQ_ALLOCATE_MEMORY, 0,
0, SECURITY_NATIVE_DREP,
SECURITY_NATIVE_DREP, ((first)?NULL:&sdescs),
((first)?NULL:&sdescs), 0,
0, &ctxclient,
&ctxclient, &sdescc,
&sdescc, &cattrs,
&cattrs, &expiry
&expiry );
);
DebugEvent("InitializeSecurityContext returns status[%lX](%s)",status,_get_sec_err_text(status)); DebugEvent("InitializeSecurityContext returns status[%lX](%s)",status,_get_sec_err_text(status));
if (!first) FreeContextBuffer(stoks.pvBuffer); if (!first) FreeContextBuffer(stoks.pvBuffer);
if (status == SEC_I_COMPLETE_NEEDED || status == SEC_I_COMPLETE_AND_CONTINUE) { if (status == SEC_I_COMPLETE_NEEDED || status == SEC_I_COMPLETE_AND_CONTINUE) {
CompleteAuthToken(&ctxclient, &sdescc); CompleteAuthToken(&ctxclient, &sdescc);
} }
if (status != SEC_I_CONTINUE_NEEDED && status != SEC_I_COMPLETE_AND_CONTINUE) { if (status != SEC_I_CONTINUE_NEEDED && status != SEC_I_COMPLETE_AND_CONTINUE) {
cont = FALSE; cont = FALSE;
} }
if (!stokc.cbBuffer && !cont) { if (!stokc.cbBuffer && !cont) {
DebugEvent("Breaking out after InitializeSecurityContext"); DebugEvent("Breaking out after InitializeSecurityContext");
break; break;
} }
status = AcceptSecurityContext( status = AcceptSecurityContext( &creds,
&creds, ((first)?NULL:&ctxserver),
((first)?NULL:&ctxserver), &sdescc,
&sdescc, ASC_REQ_DELEGATE | ASC_REQ_ALLOCATE_MEMORY,
ASC_REQ_DELEGATE | ASC_REQ_ALLOCATE_MEMORY, SECURITY_NATIVE_DREP,
SECURITY_NATIVE_DREP, &ctxserver,
&ctxserver, &sdescs,
&sdescs, &sattrs,
&sattrs, &expiry);
&expiry);
DebugEvent("AcceptSecurityContext returns status[%lX](%s)", status, _get_sec_err_text(status)); DebugEvent("AcceptSecurityContext returns status[%lX](%s)", status, _get_sec_err_text(status));
FreeContextBuffer(stokc.pvBuffer); FreeContextBuffer(stokc.pvBuffer);
if (status == SEC_I_COMPLETE_NEEDED || status == SEC_I_COMPLETE_AND_CONTINUE) { if (status == SEC_I_COMPLETE_NEEDED || status == SEC_I_COMPLETE_AND_CONTINUE) {
CompleteAuthToken(&ctxserver,&sdescs); CompleteAuthToken(&ctxserver,&sdescs);
} }
if (status == SEC_I_CONTINUE_NEEDED || status == SEC_I_COMPLETE_AND_CONTINUE) { if (status == SEC_I_CONTINUE_NEEDED || status == SEC_I_COMPLETE_AND_CONTINUE) {
cont = TRUE; cont = TRUE;
} }
if (!cont) if (!cont)
FreeContextBuffer(stoks.pvBuffer); FreeContextBuffer(stoks.pvBuffer);
first = FALSE; first = FALSE;
iters--; /* just in case, hard limit on loop */ iters--; /* just in case, hard limit on loop */
} while (cont && iters); } while (cont && iters);
if (sattrs & ASC_RET_DELEGATE) { if (sattrs & ASC_RET_DELEGATE) {
DebugEvent("Received delegate context"); DebugEvent("Received delegate context");
*outCtx = ctxserver; *outCtx = ctxserver;
code = 0; code = 0;
} else { } else {
DebugEvent("Didn't receive delegate context"); DebugEvent("Didn't receive delegate context");
outCtx->dwLower = 0; outCtx->dwLower = 0;
outCtx->dwUpper = 0; outCtx->dwUpper = 0;
DeleteSecurityContext(&ctxserver); DeleteSecurityContext(&ctxserver);
} }
DeleteSecurityContext(&ctxclient); DeleteSecurityContext(&ctxclient);
FreeCredentialsHandle(&creds); FreeCredentialsHandle(&creds);
ghp_0: ghp_0:
return code; return code;
} }
DWORD QueryAdHomePathFromSid(char * homePath, size_t homePathLen, PSID psid, PWSTR domain) { DWORD
DWORD code = 1; /* default is failure */ QueryAdHomePathFromSid(char * homePath, size_t homePathLen, PSID psid, PWSTR domain) {
NTSTATUS rv = 0; DWORD code = 1; /* default is failure */
HRESULT hr = S_OK; NTSTATUS rv = 0;
LPWSTR p = NULL; HRESULT hr = S_OK;
WCHAR adsPath[MAX_PATH] = L""; LPWSTR p = NULL;
BOOL coInitialized = FALSE; WCHAR adsPath[MAX_PATH] = L"";
BOOL coInitialized = FALSE;
CHAR ansidomain[256], *a; CHAR ansidomain[256], *a;
homePath[0] = '\0'; homePath[0] = '\0';
/* I trust this is an ASCII domain name */ /* I trust this is an ASCII domain name */
for ( p=domain, a=ansidomain; *a = (CHAR)*p; p++, a++); for ( p=domain, a=ansidomain; *a = (CHAR)*p; p++, a++);
@ -227,7 +237,9 @@ DWORD QueryAdHomePathFromSid(char * homePath, size_t homePathLen, PSID psid, PWS
IID_IADsNameTranslate, IID_IADsNameTranslate,
(void**)&pNto); (void**)&pNto);
if (FAILED(hr)) { DebugEvent("Can't create nametranslate object"); } if (FAILED(hr)) {
DebugEvent("Can't create nametranslate object");
}
else { else {
hr = pNto->Init(ADS_NAME_INITTYPE_GC,L""); hr = pNto->Init(ADS_NAME_INITTYPE_GC,L"");
if (FAILED(hr)) { if (FAILED(hr)) {
@ -242,7 +254,9 @@ DWORD QueryAdHomePathFromSid(char * homePath, size_t homePathLen, PSID psid, PWS
if (!FAILED(hr)) { if (!FAILED(hr)) {
hr = pNto->Set(ADS_NAME_TYPE_SID_OR_SID_HISTORY_NAME, p); hr = pNto->Set(ADS_NAME_TYPE_SID_OR_SID_HISTORY_NAME, p);
if (FAILED(hr)) { DebugEvent("Can't set sid string"); } if (FAILED(hr)) {
DebugEvent("Can't set sid string");
}
else { else {
BSTR bstr; BSTR bstr;
@ -262,103 +276,104 @@ DWORD QueryAdHomePathFromSid(char * homePath, size_t homePathLen, PSID psid, PWS
} }
LocalFree(p); LocalFree(p);
} else { } else {
DebugEvent("Can't convert sid to string"); DebugEvent("Can't convert sid to string");
} }
if (adsPath[0]) { if (adsPath[0]) {
WCHAR fAdsPath[MAX_PATH]; WCHAR fAdsPath[MAX_PATH];
IADsUser *pAdsUser; IADsUser *pAdsUser;
BSTR bstHomeDir = NULL; BSTR bstHomeDir = NULL;
hr = StringCchPrintfW(fAdsPath, MAX_PATH, L"LDAP://%s", adsPath); hr = StringCchPrintfW(fAdsPath, MAX_PATH, L"LDAP://%s", adsPath);
if (hr != S_OK) { if (hr != S_OK) {
DebugEvent("Can't format full adspath"); DebugEvent("Can't format full adspath");
goto cleanup; goto cleanup;
} }
DebugEvent("Trying adsPath=[%S]", fAdsPath); DebugEvent("Trying adsPath=[%S]", fAdsPath);
hr = ADsGetObject( fAdsPath, IID_IADsUser, (LPVOID *) &pAdsUser); hr = ADsGetObject( fAdsPath, IID_IADsUser, (LPVOID *) &pAdsUser);
if (hr != S_OK) { if (hr != S_OK) {
DebugEvent("Can't open IADs object"); DebugEvent("Can't open IADs object");
goto cleanup; goto cleanup;
} }
hr = pAdsUser->get_Profile(&bstHomeDir); hr = pAdsUser->get_Profile(&bstHomeDir);
if (hr != S_OK) { if (hr != S_OK) {
DebugEvent("Can't get profile directory"); DebugEvent("Can't get profile directory");
goto cleanup_homedir_section; goto cleanup_homedir_section;
} }
wcstombs(homePath, bstHomeDir, homePathLen); wcstombs(homePath, bstHomeDir, homePathLen);
DebugEvent("Got homepath [%s]", homePath); DebugEvent("Got homepath [%s]", homePath);
SysFreeString(bstHomeDir); SysFreeString(bstHomeDir);
code = 0; code = 0;
cleanup_homedir_section: cleanup_homedir_section:
pAdsUser->Release(); pAdsUser->Release();
} }
cleanup: cleanup:
if (coInitialized) if (coInitialized)
CoUninitialize(); CoUninitialize();
return code; return code;
} }
/* Try to determine the user's AD home path. *homePath is assumed to be at least MAXPATH bytes. /* Try to determine the user's AD home path. *homePath is assumed to be at least MAXPATH bytes.
If successful, opt.flags is updated with LOGON_FLAG_AD_REALM to indicate that we are dealing with If successful, opt.flags is updated with LOGON_FLAG_AD_REALM to indicate that we are dealing with
an AD realm. */ an AD realm. */
DWORD GetAdHomePath(char * homePath, size_t homePathLen, PLUID lpLogonId, LogonOptions_t * opt) { DWORD
CtxtHandle ctx; GetAdHomePath(char * homePath, size_t homePathLen, PLUID lpLogonId, LogonOptions_t * opt) {
DWORD code = 0; CtxtHandle ctx;
SECURITY_STATUS status; DWORD code = 0;
SECURITY_STATUS status;
homePath[0] = '\0'; homePath[0] = '\0';
if (LogonSSP(lpLogonId,&ctx)) { if (LogonSSP(lpLogonId,&ctx)) {
DebugEvent("Failed LogonSSP"); DebugEvent("Failed LogonSSP");
return 1; return 1;
} else { }
status = ImpersonateSecurityContext(&ctx);
if (status == SEC_E_OK) {
PSECURITY_LOGON_SESSION_DATA plsd;
NTSTATUS rv;
rv = LsaGetLogonSessionData(lpLogonId, &plsd); status = ImpersonateSecurityContext(&ctx);
if (rv == 0) { if (status == SEC_E_OK) {
PWSTR domain; PSECURITY_LOGON_SESSION_DATA plsd;
NTSTATUS rv;
domain = (PWSTR)malloc(sizeof(WCHAR) * (plsd->LogonDomain.Length+1)); rv = LsaGetLogonSessionData(lpLogonId, &plsd);
memcpy(domain, plsd->LogonDomain.Buffer, sizeof(WCHAR) * (plsd->LogonDomain.Length)); if (rv == 0) {
domain[plsd->LogonDomain.Length] = 0; PWSTR domain;
if (!QueryAdHomePathFromSid(homePath,homePathLen,plsd->Sid,domain)) { domain = (PWSTR)malloc(sizeof(WCHAR) * (plsd->LogonDomain.Length+1));
DebugEvent("Returned home path [%s]",homePath); memcpy(domain, plsd->LogonDomain.Buffer, sizeof(WCHAR) * (plsd->LogonDomain.Length));
opt->flags |= LOGON_FLAG_AD_REALM; domain[plsd->LogonDomain.Length] = 0;
}
free(domain); if (!QueryAdHomePathFromSid(homePath,homePathLen,plsd->Sid,domain)) {
LsaFreeReturnBuffer(plsd); DebugEvent("Returned home path [%s]",homePath);
} else { opt->flags |= LOGON_FLAG_AD_REALM;
DebugEvent("LsaGetLogonSessionData failed [%lX]", rv);
} }
RevertSecurityContext(&ctx); free(domain);
} else { LsaFreeReturnBuffer(plsd);
DebugEvent("Can't impersonate context [%lX]",status); } else {
code = 1; DebugEvent("LsaGetLogonSessionData failed [%lX]", rv);
} }
RevertSecurityContext(&ctx);
} else {
DebugEvent("Can't impersonate context [%lX]",status);
code = 1;
}
DeleteSecurityContext(&ctx); DeleteSecurityContext(&ctx);
return code; return code;
}
} }
BOOL GetLocalShortDomain(PWSTR Domain, DWORD cbDomain) BOOL
GetLocalShortDomain(PWSTR Domain, DWORD cbDomain)
{ {
HRESULT hr; HRESULT hr;
IADsADSystemInfo *pADsys; IADsADSystemInfo *pADsys;
@ -369,7 +384,7 @@ BOOL GetLocalShortDomain(PWSTR Domain, DWORD cbDomain)
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
coInitialized = TRUE; coInitialized = TRUE;
hr = CoCreateInstance(CLSID_ADSystemInfo, hr = CoCreateInstance( CLSID_ADSystemInfo,
NULL, NULL,
CLSCTX_INPROC_SERVER, CLSCTX_INPROC_SERVER,
IID_IADsADSystemInfo, IID_IADsADSystemInfo,
@ -388,8 +403,260 @@ BOOL GetLocalShortDomain(PWSTR Domain, DWORD cbDomain)
pADsys->Release(); pADsys->Release();
} }
if (coInitialized) if (coInitialized)
CoUninitialize(); CoUninitialize();
return retval; return retval;
} }
static HANDLE
OpenRedirector(void)
{
HANDLE hControlDevice = NULL;
hControlDevice = CreateFileW( AFS_SYMLINK_W,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0,
NULL );
if( hControlDevice == INVALID_HANDLE_VALUE)
{
hControlDevice = NULL;
DebugEvent("OpenRedirector Failed to open control device error: %d",
GetLastError());
}
return hControlDevice;
}
void
AFSCreatePAG(PLUID lpLogonId)
{
BOOLEAN bRet = FALSE;
HANDLE hControlDevice = NULL;
DWORD dwCopyBytes = 0;
AFSAuthGroupRequestCB *pAuthGroup = NULL;
WCHAR * pwchSIDString = NULL;
CtxtHandle ctx;
SECURITY_STATUS status;
PSECURITY_LOGON_SESSION_DATA plsd = NULL;
NTSTATUS rv;
BOOLEAN bImpersonated = FALSE;
GUID stAuthGroup;
unsigned char *pchGUID = NULL;
DWORD bytesReturned;
if (LogonSSP(lpLogonId, &ctx)) {
DebugEvent("AFSCreatePAG unable to obtain LogonSSP context");
return;
}
status = ImpersonateSecurityContext(&ctx);
if (status == SEC_E_OK)
{
bImpersonated = TRUE;
rv = LsaGetLogonSessionData(lpLogonId, &plsd);
if (rv == 0)
{
if( !ConvertSidToStringSidW( plsd->Sid,
&pwchSIDString))
{
DebugEvent("AFSCreatePAG Failed to convert sid to string Error %08X", GetLastError());
goto cleanup;
}
pAuthGroup = (AFSAuthGroupRequestCB *)LocalAlloc( LPTR, 0x1000);
if( pAuthGroup == NULL)
{
DebugEvent0("AFSCreatePAG Failed auth group allocation");
goto cleanup;
}
memset( pAuthGroup, 0, 0x1000);
pAuthGroup->SIDLength = (USHORT) (wcslen( pwchSIDString) * sizeof( WCHAR));
pAuthGroup->SessionId = plsd->Session;
memcpy( pAuthGroup->SIDString,
pwchSIDString,
pAuthGroup->SIDLength);
RevertSecurityContext(&ctx);
bImpersonated = FALSE;
hControlDevice = OpenRedirector();
if( hControlDevice == NULL)
{
DebugEvent0("AFSCreatePAG Failed to open redirector");
goto cleanup;
}
bRet = DeviceIoControl( hControlDevice,
IOCTL_AFS_AUTHGROUP_SID_QUERY,
NULL,
0,
&stAuthGroup,
sizeof( GUID),
&bytesReturned,
NULL);
if( bRet == FALSE)
{
DebugEvent("AFSCreatePAG Failed IOCTL_AFS_AUTHGROUP_SID_QUERY Error 0x%08X", GetLastError());
}
else
{
if( UuidToString( (UUID *)&stAuthGroup,
&pchGUID) == RPC_S_OK)
{
DebugEvent("AFSCreatePAG Initial AuthGroup %s\n", pchGUID);
RpcStringFree( &pchGUID);
}
else
{
DebugEvent0("AFSCreatePAG Failed to convert GUID to string\n");
}
}
ImpersonateSecurityContext(&ctx); bImpersonated = TRUE;
bRet = DeviceIoControl( hControlDevice,
IOCTL_AFS_AUTHGROUP_SID_QUERY,
NULL,
0,
&stAuthGroup,
sizeof( GUID),
&bytesReturned,
NULL);
if( bRet == FALSE)
{
DebugEvent("AFSCreatePAG Failed IOCTL_AFS_AUTHGROUP_SID_QUERY Impersonation Error 0x%08X", GetLastError());
}
else
{
if( UuidToString( (UUID *)&stAuthGroup,
&pchGUID) == RPC_S_OK)
{
DebugEvent("AFSCreatePAG Initial Impersonation AuthGroup %s\n", pchGUID);
RpcStringFree( &pchGUID);
}
else
{
DebugEvent0("AFSCreatePAG Failed to convert GUID to string\n");
}
}
RevertSecurityContext(&ctx); bImpersonated = FALSE;
bRet = DeviceIoControl( hControlDevice,
IOCTL_AFS_AUTHGROUP_LOGON_CREATE,
pAuthGroup,
sizeof( AFSAuthGroupRequestCB) + pAuthGroup->SIDLength - 1,
NULL,
0,
&dwCopyBytes,
NULL);
if( bRet == FALSE)
{
DebugEvent("AFSCreatePAG Failed IOCTL_AFS_AUTHGROUP_SID_CREATE Error 0x%08X", GetLastError());
}
else
{
bRet = DeviceIoControl( hControlDevice,
IOCTL_AFS_AUTHGROUP_SID_QUERY,
NULL,
0,
&stAuthGroup,
sizeof( GUID),
&bytesReturned,
NULL);
if( bRet == FALSE)
{
DebugEvent("AFSCreatePAG Failed IOCTL_AFS_AUTHGROUP_SID_QUERY Error 0x%08X", GetLastError());
}
else
{
if( UuidToString( (UUID *)&stAuthGroup,
&pchGUID) == RPC_S_OK)
{
DebugEvent("AFSCreatePAG New AuthGroup %s\n", pchGUID);
RpcStringFree( &pchGUID);
}
else
{
DebugEvent0("AFSCreatePAG Failed to convert GUID to string\n");
}
}
}
ImpersonateSecurityContext(&ctx);
bRet = DeviceIoControl( hControlDevice,
IOCTL_AFS_AUTHGROUP_SID_QUERY,
NULL,
0,
&stAuthGroup,
sizeof( GUID),
&bytesReturned,
NULL);
if( bRet == FALSE)
{
DebugEvent("AFSCreatePAG Failed IOCTL_AFS_AUTHGROUP_SID_QUERY Impersonation Error 0x%08X", GetLastError());
}
else
{
if( UuidToString( (UUID *)&stAuthGroup,
&pchGUID) == RPC_S_OK)
{
DebugEvent("AFSCreatePAG New Impersonation AuthGroup %s\n", pchGUID);
RpcStringFree( &pchGUID);
}
else
{
DebugEvent0("AFSCreatePAG Failed to convert GUID to string\n");
}
}
RevertSecurityContext(&ctx);
}
else
{
DebugEvent("AFSCreatePAG LsaGetLogonSessionData failed [%lX]", rv);
}
}
else
{
DebugEvent("AFSCreatePAG cannot impersonate context [%lX]", status);
}
cleanup:
if (bImpersonated)
RevertSecurityContext(&ctx);
DeleteSecurityContext(&ctx);
if (plsd != NULL)
LsaFreeReturnBuffer(plsd);
if ( hControlDevice != NULL)
CloseHandle( hControlDevice);
if( pwchSIDString != NULL)
LocalFree( pwchSIDString);
}

View File

@ -3117,11 +3117,11 @@ void smb_MapNTError(long code, unsigned long *NTStatusp, afs_uint32 redir)
NTStatus = 0xC000022DL; /* Retry */ NTStatus = 0xC000022DL; /* Retry */
else { else {
#ifdef COMMENT #ifdef COMMENT
NTStatus = 0xC000022DL; /* Retry */ NTStatus = 0xC000022DL; /* Retry */
#else #else
NTStatus = 0xC00000B5L; /* I/O Timeout */ NTStatus = 0xC00000B5L; /* I/O Timeout */
#endif #endif
} }
} }
else if (code == CM_ERROR_NOACCESS) { else if (code == CM_ERROR_NOACCESS) {
NTStatus = 0xC0000022L; /* Access denied */ NTStatus = 0xC0000022L; /* Access denied */
@ -3281,7 +3281,10 @@ void smb_MapNTError(long code, unsigned long *NTStatusp, afs_uint32 redir)
else if (code == CM_ERROR_RPC_MOREDATA) { else if (code == CM_ERROR_RPC_MOREDATA) {
NTStatus = 0x80000005L; /* Buffer overflow */ NTStatus = 0x80000005L; /* Buffer overflow */
} }
else { else {
char foo[256];
sprintf(foo, "No mapping for 0x%X using 0xC0982001\r\n", code);
OutputDebugString(foo);
NTStatus = 0xC0982001L; /* SMB non-specific error */ NTStatus = 0xC0982001L; /* SMB non-specific error */
} }
@ -6932,8 +6935,10 @@ long smb_CloseFID(smb_vc_t *vcp, smb_fid_t *fidp, cm_user_t *userp,
lock_ReleaseMutex(&fidp->mx); lock_ReleaseMutex(&fidp->mx);
/* CM_UNLOCK_BY_FID doesn't look at the process ID. We pass /*
* in zero. */ * CM_UNLOCK_FLAG_BY_FID doesn't look at the process ID.
* We pass in zero.
*/
key = cm_GenerateKey(vcp->vcID, 0, fidp->fid); key = cm_GenerateKey(vcp->vcID, 0, fidp->fid);
lock_ObtainWrite(&scp->rw); lock_ObtainWrite(&scp->rw);
@ -6948,7 +6953,7 @@ long smb_CloseFID(smb_vc_t *vcp, smb_fid_t *fidp, cm_user_t *userp,
goto post_syncopdone; goto post_syncopdone;
} }
cm_UnlockByKey(scp, key, CM_UNLOCK_BY_FID, userp, &req); cm_UnlockByKey(scp, key, CM_UNLOCK_FLAG_BY_FID, userp, &req);
cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_LOCK); cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_LOCK);

View File

@ -1087,6 +1087,8 @@ long smb_ReceiveV3SessionSetupX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *
* be freed when the refCount returns to zero. * be freed when the refCount returns to zero.
*/ */
unp->flags &= ~SMB_USERNAMEFLAG_AFSLOGON; unp->flags &= ~SMB_USERNAMEFLAG_AFSLOGON;
if (usernIsSID)
unp->flags |= SMB_USERNAMEFLAG_SID;
} }
if (usernIsSID) if (usernIsSID)
unp->flags |= SMB_USERNAMEFLAG_SID; unp->flags |= SMB_USERNAMEFLAG_SID;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,195 @@
/*
* Copyright (c) 2008 Secure Endpoints, Inc.
* Copyright (c) 2009-2011 Your File System, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither the name of Secure Endpoints Inc. nor the names of its contributors
* may be used to endorse or promote products derived from this software without
* specific prior written permission from Secure Endpoints, Inc. and
* Your File System, Inc.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
extern void RDR_InitIoctl(void);
extern void RDR_SetupIoctl(ULONG index, cm_fid_t *parentFid, cm_fid_t *rootFid, cm_user_t *userp);
extern void RDR_CleanupIoctl(ULONG index);
extern afs_int32 RDR_IoctlRead(cm_user_t *userp, ULONG RequestId, ULONG BufferLength, void *MappedBuffer,
ULONG *pBytesProcessed, cm_req_t *reqp, afs_uint32 pflags);
extern afs_int32 RDR_IoctlWrite(cm_user_t *userp, ULONG RequestId, ULONG BufferLength, void *MappedBuffer,
cm_req_t *reqp);
#ifdef RDR_IOCTL_PRIVATE
typedef struct RDR_ioctl {
struct RDR_ioctl *next, *prev;
ULONG index;
cm_fid_t parentFid;
cm_fid_t rootFid;
cm_scache_t *parentScp;
cm_ioctl_t ioctl;
} RDR_ioctl_t;
/* procedure implementing an ioctl */
typedef long (RDR_ioctlProc_t)(RDR_ioctl_t *, struct cm_user *userp, afs_uint32 pflags);
extern void RDR_IoctlPrepareWrite(RDR_ioctl_t *ioctlp);
extern afs_int32 RDR_IoctlPrepareRead(RDR_ioctl_t *ioctlp, cm_user_t *userp, afs_uint32 pflags);
extern RDR_ioctl_t *RDR_FindIoctl(ULONG index);
extern afs_int32 RDR_ParseIoctlPath(RDR_ioctl_t *ioctlp, cm_user_t *userp, cm_req_t *reqp,
cm_scache_t **scpp, afs_uint32 flags);
extern afs_int32 RDR_ParseIoctlParent(RDR_ioctl_t *ioctlp, cm_user_t *userp, cm_req_t *reqp,
cm_scache_t **scpp, wchar_t *leafp);
extern afs_int32
RDR_IoctlSetToken(struct RDR_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags);
extern afs_int32 RDR_IoctlGetACL(RDR_ioctl_t *ioctlp, cm_user_t *userp, afs_uint32 pflags);
extern afs_int32 RDR_IoctlGetFileCellName(RDR_ioctl_t *ioctlp, cm_user_t *userp, afs_uint32 pflags);
extern afs_int32 RDR_IoctlSetACL(RDR_ioctl_t *ioctlp, cm_user_t *userp, afs_uint32 pflags);
extern afs_int32 RDR_IoctlFlushAllVolumes(RDR_ioctl_t *ioctlp, cm_user_t *userp, afs_uint32 pflags);
extern afs_int32 RDR_IoctlFlushVolume(RDR_ioctl_t *ioctlp, cm_user_t *userp, afs_uint32 pflags);
extern afs_int32 RDR_IoctlFlushFile(RDR_ioctl_t *ioctlp, cm_user_t *userp, afs_uint32 pflags);
extern afs_int32 RDR_IoctlSetVolumeStatus(RDR_ioctl_t *ioctlp, cm_user_t *userp, afs_uint32 pflags);
extern afs_int32 RDR_IoctlGetVolumeStatus(RDR_ioctl_t *ioctlp, cm_user_t *userp, afs_uint32 pflags);
extern afs_int32 RDR_IoctlGetFid(RDR_ioctl_t *ioctlp, cm_user_t *userp, afs_uint32 pflags);
extern afs_int32 RDR_IoctlGetOwner(RDR_ioctl_t *ioctlp, cm_user_t *userp, afs_uint32 pflags);
extern afs_int32 RDR_IoctlWhereIs(RDR_ioctl_t *ioctlp, cm_user_t *userp, afs_uint32 pflags);
extern afs_int32 RDR_IoctlStatMountPoint(RDR_ioctl_t *ioctlp, cm_user_t *userp, afs_uint32 pflags);
extern afs_int32 RDR_IoctlDeleteMountPoint(RDR_ioctl_t *ioctlp, cm_user_t *userp, afs_uint32 pflags);
extern afs_int32 RDR_IoctlCheckServers(RDR_ioctl_t *ioctlp, cm_user_t *userp, afs_uint32 pflags);
extern afs_int32 RDR_IoctlGag(RDR_ioctl_t *ioctlp, cm_user_t *userp, afs_uint32 pflags);
extern afs_int32 RDR_IoctlCheckVolumes(RDR_ioctl_t *ioctlp, cm_user_t *userp, afs_uint32 pflags);
extern afs_int32 RDR_IoctlSetCacheSize(RDR_ioctl_t *ioctlp, cm_user_t *userp, afs_uint32 pflags);
extern afs_int32 RDR_IoctlGetCacheParms(RDR_ioctl_t *ioctlp, cm_user_t *userp, afs_uint32 pflags);
extern afs_int32 RDR_IoctlGetCell(RDR_ioctl_t *ioctlp, cm_user_t *userp, afs_uint32 pflags);
extern afs_int32 RDR_IoctlNewCell(RDR_ioctl_t *ioctlp, cm_user_t *userp, afs_uint32 pflags);
extern afs_int32 RDR_IoctlNewCell2(RDR_ioctl_t *ioctlp, cm_user_t *userp, afs_uint32 pflags);
extern afs_int32 RDR_IoctlGetWsCell(RDR_ioctl_t *ioctlp, cm_user_t *userp, afs_uint32 pflags);
extern afs_int32 RDR_IoctlSysName(RDR_ioctl_t *ioctlp, cm_user_t *userp, afs_uint32 pflags);
extern afs_int32 RDR_IoctlGetCellStatus(RDR_ioctl_t *ioctlp, cm_user_t *userp, afs_uint32 pflags);
extern afs_int32 RDR_IoctlSetCellStatus(RDR_ioctl_t *ioctlp, cm_user_t *userp, afs_uint32 pflags);
extern afs_int32 RDR_IoctlSetSPrefs(RDR_ioctl_t *ioctlp, cm_user_t *userp, afs_uint32 pflags);
extern afs_int32 RDR_IoctlGetSPrefs(RDR_ioctl_t *ioctlp, cm_user_t *userp, afs_uint32 pflags);
extern afs_int32 RDR_IoctlStoreBehind(RDR_ioctl_t *ioctlp, cm_user_t *userp, afs_uint32 pflags);
extern afs_int32 RDR_IoctlCreateMountPoint(RDR_ioctl_t *ioctlp, cm_user_t *userp, afs_uint32 pflags);
extern afs_int32 cm_CleanFile(cm_scache_t *scp, cm_user_t *userp, cm_req_t *reqp);
extern afs_int32 cm_FlushFile(cm_scache_t *scp, cm_user_t *userp, cm_req_t *reqp);
extern afs_int32 cm_FlushVolume(cm_user_t *, cm_req_t *reqp, afs_uint32 cell, afs_uint32 volume);
extern afs_int32 cm_FlushParent(cm_scache_t *scp, cm_user_t *userp, cm_req_t *reqp);
extern afs_int32 RDR_IoctlTraceControl(RDR_ioctl_t *ioctlp, cm_user_t *userp, afs_uint32 pflags);
extern afs_int32 RDR_IoctlSetToken(RDR_ioctl_t *ioctlp, cm_user_t *userp, afs_uint32 pflags);
extern afs_int32 RDR_IoctlGetTokenIter(RDR_ioctl_t *ioctlp, cm_user_t *userp, afs_uint32 pflags);
extern afs_int32 RDR_IoctlGetToken(RDR_ioctl_t *ioctlp, cm_user_t *userp, afs_uint32 pflags);
extern afs_int32 RDR_IoctlDelToken(RDR_ioctl_t *ioctlp, cm_user_t *userp, afs_uint32 pflags);
extern afs_int32 RDR_IoctlDelAllToken(RDR_ioctl_t *ioctlp, cm_user_t *userp, afs_uint32 pflags);
extern afs_int32 RDR_IoctlSymlink(RDR_ioctl_t *ioctlp, cm_user_t *userp, afs_uint32 pflags);
extern afs_int32 RDR_IoctlIslink(RDR_ioctl_t *ioctlp, cm_user_t *userp, afs_uint32 pflags);
extern afs_int32 RDR_IoctlListlink(RDR_ioctl_t *ioctlp, cm_user_t *userp, afs_uint32 pflags);
extern afs_int32 RDR_IoctlDeletelink(RDR_ioctl_t *ioctlp, cm_user_t *userp, afs_uint32 pflags);
extern afs_int32 RDR_IoctlMakeSubmount(RDR_ioctl_t *ioctlp, cm_user_t *userp, afs_uint32 pflags);
extern afs_int32 RDR_IoctlGetRxkcrypt(RDR_ioctl_t *ioctlp, cm_user_t *userp, afs_uint32 pflags);
extern afs_int32 RDR_IoctlSetRxkcrypt(RDR_ioctl_t *ioctlp, cm_user_t *userp, afs_uint32 pflags);
extern afs_int32 RDR_IoctlShutdown(RDR_ioctl_t *ioctlp, cm_user_t *userp, afs_uint32 pflags);
extern afs_int32 RDR_IoctlFreemountAddCell(RDR_ioctl_t *ioctlp, cm_user_t *userp, afs_uint32 pflags);
extern afs_int32 RDR_IoctlFreemountRemoveCell(RDR_ioctl_t *ioctlp, cm_user_t *userp, afs_uint32 pflags);
extern afs_int32 RDR_IoctlMemoryDump(RDR_ioctl_t *ioctlp, cm_user_t *userp, afs_uint32 pflags);
extern afs_int32 RDR_IoctlRxStatProcess(RDR_ioctl_t *ioctlp, cm_user_t *userp, afs_uint32 pflags);
extern afs_int32 RDR_IoctlRxStatPeer(RDR_ioctl_t *ioctlp, cm_user_t *userp, afs_uint32 pflags);
extern afs_int32 RDR_IoctlUUIDControl(struct RDR_ioctl * ioctlp, struct cm_user *userp, afs_uint32 pflags);
extern afs_int32 RDR_IoctlPathAvailability(struct RDR_ioctl * ioctlp, struct cm_user *userp, afs_uint32 pflags);
extern afs_int32 RDR_IoctlGetFileType(RDR_ioctl_t *ioctlp, cm_user_t *userp, afs_uint32 pflags);
extern afs_int32 RDR_IoctlVolStatTest(struct RDR_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags);
extern afs_int32 RDR_IoctlUnicodeControl(struct RDR_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags);
extern afs_int32 RDR_IoctlSetOwner(RDR_ioctl_t *ioctlp, cm_user_t *userp, afs_uint32 pflags);
extern afs_int32 RDR_IoctlSetGroup(RDR_ioctl_t *ioctlp, cm_user_t *userp, afs_uint32 pflags);
extern afs_int32 RDR_IoctlGetUnixMode(RDR_ioctl_t *ioctlp, cm_user_t *userp, afs_uint32 pflags);
extern afs_int32 RDR_IoctlSetUnixMode(RDR_ioctl_t *ioctlp, cm_user_t *userp, afs_uint32 pflags);
#endif

View File

@ -0,0 +1,351 @@
/*
* Copyright (c) 2008 Secure Endpoints, Inc.
* Copyright (c) 2009-2011 Your File System, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither the name of Secure Endpoints Inc. nor the names of its contributors
* may be used to endorse or promote products derived from this software without
* specific prior written permission from Secure Endpoints, Inc. and
* Your File System, Inc.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <afsconfig.h>
#include <afs/param.h>
#include <ntstatus.h>
#define WIN32_NO_STATUS
#include <roken.h>
#include <afs/stds.h>
#include <windows.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
#include <stdio.h>
#include <time.h>
#include <strsafe.h>
#include <osi.h>
#include "afsd.h"
#include "cm_rpc.h"
#include "afs/afsrpc.h"
#include "afs/auth.h"
#include "msrpc.h"
#define RDR_PIPE_PRIVATE
#include "RDRPipe.h"
#include "smb.h"
#include "cm_nls.h"
static RDR_pipe_t * RDR_allPipes = NULL, *RDR_allPipesLast = NULL;
static osi_rwlock_t RDR_globalPipeLock;
static wchar_t RDR_UNCName[64]=L"AFS";
void
RDR_InitPipe(void)
{
lock_InitializeRWLock(&RDR_globalPipeLock, "RDR global pipe lock", LOCK_HIERARCHY_RDR_GLOBAL);
}
RDR_pipe_t *
RDR_FindPipe(ULONG index, int locked)
{
RDR_pipe_t *pipep;
if ( !locked)
lock_ObtainRead(&RDR_globalPipeLock);
for ( pipep=RDR_allPipes; pipep; pipep=pipep->next) {
if (pipep->index == index)
break;
}
if ( !locked)
lock_ReleaseRead(&RDR_globalPipeLock);
return pipep;
}
/* called to make a fid structure into an Pipe fid structure */
DWORD
RDR_SetupPipe( ULONG index, cm_fid_t *parentFid, cm_fid_t *rootFid,
WCHAR *Name, DWORD NameLength,
cm_user_t *userp)
{
RDR_pipe_t *pipep;
cm_req_t req;
DWORD status;
char name[MAX_PATH];
cm_InitReq(&req);
lock_ObtainWrite(&RDR_globalPipeLock);
pipep = RDR_FindPipe(index, TRUE);
if (pipep) {
/* we are reusing a previous pipe */
if (cm_FidCmp(&pipep->parentFid, parentFid)) {
pipep->parentFid = *parentFid;
if (pipep->parentScp) {
cm_ReleaseSCache(pipep->parentScp);
pipep->parentScp = NULL;
}
cm_GetSCache(parentFid, &pipep->parentScp, userp, &req);
pipep->rootFid = *rootFid;
}
} else {
/* need to allocate a new one */
pipep = malloc(sizeof(*pipep));
if (pipep == NULL) {
status = STATUS_NO_MEMORY;
goto done;
}
memset(pipep, 0, sizeof(*pipep));
if (RDR_allPipes == NULL)
RDR_allPipes = RDR_allPipesLast = pipep;
else {
pipep->prev = RDR_allPipesLast;
RDR_allPipesLast->next = pipep;
RDR_allPipesLast = pipep;
}
pipep->index = index;
if (parentFid->cell == 0) {
pipep->parentFid = cm_data.rootFid;
pipep->parentScp = cm_RootSCachep(userp, &req);
cm_HoldSCache(pipep->parentScp);
} else {
pipep->parentFid = *parentFid;
cm_GetSCache(parentFid, &pipep->parentScp, userp, &req);
}
if (rootFid->cell == 0) {
pipep->rootFid = cm_data.rootFid;
} else {
pipep->rootFid = *rootFid;
}
}
StringCbCopyNW( pipep->name, sizeof(pipep->name), Name, NameLength);
cm_Utf16ToUtf8( pipep->name, -1, name, sizeof(name));
status = MSRPC_InitConn(&pipep->rpc_conn, name);
if (status == STATUS_SUCCESS) {
pipep->flags |= RDR_PIPEFLAG_MESSAGE_MODE;
pipep->devstate = RDR_DEVICESTATE_READMSGFROMPIPE |
RDR_DEVICESTATE_MESSAGEMODEPIPE |
RDR_DEVICESTATE_PIPECLIENTEND;
}
done:
lock_ReleaseWrite(&RDR_globalPipeLock);
return status;
}
void
RDR_CleanupPipe(ULONG index)
{
RDR_pipe_t *pipep;
lock_ObtainWrite(&RDR_globalPipeLock);
pipep = RDR_FindPipe(index, TRUE);
if (pipep) {
if (pipep->parentScp)
cm_ReleaseSCache(pipep->parentScp);
if (pipep->inAllocp)
free(pipep->inAllocp);
if (pipep->outAllocp)
free(pipep->outAllocp);
MSRPC_FreeConn(&pipep->rpc_conn);
if (RDR_allPipes == RDR_allPipesLast)
RDR_allPipes = RDR_allPipesLast = NULL;
else {
if (pipep->prev == NULL)
RDR_allPipes = pipep->next;
else
pipep->prev->next = pipep->next;
if (pipep->next == NULL) {
RDR_allPipesLast = pipep->prev;
pipep->prev->next = NULL;
} else
pipep->next->prev = pipep->prev;
}
free(pipep);
}
lock_ReleaseWrite(&RDR_globalPipeLock);
}
DWORD
RDR_Pipe_Read(ULONG index, ULONG BufferLength, void *MappedBuffer,
ULONG *pBytesProcessed, cm_req_t *reqp, cm_user_t *userp)
{
RDR_pipe_t *pipep;
DWORD code = STATUS_INVALID_PIPE_STATE;
lock_ObtainWrite(&RDR_globalPipeLock);
pipep = RDR_FindPipe(index, TRUE);
if (pipep) {
code = MSRPC_PrepareRead(&pipep->rpc_conn);
if (code == 0) {
*pBytesProcessed = MSRPC_ReadMessageLength(&pipep->rpc_conn, BufferLength);
code = MSRPC_ReadMessage(&pipep->rpc_conn, MappedBuffer, *pBytesProcessed);
}
}
lock_ReleaseWrite(&RDR_globalPipeLock);
return code;
}
DWORD
RDR_Pipe_Write( ULONG index, ULONG BufferLength, void *MappedBuffer,
cm_req_t *reqp, cm_user_t *userp)
{
RDR_pipe_t *pipep;
DWORD code = STATUS_INVALID_PIPE_STATE;
lock_ObtainWrite(&RDR_globalPipeLock);
pipep = RDR_FindPipe(index, TRUE);
if (pipep) {
code = MSRPC_WriteMessage( &pipep->rpc_conn, MappedBuffer,
BufferLength, userp);
}
lock_ReleaseWrite(&RDR_globalPipeLock);
return code;
}
DWORD
RDR_Pipe_QueryInfo( ULONG index, ULONG InfoClass,
ULONG BufferLength, void *MappedBuffer,
ULONG *pBytesProcessed, cm_req_t *reqp, cm_user_t *userp)
{
RDR_pipe_t *pipep;
DWORD code = STATUS_INVALID_PIPE_STATE;
size_t length;
lock_ObtainWrite(&RDR_globalPipeLock);
pipep = RDR_FindPipe(index, TRUE);
if (pipep) {
switch ( InfoClass ) {
case FileBasicInformation: {
FILE_BASIC_INFORMATION * fbInfo = (FILE_BASIC_INFORMATION *)MappedBuffer;
memset(fbInfo, 0, sizeof(FILE_BASIC_INFORMATION));
fbInfo->FileAttributes = FILE_ATTRIBUTE_NORMAL;
*pBytesProcessed = (DWORD)(sizeof(FILE_BASIC_INFORMATION));
code = STATUS_SUCCESS;
break;
}
case FileStandardInformation: {
FILE_STANDARD_INFORMATION * fsInfo = (FILE_STANDARD_INFORMATION *)MappedBuffer;
memset(fsInfo, 0, sizeof(FILE_STANDARD_INFORMATION));
*pBytesProcessed = (DWORD)(sizeof(FILE_STANDARD_INFORMATION));
code = STATUS_SUCCESS;
break;
}
case FileNameInformation: {
FILE_NAME_INFORMATION * fnInfo = (FILE_NAME_INFORMATION *)MappedBuffer;
StringCbLengthW(pipep->name, sizeof(pipep->name), &length);
if (BufferLength < sizeof(FILE_NAME_INFORMATION) + length) {
code = STATUS_BUFFER_OVERFLOW;
goto done;
}
fnInfo->FileNameLength = (DWORD)length;
memcpy( fnInfo->FileName, pipep->name, length);
*pBytesProcessed = (DWORD)(sizeof(DWORD) + length);
code = STATUS_SUCCESS;
break;
}
default:
code = STATUS_NOT_SUPPORTED;
}
}
done:
lock_ReleaseWrite(&RDR_globalPipeLock);
if (code)
*pBytesProcessed = 0;
return code;
}
DWORD
RDR_Pipe_SetInfo( ULONG index, ULONG InfoClass,
ULONG BufferLength, void *MappedBuffer,
cm_req_t *reqp, cm_user_t *userp)
{
RDR_pipe_t *pipep;
DWORD code = STATUS_INVALID_PIPE_STATE;
lock_ObtainWrite(&RDR_globalPipeLock);
pipep = RDR_FindPipe(index, TRUE);
if (pipep) {
switch ( InfoClass ) {
case FilePipeInformation: {
FILE_PIPE_INFORMATION * fpInfo = (FILE_PIPE_INFORMATION *)MappedBuffer;
if (BufferLength != sizeof(FILE_PIPE_INFORMATION)) {
code = STATUS_INFO_LENGTH_MISMATCH;
goto done;
}
switch ( fpInfo->ReadMode ) {
case FILE_PIPE_BYTE_STREAM_MODE:
pipep->flags &= ~RDR_PIPEFLAG_MESSAGE_MODE;
break;
case FILE_PIPE_MESSAGE_MODE:
pipep->flags |= RDR_PIPEFLAG_MESSAGE_MODE;
break;
}
switch ( fpInfo->CompletionMode ) {
case FILE_PIPE_QUEUE_OPERATION:
pipep->flags |= RDR_PIPEFLAG_BLOCKING;
break;
case FILE_PIPE_COMPLETE_OPERATION:
pipep->flags &= ~RDR_PIPEFLAG_BLOCKING;
break;
}
code = STATUS_SUCCESS;
break;
}
default:
code = STATUS_NOT_SUPPORTED;
}
}
done:
lock_ReleaseWrite(&RDR_globalPipeLock);
return code;
}

View File

@ -0,0 +1,244 @@
/*
* Copyright (c) 2008 Secure Endpoints, Inc.
* Copyright (c) 2009-2011 Your File System, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither the name of Secure Endpoints Inc. nor the names of its contributors
* may be used to endorse or promote products derived from this software without
* specific prior written permission from Secure Endpoints, Inc. and
* Your File System, Inc.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
extern void RDR_InitPipe(void);
extern DWORD RDR_SetupPipe( ULONG index, cm_fid_t *parentFid, cm_fid_t *rootFid,
WCHAR *Name, DWORD NameLength,
cm_user_t *userp);
extern void RDR_CleanupPipe(ULONG index);
extern DWORD RDR_Pipe_Read(ULONG index, ULONG BufferLength, void *MappedBuffer,
ULONG *pBytesProcessed, cm_req_t *reqp, cm_user_t *userp);
extern DWORD RDR_Pipe_Write(ULONG index, ULONG BufferLength, void *MappedBuffer,
cm_req_t *reqp, cm_user_t *userp);
extern DWORD RDR_Pipe_QueryInfo( ULONG index, ULONG InfoClass,
ULONG BufferLength, void *MappedBuffer,
ULONG *pBytesProcessed, cm_req_t *reqp, cm_user_t *userp);
extern DWORD RDR_Pipe_SetInfo( ULONG index, ULONG InfoClass,
ULONG BufferLength, void *MappedBuffer,
cm_req_t *reqp, cm_user_t *userp);
#ifdef RDR_PIPE_PRIVATE
typedef struct RDR_pipe {
struct RDR_pipe *next, *prev;
ULONG index;
wchar_t name[MAX_PATH];
cm_fid_t parentFid;
cm_fid_t rootFid;
cm_scache_t *parentScp;
afs_uint32 flags;
afs_uint32 devstate;
msrpc_conn rpc_conn;
/* input side */
char *inDatap; /* current position
* in input parameter block */
char *inAllocp; /* allocated input parameter block */
afs_uint32 inCopied; /* # of input bytes copied in so far
* by write calls */
/* output side */
char *outDatap; /* output results assembled so far */
char *outAllocp; /* output results assembled so far */
afs_uint32 outCopied; /* # of output bytes copied back so far */
} RDR_pipe_t;
/* flags for smb_ioctl_t */
#define RDR_PIPEFLAG_DATAIN 1 /* reading data from client to server */
#define RDR_PIPEFLAG_LOGON 2 /* got tokens from integrated logon */
#define RDR_PIPEFLAG_USEUTF8 4 /* this request is using UTF-8 strings */
#define RDR_PIPEFLAG_DATAOUT 8 /* sending data from server to client */
#define RDR_PIPEFLAG_RPC 0x0010
#define RDR_PIPEFLAG_MESSAGE_MODE 0x0020
#define RDR_PIPEFLAG_BLOCKING 0x0040
#define RDR_PIPEFLAG_INCALL 0x0080
/* Device state constants */
#define RDR_DEVICESTATE_READASBYTESTREAM 0x0000
#define RDR_DEVICESTATE_READMSGFROMPIPE 0x0100
#define RDR_DEVICESTATE_BYTESTREAMPIPE 0x0000
#define RDR_DEVICESTATE_MESSAGEMODEPIPE 0x0400
#define RDR_DEVICESTATE_PIPECLIENTEND 0x0000
#define RDR_DEVICESTATE_PIPESERVEREND 0x4000
#define RDR_DEVICESTATE_BLOCKING 0x8000
#define RDR_PIPE_MAXDATA 65536
/* procedure implementing an pipe */
typedef long (RDR_pipeProc_t)(RDR_pipe_t *, struct cm_user *userp);
extern RDR_pipe_t *RDR_FindPipe(ULONG index, int locked);
/*
* DDK Data Structures
*
* This is a userland module and does not include DDK headers.
* Replicate the DDK Data Structures required for pipe handling
* based on [MS-FSC]: File System Control Codes
* http://msdn.microsoft.com/en-us/library/cc231987%28v=PROT.13%29.aspx
*/
typedef enum _FILE_INFORMATION_CLASS {
FileDirectoryInformation = 1,
FileFullDirectoryInformation, // 2
FileBothDirectoryInformation, // 3
FileBasicInformation, // 4
FileStandardInformation, // 5
FileInternalInformation, // 6
FileEaInformation, // 7
FileAccessInformation, // 8
FileNameInformation, // 9
FileRenameInformation, // 10
FileLinkInformation, // 11
FileNamesInformation, // 12
FileDispositionInformation, // 13
FilePositionInformation, // 14
FileFullEaInformation, // 15
FileModeInformation, // 16
FileAlignmentInformation, // 17
FileAllInformation, // 18
FileAllocationInformation, // 19
FileEndOfFileInformation, // 20
FileAlternateNameInformation, // 21
FileStreamInformation, // 22
FilePipeInformation, // 23
FilePipeLocalInformation, // 24
FilePipeRemoteInformation, // 25
FileMailslotQueryInformation, // 26
FileMailslotSetInformation, // 27
FileCompressionInformation, // 28
FileObjectIdInformation, // 29
FileCompletionInformation, // 30
FileMoveClusterInformation, // 31
FileQuotaInformation, // 32
FileReparsePointInformation, // 33
FileNetworkOpenInformation, // 34
FileAttributeTagInformation, // 35
FileTrackingInformation, // 36
FileIdBothDirectoryInformation, // 37
FileIdFullDirectoryInformation, // 38
FileValidDataLengthInformation, // 39
FileShortNameInformation, // 40
FileIoCompletionNotificationInformation, // 41
FileIoStatusBlockRangeInformation, // 42
FileIoPriorityHintInformation, // 43
FileSfioReserveInformation, // 44
FileSfioVolumeInformation, // 45
FileHardLinkInformation, // 46
FileProcessIdsUsingFileInformation, // 47
FileNormalizedNameInformation, // 48
FileNetworkPhysicalNameInformation, // 49
FileIdGlobalTxDirectoryInformation, // 50
FileIsRemoteDeviceInformation, // 51
FileAttributeCacheInformation, // 52
FileNumaNodeInformation, // 53
FileStandardLinkInformation, // 54
FileRemoteProtocolInformation, // 55
FileMaximumInformation
} FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS;
typedef struct _FILE_BASIC_INFORMATION {
LARGE_INTEGER CreationTime;
LARGE_INTEGER LastAccessTime;
LARGE_INTEGER LastWriteTime;
LARGE_INTEGER ChangeTime;
ULONG FileAttributes;
} FILE_BASIC_INFORMATION, *PFILE_BASIC_INFORMATION;
typedef struct _FILE_STANDARD_INFORMATION {
LARGE_INTEGER AllocationSize;
LARGE_INTEGER EndOfFile;
ULONG NumberOfLinks;
BOOLEAN DeletePending;
BOOLEAN IsDirectory;
} FILE_STANDARD_INFORMATION, *PFILE_STANDARD_INFORMATION;
typedef struct _FILE_NAME_INFORMATION {
ULONG FileNameLength;
WCHAR FileName[1];
} FILE_NAME_INFORMATION, *PFILE_NAME_INFORMATION;
typedef struct _FILE_PIPE_INFORMATION {
ULONG ReadMode;
ULONG CompletionMode;
} FILE_PIPE_INFORMATION, *PFILE_PIPE_INFORMATION;
typedef struct _FILE_PIPE_LOCAL_INFORMATION {
ULONG NamedPipeType;
ULONG NamedPipeConfiguration;
ULONG MaximumInstances;
ULONG CurrentInstances;
ULONG InboundQuota;
ULONG ReadDataAvailable;
ULONG OutboundQuota;
ULONG WriteQuotaAvailable;
ULONG NamedPipeState;
ULONG NamedPipeEnd;
} FILE_PIPE_LOCAL_INFORMATION, *PFILE_PIPE_LOCAL_INFORMATION;
typedef struct _FILE_PIPE_REMOTE_INFORMATION {
LARGE_INTEGER CollectDataTime;
ULONG MaximumCollectionCount;
} FILE_PIPE_REMOTE_INFORMATION, *PFILE_PIPE_REMOTE_INFORMATION;
#define FILE_PIPE_BYTE_STREAM_TYPE 0x00000000
#define FILE_PIPE_MESSAGE_TYPE 0x00000001
#define FILE_PIPE_ACCEPT_REMOTE_CLIENTS 0x00000000
#define FILE_PIPE_REJECT_REMOTE_CLIENTS 0x00000002
#define FILE_PIPE_TYPE_VALID_MASK 0x00000003
#define FILE_PIPE_QUEUE_OPERATION 0x00000000
#define FILE_PIPE_COMPLETE_OPERATION 0x00000001
#define FILE_PIPE_BYTE_STREAM_MODE 0x00000000
#define FILE_PIPE_MESSAGE_MODE 0x00000001
#define FILE_PIPE_INBOUND 0x00000000
#define FILE_PIPE_OUTBOUND 0x00000001
#define FILE_PIPE_FULL_DUPLEX 0x00000002
#define FILE_PIPE_DISCONNECTED_STATE 0x00000001
#define FILE_PIPE_LISTENING_STATE 0x00000002
#define FILE_PIPE_CONNECTED_STATE 0x00000003
#define FILE_PIPE_CLOSING_STATE 0x00000004
#define FILE_PIPE_CLIENT_END 0x00000000
#define FILE_PIPE_SERVER_END 0x00000001
#define FILE_PIPE_READ_DATA 0x00000000
#define FILE_PIPE_WRITE_SPACE 0x00000001
#endif

View File

@ -0,0 +1,360 @@
/*
* Copyright (c) 2008 Secure Endpoints, Inc.
* Copyright (c) 2009-2011 Your File System, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither the name of Secure Endpoints Inc. nor the names of its contributors
* may be used to endorse or promote products derived from this software without
* specific prior written permission from Secure Endpoints, Inc. and
* Your File System, Inc.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef __cplusplus
extern "C" {
#endif
#include <ntsecapi.h>
// The following are forward declarations of structures
// which are referenced in the RDR code only by pointer.
typedef struct cm_user cm_user_t;
typedef struct cm_req cm_req_t;
typedef struct cm_fid cm_fid_t;
typedef struct cm_scache cm_scache_t;
// Function Declarations
#include <../common/AFSUserPrototypes.h>
void
RDR_InitReq( IN OUT cm_req_t *reqp );
DWORD
RDR_SetInitParams( OUT AFSRedirectorInitInfo **ppRedirInitInfo,
OUT DWORD * pRedirInitInfoLen );
DWORD
WINAPI
RDR_RequestWorkerThread( LPVOID lpParameter);
DWORD
RDR_ProcessWorkerThreads( IN DWORD);
void
RDR_ProcessRequest( AFSCommRequest *RequestBuffer);
void
RDR_EnumerateDirectory( IN cm_user_t *userp,
IN AFSFileID ParentID,
IN AFSDirQueryCB *QueryCB,
IN BOOL bWow64,
IN BOOL bQueryStatus,
IN DWORD ResultBufferLength,
IN OUT AFSCommResult **ResultCB);
void
RDR_EvaluateNodeByName( IN cm_user_t *userp,
IN AFSFileID ParentID,
IN WCHAR *Name,
IN DWORD NameLength,
IN BOOL CaseSensitive,
IN BOOL bWow64,
IN BOOL bQueryStatus,
IN BOOL bHoldFid,
IN DWORD ResultBufferLength,
IN OUT AFSCommResult **ResultCB);
void
RDR_EvaluateNodeByID( IN cm_user_t *userp,
IN AFSFileID ParentID,
IN AFSFileID SourceID,
IN BOOL bWow64,
IN BOOL bQueryStatus,
IN BOOL bHoldFid,
IN DWORD ResultBufferLength,
IN OUT AFSCommResult **ResultCB);
void
RDR_CreateFileEntry( IN cm_user_t *userp,
IN WCHAR *FileName,
IN DWORD FileNameLength,
IN AFSFileCreateCB *CreateCB,
IN BOOL bWow64,
IN BOOL bHoldFid,
IN DWORD ResultBufferLength,
IN OUT AFSCommResult **ResultCB);
void
RDR_UpdateFileEntry( IN cm_user_t *userp,
IN AFSFileID FileId,
IN AFSFileUpdateCB *UpdateCB,
IN BOOL bWow64,
IN DWORD ResultBufferLength,
IN OUT AFSCommResult **ResultCB);
void
RDR_DeleteFileEntry( IN cm_user_t *userp,
IN AFSFileID ParentId,
IN ULONGLONG ProcessId,
IN WCHAR *FileName,
IN DWORD FileNameLength,
IN BOOL bWow64,
IN BOOL bCheckOnly,
IN DWORD ResultBufferLength,
IN OUT AFSCommResult **ResultCB);
void
RDR_RenameFileEntry( IN cm_user_t *userp,
IN WCHAR *SourceFileName,
IN DWORD SourceFileNameLength,
IN AFSFileID SourceFileId,
IN AFSFileRenameCB *RenameCB,
IN BOOL bWow64,
IN DWORD ResultBufferLength,
IN OUT AFSCommResult **ResultCB);
void
RDR_FlushFileEntry( IN cm_user_t *userp,
IN AFSFileID FileId,
IN BOOL bWow64,
IN DWORD ResultBufferLength,
IN OUT AFSCommResult **ResultCB);
void
RDR_OpenFileEntry( IN cm_user_t *userp,
IN AFSFileID FileId,
IN AFSFileOpenCB *OpenCB,
IN BOOL bWow64,
IN BOOL bHoldFid,
IN DWORD ResultBufferLength,
IN OUT AFSCommResult **ResultCB);
void
RDR_CleanupFileEntry( IN cm_user_t *userp,
IN AFSFileID FileId,
IN WCHAR *FileName,
IN DWORD FileNameLength,
IN AFSFileCleanupCB *CleanupCB,
IN BOOL bWow64,
IN BOOL bFlushFile,
IN BOOL bDeleteFile,
IN BOOL bUnlockFile,
IN DWORD ResultBufferLength,
IN OUT AFSCommResult **ResultCB);
BOOL
RDR_RequestFileExtentsAsync( IN cm_user_t *userp,
IN AFSFileID FileId,
IN AFSRequestExtentsCB *RequestExtentsCB,
IN BOOL bWow64,
IN OUT DWORD * ResultBufferLength,
IN OUT AFSSetFileExtentsCB **ResultCB);
void
RDR_ReleaseFileExtents( IN cm_user_t *userp,
IN AFSFileID FileId,
IN AFSReleaseExtentsCB *ReleaseExtentsCB,
IN BOOL bWow64,
IN DWORD ResultBufferLength,
IN OUT AFSCommResult **ResultCB);
DWORD
RDR_RequestExtentRelease( IN cm_fid_t *fidp,
IN LARGE_INTEGER numOfHeldExtents,
IN DWORD numOfExtents,
IN AFSFileExtentCB *extentList);
DWORD
RDR_ProcessReleaseFileExtentsResult( IN AFSReleaseFileExtentsResultCB *ReleaseFileExtentsResultCB,
IN DWORD ResultBufferLength);
DWORD
RDR_ReleaseFailedSetFileExtents( IN cm_user_t *userp,
IN AFSSetFileExtentsCB *SetFileExtentsResultCB,
IN DWORD ResultBufferLength);
DWORD
RDR_SetFileExtents( IN AFSSetFileExtentsCB *pSetFileExtentsResultCB,
IN DWORD dwResultBufferLength);
void
RDR_PioctlOpen( IN cm_user_t *userp,
IN AFSFileID ParentId,
IN AFSPIOCtlOpenCloseRequestCB *pPioctlCB,
IN BOOL bWow64,
IN DWORD ResultBufferLength,
IN OUT AFSCommResult **ResultCB);
void
RDR_PioctlClose( IN cm_user_t *userp,
IN AFSFileID ParentId,
IN AFSPIOCtlOpenCloseRequestCB *pPioctlCB,
IN BOOL bWow64,
IN DWORD ResultBufferLength,
IN OUT AFSCommResult **ResultCB);
void
RDR_PioctlWrite( IN cm_user_t *userp,
IN AFSFileID ParentId,
IN AFSPIOCtlIORequestCB *pPioctlCB,
IN BOOL bWow64,
IN DWORD ResultBufferLength,
IN OUT AFSCommResult **ResultCB);
void
RDR_PioctlRead( IN cm_user_t *userp,
IN AFSFileID ParentId,
IN AFSPIOCtlIORequestCB *pPioctlCB,
IN BOOL bWow64,
IN BOOL bIsLocalSystem,
IN DWORD ResultBufferLength,
IN OUT AFSCommResult **ResultCB);
void
RDR_ByteRangeLockSync( IN cm_user_t *userp,
IN AFSFileID FileId,
IN AFSByteRangeLockRequestCB *pBRLRequestCB,
IN BOOL bWow64,
IN DWORD ResultBufferLength,
IN OUT AFSCommResult **ResultCB);
void
RDR_ByteRangeUnlock( IN cm_user_t *userp,
IN AFSFileID FileId,
IN AFSByteRangeUnlockRequestCB *pBRURequestCB,
IN BOOL bWow64,
IN DWORD ResultBufferLength,
IN OUT AFSCommResult **ResultCB);
void
RDR_ByteRangeUnlockAll( IN cm_user_t *userp,
IN AFSFileID FileId,
IN AFSByteRangeUnlockRequestCB *pBRURequestCB,
IN BOOL bWow64,
IN DWORD ResultBufferLength,
IN OUT AFSCommResult **ResultCB);
void
RDR_GetVolumeInfo( IN cm_user_t *userp,
IN AFSFileID FileId,
IN BOOL bWow64,
IN DWORD ResultBufferLength,
IN OUT AFSCommResult **ResultCB);
void
RDR_HoldFid( IN cm_user_t *userp,
IN AFSHoldFidRequestCB * pHoldFidCB,
IN BOOL bFast,
IN DWORD ResultBufferLength,
IN OUT AFSCommResult **ResultCB);
void
RDR_ReleaseFid( IN cm_user_t *userp,
IN AFSReleaseFidRequestCB * pReleaseFidCB,
IN BOOL bFast,
IN DWORD ResultBufferLength,
IN OUT AFSCommResult **ResultCB);
void
RDR_PipeOpen( IN cm_user_t *userp,
IN AFSFileID ParentId,
IN WCHAR *Name,
IN DWORD NameLength,
IN AFSPipeOpenCloseRequestCB *pPipeCB,
IN BOOL bWow64,
IN DWORD ResultBufferLength,
IN OUT AFSCommResult **ResultCB);
void
RDR_PipeClose( IN cm_user_t *userp,
IN AFSFileID ParentId,
IN AFSPipeOpenCloseRequestCB *pPipeCB,
IN BOOL bWow64,
IN DWORD ResultBufferLength,
IN OUT AFSCommResult **ResultCB);
void
RDR_PipeWrite( IN cm_user_t *userp,
IN AFSFileID ParentId,
IN AFSPipeIORequestCB *pPipeCB,
IN BYTE *pPipeData,
IN BOOL bWow64,
IN DWORD ResultBufferLength,
IN OUT AFSCommResult **ResultCB);
void
RDR_PipeRead( IN cm_user_t *userp,
IN AFSFileID ParentId,
IN AFSPipeIORequestCB *pPipeCB,
IN BOOL bWow64,
IN DWORD ResultBufferLength,
IN OUT AFSCommResult **ResultCB);
void
RDR_PipeSetInfo( IN cm_user_t *userp,
IN AFSFileID ParentId,
IN AFSPipeInfoRequestCB *pPipeCB,
IN BYTE *pPipeData,
IN BOOL bWow64,
IN DWORD ResultBufferLength,
IN OUT AFSCommResult **ResultCB);
void
RDR_PipeQueryInfo( IN cm_user_t *userp,
IN AFSFileID ParentId,
IN AFSPipeInfoRequestCB *pPipeCB,
IN BOOL bWow64,
IN DWORD ResultBufferLength,
IN OUT AFSCommResult **ResultCB);
void
RDR_PipeTransceive( IN cm_user_t *userp,
IN AFSFileID ParentId,
IN AFSPipeIORequestCB *pPipeCB,
IN BYTE *pPipeData,
IN BOOL bWow64,
IN DWORD ResultBufferLength,
IN OUT AFSCommResult **ResultCB);
cm_user_t *
RDR_UserFromCommRequest( IN AFSCommRequest * pRequest);
cm_user_t *
RDR_UserFromAuthGroup( IN GUID *pGuid);
void
RDR_ReleaseUser( IN cm_user_t *userp);
void
RDR_fid2FID( IN cm_fid_t *fid,
IN AFSFileID *FileId);
void
RDR_FID2fid( IN AFSFileID *FileId,
IN cm_fid_t *fid);
void
RDR_InitIoctl(void);
#ifdef __cplusplus
}
#endif