[ADVAPI32]
[reactos.git] / reactos / dll / win32 / advapi32 / sec / lsa.c
index 80ee33b..898497c 100644 (file)
@@ -13,8 +13,9 @@
 
 #include <advapi32.h>
 
-WINE_DEFAULT_DEBUG_CHANNEL(advapi);
+#include <lsa_c.h>
 
+WINE_DEFAULT_DEBUG_CHANNEL(advapi);
 
 static
 BOOL
@@ -163,7 +164,7 @@ LsaAddPrivilegesToAccount(IN LSA_HANDLE AccountHandle,
  * @implemented
  */
 NTSTATUS
-NTAPI
+WINAPI
 LsaClearAuditLog(IN LSA_HANDLE PolicyHandle)
 {
     NTSTATUS Status;
@@ -316,10 +317,30 @@ LsaCreateTrustedDomainEx(IN LSA_HANDLE PolicyHandle,
                          IN ACCESS_MASK DesiredAccess,
                          OUT PLSA_HANDLE TrustedDomainHandle)
 {
-    FIXME("LsaCreateTrustedDomainEx(%p %p %p 0x%08lx %p) stub\n",
+    PLSAPR_TRUSTED_DOMAIN_AUTH_INFORMATION_INTERNAL EncryptedAuthInfo = NULL;
+    NTSTATUS Status;
+
+    TRACE("LsaCreateTrustedDomainEx(%p %p %p 0x%08lx %p) stub\n",
           PolicyHandle, TrustedDomainInformation, AuthenticationInformation,
           DesiredAccess, TrustedDomainHandle);
-    return STATUS_SUCCESS;
+
+    RpcTryExcept
+    {
+        /* FIXME: Encrypt AuthenticationInformation */
+
+        Status = LsarCreateTrustedDomainEx2((LSAPR_HANDLE)PolicyHandle,
+                                            (PLSAPR_TRUSTED_DOMAIN_INFORMATION_EX)TrustedDomainInformation,
+                                            EncryptedAuthInfo,
+                                            DesiredAccess,
+                                            (PLSAPR_HANDLE)TrustedDomainHandle);
+    }
+    RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+    {
+        Status = I_RpcMapWin32Status(RpcExceptionCode());
+    }
+    RpcEndExcept;
+
+    return Status;
 }
 
 
@@ -397,21 +418,19 @@ LsaEnumerateAccountRights(IN LSA_HANDLE PolicyHandle,
 
     RpcTryExcept
     {
-        Status = LsarEnmuerateAccountRights((LSAPR_HANDLE)PolicyHandle,
+        Status = LsarEnumerateAccountRights((LSAPR_HANDLE)PolicyHandle,
                                             AccountSid,
                                             &UserRightsSet);
 
-        *CountOfRights = UserRightsSet.Entries;
         *UserRights = (PUNICODE_STRING)UserRightsSet.UserRights;
+        *CountOfRights = UserRightsSet.Entries;
     }
     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
     {
         Status = I_RpcMapWin32Status(RpcExceptionCode());
 
         if (UserRightsSet.UserRights != NULL)
-        {
             MIDL_user_free(UserRightsSet.UserRights);
-        }
     }
     RpcEndExcept;
 
@@ -420,7 +439,51 @@ LsaEnumerateAccountRights(IN LSA_HANDLE PolicyHandle,
 
 
 /*
- * @unimplemented
+ * @implemented
+ */
+NTSTATUS
+WINAPI
+LsaEnumerateAccounts(IN LSA_HANDLE PolicyHandle,
+                     IN OUT PLSA_ENUMERATION_HANDLE EnumerationContext,
+                     OUT PVOID *Buffer,
+                     IN ULONG PreferedMaximumLength,
+                     OUT PULONG CountReturned)
+{
+    LSAPR_ACCOUNT_ENUM_BUFFER AccountEnumBuffer;
+    NTSTATUS Status;
+
+    TRACE("LsaEnumerateAccounts(%p %p %p %lu %p)\n",
+          PolicyHandle, EnumerationContext, Buffer,
+          PreferedMaximumLength, CountReturned);
+
+    AccountEnumBuffer.EntriesRead = 0;
+    AccountEnumBuffer.Information = NULL;
+
+    RpcTryExcept
+    {
+        Status = LsarEnumerateAccounts((LSAPR_HANDLE)PolicyHandle,
+                                       EnumerationContext,
+                                       &AccountEnumBuffer,
+                                       PreferedMaximumLength);
+
+        *Buffer = AccountEnumBuffer.Information;
+        *CountReturned = AccountEnumBuffer.EntriesRead;
+    }
+    RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+    {
+        if (AccountEnumBuffer.Information != NULL)
+            MIDL_user_free(AccountEnumBuffer.Information);
+
+        Status = I_RpcMapWin32Status(RpcExceptionCode());
+    }
+    RpcEndExcept;
+
+    return Status;
+}
+
+
+/*
+ * @implemented
  */
 NTSTATUS
 WINAPI
@@ -429,9 +492,79 @@ LsaEnumerateAccountsWithUserRight(IN LSA_HANDLE PolicyHandle,
                                   OUT PVOID *Buffer,
                                   OUT PULONG CountReturned)
 {
-    FIXME("LsaEnumerateAccountsWithUserRight(%p %p %p %p) stub\n",
+    LSAPR_ACCOUNT_ENUM_BUFFER AccountEnumBuffer;
+    NTSTATUS Status;
+
+    TRACE("LsaEnumerateAccountsWithUserRight(%p %p %p %p) stub\n",
           PolicyHandle, UserRight, Buffer, CountReturned);
-    return STATUS_NO_MORE_ENTRIES;
+
+    AccountEnumBuffer.EntriesRead = 0;
+    AccountEnumBuffer.Information = NULL;
+
+    RpcTryExcept
+    {
+        Status = LsarEnumerateAccountsWithUserRight((LSAPR_HANDLE)PolicyHandle,
+                                                    (PRPC_UNICODE_STRING)UserRight,
+                                                    &AccountEnumBuffer);
+
+        *Buffer = AccountEnumBuffer.Information;
+        *CountReturned = AccountEnumBuffer.EntriesRead;
+    }
+    RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+    {
+        if (AccountEnumBuffer.Information != NULL)
+            MIDL_user_free(AccountEnumBuffer.Information);
+
+        Status = I_RpcMapWin32Status(RpcExceptionCode());
+    }
+    RpcEndExcept;
+
+    return Status;
+}
+
+
+/*
+ * @implemented
+ */
+NTSTATUS
+WINAPI
+LsaEnumeratePrivileges(IN LSA_HANDLE PolicyHandle,
+                       IN OUT PLSA_ENUMERATION_HANDLE EnumerationContext,
+                       OUT PVOID *Buffer,
+                       IN ULONG PreferedMaximumLength,
+                       OUT PULONG CountReturned)
+{
+    LSAPR_PRIVILEGE_ENUM_BUFFER PrivilegeEnumBuffer;
+    NTSTATUS Status;
+
+    TRACE("LsaEnumeratePrivileges(%p %p %p %lu %p)\n",
+          PolicyHandle, EnumerationContext, Buffer,
+          PreferedMaximumLength, CountReturned);
+
+    PrivilegeEnumBuffer.Entries = 0;
+    PrivilegeEnumBuffer.Privileges = NULL;
+
+    RpcTryExcept
+    {
+        Status = LsarEnumeratePrivileges((LSAPR_HANDLE)PolicyHandle,
+                                         EnumerationContext,
+                                         &PrivilegeEnumBuffer,
+                                         PreferedMaximumLength);
+
+        *Buffer = PrivilegeEnumBuffer.Privileges;
+        *CountReturned = PrivilegeEnumBuffer.Entries;
+
+    }
+    RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+    {
+        if (PrivilegeEnumBuffer.Privileges != NULL)
+            MIDL_user_free(PrivilegeEnumBuffer.Privileges);
+
+        Status = I_RpcMapWin32Status(RpcExceptionCode());
+    }
+    RpcEndExcept;
+
+    return Status;
 }
 
 
@@ -478,10 +611,13 @@ LsaEnumerateTrustedDomains(IN LSA_HANDLE PolicyHandle,
           PolicyHandle, EnumerationContext, Buffer,
           PreferedMaximumLength, CountReturned);
 
-    if (CountReturned) *CountReturned = 0;
+    if (CountReturned)
+        *CountReturned = 0;
+
     return STATUS_SUCCESS;
 }
 
+
 /*
  * @unimplemented
  */
@@ -497,7 +633,9 @@ LsaEnumerateTrustedDomainsEx(IN LSA_HANDLE PolicyHandle,
           PolicyHandle, EnumerationContext, Buffer,
           PreferedMaximumLength, CountReturned);
 
-    if (CountReturned) *CountReturned = 0;
+    if (CountReturned)
+        *CountReturned = 0;
+
     return STATUS_SUCCESS;
 }
 
@@ -514,6 +652,78 @@ LsaFreeMemory(IN PVOID Buffer)
 }
 
 
+/*
+ * @implemented
+ */
+NTSTATUS
+WINAPI
+LsaGetQuotasForAccount(IN LSA_HANDLE AccountHandle,
+                       OUT PQUOTA_LIMITS QuotaLimits)
+{
+    NTSTATUS Status;
+
+    TRACE("LsaGetQuotasForAccount(%p %p)\n",
+          AccountHandle, QuotaLimits);
+
+    RpcTryExcept
+    {
+        Status = LsarGetQuotasForAccount((LSAPR_HANDLE)AccountHandle,
+                                         QuotaLimits);
+    }
+    RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+    {
+        Status = I_RpcMapWin32Status(RpcExceptionCode());
+    }
+    RpcEndExcept;
+
+    return Status;
+}
+
+
+/*
+ * @unimplemented
+ */
+NTSTATUS
+WINAPI
+LsaGetRemoteUserName(IN PLSA_UNICODE_STRING SystemName OPTIONAL,
+                     OUT PLSA_UNICODE_STRING *UserName,
+                     OUT PLSA_UNICODE_STRING *DomainName OPTIONAL)
+{
+    PRPC_UNICODE_STRING UserNameString = NULL;
+    PRPC_UNICODE_STRING DomainNameString = NULL;
+    NTSTATUS Status;
+
+    TRACE("LsaGetRemoteUserName(%s %p %p)\n",
+          SystemName ? debugstr_w(SystemName->Buffer) : "(null)",
+          UserName, DomainName);
+
+    RpcTryExcept
+    {
+        Status = LsarGetUserName((PLSAPR_SERVER_NAME)SystemName,
+                                 &UserNameString,
+                                 (DomainName != NULL) ? &DomainNameString : NULL);
+
+        *UserName = (PLSA_UNICODE_STRING)UserNameString;
+
+        if (DomainName != NULL)
+            *DomainName = (PLSA_UNICODE_STRING)DomainNameString;
+    }
+    RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+    {
+        if (UserNameString != NULL)
+            MIDL_user_free(UserNameString);
+
+        if (DomainNameString != NULL)
+            MIDL_user_free(DomainNameString);
+
+        Status = I_RpcMapWin32Status(RpcExceptionCode());
+    }
+    RpcEndExcept;
+
+    return Status;
+}
+
+
 /*
  * @implemented
  */
@@ -543,7 +753,7 @@ LsaGetSystemAccessAccount(IN LSA_HANDLE AccountHandle,
 
 
 /*
- * @unimplemented
+ * @implemented
  */
 NTSTATUS
 WINAPI
@@ -689,6 +899,22 @@ LsaLookupNames2(IN LSA_HANDLE PolicyHandle,
 }
 
 
+/*
+ * @unimplemented
+ */
+NTSTATUS
+WINAPI
+LsaLookupPrivilegeDisplayName(IN LSA_HANDLE PolicyHandle,
+                              IN PLSA_UNICODE_STRING Name,
+                              OUT PLSA_UNICODE_STRING *DisplayName,
+                              OUT PSHORT LanguageReturned)
+{
+    FIXME("LsaLookupPrivilegeDisplayName(%p %p %p %p)\n",
+          PolicyHandle, Name, DisplayName, LanguageReturned);
+    return STATUS_NOT_IMPLEMENTED;
+}
+
+
 /*
  * @implemented
  */
@@ -913,6 +1139,26 @@ LsaOpenPolicy(IN PLSA_UNICODE_STRING SystemName OPTIONAL,
 }
 
 
+/*
+ * @unimplemented
+ */
+NTSTATUS
+WINAPI
+LsaOpenPolicySce(IN PLSA_UNICODE_STRING SystemName OPTIONAL,
+                 IN PLSA_OBJECT_ATTRIBUTES ObjectAttributes,
+                 IN ACCESS_MASK DesiredAccess,
+                 OUT PLSA_HANDLE PolicyHandle)
+{
+    FIXME("LsaOpenPolicySce(%s %p 0x%08lx %p)\n",
+          SystemName ? debugstr_w(SystemName->Buffer) : "(null)",
+          ObjectAttributes, DesiredAccess, PolicyHandle);
+    return STATUS_NOT_IMPLEMENTED;
+}
+
+
+/*
+ * @implemented
+ */
 NTSTATUS
 WINAPI
 LsaOpenSecret(IN LSA_HANDLE PolicyHandle,
@@ -1011,7 +1257,7 @@ LsaOpenTrustedDomainByName(IN LSA_HANDLE PolicyHandle,
 
 
 /*
- * @unimplemented
+ * @implemented
  */
 NTSTATUS
 WINAPI
@@ -1019,14 +1265,35 @@ LsaQueryDomainInformationPolicy(IN LSA_HANDLE PolicyHandle,
                                 IN POLICY_DOMAIN_INFORMATION_CLASS InformationClass,
                                 OUT PVOID *Buffer)
 {
-    FIXME("LsaQueryDomainInformationPolicy(%p %lu %p) stub\n",
+    PLSAPR_POLICY_DOMAIN_INFORMATION PolicyInformation = NULL;
+    NTSTATUS Status;
+
+    TRACE("LsaQueryDomainInformationPolicy(%p %lu %p)\n",
           PolicyHandle, InformationClass, Buffer);
-    return STATUS_NOT_IMPLEMENTED;
+
+    RpcTryExcept
+    {
+        Status = LsarQueryDomainInformationPolicy((LSAPR_HANDLE)PolicyHandle,
+                                                  InformationClass,
+                                                  &PolicyInformation);
+
+        *Buffer = PolicyInformation;
+    }
+    RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+    {
+        if (PolicyInformation != NULL)
+            MIDL_user_free(PolicyInformation);
+
+        Status = I_RpcMapWin32Status(RpcExceptionCode());
+    }
+    RpcEndExcept;
+
+    return Status;
 }
 
 
 /*
- * @unimplemented
+ * @implemented
  */
 NTSTATUS
 WINAPI
@@ -1034,9 +1301,25 @@ LsaQueryForestTrustInformation(IN LSA_HANDLE PolicyHandle,
                                IN PLSA_UNICODE_STRING TrustedDomainName,
                                OUT PLSA_FOREST_TRUST_INFORMATION *ForestTrustInfo)
 {
-    FIXME("LsaQueryForestTrustInformation(%p %p %p) stub\n",
+    NTSTATUS Status;
+
+    TRACE("LsaQueryForestTrustInformation(%p %p %p)\n",
           PolicyHandle, TrustedDomainName, ForestTrustInfo);
-    return STATUS_NOT_IMPLEMENTED;
+
+    RpcTryExcept
+    {
+        Status = LsarQueryForestTrustInformation((LSAPR_HANDLE)PolicyHandle,
+                                                 TrustedDomainName,
+                                                 ForestTrustDomainInfo,
+                                                 ForestTrustInfo);
+    }
+    RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+    {
+        Status = I_RpcMapWin32Status(RpcExceptionCode());
+    }
+    RpcEndExcept;
+
+    return Status;
 }
 
 
@@ -1215,6 +1498,51 @@ done:
 }
 
 
+/*
+ * @implemented
+ */
+NTSTATUS
+WINAPI
+LsaQuerySecurityObject(IN LSA_HANDLE ObjectHandle,
+                       IN SECURITY_INFORMATION SecurityInformation,
+                       OUT PSECURITY_DESCRIPTOR *SecurityDescriptor)
+{
+    LSAPR_SR_SECURITY_DESCRIPTOR SdBuffer;
+    PLSAPR_SR_SECURITY_DESCRIPTOR SdPointer;
+    NTSTATUS Status;
+
+    TRACE("LsaQuerySecurityObject(%p %lx %p)\n",
+          ObjectHandle, SecurityInformation, SecurityDescriptor);
+
+    SdBuffer.Length = 0;
+    SdBuffer.SecurityDescriptor = NULL;
+
+    SdPointer = &SdBuffer;
+
+    RpcTryExcept
+    {
+        Status = LsarQuerySecurityObject((LSAPR_HANDLE)ObjectHandle,
+                                         SecurityInformation,
+                                         &SdPointer);
+        if (NT_SUCCESS(Status))
+        {
+            *SecurityDescriptor = SdBuffer.SecurityDescriptor;
+        }
+        else
+        {
+            *SecurityDescriptor = NULL;
+        }
+    }
+    RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+    {
+        Status = I_RpcMapWin32Status(RpcExceptionCode());
+    }
+    RpcEndExcept;
+
+    return Status;
+}
+
+
 /*
  * @unimplemented
  */
@@ -1255,7 +1583,7 @@ LsaQueryTrustedDomainInfoByName(IN LSA_HANDLE PolicyHandle,
         Status = LsarQueryTrustedDomainInfoByName((LSAPR_HANDLE)PolicyHandle,
                                                   (PRPC_UNICODE_STRING)TrustedDomainName,
                                                   InformationClass,
-                                                  (unsigned long *)Buffer); // Shuld be: (PLSAPR_POLICY_INFORMATION *)Buffer
+                                                  (PLSAPR_TRUSTED_DOMAIN_INFO *)Buffer);
     }
     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
     {
@@ -1267,20 +1595,6 @@ LsaQueryTrustedDomainInfoByName(IN LSA_HANDLE PolicyHandle,
 }
 
 
-/*
- * @unimplemented
- */
-NTSTATUS
-WINAPI
-LsaRegisterPolicyChangeNotification(IN POLICY_NOTIFICATION_INFORMATION_CLASS InformationClass,
-                                    IN HANDLE NotificationEventHandle)
-{
-    FIXME("LsaRegisterPolicyChangeNotification(%d %p) stub\n",
-          InformationClass, NotificationEventHandle);
-    return STATUS_UNSUCCESSFUL;
-}
-
-
 /*
  * @implemented
  */
@@ -1317,6 +1631,33 @@ LsaRemoveAccountRights(IN LSA_HANDLE PolicyHandle,
 }
 
 
+/*
+ * @implemented
+ */
+NTSTATUS
+WINAPI
+LsaRemovePrivilegesFromAccount(IN LSA_HANDLE AccountHandle,
+                               IN BOOLEAN AllPrivileges,
+                               IN PPRIVILEGE_SET Privileges OPTIONAL)
+{
+    NTSTATUS Status;
+
+    RpcTryExcept
+    {
+        Status = LsarRemovePrivilegesFromAccount((LSAPR_HANDLE)AccountHandle,
+                                                 AllPrivileges,
+                                                 (PLSAPR_PRIVILEGE_SET)Privileges);
+    }
+    RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+    {
+        Status = I_RpcMapWin32Status(RpcExceptionCode());
+    }
+    RpcEndExcept;
+
+    return Status;
+}
+
+
 /*
  * @unimplemented
  */
@@ -1333,7 +1674,7 @@ LsaRetrievePrivateData(IN LSA_HANDLE PolicyHandle,
 
 
 /*
- * @unimplemented
+ * @implemented
  */
 NTSTATUS
 WINAPI
@@ -1341,14 +1682,29 @@ LsaSetDomainInformationPolicy(IN LSA_HANDLE PolicyHandle,
                               IN POLICY_DOMAIN_INFORMATION_CLASS InformationClass,
                               IN PVOID Buffer OPTIONAL)
 {
-    FIXME("LsaSetDomainInformationPolicy(%p %d %p) stub\n",
+    NTSTATUS Status;
+
+    TRACE("LsaSetDomainInformationPolicy(%p %d %p)\n",
           PolicyHandle, InformationClass, Buffer);
-    return STATUS_UNSUCCESSFUL;
+
+    RpcTryExcept
+    {
+        Status = LsarSetDomainInformationPolicy((LSAPR_HANDLE)PolicyHandle,
+                                                InformationClass,
+                                                (PLSAPR_POLICY_DOMAIN_INFORMATION)Buffer);
+    }
+    RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+    {
+        Status = I_RpcMapWin32Status(RpcExceptionCode());
+    }
+    RpcEndExcept;
+
+    return Status;
 }
 
 
 /*
- * @unimplemented
+ * @implemented
  */
 NTSTATUS
 WINAPI
@@ -1358,9 +1714,27 @@ LsaSetForestTrustInformation(IN LSA_HANDLE PolicyHandle,
                              IN BOOL CheckOnly,
                              OUT PLSA_FOREST_TRUST_COLLISION_INFORMATION *CollisionInfo)
 {
-    FIXME("LsaSetForestTrustInformation(%p %p %p %d %p) stub\n",
+    NTSTATUS Status;
+
+    TRACE("LsaSetForestTrustInformation(%p %p %p %d %p)\n",
           PolicyHandle, TrustedDomainName, ForestTrustInfo, CheckOnly, CollisionInfo);
-    return STATUS_NOT_IMPLEMENTED;
+
+    RpcTryExcept
+    {
+        Status = LsarSetForestTrustInformation((LSAPR_HANDLE)PolicyHandle,
+                                               TrustedDomainName,
+                                               ForestTrustDomainInfo,
+                                               ForestTrustInfo,
+                                               CheckOnly,
+                                               CollisionInfo);
+    }
+    RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+    {
+        Status = I_RpcMapWin32Status(RpcExceptionCode());
+    }
+    RpcEndExcept;
+
+    return Status;
 }
 
 
@@ -1394,6 +1768,49 @@ LsaSetInformationPolicy(IN LSA_HANDLE PolicyHandle,
 }
 
 
+/*
+ * @unimplemented
+ */
+NTSTATUS
+WINAPI
+LsaSetInformationTrustedDomain(IN LSA_HANDLE TrustedDomainHandle,
+                               IN TRUSTED_INFORMATION_CLASS InformationClass,
+                               IN PVOID Buffer)
+{
+    FIXME("LsaSetInformationTrustedDomain(%p %d %p)\n",
+          TrustedDomainHandle, InformationClass, Buffer);
+    return STATUS_NOT_IMPLEMENTED;
+}
+
+
+/*
+ * @implemented
+ */
+NTSTATUS
+WINAPI
+LsaSetQuotasForAccount(IN LSA_HANDLE AccountHandle,
+                       IN PQUOTA_LIMITS QuotaLimits)
+{
+    NTSTATUS Status;
+
+    TRACE("LsaSetQuotasForAccount(%p %p)\n",
+          AccountHandle, QuotaLimits);
+
+    RpcTryExcept
+    {
+        Status = LsarSetQuotasForAccount((LSAPR_HANDLE)AccountHandle,
+                                         QuotaLimits);
+    }
+    RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+    {
+        Status = I_RpcMapWin32Status(RpcExceptionCode());
+    }
+    RpcEndExcept;
+
+    return Status;
+}
+
+
 /*
  * @implemented
  */
@@ -1468,6 +1885,60 @@ done:
 }
 
 
+/*
+ * @implemented
+ */
+NTSTATUS
+WINAPI
+LsaSetSecurityObject(IN LSA_HANDLE ObjectHandle,
+                     IN SECURITY_INFORMATION SecurityInformation,
+                     IN PSECURITY_DESCRIPTOR SecurityDescriptor)
+{
+    LSAPR_SR_SECURITY_DESCRIPTOR SdBuffer = {0, NULL};
+    ULONG SdLength = 0;
+    NTSTATUS Status;
+
+    TRACE("LsaSetSecurityObject(%p %lx %p)\n",
+          ObjectHandle, SecurityInformation, SecurityDescriptor);
+
+    Status = RtlMakeSelfRelativeSD(SecurityDescriptor,
+                                   NULL,
+                                   &SdLength);
+    if (Status != STATUS_BUFFER_TOO_SMALL)
+        return STATUS_INVALID_PARAMETER;
+
+    SdBuffer.SecurityDescriptor = MIDL_user_allocate(SdLength);
+    if (SdBuffer.SecurityDescriptor == NULL)
+        return STATUS_INSUFFICIENT_RESOURCES;
+
+    Status = RtlMakeSelfRelativeSD(SecurityDescriptor,
+                                   (PSECURITY_DESCRIPTOR)SdBuffer.SecurityDescriptor,
+                                   &SdLength);
+    if (!NT_SUCCESS(Status))
+        goto done;
+
+    SdBuffer.Length = SdLength;
+
+    RpcTryExcept
+    {
+        Status = LsarSetSecurityObject((LSAPR_HANDLE)ObjectHandle,
+                                       SecurityInformation,
+                                       &SdBuffer);
+    }
+    RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+    {
+        Status = I_RpcMapWin32Status(RpcExceptionCode());
+    }
+    RpcEndExcept;
+
+done:
+    if (SdBuffer.SecurityDescriptor != NULL)
+        MIDL_user_free(SdBuffer.SecurityDescriptor);
+
+    return Status;
+}
+
+
 /*
  * @implemented
  */
@@ -1542,18 +2013,4 @@ LsaStorePrivateData(IN LSA_HANDLE PolicyHandle,
     return STATUS_OBJECT_NAME_NOT_FOUND;
 }
 
-
-/*
- * @unimplemented
- */
-NTSTATUS
-WINAPI
-LsaUnregisterPolicyChangeNotification(IN POLICY_NOTIFICATION_INFORMATION_CLASS InformationClass,
-                                      IN HANDLE NotificationEventHandle)
-{
-    FIXME("(%d %p) stub\n",
-          InformationClass, NotificationEventHandle);
-    return STATUS_SUCCESS;
-}
-
 /* EOF */