1 static void SetACLPrivileges();
2 
3 static bool ReadSacl=false;
4 
5 
6 
7 #ifndef SFX_MODULE
ExtractACL20(Archive & Arc,const wchar * FileName)8 void ExtractACL20(Archive &Arc,const wchar *FileName)
9 {
10   SetACLPrivileges();
11 
12   if (Arc.BrokenHeader)
13   {
14     uiMsg(UIERROR_ACLBROKEN,Arc.FileName,FileName);
15     ErrHandler.SetErrorCode(RARX_CRC);
16     return;
17   }
18 
19   if (Arc.EAHead.Method<0x31 || Arc.EAHead.Method>0x35 || Arc.EAHead.UnpVer>VER_PACK)
20   {
21     uiMsg(UIERROR_ACLUNKNOWN,Arc.FileName,FileName);
22     ErrHandler.SetErrorCode(RARX_WARNING);
23     return;
24   }
25 
26   ComprDataIO DataIO;
27   Unpack Unpack(&DataIO);
28   Unpack.Init(0x10000,false);
29 
30   Array<byte> UnpData(Arc.EAHead.UnpSize);
31   DataIO.SetUnpackToMemory(&UnpData[0],Arc.EAHead.UnpSize);
32   DataIO.SetPackedSizeToRead(Arc.EAHead.DataSize);
33   DataIO.EnableShowProgress(false);
34   DataIO.SetFiles(&Arc,NULL);
35   DataIO.UnpHash.Init(HASH_CRC32,1);
36   Unpack.SetDestSize(Arc.EAHead.UnpSize);
37   Unpack.DoUnpack(Arc.EAHead.UnpVer,false);
38 
39   if (Arc.EAHead.EACRC!=DataIO.UnpHash.GetCRC32())
40   {
41     uiMsg(UIERROR_ACLBROKEN,Arc.FileName,FileName);
42     ErrHandler.SetErrorCode(RARX_CRC);
43     return;
44   }
45 
46   SECURITY_INFORMATION  si=OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|
47                            DACL_SECURITY_INFORMATION;
48   if (ReadSacl)
49     si|=SACL_SECURITY_INFORMATION;
50   SECURITY_DESCRIPTOR *sd=(SECURITY_DESCRIPTOR *)&UnpData[0];
51 
52   int SetCode=SetFileSecurity(FileName,si,sd);
53 
54   if (!SetCode)
55   {
56     uiMsg(UIERROR_ACLSET,Arc.FileName,FileName);
57     DWORD LastError=GetLastError();
58     ErrHandler.SysErrMsg();
59     if (LastError==ERROR_ACCESS_DENIED && !IsUserAdmin())
60       uiMsg(UIERROR_NEEDADMIN);
61     ErrHandler.SetErrorCode(RARX_WARNING);
62   }
63 }
64 #endif
65 
66 
ExtractACL(Archive & Arc,const wchar * FileName)67 void ExtractACL(Archive &Arc,const wchar *FileName)
68 {
69   Array<byte> SubData;
70   if (!Arc.ReadSubData(&SubData,NULL,false))
71     return;
72 
73   SetACLPrivileges();
74 
75   SECURITY_INFORMATION si=OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|
76                           DACL_SECURITY_INFORMATION;
77   if (ReadSacl)
78     si|=SACL_SECURITY_INFORMATION;
79   SECURITY_DESCRIPTOR *sd=(SECURITY_DESCRIPTOR *)&SubData[0];
80 
81   int SetCode=SetFileSecurity(FileName,si,sd);
82   if (!SetCode)
83   {
84     wchar LongName[NM];
85     if (GetWinLongPath(FileName,LongName,ASIZE(LongName)))
86       SetCode=SetFileSecurity(LongName,si,sd);
87   }
88 
89   if (!SetCode)
90   {
91     uiMsg(UIERROR_ACLSET,Arc.FileName,FileName);
92     DWORD LastError=GetLastError();
93     ErrHandler.SysErrMsg();
94     if (LastError==ERROR_ACCESS_DENIED && !IsUserAdmin())
95       uiMsg(UIERROR_NEEDADMIN);
96     ErrHandler.SetErrorCode(RARX_WARNING);
97   }
98 }
99 
100 
SetACLPrivileges()101 void SetACLPrivileges()
102 {
103   static bool InitDone=false;
104   if (InitDone)
105     return;
106 
107   if (SetPrivilege(SE_SECURITY_NAME))
108     ReadSacl=true;
109   SetPrivilege(SE_RESTORE_NAME);
110 
111   InitDone=true;
112 }
113 
114 
SetPrivilege(LPCTSTR PrivName)115 bool SetPrivilege(LPCTSTR PrivName)
116 {
117   bool Success=false;
118 
119   HANDLE hToken;
120   if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken))
121   {
122     TOKEN_PRIVILEGES tp;
123     tp.PrivilegeCount = 1;
124     tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
125 
126     if (LookupPrivilegeValue(NULL,PrivName,&tp.Privileges[0].Luid) &&
127         AdjustTokenPrivileges(hToken, FALSE, &tp, 0, NULL, NULL) &&
128         GetLastError() == ERROR_SUCCESS)
129       Success=true;
130 
131     CloseHandle(hToken);
132   }
133 
134   return Success;
135 }
136