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;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|