[NETAPI32]
authorEric Kohl <eric.kohl@reactos.org>
Wed, 7 Nov 2012 18:51:38 +0000 (18:51 +0000)
committerEric Kohl <eric.kohl@reactos.org>
Wed, 7 Nov 2012 18:51:38 +0000 (18:51 +0000)
NetLocalGroupEnum: Make sure that built-in aliases are retrieved once and only one alias is enumerated upon each consecutive call. Retrieve name and comment for each alias.

svn path=/trunk/; revision=57684

reactos/dll/win32/netapi32/local_group.c

index ab37ee2..a02d1cc 100644 (file)
@@ -49,8 +49,10 @@ typedef struct _ENUM_CONTEXT
     SAM_HANDLE AccountDomainHandle;
 
     SAM_ENUMERATE_HANDLE EnumerationContext;
-    PSAM_RID_ENUMERATION EnumBuffer;
-    ULONG EnumReturned;
+    PSAM_RID_ENUMERATION Buffer;
+    ULONG Returned;
+    ULONG Index;
+    BOOLEAN BuiltinDone;
 
 } ENUM_CONTEXT, *PENUM_CONTEXT;
 
@@ -241,9 +243,12 @@ NET_API_STATUS WINAPI NetLocalGroupEnum(
     LPDWORD totalentries,
     PDWORD_PTR resumehandle)
 {
+    PSAM_RID_ENUMERATION CurrentAlias;
     PENUM_CONTEXT EnumContext = NULL;
     PSID DomainSid = NULL;
     ULONG i;
+    SAM_HANDLE AliasHandle = NULL;
+    PALIAS_GENERAL_INFORMATION AliasInfo = NULL;
 
     NET_API_STATUS ApiStatus = NERR_Success;
     NTSTATUS Status = STATUS_SUCCESS;
@@ -267,8 +272,10 @@ NET_API_STATUS WINAPI NetLocalGroupEnum(
             goto done;
 
         EnumContext->EnumerationContext = 0;
-        EnumContext->EnumBuffer = NULL;
-        EnumContext->EnumReturned = 0;
+        EnumContext->Buffer = NULL;
+        EnumContext->Returned = 0;
+        EnumContext->Index = 0;
+        EnumContext->BuiltinDone = FALSE;
 
         Status = SamConnect(NULL,
                             &EnumContext->ServerHandle,
@@ -290,7 +297,7 @@ NET_API_STATUS WINAPI NetLocalGroupEnum(
         }
 
         Status = SamOpenDomain(EnumContext->ServerHandle,
-                               DOMAIN_LIST_ACCOUNTS,
+                               DOMAIN_LIST_ACCOUNTS | DOMAIN_LOOKUP,
                                DomainSid,
                                &EnumContext->AccountDomainHandle);
 
@@ -312,7 +319,7 @@ NET_API_STATUS WINAPI NetLocalGroupEnum(
         }
 
         Status = SamOpenDomain(EnumContext->ServerHandle,
-                               DOMAIN_LIST_ACCOUNTS,
+                               DOMAIN_LIST_ACCOUNTS | DOMAIN_LOOKUP,
                                DomainSid,
                                &EnumContext->BuiltinDomainHandle);
 
@@ -326,40 +333,96 @@ NET_API_STATUS WINAPI NetLocalGroupEnum(
         }
     }
 
+
     while (TRUE)
     {
-        Status = SamEnumerateAliasesInDomain(EnumContext->BuiltinDomainHandle,
-                                             &EnumContext->EnumerationContext,
-                                             (PVOID *)&EnumContext->EnumBuffer,
-                                             prefmaxlen,
-                                             &EnumContext->EnumReturned);
 
-        TRACE("SamEnumerateAliasesInDomain returned (Status %08lx)\n", Status);
+        if (EnumContext->Index >= EnumContext->Returned)
+        {
+            if (EnumContext->BuiltinDone == TRUE)
+            {
+                ApiStatus = NERR_Success;
+                goto done;
+            }
+
+            TRACE("Calling SamEnumerateAliasesInDomain\n");
+
+            Status = SamEnumerateAliasesInDomain(EnumContext->BuiltinDomainHandle,
+                                                 &EnumContext->EnumerationContext,
+                                                 (PVOID *)&EnumContext->Buffer,
+                                                 prefmaxlen,
+                                                 &EnumContext->Returned);
+
+            TRACE("SamEnumerateAliasesInDomain returned (Status %08lx)\n", Status);
+            if (!NT_SUCCESS(Status))
+            {
+                ERR("SamEnumerateAliasesInDomain failed (Status %08lx)\n", Status);
+                ApiStatus = NetpNtStatusToApiStatus(Status);
+                goto done;
+            }
+
+            if (Status == STATUS_MORE_ENTRIES)
+            {
+                ApiStatus = NERR_BufTooSmall;
+                goto done;
+            }
+            else
+            {
+                EnumContext->BuiltinDone = TRUE;
+            }
+        }
+
+        TRACE("EnumContext: %lu\n", EnumContext);
+        TRACE("EnumContext->Returned: %lu\n", EnumContext->Returned);
+        TRACE("EnumContext->Buffer: %p\n", EnumContext->Buffer);
+
+        /* Get a pointer to the current alias */
+        CurrentAlias = &EnumContext->Buffer[EnumContext->Index];
+
+        TRACE("RID: %lu\n", CurrentAlias->RelativeId);
 
+        Status = SamOpenAlias(EnumContext->BuiltinDomainHandle,
+                              ALIAS_READ_INFORMATION,
+                              CurrentAlias->RelativeId,
+                              &AliasHandle);
         if (!NT_SUCCESS(Status))
         {
-            ERR("SamEnumerateAliasesInDomain failed (Status %08lx)\n", Status);
+            ERR("SamOpenAlias failed (Status %08lx)\n", Status);
             ApiStatus = NetpNtStatusToApiStatus(Status);
             goto done;
         }
 
-        TRACE("EnumContext: %lu\n", EnumContext);
-        TRACE("EnumReturned: %lu\n", EnumContext->EnumReturned);
-        TRACE("EnumBuffer: %p\n", EnumContext->EnumBuffer);
+        Status = SamQueryInformationAlias(AliasHandle,
+                                          AliasGeneralInformation,
+                                          (PVOID *)&AliasInfo);
+        if (!NT_SUCCESS(Status))
+        {
+            ERR("SamQueryInformationAlias failed (Status %08lx)\n", Status);
+            ApiStatus = NetpNtStatusToApiStatus(Status);
+            goto done;
+        }
+
+        SamCloseHandle(AliasHandle);
+        AliasHandle = NULL;
+
+        TRACE("Name: %S\n", AliasInfo->Name.Buffer);
+        TRACE("Comment: %S\n", AliasInfo->AdminComment.Buffer);
 
-        for (i = 0; i < EnumContext->EnumReturned; i++)
+
+        if (AliasInfo != NULL)
         {
-            TRACE("RID: %lu\n", EnumContext->EnumBuffer[i].RelativeId);
-            TRACE("Name: %p\n", EnumContext->EnumBuffer[i].Name.Buffer);
-            TRACE("Name: %S\n", EnumContext->EnumBuffer[i].Name.Buffer);
-            if (EnumContext->EnumBuffer[i].Name.Buffer != NULL)
-            {
-                TRACE("Name: %hx\n", EnumContext->EnumBuffer[i].Name.Buffer[0]);
-            }
+            if (AliasInfo->Name.Buffer != NULL)
+                SamFreeMemory(AliasInfo->Name.Buffer);
+
+            if (AliasInfo->AdminComment.Buffer != NULL)
+                SamFreeMemory(AliasInfo->AdminComment.Buffer);
+
+            SamFreeMemory(AliasInfo);
+            AliasInfo = NULL;
         }
 
-        if (Status != STATUS_MORE_ENTRIES)
-            break;
+
+        EnumContext->Index++;
     }
 
 
@@ -377,14 +440,14 @@ done:
             if (EnumContext->ServerHandle != NULL)
                 SamCloseHandle(EnumContext->ServerHandle);
 
-            if (EnumContext->EnumBuffer != NULL)
+            if (EnumContext->Buffer != NULL)
             {
-                for (i = 0; i < EnumContext->EnumReturned; i++)
+                for (i = 0; i < EnumContext->Returned; i++)
                 {
-                    SamFreeMemory(EnumContext->EnumBuffer[i].Name.Buffer);
+                    SamFreeMemory(EnumContext->Buffer[i].Name.Buffer);
                 }
 
-                SamFreeMemory(EnumContext->EnumBuffer);
+                SamFreeMemory(EnumContext->Buffer);
             }
 
             NetApiBufferFree(EnumContext);
@@ -392,6 +455,19 @@ done:
         }
     }
 
+    if (AliasHandle != NULL)
+        SamCloseHandle(AliasHandle);
+
+    if (AliasInfo != NULL)
+    {
+        if (AliasInfo->Name.Buffer != NULL)
+            SamFreeMemory(AliasInfo->Name.Buffer);
+
+        if (AliasInfo->AdminComment.Buffer != NULL)
+            SamFreeMemory(AliasInfo->AdminComment.Buffer);
+
+        SamFreeMemory(AliasInfo);
+    }
 
     if (resumehandle != NULL)
         *resumehandle = (DWORD_PTR)EnumContext;