advapi32: Implement GetSecurityInfo. [take 2]

Dan Hipschman dsh at linux.ucla.edu
Tue Aug 5 18:21:09 CDT 2008


New since last send:
- Add a doc comment.
- Use LocalAlloc instead of HeapAlloc.
- Use GetSecurityDescriptorFoo instead of "=" since the "pointers" may be relative.
- Add some tests.

---
 dlls/advapi32/security.c       |   57 ++++++++++++++++++++++++++++++++++++++-
 dlls/advapi32/tests/security.c |   32 ++++++++++++++++++++++
 2 files changed, 87 insertions(+), 2 deletions(-)

diff --git a/dlls/advapi32/security.c b/dlls/advapi32/security.c
index 95b7a7b..4c2119f 100644
--- a/dlls/advapi32/security.c
+++ b/dlls/advapi32/security.c
@@ -19,6 +19,7 @@
  *
  */
 
+#include <assert.h>
 #include <stdarg.h>
 #include <string.h>
 
@@ -2710,6 +2711,22 @@ BOOL WINAPI PrivilegedServiceAuditAlarmW( LPCWSTR SubsystemName, LPCWSTR Service
 
 /******************************************************************************
  * GetSecurityInfo [ADVAPI32.@]
+ *
+ * Retrieves a copy of the security descriptor associated with an object.
+ *
+ * PARAMS
+ *  hObject              [I] A handle for the object.
+ *  ObjectType           [I] The type of object.
+ *  SecurityInfo         [I] A bitmask indicating what info to retrieve.
+ *  ppsidOwner           [O] If non-null, receives a pointer to the owner SID.
+ *  ppsidGroup           [O] If non-null, receives a pointer to the group SID.
+ *  ppDacl               [O] If non-null, receives a pointer to the DACL.
+ *  ppSacl               [O] If non-null, receives a pointer to the SACL.
+ *  ppSecurityDescriptor [O] Receives a pointer to the security descriptor,
+ *                           which must be freed with LocalFree.
+ *
+ * RETURNS
+ *  ERROR_SUCCESS if all's well, and a WIN32 error code otherwise.
  */
 DWORD WINAPI GetSecurityInfo(
     HANDLE hObject, SE_OBJECT_TYPE ObjectType,
@@ -2718,8 +2735,44 @@ DWORD WINAPI GetSecurityInfo(
     PSECURITY_DESCRIPTOR *ppSecurityDescriptor
 )
 {
-  FIXME("stub!\n");
-  return ERROR_BAD_PROVIDER;
+    PSECURITY_DESCRIPTOR sd;
+    NTSTATUS status;
+    ULONG n1, n2;
+    BOOL present, defaulted;
+
+    status = NtQuerySecurityObject(hObject, SecurityInfo, NULL, 0, &n1);
+    assert(status != STATUS_SUCCESS);
+    if (status != STATUS_BUFFER_TOO_SMALL)
+        return RtlNtStatusToDosError(status);
+
+    sd = LocalAlloc(0, n1);
+    if (!sd)
+        return ERROR_NOT_ENOUGH_MEMORY;
+
+    status = NtQuerySecurityObject(hObject, SecurityInfo, sd, n1, &n2);
+    if (status != STATUS_SUCCESS)
+    {
+        LocalFree(sd);
+        return RtlNtStatusToDosError(status);
+    }
+
+    if (   (ppsidOwner && (SecurityInfo & OWNER_SECURITY_INFORMATION)
+            && !GetSecurityDescriptorOwner(sd, ppsidOwner, &defaulted))
+        || (ppsidGroup && (SecurityInfo & GROUP_SECURITY_INFORMATION)
+            && !GetSecurityDescriptorGroup(sd, ppsidGroup, &defaulted))
+        || (ppDacl && (SecurityInfo & DACL_SECURITY_INFORMATION)
+            && !GetSecurityDescriptorDacl(sd, &present, ppDacl, &defaulted))
+        || (ppSacl && (SecurityInfo & SACL_SECURITY_INFORMATION)
+            && !GetSecurityDescriptorSacl(sd, &present, ppSacl, &defaulted)))
+    {
+        LocalFree(sd);
+        return GetLastError();
+    }
+
+    if (ppSecurityDescriptor)
+        *ppSecurityDescriptor = sd;
+
+    return ERROR_SUCCESS;
 }
 
 /******************************************************************************
diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c
index ea4d912..9eab933 100644
--- a/dlls/advapi32/tests/security.c
+++ b/dlls/advapi32/tests/security.c
@@ -2483,6 +2483,37 @@ static void test_acls(void)
     ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "InitializeAcl(-1) failed with error %d\n", GetLastError());
 }
 
+static void test_GetSecurityInfo(void)
+{
+    HANDLE obj;
+    PSECURITY_DESCRIPTOR sd;
+    PSID owner, group;
+    PACL dacl;
+    DWORD ret;
+
+    /* Create something.  Files have lots of associated security info.  */
+    obj = CreateFile(myARGV[0], GENERIC_READ, FILE_SHARE_READ, NULL,
+                     OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+    if (!obj)
+    {
+        skip("Couldn't create an object for GetSecurityInfo test\n");
+        return;
+    }
+
+    ret = GetSecurityInfo(obj, SE_FILE_OBJECT,
+                          OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
+                          &owner, &group, &dacl, NULL, &sd);
+    ok(ret == ERROR_SUCCESS, "GetSecurityInfo returned %d\n", ret);
+    ok(sd != NULL, "GetSecurityInfo\n");
+    ok(owner != NULL, "GetSecurityInfo\n");
+    ok(group != NULL, "GetSecurityInfo\n");
+    ok(dacl != NULL, "GetSecurityInfo\n");
+    ok(IsValidAcl(dacl), "GetSecurityInfo\n");
+
+    LocalFree(sd);
+    CloseHandle(obj);
+}
+
 START_TEST(security)
 {
     init();
@@ -2511,4 +2542,5 @@ START_TEST(security)
     test_ConvertSecurityDescriptorToString();
     test_PrivateObjectSecurity();
     test_acls();
+    test_GetSecurityInfo();
 }



More information about the wine-patches mailing list