aboutsummaryrefslogtreecommitdiff
path: root/CPP/Windows/FileDir.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'CPP/Windows/FileDir.cpp')
-rw-r--r--CPP/Windows/FileDir.cpp102
1 files changed, 64 insertions, 38 deletions
diff --git a/CPP/Windows/FileDir.cpp b/CPP/Windows/FileDir.cpp
index ad0d8c9..bf77c15 100644
--- a/CPP/Windows/FileDir.cpp
+++ b/CPP/Windows/FileDir.cpp
@@ -34,7 +34,9 @@ using namespace NName;
34 34
35#ifndef _WIN32 35#ifndef _WIN32
36 36
37static bool FiTime_To_timespec(const CFiTime *ft, timespec &ts) 37extern
38bool FiTime_To_timespec(const CFiTime *ft, timespec &ts);
39bool FiTime_To_timespec(const CFiTime *ft, timespec &ts)
38{ 40{
39 if (ft) 41 if (ft)
40 { 42 {
@@ -51,7 +53,7 @@ static bool FiTime_To_timespec(const CFiTime *ft, timespec &ts)
51 ts.tv_sec = 0; 53 ts.tv_sec = 0;
52 ts.tv_nsec = 54 ts.tv_nsec =
53 #ifdef UTIME_OMIT 55 #ifdef UTIME_OMIT
54 UTIME_OMIT; // -2 keep old timesptamp 56 UTIME_OMIT; // -2 keep old timestamp
55 #else 57 #else
56 // UTIME_NOW; -1 // set to the current time 58 // UTIME_NOW; -1 // set to the current time
57 0; 59 0;
@@ -170,6 +172,10 @@ bool SetLinkFileTime(CFSTR path, const CFiTime *cTime, const CFiTime *aTime, con
170 172
171bool SetFileAttrib(CFSTR path, DWORD attrib) 173bool SetFileAttrib(CFSTR path, DWORD attrib)
172{ 174{
175 /* win10:
176 if (attrib == 0), it sets (FILE_ATTRIBUTE_NORMAL) attribute
177 (FILE_ATTRIBUTE_DIRECTORY and some another attributes are ignored for files).
178 */
173 #ifndef _UNICODE 179 #ifndef _UNICODE
174 if (!g_IsNT) 180 if (!g_IsNT)
175 { 181 {
@@ -1078,7 +1084,7 @@ static BOOL My_CopyFile(CFSTR oldFile, CFSTR newFile, ICopyFileProgress *progres
1078 } 1084 }
1079 // There is file IO error or process was interrupted by user. 1085 // There is file IO error or process was interrupted by user.
1080 // We close output file and delete it. 1086 // We close output file and delete it.
1081 // DeleteFileAlways doesn't change errno (if successed), but we restore errno. 1087 // DeleteFileAlways doesn't change errno (if succeed), but we restore errno.
1082 const int errno_save = errno; 1088 const int errno_save = errno;
1083 DeleteFileAlways(newFile); 1089 DeleteFileAlways(newFile);
1084 errno = errno_save; 1090 errno = errno_save;
@@ -1240,26 +1246,34 @@ bool SetLinkFileTime(CFSTR path, const CFiTime *cTime, const CFiTime *aTime, con
1240} 1246}
1241 1247
1242 1248
1243struct C_umask 1249C_umask::C_umask()
1244{ 1250{
1245 mode_t mask; 1251/*
1246 1252 For security purposes, we restrict the file (mode) attributes
1247 C_umask() 1253 using the process's file mode creation mask (umask).
1248 { 1254 System's umask is used by open(), mkdir(), and other system calls
1249 /* by security reasons we restrict attributes according 1255 that create files to modify the permissions placed on newly
1250 with process's file mode creation mask (umask) */ 1256 created files or directories.
1251 const mode_t um = umask(0); // octal :0022 is expected 1257 We use (g_umask.mask) for any function that changes the file's access
1252 mask = 0777 & (~um); // octal: 0755 is expected 1258 mode but is not affected by the system's umask.
1253 umask(um); // restore the umask 1259 We use additional mask restiction 0777 for security purposes.
1254 // printf("\n umask = 0%03o mask = 0%03o\n", um, mask); 1260 So we don't create the following mode bits for files and directories:
1255 1261 S_ISUID 04000 set-user-ID bit
1256 // mask = 0777; // debug we can disable the restriction: 1262 S_ISGID 02000 set-group-ID bit
1257 } 1263 S_ISVTX 01000 sticky bit
1258}; 1264 system's open(), mkdir() also can have similar 0777 restiction for some cases.
1265*/
1266 const mode_t um = umask(0); // um = 0022 (octal) is expected
1267 mask = ~um
1268 & 0777; // 0777 is our additional mode restruction : is secure
1269 // & 07777; // for debug : 07777 to support all mode bits : is not secure
1270 // mask = 07777; // for debug : to restore all mode bits
1271 umask(um); // restore original umask that was changed by umask(0) in code above
1272}
1259 1273
1260static C_umask g_umask; 1274C_umask g_umask;
1261 1275
1262// #define PRF(x) x; 1276// #define PRF(x) x
1263#define PRF(x) 1277#define PRF(x)
1264 1278
1265#define TRACE_SetFileAttrib(msg) \ 1279#define TRACE_SetFileAttrib(msg) \
@@ -1273,12 +1287,17 @@ int my_chown(CFSTR path, uid_t owner, gid_t group)
1273 return chown(path, owner, group); 1287 return chown(path, owner, group);
1274} 1288}
1275 1289
1290int my_chown_Link(CFSTR path, uid_t owner, gid_t group)
1291{
1292 return lchown(path, owner, group);
1293 // return fchownat(AT_FDCWD, path, owner, group, AT_SYMLINK_NOFOLLOW);
1294}
1295
1276bool SetFileAttrib_PosixHighDetect(CFSTR path, DWORD attrib) 1296bool SetFileAttrib_PosixHighDetect(CFSTR path, DWORD attrib)
1277{ 1297{
1278 TRACE_SetFileAttrib("") 1298 TRACE_SetFileAttrib("")
1279 1299 mode_t mode;
1280 struct stat st; 1300 struct stat st;
1281
1282 bool use_lstat = true; 1301 bool use_lstat = true;
1283 if (use_lstat) 1302 if (use_lstat)
1284 { 1303 {
@@ -1297,20 +1316,26 @@ bool SetFileAttrib_PosixHighDetect(CFSTR path, DWORD attrib)
1297 return false; 1316 return false;
1298 } 1317 }
1299 } 1318 }
1300 1319 mode = st.st_mode;
1320
1301 if (attrib & FILE_ATTRIBUTE_UNIX_EXTENSION) 1321 if (attrib & FILE_ATTRIBUTE_UNIX_EXTENSION)
1302 { 1322 {
1303 TRACE_SetFileAttrib("attrib & FILE_ATTRIBUTE_UNIX_EXTENSION") 1323 TRACE_SetFileAttrib("attrib & FILE_ATTRIBUTE_UNIX_EXTENSION")
1304 st.st_mode = attrib >> 16; 1324 mode = attrib >> 16;
1305 if (S_ISDIR(st.st_mode)) 1325 if (S_ISDIR(mode))
1306 { 1326 {
1327 if (!S_ISDIR(st.st_mode))
1328 return true;
1307 // user/7z must be able to create files in this directory 1329 // user/7z must be able to create files in this directory
1308 st.st_mode |= (S_IRUSR | S_IWUSR | S_IXUSR); 1330 mode |= (S_IRUSR | S_IWUSR | S_IXUSR);
1331 }
1332 else
1333 {
1334 if (!S_ISREG(mode) || !S_ISREG(st.st_mode))
1335 return true;
1309 } 1336 }
1310 else if (!S_ISREG(st.st_mode))
1311 return true;
1312 } 1337 }
1313 else if (S_ISLNK(st.st_mode)) 1338 else if (S_ISLNK(mode))
1314 { 1339 {
1315 /* for most systems: permissions for symlinks are fixed to rwxrwxrwx. 1340 /* for most systems: permissions for symlinks are fixed to rwxrwxrwx.
1316 so we don't need chmod() for symlinks. */ 1341 so we don't need chmod() for symlinks. */
@@ -1322,27 +1347,28 @@ bool SetFileAttrib_PosixHighDetect(CFSTR path, DWORD attrib)
1322 { 1347 {
1323 TRACE_SetFileAttrib("Only Windows Attributes") 1348 TRACE_SetFileAttrib("Only Windows Attributes")
1324 // Only Windows Attributes 1349 // Only Windows Attributes
1325 if (S_ISDIR(st.st_mode) 1350 if (S_ISDIR(mode)
1326 || (attrib & FILE_ATTRIBUTE_READONLY) == 0) 1351 || (attrib & FILE_ATTRIBUTE_READONLY) == 0)
1327 return true; 1352 return true;
1328 st.st_mode &= ~(mode_t)(S_IWUSR | S_IWGRP | S_IWOTH); // octal: ~0222; // disable write permissions 1353 mode &= ~(mode_t)(S_IWUSR | S_IWGRP | S_IWOTH); // octal: ~0222; // disable write permissions
1329 } 1354 }
1330 1355
1331 int res; 1356 int res;
1357 mode &= g_umask.mask;
1332 /* 1358 /*
1333 if (S_ISLNK(st.st_mode)) 1359 if (S_ISLNK(mode))
1334 { 1360 {
1335 printf("\nfchmodat()\n"); 1361 printf("\nfchmodat()\n");
1336 TRACE_chmod(path, (st.st_mode) & g_umask.mask) 1362 TRACE_chmod(path, (mode))
1337 // AT_SYMLINK_NOFOLLOW is not implemted still in Linux. 1363 // AT_SYMLINK_NOFOLLOW is not implemented still in Linux.
1338 res = fchmodat(AT_FDCWD, path, (st.st_mode) & g_umask.mask, 1364 res = fchmodat(AT_FDCWD, path, (mode),
1339 S_ISLNK(st.st_mode) ? AT_SYMLINK_NOFOLLOW : 0); 1365 S_ISLNK(mode) ? AT_SYMLINK_NOFOLLOW : 0);
1340 } 1366 }
1341 else 1367 else
1342 */ 1368 */
1343 { 1369 {
1344 TRACE_chmod(path, (st.st_mode) & g_umask.mask) 1370 TRACE_chmod(path, mode)
1345 res = chmod(path, (st.st_mode) & g_umask.mask); 1371 res = chmod(path, mode);
1346 } 1372 }
1347 // TRACE_SetFileAttrib("End") 1373 // TRACE_SetFileAttrib("End")
1348 return (res == 0); 1374 return (res == 0);