#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h>
+#include <strsafe.h>
#include <osi.h>
#include "afsd.h"
#include "smb.h"
#include "cm_rpc.h"
#include "lanahelper.h"
+#include "afsicf.h"
extern int RXAFSCB_ExecuteRequest(struct rx_call *z_call);
extern int RXSTATS_ExecuteRequest(struct rx_call *z_call);
cm_initparams_v1 cm_initParams;
+char *cm_sysName = 0;
+int cm_sysNameCount = 0;
+char *cm_sysNameList[MAXNUMSYSNAMES];
+
+DWORD TraceOption = 0;
+
/*
* AFSD Initialization Log
*
char t[100], u[100], *p, *path;
int zilch;
int code;
+ DWORD dwLow, dwHigh;
+ HKEY parmKey;
+ DWORD dummyLen;
+ DWORD maxLogSize = 100 * 1024;
afsi_file = INVALID_HANDLE_VALUE;
if (getenv("TEMP"))
{
- strcpy(wd, getenv("TEMP"));
+ StringCbCopyA(wd, sizeof(wd), getenv("TEMP"));
}
else
{
code = GetWindowsDirectory(wd, sizeof(wd));
if (code == 0) return;
}
- strcat(wd, "\\afsd_init.log");
+ StringCbCatA(wd, sizeof(wd), "\\afsd_init.log");
GetTimeFormat(LOCALE_SYSTEM_DEFAULT, 0, NULL, NULL, t, sizeof(t));
afsi_file = CreateFile(wd, GENERIC_WRITE, FILE_SHARE_READ, NULL,
OPEN_ALWAYS, FILE_FLAG_WRITE_THROUGH, NULL);
+
+ code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSConfigKeyName,
+ 0, KEY_QUERY_VALUE, &parmKey);
+ if (code == ERROR_SUCCESS) {
+ dummyLen = sizeof(maxLogSize);
+ code = RegQueryValueEx(parmKey, "MaxLogSize", NULL, NULL,
+ (BYTE *) &maxLogSize, &dummyLen);
+ RegCloseKey (parmKey);
+ }
+
+ if (maxLogSize) {
+ dwLow = GetFileSize( afsi_file, &dwHigh );
+ if ( dwHigh > 0 || dwLow >= maxLogSize ) {
+ CloseHandle(afsi_file);
+ afsi_file = CreateFile( wd, GENERIC_WRITE, FILE_SHARE_READ, NULL,
+ CREATE_ALWAYS, FILE_FLAG_WRITE_THROUGH, NULL);
+ }
+ }
+
SetFilePointer(afsi_file, 0, NULL, FILE_END);
GetTimeFormat(LOCALE_SYSTEM_DEFAULT, 0, NULL, NULL, u, sizeof(u));
- strcat(t, ": Create log file\n");
- strcat(u, ": Created log file\n");
+ StringCbCatA(t, sizeof(t), ": Create log file\n");
+ StringCbCatA(u, sizeof(u), ": Created log file\n");
WriteFile(afsi_file, t, strlen(t), &zilch, NULL);
WriteFile(afsi_file, u, strlen(u), &zilch, NULL);
p = "PATH=";
void
afsi_log(char *pattern, ...)
{
- char s[100], t[100], d[100], u[300];
+ char s[256], t[100], d[100], u[512];
int zilch;
va_list ap;
va_start(ap, pattern);
- vsprintf(s, pattern, ap);
+ StringCbVPrintfA(s, sizeof(s), pattern, ap);
if ( afsi_log_useTimestamp ) {
GetTimeFormat(LOCALE_SYSTEM_DEFAULT, 0, NULL, NULL, t, sizeof(t));
GetDateFormat(LOCALE_SYSTEM_DEFAULT, 0, NULL, NULL, d, sizeof(d));
- sprintf(u, "%s %s: %s\n", d, t, s);
+ StringCbPrintfA(u, sizeof(u), "%s %s: %s\n", d, t, s);
if (afsi_file != INVALID_HANDLE_VALUE)
WriteFile(afsi_file, u, strlen(u), &zilch, NULL);
#ifdef NOTSERVICE
return;
len = GetTempPath(sizeof(buf)-10, buf);
- strcpy(&buf[len], "/afsd.log");
+ StringCbCopyA(&buf[len], sizeof(buf)-len, "/afsd.log");
handle = CreateFile(buf, GENERIC_WRITE, FILE_SHARE_READ,
NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (handle == INVALID_HANDLE_VALUE) {
CloseHandle(handle);
}
+static void
+configureBackConnectionHostNames(void)
+{
+ /* On Windows XP SP2, Windows 2003 SP1, and all future Windows operating systems
+ * there is a restriction on the use of SMB authentication on loopback connections.
+ * There are two work arounds available:
+ *
+ * (1) We can disable the check for matching host names. This does not
+ * require a reboot:
+ * [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa]
+ * "DisableLoopbackCheck"=dword:00000001
+ *
+ * (2) We can add the AFS SMB/CIFS service name to an approved list. This
+ * does require a reboot:
+ * [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0]
+ * "BackConnectionHostNames"=multi-sz
+ *
+ * The algorithm will be:
+ * (1) Check to see if cm_NetbiosName exists in the BackConnectionHostNames list
+ * (2a) If not, add it to the list. (This will not take effect until the next reboot.)
+ * (2b1) and check to see if DisableLoopbackCheck is set.
+ * (2b2) If not set, set the DisableLoopbackCheck value to 0x1
+ * (2b3) and create HKLM\SOFTWARE\OpenAFS\Client UnsetDisableLoopbackCheck
+ * (2c) else If cm_NetbiosName exists in the BackConnectionHostNames list,
+ * check for the UnsetDisableLoopbackCheck value.
+ * If set, set the DisableLoopbackCheck flag to 0x0
+ * and delete the UnsetDisableLoopbackCheck value
+ */
+ HKEY hkLsa;
+ HKEY hkMSV10;
+ HKEY hkClient;
+ DWORD dwType;
+ DWORD dwSize;
+ DWORD dwValue;
+ PBYTE pHostNames = NULL, pName;
+ BOOL bNameFound = FALSE;
+
+ if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE,
+ "SYSTEM\\CurrentControlSet\\Control\\Lsa\\MSV1_0",
+ 0,
+ KEY_READ|KEY_WRITE,
+ &hkMSV10) == ERROR_SUCCESS )
+ {
+ if (RegQueryValueEx( hkMSV10, "BackConnectionHostNames", 0, &dwType, NULL, &dwSize) == ERROR_SUCCESS) {
+ pHostNames = malloc(dwSize + strlen(cm_NetbiosName) + 1);
+ RegQueryValueEx( hkMSV10, "BackConnectionHostNames", 0, &dwType, pHostNames, &dwSize);
+
+ for (pName = pHostNames; *pName ; pName += strlen(pName) + 1)
+ {
+ if ( !stricmp(pName, cm_NetbiosName) ) {
+ bNameFound = TRUE;
+ break;
+ }
+ }
+ }
+
+ if ( !bNameFound ) {
+ if ( !pHostNames ) {
+ pName = pHostNames = malloc(strlen(cm_NetbiosName) + 2);
+ dwSize = 1;
+ }
+ strcpy(pName, cm_NetbiosName);
+ pName += strlen(cm_NetbiosName) + 1;
+ *pName = '\0'; /* add a second nul terminator */
+
+ dwType = REG_MULTI_SZ;
+ dwSize += strlen(cm_NetbiosName) + 1;
+ RegSetValueEx( hkMSV10, "BackConnectionHostNames", 0, dwType, pHostNames, dwSize);
+
+ if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE,
+ "SYSTEM\\CurrentControlSet\\Control\\Lsa",
+ 0,
+ KEY_READ|KEY_WRITE,
+ &hkLsa) == ERROR_SUCCESS )
+ {
+ dwSize = sizeof(DWORD);
+ if ( RegQueryValueEx( hkLsa, "DisableLoopbackCheck", 0, &dwType, &dwValue, &dwSize) != ERROR_SUCCESS ||
+ dwValue == 0 ) {
+ dwType = REG_DWORD;
+ dwSize = sizeof(DWORD);
+ dwValue = 1;
+ RegSetValueEx( hkLsa, "DisableLoopbackCheck", 0, dwType, &dwValue, dwSize);
+
+ if (RegCreateKeyEx( HKEY_LOCAL_MACHINE,
+ "SOFTWARE\\OpenAFS\\Client",
+ 0,
+ NULL,
+ REG_OPTION_NON_VOLATILE,
+ KEY_READ|KEY_WRITE,
+ NULL,
+ &hkClient,
+ NULL) == ERROR_SUCCESS) {
+
+ dwType = REG_DWORD;
+ dwSize = sizeof(DWORD);
+ dwValue = 1;
+ RegSetValueEx( hkClient, "RemoveDisableLoopbackCheck", 0, dwType, &dwValue, dwSize);
+ RegCloseKey(hkClient);
+ }
+ RegCloseKey(hkLsa);
+ }
+ }
+ } else {
+ if (RegCreateKeyEx( HKEY_LOCAL_MACHINE,
+ "SOFTWARE\\OpenAFS\\Client",
+ 0,
+ NULL,
+ REG_OPTION_NON_VOLATILE,
+ KEY_READ|KEY_WRITE,
+ NULL,
+ &hkClient,
+ NULL) == ERROR_SUCCESS) {
+
+ dwSize = sizeof(DWORD);
+ if ( RegQueryValueEx( hkClient, "RemoveDisableLoopbackCheck", 0, &dwType, &dwValue, &dwSize) == ERROR_SUCCESS &&
+ dwValue == 1 ) {
+ if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE,
+ "SYSTEM\\CurrentControlSet\\Control\\Lsa",
+ 0,
+ KEY_READ|KEY_WRITE,
+ &hkLsa) == ERROR_SUCCESS )
+ {
+ RegDeleteValue(hkLsa, "DisableLoopbackCheck");
+ RegCloseKey(hkLsa);
+ }
+ }
+ RegDeleteValue(hkClient, "RemoveDisableLoopbackCheck");
+ RegCloseKey(hkClient);
+ }
+ }
+ RegCloseKey(hkMSV10);
+ }
+}
+
+
/*
* AFSD Initialization
*/
long logChunkSize;
long stats;
long traceBufSize;
+ long maxcpus;
long ltt, ltto;
long rx_mtu, rx_nojumbo;
+ long virtualCache;
char rootCellName[256];
struct rx_service *serverp;
static struct rx_securityClass *nullServerSecurityClassp;
char buf[200];
HKEY parmKey;
DWORD dummyLen;
+ DWORD regType;
long code;
/*int freelanceEnabled;*/
WSADATA WSAjunk;
lana_number_t lanaNum;
+ int i;
WSAStartup(0x0101, &WSAjunk);
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
| FORMAT_MESSAGE_ALLOCATE_BUFFER,
NULL, code, 0, (LPTSTR)&msgBuf, 0, NULL);
- sprintf(buf,
+ StringCbPrintfA(buf, sizeof(buf),
"Failure in configuration while opening Registry: %s",
msgBuf);
osi_panic(buf, __FILE__, __LINE__);
}
+ dummyLen = sizeof(maxcpus);
+ code = RegQueryValueEx(parmKey, "MaxCPUs", NULL, NULL,
+ (BYTE *) &maxcpus, &dummyLen);
+ if (code == ERROR_SUCCESS) {
+ HANDLE hProcess;
+ DWORD_PTR processAffinityMask, systemAffinityMask;
+
+ hProcess = OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_SET_INFORMATION,
+ FALSE, GetCurrentProcessId());
+ if ( hProcess != NULL &&
+ GetProcessAffinityMask(hProcess, &processAffinityMask, &systemAffinityMask) )
+ {
+ int i, n, bits;
+ DWORD_PTR mask, newAffinityMask;
+
+#if defined(_WIN64)
+ bits = 64;
+#else
+ bits = 32;
+#endif
+ for ( i=0, n=0, mask=1, newAffinityMask=0; i<bits && n<maxcpus; i++ ) {
+ if ( processAffinityMask & mask ) {
+ newAffinityMask |= mask;
+ n++;
+ }
+ mask *= 2;
+ }
+
+ SetProcessAffinityMask(hProcess, newAffinityMask);
+ CloseHandle(hProcess);
+ afsi_log("CPU Restrictions set to %d cpu(s); %d cpu(s) available", maxcpus, n);
+ } else {
+ afsi_log("CPU Restrictions set to %d cpu(s); unable to access process information", maxcpus);
+ }
+ }
+
+ dummyLen = sizeof(TraceOption);
+ code = RegQueryValueEx(parmKey, "TraceOption", NULL, NULL,
+ (BYTE *) &TraceOption, &dummyLen);
+ afsi_log("Event Log Tracing = %lX", TraceOption);
+
dummyLen = sizeof(traceBufSize);
code = RegQueryValueEx(parmKey, "TraceBufferSize", NULL, NULL,
(BYTE *) &traceBufSize, &dummyLen);
afsi_log("Logoff token transfer on by default");
}
smb_LogoffTokenTransfer = ltt;
+ afsi_log("Logoff token transfer is currently ignored");
if (ltt) {
dummyLen = sizeof(ltto);
ltto = 0;
}
smb_LogoffTransferTimeout = ltto;
+ afsi_log("Default logoff token is currently ignored");
dummyLen = sizeof(cm_rootVolumeName);
code = RegQueryValueEx(parmKey, "RootVolume", NULL, NULL,
if (code == ERROR_SUCCESS)
afsi_log("Root volume %s", cm_rootVolumeName);
else {
- strcpy(cm_rootVolumeName, "root.afs");
+ StringCbCopyA(cm_rootVolumeName, sizeof(cm_rootVolumeName), "root.afs");
afsi_log("Default root volume name root.afs");
}
cm_mountRootLen = sizeof(cm_mountRoot);
- code = RegQueryValueEx(parmKey, "Mountroot", NULL, NULL,
+ code = RegQueryValueEx(parmKey, "MountRoot", NULL, NULL,
cm_mountRoot, &cm_mountRootLen);
if (code == ERROR_SUCCESS) {
afsi_log("Mount root %s", cm_mountRoot);
cm_mountRootLen = strlen(cm_mountRoot);
} else {
- strcpy(cm_mountRoot, "/afs");
+ StringCbCopyA(cm_mountRoot, sizeof(cm_mountRoot), "/afs");
cm_mountRootLen = 4;
/* Don't log */
}
- dummyLen = sizeof(cm_CachePath);
- code = RegQueryValueEx(parmKey, "CachePath", NULL, NULL,
- cm_CachePath, &dummyLen);
- if (code == ERROR_SUCCESS)
+ dummyLen = sizeof(buf);
+ code = RegQueryValueEx(parmKey, "CachePath", NULL, ®Type,
+ buf, &dummyLen);
+ if (code == ERROR_SUCCESS && buf[0]) {
+ if(regType == REG_EXPAND_SZ) {
+ dummyLen = ExpandEnvironmentStrings(buf, cm_CachePath, sizeof(cm_CachePath));
+ if(dummyLen > sizeof(cm_CachePath)) {
+ afsi_log("Cache path [%s] longer than %d after expanding env strings", buf, sizeof(cm_CachePath));
+ osi_panic("CachePath too long", __FILE__, __LINE__);
+ }
+ } else {
+ StringCbCopyA(cm_CachePath, sizeof(cm_CachePath), buf);
+ }
afsi_log("Cache path %s", cm_CachePath);
- else {
+ } else {
GetWindowsDirectory(cm_CachePath, sizeof(cm_CachePath));
cm_CachePath[2] = 0; /* get drive letter only */
- strcat(cm_CachePath, "\\AFSCache");
+ StringCbCatA(cm_CachePath, sizeof(cm_CachePath), "\\AFSCache");
afsi_log("Default cache path %s", cm_CachePath);
}
+ dummyLen = sizeof(virtualCache);
+ code = RegQueryValueEx(parmKey, "NonPersistentCaching", NULL, NULL,
+ &virtualCache, &dummyLen);
+ if (code == ERROR_SUCCESS && virtualCache) {
+ buf_cacheType = CM_BUF_CACHETYPE_VIRTUAL;
+ } else {
+ buf_cacheType = CM_BUF_CACHETYPE_FILE;
+ }
+ afsi_log("Cache type is %s", ((buf_cacheType == CM_BUF_CACHETYPE_FILE)?"FILE":"VIRTUAL"));
+
dummyLen = sizeof(traceOnPanic);
code = RegQueryValueEx(parmKey, "TrapOnPanic", NULL, NULL,
(BYTE *) &traceOnPanic, &dummyLen);
/* Don't log */
}
- dummyLen = sizeof(cm_sysName);
+ for ( i=0; i < MAXNUMSYSNAMES; i++ ) {
+ cm_sysNameList[i] = osi_Alloc(MAXSYSNAME);
+ cm_sysNameList[i][0] = '\0';
+ }
+ cm_sysName = cm_sysNameList[0];
+
+ dummyLen = MAXSYSNAME;
code = RegQueryValueEx(parmKey, "SysName", NULL, NULL,
cm_sysName, &dummyLen);
if (code == ERROR_SUCCESS)
afsi_log("Sys name %s", cm_sysName);
else {
- strcat(cm_sysName, "i386_nt40");
+ StringCbCopyA(cm_sysName, MAXSYSNAME, "i386_nt40");
afsi_log("Default sys name %s", cm_sysName);
}
+ cm_sysNameCount = 1;
dummyLen = sizeof(cryptall);
code = RegQueryValueEx(parmKey, "SecurityLevel", NULL, NULL,
}
afsi_log("Maximum number of VCs per server is %d", smb_maxVCPerServer);
+ dummyLen = sizeof(smb_authType);
+ code = RegQueryValueEx(parmKey, "SMBAuthType", NULL, NULL,
+ (BYTE *) &smb_authType, &dummyLen);
+
+ if (code != ERROR_SUCCESS ||
+ (smb_authType != SMB_AUTH_EXTENDED && smb_authType != SMB_AUTH_NTLM && smb_authType != SMB_AUTH_NONE)) {
+ smb_authType = SMB_AUTH_EXTENDED; /* default is to use extended authentication */
+ }
+ afsi_log("SMB authentication type is %s", ((smb_authType == SMB_AUTH_NONE)?"NONE":((smb_authType == SMB_AUTH_EXTENDED)?"EXTENDED":"NTLM")));
+
dummyLen = sizeof(rx_nojumbo);
code = RegQueryValueEx(parmKey, "RxNoJumbo", NULL, NULL,
(BYTE *) &rx_nojumbo, &dummyLen);
afsi_log("Using >%s< as SMB server name", cm_NetbiosName);
} else {
/* something went horribly wrong. We can't proceed without a netbios name */
- sprintf(buf,"Netbios name could not be determined: %li", code);
+ StringCbPrintfA(buf,sizeof(buf),"Netbios name could not be determined: %li", code);
osi_panic(buf, __FILE__, __LINE__);
}
}
/* Open Microsoft Firewall to allow in port 7001 */
- {
- HKEY hk;
- DWORD dwDisp;
- TCHAR* value = TEXT("7001:UDP:*:Enabled:AFS Cache Manager Callback");
- if (RegCreateKeyEx (HKEY_LOCAL_MACHINE,
- "SYSTEM\\CurrentControlSet\\Services\\SharedAccess\\Parameters\\FirewallPolicy\\DomainProfile\\GloballyOpenP",
- 0, TEXT("container"), 0, KEY_SET_VALUE, NULL, &hk, &dwDisp) == ERROR_SUCCESS)
- {
- RegSetValueEx (hk, TEXT("7001:UDP"), 0, REG_SZ, (PBYTE)value, sizeof(TCHAR) * (1+lstrlen(value)));
- RegCloseKey (hk);
- }
- if (RegCreateKeyEx (HKEY_LOCAL_MACHINE,
- "SYSTEM\\CurrentControlSet\\Services\\SharedAccess\\Parameters\\FirewallPolicy\\StandardProfile\\GloballyOpenP",
- 0, TEXT("container"), 0, KEY_SET_VALUE, NULL, &hk, &dwDisp) == ERROR_SUCCESS)
- {
- RegSetValueEx (hk, TEXT("7001:UDP"), 0, REG_SZ, (PBYTE)value, sizeof(TCHAR) * (1+lstrlen(value)));
- RegCloseKey (hk);
- }
- }
+ icf_CheckAndAddAFSPorts(AFS_PORTSET_CLIENT);
+
+ /* Ensure the AFS Netbios Name is registered to allow loopback access */
+ configureBackConnectionHostNames();
/* initialize RX, and tell it to listen to port 7001, which is used for
* callback RPC messages.
/* this should really be in an init daemon from here on down */
if (!cm_freelanceEnabled) {
+ osi_Log0(afsd_logp, "Loading Root Volume from cell");
code = cm_GetVolumeByName(cm_rootCellp, cm_rootVolumeName, cm_rootUserp,
&req, CM_FLAG_CREATE, &cm_rootVolumep);
afsi_log("cm_GetVolumeByName code %x root vol %x", code,