root/lib/qcopy-acl.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. is_attr_permissions
  2. qcopy_acl

     1 /* Copy access control list from one file to another.  -*- coding: utf-8 -*-
     2 
     3    Copyright (C) 2002-2003, 2005-2023 Free Software Foundation, Inc.
     4 
     5    This program is free software: you can redistribute it and/or modify
     6    it under the terms of the GNU General Public License as published by
     7    the Free Software Foundation, either version 3 of the License, or
     8    (at your option) any later version.
     9 
    10    This program is distributed in the hope that it will be useful,
    11    but WITHOUT ANY WARRANTY; without even the implied warranty of
    12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13    GNU General Public License for more details.
    14 
    15    You should have received a copy of the GNU General Public License
    16    along with this program.  If not, see <https://www.gnu.org/licenses/>.
    17 
    18    Written by Paul Eggert, Andreas Grünbacher, and Bruno Haible.  */
    19 
    20 #include <config.h>
    21 
    22 #include "acl.h"
    23 
    24 #include "acl-internal.h"
    25 
    26 #if USE_XATTR
    27 
    28 # include <attr/libattr.h>
    29 
    30 /* Returns 1 if NAME is the name of an extended attribute that is related
    31    to permissions, i.e. ACLs.  Returns 0 otherwise.  */
    32 
    33 static int
    34 is_attr_permissions (const char *name, struct error_context *ctx)
    35 {
    36   return attr_copy_action (name, ctx) == ATTR_ACTION_PERMISSIONS;
    37 }
    38 
    39 #endif  /* USE_XATTR */
    40 
    41 /* Copy access control lists from one file to another. If SOURCE_DESC is
    42    a valid file descriptor, use file descriptor operations, else use
    43    filename based operations on SRC_NAME. Likewise for DEST_DESC and
    44    DST_NAME.
    45    If access control lists are not available, fchmod the target file to
    46    MODE.  Also sets the non-permission bits of the destination file
    47    (S_ISUID, S_ISGID, S_ISVTX) to those from MODE if any are set.
    48    Return 0 if successful.
    49    Return -2 and set errno for an error relating to the source file.
    50    Return -1 and set errno for an error relating to the destination file.  */
    51 
    52 int
    53 qcopy_acl (const char *src_name, int source_desc, const char *dst_name,
    54            int dest_desc, mode_t mode)
    55 {
    56   int ret;
    57 
    58 #ifdef USE_XATTR
    59   /* in case no ACLs present and also to set higher mode bits
    60      we chmod before setting ACLs as doing it after could overwrite them
    61      (especially true for NFSv4, posix ACL has that ugly "mask" hack that
    62      nobody understands) */
    63   ret = chmod_or_fchmod (dst_name, dest_desc, mode);
    64   /* Rather than fiddling with acls one by one, we just copy the whole ACL xattrs
    65      (Posix or NFSv4). Of course, that won't address ACLs conversion
    66      (i.e. posix <-> nfs4) but we can't do it anyway, so for now, we don't care
    67      Functions attr_copy_* return 0 in case we copied something OR nothing
    68      to copy */
    69   if (ret == 0)
    70     ret = source_desc <= 0 || dest_desc <= 0
    71       ? attr_copy_file (src_name, dst_name, is_attr_permissions, NULL)
    72       : attr_copy_fd (src_name, source_desc, dst_name, dest_desc,
    73                       is_attr_permissions, NULL);
    74 #else
    75   /* no XATTR, so we proceed the old dusty way */
    76   struct permission_context ctx;
    77 
    78   ret = get_permissions (src_name, source_desc, mode, &ctx);
    79   if (ret != 0)
    80     return -2;
    81   ret = set_permissions (&ctx, dst_name, dest_desc);
    82   free_permission_context (&ctx);
    83 #endif
    84   return ret;
    85 }

/* [<][>][^][v][top][bottom][index][help] */