CASA/LoginCapture/windows/lextend.cpp
2006-01-18 23:34:21 +00:00

501 lines
14 KiB
C++

/***********************************************************************
*
* Copyright (C) 2005-2006 Novell, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* To contact Novell about this file by physical or electronic mail,
* you may find current contact information at www.novell.com.
*
***********************************************************************/
/***********************************************************************
*
* Following are registry entries, which must be created in order
* to run this login extension;
*
* [HKEY_LOCAL_MACHINE\SOFTWARE\Novell\Graphical Login\NWLGE\LCredMgr]
* "LoginExtName"="lcredmgr.dll"
* "LoginExtDesc"="CASA Login Extension"
* "LoginExtType"=DWORD:00008002 // means MASTER + AUTHENTICATE
*
***********************************************************************/
//===[ Header files specific to this module ]==============================
#include "lcredmgr.h"
#define N_PLAT_MSW4
#define N_ARCH_32
#include <nwalias.h>
#include <nwlgext.h>
#include <nwdsdc.h>
#include <nwdsdefs.h>
#include <nwdsdsa.h>
#include <nwerror.h>
//===[ External data ]==============================
extern PSETCREDENTIAL pCASASetCredential;
//===[ External prototypes ]==============================
//===[ Manifest constants ]==============================
//===[ Type definitions ]==============================
//===[ Function Prototypes ]==============================
N_TYPEDEF_CALLBACK(NWDSCCODE,pNWDSCreateContext)(NWDSContextHandle N_FAR *);
N_TYPEDEF_CALLBACK(NWDSCCODE,pNWDSSetContext)(NWDSContextHandle,nint,nptr);
N_TYPEDEF_CALLBACK(NWDSCCODE,pNWDSWhoAmI)(NWDSContextHandle,pnstr8);
N_TYPEDEF_CALLBACK(NWDSCCODE,pNWDSFreeContext)(NWDSContextHandle);
N_TYPEDEF_CALLBACK(NWCCODE,pNWLoginExtInit)(pNWLGAccessRec*,pNWVersion,pNWVersion,nptr,nptr);
N_TYPEDEF_CALLBACK(NWCCODE,pNWLGGetLoginData)(nint,nint,nptr,nint);
//===[ Global Variables ]==============================
NWLGAccessRec g_NextAccess = {0, 0, 0}, *g_pAccess = 0;
BOOL g_passwordChanged = FALSE;
//++=======================================================================
int
SetCredentialsInWallet(
pnstr pTree,
pnstr pUser,
nint passwordLen,
pnstr pPassword
)
//=======================================================================--
{
int ccode;
SSCS_BASIC_CREDENTIAL basicCredential;
SSCS_SECRET_ID_T traditionalClient;
SSCS_SECRET_ID_T tree;
BOOLEAN bLibraryLoaded;
#ifdef _DEBUG
DebugPrint("Tree name [%s]\n", pTree);
DebugPrint("User name [%s]\n", pUser);
DebugPrint("Password [%s]\n", pPassword);
#endif
bLibraryLoaded = InitCASALibrary();
if (bLibraryLoaded == FALSE)
{
SetLastError(NO_ERROR);
return NO_ERROR;
}
strcpy((char *)&traditionalClient.id, "Traditional_Client");
traditionalClient.len = (long)strlen((char *)&traditionalClient.id) + 1;
strcpy((char *)&tree.id, pTree);
strupr((char *)&tree.id);
tree.len = (long)strlen((char *)&tree.id) + 1;
basicCredential.unFlags = USERNAME_TYPE_NDS_FDN_F;
if (!pUser)
{
//
// Logout trying to clear the credentials
//
basicCredential.unLen = 0;
basicCredential.pwordLen = 0;
ccode = (*pCASASetCredential)(
0,
&traditionalClient,
&tree,
SSCS_CRED_TYPE_BASIC_F,
&basicCredential,
NULL);
#ifdef _DEBUG
DebugPrint("miCASASetCredential returned 0x%x\n", ccode);
#endif
}
else
{
basicCredential.pwordLen = passwordLen;
if (passwordLen)
{
strcpy((char *)&basicCredential.password, pPassword);
basicCredential.pwordLen++;
}
strcpy((char *)&basicCredential.username, pUser);
basicCredential.unLen = (unsigned long)strlen((char *)&basicCredential.username) + 1;
ccode = (*pCASASetCredential)(
0,
&traditionalClient,
&tree,
SSCS_CRED_TYPE_BASIC_F,
&basicCredential,
NULL);
#ifdef _DEBUG
DebugPrint("miCASASetCredential returned 0x%x\n", ccode);
#endif
}
return (ccode);
}
//++=======================================================================
int
GetUserFDN(
pnstr pTree,
pnstr pUser
)
//=======================================================================--
{
int ccode;
HMODULE hInst;
NWDSContextHandle hContext;
pNWDSCreateContext pfCreateContext;
pNWDSSetContext pfSetContext;
pNWDSWhoAmI pfWhoAmI;
pNWDSFreeContext pfFreeContext;
hInst = GetModuleHandle(L"NETWIN32.DLL");
pfCreateContext = (pNWDSCreateContext)GetProcAddress(hInst,"NWDSCreateContextHandle");
pfSetContext = (pNWDSSetContext)GetProcAddress(hInst,"NWDSSetContext");
pfWhoAmI = (pNWDSWhoAmI)GetProcAddress(hInst,"NWDSWhoAmI");
pfFreeContext = (pNWDSFreeContext)GetProcAddress(hInst,"NWDSFreeContext");
if (!pfCreateContext
|| !pfSetContext
|| !pfWhoAmI
|| !pfFreeContext)
{
return -1;
}
ccode = pfCreateContext(&hContext);
if (ccode == SUCCESS)
{
pfSetContext(hContext, DCK_TREE_NAME, pTree);
pfSetContext(hContext, DCK_NAME_CONTEXT, "[root]");
ccode = pfWhoAmI(hContext, pUser);
#ifdef _DEBUG
DebugPrint("NWDSWhoAmI returned 0x%x\n", ccode);
#endif
pfFreeContext(hContext);
}
return ccode;
}
//++=======================================================================
N_GLOBAL_CALLBACK(NWCCODE)
OurEventHandler(
pNWLGAccessRec pAccess,
nint event,
nint eventType,
nint eventSubType,
nparam parm1,
nparam parm2,
nflag32 flags
)
//=======================================================================--
{
pNWLGGetLoginData pGetLoginData;
pNWLGStartInfo data;
HMODULE hInst;
NWCCODE rc, retCode = NWLG_EVT_OK;
char szUserFDN[MAX_DN_BYTES];
switch (event)
{
case NWLG_PRE_SCRIPTS:
#ifdef _DEBUG
DebugPrint("EventHandler called with NWLG_PRE_SCRIPTS.\n");
#endif
case NWLG_SYNC_PWD_END:
#ifdef _DEBUG
DebugPrint("EventHandler called with NWLG_SYNC_PWD_END.\n");
#endif
hInst = GetModuleHandle(L"LGNWNT32.DLL");
pGetLoginData = (pNWLGGetLoginData)GetProcAddress(hInst,"NWLGGetLoginData");
if (pGetLoginData)
{
rc = pGetLoginData(NWLG_SD_START_INFO, 0, &data, sizeof(&data));
if (rc == NWLG_OK)
{
if (data
&& data->password
&& data->restartMode != 2)
{
if (g_passwordChanged == FALSE)
{
rc = GetUserFDN(data->tree, szUserFDN);
if (rc == SUCCESS)
{
#ifdef _DEBUG
DebugPrint("GetUserFDN returned user [%s]\n", szUserFDN);
#endif
SetCredentialsInWallet(
data->tree,
szUserFDN,
data->passwordLen,
data->password);
}
}
#ifdef _DEBUG
else
{
DebugPrint("Credentials not set since password changed flag = TRUE.\n");
}
#endif
}
#ifdef _DEBUG
else
{
DebugPrint("No NWLG_SD_START_INFO returned from NWLGGetLoginData or no password data or invalid restartMode.\n");
}
#endif
}
#ifdef _DEBUG
else
{
DebugPrint("GetLoginData for NWLG_SD_START_INFO failed. 0x%X\n", rc);
}
#endif
}
#ifdef _DEBUG
else
{
DebugPrint("GetProcAddress for NWLGGetLoginData failed, module handle 0x%x, error %d\n", hInst, GetLastError());
}
#endif
break;
case NWLG_TERMINATE:
#ifdef _DEBUG
DebugPrint("EventHandler called with NWLG_TERMINATE.\n");
#endif
// We have to unchain here !
pAccess->pEventHandler = g_NextAccess.pEventHandler;
}
// It is time to chain to the default handler, which will take care of
// all events (because our DLL is a master extension, not a secondary,
// and does not handle events as expected from master extension).
// The default handler was copied when our DLL was initialized.
if (g_NextAccess.pEventHandler)
{
retCode = (*g_NextAccess.pEventHandler)
(pAccess,event,eventType,eventSubType,parm1,parm2,flags);
}
return (retCode);
}
//++=======================================================================
N_GLOBAL_CALLBACK(NWCCODE)
OurIOHandler(
pNWLGAccessRec pAccess,
nint ioEvent,
nparam param1,
nparam param2,
nflag32 flags
)
//=======================================================================--
{
pNWLGGetLoginData pGetLoginData;
pNWLGStartInfo data;
HINSTANCE hInst;
NWCCODE rc, rcode = NWLG_OK;
char szUserFDN[MAX_DN_BYTES];
switch (ioEvent)
{
#ifdef _DEBUG
DebugPrint("IOHandler called.\n");
#endif
case NWLG_IO_CHANGE_PWD:
#ifdef _DEBUG
DebugPrint("IOHandler called with NWLG_IO_CHANGE_PWD.\n");
#endif
if (g_NextAccess.pIOHandler)
{
rcode = g_NextAccess.pIOHandler(pAccess, ioEvent, param1, param2, flags);
if (NWLG_CANCEL != pAccess->status)
{
hInst = GetModuleHandle(L"LGNWNT32.DLL");
pGetLoginData = (pNWLGGetLoginData)GetProcAddress(hInst,"NWLGGetLoginData");
if (pGetLoginData)
{
rc = pGetLoginData(NWLG_SD_START_INFO, 0, &data, sizeof(&data));
if (rc == NWLG_OK)
{
if (data
&& param1
&& ((pNWLGUserID)param1)->password)
{
if (data->restartMode != 2)
{
g_passwordChanged = TRUE;
rc = GetUserFDN(data->tree, szUserFDN);
if (rc == SUCCESS)
{
#ifdef _DEBUG
DebugPrint("GetUserFDN returned user [%s]\n", szUserFDN);
#endif
SetCredentialsInWallet(
data->tree,
szUserFDN,
(unsigned long)strlen(((pNWLGUserID)param1)->password),
((pNWLGUserID)param1)->password);
}
}
#ifdef _DEBUG
else
{
DebugPrint("Invalid restartMode.\n");
}
#endif
}
#ifdef _DEBUG
else
{
DebugPrint("No NWLG_SD_START_INFO returned from NWLGGetLoginData or no password data.\n");
}
#endif
}
#ifdef _DEBUG
else
{
DebugPrint("GetLoginData for NWLG_SD_START_INFO failed. 0x%X\n", rc);
}
#endif
}
#ifdef _DEBUG
else
{
DebugPrint("GetProcAddress for NWLGGetLoginData failed, module handle 0x%x, error %d\n", hInst, GetLastError());
}
#endif
}
#ifdef _DEBUG
else
{
DebugPrint("Password change cancelled by previous IOHandler!\n");
}
#endif
}
#ifdef _DEBUG
else
{
DebugPrint("Previous IOHandler not presend?!\n");
}
#endif
break;
default:
if (g_NextAccess.pIOHandler)
{
rcode = g_NextAccess.pIOHandler(pAccess, ioEvent, param1, param2, flags);
}
}
return (rcode);
}
//++=======================================================================
void
InitLoginExtension(
)
//=======================================================================--
{
NWCCODE ccode;
HINSTANCE hInst;
NWVersion versionSupported, runtimeVersion;
pNWLoginExtInit pLoginExtInit;
hInst = GetModuleHandle(L"LGNWNT32.DLL");
if (hInst)
{
pLoginExtInit = (pNWLoginExtInit)GetProcAddress(hInst,"NWLoginExtInit");
if (pLoginExtInit)
{
versionSupported.major = 1;
versionSupported.minor = 0;
versionSupported.revision = 0;
ccode = pLoginExtInit(
&g_pAccess,
&versionSupported,
&runtimeVersion,
NULL,
NULL);
if (ccode == NWLG_OK)
{
// Save off the old pointers
g_NextAccess = *g_pAccess;
if (g_pAccess)
{
g_pAccess->pIOHandler = OurIOHandler;
g_pAccess->pEventHandler = (pEvtHndlr)OurEventHandler;
}
}
}
}
return;
}
//=========================================================================
//=========================================================================