1228753Smm/*- 2228753Smm * Copyright (c) 2003-2007 Tim Kientzle 3228753Smm * All rights reserved. 4228753Smm * 5228753Smm * Redistribution and use in source and binary forms, with or without 6228753Smm * modification, are permitted provided that the following conditions 7228753Smm * are met: 8228753Smm * 1. Redistributions of source code must retain the above copyright 9228753Smm * notice, this list of conditions and the following disclaimer. 10228753Smm * 2. Redistributions in binary form must reproduce the above copyright 11228753Smm * notice, this list of conditions and the following disclaimer in the 12228753Smm * documentation and/or other materials provided with the distribution. 13228753Smm * 14228753Smm * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR 15228753Smm * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16228753Smm * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17228753Smm * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 18228753Smm * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19228753Smm * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20228753Smm * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21228753Smm * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22228753Smm * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23228753Smm * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24228753Smm */ 25228753Smm#include "test.h" 26228763Smm__FBSDID("$FreeBSD$"); 27228753Smm 28232153Smm#if !defined(_WIN32) || defined(__CYGWIN__) 29228753Smm 30228753Smm#define UMASK 022 31228753Smm 32228753Smmstatic long _default_gid = -1; 33228753Smmstatic long _invalid_gid = -1; 34228753Smmstatic long _alt_gid = -1; 35228753Smm 36228753Smm/* 37228753Smm * To fully test SGID restores, we need three distinct GIDs to work 38228753Smm * with: 39228753Smm * * the GID that files are created with by default (for the 40228753Smm * current user in the current directory) 41228753Smm * * An "alt gid" that this user can create files with 42228753Smm * * An "invalid gid" that this user is not permitted to create 43228753Smm * files with. 44228753Smm * The second fails if this user doesn't belong to at least two groups; 45228753Smm * the third fails if the current user is root. 46228753Smm */ 47228753Smmstatic void 48228753Smmsearchgid(void) 49228753Smm{ 50228753Smm static int _searched = 0; 51228753Smm uid_t uid = getuid(); 52228753Smm gid_t gid = 0; 53228753Smm unsigned int n; 54228753Smm struct stat st; 55228753Smm int fd; 56228753Smm 57228753Smm /* If we've already looked this up, we're done. */ 58228753Smm if (_searched) 59228753Smm return; 60228753Smm _searched = 1; 61228753Smm 62228753Smm /* Create a file on disk in the current default dir. */ 63228753Smm fd = open("test_gid", O_CREAT | O_BINARY, 0664); 64228753Smm failure("Couldn't create a file for gid testing."); 65228753Smm assert(fd > 0); 66228753Smm 67228753Smm /* See what GID it ended up with. This is our "valid" GID. */ 68228753Smm assert(fstat(fd, &st) == 0); 69228753Smm _default_gid = st.st_gid; 70228753Smm 71228753Smm /* Find a GID for which fchown() fails. This is our "invalid" GID. */ 72228753Smm _invalid_gid = -1; 73228753Smm /* This loop stops when we wrap the gid or examine 10,000 gids. */ 74228753Smm for (gid = 1, n = 1; gid == n && n < 10000 ; n++, gid++) { 75228753Smm if (fchown(fd, uid, gid) != 0) { 76228753Smm _invalid_gid = gid; 77228753Smm break; 78228753Smm } 79228753Smm } 80228753Smm 81228753Smm /* 82228753Smm * Find a GID for which fchown() succeeds, but which isn't the 83228753Smm * default. This is the "alternate" gid. 84228753Smm */ 85228753Smm _alt_gid = -1; 86228753Smm for (gid = 0, n = 0; gid == n && n < 10000 ; n++, gid++) { 87228753Smm /* _alt_gid must be different than _default_gid */ 88228753Smm if (gid == (gid_t)_default_gid) 89228753Smm continue; 90228753Smm if (fchown(fd, uid, gid) == 0) { 91228753Smm _alt_gid = gid; 92228753Smm break; 93228753Smm } 94228753Smm } 95228753Smm close(fd); 96228753Smm} 97228753Smm 98228753Smmstatic int 99228753Smmaltgid(void) 100228753Smm{ 101228753Smm searchgid(); 102228753Smm return (_alt_gid); 103228753Smm} 104228753Smm 105228753Smmstatic int 106228753Smminvalidgid(void) 107228753Smm{ 108228753Smm searchgid(); 109228753Smm return (_invalid_gid); 110228753Smm} 111228753Smm 112228753Smmstatic int 113228753Smmdefaultgid(void) 114228753Smm{ 115228753Smm searchgid(); 116228753Smm return (_default_gid); 117228753Smm} 118228753Smm#endif 119228753Smm 120228753Smm/* 121228753Smm * Exercise permission and ownership restores. 122228753Smm * In particular, try to exercise a bunch of border cases related 123228753Smm * to files/dirs that already exist, SUID/SGID bits, etc. 124228753Smm */ 125228753Smm 126228753SmmDEFINE_TEST(test_write_disk_perms) 127228753Smm{ 128232153Smm#if defined(_WIN32) && !defined(__CYGWIN__) 129228753Smm skipping("archive_write_disk interface"); 130228753Smm#else 131228753Smm struct archive *a; 132228753Smm struct archive_entry *ae; 133228753Smm struct stat st; 134228753Smm 135228753Smm assertUmask(UMASK); 136228753Smm 137228753Smm /* 138228753Smm * Set ownership of the current directory to the group of this 139228753Smm * process. Otherwise, the SGID tests below fail if the 140228753Smm * /tmp directory is owned by a group to which we don't belong 141228753Smm * and we're on a system where group ownership is inherited. 142228753Smm * (Because we're not allowed to SGID files with defaultgid().) 143228753Smm */ 144228753Smm assertEqualInt(0, chown(".", getuid(), getgid())); 145228753Smm 146228753Smm /* Create an archive_write_disk object. */ 147228753Smm assert((a = archive_write_disk_new()) != NULL); 148228753Smm 149228753Smm /* Write a regular file to it. */ 150228753Smm assert((ae = archive_entry_new()) != NULL); 151228753Smm archive_entry_copy_pathname(ae, "file_0755"); 152228753Smm archive_entry_set_mode(ae, S_IFREG | 0777); 153228753Smm assert(0 == archive_write_header(a, ae)); 154228753Smm assert(0 == archive_write_finish_entry(a)); 155228753Smm archive_entry_free(ae); 156228753Smm 157228753Smm /* Write a regular file, then write over it. */ 158228753Smm /* For files, the perms should get updated. */ 159228753Smm assert((ae = archive_entry_new()) != NULL); 160228753Smm archive_entry_copy_pathname(ae, "file_overwrite_0144"); 161228753Smm archive_entry_set_mode(ae, S_IFREG | 0777); 162228753Smm assert(0 == archive_write_header(a, ae)); 163228753Smm archive_entry_free(ae); 164228753Smm assert(0 == archive_write_finish_entry(a)); 165228753Smm /* Check that file was created with different perms. */ 166228753Smm assert(0 == stat("file_overwrite_0144", &st)); 167228753Smm failure("file_overwrite_0144: st.st_mode=%o", st.st_mode); 168228753Smm assert((st.st_mode & 07777) != 0144); 169228753Smm /* Overwrite, this should change the perms. */ 170228753Smm assert((ae = archive_entry_new()) != NULL); 171228753Smm archive_entry_copy_pathname(ae, "file_overwrite_0144"); 172228753Smm archive_entry_set_mode(ae, S_IFREG | 0144); 173228753Smm assert(0 == archive_write_header(a, ae)); 174228753Smm archive_entry_free(ae); 175228753Smm assert(0 == archive_write_finish_entry(a)); 176228753Smm 177228753Smm /* Write a regular dir. */ 178228753Smm assert((ae = archive_entry_new()) != NULL); 179228753Smm archive_entry_copy_pathname(ae, "dir_0514"); 180228753Smm archive_entry_set_mode(ae, S_IFDIR | 0514); 181228753Smm assert(0 == archive_write_header(a, ae)); 182228753Smm archive_entry_free(ae); 183228753Smm assert(0 == archive_write_finish_entry(a)); 184228753Smm 185228753Smm /* Overwrite an existing dir. */ 186228753Smm /* For dir, the first perms should get left. */ 187228753Smm assertMakeDir("dir_overwrite_0744", 0744); 188228753Smm /* Check original perms. */ 189228753Smm assert(0 == stat("dir_overwrite_0744", &st)); 190228753Smm failure("dir_overwrite_0744: st.st_mode=%o", st.st_mode); 191228753Smm assert((st.st_mode & 0777) == 0744); 192228753Smm /* Overwrite shouldn't edit perms. */ 193228753Smm assert((ae = archive_entry_new()) != NULL); 194228753Smm archive_entry_copy_pathname(ae, "dir_overwrite_0744"); 195228753Smm archive_entry_set_mode(ae, S_IFDIR | 0777); 196228753Smm assert(0 == archive_write_header(a, ae)); 197228753Smm archive_entry_free(ae); 198228753Smm assert(0 == archive_write_finish_entry(a)); 199228753Smm /* Make sure they're unchanged. */ 200228753Smm assert(0 == stat("dir_overwrite_0744", &st)); 201228753Smm failure("dir_overwrite_0744: st.st_mode=%o", st.st_mode); 202228753Smm assert((st.st_mode & 0777) == 0744); 203228753Smm 204228753Smm /* Write a regular file with SUID bit, but don't use _EXTRACT_PERM. */ 205228753Smm assert((ae = archive_entry_new()) != NULL); 206228753Smm archive_entry_copy_pathname(ae, "file_no_suid"); 207228753Smm archive_entry_set_mode(ae, S_IFREG | S_ISUID | 0777); 208228753Smm archive_write_disk_set_options(a, 0); 209228753Smm assert(0 == archive_write_header(a, ae)); 210228753Smm assert(0 == archive_write_finish_entry(a)); 211228753Smm 212228753Smm /* Write a regular file with ARCHIVE_EXTRACT_PERM. */ 213228753Smm assert(archive_entry_clear(ae) != NULL); 214228753Smm archive_entry_copy_pathname(ae, "file_0777"); 215228753Smm archive_entry_set_mode(ae, S_IFREG | 0777); 216228753Smm archive_write_disk_set_options(a, ARCHIVE_EXTRACT_PERM); 217228753Smm assert(0 == archive_write_header(a, ae)); 218228753Smm assert(0 == archive_write_finish_entry(a)); 219228753Smm 220228753Smm /* Write a regular file with ARCHIVE_EXTRACT_PERM & SUID bit */ 221228753Smm assert(archive_entry_clear(ae) != NULL); 222228753Smm archive_entry_copy_pathname(ae, "file_4742"); 223228753Smm archive_entry_set_mode(ae, S_IFREG | S_ISUID | 0742); 224228753Smm archive_entry_set_uid(ae, getuid()); 225228753Smm archive_write_disk_set_options(a, ARCHIVE_EXTRACT_PERM); 226228753Smm assert(0 == archive_write_header(a, ae)); 227228753Smm assert(0 == archive_write_finish_entry(a)); 228228753Smm 229228753Smm /* 230228753Smm * Write a regular file with ARCHIVE_EXTRACT_PERM & SUID bit, 231228753Smm * but wrong uid. POSIX says you shouldn't restore SUID bit 232228753Smm * unless the UID could be restored. 233228753Smm */ 234228753Smm assert(archive_entry_clear(ae) != NULL); 235228753Smm archive_entry_copy_pathname(ae, "file_bad_suid"); 236228753Smm archive_entry_set_mode(ae, S_IFREG | S_ISUID | 0742); 237228753Smm archive_entry_set_uid(ae, getuid() + 1); 238228753Smm archive_write_disk_set_options(a, ARCHIVE_EXTRACT_PERM); 239228753Smm assertA(0 == archive_write_header(a, ae)); 240228753Smm /* 241228753Smm * Because we didn't ask for owner, the failure to 242228753Smm * restore SUID shouldn't return a failure. 243228753Smm * We check below to make sure SUID really wasn't set. 244228753Smm * See more detailed comments below. 245228753Smm */ 246228753Smm failure("Opportunistic SUID failure shouldn't return error."); 247228753Smm assertEqualInt(0, archive_write_finish_entry(a)); 248228753Smm 249228753Smm if (getuid() != 0) { 250228753Smm assert(archive_entry_clear(ae) != NULL); 251228753Smm archive_entry_copy_pathname(ae, "file_bad_suid2"); 252228753Smm archive_entry_set_mode(ae, S_IFREG | S_ISUID | 0742); 253228753Smm archive_entry_set_uid(ae, getuid() + 1); 254228753Smm archive_write_disk_set_options(a, 255228753Smm ARCHIVE_EXTRACT_PERM | ARCHIVE_EXTRACT_OWNER); 256228753Smm assertA(0 == archive_write_header(a, ae)); 257228753Smm /* Owner change should fail here. */ 258228753Smm failure("Non-opportunistic SUID failure should return error."); 259228753Smm assertEqualInt(ARCHIVE_WARN, archive_write_finish_entry(a)); 260228753Smm } 261228753Smm 262228753Smm /* Write a regular file with ARCHIVE_EXTRACT_PERM & SGID bit */ 263228753Smm assert(archive_entry_clear(ae) != NULL); 264228753Smm archive_entry_copy_pathname(ae, "file_perm_sgid"); 265228753Smm archive_entry_set_mode(ae, S_IFREG | S_ISGID | 0742); 266228753Smm archive_entry_set_gid(ae, defaultgid()); 267228753Smm archive_write_disk_set_options(a, ARCHIVE_EXTRACT_PERM); 268228753Smm assert(0 == archive_write_header(a, ae)); 269228753Smm failure("Setting SGID bit should succeed here."); 270228753Smm assertEqualIntA(a, 0, archive_write_finish_entry(a)); 271228753Smm 272228753Smm if (altgid() == -1) { 273228753Smm /* 274228753Smm * Current user must belong to at least two groups or 275228753Smm * else we can't test setting the GID to another group. 276228753Smm */ 277228753Smm skipping("Current user can't test gid restore: must belong to more than one group."); 278228753Smm } else { 279228753Smm /* 280228753Smm * Write a regular file with ARCHIVE_EXTRACT_PERM & SGID bit 281228753Smm * but without ARCHIVE_EXTRACT_OWNER. 282228753Smm */ 283228753Smm /* 284228753Smm * This is a weird case: The user has asked for permissions to 285228753Smm * be restored but not asked for ownership to be restored. As 286228753Smm * a result, the default file creation will create a file with 287228753Smm * the wrong group. There are several possible behaviors for 288228753Smm * libarchive in this scenario: 289228753Smm * = Set the SGID bit. It is wrong and a security hole to 290228753Smm * set SGID with the wrong group. Even POSIX thinks so. 291228753Smm * = Implicitly set the group. I don't like this. 292228753Smm * = drop the SGID bit and warn (the old libarchive behavior) 293228753Smm * = drop the SGID bit and don't warn (the current libarchive 294228753Smm * behavior). 295228753Smm * The current behavior sees SGID/SUID restore when you 296228753Smm * don't ask for owner restore as an "opportunistic" 297228753Smm * action. That is, libarchive should do it if it can, 298228753Smm * but if it can't, it's not an error. 299228753Smm */ 300228753Smm assert(archive_entry_clear(ae) != NULL); 301228753Smm archive_entry_copy_pathname(ae, "file_alt_sgid"); 302228753Smm archive_entry_set_mode(ae, S_IFREG | S_ISGID | 0742); 303228753Smm archive_entry_set_uid(ae, getuid()); 304228753Smm archive_entry_set_gid(ae, altgid()); 305228753Smm archive_write_disk_set_options(a, ARCHIVE_EXTRACT_PERM); 306228753Smm assert(0 == archive_write_header(a, ae)); 307228753Smm 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."); 308228753Smm assertEqualIntA(a, 0, archive_write_finish_entry(a)); 309228753Smm 310228753Smm /* 311228753Smm * As above, but add _EXTRACT_OWNER to verify that it 312228753Smm * does succeed. 313228753Smm */ 314228753Smm assert(archive_entry_clear(ae) != NULL); 315228753Smm archive_entry_copy_pathname(ae, "file_alt_sgid_owner"); 316228753Smm archive_entry_set_mode(ae, S_IFREG | S_ISGID | 0742); 317228753Smm archive_entry_set_uid(ae, getuid()); 318228753Smm archive_entry_set_gid(ae, altgid()); 319228753Smm archive_write_disk_set_options(a, 320228753Smm ARCHIVE_EXTRACT_PERM | ARCHIVE_EXTRACT_OWNER); 321228753Smm assert(0 == archive_write_header(a, ae)); 322228753Smm failure("Setting SGID bit should succeed here."); 323228753Smm assertEqualIntA(a, ARCHIVE_OK, archive_write_finish_entry(a)); 324228753Smm } 325228753Smm 326228753Smm /* 327228753Smm * Write a regular file with ARCHIVE_EXTRACT_PERM & SGID bit, 328228753Smm * but wrong GID. POSIX says you shouldn't restore SGID bit 329228753Smm * unless the GID could be restored. 330228753Smm */ 331228753Smm if (invalidgid() == -1) { 332228753Smm /* This test always fails for root. */ 333228753Smm printf("Running as root: Can't test SGID failures.\n"); 334228753Smm } else { 335228753Smm assert(archive_entry_clear(ae) != NULL); 336228753Smm archive_entry_copy_pathname(ae, "file_bad_sgid"); 337228753Smm archive_entry_set_mode(ae, S_IFREG | S_ISGID | 0742); 338228753Smm archive_entry_set_gid(ae, invalidgid()); 339228753Smm archive_write_disk_set_options(a, ARCHIVE_EXTRACT_PERM); 340228753Smm assertA(0 == archive_write_header(a, ae)); 341228753Smm failure("This SGID restore should fail without an error."); 342228753Smm assertEqualIntA(a, 0, archive_write_finish_entry(a)); 343228753Smm 344228753Smm assert(archive_entry_clear(ae) != NULL); 345228753Smm archive_entry_copy_pathname(ae, "file_bad_sgid2"); 346228753Smm archive_entry_set_mode(ae, S_IFREG | S_ISGID | 0742); 347228753Smm archive_entry_set_gid(ae, invalidgid()); 348228753Smm archive_write_disk_set_options(a, 349228753Smm ARCHIVE_EXTRACT_PERM | ARCHIVE_EXTRACT_OWNER); 350228753Smm assertA(0 == archive_write_header(a, ae)); 351228753Smm failure("This SGID restore should fail with an error."); 352228753Smm assertEqualIntA(a, ARCHIVE_WARN, archive_write_finish_entry(a)); 353228753Smm } 354228753Smm 355228753Smm /* Set ownership should fail if we're not root. */ 356228753Smm if (getuid() == 0) { 357228753Smm printf("Running as root: Can't test setuid failures.\n"); 358228753Smm } else { 359228753Smm assert(archive_entry_clear(ae) != NULL); 360228753Smm archive_entry_copy_pathname(ae, "file_bad_owner"); 361228753Smm archive_entry_set_mode(ae, S_IFREG | 0744); 362228753Smm archive_entry_set_uid(ae, getuid() + 1); 363228753Smm archive_write_disk_set_options(a, ARCHIVE_EXTRACT_OWNER); 364228753Smm assertA(0 == archive_write_header(a, ae)); 365228753Smm assertEqualIntA(a,ARCHIVE_WARN,archive_write_finish_entry(a)); 366228753Smm } 367228753Smm 368232153Smm assertEqualInt(ARCHIVE_OK, archive_write_free(a)); 369228753Smm archive_entry_free(ae); 370228753Smm 371228753Smm /* Test the entries on disk. */ 372228753Smm assert(0 == stat("file_0755", &st)); 373228753Smm failure("file_0755: st.st_mode=%o", st.st_mode); 374228753Smm assert((st.st_mode & 07777) == 0755); 375228753Smm 376228753Smm assert(0 == stat("file_overwrite_0144", &st)); 377228753Smm failure("file_overwrite_0144: st.st_mode=%o", st.st_mode); 378228753Smm assert((st.st_mode & 07777) == 0144); 379228753Smm 380228753Smm assert(0 == stat("dir_0514", &st)); 381228753Smm failure("dir_0514: st.st_mode=%o", st.st_mode); 382228753Smm assert((st.st_mode & 07777) == 0514); 383228753Smm 384228753Smm assert(0 == stat("dir_overwrite_0744", &st)); 385228753Smm failure("dir_overwrite_0744: st.st_mode=%o", st.st_mode); 386228753Smm assert((st.st_mode & 0777) == 0744); 387228753Smm 388228753Smm assert(0 == stat("file_no_suid", &st)); 389228753Smm failure("file_0755: st.st_mode=%o", st.st_mode); 390228753Smm assert((st.st_mode & 07777) == 0755); 391228753Smm 392228753Smm assert(0 == stat("file_0777", &st)); 393228753Smm failure("file_0777: st.st_mode=%o", st.st_mode); 394228753Smm assert((st.st_mode & 07777) == 0777); 395228753Smm 396228753Smm /* SUID bit should get set here. */ 397228753Smm assert(0 == stat("file_4742", &st)); 398228753Smm failure("file_4742: st.st_mode=%o", st.st_mode); 399228753Smm assert((st.st_mode & 07777) == (S_ISUID | 0742)); 400228753Smm 401228753Smm /* SUID bit should NOT have been set here. */ 402228753Smm assert(0 == stat("file_bad_suid", &st)); 403228753Smm failure("file_bad_suid: st.st_mode=%o", st.st_mode); 404228753Smm assert((st.st_mode & 07777) == (0742)); 405228753Smm 406228753Smm /* Some things don't fail if you're root, so suppress this. */ 407228753Smm if (getuid() != 0) { 408228753Smm /* SUID bit should NOT have been set here. */ 409228753Smm assert(0 == stat("file_bad_suid2", &st)); 410228753Smm failure("file_bad_suid2: st.st_mode=%o", st.st_mode); 411228753Smm assert((st.st_mode & 07777) == (0742)); 412228753Smm } 413228753Smm 414228753Smm /* SGID should be set here. */ 415228753Smm assert(0 == stat("file_perm_sgid", &st)); 416228753Smm failure("file_perm_sgid: st.st_mode=%o", st.st_mode); 417228753Smm assert((st.st_mode & 07777) == (S_ISGID | 0742)); 418228753Smm 419228753Smm if (altgid() != -1) { 420228753Smm /* SGID should not be set here. */ 421228753Smm assert(0 == stat("file_alt_sgid", &st)); 422228753Smm failure("file_alt_sgid: st.st_mode=%o", st.st_mode); 423228753Smm assert((st.st_mode & 07777) == (0742)); 424228753Smm 425228753Smm /* SGID should be set here. */ 426228753Smm assert(0 == stat("file_alt_sgid_owner", &st)); 427228753Smm failure("file_alt_sgid: st.st_mode=%o", st.st_mode); 428228753Smm assert((st.st_mode & 07777) == (S_ISGID | 0742)); 429228753Smm } 430228753Smm 431228753Smm if (invalidgid() != -1) { 432228753Smm /* SGID should NOT be set here. */ 433228753Smm assert(0 == stat("file_bad_sgid", &st)); 434228753Smm failure("file_bad_sgid: st.st_mode=%o", st.st_mode); 435228753Smm assert((st.st_mode & 07777) == (0742)); 436228753Smm /* SGID should NOT be set here. */ 437228753Smm assert(0 == stat("file_bad_sgid2", &st)); 438228753Smm failure("file_bad_sgid2: st.st_mode=%o", st.st_mode); 439228753Smm assert((st.st_mode & 07777) == (0742)); 440228753Smm } 441228753Smm 442228753Smm if (getuid() != 0) { 443228753Smm assert(0 == stat("file_bad_owner", &st)); 444228753Smm failure("file_bad_owner: st.st_mode=%o", st.st_mode); 445228753Smm assert((st.st_mode & 07777) == (0744)); 446228753Smm failure("file_bad_owner: st.st_uid=%d getuid()=%d", 447228753Smm st.st_uid, getuid()); 448228753Smm /* The entry had getuid()+1, but because we're 449228753Smm * not root, we should not have been able to set that. */ 450228753Smm assert(st.st_uid == getuid()); 451228753Smm } 452228753Smm#endif 453228753Smm} 454