Print this page
3619 cp -p clobbers permissions/ownership following symbolic links


   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*




  23  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 
  27 /*      Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T     */
  28 /*        All Rights Reserved   */
  29 
  30 /*
  31  * University Copyright- Copyright (c) 1982, 1986, 1988
  32  * The Regents of the University of California
  33  * All Rights Reserved
  34  *
  35  * University Acknowledgment- Portions of this document are derived from
  36  * software developed by the University of California, Berkeley, and its
  37  * contributors.
  38  */
  39 
  40 /*
  41  * Combined mv/cp/ln command:
  42  *      mv file1 file2


1331  * chg_time()
1332  *
1333  * Try to preserve modification and access time.
1334  * If 1) pflg is not set, or 2) pflg is set and this is the Solaris version,
1335  * don't report a utimensat() failure.
1336  * If this is the XPG4 version and utimensat fails, if 1) pflg is set (cp -p)
1337  * or 2) we are doing a mv, print a diagnostic message; arrange for a non-zero
1338  * exit status only if pflg is set.
1339  * utimensat(2) is being used to achieve granularity in nanoseconds
1340  * (if supported by the underlying file system) while setting file times.
1341  */
1342 static int
1343 chg_time(char *to, struct stat ss)
1344 {
1345         struct timespec times[2];
1346         int rc;
1347 
1348         times[0] = ss.st_atim;
1349         times[1] = ss.st_mtim;
1350 
1351         rc = utimensat(AT_FDCWD, to, times, 0);

1352 #ifdef XPG4
1353         if ((pflg || mve) && rc != 0) {
1354                 (void) fprintf(stderr,
1355                     gettext("%s: cannot set times for %s: "), cmd, to);
1356                 perror("");
1357                 if (pflg)
1358                         return (1);
1359         }
1360 #endif
1361 
1362         return (0);
1363 
1364 }
1365 
1366 /*
1367  * chg_mode()
1368  *
1369  * This function is called upon "cp -p" or mv across filesystems.
1370  *
1371  * Try to preserve the owner and group id.  If chown() fails,
1372  * only print a diagnostic message if doing a mv in the XPG4 version;
1373  * try to clear S_ISUID and S_ISGID bits in the target.  If unable to clear
1374  * S_ISUID and S_ISGID bits, print a diagnostic message and arrange for a
1375  * non-zero exit status because this is a security violation.
1376  * Try to preserve permissions.
1377  * If this is the XPG4 version and chmod() fails, print a diagnostic message
1378  * and arrange for a non-zero exit status.
1379  * If this is the Solaris version and chmod() fails, do not print a
1380  * diagnostic message or exit with a non-zero value.
1381  */
1382 static int
1383 chg_mode(char *target, uid_t uid, gid_t gid, mode_t mode)
1384 {
1385         int clearflg = 0; /* controls message printed upon chown() error */

1386 




1387         if (chown(target, uid, gid) != 0) {
1388 #ifdef XPG4
1389                 if (mve) {
1390                         (void) fprintf(stderr, gettext("%s: cannot change"
1391                             " owner and group of %s: "), cmd, target);
1392                         perror("");
1393                 }
1394 #endif
1395                 if (mode & (S_ISUID | S_ISGID)) {
1396                         /* try to clear S_ISUID and S_ISGID */
1397                         mode &= ~S_ISUID & ~S_ISGID;
1398                         ++clearflg;
1399                 }
1400         }
1401         if (chmod(target, mode) != 0) {
1402                 if (clearflg) {
1403                         (void) fprintf(stderr, gettext(
1404                             "%s: cannot clear S_ISUID and S_ISGID bits in"
1405                             " %s: "), cmd, target);
1406                         perror("");




   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
  24  */
  25 
  26 /*
  27  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  28  * Use is subject to license terms.
  29  */
  30 
  31 /*      Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T     */
  32 /*        All Rights Reserved   */
  33 
  34 /*
  35  * University Copyright- Copyright (c) 1982, 1986, 1988
  36  * The Regents of the University of California
  37  * All Rights Reserved
  38  *
  39  * University Acknowledgment- Portions of this document are derived from
  40  * software developed by the University of California, Berkeley, and its
  41  * contributors.
  42  */
  43 
  44 /*
  45  * Combined mv/cp/ln command:
  46  *      mv file1 file2


1335  * chg_time()
1336  *
1337  * Try to preserve modification and access time.
1338  * If 1) pflg is not set, or 2) pflg is set and this is the Solaris version,
1339  * don't report a utimensat() failure.
1340  * If this is the XPG4 version and utimensat fails, if 1) pflg is set (cp -p)
1341  * or 2) we are doing a mv, print a diagnostic message; arrange for a non-zero
1342  * exit status only if pflg is set.
1343  * utimensat(2) is being used to achieve granularity in nanoseconds
1344  * (if supported by the underlying file system) while setting file times.
1345  */
1346 static int
1347 chg_time(char *to, struct stat ss)
1348 {
1349         struct timespec times[2];
1350         int rc;
1351 
1352         times[0] = ss.st_atim;
1353         times[1] = ss.st_mtim;
1354 
1355         rc = utimensat(AT_FDCWD, to, times,
1356             ISLNK(s1) ? AT_SYMLINK_NOFOLLOW : 0);
1357 #ifdef XPG4
1358         if ((pflg || mve) && rc != 0) {
1359                 (void) fprintf(stderr,
1360                     gettext("%s: cannot set times for %s: "), cmd, to);
1361                 perror("");
1362                 if (pflg)
1363                         return (1);
1364         }
1365 #endif
1366 
1367         return (0);
1368 
1369 }
1370 
1371 /*
1372  * chg_mode()
1373  *
1374  * This function is called upon "cp -p" or mv across filesystems.
1375  *
1376  * Try to preserve the owner and group id.  If chown() fails,
1377  * only print a diagnostic message if doing a mv in the XPG4 version;
1378  * try to clear S_ISUID and S_ISGID bits in the target.  If unable to clear
1379  * S_ISUID and S_ISGID bits, print a diagnostic message and arrange for a
1380  * non-zero exit status because this is a security violation.
1381  * Try to preserve permissions.
1382  * If this is the XPG4 version and chmod() fails, print a diagnostic message
1383  * and arrange for a non-zero exit status.
1384  * If this is the Solaris version and chmod() fails, do not print a
1385  * diagnostic message or exit with a non-zero value.
1386  */
1387 static int
1388 chg_mode(char *target, uid_t uid, gid_t gid, mode_t mode)
1389 {
1390         int clearflg = 0; /* controls message printed upon chown() error */
1391         struct stat st;
1392 
1393         /* Don't change mode if target is symlink */
1394         if (lstat(target, &st) == 0 && ISLNK(st))
1395                 return (0);
1396 
1397         if (chown(target, uid, gid) != 0) {
1398 #ifdef XPG4
1399                 if (mve) {
1400                         (void) fprintf(stderr, gettext("%s: cannot change"
1401                             " owner and group of %s: "), cmd, target);
1402                         perror("");
1403                 }
1404 #endif
1405                 if (mode & (S_ISUID | S_ISGID)) {
1406                         /* try to clear S_ISUID and S_ISGID */
1407                         mode &= ~S_ISUID & ~S_ISGID;
1408                         ++clearflg;
1409                 }
1410         }
1411         if (chmod(target, mode) != 0) {
1412                 if (clearflg) {
1413                         (void) fprintf(stderr, gettext(
1414                             "%s: cannot clear S_ISUID and S_ISGID bits in"
1415                             " %s: "), cmd, target);
1416                         perror("");