Implement SetFileSecurityA/W.
[reactos.git] / reactos / lib / advapi32 / sec / misc.c
index 88d3c9c..7e0ce6e 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: misc.c,v 1.18 2004/05/27 14:50:17 weiden Exp $
+/* $Id: misc.c,v 1.24 2004/09/08 11:36:24 ekohl Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS system libraries
@@ -6,9 +6,7 @@
  * PURPOSE:         Miscellaneous security functions
  */
 
-#define NTOS_MODE_USER
-#include <ntos.h>
-#include <windows.h>
+#include "advapi32.h"
 #include <accctrl.h>
 
 #define NDEBUG
@@ -59,32 +57,118 @@ AreAnyAccessesGranted(DWORD GrantedAccess,
  *  The information returned is constrained by the callers access rights and
  *  privileges.
  *
- * @unimplemented
+ * @implemented
  */
 BOOL WINAPI
-GetFileSecurityA (LPCSTR lpFileName,
-                 SECURITY_INFORMATION RequestedInformation,
-                 PSECURITY_DESCRIPTOR pSecurityDescriptor,
-                 DWORD nLength,
-                 LPDWORD lpnLengthNeeded)
+GetFileSecurityA(LPCSTR lpFileName,
+                SECURITY_INFORMATION RequestedInformation,
+                PSECURITY_DESCRIPTOR pSecurityDescriptor,
+                DWORD nLength,
+                LPDWORD lpnLengthNeeded)
 {
-  DPRINT1("GetFileSecurityA: stub\n");
-  return TRUE;
+  UNICODE_STRING FileName;
+  NTSTATUS Status;
+  BOOL bResult;
+
+  Status = RtlCreateUnicodeStringFromAsciiz(&FileName,
+                                           (LPSTR)lpFileName);
+  if (!NT_SUCCESS(Status))
+    {
+      SetLastError(RtlNtStatusToDosError(Status));
+      return FALSE;
+    }
+
+  bResult = GetFileSecurityW(FileName.Buffer,
+                            RequestedInformation,
+                            pSecurityDescriptor,
+                            nLength,
+                            lpnLengthNeeded);
+
+  RtlFreeUnicodeString(&FileName);
+
+  return bResult;
 }
 
+
 /*
- * @unimplemented
+ * @implemented
  */
 BOOL WINAPI
-GetFileSecurityW (LPCWSTR lpFileName,
-                  SECURITY_INFORMATION RequestedInformation,
-                  PSECURITY_DESCRIPTOR pSecurityDescriptor,
-                  DWORD nLength, LPDWORD lpnLengthNeeded)
+GetFileSecurityW(LPCWSTR lpFileName,
+                SECURITY_INFORMATION RequestedInformation,
+                PSECURITY_DESCRIPTOR pSecurityDescriptor,
+                DWORD nLength,
+                LPDWORD lpnLengthNeeded)
 {
-  DPRINT1("GetFileSecurityW: stub\n");
+  OBJECT_ATTRIBUTES ObjectAttributes;
+  IO_STATUS_BLOCK StatusBlock;
+  UNICODE_STRING FileName;
+  ULONG AccessMask = 0;
+  HANDLE FileHandle;
+  NTSTATUS Status;
+
+  DPRINT("GetFileSecurityW() called\n");
+
+  if (RequestedInformation &
+      (OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION))
+    {
+      AccessMask |= STANDARD_RIGHTS_READ;
+    }
+
+  if (RequestedInformation & SACL_SECURITY_INFORMATION)
+    {
+      AccessMask |= ACCESS_SYSTEM_SECURITY;
+    }
+
+  if (!RtlDosPathNameToNtPathName_U((LPWSTR)lpFileName,
+                                   &FileName,
+                                   NULL,
+                                   NULL))
+    {
+      DPRINT("Invalid path\n");
+      SetLastError(ERROR_INVALID_NAME);
+      return FALSE;
+    }
+
+  InitializeObjectAttributes(&ObjectAttributes,
+                            &FileName,
+                            OBJ_CASE_INSENSITIVE,
+                            NULL,
+                            NULL);
+
+  Status = NtOpenFile(&FileHandle,
+                     AccessMask,
+                     &ObjectAttributes,
+                     &StatusBlock,
+                     FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+                     0);
+  if (!NT_SUCCESS(Status))
+    {
+      DPRINT("NtOpenFile() failed (Status %lx)\n", Status);
+      SetLastError(RtlNtStatusToDosError(Status));
+      return FALSE;
+    }
+
+  RtlFreeUnicodeString(&FileName);
+
+  Status = NtQuerySecurityObject(FileHandle,
+                                RequestedInformation,
+                                pSecurityDescriptor,
+                                nLength,
+                                lpnLengthNeeded);
+  NtClose(FileHandle);
+
+  if (!NT_SUCCESS(Status))
+    {
+      DPRINT("NtQuerySecurityObject() failed (Status %lx)\n", Status);
+      SetLastError(RtlNtStatusToDosError(Status));
+      return FALSE;
+    }
+
   return TRUE;
 }
 
+
 /*
  * @implemented
  */
@@ -112,33 +196,117 @@ GetKernelObjectSecurity(HANDLE Handle,
 
 
 /******************************************************************************
- * SetFileSecurityW [ADVAPI32.@]
+ * SetFileSecurityA [ADVAPI32.@]
  * Sets the security of a file or directory
  *
- * @unimplemented
+ * @implemented
  */
 BOOL STDCALL
-SetFileSecurityW (LPCWSTR lpFileName,
-                 SECURITY_INFORMATION RequestedInformation,
+SetFileSecurityA (LPCSTR lpFileName,
+                 SECURITY_INFORMATION SecurityInformation,
                  PSECURITY_DESCRIPTOR pSecurityDescriptor)
 {
-  DPRINT1("SetFileSecurityW : stub\n");
-  return TRUE;
+  UNICODE_STRING FileName;
+  NTSTATUS Status;
+  BOOL bResult;
+
+  Status = RtlCreateUnicodeStringFromAsciiz(&FileName,
+                                           (LPSTR)lpFileName);
+  if (!NT_SUCCESS(Status))
+    {
+      SetLastError(RtlNtStatusToDosError(Status));
+      return FALSE;
+    }
+
+  bResult = SetFileSecurityW(FileName.Buffer,
+                            SecurityInformation,
+                            pSecurityDescriptor);
+
+  RtlFreeUnicodeString(&FileName);
+
+  return bResult;
 }
 
 
 /******************************************************************************
- * SetFileSecurityA [ADVAPI32.@]
+ * SetFileSecurityW [ADVAPI32.@]
  * Sets the security of a file or directory
  *
- * @unimplemented
+ * @implemented
  */
 BOOL STDCALL
-SetFileSecurityA (LPCSTR lpFileName,
-                 SECURITY_INFORMATION RequestedInformation,
+SetFileSecurityW (LPCWSTR lpFileName,
+                 SECURITY_INFORMATION SecurityInformation,
                  PSECURITY_DESCRIPTOR pSecurityDescriptor)
 {
-  DPRINT("SetFileSecurityA : stub\n");
+  OBJECT_ATTRIBUTES ObjectAttributes;
+  IO_STATUS_BLOCK StatusBlock;
+  UNICODE_STRING FileName;
+  ULONG AccessMask = 0;
+  HANDLE FileHandle;
+  NTSTATUS Status;
+
+  DPRINT("SetFileSecurityW() called\n");
+
+  if (SecurityInformation &
+      (OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION))
+    {
+      AccessMask |= WRITE_OWNER;
+    }
+
+  if (SecurityInformation & DACL_SECURITY_INFORMATION)
+    {
+      AccessMask |= WRITE_DAC;
+    }
+
+  if (SecurityInformation & SACL_SECURITY_INFORMATION)
+    {
+      AccessMask |= ACCESS_SYSTEM_SECURITY;
+    }
+
+  if (!RtlDosPathNameToNtPathName_U((LPWSTR)lpFileName,
+                                   &FileName,
+                                   NULL,
+                                   NULL))
+    {
+      DPRINT("Invalid path\n");
+      SetLastError(ERROR_INVALID_NAME);
+      return FALSE;
+    }
+
+  InitializeObjectAttributes(&ObjectAttributes,
+                            &FileName,
+                            OBJ_CASE_INSENSITIVE,
+                            NULL,
+                            NULL);
+
+  Status = NtOpenFile(&FileHandle,
+                     AccessMask,
+                     &ObjectAttributes,
+                     &StatusBlock,
+                     FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+                     0);
+  if (!NT_SUCCESS(Status))
+    {
+      DPRINT("NtOpenFile() failed (Status %lx)\n", Status);
+      SetLastError(RtlNtStatusToDosError(Status));
+      return FALSE;
+    }
+
+  RtlFreeUnicodeString(&FileName);
+
+  Status = NtSetSecurityObject(FileHandle,
+                              SecurityInformation,
+                              pSecurityDescriptor);
+  NtClose(FileHandle);
+
+  if (!NT_SUCCESS(Status))
+    {
+      DPRINT("NtSetSecurityObject() failed (Status %lx)\n", Status);
+      SetLastError(RtlNtStatusToDosError(Status));
+      return FALSE;
+    }
+
   return TRUE;
 }
 
@@ -379,6 +547,8 @@ LookupAccountSidA (LPCSTR lpSystemName,
                   PSID_NAME_USE peUse)
 {
   DPRINT1("LookupAccountSidA is unimplemented, but returns success\n");
+  lstrcpynA(lpName, "Administrator", *cchName);
+  lstrcpynA(lpReferencedDomainName, "ReactOS", *cchReferencedDomainName);
   return TRUE;
 }
 
@@ -398,6 +568,8 @@ LookupAccountSidW (LPCWSTR lpSystemName,
                   PSID_NAME_USE peUse)
 {
   DPRINT1("LookupAccountSidW is unimplemented, but returns success\n");
+  lstrcpynW(lpName, L"Administrator", *cchName);
+  lstrcpynW(lpReferencedDomainName, L"ReactOS", *cchReferencedDomainName);
   return TRUE;
 }
 
@@ -455,11 +627,64 @@ LookupPrivilegeValueA (LPCSTR lpSystemName,
  * @unimplemented
  */
 BOOL STDCALL
-LookupPrivilegeValueW (LPCWSTR lpSystemName,
-                      LPCWSTR lpName,
-                      PLUID lpLuid)
+LookupPrivilegeValueW (LPCWSTR SystemName,
+                      LPCWSTR PrivName,
+                      PLUID Luid)
 {
-  DPRINT1("LookupPrivilegeValueW: stub\n");
+  static const WCHAR * const DefaultPrivNames[] =
+    {
+      L"SeCreateTokenPrivilege",
+      L"SeAssignPrimaryTokenPrivilege",
+      L"SeLockMemoryPrivilege",
+      L"SeIncreaseQuotaPrivilege",
+      L"SeUnsolicitedInputPrivilege",
+      L"SeMachineAccountPrivilege",
+      L"SeTcbPrivilege",
+      L"SeSecurityPrivilege",
+      L"SeTakeOwnershipPrivilege",
+      L"SeLoadDriverPrivilege",
+      L"SeSystemProfilePrivilege",
+      L"SeSystemtimePrivilege",
+      L"SeProfileSingleProcessPrivilege",
+      L"SeIncreaseBasePriorityPrivilege",
+      L"SeCreatePagefilePrivilege",
+      L"SeCreatePermanentPrivilege",
+      L"SeBackupPrivilege",
+      L"SeRestorePrivilege",
+      L"SeShutdownPrivilege",
+      L"SeDebugPrivilege",
+      L"SeAuditPrivilege",
+      L"SeSystemEnvironmentPrivilege",
+      L"SeChangeNotifyPrivilege",
+      L"SeRemoteShutdownPrivilege",
+      L"SeUndockPrivilege",
+      L"SeSyncAgentPrivilege",
+      L"SeEnableDelegationPrivilege",
+      L"SeManageVolumePrivilege",
+      L"SeImpersonatePrivilege",
+      L"SeCreateGlobalPrivilege"
+    };
+  unsigned Priv;
+
+  if (NULL != SystemName && L'\0' != *SystemName)
+    {
+      DPRINT1("LookupPrivilegeValueW: not implemented for remote system\n");
+      SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+      return FALSE;
+    }
+
+  for (Priv = 0; Priv < sizeof(DefaultPrivNames) / sizeof(DefaultPrivNames[0]); Priv++)
+    {
+      if (0 == wcscmp(PrivName, DefaultPrivNames[Priv]))
+        {
+          Luid->LowPart = Priv + 1;
+          Luid->HighPart = 0;
+          return TRUE;
+        }
+    }
+
+  DPRINT1("LookupPrivilegeValueW: no such privilege %S\n", PrivName);
+  SetLastError(ERROR_NO_SUCH_PRIVILEGE);
   return FALSE;
 }
 
@@ -611,4 +836,57 @@ SetNamedSecurityInfoA(LPSTR pObjectName,
   return ERROR_CALL_NOT_IMPLEMENTED;
 }
 
+
+/**********************************************************************
+ * GetSecurityInfo                             EXPORTED
+ *
+ * @unimplemented
+ */
+DWORD STDCALL
+GetSecurityInfo(HANDLE handle,
+                SE_OBJECT_TYPE ObjectType,
+                SECURITY_INFORMATION SecurityInfo,
+                PSID* ppsidOwner,
+                PSID* ppsidGroup,
+                PACL* ppDacl,
+                PACL* ppSacl,
+                PSECURITY_DESCRIPTOR* ppSecurityDescriptor)
+{
+  DPRINT1("GetSecurityInfo: stub\n");
+  return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+
+/**********************************************************************
+ * ImpersonateNamedPipeClient                  EXPORTED
+ *
+ * @implemented
+ */
+BOOL STDCALL
+ImpersonateNamedPipeClient(HANDLE hNamedPipe)
+{
+  IO_STATUS_BLOCK StatusBlock;
+  NTSTATUS Status;
+
+  DPRINT("ImpersonateNamedPipeClient() called\n");
+
+  Status = NtFsControlFile(hNamedPipe,
+                          NULL,
+                          NULL,
+                          NULL,
+                          &StatusBlock,
+                          FSCTL_PIPE_IMPERSONATE,
+                          NULL,
+                          0,
+                          NULL,
+                          0);
+  if (!NT_SUCCESS(Status))
+  {
+    SetLastError(RtlNtStatusToDosError(Status));
+    return FALSE;
+  }
+
+  return TRUE;
+}
+
 /* EOF */