test_write_disk_perms.c revision 232153
18876Srgrimes/*- 24Srgrimes * Copyright (c) 2003-2007 Tim Kientzle 34Srgrimes * All rights reserved. 44Srgrimes * 58876Srgrimes * Redistribution and use in source and binary forms, with or without 64Srgrimes * modification, are permitted provided that the following conditions 74Srgrimes * are met: 84Srgrimes * 1. Redistributions of source code must retain the above copyright 94Srgrimes * notice, this list of conditions and the following disclaimer. 104Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 118876Srgrimes * notice, this list of conditions and the following disclaimer in the 128876Srgrimes * documentation and/or other materials provided with the distribution. 134Srgrimes * 144Srgrimes * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR 158876Srgrimes * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 164Srgrimes * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 178876Srgrimes * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 184Srgrimes * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 194Srgrimes * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 204Srgrimes * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 214Srgrimes * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 228876Srgrimes * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 234Srgrimes * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 244Srgrimes */ 254Srgrimes#include "test.h" 2617495Sjoerg__FBSDID("$FreeBSD: head/contrib/libarchive/libarchive/test/test_write_disk_perms.c 232153 2012-02-25 10:58:02Z mm $"); 274Srgrimes 28623Srgrimes#if !defined(_WIN32) || defined(__CYGWIN__) 294Srgrimes 304Srgrimes#define UMASK 022 314Srgrimes 324Srgrimesstatic long _default_gid = -1; 334Srgrimesstatic long _invalid_gid = -1; 342056Swollmanstatic long _alt_gid = -1; 3517495Sjoerg 362056Swollman/* 3712734Sbde * To fully test SGID restores, we need three distinct GIDs to work 3812734Sbde * with: 3912734Sbde * * the GID that files are created with by default (for the 402056Swollman * current user in the current directory) 412056Swollman * * An "alt gid" that this user can create files with 424Srgrimes * * An "invalid gid" that this user is not permitted to create 434Srgrimes * files with. 444Srgrimes * The second fails if this user doesn't belong to at least two groups; 454Srgrimes * the third fails if the current user is root. 464Srgrimes */ 474Srgrimesstatic void 484Srgrimessearchgid(void) 494Srgrimes{ 504Srgrimes static int _searched = 0; 514Srgrimes uid_t uid = getuid(); 5212720Sphk gid_t gid = 0; 5312720Sphk unsigned int n; 5412720Sphk struct stat st; 5512720Sphk int fd; 564Srgrimes 5717495Sjoerg /* If we've already looked this up, we're done. */ 5817495Sjoerg if (_searched) 5917495Sjoerg return; 6017495Sjoerg _searched = 1; 6117495Sjoerg 6217495Sjoerg /* Create a file on disk in the current default dir. */ 6317495Sjoerg fd = open("test_gid", O_CREAT | O_BINARY, 0664); 644Srgrimes failure("Couldn't create a file for gid testing."); 654Srgrimes assert(fd > 0); 664Srgrimes 674Srgrimes /* See what GID it ended up with. This is our "valid" GID. */ 684Srgrimes assert(fstat(fd, &st) == 0); 6912515Sphk _default_gid = st.st_gid; 7012515Sphk 7112515Sphk /* Find a GID for which fchown() fails. This is our "invalid" GID. */ 7212515Sphk _invalid_gid = -1; 7312515Sphk /* This loop stops when we wrap the gid or examine 10,000 gids. */ 7412473Sbde for (gid = 1, n = 1; gid == n && n < 10000 ; n++, gid++) { 754Srgrimes if (fchown(fd, uid, gid) != 0) { 764Srgrimes _invalid_gid = gid; 774Srgrimes break; 784Srgrimes } 794Srgrimes } 804Srgrimes 814Srgrimes /* 824Srgrimes * Find a GID for which fchown() succeeds, but which isn't the 834Srgrimes * default. This is the "alternate" gid. 844Srgrimes */ 854Srgrimes _alt_gid = -1; 864Srgrimes for (gid = 0, n = 0; gid == n && n < 10000 ; n++, gid++) { 874Srgrimes /* _alt_gid must be different than _default_gid */ 884Srgrimes if (gid == (gid_t)_default_gid) 894Srgrimes continue; 904Srgrimes if (fchown(fd, uid, gid) == 0) { 914Srgrimes _alt_gid = gid; 924Srgrimes break; 934Srgrimes } 944Srgrimes } 954Srgrimes close(fd); 964Srgrimes} 974Srgrimes 984Srgrimesstatic int 994Srgrimesaltgid(void) 1004Srgrimes{ 1014Srgrimes searchgid(); 1024Srgrimes return (_alt_gid); 1034Srgrimes} 1044Srgrimes 1054Srgrimesstatic int 1064Srgrimesinvalidgid(void) 1074Srgrimes{ 1084Srgrimes searchgid(); 1094Srgrimes return (_invalid_gid); 1104Srgrimes} 1114Srgrimes 1124Srgrimesstatic int 1134Srgrimesdefaultgid(void) 1144Srgrimes{ 1154Srgrimes searchgid(); 1164Srgrimes return (_default_gid); 1174Srgrimes} 1184Srgrimes#endif 1194Srgrimes 1204Srgrimes/* 1214Srgrimes * Exercise permission and ownership restores. 1224Srgrimes * In particular, try to exercise a bunch of border cases related 1234Srgrimes * to files/dirs that already exist, SUID/SGID bits, etc. 1244Srgrimes */ 1254Srgrimes 1264SrgrimesDEFINE_TEST(test_write_disk_perms) 1274Srgrimes{ 1284Srgrimes#if defined(_WIN32) && !defined(__CYGWIN__) 1294Srgrimes skipping("archive_write_disk interface"); 1304Srgrimes#else 1314Srgrimes struct archive *a; 1324Srgrimes struct archive_entry *ae; 1334Srgrimes struct stat st; 1344Srgrimes 1354Srgrimes assertUmask(UMASK); 1364Srgrimes 1374Srgrimes /* 1384Srgrimes * Set ownership of the current directory to the group of this 1394Srgrimes * process. Otherwise, the SGID tests below fail if the 1404Srgrimes * /tmp directory is owned by a group to which we don't belong 1414Srgrimes * and we're on a system where group ownership is inherited. 1424Srgrimes * (Because we're not allowed to SGID files with defaultgid().) 1434Srgrimes */ 1444Srgrimes assertEqualInt(0, chown(".", getuid(), getgid())); 1454Srgrimes 1464Srgrimes /* Create an archive_write_disk object. */ 1474Srgrimes assert((a = archive_write_disk_new()) != NULL); 1484Srgrimes 1494Srgrimes /* Write a regular file to it. */ 1504Srgrimes assert((ae = archive_entry_new()) != NULL); 1514Srgrimes archive_entry_copy_pathname(ae, "file_0755"); 1524Srgrimes archive_entry_set_mode(ae, S_IFREG | 0777); 1534Srgrimes assert(0 == archive_write_header(a, ae)); 1544Srgrimes assert(0 == archive_write_finish_entry(a)); 1554Srgrimes archive_entry_free(ae); 1564Srgrimes 1574Srgrimes /* Write a regular file, then write over it. */ 1584Srgrimes /* For files, the perms should get updated. */ 1594Srgrimes assert((ae = archive_entry_new()) != NULL); 1604Srgrimes archive_entry_copy_pathname(ae, "file_overwrite_0144"); 1614Srgrimes archive_entry_set_mode(ae, S_IFREG | 0777); 1624Srgrimes assert(0 == archive_write_header(a, ae)); 1634Srgrimes archive_entry_free(ae); 1644Srgrimes assert(0 == archive_write_finish_entry(a)); 1654Srgrimes /* Check that file was created with different perms. */ 1664Srgrimes assert(0 == stat("file_overwrite_0144", &st)); 1674Srgrimes failure("file_overwrite_0144: st.st_mode=%o", st.st_mode); 1684Srgrimes assert((st.st_mode & 07777) != 0144); 1694Srgrimes /* Overwrite, this should change the perms. */ 1704Srgrimes assert((ae = archive_entry_new()) != NULL); 1714Srgrimes archive_entry_copy_pathname(ae, "file_overwrite_0144"); 1724Srgrimes archive_entry_set_mode(ae, S_IFREG | 0144); 1734Srgrimes assert(0 == archive_write_header(a, ae)); 1744Srgrimes archive_entry_free(ae); 1754Srgrimes assert(0 == archive_write_finish_entry(a)); 1764Srgrimes 1774Srgrimes /* Write a regular dir. */ 1784Srgrimes assert((ae = archive_entry_new()) != NULL); 1794Srgrimes archive_entry_copy_pathname(ae, "dir_0514"); 1804Srgrimes archive_entry_set_mode(ae, S_IFDIR | 0514); 1814Srgrimes assert(0 == archive_write_header(a, ae)); 18217495Sjoerg archive_entry_free(ae); 1834Srgrimes assert(0 == archive_write_finish_entry(a)); 1844Srgrimes 1854Srgrimes /* Overwrite an existing dir. */ 1864Srgrimes /* For dir, the first perms should get left. */ 1874Srgrimes assertMakeDir("dir_overwrite_0744", 0744); 18817495Sjoerg /* Check original perms. */ 18917495Sjoerg assert(0 == stat("dir_overwrite_0744", &st)); 19017495Sjoerg failure("dir_overwrite_0744: st.st_mode=%o", st.st_mode); 19117495Sjoerg assert((st.st_mode & 0777) == 0744); 19217495Sjoerg /* Overwrite shouldn't edit perms. */ 19317495Sjoerg assert((ae = archive_entry_new()) != NULL); 19417495Sjoerg archive_entry_copy_pathname(ae, "dir_overwrite_0744"); 19517495Sjoerg archive_entry_set_mode(ae, S_IFDIR | 0777); 19617495Sjoerg assert(0 == archive_write_header(a, ae)); 19717495Sjoerg archive_entry_free(ae); 19817495Sjoerg assert(0 == archive_write_finish_entry(a)); 19917495Sjoerg /* Make sure they're unchanged. */ 20017495Sjoerg assert(0 == stat("dir_overwrite_0744", &st)); 20117495Sjoerg failure("dir_overwrite_0744: st.st_mode=%o", st.st_mode); 20217495Sjoerg assert((st.st_mode & 0777) == 0744); 20317495Sjoerg 20417495Sjoerg /* Write a regular file with SUID bit, but don't use _EXTRACT_PERM. */ 20517495Sjoerg assert((ae = archive_entry_new()) != NULL); 20617495Sjoerg archive_entry_copy_pathname(ae, "file_no_suid"); 20717495Sjoerg archive_entry_set_mode(ae, S_IFREG | S_ISUID | 0777); 20817495Sjoerg archive_write_disk_set_options(a, 0); 20917495Sjoerg assert(0 == archive_write_header(a, ae)); 21017495Sjoerg assert(0 == archive_write_finish_entry(a)); 21117495Sjoerg 21217495Sjoerg /* Write a regular file with ARCHIVE_EXTRACT_PERM. */ 21317495Sjoerg assert(archive_entry_clear(ae) != NULL); 21417495Sjoerg archive_entry_copy_pathname(ae, "file_0777"); 21517495Sjoerg archive_entry_set_mode(ae, S_IFREG | 0777); 21617495Sjoerg archive_write_disk_set_options(a, ARCHIVE_EXTRACT_PERM); 21717495Sjoerg assert(0 == archive_write_header(a, ae)); 21817495Sjoerg assert(0 == archive_write_finish_entry(a)); 21917495Sjoerg 22017495Sjoerg /* Write a regular file with ARCHIVE_EXTRACT_PERM & SUID bit */ 22117495Sjoerg assert(archive_entry_clear(ae) != NULL); 2224Srgrimes archive_entry_copy_pathname(ae, "file_4742"); 2234Srgrimes archive_entry_set_mode(ae, S_IFREG | S_ISUID | 0742); 2244Srgrimes archive_entry_set_uid(ae, getuid()); 2254Srgrimes archive_write_disk_set_options(a, ARCHIVE_EXTRACT_PERM); 2264Srgrimes assert(0 == archive_write_header(a, ae)); 2274Srgrimes assert(0 == archive_write_finish_entry(a)); 2284Srgrimes 2294Srgrimes /* 2304Srgrimes * Write a regular file with ARCHIVE_EXTRACT_PERM & SUID bit, 2314Srgrimes * but wrong uid. POSIX says you shouldn't restore SUID bit 2324Srgrimes * unless the UID could be restored. 2334Srgrimes */ 2344Srgrimes assert(archive_entry_clear(ae) != NULL); 2354Srgrimes archive_entry_copy_pathname(ae, "file_bad_suid"); 2364Srgrimes archive_entry_set_mode(ae, S_IFREG | S_ISUID | 0742); 2374Srgrimes archive_entry_set_uid(ae, getuid() + 1); 2384Srgrimes archive_write_disk_set_options(a, ARCHIVE_EXTRACT_PERM); 2394Srgrimes assertA(0 == archive_write_header(a, ae)); 2404Srgrimes /* 2414Srgrimes * Because we didn't ask for owner, the failure to 2424Srgrimes * restore SUID shouldn't return a failure. 2434Srgrimes * We check below to make sure SUID really wasn't set. 2444Srgrimes * See more detailed comments below. 2454Srgrimes */ 2464Srgrimes failure("Opportunistic SUID failure shouldn't return error."); 24712473Sbde assertEqualInt(0, archive_write_finish_entry(a)); 2482112Swollman 2492112Swollman if (getuid() != 0) { 2502112Swollman assert(archive_entry_clear(ae) != NULL); 2512112Swollman archive_entry_copy_pathname(ae, "file_bad_suid2"); 2522112Swollman archive_entry_set_mode(ae, S_IFREG | S_ISUID | 0742); 2534Srgrimes archive_entry_set_uid(ae, getuid() + 1); 2544Srgrimes archive_write_disk_set_options(a, 2554Srgrimes ARCHIVE_EXTRACT_PERM | ARCHIVE_EXTRACT_OWNER); 2564Srgrimes assertA(0 == archive_write_header(a, ae)); 25717495Sjoerg /* Owner change should fail here. */ 25817495Sjoerg failure("Non-opportunistic SUID failure should return error."); 25917495Sjoerg assertEqualInt(ARCHIVE_WARN, archive_write_finish_entry(a)); 26017495Sjoerg } 26117495Sjoerg 26217495Sjoerg /* Write a regular file with ARCHIVE_EXTRACT_PERM & SGID bit */ 26317495Sjoerg assert(archive_entry_clear(ae) != NULL); 26417495Sjoerg archive_entry_copy_pathname(ae, "file_perm_sgid"); 26517495Sjoerg archive_entry_set_mode(ae, S_IFREG | S_ISGID | 0742); 26617495Sjoerg archive_entry_set_gid(ae, defaultgid()); 26717495Sjoerg archive_write_disk_set_options(a, ARCHIVE_EXTRACT_PERM); 26817495Sjoerg assert(0 == archive_write_header(a, ae)); 26917495Sjoerg failure("Setting SGID bit should succeed here."); 27017495Sjoerg assertEqualIntA(a, 0, archive_write_finish_entry(a)); 2714Srgrimes 2724Srgrimes if (altgid() == -1) { 2734Srgrimes /* 2744Srgrimes * Current user must belong to at least two groups or 2754Srgrimes * else we can't test setting the GID to another group. 2764Srgrimes */ 2774Srgrimes skipping("Current user can't test gid restore: must belong to more than one group."); 2784Srgrimes } else { 2794Srgrimes /* 2804Srgrimes * Write a regular file with ARCHIVE_EXTRACT_PERM & SGID bit 28115680Sgpalmer * but without ARCHIVE_EXTRACT_OWNER. 28217495Sjoerg */ 2834Srgrimes /* 28417495Sjoerg * This is a weird case: The user has asked for permissions to 28517495Sjoerg * be restored but not asked for ownership to be restored. As 28617495Sjoerg * a result, the default file creation will create a file with 28717495Sjoerg * the wrong group. There are several possible behaviors for 28817495Sjoerg * libarchive in this scenario: 28917495Sjoerg * = Set the SGID bit. It is wrong and a security hole to 29017495Sjoerg * set SGID with the wrong group. Even POSIX thinks so. 29117495Sjoerg * = Implicitly set the group. I don't like this. 29217495Sjoerg * = drop the SGID bit and warn (the old libarchive behavior) 29317495Sjoerg * = drop the SGID bit and don't warn (the current libarchive 29417495Sjoerg * behavior). 29517495Sjoerg * The current behavior sees SGID/SUID restore when you 2964Srgrimes * don't ask for owner restore as an "opportunistic" 2974Srgrimes * action. That is, libarchive should do it if it can, 2984Srgrimes * but if it can't, it's not an error. 2994Srgrimes */ 3004Srgrimes assert(archive_entry_clear(ae) != NULL); 3014Srgrimes archive_entry_copy_pathname(ae, "file_alt_sgid"); 3024Srgrimes archive_entry_set_mode(ae, S_IFREG | S_ISGID | 0742); 3034Srgrimes archive_entry_set_uid(ae, getuid()); 3044Srgrimes archive_entry_set_gid(ae, altgid()); 3054Srgrimes archive_write_disk_set_options(a, ARCHIVE_EXTRACT_PERM); 3064Srgrimes assert(0 == archive_write_header(a, ae)); 3074Srgrimes failure("Setting SGID bit should fail because of group mismatch but the failure should be silent because we didn't ask for the group to be set."); 3084Srgrimes assertEqualIntA(a, 0, archive_write_finish_entry(a)); 3094Srgrimes 3104Srgrimes /* 3114Srgrimes * As above, but add _EXTRACT_OWNER to verify that it 3124Srgrimes * does succeed. 3134Srgrimes */ 3144Srgrimes assert(archive_entry_clear(ae) != NULL); 3154Srgrimes archive_entry_copy_pathname(ae, "file_alt_sgid_owner"); 3164Srgrimes archive_entry_set_mode(ae, S_IFREG | S_ISGID | 0742); 3174Srgrimes archive_entry_set_uid(ae, getuid()); 3184Srgrimes archive_entry_set_gid(ae, altgid()); 3194Srgrimes archive_write_disk_set_options(a, 3204Srgrimes ARCHIVE_EXTRACT_PERM | ARCHIVE_EXTRACT_OWNER); 3214Srgrimes assert(0 == archive_write_header(a, ae)); 3224Srgrimes failure("Setting SGID bit should succeed here."); 3234Srgrimes assertEqualIntA(a, ARCHIVE_OK, archive_write_finish_entry(a)); 3244Srgrimes } 3254Srgrimes 3264Srgrimes /* 3274Srgrimes * Write a regular file with ARCHIVE_EXTRACT_PERM & SGID bit, 328798Swollman * but wrong GID. POSIX says you shouldn't restore SGID bit 3294Srgrimes * unless the GID could be restored. 330798Swollman */ 3314Srgrimes if (invalidgid() == -1) { 3328876Srgrimes /* This test always fails for root. */ 333 printf("Running as root: Can't test SGID failures.\n"); 334 } else { 335 assert(archive_entry_clear(ae) != NULL); 336 archive_entry_copy_pathname(ae, "file_bad_sgid"); 337 archive_entry_set_mode(ae, S_IFREG | S_ISGID | 0742); 338 archive_entry_set_gid(ae, invalidgid()); 339 archive_write_disk_set_options(a, ARCHIVE_EXTRACT_PERM); 340 assertA(0 == archive_write_header(a, ae)); 341 failure("This SGID restore should fail without an error."); 342 assertEqualIntA(a, 0, archive_write_finish_entry(a)); 343 344 assert(archive_entry_clear(ae) != NULL); 345 archive_entry_copy_pathname(ae, "file_bad_sgid2"); 346 archive_entry_set_mode(ae, S_IFREG | S_ISGID | 0742); 347 archive_entry_set_gid(ae, invalidgid()); 348 archive_write_disk_set_options(a, 349 ARCHIVE_EXTRACT_PERM | ARCHIVE_EXTRACT_OWNER); 350 assertA(0 == archive_write_header(a, ae)); 351 failure("This SGID restore should fail with an error."); 352 assertEqualIntA(a, ARCHIVE_WARN, archive_write_finish_entry(a)); 353 } 354 355 /* Set ownership should fail if we're not root. */ 356 if (getuid() == 0) { 357 printf("Running as root: Can't test setuid failures.\n"); 358 } else { 359 assert(archive_entry_clear(ae) != NULL); 360 archive_entry_copy_pathname(ae, "file_bad_owner"); 361 archive_entry_set_mode(ae, S_IFREG | 0744); 362 archive_entry_set_uid(ae, getuid() + 1); 363 archive_write_disk_set_options(a, ARCHIVE_EXTRACT_OWNER); 364 assertA(0 == archive_write_header(a, ae)); 365 assertEqualIntA(a,ARCHIVE_WARN,archive_write_finish_entry(a)); 366 } 367 368 assertEqualInt(ARCHIVE_OK, archive_write_free(a)); 369 archive_entry_free(ae); 370 371 /* Test the entries on disk. */ 372 assert(0 == stat("file_0755", &st)); 373 failure("file_0755: st.st_mode=%o", st.st_mode); 374 assert((st.st_mode & 07777) == 0755); 375 376 assert(0 == stat("file_overwrite_0144", &st)); 377 failure("file_overwrite_0144: st.st_mode=%o", st.st_mode); 378 assert((st.st_mode & 07777) == 0144); 379 380 assert(0 == stat("dir_0514", &st)); 381 failure("dir_0514: st.st_mode=%o", st.st_mode); 382 assert((st.st_mode & 07777) == 0514); 383 384 assert(0 == stat("dir_overwrite_0744", &st)); 385 failure("dir_overwrite_0744: st.st_mode=%o", st.st_mode); 386 assert((st.st_mode & 0777) == 0744); 387 388 assert(0 == stat("file_no_suid", &st)); 389 failure("file_0755: st.st_mode=%o", st.st_mode); 390 assert((st.st_mode & 07777) == 0755); 391 392 assert(0 == stat("file_0777", &st)); 393 failure("file_0777: st.st_mode=%o", st.st_mode); 394 assert((st.st_mode & 07777) == 0777); 395 396 /* SUID bit should get set here. */ 397 assert(0 == stat("file_4742", &st)); 398 failure("file_4742: st.st_mode=%o", st.st_mode); 399 assert((st.st_mode & 07777) == (S_ISUID | 0742)); 400 401 /* SUID bit should NOT have been set here. */ 402 assert(0 == stat("file_bad_suid", &st)); 403 failure("file_bad_suid: st.st_mode=%o", st.st_mode); 404 assert((st.st_mode & 07777) == (0742)); 405 406 /* Some things don't fail if you're root, so suppress this. */ 407 if (getuid() != 0) { 408 /* SUID bit should NOT have been set here. */ 409 assert(0 == stat("file_bad_suid2", &st)); 410 failure("file_bad_suid2: st.st_mode=%o", st.st_mode); 411 assert((st.st_mode & 07777) == (0742)); 412 } 413 414 /* SGID should be set here. */ 415 assert(0 == stat("file_perm_sgid", &st)); 416 failure("file_perm_sgid: st.st_mode=%o", st.st_mode); 417 assert((st.st_mode & 07777) == (S_ISGID | 0742)); 418 419 if (altgid() != -1) { 420 /* SGID should not be set here. */ 421 assert(0 == stat("file_alt_sgid", &st)); 422 failure("file_alt_sgid: st.st_mode=%o", st.st_mode); 423 assert((st.st_mode & 07777) == (0742)); 424 425 /* SGID should be set here. */ 426 assert(0 == stat("file_alt_sgid_owner", &st)); 427 failure("file_alt_sgid: st.st_mode=%o", st.st_mode); 428 assert((st.st_mode & 07777) == (S_ISGID | 0742)); 429 } 430 431 if (invalidgid() != -1) { 432 /* SGID should NOT be set here. */ 433 assert(0 == stat("file_bad_sgid", &st)); 434 failure("file_bad_sgid: st.st_mode=%o", st.st_mode); 435 assert((st.st_mode & 07777) == (0742)); 436 /* SGID should NOT be set here. */ 437 assert(0 == stat("file_bad_sgid2", &st)); 438 failure("file_bad_sgid2: st.st_mode=%o", st.st_mode); 439 assert((st.st_mode & 07777) == (0742)); 440 } 441 442 if (getuid() != 0) { 443 assert(0 == stat("file_bad_owner", &st)); 444 failure("file_bad_owner: st.st_mode=%o", st.st_mode); 445 assert((st.st_mode & 07777) == (0744)); 446 failure("file_bad_owner: st.st_uid=%d getuid()=%d", 447 st.st_uid, getuid()); 448 /* The entry had getuid()+1, but because we're 449 * not root, we should not have been able to set that. */ 450 assert(st.st_uid == getuid()); 451 } 452#endif 453} 454