[NETAPI32] Add the NetpAllocStrFromWStr helper function
[reactos.git] / dll / win32 / netapi32 / misc.c
index c864e17..8fa84a0 100644 (file)
 /*
- * COPYRIGHT:       See COPYING in the top level directory
- * PROJECT:         NetAPI DLL
- * FILE:            reactos/dll/win32/netapi32/misc.c
- * PURPOSE:         Helper functions
- *
- * PROGRAMMERS:     Eric Kohl
+ * PROJECT:     NetAPI DLL
+ * LICENSE:     GPL-2.0 (https://spdx.org/licenses/GPL-2.0)
+ * PURPOSE:     Miscellaneous functions
+ * COPYRIGHT:   Copyright 2017 Eric Kohl (eric.kohl@reactos.org)
  */
 
 /* INCLUDES ******************************************************************/
 
 #include "netapi32.h"
 
-WINE_DEFAULT_DEBUG_CHANNEL(netapi32);
+#include <rpc.h>
+#include "srvsvc_c.h"
+#include "wkssvc_c.h"
 
-/* GLOBALS *******************************************************************/
 
-static SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY};
+WINE_DEFAULT_DEBUG_CHANNEL(netapi32);
 
 /* FUNCTIONS *****************************************************************/
 
-NTSTATUS
-GetAccountDomainSid(IN PUNICODE_STRING ServerName,
-                    OUT PSID *AccountDomainSid)
+NET_API_STATUS
+WINAPI
+NetRegisterDomainNameChangeNotification(
+    _Out_ PHANDLE NotificationEventHandle)
 {
-    PPOLICY_ACCOUNT_DOMAIN_INFO AccountDomainInfo = NULL;
-    LSA_OBJECT_ATTRIBUTES ObjectAttributes;
-    LSA_HANDLE PolicyHandle = NULL;
-    ULONG Length = 0;
+    HANDLE EventHandle;
     NTSTATUS Status;
 
-    memset(&ObjectAttributes, 0, sizeof(LSA_OBJECT_ATTRIBUTES));
+    TRACE("NetRegisterDomainNameChangeNotification(%p)\n",
+          NotificationEventHandle);
 
-    Status = LsaOpenPolicy(ServerName,
-                           &ObjectAttributes,
-                           POLICY_VIEW_LOCAL_INFORMATION,
-                           &PolicyHandle);
-    if (!NT_SUCCESS(Status))
-    {
-        ERR("LsaOpenPolicy failed (Status %08lx)\n", Status);
-        return Status;
-    }
+    if (NotificationEventHandle == NULL)
+        return ERROR_INVALID_PARAMETER;
 
-    Status = LsaQueryInformationPolicy(PolicyHandle,
-                                       PolicyAccountDomainInformation,
-                                       (PVOID *)&AccountDomainInfo);
+    EventHandle = CreateEventW(NULL, FALSE, FALSE, NULL);
+    if (EventHandle == NULL)
+        return GetLastError();
+
+    Status = LsaRegisterPolicyChangeNotification(PolicyNotifyDnsDomainInformation,
+                                                 NotificationEventHandle);
     if (!NT_SUCCESS(Status))
     {
-        ERR("LsaQueryInformationPolicy failed (Status %08lx)\n", Status);
-        goto done;
+        CloseHandle(EventHandle);
+        return NetpNtStatusToApiStatus(Status);
     }
 
-    Length = RtlLengthSid(AccountDomainInfo->DomainSid);
+    *NotificationEventHandle = EventHandle;
 
-    *AccountDomainSid = RtlAllocateHeap(RtlGetProcessHeap(), 0, Length);
-    if (*AccountDomainSid == NULL)
-    {
-        ERR("Failed to allocate SID\n");
-        Status = STATUS_INSUFFICIENT_RESOURCES;
-        goto done;
-    }
+    return NERR_Success;
+}
 
-    memcpy(*AccountDomainSid, AccountDomainInfo->DomainSid, Length);
 
-done:
-    if (AccountDomainInfo != NULL)
-        LsaFreeMemory(AccountDomainInfo);
+NET_API_STATUS
+WINAPI
+NetStatisticsGet(
+    _In_ LPWSTR server,
+    _In_ LPWSTR service,
+    _In_ DWORD level,
+    _In_ DWORD options,
+    _Out_ LPBYTE *bufptr)
+{
+    NET_API_STATUS status = ERROR_NOT_SUPPORTED;
 
-    LsaClose(PolicyHandle);
+    TRACE("NetStatisticsGet(%s %s %lu %lu %p)\n",
+          debugstr_w(server), debugstr_w(service), level, options, bufptr);
 
-    return Status;
+    *bufptr = NULL;
+
+    if (_wcsicmp(service, L"LanmanWorkstation") == 0)
+    {
+        if (level != 0)
+            return ERROR_INVALID_LEVEL;
+
+        if (options != 0)
+            return ERROR_INVALID_PARAMETER;
+
+        RpcTryExcept
+        {
+            status = NetrWorkstationStatisticsGet(server,
+                                                  L"LanmanWorkstation",
+                                                  level,
+                                                  options,
+                                                  (LPSTAT_WORKSTATION_0*)bufptr);
+        }
+        RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+        {
+            status = I_RpcMapWin32Status(RpcExceptionCode());
+        }
+        RpcEndExcept;
+    }
+    else if (_wcsicmp(service, L"LanmanServer") == 0)
+    {
+        if (level != 0)
+            return ERROR_INVALID_LEVEL;
+
+        if (options != 0)
+            return ERROR_INVALID_PARAMETER;
+
+        RpcTryExcept
+        {
+            status = NetrServerStatisticsGet(server,
+                                             L"LanmanServer",
+                                             level,
+                                             options,
+                                             (LPSTAT_SERVER_0 *)bufptr);
+        }
+        RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+        {
+            status = I_RpcMapWin32Status(RpcExceptionCode());
+        }
+        RpcEndExcept;
+    }
+
+    return status;
 }
 
 
-NTSTATUS
-GetBuiltinDomainSid(OUT PSID *BuiltinDomainSid)
+NET_API_STATUS
+WINAPI
+NetUnregisterDomainNameChangeNotification(
+    _In_ HANDLE NotificationEventHandle)
 {
-    PSID Sid = NULL;
-    PULONG Ptr;
-    NTSTATUS Status = STATUS_SUCCESS;
+    NTSTATUS Status;
 
-    *BuiltinDomainSid = NULL;
+    TRACE("NetUnregisterDomainNameChangeNotification(%p)\n",
+          NotificationEventHandle);
 
-    Sid = RtlAllocateHeap(RtlGetProcessHeap(),
-                          0,
-                          RtlLengthRequiredSid(1));
-    if (Sid == NULL)
-        return STATUS_INSUFFICIENT_RESOURCES;
+    if (NotificationEventHandle == NULL)
+        return ERROR_INVALID_PARAMETER;
 
-    Status = RtlInitializeSid(Sid,
-                              &NtAuthority,
-                              1);
-    if (!NT_SUCCESS(Status))
-        goto done;
+    Status = LsaUnregisterPolicyChangeNotification(PolicyNotifyDnsDomainInformation,
+                                                   NotificationEventHandle);
 
-    Ptr = RtlSubAuthoritySid(Sid, 0);
-    *Ptr = SECURITY_BUILTIN_DOMAIN_RID;
+    return NetpNtStatusToApiStatus(Status);
+}
 
-    *BuiltinDomainSid = Sid;
 
-done:
+PSTR
+WINAPI
+NetpAllocAnsiStrFromWStr(
+    _In_ PWSTR InString)
+{
+    UNICODE_STRING UnicodeString;
+    ANSI_STRING AnsiString;
+    ULONG Size;
+    NET_API_STATUS NetStatus;
+    NTSTATUS Status;
+
+    RtlInitUnicodeString(&UnicodeString, InString);
+
+    Size = RtlUnicodeStringToAnsiSize(&UnicodeString);
+    NetStatus = NetApiBufferAllocate(Size,
+                                     (PVOID*)&AnsiString.Buffer);
+    if (NetStatus != NERR_Success)
+        return NULL;
+
+    Status = RtlUnicodeStringToAnsiString(&AnsiString,
+                                          &UnicodeString,
+                                          FALSE);
     if (!NT_SUCCESS(Status))
     {
-        if (Sid != NULL)
-            RtlFreeHeap(RtlGetProcessHeap(), 0, Sid);
+        NetApiBufferFree(AnsiString.Buffer);
+        return NULL;
     }
 
-    return Status;
+    return AnsiString.Buffer;
 }
 
 
-NTSTATUS
-OpenAccountDomain(IN SAM_HANDLE ServerHandle,
-                  IN PUNICODE_STRING ServerName,
-                  IN ULONG DesiredAccess,
-                  OUT PSAM_HANDLE DomainHandle)
+PSTR
+WINAPI
+NetpAllocStrFromWStr(
+    _In_ PWSTR InString)
 {
-    PSID DomainSid = NULL;
+    UNICODE_STRING UnicodeString;
+    OEM_STRING OemString;
+    ULONG Size;
+    NET_API_STATUS NetStatus;
     NTSTATUS Status;
 
-    Status = GetAccountDomainSid(ServerName,
-                                 &DomainSid);
-    if (!NT_SUCCESS(Status))
-    {
-        ERR("GetAccountDomainSid failed (Status %08lx)\n", Status);
-        return Status;
-    }
-
-    Status = SamOpenDomain(ServerHandle,
-                           DesiredAccess,
-                           DomainSid,
-                           DomainHandle);
+    RtlInitUnicodeString(&UnicodeString, InString);
 
-    RtlFreeHeap(RtlGetProcessHeap(), 0, DomainSid);
+    Size = RtlUnicodeStringToOemSize(&UnicodeString);
+    NetStatus = NetApiBufferAllocate(Size,
+                                     (PVOID*)&OemString.Buffer);
+    if (NetStatus != NERR_Success)
+        return NULL;
 
+    Status = RtlUnicodeStringToOemString(&OemString,
+                                         &UnicodeString,
+                                         FALSE);
     if (!NT_SUCCESS(Status))
     {
-        ERR("SamOpenDomain failed (Status %08lx)\n", Status);
+        NetApiBufferFree(OemString.Buffer);
+        return NULL;
     }
 
-    return Status;
+    return OemString.Buffer;
 }
 
 
-NTSTATUS
-OpenBuiltinDomain(IN SAM_HANDLE ServerHandle,
-                  IN ULONG DesiredAccess,
-                  OUT PSAM_HANDLE DomainHandle)
+PWSTR
+WINAPI
+NetpAllocWStrFromAnsiStr(
+    _In_ PSTR InString)
 {
-    PSID DomainSid = NULL;
+    ANSI_STRING AnsiString;
+    UNICODE_STRING UnicodeString;
+    ULONG Size;
+    NET_API_STATUS NetStatus;
     NTSTATUS Status;
 
-    Status = GetBuiltinDomainSid(&DomainSid);
+    RtlInitAnsiString(&AnsiString, InString);
+
+    Size = RtlAnsiStringToUnicodeSize(&AnsiString);
+    NetStatus = NetApiBufferAllocate(Size,
+                                     (PVOID*)&UnicodeString.Buffer);
+    if (NetStatus != NERR_Success)
+        return NULL;
+
+    Status = RtlAnsiStringToUnicodeString(&UnicodeString,
+                                          &AnsiString,
+                                          FALSE);
     if (!NT_SUCCESS(Status))
     {
-        ERR("GetBuiltinDomainSid failed (Status %08lx)\n", Status);
-        return Status;
+        NetApiBufferFree(UnicodeString.Buffer);
+        return NULL;
     }
 
-    Status = SamOpenDomain(ServerHandle,
-                           DesiredAccess,
-                           DomainSid,
-                           DomainHandle);
+    return UnicodeString.Buffer;
+}
+
+
+PWSTR
+WINAPI
+NetpAllocWStrFromStr(
+    _In_ PSTR InString)
+{
+    OEM_STRING OemString;
+    UNICODE_STRING UnicodeString;
+    ULONG Size;
+    NET_API_STATUS NetStatus;
+    NTSTATUS Status;
+
+    RtlInitAnsiString((PANSI_STRING)&OemString, InString);
 
-    RtlFreeHeap(RtlGetProcessHeap(), 0, DomainSid);
+    Size = RtlOemStringToUnicodeSize(&OemString);
+    NetStatus = NetApiBufferAllocate(Size,
+                                     (PVOID*)&UnicodeString.Buffer);
+    if (NetStatus != NERR_Success)
+        return NULL;
 
+    Status = RtlOemStringToUnicodeString(&UnicodeString,
+                                         &OemString,
+                                         FALSE);
     if (!NT_SUCCESS(Status))
     {
-        ERR("SamOpenDomain failed (Status %08lx)\n", Status);
+        NetApiBufferFree(UnicodeString.Buffer);
+        return NULL;
     }
 
-    return Status;
+    return UnicodeString.Buffer;
 }
 
 
-NET_API_STATUS
-BuildSidFromSidAndRid(IN PSID SrcSid,
-                      IN ULONG RelativeId,
-                      OUT PSID *DestSid)
+PWSTR
+WINAPI
+NetpAllocWStrFromWStr(
+    _In_ PWSTR InString)
 {
-    UCHAR RidCount;
-    PSID DstSid;
-    ULONG i;
-    ULONG DstSidSize;
-    PULONG p, q;
-    NET_API_STATUS ApiStatus = NERR_Success;
-
-    RidCount = *RtlSubAuthorityCountSid(SrcSid);
-    if (RidCount >= 8)
-        return ERROR_INVALID_PARAMETER;
+    PWSTR OutString;
+    ULONG Size;
+    NET_API_STATUS Status;
 
-    DstSidSize = RtlLengthRequiredSid(RidCount + 1);
+    Size = (wcslen(InString) + 1) * sizeof(WCHAR);
+    Status = NetApiBufferAllocate(Size,
+                                  (PVOID*)&OutString);
+    if (Status != NERR_Success)
+        return NULL;
 
-    ApiStatus = NetApiBufferAllocate(DstSidSize,
-                                     &DstSid);
-    if (ApiStatus != NERR_Success)
-        return ApiStatus;
+    wcscpy(OutString, InString);
+
+    return OutString;
+}
 
-    RtlInitializeSid(DstSid,
-                     RtlIdentifierAuthoritySid(SrcSid),
-                     RidCount + 1);
 
-    for (i = 0; i < (ULONG)RidCount; i++)
+NET_API_STATUS
+WINAPI
+NetpNtStatusToApiStatus(
+    _In_ NTSTATUS Status)
+{
+    NET_API_STATUS ApiStatus;
+
+    switch (Status)
     {
-        p = RtlSubAuthoritySid(SrcSid, i);
-        q = RtlSubAuthoritySid(DstSid, i);
-        *q = *p;
-    }
+        case STATUS_SUCCESS:
+            ApiStatus = NERR_Success;
+            break;
 
-    q = RtlSubAuthoritySid(DstSid, (ULONG)RidCount);
-    *q = RelativeId;
+        case STATUS_INVALID_ACCOUNT_NAME:
+            ApiStatus = NERR_BadUsername;
+            break;
 
-    *DestSid = DstSid;
+        case STATUS_PASSWORD_RESTRICTION:
+            ApiStatus = NERR_PasswordTooShort;
+            break;
 
-    return NERR_Success;
+        default:
+            ApiStatus = RtlNtStatusToDosError(Status);
+            break;
+    }
+
+    return ApiStatus;
 }
 
 /* EOF */