Erich Hoover : advapi32: Support service objects in GetSecurityInfo.

Alexandre Julliard julliard at winehq.org
Fri Dec 14 14:10:00 CST 2012


Module: wine
Branch: master
Commit: 331b99cf191b39caf87db8c3902d680007317ade
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=331b99cf191b39caf87db8c3902d680007317ade

Author: Erich Hoover <ehoover at mines.edu>
Date:   Thu Dec 13 14:08:05 2012 -0700

advapi32: Support service objects in GetSecurityInfo.

---

 dlls/advapi32/advapi32_misc.h |    4 ++-
 dlls/advapi32/security.c      |   31 ++++++++++++++++++++++++-
 dlls/advapi32/service.c       |   31 ++++++++++++++++++++------
 dlls/advapi32/tests/service.c |   48 ++++++++++++++++++++++++++++++++++++++--
 4 files changed, 101 insertions(+), 13 deletions(-)

diff --git a/dlls/advapi32/advapi32_misc.h b/dlls/advapi32/advapi32_misc.h
index e4ecfbb..3e58b04 100644
--- a/dlls/advapi32/advapi32_misc.h
+++ b/dlls/advapi32/advapi32_misc.h
@@ -21,6 +21,7 @@
 #define __WINE_ADVAPI32MISC_H
 
 #include "ntsecapi.h"
+#include "winsvc.h"
 
 const char * debugstr_sid(PSID sid) DECLSPEC_HIDDEN;
 BOOL ADVAPI_IsLocalComputer(LPCWSTR ServerName) DECLSPEC_HIDDEN;
@@ -28,6 +29,7 @@ BOOL ADVAPI_GetComputerSid(PSID sid) DECLSPEC_HIDDEN;
 
 BOOL lookup_local_wellknown_name(const LSA_UNICODE_STRING*, PSID, LPDWORD, LPWSTR, LPDWORD, PSID_NAME_USE, BOOL*) DECLSPEC_HIDDEN;
 BOOL lookup_local_user_name(const LSA_UNICODE_STRING*, PSID, LPDWORD, LPWSTR, LPDWORD, PSID_NAME_USE, BOOL*) DECLSPEC_HIDDEN;
-WCHAR *SERV_dup(const char *str);
+WCHAR *SERV_dup(const char *str) DECLSPEC_HIDDEN;
+NTSTATUS SERV_QueryServiceObjectSecurity(SC_HANDLE, SECURITY_INFORMATION, PSECURITY_DESCRIPTOR, DWORD, LPDWORD) DECLSPEC_HIDDEN;
 
 #endif /* __WINE_ADVAPI32MISC_H */
diff --git a/dlls/advapi32/security.c b/dlls/advapi32/security.c
index e000854..d857591 100644
--- a/dlls/advapi32/security.c
+++ b/dlls/advapi32/security.c
@@ -3046,7 +3046,26 @@ DWORD WINAPI GetSecurityInfo(
     ULONG n1, n2;
     BOOL present, defaulted;
 
-    status = NtQuerySecurityObject(hObject, SecurityInfo, NULL, 0, &n1);
+    /* A NULL descriptor is allowed if any one of the other pointers is not NULL */
+    if (!(ppsidOwner||ppsidGroup||ppDacl||ppSacl||ppSecurityDescriptor)) return ERROR_INVALID_PARAMETER;
+
+    /* If no descriptor, we have to check that there's a pointer for the requested information */
+    if( !ppSecurityDescriptor && (
+        ((SecurityInfo & OWNER_SECURITY_INFORMATION) && !ppsidOwner)
+    ||  ((SecurityInfo & GROUP_SECURITY_INFORMATION) && !ppsidGroup)
+    ||  ((SecurityInfo & DACL_SECURITY_INFORMATION)  && !ppDacl)
+    ||  ((SecurityInfo & SACL_SECURITY_INFORMATION)  && !ppSacl)  ))
+        return ERROR_INVALID_PARAMETER;
+
+    switch (ObjectType)
+    {
+    case SE_SERVICE:
+        status = SERV_QueryServiceObjectSecurity(hObject, SecurityInfo, NULL, 0, &n1);
+        break;
+    default:
+        status = NtQuerySecurityObject(hObject, SecurityInfo, NULL, 0, &n1);
+        break;
+    }
     if (status != STATUS_BUFFER_TOO_SMALL && status != STATUS_SUCCESS)
         return RtlNtStatusToDosError(status);
 
@@ -3054,7 +3073,15 @@ DWORD WINAPI GetSecurityInfo(
     if (!sd)
         return ERROR_NOT_ENOUGH_MEMORY;
 
-    status = NtQuerySecurityObject(hObject, SecurityInfo, sd, n1, &n2);
+    switch (ObjectType)
+    {
+    case SE_SERVICE:
+        status = SERV_QueryServiceObjectSecurity(hObject, SecurityInfo, sd, n1, &n2);
+        break;
+    default:
+        status = NtQuerySecurityObject(hObject, SecurityInfo, sd, n1, &n2);
+        break;
+    }
     if (status != STATUS_SUCCESS)
     {
         LocalFree(sd);
diff --git a/dlls/advapi32/service.c b/dlls/advapi32/service.c
index 07b9e4b..fc98880 100644
--- a/dlls/advapi32/service.c
+++ b/dlls/advapi32/service.c
@@ -28,6 +28,8 @@
 #include <time.h>
 #include <assert.h>
 
+#include "ntstatus.h"
+#define WIN32_NO_STATUS
 #include "windef.h"
 #include "winbase.h"
 #include "winsvc.h"
@@ -2147,17 +2149,14 @@ BOOL WINAPI ChangeServiceConfig2W( SC_HANDLE hService, DWORD dwInfoLevel,
     return err == ERROR_SUCCESS;
 }
 
-/******************************************************************************
- * QueryServiceObjectSecurity [ADVAPI32.@]
- */
-BOOL WINAPI QueryServiceObjectSecurity(SC_HANDLE hService,
+NTSTATUS SERV_QueryServiceObjectSecurity(SC_HANDLE hService,
        SECURITY_INFORMATION dwSecurityInformation,
        PSECURITY_DESCRIPTOR lpSecurityDescriptor,
        DWORD cbBufSize, LPDWORD pcbBytesNeeded)
 {
     SECURITY_DESCRIPTOR descriptor;
+    NTSTATUS status;
     DWORD size;
-    BOOL succ;
     ACL acl;
 
     FIXME("%p %d %p %u %p - semi-stub\n", hService, dwSecurityInformation,
@@ -2172,9 +2171,27 @@ BOOL WINAPI QueryServiceObjectSecurity(SC_HANDLE hService,
     SetSecurityDescriptorDacl(&descriptor, TRUE, &acl, TRUE);
 
     size = cbBufSize;
-    succ = MakeSelfRelativeSD(&descriptor, lpSecurityDescriptor, &size);
+    status = RtlMakeSelfRelativeSD(&descriptor, lpSecurityDescriptor, &size);
     *pcbBytesNeeded = size;
-    return succ;
+    return status;
+}
+
+/******************************************************************************
+ * QueryServiceObjectSecurity [ADVAPI32.@]
+ */
+BOOL WINAPI QueryServiceObjectSecurity(SC_HANDLE hService,
+       SECURITY_INFORMATION dwSecurityInformation,
+       PSECURITY_DESCRIPTOR lpSecurityDescriptor,
+       DWORD cbBufSize, LPDWORD pcbBytesNeeded)
+{
+    NTSTATUS status = SERV_QueryServiceObjectSecurity(hService, dwSecurityInformation, lpSecurityDescriptor,
+                                                      cbBufSize, pcbBytesNeeded);
+    if (status != STATUS_SUCCESS)
+    {
+        SetLastError(RtlNtStatusToDosError(status));
+        return FALSE;
+    }
+    return TRUE;
 }
 
 /******************************************************************************
diff --git a/dlls/advapi32/tests/service.c b/dlls/advapi32/tests/service.c
index b6aff26..5fcd4cb 100644
--- a/dlls/advapi32/tests/service.c
+++ b/dlls/advapi32/tests/service.c
@@ -48,6 +48,8 @@ static BOOL (WINAPI *pQueryServiceConfig2A)(SC_HANDLE,DWORD,LPBYTE,DWORD,LPDWORD
 static BOOL (WINAPI *pQueryServiceConfig2W)(SC_HANDLE,DWORD,LPBYTE,DWORD,LPDWORD);
 static BOOL (WINAPI *pQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE,
                                             DWORD, LPDWORD);
+static BOOL (WINAPI *pQueryServiceObjectSecurity)(SC_HANDLE, SECURITY_INFORMATION,
+                                                  PSECURITY_DESCRIPTOR, DWORD, LPDWORD);
 
 static void init_function_pointers(void)
 {
@@ -60,6 +62,7 @@ static void init_function_pointers(void)
     pQueryServiceConfig2A= (void*)GetProcAddress(hadvapi32, "QueryServiceConfig2A");
     pQueryServiceConfig2W= (void*)GetProcAddress(hadvapi32, "QueryServiceConfig2W");
     pQueryServiceStatusEx= (void*)GetProcAddress(hadvapi32, "QueryServiceStatusEx");
+    pQueryServiceObjectSecurity = (void*)GetProcAddress(hadvapi32, "QueryServiceObjectSecurity");
 }
 
 static void test_open_scm(void)
@@ -1756,7 +1759,7 @@ static void test_close(void)
 static void test_sequence(void)
 {
     SC_HANDLE scm_handle, svc_handle;
-    BOOL ret;
+    BOOL ret, is_nt4;
     QUERY_SERVICE_CONFIGA *config;
     DWORD given, needed;
     static const CHAR servicename [] = "Winetest";
@@ -1780,6 +1783,9 @@ static void test_sequence(void)
         ok(scm_handle != NULL, "Could not get a handle to the manager: %d\n", GetLastError());
 
     if (!scm_handle) return;
+    svc_handle = OpenServiceA(scm_handle, NULL, GENERIC_READ);
+    is_nt4=(svc_handle == NULL && GetLastError() == ERROR_INVALID_PARAMETER);
+    CloseServiceHandle(svc_handle);
 
     /* Create a dummy service */
     SetLastError(0xdeadbeef);
@@ -1817,8 +1823,44 @@ static void test_sequence(void)
             PSID sidOwner, sidGroup;
             PACL dacl, sacl;
             PSECURITY_DESCRIPTOR pSD;
-            HRESULT retval = pGetSecurityInfo(svc_handle,SE_SERVICE,DACL_SECURITY_INFORMATION,&sidOwner,&sidGroup,&dacl,&sacl,&pSD);
-            todo_wine ok(ERROR_SUCCESS == retval, "Expected GetSecurityInfo to succeed: result %d\n",retval);
+            DWORD error, n1, n2;
+            HRESULT retval;
+            BOOL bret;
+
+            /* Test using GetSecurityInfo to obtain security information */
+            retval = pGetSecurityInfo(svc_handle, SE_SERVICE, DACL_SECURITY_INFORMATION, &sidOwner,
+                                      &sidGroup, &dacl, &sacl, &pSD);
+            LocalFree(pSD);
+            ok(retval == ERROR_SUCCESS, "Expected GetSecurityInfo to succeed: result %d\n", retval);
+            retval = pGetSecurityInfo(svc_handle, SE_SERVICE, DACL_SECURITY_INFORMATION, NULL,
+                                      NULL, NULL, NULL, &pSD);
+            LocalFree(pSD);
+            ok(retval == ERROR_SUCCESS, "Expected GetSecurityInfo to succeed: result %d\n", retval);
+            if (!is_nt4)
+            {
+                retval = pGetSecurityInfo(svc_handle, SE_SERVICE, DACL_SECURITY_INFORMATION, NULL,
+                                          NULL, &dacl, NULL, NULL);
+                ok(retval == ERROR_SUCCESS, "Expected GetSecurityInfo to succeed: result %d\n", retval);
+                SetLastError(0xdeadbeef);
+                retval = pGetSecurityInfo(svc_handle, SE_SERVICE, DACL_SECURITY_INFORMATION, NULL,
+                                          NULL, NULL, NULL, NULL);
+                error = GetLastError();
+                ok(retval == ERROR_INVALID_PARAMETER, "Expected GetSecurityInfo to fail: result %d\n", retval);
+                ok(error == 0xdeadbeef, "Unexpected last error %d\n", error);
+            }
+            else
+                win_skip("A NULL security descriptor in GetSecurityInfo results in an exception on NT4.\n");
+
+            /* Test using QueryServiceObjectSecurity to obtain security information */
+            SetLastError(0xdeadbeef);
+            bret = pQueryServiceObjectSecurity(svc_handle, DACL_SECURITY_INFORMATION, pSD, 0, &n1);
+            error = GetLastError();
+            ok(!bret, "Expected QueryServiceObjectSecurity to fail: result %d\n", bret);
+            ok(error == ERROR_INSUFFICIENT_BUFFER, "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", error);
+            pSD = LocalAlloc(0, n1);
+            bret = pQueryServiceObjectSecurity(svc_handle, DACL_SECURITY_INFORMATION, pSD, n1, &n2);
+            ok(bret, "Expected QueryServiceObjectSecurity to succeed: result %d\n", bret);
+            LocalFree(pSD);
         }
     }
 




More information about the wine-cvs mailing list