test_write_disk_perms.c revision 228759
1151912Sphk/*- 2151912Sphk * Copyright (c) 2003-2007 Tim Kientzle 3209440Smav * All rights reserved. 4151912Sphk * 5151912Sphk * Redistribution and use in source and binary forms, with or without 6151912Sphk * modification, are permitted provided that the following conditions 7151912Sphk * are met: 8151912Sphk * 1. Redistributions of source code must retain the above copyright 9151912Sphk * notice, this list of conditions and the following disclaimer. 10151912Sphk * 2. Redistributions in binary form must reproduce the above copyright 11151912Sphk * notice, this list of conditions and the following disclaimer in the 12151912Sphk * documentation and/or other materials provided with the distribution. 13151912Sphk * 14151912Sphk * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR 15151912Sphk * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16151912Sphk * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17151912Sphk * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 18151912Sphk * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19151912Sphk * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20151912Sphk * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21151912Sphk * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22151912Sphk * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23151912Sphk * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24151912Sphk */ 25151912Sphk#include "test.h" 26151912Sphk__FBSDID("$FreeBSD: head/lib/libarchive/test/test_write_disk_perms.c 201247 2009-12-30 05:59:21Z kientzle $"); 27151912Sphk 28151912Sphk#if ARCHIVE_VERSION_NUMBER >= 1009000 && (!defined(_WIN32) || defined(__CYGWIN__)) 29151912Sphk 30151912Sphk#define UMASK 022 31151912Sphk 32268351Smarcelstatic long _default_gid = -1; 33209371Smavstatic long _invalid_gid = -1; 34209371Smavstatic long _alt_gid = -1; 35209371Smav 36209371Smav/* 37151912Sphk * To fully test SGID restores, we need three distinct GIDs to work 38273598Srpaulo * with: 39159217Snjl * * the GID that files are created with by default (for the 40151912Sphk * current user in the current directory) 41151912Sphk * * An "alt gid" that this user can create files with 42209371Smav * * An "invalid gid" that this user is not permitted to create 43151912Sphk * files with. 44273598Srpaulo * The second fails if this user doesn't belong to at least two groups; 45151912Sphk * the third fails if the current user is root. 46209371Smav */ 47209371Smavstatic void 48209371Smavsearchgid(void) 49151912Sphk{ 50159217Snjl static int _searched = 0; 51193530Sjkim uid_t uid = getuid(); 52193530Sjkim gid_t gid = 0; 53193530Sjkim unsigned int n; 54151912Sphk struct stat st; 55175385Sjhb int fd; 56151912Sphk 57209371Smav /* If we've already looked this up, we're done. */ 58209371Smav if (_searched) 59209371Smav return; 60209371Smav _searched = 1; 61203062Savg 62240286Smav /* Create a file on disk in the current default dir. */ 63203062Savg fd = open("test_gid", O_CREAT | O_BINARY, 0664); 64213302Smav failure("Couldn't create a file for gid testing."); 65232797Smav assert(fd > 0); 66203062Savg 67151912Sphk /* See what GID it ended up with. This is our "valid" GID. */ 68151912Sphk assert(fstat(fd, &st) == 0); 69209371Smav _default_gid = st.st_gid; 70169574Stakawata 71151931Sscottl /* Find a GID for which fchown() fails. This is our "invalid" GID. */ 72151935Sscottl _invalid_gid = -1; 73151931Sscottl /* This loop stops when we wrap the gid or examine 10,000 gids. */ 74151931Sscottl for (gid = 1, n = 1; gid == n && n < 10000 ; n++, gid++) { 75209371Smav if (fchown(fd, uid, gid) != 0) { 76151912Sphk _invalid_gid = gid; 77209371Smav break; 78209371Smav } 79209371Smav } 80209371Smav 81209440Smav /* 82212533Smav * Find a GID for which fchown() succeeds, but which isn't the 83212238Smav * default. This is the "alternate" gid. 84159217Snjl */ 85209371Smav _alt_gid = -1; 86209371Smav for (gid = 0, n = 0; gid == n && n < 10000 ; n++, gid++) { 87151912Sphk /* _alt_gid must be different than _default_gid */ 88209371Smav if (gid == (gid_t)_default_gid) 89209440Smav continue; 90209371Smav if (fchown(fd, uid, gid) == 0) { 91209371Smav _alt_gid = gid; 92209371Smav break; 93209371Smav } 94209371Smav } 95209371Smav close(fd); 96209371Smav} 97209371Smav 98212323Smavstatic int 99212323Smavaltgid(void) 100209371Smav{ 101209371Smav searchgid(); 102209371Smav return (_alt_gid); 103209371Smav} 104209371Smav 105209371Smavstatic int 106209371Smavinvalidgid(void) 107212491Smav{ 108209371Smav searchgid(); 109209371Smav return (_invalid_gid); 110209371Smav} 111273598Srpaulo 112273598Srpaulostatic int 113273598Srpaulodefaultgid(void) 114273598Srpaulo{ 115151912Sphk searchgid(); 116151912Sphk return (_default_gid); 117273598Srpaulo} 118273598Srpaulo#endif 119273598Srpaulo 120273598Srpaulo/* 121273598Srpaulo * Exercise permission and ownership restores. 122273598Srpaulo * In particular, try to exercise a bunch of border cases related 123273598Srpaulo * to files/dirs that already exist, SUID/SGID bits, etc. 124273598Srpaulo */ 125273598Srpaulo 126273598SrpauloDEFINE_TEST(test_write_disk_perms) 127273598Srpaulo{ 128273598Srpaulo#if ARCHIVE_VERSION_NUMBER < 1009000 || (defined(_WIN32) && !defined(__CYGWIN__)) 129273598Srpaulo skipping("archive_write_disk interface"); 130159217Snjl#else 131209371Smav struct archive *a; 132151912Sphk struct archive_entry *ae; 133159217Snjl struct stat st; 134159217Snjl 135269515Sroyger assertUmask(UMASK); 136269515Sroyger 137269515Sroyger /* 138159217Snjl * Set ownership of the current directory to the group of this 139151912Sphk * process. Otherwise, the SGID tests below fail if the 140151912Sphk * /tmp directory is owned by a group to which we don't belong 141209371Smav * and we're on a system where group ownership is inherited. 142151912Sphk * (Because we're not allowed to SGID files with defaultgid().) 143151912Sphk */ 144175385Sjhb assertEqualInt(0, chown(".", getuid(), getgid())); 145151912Sphk 146151912Sphk /* Create an archive_write_disk object. */ 147175361Sjhb assert((a = archive_write_disk_new()) != NULL); 148209371Smav 149175361Sjhb /* Write a regular file to it. */ 150175361Sjhb assert((ae = archive_entry_new()) != NULL); 151175385Sjhb archive_entry_copy_pathname(ae, "file_0755"); 152175385Sjhb archive_entry_set_mode(ae, S_IFREG | 0777); 153209440Smav assert(0 == archive_write_header(a, ae)); 154209440Smav assert(0 == archive_write_finish_entry(a)); 155209440Smav archive_entry_free(ae); 156209440Smav 157185103Sjkim /* Write a regular file, then write over it. */ 158185103Sjkim /* For files, the perms should get updated. */ 159175361Sjhb assert((ae = archive_entry_new()) != NULL); 160175361Sjhb archive_entry_copy_pathname(ae, "file_overwrite_0144"); 161175361Sjhb archive_entry_set_mode(ae, S_IFREG | 0777); 162209371Smav assert(0 == archive_write_header(a, ae)); 163175361Sjhb archive_entry_free(ae); 164175361Sjhb assert(0 == archive_write_finish_entry(a)); 165175385Sjhb /* Check that file was created with different perms. */ 166175385Sjhb assert(0 == stat("file_overwrite_0144", &st)); 167185103Sjkim failure("file_overwrite_0144: st.st_mode=%o", st.st_mode); 168185103Sjkim assert((st.st_mode & 07777) != 0144); 169175361Sjhb /* Overwrite, this should change the perms. */ 170175361Sjhb assert((ae = archive_entry_new()) != NULL); 171209371Smav archive_entry_copy_pathname(ae, "file_overwrite_0144"); 172247463Smav archive_entry_set_mode(ae, S_IFREG | 0144); 173209371Smav assert(0 == archive_write_header(a, ae)); 174209371Smav archive_entry_free(ae); 175209371Smav assert(0 == archive_write_finish_entry(a)); 176209371Smav 177212491Smav /* Write a regular dir. */ 178209371Smav assert((ae = archive_entry_new()) != NULL); 179209371Smav archive_entry_copy_pathname(ae, "dir_0514"); 180247463Smav archive_entry_set_mode(ae, S_IFDIR | 0514); 181209371Smav assert(0 == archive_write_header(a, ae)); 182247463Smav archive_entry_free(ae); 183209371Smav assert(0 == archive_write_finish_entry(a)); 184209371Smav 185209371Smav /* Overwrite an existing dir. */ 186209371Smav /* For dir, the first perms should get left. */ 187247463Smav assertMakeDir("dir_overwrite_0744", 0744); 188247463Smav /* Check original perms. */ 189247463Smav assert(0 == stat("dir_overwrite_0744", &st)); 190210290Smav failure("dir_overwrite_0744: st.st_mode=%o", st.st_mode); 191212238Smav assert((st.st_mode & 0777) == 0744); 192212238Smav /* Overwrite shouldn't edit perms. */ 193212238Smav assert((ae = archive_entry_new()) != NULL); 194212491Smav archive_entry_copy_pathname(ae, "dir_overwrite_0744"); 195212238Smav archive_entry_set_mode(ae, S_IFDIR | 0777); 196212491Smav assert(0 == archive_write_header(a, ae)); 197209371Smav archive_entry_free(ae); 198209371Smav assert(0 == archive_write_finish_entry(a)); 199209371Smav /* Make sure they're unchanged. */ 200209371Smav assert(0 == stat("dir_overwrite_0744", &st)); 201212491Smav failure("dir_overwrite_0744: st.st_mode=%o", st.st_mode); 202212491Smav assert((st.st_mode & 0777) == 0744); 203212491Smav 204212491Smav /* Write a regular file with SUID bit, but don't use _EXTRACT_PERM. */ 205209371Smav assert((ae = archive_entry_new()) != NULL); 206212238Smav archive_entry_copy_pathname(ae, "file_no_suid"); 207212491Smav archive_entry_set_mode(ae, S_IFREG | S_ISUID | 0777); 208212491Smav archive_write_disk_set_options(a, 0); 209212491Smav assert(0 == archive_write_header(a, ae)); 210212491Smav assert(0 == archive_write_finish_entry(a)); 211209371Smav 212224919Smav /* Write a regular file with ARCHIVE_EXTRACT_PERM. */ 213224919Smav assert(archive_entry_clear(ae) != NULL); 214224919Smav archive_entry_copy_pathname(ae, "file_0777"); 215224919Smav archive_entry_set_mode(ae, S_IFREG | 0777); 216212238Smav archive_write_disk_set_options(a, ARCHIVE_EXTRACT_PERM); 217209371Smav assert(0 == archive_write_header(a, ae)); 218209371Smav assert(0 == archive_write_finish_entry(a)); 219209371Smav 220209371Smav /* Write a regular file with ARCHIVE_EXTRACT_PERM & SUID bit */ 221209371Smav assert(archive_entry_clear(ae) != NULL); 222209371Smav archive_entry_copy_pathname(ae, "file_4742"); 223209371Smav archive_entry_set_mode(ae, S_IFREG | S_ISUID | 0742); 224209371Smav archive_entry_set_uid(ae, getuid()); 225209371Smav archive_write_disk_set_options(a, ARCHIVE_EXTRACT_PERM); 226209371Smav assert(0 == archive_write_header(a, ae)); 227209371Smav assert(0 == archive_write_finish_entry(a)); 228209371Smav 229209371Smav /* 230209371Smav * Write a regular file with ARCHIVE_EXTRACT_PERM & SUID bit, 231209371Smav * but wrong uid. POSIX says you shouldn't restore SUID bit 232209371Smav * unless the UID could be restored. 233209371Smav */ 234209371Smav assert(archive_entry_clear(ae) != NULL); 235209371Smav archive_entry_copy_pathname(ae, "file_bad_suid"); 236209371Smav archive_entry_set_mode(ae, S_IFREG | S_ISUID | 0742); 237209371Smav archive_entry_set_uid(ae, getuid() + 1); 238209371Smav archive_write_disk_set_options(a, ARCHIVE_EXTRACT_PERM); 239209371Smav assertA(0 == archive_write_header(a, ae)); 240209371Smav /* 241209371Smav * Because we didn't ask for owner, the failure to 242212491Smav * restore SUID shouldn't return a failure. 243212491Smav * We check below to make sure SUID really wasn't set. 244212323Smav * See more detailed comments below. 245212323Smav */ 246212323Smav failure("Opportunistic SUID failure shouldn't return error."); 247212323Smav assertEqualInt(0, archive_write_finish_entry(a)); 248212323Smav 249212323Smav if (getuid() != 0) { 250212323Smav assert(archive_entry_clear(ae) != NULL); 251212323Smav archive_entry_copy_pathname(ae, "file_bad_suid2"); 252212323Smav archive_entry_set_mode(ae, S_IFREG | S_ISUID | 0742); 253212323Smav archive_entry_set_uid(ae, getuid() + 1); 254212323Smav archive_write_disk_set_options(a, 255212323Smav ARCHIVE_EXTRACT_PERM | ARCHIVE_EXTRACT_OWNER); 256212323Smav assertA(0 == archive_write_header(a, ae)); 257212323Smav /* Owner change should fail here. */ 258212491Smav failure("Non-opportunistic SUID failure should return error."); 259212491Smav assertEqualInt(ARCHIVE_WARN, archive_write_finish_entry(a)); 260212323Smav } 261212491Smav 262212323Smav /* Write a regular file with ARCHIVE_EXTRACT_PERM & SGID bit */ 263212323Smav assert(archive_entry_clear(ae) != NULL); 264212323Smav archive_entry_copy_pathname(ae, "file_perm_sgid"); 265209371Smav archive_entry_set_mode(ae, S_IFREG | S_ISGID | 0742); 266209371Smav archive_entry_set_gid(ae, defaultgid()); 267212491Smav archive_write_disk_set_options(a, ARCHIVE_EXTRACT_PERM); 268209371Smav assert(0 == archive_write_header(a, ae)); 269212491Smav failure("Setting SGID bit should succeed here."); 270212491Smav assertEqualIntA(a, 0, archive_write_finish_entry(a)); 271209371Smav 272212491Smav if (altgid() == -1) { 273209371Smav /* 274209371Smav * Current user must belong to at least two groups or 275209371Smav * else we can't test setting the GID to another group. 276209990Smav */ 277209990Smav skipping("Current user can't test gid restore: must belong to more than one group."); 278209371Smav } else { 279209371Smav /* 280209371Smav * Write a regular file with ARCHIVE_EXTRACT_PERM & SGID bit 281209371Smav * but without ARCHIVE_EXTRACT_OWNER. 282209371Smav */ 283209371Smav /* 284209371Smav * This is a weird case: The user has asked for permissions to 285209371Smav * be restored but not asked for ownership to be restored. As 286209371Smav * a result, the default file creation will create a file with 287209371Smav * the wrong group. There are several possible behaviors for 288209371Smav * libarchive in this scenario: 289209371Smav * = Set the SGID bit. It is wrong and a security hole to 290209371Smav * set SGID with the wrong group. Even POSIX thinks so. 291209371Smav * = Implicitly set the group. I don't like this. 292209371Smav * = drop the SGID bit and warn (the old libarchive behavior) 293209371Smav * = drop the SGID bit and don't warn (the current libarchive 294209371Smav * behavior). 295209371Smav * The current behavior sees SGID/SUID restore when you 296209371Smav * don't ask for owner restore as an "opportunistic" 297209371Smav * action. That is, libarchive should do it if it can, 298209371Smav * but if it can't, it's not an error. 299209371Smav */ 300209371Smav assert(archive_entry_clear(ae) != NULL); 301209371Smav archive_entry_copy_pathname(ae, "file_alt_sgid"); 302208436Smav archive_entry_set_mode(ae, S_IFREG | S_ISGID | 0742); 303209371Smav archive_entry_set_uid(ae, getuid()); 304208436Smav archive_entry_set_gid(ae, altgid()); 305208436Smav archive_write_disk_set_options(a, ARCHIVE_EXTRACT_PERM); 306208436Smav assert(0 == archive_write_header(a, ae)); 307208436Smav 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."); 308208438Smav assertEqualIntA(a, 0, archive_write_finish_entry(a)); 309208436Smav 310208436Smav /* 311208436Smav * As above, but add _EXTRACT_OWNER to verify that it 312208436Smav * does succeed. 313208436Smav */ 314208436Smav assert(archive_entry_clear(ae) != NULL); 315208436Smav archive_entry_copy_pathname(ae, "file_alt_sgid_owner"); 316209371Smav archive_entry_set_mode(ae, S_IFREG | S_ISGID | 0742); 317209371Smav archive_entry_set_uid(ae, getuid()); 318258164Smav archive_entry_set_gid(ae, altgid()); 319208436Smav archive_write_disk_set_options(a, 320208436Smav ARCHIVE_EXTRACT_PERM | ARCHIVE_EXTRACT_OWNER); 321208436Smav assert(0 == archive_write_header(a, ae)); 322216263Sjhb failure("Setting SGID bit should succeed here."); 323216263Sjhb assertEqualIntA(a, ARCHIVE_OK, archive_write_finish_entry(a)); 324216263Sjhb } 325216263Sjhb 326216263Sjhb /* 327216263Sjhb * Write a regular file with ARCHIVE_EXTRACT_PERM & SGID bit, 328216263Sjhb * but wrong GID. POSIX says you shouldn't restore SGID bit 329216263Sjhb * unless the GID could be restored. 330216263Sjhb */ 331216263Sjhb if (invalidgid() == -1) { 332216263Sjhb /* This test always fails for root. */ 333216263Sjhb printf("Running as root: Can't test SGID failures.\n"); 334216263Sjhb } else { 335216263Sjhb assert(archive_entry_clear(ae) != NULL); 336216263Sjhb archive_entry_copy_pathname(ae, "file_bad_sgid"); 337216263Sjhb archive_entry_set_mode(ae, S_IFREG | S_ISGID | 0742); 338216263Sjhb archive_entry_set_gid(ae, invalidgid()); 339273598Srpaulo archive_write_disk_set_options(a, ARCHIVE_EXTRACT_PERM); 340273598Srpaulo assertA(0 == archive_write_header(a, ae)); 341273598Srpaulo failure("This SGID restore should fail without an error."); 342273598Srpaulo assertEqualIntA(a, 0, archive_write_finish_entry(a)); 343273598Srpaulo 344273598Srpaulo assert(archive_entry_clear(ae) != NULL); 345273598Srpaulo archive_entry_copy_pathname(ae, "file_bad_sgid2"); 346273598Srpaulo archive_entry_set_mode(ae, S_IFREG | S_ISGID | 0742); 347273598Srpaulo archive_entry_set_gid(ae, invalidgid()); 348273598Srpaulo archive_write_disk_set_options(a, 349273598Srpaulo ARCHIVE_EXTRACT_PERM | ARCHIVE_EXTRACT_OWNER); 350273598Srpaulo assertA(0 == archive_write_header(a, ae)); 351273598Srpaulo failure("This SGID restore should fail with an error."); 352273598Srpaulo assertEqualIntA(a, ARCHIVE_WARN, archive_write_finish_entry(a)); 353273598Srpaulo } 354273598Srpaulo 355273598Srpaulo /* Set ownership should fail if we're not root. */ 356273598Srpaulo if (getuid() == 0) { 357273598Srpaulo printf("Running as root: Can't test setuid failures.\n"); 358273598Srpaulo } else { 359273598Srpaulo assert(archive_entry_clear(ae) != NULL); 360273598Srpaulo archive_entry_copy_pathname(ae, "file_bad_owner"); 361273598Srpaulo archive_entry_set_mode(ae, S_IFREG | 0744); 362273598Srpaulo archive_entry_set_uid(ae, getuid() + 1); 363273598Srpaulo archive_write_disk_set_options(a, ARCHIVE_EXTRACT_OWNER); 364273598Srpaulo assertA(0 == archive_write_header(a, ae)); 365273598Srpaulo assertEqualIntA(a,ARCHIVE_WARN,archive_write_finish_entry(a)); 366273598Srpaulo } 367273598Srpaulo 368273598Srpaulo#if ARCHIVE_VERSION_NUMBER < 2000000 369273598Srpaulo archive_write_finish(a); 370273598Srpaulo#else 371273598Srpaulo assert(0 == archive_write_finish(a)); 372273598Srpaulo#endif 373273598Srpaulo archive_entry_free(ae); 374273598Srpaulo 375273598Srpaulo /* Test the entries on disk. */ 376273598Srpaulo assert(0 == stat("file_0755", &st)); 377273598Srpaulo failure("file_0755: st.st_mode=%o", st.st_mode); 378273598Srpaulo assert((st.st_mode & 07777) == 0755); 379273598Srpaulo 380169592Snjl assert(0 == stat("file_overwrite_0144", &st)); 381172489Snjl failure("file_overwrite_0144: st.st_mode=%o", st.st_mode); 382209371Smav assert((st.st_mode & 07777) == 0144); 383169574Stakawata 384169574Stakawata assert(0 == stat("dir_0514", &st)); 385169574Stakawata failure("dir_0514: st.st_mode=%o", st.st_mode); 386169574Stakawata assert((st.st_mode & 07777) == 0514); 387258164Smav 388169574Stakawata assert(0 == stat("dir_overwrite_0744", &st)); 389172489Snjl failure("dir_overwrite_0744: st.st_mode=%o", st.st_mode); 390209371Smav assert((st.st_mode & 0777) == 0744); 391172489Snjl 392208436Smav assert(0 == stat("file_no_suid", &st)); 393208436Smav failure("file_0755: st.st_mode=%o", st.st_mode); 394208436Smav assert((st.st_mode & 07777) == 0755); 395208436Smav 396208436Smav assert(0 == stat("file_0777", &st)); 397208436Smav failure("file_0777: st.st_mode=%o", st.st_mode); 398258164Smav assert((st.st_mode & 07777) == 0777); 399208436Smav 400258164Smav /* SUID bit should get set here. */ 401258164Smav assert(0 == stat("file_4742", &st)); 402208436Smav failure("file_4742: st.st_mode=%o", st.st_mode); 403258164Smav assert((st.st_mode & 07777) == (S_ISUID | 0742)); 404258164Smav 405258164Smav /* SUID bit should NOT have been set here. */ 406258164Smav assert(0 == stat("file_bad_suid", &st)); 407258164Smav failure("file_bad_suid: st.st_mode=%o", st.st_mode); 408208436Smav assert((st.st_mode & 07777) == (0742)); 409258164Smav 410208436Smav /* Some things don't fail if you're root, so suppress this. */ 411231161Sjkim if (getuid() != 0) { 412208436Smav /* SUID bit should NOT have been set here. */ 413208436Smav assert(0 == stat("file_bad_suid2", &st)); 414208436Smav failure("file_bad_suid2: st.st_mode=%o", st.st_mode); 415208436Smav assert((st.st_mode & 07777) == (0742)); 416208436Smav } 417208436Smav 418169574Stakawata /* SGID should be set here. */ 419169574Stakawata assert(0 == stat("file_perm_sgid", &st)); 420169574Stakawata failure("file_perm_sgid: st.st_mode=%o", st.st_mode); 421151912Sphk assert((st.st_mode & 07777) == (S_ISGID | 0742)); 422209371Smav 423151912Sphk if (altgid() != -1) { 424159217Snjl /* SGID should not be set here. */ 425159217Snjl assert(0 == stat("file_alt_sgid", &st)); 426269515Sroyger failure("file_alt_sgid: st.st_mode=%o", st.st_mode); 427151912Sphk assert((st.st_mode & 07777) == (0742)); 428199016Savg 429208436Smav /* SGID should be set here. */ 430169592Snjl assert(0 == stat("file_alt_sgid_owner", &st)); 431151912Sphk failure("file_alt_sgid: st.st_mode=%o", st.st_mode); 432159217Snjl assert((st.st_mode & 07777) == (S_ISGID | 0742)); 433151912Sphk } 434151912Sphk 435151912Sphk if (invalidgid() != -1) { 436151912Sphk /* SGID should NOT be set here. */ 437209371Smav assert(0 == stat("file_bad_sgid", &st)); 438151912Sphk failure("file_bad_sgid: st.st_mode=%o", st.st_mode); 439209371Smav assert((st.st_mode & 07777) == (0742)); 440209371Smav /* SGID should NOT be set here. */ 441209371Smav assert(0 == stat("file_bad_sgid2", &st)); 442209371Smav failure("file_bad_sgid2: st.st_mode=%o", st.st_mode); 443209371Smav assert((st.st_mode & 07777) == (0742)); 444212238Smav } 445209371Smav 446151912Sphk if (getuid() != 0) { 447151912Sphk assert(0 == stat("file_bad_owner", &st)); 448151912Sphk failure("file_bad_owner: st.st_mode=%o", st.st_mode); 449151912Sphk assert((st.st_mode & 07777) == (0744)); 450151912Sphk failure("file_bad_owner: st.st_uid=%d getuid()=%d", 451151912Sphk st.st_uid, getuid()); 452151912Sphk /* The entry had getuid()+1, but because we're 453209371Smav * not root, we should not have been able to set that. */ 454209371Smav assert(st.st_uid == getuid()); 455159217Snjl } 456159217Snjl#endif 457159217Snjl} 458151912Sphk