windows-nt/Source/XPSP1/NT/inetsrv/iis/svcs/w3/client/w3stub.c
2020-09-26 16:20:57 +08:00

506 lines
9.3 KiB
C
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*++
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;
}