-/*
- * Copyright (C) 1998, 1989 Transarc Corporation - All rights reserved
- *
- * (C) COPYRIGHT IBM CORPORATION 1987, 1988
- * LICENSED MATERIALS - PROPERTY OF IBM
- *
- *
+/*
+ * Copyright 2000, International Business Machines Corporation and others.
+ * All Rights Reserved.
+ *
+ * This software has been released under the terms of the IBM Public
+ * License. For details, see the LICENSE file in the top-level source
+ * directory or online at http://www.openafs.org/dl/license10.html
*/
+
#include <afs/param.h>
#include <afs/stds.h>
#include "cm_config.h"
#include "krb.h"
+#include <io.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <fcntl.h>
+
+DWORD LogonOption,TraceOption;
HANDLE hDLL;
WSADATA WSAjunk;
-char NPName[] = "System\\CurrentControlSet\\Services\\TransarcAFSDaemon\\NetworkProvider";
-
#define REG_CLIENT_PARMS_KEY "SYSTEM\\CurrentControlSet\\Services\\TransarcAFSDaemon\\Parameters"
+#define REG_CLIENT_PROVIDER_KEY "SYSTEM\\CurrentControlSet\\Services\\TransarcAFSDaemon\\NetworkProvider"
#define REG_CLIENT_RETRY_INTERVAL_PARM "LoginRetryInterval"
#define REG_CLIENT_FAIL_SILENTLY_PARM "FailLoginsSilently"
-#define DEFAULT_RETRY_INTERVAL 30 // seconds
+#define DEFAULT_RETRY_INTERVAL 30 /* seconds*/
#define DEFAULT_FAIL_SILENTLY FALSE
-#define DEFAULT_SLEEP_INTERVAL 5 // seconds
+#define DEFAULT_SLEEP_INTERVAL 5 /* seconds*/
+
+#define ISLOGONINTEGRATED(v) ( ((v) & LOGON_OPTION_INTEGRATED)==LOGON_OPTION_INTEGRATED)
+#define ISHIGHSECURITY(v) ( ((v) & LOGON_OPTION_HIGHSECURITY)==LOGON_OPTION_HIGHSECURITY)
+#define TRACE_OPTION_EVENT 1
+#define ISLOGONTRACE(v) ( ((v) & TRACE_OPTION_EVENT)==TRACE_OPTION_EVENT)
/* Structure def copied from DDK (NTDEF.H) */
typedef struct UNICODE_STRING {
*
* Returns NULL on failure.
*/
-WCHAR *GetLogonScript(void)
+
+
+void DebugEvent0(char *a)
+{
+ HANDLE h; char *ptbuf[1];
+ if (!ISLOGONTRACE(TraceOption))
+ return;
+ h = RegisterEventSource(NULL, AFS_DAEMON_EVENT_NAME);
+ ptbuf[0] = a;
+ ReportEvent(h, EVENTLOG_INFORMATION_TYPE, 0, 0, NULL, 1, 0, (const char **)ptbuf, NULL);
+ DeregisterEventSource(h);
+}
+
+#define MAXBUF_ 131
+void DebugEvent(char *a,char *b,...)
+{
+ HANDLE h; char *ptbuf[1],buf[MAXBUF_+1];
+ va_list marker;
+ if (!ISLOGONTRACE(TraceOption))
+ return;
+ h = RegisterEventSource(NULL, AFS_DAEMON_EVENT_NAME);
+ va_start(marker,b);
+ _vsnprintf(buf,MAXBUF_,b,marker);
+ buf[MAXBUF_] = '\0';
+ ptbuf[0] = buf;
+ ReportEvent(h, EVENTLOG_INFORMATION_TYPE, 0, 0, NULL, 1, 0, (const char **)ptbuf, NULL);\
+ DeregisterEventSource(h);
+ va_end(marker);
+}
+
+CHAR *GenRandomName(CHAR *pbuf)
{
- WCHAR *script;
+ int i;
+ srand( (unsigned)time( NULL ) );
+ for (i=0;i<MAXRANDOMNAMELEN-1;i++)
+ pbuf[i]='a'+(rand() % 26);
+ pbuf[MAXRANDOMNAMELEN-1]=0;
+ return pbuf;
+}
+
+WCHAR *GetLogonScript(CHAR *pname)
+{
+ WCHAR *script,*buf;
DWORD code;
DWORD LSPtype, LSPsize;
HKEY NPKey;
+ WCHAR randomName[MAXRANDOMNAMELEN];
/*
* Get Network Provider key.
* Assume this works or we wouldn't be here.
*/
- (void) RegOpenKeyEx(HKEY_LOCAL_MACHINE, NPName,
+ (void) RegOpenKeyEx(HKEY_LOCAL_MACHINE, REG_CLIENT_PROVIDER_KEY,
0, KEY_QUERY_VALUE, &NPKey);
/*
* Get Logon Script pathname length
*/
- code = RegQueryValueEx(NPKey, "LogonScript", NULL,
+
+ code = RegQueryValueExW(NPKey, L"LogonScript", NULL,
&LSPtype, NULL, &LSPsize);
if (code) {
return NULL;
}
- script = (WCHAR *)LocalAlloc(LMEM_FIXED, LSPsize);
-
+ buf=(WCHAR *)LocalAlloc(LMEM_FIXED,LSPsize);
+ script=(WCHAR *)LocalAlloc(LMEM_FIXED,LSPsize+(MAXRANDOMNAMELEN)*sizeof(WCHAR));
/*
* Explicitly call UNICODE version
* Assume it will succeed since it did before
*/
(void) RegQueryValueExW(NPKey, L"LogonScript", NULL,
- &LSPtype, (LPBYTE)script, &LSPsize);
+ &LSPtype, (LPBYTE)buf, &LSPsize);
+ MultiByteToWideChar(CP_ACP,0,pname,strlen(pname)+1,randomName,(strlen(pname)+1)*sizeof(WCHAR));
+ swprintf(script,buf,randomName);
+ LocalFree(buf);
+
+#ifdef DEBUG_VERBOSE
+ {
+ HANDLE h; char *ptbuf[1],buf[132],tbuf[255];
+ WideCharToMultiByte(CP_ACP,0,script,LSPsize,tbuf,255,NULL,NULL);
+ h = RegisterEventSource(NULL, AFS_DAEMON_EVENT_NAME);
+ sprintf(buf, "Script[%s,%d] Return Code[%x]",tbuf,LSPsize,code);
+ ptbuf[0] = buf;
+ ReportEvent(h, EVENTLOG_INFORMATION_TYPE, 0, 0, NULL, 1, 0, ptbuf, NULL);
+ DeregisterEventSource(h);
+ }
+#endif
RegCloseKey (NPKey);
return script;
goto close_svc;
/* Allocate buffer */
- pConfig = (LPQUERY_SERVICE_CONFIG)GlobalAlloc(GMEM_FIXED, BufSize);
+ pConfig = (LPQUERY_SERVICE_CONFIG)GlobalAlloc(GMEM_FIXED,BufSize);
if (!pConfig)
goto close_svc;
DWORD MapAuthError(DWORD code)
{
switch (code) {
- case INTK_BADPW: return WN_BAD_PASSWORD;
- case KERB_ERR_PRINCIPAL_UNKNOWN: return WN_BAD_USER;
- default: return WN_NO_NETWORK;
+ case KTC_NOCM:
+ case KTC_NOCMRPC:
+ return WN_NO_NETWORK;
+/* case INTK_BADPW: return WN_BAD_PASSWORD;*/
+/* case KERB_ERR_PRINCIPAL_UNKNOWN: return WN_BAD_USER;*/
+ default: return WN_SUCCESS;
}
}
case DLL_PROCESS_ATTACH:
/* Initialize AFS libraries */
rx_Init(0);
+ initAFSDirPath();
ka_Init(0);
break;
static void GetLoginBehavior(int *pRetryInterval, BOOLEAN *pFailSilently)
{
- long result;
- HKEY hKey;
- DWORD dummyLen;
+ long result;
+ HKEY hKey;
+ DWORD dummyLen;
result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, REG_CLIENT_PARMS_KEY, 0, KEY_QUERY_VALUE, &hKey);
- if (result != ERROR_SUCCESS) {
- *pRetryInterval = DEFAULT_RETRY_INTERVAL;
- *pFailSilently = DEFAULT_FAIL_SILENTLY;
- return;
- }
+ if (result != ERROR_SUCCESS) {
+ *pRetryInterval = DEFAULT_RETRY_INTERVAL;
+ *pFailSilently = DEFAULT_FAIL_SILENTLY;
+ return;
+ }
- result = RegQueryValueEx(hKey, REG_CLIENT_RETRY_INTERVAL_PARM, 0, 0, (BYTE *)pRetryInterval, &dummyLen);
- if (result != ERROR_SUCCESS)
- *pRetryInterval = DEFAULT_RETRY_INTERVAL;
+ result = RegQueryValueEx(hKey, REG_CLIENT_RETRY_INTERVAL_PARM, 0, 0, (BYTE *)pRetryInterval, &dummyLen);
+ if (result != ERROR_SUCCESS)
+ *pRetryInterval = DEFAULT_RETRY_INTERVAL;
- result = RegQueryValueEx(hKey, REG_CLIENT_FAIL_SILENTLY_PARM, 0, 0, (BYTE *)pFailSilently, &dummyLen);
- if (result != ERROR_SUCCESS)
- *pFailSilently = DEFAULT_FAIL_SILENTLY;
+ result = RegQueryValueEx(hKey, REG_CLIENT_FAIL_SILENTLY_PARM, 0, 0, (BYTE *)pFailSilently, &dummyLen);
+ if (result != ERROR_SUCCESS)
+ *pFailSilently = DEFAULT_FAIL_SILENTLY;
- // Make sure this is really a bool value in the strict sense
- *pFailSilently = !!*pFailSilently;
-
- RegCloseKey(hKey);
-}
+ /* Make sure this is really a bool value in the strict sense*/
+ *pFailSilently = !!*pFailSilently;
+
+ RegCloseKey(hKey);
+}
+
+BOOL IsServiceRunning (void)
+{
+ SERVICE_STATUS Status;
+ SC_HANDLE hManager;
+ memset (&Status, 0x00, sizeof(Status));
+ Status.dwCurrentState = SERVICE_STOPPED;
+
+ if ((hManager = OpenSCManager (NULL, NULL, GENERIC_READ)) != NULL)
+ {
+ SC_HANDLE hService;
+ if ((hService = OpenService (hManager, TEXT("TransarcAFSDaemon"), GENERIC_READ)) != NULL)
+ {
+ QueryServiceStatus (hService, &Status);
+ CloseServiceHandle (hService);
+ }
+
+ CloseServiceHandle (hManager);
+ }
+ DebugEvent("AFS AfsLogon - Test Service Running","Return Code[%x] ?Running[%d]",Status.dwCurrentState,(Status.dwCurrentState == SERVICE_RUNNING));
+ return (Status.dwCurrentState == SERVICE_RUNNING);
+}
DWORD APIENTRY NPLogonNotify(
PLUID lpLogonId,
LPVOID StationHandle,
LPWSTR *lpLogonScript)
{
- char uname[256];
- char password[256];
- char cell[256];
+ char uname[256]="";
+ char *ctemp;
+ char password[256]="";
+ char cell[256]="<non-integrated logon>";
MSV1_0_INTERACTIVE_LOGON *IL;
DWORD code;
int pw_exp;
char *reason;
BOOLEAN interactive;
BOOLEAN flag;
+ DWORD LSPtype, LSPsize;
+ HKEY NPKey;
HWND hwndOwner = (HWND)StationHandle;
- BOOLEAN failSilently;
- int retryInterval;
- int sleepInterval = DEFAULT_SLEEP_INTERVAL; // seconds
- BOOLEAN afsWillAutoStart;
+ BOOLEAN failSilently;
+ int retryInterval;
+ int sleepInterval = DEFAULT_SLEEP_INTERVAL; /* seconds */
+ BOOLEAN afsWillAutoStart;
+ CHAR RandomName[MAXRANDOMNAMELEN];
+ BOOLEAN uppercased_name = TRUE;
+
+ /* Initialize Logon Script to none */
+ *lpLogonScript=NULL;
IL = (MSV1_0_INTERACTIVE_LOGON *) lpAuthentInfo;
wcstombs(uname, IL->UserName.Buffer, 256);
wcstombs(password, IL->Password.Buffer, 256);
- /* Check for zero length password */
- if (password[0] == 0) {
- code = GT_PW_NULL;
- reason = "zero length password is illegal";
- goto checkauth;
- }
+ /* Make sure AD-DOMANS sent from login that is sent to us is striped */
+ ctemp = strchr(uname, '@');
+ if (ctemp) *ctemp = 0;
- /* Get cell name */
- code = cm_GetRootCellName(cell);
- if (code < 0) {
- code = KTC_NOCELL;
- reason = "unknown cell";
- goto checkauth;
- }
+ /* is the name all uppercase? */
+ for ( ctemp = uname; *ctemp ; ctemp++) {
+ if ( islower(*ctemp) ) {
+ uppercased_name = FALSE;
+ break;
+ }
+ }
+
+ (void) RegOpenKeyEx(HKEY_LOCAL_MACHINE, REG_CLIENT_PARMS_KEY,
+ 0, KEY_QUERY_VALUE, &NPKey);
+ LSPsize=sizeof(TraceOption);
+ RegQueryValueEx(NPKey, "TraceOption", NULL,
+ &LSPtype, (LPBYTE)&TraceOption, &LSPsize);
+ RegCloseKey (NPKey);
+
+ /*
+ * Get Logon OPTIONS
+ */
+
+ (void) RegOpenKeyEx(HKEY_LOCAL_MACHINE, REG_CLIENT_PROVIDER_KEY,
+ 0, KEY_QUERY_VALUE, &NPKey);
+
+ LSPsize=sizeof(LogonOption);
+ code = RegQueryValueEx(NPKey, "LogonOptions", NULL,
+ &LSPtype, (LPBYTE)&LogonOption, &LSPsize);
+
+ RegCloseKey (NPKey);
+ if ((code!=0) || (LSPtype!=REG_DWORD))
+ LogonOption=LOGON_OPTION_INTEGRATED; /*default to integrated logon only*/
- /* Get user specified login behavior (or defaults) */
- GetLoginBehavior(&retryInterval, &failSilently);
+ afsWillAutoStart = AFSWillAutoStart();
- afsWillAutoStart = AFSWillAutoStart();
+ DebugEvent("AFS AfsLogon - NPLogonNotify","LogonOption[%x], Service AutoStart[%d]",
+ LogonOption,afsWillAutoStart);
+
+ /* Get local machine specified login behavior (or defaults) */
+ GetLoginBehavior(&retryInterval, &failSilently);
- /* Possibly loop until AFS is started. */
- while (1) {
- code = ka_UserAuthenticateGeneral(
- KA_USERAUTH_VERSION+KA_USERAUTH_AUTHENT_LOGON,
- uname, "", cell, password, 0, &pw_exp, 0,
- &reason);
-
+ /* Check for zero length password if integrated logon*/
+ if ( ISLOGONINTEGRATED(LogonOption) ) {
+ if ( password[0] == 0 ) {
+ code = GT_PW_NULL;
+ reason = "zero length password is illegal";
+ code=0;
+ }
+
+ /* Get cell name if doing integrated logon */
+ code = cm_GetRootCellName(cell);
+ if (code < 0) {
+ code = KTC_NOCELL;
+ reason = "unknown cell";
+ code=0;
+ }
+
+ /*only do if high security option is on*/
+ if (ISHIGHSECURITY(LogonOption))
+ *lpLogonScript = GetLogonScript(GenRandomName(RandomName));
+ }
+
+ /* loop until AFS is started. */
+ while (TRUE) {
+ code=0;
+
+ /* is service started yet?*/
+ DebugEvent("AFS AfsLogon - ka_UserAuthenticateGeneral2","Code[%x] uname[%s] Cell[%s]",
+ code,uname,cell);
+
+ /* if Integrated Logon only */
+ if (ISLOGONINTEGRATED(LogonOption) && !ISHIGHSECURITY(LogonOption))
+ {
+ code = ka_UserAuthenticateGeneral2(KA_USERAUTH_VERSION+KA_USERAUTH_AUTHENT_LOGON,
+ uname, "", cell, password,uname, 0, &pw_exp, 0,
+ &reason);
+ DebugEvent("AFS AfsLogon - (INTEGRATED only)ka_UserAuthenticateGeneral2","Code[%x]",
+ code);
+ if ( code && code != KTC_NOCM && code != KTC_NOCMRPC && uppercased_name ) {
+ for ( ctemp = uname; *ctemp ; ctemp++) {
+ *ctemp = tolower(*ctemp);
+ }
+ uppercased_name = FALSE;
+ continue;
+ }
+ }
+ /* if Integrated Logon and High Security pass random generated name*/
+ else if (ISLOGONINTEGRATED(LogonOption) && ISHIGHSECURITY(LogonOption))
+ {
+ code = ka_UserAuthenticateGeneral2(KA_USERAUTH_VERSION+KA_USERAUTH_AUTHENT_LOGON,
+ uname, "", cell, password,RandomName, 0, &pw_exp, 0,
+ &reason);
+ DebugEvent("AFS AfsLogon - (Both)ka_UserAuthenticateGeneral2","Code[%x] RandomName[%s]",
+ code, RandomName);
+
+ if ( code && code != KTC_NOCM && code != KTC_NOCMRPC && uppercased_name ) {
+ for ( ctemp = uname; *ctemp ; ctemp++) {
+ *ctemp = tolower(*ctemp);
+ }
+ uppercased_name = FALSE;
+ continue;
+ }
+ } else {
+ /*JUST check to see if its running*/
+ if (IsServiceRunning())
+ break;
+ code = KTC_NOCM;
+ if (!afsWillAutoStart)
+ break;
+ }
+
/* If we've failed because the client isn't running yet and the
- * client is set to autostart (and therefore it makes sense for
- * us to wait for it to start) then sleep a while and try again.
- * If the error was something else, then give up. */
+ * client is set to autostart (and therefore it makes sense for
+ * us to wait for it to start) then sleep a while and try again.
+ * If the error was something else, then give up. */
if (code != KTC_NOCM && code != KTC_NOCMRPC || !afsWillAutoStart)
- break;
+ break;
- /* If the retry interval has expired and we still aren't
- * logged in, then just give up if we are not in interactive
- * mode or the failSilently flag is set, otherwise let the
- * user know we failed and give them a chance to try again. */
- if (retryInterval <= 0) {
- if (!interactive || failSilently)
- break;
-
+ /* If the retry interval has expired and we still aren't
+ * logged in, then just give up if we are not in interactive
+ * mode or the failSilently flag is set, otherwise let the
+ * user know we failed and give them a chance to try again. */
+ if (retryInterval <= 0) {
+ reason = "AFS not running";
+ if (!interactive || failSilently)
+ break;
flag = MessageBox(hwndOwner,
- "AFS is still starting. Retry?",
- "AFS Logon",
- MB_ICONQUESTION | MB_RETRYCANCEL);
+ "AFS is still starting. Retry?",
+ "AFS Logon",
+ MB_ICONQUESTION | MB_RETRYCANCEL);
if (flag == IDCANCEL)
- break;
-
- /* Wait just a little while and try again */
- retryInterval = sleepInterval = DEFAULT_SLEEP_INTERVAL;
- }
-
- if (retryInterval < sleepInterval)
- sleepInterval = retryInterval;
-
- Sleep(sleepInterval * 1000);
+ break;
- retryInterval -= sleepInterval;
+ /* Wait just a little while and try again */
+ retryInterval = sleepInterval = DEFAULT_SLEEP_INTERVAL;
}
-checkauth:
+ if (retryInterval < sleepInterval)
+ sleepInterval = retryInterval;
+
+ Sleep(sleepInterval * 1000);
+
+ retryInterval -= sleepInterval;
+ }
+
if (code) {
- char msg[128];
-
- sprintf(msg, "Integrated login failed: %s", reason);
-
+ char msg[128];
+ sprintf(msg, "Integrated login failed: %s", reason);
+
if (interactive && !failSilently)
MessageBox(hwndOwner, msg, "AFS Logon", MB_OK);
else {
- HANDLE h;
- char *ptbuf[1];
-
- h = RegisterEventSource(NULL, AFS_DAEMON_EVENT_NAME);
- ptbuf[0] = msg;
- ReportEvent(h, EVENTLOG_WARNING_TYPE, 0, 1008, NULL,
- 1, 0, ptbuf, NULL);
- DeregisterEventSource(h);
- }
- }
+ HANDLE h;
+ char *ptbuf[1];
+
+ h = RegisterEventSource(NULL, AFS_DAEMON_EVENT_NAME);
+ ptbuf[0] = msg;
+ ReportEvent(h, EVENTLOG_WARNING_TYPE, 0, 1008, NULL,
+ 1, 0, ptbuf, NULL);
+ DeregisterEventSource(h);
+ }
+ code = MapAuthError(code);
+ SetLastError(code);
- /* Get logon script */
- if (interactive)
- *lpLogonScript = GetLogonScript();
+ if (ISLOGONINTEGRATED(LogonOption) && (code!=0))
+ {
+ if (*lpLogonScript)
+ LocalFree(*lpLogonScript);
+ *lpLogonScript = NULL;
+ if (!afsWillAutoStart) // its not running, so if not autostart or integrated logon then just skip
+ code = 0;
- if (code) {
- code = MapAuthError(code);
- SetLastError(code);
+ }
}
+ DebugEvent("AFS AfsLogon - Exit","Return Code[%x]",code);
return code;
}
LPVOID StationHandle,
DWORD dwChangeInfo)
{
+ DebugEvent0("AFS AfsLogon - NPPasswordChangeNotify");
return 0;
}