/*++ 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 #include #include #include "w3svci_c.h" // W3_USER_ENUM_STRUCT #include "w3svc.h" #include #include #include 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; }