499 lines
14 KiB
C++
499 lines
14 KiB
C++
/***********************************************************************
|
|
* File: lcredmgr.cpp
|
|
* Author: Todd Throne (tthrone@novell.com)
|
|
*
|
|
* Abstract: Stores the credentials gathered during traditional
|
|
* client login in CASA.
|
|
*
|
|
* Copyright (C) 2005 Novell, Inc.
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2 of the License, or (at your option) any later version.
|
|
*
|
|
* 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 General Public
|
|
* License along with this library; if not, write to the Free
|
|
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
*
|
|
* 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;
|
|
}
|
|
|
|
//=========================================================================
|
|
//=========================================================================
|