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