506 lines
9.3 KiB
C
506 lines
9.3 KiB
C
/*++
|
||
|
||
Copyright (c) 1991 Microsoft Corporation
|
||
|
||
Module Name:
|
||
|
||
w3stub.c
|
||
|
||
Abstract:
|
||
|
||
Client stubs of the W3 Daemon APIs.
|
||
|
||
Author:
|
||
|
||
Dan Hinsley (DanHi) 23-Mar-1993
|
||
|
||
Environment:
|
||
|
||
User Mode - Win32
|
||
|
||
Revision History:
|
||
|
||
--*/
|
||
|
||
#include <nt.h>
|
||
#include <ntrtl.h>
|
||
#include <nturtl.h>
|
||
|
||
#include "w3svci_c.h" // W3_USER_ENUM_STRUCT
|
||
|
||
#include "w3svc.h"
|
||
#include <winsock2.h>
|
||
|
||
#include <ntsam.h>
|
||
#include <ntlsa.h>
|
||
|
||
DWORD
|
||
GetSecret(
|
||
IN LPWSTR Server,
|
||
IN LPWSTR SecretName,
|
||
OUT LPWSTR * ppSecret
|
||
);
|
||
|
||
DWORD
|
||
SetSecret(
|
||
IN LPWSTR Server,
|
||
IN LPWSTR SecretName,
|
||
IN LPWSTR pSecret,
|
||
IN DWORD cbSecret
|
||
);
|
||
|
||
NET_API_STATUS
|
||
NET_API_FUNCTION
|
||
W3GetAdminInformation(
|
||
IN LPWSTR Server OPTIONAL,
|
||
OUT LPW3_CONFIG_INFO * ppConfig
|
||
)
|
||
{
|
||
NET_API_STATUS status;
|
||
LPWSTR pSecret;
|
||
|
||
RpcTryExcept {
|
||
|
||
//
|
||
// Try RPC (local or remote) version of API.
|
||
//
|
||
status = W3rGetAdminInformation(
|
||
Server,
|
||
ppConfig
|
||
);
|
||
}
|
||
RpcExcept (1) {
|
||
status = RpcExceptionCode();
|
||
}
|
||
RpcEndExcept
|
||
|
||
if ( status )
|
||
return status;
|
||
|
||
memset( (*ppConfig)->szCatapultUserPwd,
|
||
0,
|
||
sizeof( (*ppConfig)->szCatapultUserPwd ));
|
||
|
||
return (status);
|
||
}
|
||
|
||
NET_API_STATUS
|
||
NET_API_FUNCTION
|
||
W3SetAdminInformation(
|
||
IN LPWSTR Server OPTIONAL,
|
||
IN LPW3_CONFIG_INFO pConfig
|
||
)
|
||
{
|
||
NET_API_STATUS status;
|
||
|
||
RpcTryExcept {
|
||
|
||
//
|
||
// Try RPC (local or remote) version of API.
|
||
//
|
||
status = W3rSetAdminInformation(
|
||
Server,
|
||
pConfig
|
||
);
|
||
}
|
||
RpcExcept (1) {
|
||
status = RpcExceptionCode();
|
||
}
|
||
RpcEndExcept
|
||
|
||
if ( status )
|
||
return status;
|
||
|
||
return (status);
|
||
}
|
||
|
||
|
||
|
||
NET_API_STATUS
|
||
NET_API_FUNCTION
|
||
W3EnumerateUsers(
|
||
IN LPWSTR Server OPTIONAL,
|
||
OUT LPDWORD EntriesRead,
|
||
OUT LPW3_USER_INFO * Buffer
|
||
)
|
||
{
|
||
NET_API_STATUS status;
|
||
W3_USER_ENUM_STRUCT EnumStruct;
|
||
|
||
RpcTryExcept {
|
||
|
||
//
|
||
// Try RPC (local or remote) version of API.
|
||
//
|
||
status = W3rEnumerateUsers(
|
||
Server,
|
||
&EnumStruct
|
||
);
|
||
*EntriesRead = EnumStruct.EntriesRead;
|
||
*Buffer = EnumStruct.Buffer;
|
||
|
||
}
|
||
RpcExcept (1) {
|
||
status = RpcExceptionCode();
|
||
}
|
||
RpcEndExcept
|
||
|
||
return (status);
|
||
|
||
}
|
||
|
||
|
||
NET_API_STATUS
|
||
NET_API_FUNCTION
|
||
W3DisconnectUser(
|
||
IN LPWSTR Server OPTIONAL,
|
||
IN DWORD User
|
||
)
|
||
|
||
{
|
||
NET_API_STATUS status;
|
||
|
||
RpcTryExcept {
|
||
|
||
//
|
||
// Try RPC (local or remote) version of API.
|
||
//
|
||
status = W3rDisconnectUser(
|
||
Server,
|
||
User
|
||
);
|
||
}
|
||
RpcExcept (1) {
|
||
status = RpcExceptionCode();
|
||
}
|
||
RpcEndExcept
|
||
|
||
return (status);
|
||
|
||
}
|
||
|
||
|
||
NET_API_STATUS
|
||
NET_API_FUNCTION
|
||
W3QueryStatistics(
|
||
IN LPWSTR Server OPTIONAL,
|
||
IN DWORD Level,
|
||
OUT LPBYTE * Buffer
|
||
)
|
||
{
|
||
NET_API_STATUS status;
|
||
|
||
*Buffer = NULL;
|
||
|
||
RpcTryExcept {
|
||
|
||
//
|
||
// Try RPC (local or remote) version of API.
|
||
//
|
||
status = W3rQueryStatistics(
|
||
Server,
|
||
Level,
|
||
(LPSTATISTICS_INFO)Buffer
|
||
);
|
||
}
|
||
RpcExcept (1) {
|
||
status = RpcExceptionCode();
|
||
}
|
||
RpcEndExcept
|
||
|
||
return (status);
|
||
|
||
}
|
||
|
||
|
||
NET_API_STATUS
|
||
NET_API_FUNCTION
|
||
W3ClearStatistics(
|
||
IN LPWSTR Server OPTIONAL
|
||
)
|
||
{
|
||
NET_API_STATUS status;
|
||
|
||
RpcTryExcept {
|
||
|
||
//
|
||
// Try RPC (local or remote) version of API.
|
||
//
|
||
status = W3rClearStatistics(
|
||
Server
|
||
);
|
||
}
|
||
RpcExcept (1) {
|
||
status = RpcExceptionCode();
|
||
}
|
||
RpcEndExcept
|
||
|
||
return (status);
|
||
|
||
}
|
||
|
||
DWORD
|
||
GetSecret(
|
||
IN LPWSTR Server,
|
||
IN LPWSTR SecretName,
|
||
OUT LPWSTR * ppSecret
|
||
)
|
||
/*++
|
||
|
||
Description
|
||
|
||
Gets the specified LSA secret
|
||
|
||
Arguments:
|
||
|
||
Server - Server name (or NULL) secret lives on
|
||
SecretName - Name of the LSA secret
|
||
ppSecret - Receives an allocated block of memory containing the secret.
|
||
Must be freed with LocalFree.
|
||
|
||
Note:
|
||
|
||
--*/
|
||
{
|
||
LSA_HANDLE hPolicy;
|
||
UNICODE_STRING * punicodePassword;
|
||
UNICODE_STRING unicodeServer;
|
||
NTSTATUS ntStatus;
|
||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||
LSA_HANDLE hSecret;
|
||
UNICODE_STRING unicodeSecret;
|
||
|
||
|
||
RtlInitUnicodeString( &unicodeServer,
|
||
Server );
|
||
|
||
//
|
||
// Open a policy to the remote LSA
|
||
//
|
||
|
||
InitializeObjectAttributes( &ObjectAttributes,
|
||
NULL,
|
||
0L,
|
||
NULL,
|
||
NULL );
|
||
|
||
ntStatus = LsaOpenPolicy( &unicodeServer,
|
||
&ObjectAttributes,
|
||
POLICY_ALL_ACCESS,
|
||
&hPolicy );
|
||
|
||
if ( !NT_SUCCESS( ntStatus ) )
|
||
return RtlNtStatusToDosError( ntStatus );
|
||
|
||
//
|
||
// Open the LSA secret
|
||
//
|
||
|
||
RtlInitUnicodeString( &unicodeSecret,
|
||
SecretName );
|
||
|
||
ntStatus = LsaOpenSecret( hPolicy,
|
||
&unicodeSecret,
|
||
SECRET_ALL_ACCESS,
|
||
&hSecret );
|
||
|
||
LsaClose( hPolicy );
|
||
|
||
if ( !NT_SUCCESS( ntStatus ))
|
||
return RtlNtStatusToDosError( ntStatus );
|
||
|
||
//
|
||
// Query the secret value
|
||
//
|
||
|
||
ntStatus = LsaQuerySecret( hSecret,
|
||
&punicodePassword,
|
||
NULL,
|
||
NULL,
|
||
NULL );
|
||
|
||
LsaClose( hSecret );
|
||
|
||
if ( !NT_SUCCESS( ntStatus ))
|
||
return RtlNtStatusToDosError( ntStatus );
|
||
|
||
*ppSecret = LocalAlloc( LPTR, punicodePassword->Length + sizeof(WCHAR) );
|
||
|
||
if ( !*ppSecret )
|
||
{
|
||
RtlZeroMemory( punicodePassword->Buffer,
|
||
punicodePassword->MaximumLength );
|
||
|
||
LsaFreeMemory( (PVOID) punicodePassword );
|
||
return ERROR_NOT_ENOUGH_MEMORY;
|
||
}
|
||
|
||
//
|
||
// Copy it into the buffer, Length is count of bytes
|
||
//
|
||
|
||
memcpy( *ppSecret,
|
||
punicodePassword->Buffer,
|
||
punicodePassword->Length );
|
||
|
||
(*ppSecret)[punicodePassword->Length/sizeof(WCHAR)] = L'\0';
|
||
|
||
RtlZeroMemory( punicodePassword->Buffer,
|
||
punicodePassword->MaximumLength );
|
||
LsaFreeMemory( (PVOID) punicodePassword );
|
||
|
||
return NO_ERROR;
|
||
}
|
||
|
||
DWORD
|
||
SetSecret(
|
||
IN LPWSTR Server,
|
||
IN LPWSTR SecretName,
|
||
IN LPWSTR pSecret,
|
||
IN DWORD cbSecret
|
||
)
|
||
/*++
|
||
|
||
Description
|
||
|
||
Sets the specified LSA secret
|
||
|
||
Arguments:
|
||
|
||
Server - Server name (or NULL) secret lives on
|
||
SecretName - Name of the LSA secret
|
||
pSecret - Pointer to secret memory
|
||
cbSecret - Size of pSecret memory block
|
||
|
||
Note:
|
||
|
||
--*/
|
||
{
|
||
LSA_HANDLE hPolicy;
|
||
UNICODE_STRING unicodePassword;
|
||
UNICODE_STRING unicodeServer;
|
||
NTSTATUS ntStatus;
|
||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||
LSA_HANDLE hSecret;
|
||
UNICODE_STRING unicodeSecret;
|
||
|
||
|
||
RtlInitUnicodeString( &unicodeServer,
|
||
Server );
|
||
|
||
//
|
||
// Initialize the unicode string by hand so we can handle '\0' in the
|
||
// string
|
||
//
|
||
|
||
unicodePassword.Buffer = pSecret;
|
||
unicodePassword.Length = (USHORT) cbSecret;
|
||
unicodePassword.MaximumLength = (USHORT) cbSecret;
|
||
|
||
//
|
||
// Open a policy to the remote LSA
|
||
//
|
||
|
||
InitializeObjectAttributes( &ObjectAttributes,
|
||
NULL,
|
||
0L,
|
||
NULL,
|
||
NULL );
|
||
|
||
ntStatus = LsaOpenPolicy( &unicodeServer,
|
||
&ObjectAttributes,
|
||
POLICY_ALL_ACCESS,
|
||
&hPolicy );
|
||
|
||
if ( !NT_SUCCESS( ntStatus ) )
|
||
return RtlNtStatusToDosError( ntStatus );
|
||
|
||
//
|
||
// Create or open the LSA secret
|
||
//
|
||
|
||
RtlInitUnicodeString( &unicodeSecret,
|
||
SecretName );
|
||
|
||
ntStatus = LsaCreateSecret( hPolicy,
|
||
&unicodeSecret,
|
||
SECRET_ALL_ACCESS,
|
||
&hSecret );
|
||
|
||
if ( !NT_SUCCESS( ntStatus ))
|
||
{
|
||
|
||
//
|
||
// If the secret already exists, then we just need to open it
|
||
//
|
||
|
||
if ( ntStatus == STATUS_OBJECT_NAME_COLLISION )
|
||
{
|
||
ntStatus = LsaOpenSecret( hPolicy,
|
||
&unicodeSecret,
|
||
SECRET_ALL_ACCESS,
|
||
&hSecret );
|
||
}
|
||
|
||
if ( !NT_SUCCESS( ntStatus ))
|
||
{
|
||
LsaClose( hPolicy );
|
||
return RtlNtStatusToDosError( ntStatus );
|
||
}
|
||
}
|
||
|
||
//
|
||
// Set the secret value
|
||
//
|
||
|
||
ntStatus = LsaSetSecret( hSecret,
|
||
&unicodePassword,
|
||
&unicodePassword );
|
||
|
||
LsaClose( hSecret );
|
||
LsaClose( hPolicy );
|
||
|
||
if ( !NT_SUCCESS( ntStatus ))
|
||
{
|
||
return RtlNtStatusToDosError( ntStatus );
|
||
}
|
||
|
||
return NO_ERROR;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|