file_subs.c (76017) | file_subs.c (76351) |
---|---|
1/*- 2 * Copyright (c) 1992 Keith Muller. 3 * Copyright (c) 1992, 1993 4 * The Regents of the University of California. All rights reserved. 5 * 6 * This code is derived from software contributed to Berkeley by 7 * Keith Muller of the University of California, San Diego. 8 * --- 26 unchanged lines hidden (view full) --- 35 * SUCH DAMAGE. 36 */ 37 38#ifndef lint 39#if 0 40static char sccsid[] = "@(#)file_subs.c 8.1 (Berkeley) 5/31/93"; 41#endif 42static const char rcsid[] = | 1/*- 2 * Copyright (c) 1992 Keith Muller. 3 * Copyright (c) 1992, 1993 4 * The Regents of the University of California. All rights reserved. 5 * 6 * This code is derived from software contributed to Berkeley by 7 * Keith Muller of the University of California, San Diego. 8 * --- 26 unchanged lines hidden (view full) --- 35 * SUCH DAMAGE. 36 */ 37 38#ifndef lint 39#if 0 40static char sccsid[] = "@(#)file_subs.c 8.1 (Berkeley) 5/31/93"; 41#endif 42static const char rcsid[] = |
43 "$FreeBSD: head/bin/pax/file_subs.c 76017 2001-04-26 08:37:00Z kris $"; | 43 "$FreeBSD: head/bin/pax/file_subs.c 76351 2001-05-08 06:19:06Z kris $"; |
44#endif /* not lint */ 45 46#include <sys/types.h> 47#include <sys/time.h> 48#include <sys/stat.h> 49#include <unistd.h> 50#include <fcntl.h> 51#include <string.h> 52#include <stdio.h> 53#include <errno.h> 54#include <sys/uio.h> 55#include <stdlib.h> 56#include "pax.h" | 44#endif /* not lint */ 45 46#include <sys/types.h> 47#include <sys/time.h> 48#include <sys/stat.h> 49#include <unistd.h> 50#include <fcntl.h> 51#include <string.h> 52#include <stdio.h> 53#include <errno.h> 54#include <sys/uio.h> 55#include <stdlib.h> 56#include "pax.h" |
57#include "options.h" |
|
57#include "extern.h" 58 59static int 60mk_link __P((register char *,register struct stat *,register char *, int)); 61 62/* 63 * routines that deal with file operations such as: creating, removing; 64 * and setting access modes, uid/gid and times of files --- 52 unchanged lines hidden (view full) --- 117 * try to open it again, if this fails, check all the nodes in 118 * the path and give it a final try. if chk_path() finds that 119 * it cannot fix anything, we will skip the last attempt 120 */ 121 if ((fd = open(arcn->name, O_WRONLY | O_CREAT | O_TRUNC, 122 file_mode)) >= 0) 123 break; 124 oerrno = errno; | 58#include "extern.h" 59 60static int 61mk_link __P((register char *,register struct stat *,register char *, int)); 62 63/* 64 * routines that deal with file operations such as: creating, removing; 65 * and setting access modes, uid/gid and times of files --- 52 unchanged lines hidden (view full) --- 118 * try to open it again, if this fails, check all the nodes in 119 * the path and give it a final try. if chk_path() finds that 120 * it cannot fix anything, we will skip the last attempt 121 */ 122 if ((fd = open(arcn->name, O_WRONLY | O_CREAT | O_TRUNC, 123 file_mode)) >= 0) 124 break; 125 oerrno = errno; |
125 if (chk_path(arcn->name,arcn->sb.st_uid,arcn->sb.st_gid) < 0) { | 126 if (nodirs || chk_path(arcn->name,arcn->sb.st_uid,arcn->sb.st_gid) < 0) { |
126 syswarn(1, oerrno, "Unable to create %s", arcn->name); 127 return(-1); 128 } 129 } 130 return(fd); 131} 132 133/* --- 217 unchanged lines hidden (view full) --- 351 * from file is gone (or did not exist), try to make the hard link. 352 * if it fails, check the path and try it again (if chk_path() says to 353 * try again) 354 */ 355 for (;;) { 356 if (link(to, from) == 0) 357 break; 358 oerrno = errno; | 127 syswarn(1, oerrno, "Unable to create %s", arcn->name); 128 return(-1); 129 } 130 } 131 return(fd); 132} 133 134/* --- 217 unchanged lines hidden (view full) --- 352 * from file is gone (or did not exist), try to make the hard link. 353 * if it fails, check the path and try it again (if chk_path() says to 354 * try again) 355 */ 356 for (;;) { 357 if (link(to, from) == 0) 358 break; 359 oerrno = errno; |
359 if (chk_path(from, to_sb->st_uid, to_sb->st_gid) == 0) | 360 if (!nodirs && chk_path(from, to_sb->st_uid, to_sb->st_gid) == 0) |
360 continue; 361 if (!ign) { 362 syswarn(1, oerrno, "Could not link to %s from %s", to, 363 from); 364 return(-1); 365 } 366 return(1); 367 } --- 58 unchanged lines hidden (view full) --- 426 /* 427 * Skip sockets, operation has no meaning under BSD 428 */ 429 paxwarn(0, 430 "%s skipped. Sockets cannot be copied or extracted", 431 arcn->name); 432 return(-1); 433 case PAX_SLK: | 361 continue; 362 if (!ign) { 363 syswarn(1, oerrno, "Could not link to %s from %s", to, 364 from); 365 return(-1); 366 } 367 return(1); 368 } --- 58 unchanged lines hidden (view full) --- 427 /* 428 * Skip sockets, operation has no meaning under BSD 429 */ 430 paxwarn(0, 431 "%s skipped. Sockets cannot be copied or extracted", 432 arcn->name); 433 return(-1); 434 case PAX_SLK: |
434 if ((res = symlink(arcn->ln_name, arcn->name)) == 0) 435 return(0); | 435 res = symlink(arcn->ln_name, arcn->name); |
436 break; 437 case PAX_CTG: 438 case PAX_HLK: 439 case PAX_HRG: 440 case PAX_REG: 441 default: 442 /* 443 * we should never get here --- 16 unchanged lines hidden (view full) --- 460 */ 461 oerrno = errno; 462 if ((ign = unlnk_exist(arcn->name, arcn->type)) < 0) 463 return(-1); 464 465 if (++pass <= 1) 466 continue; 467 | 436 break; 437 case PAX_CTG: 438 case PAX_HLK: 439 case PAX_HRG: 440 case PAX_REG: 441 default: 442 /* 443 * we should never get here --- 16 unchanged lines hidden (view full) --- 460 */ 461 oerrno = errno; 462 if ((ign = unlnk_exist(arcn->name, arcn->type)) < 0) 463 return(-1); 464 465 if (++pass <= 1) 466 continue; 467 |
468 if (chk_path(arcn->name,arcn->sb.st_uid,arcn->sb.st_gid) < 0) { | 468 if (nodirs || chk_path(arcn->name,arcn->sb.st_uid,arcn->sb.st_gid) < 0) { |
469 syswarn(1, oerrno, "Could not create: %s", arcn->name); 470 return(-1); 471 } 472 } 473 474 /* 475 * we were able to create the node. set uid/gid, modes and times 476 */ 477 if (pids) | 469 syswarn(1, oerrno, "Could not create: %s", arcn->name); 470 return(-1); 471 } 472 } 473 474 /* 475 * we were able to create the node. set uid/gid, modes and times 476 */ 477 if (pids) |
478 res = set_ids(arcn->name, arcn->sb.st_uid, arcn->sb.st_gid); | 478 res = ((arcn->type == PAX_SLK) ? 479 set_lids(arcn->name, arcn->sb.st_uid, arcn->sb.st_gid) : 480 set_ids(arcn->name, arcn->sb.st_uid, arcn->sb.st_gid)); |
479 else 480 res = 0; 481 482 /* | 481 else 482 res = 0; 483 484 /* |
485 * symlinks are done now. 486 */ 487 if (arcn->type == PAX_SLK) 488 return(0); 489 490 /* |
|
483 * IMPORTANT SECURITY NOTE: 484 * if not preserving mode or we cannot set uid/gid, then PROHIBIT any 485 * set uid/gid bits 486 */ 487 if (!pmode || res) 488 arcn->sb.st_mode &= ~(SETBITS); 489 if (pmode) 490 set_pmode(arcn->name, arcn->sb.st_mode); 491 | 491 * IMPORTANT SECURITY NOTE: 492 * if not preserving mode or we cannot set uid/gid, then PROHIBIT any 493 * set uid/gid bits 494 */ 495 if (!pmode || res) 496 arcn->sb.st_mode &= ~(SETBITS); 497 if (pmode) 498 set_pmode(arcn->name, arcn->sb.st_mode); 499 |
492 if (arcn->type == PAX_DIR) { | 500 if (arcn->type == PAX_DIR && strcmp(NM_CPIO, argv0) != 0) { |
493 /* 494 * Dirs must be processed again at end of extract to set times 495 * and modes to agree with those stored in the archive. However 496 * to allow extract to continue, we may have to also set owner 497 * rights. This allows nodes in the archive that are children 498 * of this directory to be extracted without failure. Both time 499 * and modes will be fixed after the entire archive is read and 500 * before pax exits. --- 246 unchanged lines hidden (view full) --- 747int 748set_ids(fnm, uid, gid) 749 char *fnm; 750 uid_t uid; 751 gid_t gid; 752#endif 753{ 754 if (chown(fnm, uid, gid) < 0) { | 501 /* 502 * Dirs must be processed again at end of extract to set times 503 * and modes to agree with those stored in the archive. However 504 * to allow extract to continue, we may have to also set owner 505 * rights. This allows nodes in the archive that are children 506 * of this directory to be extracted without failure. Both time 507 * and modes will be fixed after the entire archive is read and 508 * before pax exits. --- 246 unchanged lines hidden (view full) --- 755int 756set_ids(fnm, uid, gid) 757 char *fnm; 758 uid_t uid; 759 gid_t gid; 760#endif 761{ 762 if (chown(fnm, uid, gid) < 0) { |
755 syswarn(1, errno, "Unable to set file uid/gid of %s", fnm); | 763 /* 764 * ignore EPERM unless in verbose mode or being run by root. 765 * if running as pax, POSIX requires a warning. 766 */ 767 if (strcmp(NM_PAX, argv0) == 0 || errno != EPERM || vflag || 768 geteuid() == 0) 769 syswarn(1, errno, "Unable to set file uid/gid of %s", 770 fnm); |
756 return(-1); 757 } 758 return(0); 759} 760 761/* | 771 return(-1); 772 } 773 return(0); 774} 775 776/* |
777 * set_lids() 778 * set the uid and gid of a file system node 779 * Return: 780 * 0 when set, -1 on failure 781 */ 782 783#ifdef __STDC__ 784int 785set_lids(char *fnm, uid_t uid, gid_t gid) 786#else 787int 788set_lids(fnm, uid, gid) 789 char *fnm; 790 uid_t uid; 791 gid_t gid; 792#endif 793{ 794 if (lchown(fnm, uid, gid) < 0) { 795 /* 796 * ignore EPERM unless in verbose mode or being run by root. 797 * if running as pax, POSIX requires a warning. 798 */ 799 if (strcmp(NM_PAX, argv0) == 0 || errno != EPERM || vflag || 800 geteuid() == 0) 801 syswarn(1, errno, "Unable to set file uid/gid of %s", 802 fnm); 803 return(-1); 804 } 805 return(0); 806} 807 808/* |
|
762 * set_pmode() 763 * Set file access mode 764 */ 765 766#ifdef __STDC__ 767void 768set_pmode(char *fnm, mode_t mode) 769#else --- 288 unchanged lines hidden --- | 809 * set_pmode() 810 * Set file access mode 811 */ 812 813#ifdef __STDC__ 814void 815set_pmode(char *fnm, mode_t mode) 816#else --- 288 unchanged lines hidden --- |