1214 lines
25 KiB
C
1214 lines
25 KiB
C
/*++
|
||
|
||
Copyright (c) 1993 Microsoft Corporation
|
||
|
||
Module Name:
|
||
|
||
api.c
|
||
|
||
Abstract:
|
||
|
||
This module contains exposed APIs that is used by the
|
||
NetWare Control Panel Applet.
|
||
|
||
Author:
|
||
|
||
Yi-Hsin Sung 15-Jul-1993
|
||
|
||
Revision History:
|
||
|
||
ChuckC 23-Jul-93 Completed the stubs
|
||
|
||
--*/
|
||
|
||
#include <nwclient.h>
|
||
#include <nwcanon.h>
|
||
#include <validc.h>
|
||
#include <nwdlg.h>
|
||
#include <nwreg.h>
|
||
#include <nwapi.h>
|
||
#include <ntddnwfs.h>
|
||
|
||
//Multi-User code merge
|
||
DWORD
|
||
NwpCitrixGetUserInfo(
|
||
LPWSTR *ppszUserSid
|
||
);
|
||
//
|
||
// forward declare
|
||
//
|
||
|
||
DWORD
|
||
NwpGetCurrentUserRegKey(
|
||
IN DWORD DesiredAccess,
|
||
OUT HKEY *phKeyCurrentUser
|
||
);
|
||
|
||
|
||
|
||
DWORD
|
||
NwQueryInfo(
|
||
OUT PDWORD pnPrintOptions,
|
||
OUT LPWSTR *ppszPreferredSrv
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
This routine gets the user's preferred server and print options from
|
||
the registry.
|
||
|
||
Arguments:
|
||
|
||
pnPrintOptions - Receives the user's print option
|
||
|
||
ppszPreferredSrv - Receives the user's preferred server
|
||
|
||
|
||
Return Value:
|
||
|
||
Returns the appropriate Win32 error.
|
||
|
||
--*/
|
||
{
|
||
|
||
HKEY hKeyCurrentUser = NULL;
|
||
DWORD BufferSize;
|
||
DWORD BytesNeeded;
|
||
DWORD PrintOption;
|
||
DWORD ValueType;
|
||
LPWSTR PreferredServer ;
|
||
DWORD err ;
|
||
|
||
//
|
||
// get to right place in registry and allocate dthe buffer
|
||
//
|
||
if (err = NwpGetCurrentUserRegKey( KEY_READ, &hKeyCurrentUser))
|
||
{
|
||
//
|
||
// If somebody mess around with the registry and we can't find
|
||
// the registry, just use the defaults.
|
||
//
|
||
*ppszPreferredSrv = NULL;
|
||
*pnPrintOptions = NW_PRINT_OPTION_DEFAULT;
|
||
return NO_ERROR;
|
||
}
|
||
|
||
BufferSize = sizeof(WCHAR) * (MAX_PATH + 2) ;
|
||
PreferredServer = (LPWSTR) LocalAlloc(LPTR, BufferSize) ;
|
||
if (!PreferredServer)
|
||
return (GetLastError()) ;
|
||
|
||
//
|
||
// Read PreferredServer value into Buffer.
|
||
//
|
||
BytesNeeded = BufferSize ;
|
||
|
||
err = RegQueryValueExW( hKeyCurrentUser,
|
||
NW_SERVER_VALUENAME,
|
||
NULL,
|
||
&ValueType,
|
||
(LPBYTE) PreferredServer,
|
||
&BytesNeeded );
|
||
|
||
if (err != NO_ERROR)
|
||
{
|
||
//
|
||
// set to empty and carry on
|
||
//
|
||
PreferredServer[0] = 0;
|
||
}
|
||
|
||
//
|
||
// Read PrintOption value into PrintOption.
|
||
//
|
||
BytesNeeded = sizeof(PrintOption);
|
||
|
||
err = RegQueryValueExW( hKeyCurrentUser,
|
||
NW_PRINTOPTION_VALUENAME,
|
||
NULL,
|
||
&ValueType,
|
||
(LPBYTE) &PrintOption,
|
||
&BytesNeeded );
|
||
|
||
if (err != NO_ERROR)
|
||
{
|
||
//
|
||
// set to default and carry on
|
||
//
|
||
PrintOption = NW_PRINT_OPTION_DEFAULT;
|
||
}
|
||
|
||
if (hKeyCurrentUser != NULL)
|
||
(void) RegCloseKey(hKeyCurrentUser) ;
|
||
*ppszPreferredSrv = PreferredServer ;
|
||
*pnPrintOptions = PrintOption ;
|
||
return NO_ERROR ;
|
||
}
|
||
|
||
|
||
|
||
DWORD
|
||
NwSetInfoInRegistry(
|
||
IN DWORD nPrintOptions,
|
||
IN LPWSTR pszPreferredSrv
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine set the user's print option and preferred server into
|
||
the registry.
|
||
|
||
Arguments:
|
||
|
||
nPrintOptions - Supplies the print option.
|
||
|
||
pszPreferredSrv - Supplies the preferred server.
|
||
|
||
Return Value:
|
||
|
||
Returns the appropriate Win32 error.
|
||
|
||
--*/
|
||
{
|
||
|
||
HKEY hKeyCurrentUser = NULL;
|
||
|
||
DWORD err = NwpGetCurrentUserRegKey( KEY_SET_VALUE,
|
||
&hKeyCurrentUser );
|
||
if (err != NO_ERROR)
|
||
return err;
|
||
|
||
err = RegSetValueEx(hKeyCurrentUser,
|
||
NW_SERVER_VALUENAME,
|
||
0,
|
||
REG_SZ,
|
||
(CONST BYTE *)pszPreferredSrv,
|
||
(wcslen(pszPreferredSrv)+1) * sizeof(WCHAR)) ;
|
||
|
||
if (err != NO_ERROR)
|
||
{
|
||
if (hKeyCurrentUser != NULL)
|
||
(void) RegCloseKey(hKeyCurrentUser) ;
|
||
return err;
|
||
}
|
||
|
||
err = RegSetValueEx(hKeyCurrentUser,
|
||
NW_PRINTOPTION_VALUENAME,
|
||
0,
|
||
REG_DWORD,
|
||
(CONST BYTE *)&nPrintOptions,
|
||
sizeof(nPrintOptions)) ;
|
||
|
||
if (hKeyCurrentUser != NULL)
|
||
(void) RegCloseKey(hKeyCurrentUser) ;
|
||
return err;
|
||
}
|
||
DWORD
|
||
NwQueryLogonOptions(
|
||
OUT PDWORD pnLogonScriptOptions
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
This routine gets the user's Logon script options from the registry.
|
||
|
||
Arguments:
|
||
|
||
pnLogonScriptOptions - Receives the user's Logon script options
|
||
|
||
|
||
Return Value:
|
||
|
||
Returns the appropriate Win32 error.
|
||
|
||
--*/
|
||
{
|
||
|
||
HKEY hKeyCurrentUser;
|
||
DWORD BytesNeeded;
|
||
DWORD LogonScriptOption;
|
||
DWORD ValueType;
|
||
DWORD err ;
|
||
|
||
//
|
||
// get to right place in registry and allocate the buffer
|
||
//
|
||
if (err = NwpGetCurrentUserRegKey( KEY_READ, &hKeyCurrentUser))
|
||
{
|
||
//
|
||
// If somebody mess around with the registry and we can't find
|
||
// the registry, assume no.
|
||
//
|
||
*pnLogonScriptOptions = NW_LOGONSCRIPT_DEFAULT ;
|
||
return NO_ERROR;
|
||
}
|
||
|
||
//
|
||
// Read LogonScriptOption value into LogonScriptOption.
|
||
//
|
||
BytesNeeded = sizeof(LogonScriptOption);
|
||
|
||
err = RegQueryValueExW( hKeyCurrentUser,
|
||
NW_LOGONSCRIPT_VALUENAME,
|
||
NULL,
|
||
&ValueType,
|
||
(LPBYTE) &LogonScriptOption,
|
||
&BytesNeeded );
|
||
|
||
if (err != NO_ERROR)
|
||
{
|
||
//
|
||
// default to nothing and carry on
|
||
//
|
||
LogonScriptOption = NW_LOGONSCRIPT_DEFAULT;
|
||
}
|
||
|
||
*pnLogonScriptOptions = LogonScriptOption ;
|
||
return NO_ERROR ;
|
||
}
|
||
|
||
DWORD
|
||
NwSetLogonOptionsInRegistry(
|
||
IN DWORD nLogonScriptOptions
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine set the logon script options in the registry.
|
||
|
||
Arguments:
|
||
|
||
nLogonScriptOptions - Supplies the logon options
|
||
|
||
Return Value:
|
||
|
||
Returns the appropriate Win32 error.
|
||
|
||
--*/
|
||
{
|
||
|
||
HKEY hKeyCurrentUser;
|
||
|
||
DWORD err = NwpGetCurrentUserRegKey( KEY_SET_VALUE,
|
||
&hKeyCurrentUser );
|
||
if (err != NO_ERROR)
|
||
return err;
|
||
|
||
err = RegSetValueEx(hKeyCurrentUser,
|
||
NW_LOGONSCRIPT_VALUENAME,
|
||
0,
|
||
REG_DWORD,
|
||
(CONST BYTE *)&nLogonScriptOptions,
|
||
sizeof(nLogonScriptOptions)) ;
|
||
|
||
(void) RegCloseKey( hKeyCurrentUser );
|
||
return err;
|
||
}
|
||
|
||
|
||
DWORD
|
||
NwSetInfoInWksta(
|
||
IN DWORD nPrintOption,
|
||
IN LPWSTR pszPreferredSrv
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine notifies the workstation service and the redirector
|
||
about the user's new print option and preferred server.
|
||
|
||
Arguments:
|
||
|
||
nPrintOptions - Supplies the print option.
|
||
|
||
pszPreferredSrv - Supplies the preferred server.
|
||
|
||
Return Value:
|
||
|
||
Returns the appropriate Win32 error.
|
||
|
||
--*/
|
||
{
|
||
DWORD err;
|
||
|
||
RpcTryExcept {
|
||
|
||
err = NwrSetInfo( NULL, nPrintOption, pszPreferredSrv );
|
||
|
||
}
|
||
RpcExcept(1) {
|
||
|
||
err = NwpMapRpcError(RpcExceptionCode());
|
||
}
|
||
RpcEndExcept
|
||
|
||
return err;
|
||
|
||
}
|
||
|
||
DWORD
|
||
NwSetLogonScript(
|
||
IN DWORD ScriptOptions
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine notifies the workstation service of login script
|
||
options.
|
||
|
||
Arguments:
|
||
|
||
ScriptOptions - Supplies the options.
|
||
|
||
Return Value:
|
||
|
||
Returns the appropriate Win32 error.
|
||
|
||
--*/
|
||
{
|
||
DWORD err;
|
||
|
||
RpcTryExcept {
|
||
|
||
err = NwrSetLogonScript( NULL, ScriptOptions );
|
||
|
||
}
|
||
RpcExcept(1) {
|
||
|
||
err = NwpMapRpcError(RpcExceptionCode());
|
||
}
|
||
RpcEndExcept
|
||
|
||
return err;
|
||
|
||
}
|
||
|
||
|
||
DWORD
|
||
NwValidateUser(
|
||
IN LPWSTR pszPreferredSrv
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine checks to see if the user can be authenticated on the
|
||
chosen preferred server.
|
||
|
||
Arguments:
|
||
|
||
pszPreferredSrv - Supplies the preferred server name.
|
||
|
||
Return Value:
|
||
|
||
Returns the appropriate Win32 error.
|
||
|
||
--*/
|
||
{
|
||
DWORD err;
|
||
|
||
//
|
||
// Don't need to validate if the preferred server is NULL or empty string
|
||
//
|
||
if ( ( pszPreferredSrv == NULL )
|
||
|| ( *pszPreferredSrv == 0 )
|
||
)
|
||
{
|
||
return NO_ERROR;
|
||
}
|
||
|
||
//
|
||
// See if the name contains any invalid characters
|
||
//
|
||
if ( !IS_VALID_SERVER_TOKEN( pszPreferredSrv, wcslen( pszPreferredSrv )))
|
||
return ERROR_INVALID_NAME;
|
||
|
||
RpcTryExcept {
|
||
|
||
err = NwrValidateUser( NULL, pszPreferredSrv );
|
||
|
||
}
|
||
RpcExcept(1) {
|
||
|
||
err = NwpMapRpcError( RpcExceptionCode() );
|
||
}
|
||
RpcEndExcept
|
||
|
||
return err;
|
||
}
|
||
|
||
|
||
DWORD
|
||
NwpGetCurrentUserRegKey(
|
||
IN DWORD DesiredAccess,
|
||
OUT HKEY *phKeyCurrentUser
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine opens the current user's registry key under
|
||
\HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\NWCWorkstation\Parameters
|
||
|
||
Arguments:
|
||
|
||
DesiredAccess - The access mask to open the key with
|
||
|
||
phKeyCurrentUser - Receives the opened key handle
|
||
|
||
Return Value:
|
||
|
||
Returns the appropriate Win32 error.
|
||
|
||
--*/
|
||
{
|
||
DWORD err;
|
||
HKEY hkeyWksta;
|
||
LPWSTR CurrentUser;
|
||
|
||
//
|
||
// Open HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services
|
||
// \NWCWorkstation\Parameters
|
||
//
|
||
err = RegOpenKeyExW(
|
||
HKEY_LOCAL_MACHINE,
|
||
NW_WORKSTATION_REGKEY,
|
||
REG_OPTION_NON_VOLATILE,
|
||
KEY_READ,
|
||
&hkeyWksta
|
||
);
|
||
|
||
if ( err ) {
|
||
KdPrint(("NWPROVAU: NwGetCurrentUserRegKey open Parameters key unexpected error %lu!\n", err));
|
||
return err;
|
||
}
|
||
|
||
// -- MultiUser code merge ----
|
||
// Get the current user's SID string
|
||
// DON'T look in the registry. This thread should be owned by the
|
||
// user.
|
||
//
|
||
CurrentUser = NULL;
|
||
err = NwpCitrixGetUserInfo( &CurrentUser );
|
||
if ( err ) {
|
||
KdPrint(("NWPROVAU: NwGetCurrentUserRegKey get CurrentUser SID unexpected error %lu!\n", err));
|
||
(void) RegCloseKey( hkeyWksta );
|
||
return err;
|
||
}
|
||
//
|
||
// Get the current user's SID string.
|
||
//
|
||
//err = NwReadRegValue(
|
||
// hkeyWksta,
|
||
// NW_CURRENTUSER_VALUENAME,
|
||
// &CurrentUser
|
||
// );
|
||
|
||
|
||
if ( err ) {
|
||
KdPrint(("NWPROVAU: NwGetCurrentUserRegKey read CurrentUser value unexpected error %lu!\n", err));
|
||
(void) RegCloseKey( hkeyWksta );
|
||
return err;
|
||
}
|
||
|
||
(void) RegCloseKey( hkeyWksta );
|
||
|
||
//
|
||
// Open HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services
|
||
// \NWCWorkstation\Parameters\Option
|
||
//
|
||
err = RegOpenKeyExW(
|
||
HKEY_LOCAL_MACHINE,
|
||
NW_WORKSTATION_OPTION_REGKEY,
|
||
REG_OPTION_NON_VOLATILE,
|
||
KEY_READ,
|
||
&hkeyWksta
|
||
);
|
||
|
||
if ( err ) {
|
||
KdPrint(("NWPROVAU: NwGetCurrentUserRegKey open Parameters\\Option key unexpected error %lu!\n", err));
|
||
return err;
|
||
}
|
||
|
||
//
|
||
// Open current user's key
|
||
//
|
||
err = RegOpenKeyExW(
|
||
hkeyWksta,
|
||
CurrentUser,
|
||
REG_OPTION_NON_VOLATILE,
|
||
DesiredAccess,
|
||
phKeyCurrentUser
|
||
);
|
||
|
||
if ( err == ERROR_FILE_NOT_FOUND)
|
||
{
|
||
DWORD Disposition;
|
||
|
||
//
|
||
// Create <NewUser> key under NWCWorkstation\Parameters\Option
|
||
//
|
||
err = RegCreateKeyExW(
|
||
hkeyWksta,
|
||
CurrentUser,
|
||
0,
|
||
WIN31_CLASS,
|
||
REG_OPTION_NON_VOLATILE,
|
||
DesiredAccess,
|
||
NULL, // security attr
|
||
phKeyCurrentUser,
|
||
&Disposition
|
||
);
|
||
|
||
if ( err == NO_ERROR )
|
||
{
|
||
err = NwLibSetEverybodyPermission( *phKeyCurrentUser,
|
||
KEY_SET_VALUE );
|
||
|
||
if ( err != NO_ERROR )
|
||
{
|
||
KdPrint(("NWPROVAU: NwpSaveLogonCredential set security on Option\\%ws key unexpected error %lu!\n", CurrentUser, err));
|
||
}
|
||
}
|
||
}
|
||
|
||
if ( err ) {
|
||
KdPrint(("NWPROVAU: NwGetCurrentUserRegKey open or create of Parameters\\Option\\%ws key failed %lu\n", CurrentUser, err));
|
||
}
|
||
|
||
(void) RegCloseKey( hkeyWksta );
|
||
(void) LocalFree((HLOCAL)CurrentUser) ;
|
||
return err;
|
||
}
|
||
|
||
DWORD
|
||
NwEnumGWDevices(
|
||
LPDWORD Index,
|
||
LPBYTE Buffer,
|
||
DWORD BufferSize,
|
||
LPDWORD BytesNeeded,
|
||
LPDWORD EntriesRead
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine enumerates the special gateway devices (redirections)
|
||
that are cureently in use.
|
||
|
||
Arguments:
|
||
|
||
Index - Point to start enumeration. Should be zero for first call.
|
||
|
||
Buffer - buffer for return data
|
||
|
||
BufferSize - size of buffer in bytes
|
||
|
||
BytesNeeded - number of bytes needed to return all the data
|
||
|
||
EntriesRead - number of entries read
|
||
|
||
Return Value:
|
||
|
||
Returns the appropriate Win32 error.
|
||
|
||
--*/
|
||
{
|
||
DWORD i, err ;
|
||
LPNETRESOURCE lpNetRes = (LPNETRESOURCE) Buffer ;
|
||
|
||
//
|
||
// call the implementing routine on server side
|
||
//
|
||
RpcTryExcept {
|
||
|
||
err = NwrEnumGWDevices( NULL,
|
||
Index,
|
||
Buffer,
|
||
BufferSize,
|
||
BytesNeeded,
|
||
EntriesRead) ;
|
||
|
||
if ( err == NO_ERROR)
|
||
{
|
||
//
|
||
// the change the offsets into real pointers
|
||
//
|
||
for (i = 0; i < *EntriesRead; i++)
|
||
{
|
||
lpNetRes->lpLocalName =
|
||
(LPWSTR) (Buffer+(DWORD_PTR)lpNetRes->lpLocalName) ;
|
||
lpNetRes->lpRemoteName =
|
||
(LPWSTR) (Buffer+(DWORD_PTR)lpNetRes->lpRemoteName) ;
|
||
lpNetRes->lpProvider =
|
||
(LPWSTR) (Buffer+(DWORD_PTR)lpNetRes->lpProvider) ;
|
||
lpNetRes++ ;
|
||
}
|
||
}
|
||
}
|
||
RpcExcept(1) {
|
||
|
||
err = NwpMapRpcError( RpcExceptionCode() );
|
||
}
|
||
RpcEndExcept
|
||
|
||
return err ;
|
||
}
|
||
|
||
|
||
DWORD
|
||
NwAddGWDevice(
|
||
LPWSTR DeviceName,
|
||
LPWSTR RemoteName,
|
||
LPWSTR AccountName,
|
||
LPWSTR Password,
|
||
DWORD Flags
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine adds a gateway redirection.
|
||
|
||
Arguments:
|
||
|
||
DeviceName - the drive to redirect
|
||
|
||
RemoteName - the remote network resource to redirect to
|
||
|
||
Flags - supplies the options (eg. UpdateRegistry & make this sticky)
|
||
|
||
Return Value:
|
||
|
||
Returns the appropriate Win32 error.
|
||
|
||
--*/
|
||
{
|
||
DWORD err;
|
||
|
||
RpcTryExcept {
|
||
|
||
err = NwrAddGWDevice( NULL,
|
||
DeviceName,
|
||
RemoteName,
|
||
AccountName,
|
||
Password,
|
||
Flags) ;
|
||
|
||
}
|
||
RpcExcept(1) {
|
||
|
||
err = NwpMapRpcError( RpcExceptionCode() );
|
||
}
|
||
RpcEndExcept
|
||
|
||
return err;
|
||
}
|
||
|
||
|
||
DWORD
|
||
NwDeleteGWDevice(
|
||
LPWSTR DeviceName,
|
||
DWORD Flags
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine deletes a gateway redirection.
|
||
|
||
Arguments:
|
||
|
||
DeviceName - the drive to delete
|
||
|
||
Flags - supplies the options (eg. UpdateRegistry & make this sticky)
|
||
|
||
Return Value:
|
||
|
||
Returns the appropriate Win32 error.
|
||
|
||
--*/
|
||
{
|
||
DWORD err;
|
||
|
||
RpcTryExcept {
|
||
|
||
err = NwrDeleteGWDevice(NULL, DeviceName, Flags) ;
|
||
|
||
}
|
||
RpcExcept(1) {
|
||
|
||
err = NwpMapRpcError( RpcExceptionCode() );
|
||
}
|
||
RpcEndExcept
|
||
|
||
return err;
|
||
}
|
||
|
||
|
||
DWORD
|
||
NwQueryGatewayAccount(
|
||
LPWSTR AccountName,
|
||
DWORD AccountNameLen,
|
||
LPDWORD AccountCharsNeeded,
|
||
LPWSTR Password,
|
||
DWORD PasswordLen,
|
||
LPDWORD PasswordCharsNeeded
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Query the gateway account info. specifically, the Account name and
|
||
the passeord stored as an LSA secret.
|
||
|
||
Arguments:
|
||
|
||
AccountName - buffer used to return account name
|
||
|
||
AccountNameLen - length of buffer
|
||
|
||
Password - buffer used to return account name
|
||
|
||
PasswordLen - length of buffer
|
||
|
||
Return Value:
|
||
|
||
Returns the appropriate Win32 error.
|
||
|
||
--*/
|
||
{
|
||
DWORD err;
|
||
|
||
RpcTryExcept {
|
||
|
||
if (AccountName && AccountNameLen)
|
||
*AccountName = 0 ;
|
||
|
||
if (Password && PasswordLen)
|
||
*Password = 0 ;
|
||
|
||
err = NwrQueryGatewayAccount(NULL,
|
||
AccountName,
|
||
AccountNameLen,
|
||
AccountCharsNeeded,
|
||
Password,
|
||
PasswordLen,
|
||
PasswordCharsNeeded) ;
|
||
}
|
||
RpcExcept(1) {
|
||
|
||
err = NwpMapRpcError( RpcExceptionCode() );
|
||
}
|
||
RpcEndExcept
|
||
|
||
return err;
|
||
}
|
||
|
||
DWORD
|
||
NwSetGatewayAccount(
|
||
LPWSTR AccountName,
|
||
LPWSTR Password
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Set the account and password to be used for gateway access.
|
||
|
||
Arguments:
|
||
|
||
AccountName - the account (NULL terminated)
|
||
|
||
Password - the password string (NULL terminated)
|
||
|
||
Return Value:
|
||
|
||
Returns the appropriate Win32 error.
|
||
|
||
--*/
|
||
{
|
||
DWORD err;
|
||
|
||
RpcTryExcept {
|
||
|
||
err = NwrSetGatewayAccount( NULL,
|
||
AccountName,
|
||
Password);
|
||
}
|
||
RpcExcept(1) {
|
||
|
||
err = NwpMapRpcError( RpcExceptionCode() );
|
||
}
|
||
RpcEndExcept
|
||
|
||
return err;
|
||
}
|
||
|
||
|
||
DWORD
|
||
NwLogonGatewayAccount(
|
||
LPWSTR AccountName,
|
||
LPWSTR Password,
|
||
LPWSTR Server
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Logon the SYSTEM process with the specified account/password.
|
||
|
||
Arguments:
|
||
|
||
AccountName - the account (NULL terminated)
|
||
|
||
Password - the password string (NULL terminated)
|
||
|
||
Server - the server to authenticate against
|
||
|
||
Return Value:
|
||
|
||
Returns the appropriate Win32 error.
|
||
|
||
--*/
|
||
{
|
||
|
||
DWORD err ;
|
||
LUID SystemId = SYSTEM_LUID ;
|
||
|
||
RpcTryExcept {
|
||
|
||
(void) NwrLogoffUser(NULL, &SystemId);
|
||
|
||
err = NwrLogonUser( NULL,
|
||
&SystemId,
|
||
AccountName,
|
||
Password,
|
||
Server,
|
||
NULL,
|
||
NULL,
|
||
0,
|
||
NW_GATEWAY_PRINT_OPTION_DEFAULT
|
||
);
|
||
}
|
||
RpcExcept(1) {
|
||
|
||
err = NwpMapRpcError( RpcExceptionCode() );
|
||
}
|
||
RpcEndExcept
|
||
|
||
return err ;
|
||
}
|
||
|
||
NTSTATUS
|
||
NwGetUserNameForServer(
|
||
PUNICODE_STRING ServerName,
|
||
PUNICODE_STRING UserName
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Calls the redir to get the User Name used to connect to the server
|
||
in question.
|
||
|
||
Arguments:
|
||
|
||
ServerName - the server in question
|
||
|
||
UserName - used to return the user name
|
||
|
||
Return Value:
|
||
|
||
Returns the appropriate NTSTATUS
|
||
|
||
--*/
|
||
{
|
||
NTSTATUS Status;
|
||
WCHAR LocalUserName[NW_MAX_USERNAME_LEN];
|
||
ULONG UserNameLen = sizeof(LocalUserName);
|
||
|
||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||
UNICODE_STRING DriverName;
|
||
HANDLE RdrHandle = NULL;
|
||
IO_STATUS_BLOCK IoStatus;
|
||
|
||
//
|
||
// Initialize variables
|
||
//
|
||
|
||
RtlInitUnicodeString( &DriverName, DD_NWFS_DEVICE_NAME_U );
|
||
InitializeObjectAttributes(
|
||
&ObjectAttributes,
|
||
&DriverName,
|
||
0,
|
||
NULL,
|
||
NULL
|
||
);
|
||
|
||
//
|
||
// open handle to the redir
|
||
//
|
||
|
||
Status = NtOpenFile(
|
||
&RdrHandle,
|
||
FILE_LIST_DIRECTORY | SYNCHRONIZE,
|
||
&ObjectAttributes,
|
||
&IoStatus,
|
||
FILE_SHARE_READ,
|
||
0 // open options
|
||
);
|
||
|
||
if (!NT_SUCCESS(Status) ||
|
||
!NT_SUCCESS(IoStatus.Status) )
|
||
{
|
||
return( Status );
|
||
}
|
||
|
||
|
||
//
|
||
// Call the driver to get use the user name
|
||
//
|
||
|
||
Status = NtFsControlFile(
|
||
RdrHandle,
|
||
NULL,
|
||
NULL,
|
||
NULL,
|
||
&IoStatus,
|
||
FSCTL_NWR_GET_USERNAME,
|
||
ServerName->Buffer,
|
||
ServerName->Length,
|
||
LocalUserName,
|
||
UserNameLen
|
||
);
|
||
|
||
NtClose(RdrHandle);
|
||
|
||
if (!NT_SUCCESS(Status))
|
||
{
|
||
return(Status);
|
||
}
|
||
|
||
//
|
||
// copy the info if it fits. set size required and fail otherwise.
|
||
//
|
||
|
||
if (UserName->MaximumLength >= IoStatus.Information)
|
||
{
|
||
UserName->Length = (USHORT) IoStatus.Information;
|
||
|
||
RtlCopyMemory( UserName->Buffer,
|
||
LocalUserName,
|
||
UserNameLen );
|
||
Status = STATUS_SUCCESS;
|
||
}
|
||
else
|
||
{
|
||
UserName->Length = (USHORT) IoStatus.Information;
|
||
Status = STATUS_BUFFER_TOO_SMALL;
|
||
}
|
||
|
||
return(Status);
|
||
}
|
||
|
||
|
||
NTSTATUS
|
||
NwEncryptChallenge(
|
||
IN PUCHAR Challenge,
|
||
IN ULONG ObjectId,
|
||
IN OPTIONAL PUNICODE_STRING ServerName,
|
||
IN OPTIONAL PUNICODE_STRING Password,
|
||
OUT PUCHAR ChallengeResponse,
|
||
OUT OPTIONAL PUCHAR SessionKey
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Calls the redir to encrypt a challenge
|
||
|
||
Arguments:
|
||
|
||
Challenge - Challenge key
|
||
|
||
ObjectId - User's object ID
|
||
|
||
ServerName - The server to authenticate against
|
||
|
||
Password - Password supplied
|
||
|
||
ChallengeResponse - Used to return the challenge response
|
||
|
||
SessionKey - Used to return the session key
|
||
|
||
Return Value:
|
||
|
||
Returns the appropriate NTSTATUS
|
||
|
||
--*/
|
||
{
|
||
NTSTATUS Status;
|
||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||
UNICODE_STRING DriverName;
|
||
HANDLE RdrHandle = NULL;
|
||
IO_STATUS_BLOCK IoStatus;
|
||
PNWR_GET_CHALLENGE_REQUEST ChallengeRequest = NULL;
|
||
NWR_GET_CHALLENGE_REPLY ChallengeReply;
|
||
ULONG ChallengeRequestSize;
|
||
|
||
//
|
||
// Initialize variables
|
||
//
|
||
|
||
RtlInitUnicodeString( &DriverName, DD_NWFS_DEVICE_NAME_U );
|
||
|
||
InitializeObjectAttributes(
|
||
&ObjectAttributes,
|
||
&DriverName,
|
||
0,
|
||
NULL,
|
||
NULL
|
||
);
|
||
|
||
//
|
||
// open handle to redirector
|
||
//
|
||
|
||
Status = NtOpenFile(
|
||
&RdrHandle,
|
||
FILE_LIST_DIRECTORY | SYNCHRONIZE,
|
||
&ObjectAttributes,
|
||
&IoStatus,
|
||
FILE_SHARE_READ,
|
||
0 // open options
|
||
);
|
||
|
||
if (!NT_SUCCESS(Status) ||
|
||
!NT_SUCCESS(IoStatus.Status) )
|
||
{
|
||
return( Status );
|
||
}
|
||
|
||
|
||
|
||
ChallengeRequestSize = sizeof(NWR_GET_CHALLENGE_REQUEST) +
|
||
((Password != NULL) ? Password->Length : 0) +
|
||
((ServerName != NULL) ? ServerName->Length : 0);
|
||
|
||
ChallengeRequest = (PNWR_GET_CHALLENGE_REQUEST) RtlAllocateHeap(
|
||
RtlProcessHeap(),
|
||
0,
|
||
ChallengeRequestSize
|
||
);
|
||
|
||
if (ChallengeRequest == NULL )
|
||
{
|
||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||
goto Cleanup;
|
||
}
|
||
|
||
//
|
||
// Marshall the challenge request structure. Only send servername if
|
||
// password has not been specified.
|
||
//
|
||
|
||
ChallengeRequest->ObjectId = ObjectId;
|
||
ChallengeRequest->Flags = 0;
|
||
|
||
//
|
||
// If both password and servername are present, use the password.
|
||
//
|
||
|
||
if ((Password != NULL) && (Password->Length != 0))
|
||
{
|
||
|
||
ChallengeRequest->ServerNameorPasswordLength = Password->Length;
|
||
RtlCopyMemory(
|
||
ChallengeRequest->ServerNameorPassword,
|
||
Password->Buffer,
|
||
Password->Length
|
||
);
|
||
ChallengeRequest->Flags = CHALLENGE_FLAGS_PASSWORD;
|
||
|
||
}
|
||
else if ((ServerName != NULL) && (ServerName->Length != 0))
|
||
{
|
||
|
||
ChallengeRequest->ServerNameorPasswordLength = ServerName->Length;
|
||
|
||
RtlCopyMemory(
|
||
ChallengeRequest->ServerNameorPassword,
|
||
ServerName->Buffer,
|
||
ServerName->Length
|
||
);
|
||
|
||
ChallengeRequest->Flags = CHALLENGE_FLAGS_SERVERNAME;
|
||
}
|
||
|
||
RtlCopyMemory(
|
||
ChallengeRequest->Challenge,
|
||
Challenge,
|
||
8
|
||
);
|
||
|
||
//
|
||
// Issue FS control to redir to get challenge response
|
||
//
|
||
|
||
Status = NtFsControlFile(
|
||
RdrHandle,
|
||
NULL,
|
||
NULL,
|
||
NULL,
|
||
&IoStatus,
|
||
FSCTL_NWR_CHALLENGE,
|
||
ChallengeRequest,
|
||
ChallengeRequestSize,
|
||
&ChallengeReply,
|
||
sizeof(ChallengeReply)
|
||
);
|
||
if (!NT_SUCCESS(Status) || !NT_SUCCESS(IoStatus.Status)) {
|
||
goto Cleanup;
|
||
}
|
||
|
||
|
||
RtlCopyMemory(
|
||
ChallengeResponse,
|
||
ChallengeReply.Challenge,
|
||
8
|
||
);
|
||
|
||
if (SessionKey != NULL)
|
||
{
|
||
RtlCopyMemory(
|
||
ChallengeResponse,
|
||
ChallengeReply.Challenge,
|
||
8
|
||
);
|
||
}
|
||
|
||
Cleanup:
|
||
|
||
if (RdrHandle != NULL)
|
||
{
|
||
NtClose(RdrHandle);
|
||
}
|
||
|
||
if (ChallengeRequest != NULL)
|
||
{
|
||
RtlFreeHeap(
|
||
RtlProcessHeap(),
|
||
0,
|
||
ChallengeRequest
|
||
);
|
||
}
|
||
|
||
return(Status);
|
||
}
|
||
|