From owner-p4-projects@FreeBSD.ORG Tue Aug 5 17:12:36 2008 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 2953E1065678; Tue, 5 Aug 2008 17:12:36 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id DF575106567D for ; Tue, 5 Aug 2008 17:12:35 +0000 (UTC) (envelope-from trasz@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id CD97B8FC22 for ; Tue, 5 Aug 2008 17:12:35 +0000 (UTC) (envelope-from trasz@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.2/8.14.2) with ESMTP id m75HCZkc031672 for ; Tue, 5 Aug 2008 17:12:35 GMT (envelope-from trasz@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.2/8.14.1/Submit) id m75HCZoF031670 for perforce@freebsd.org; Tue, 5 Aug 2008 17:12:35 GMT (envelope-from trasz@freebsd.org) Date: Tue, 5 Aug 2008 17:12:35 GMT Message-Id: <200808051712.m75HCZoF031670@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to trasz@freebsd.org using -f From: Edward Tomasz Napierala To: Perforce Change Reviews Cc: Subject: PERFORCE change 146714 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 05 Aug 2008 17:12:36 -0000 http://perforce.freebsd.org/chv.cgi?CH=146714 Change 146714 by trasz@trasz_traszkan on 2008/08/05 17:11:50 Add support for NFS4 ACLs to cp(1) and mv(1). Affected files ... .. //depot/projects/soc2008/trasz_nfs4acl/TODO#32 edit .. //depot/projects/soc2008/trasz_nfs4acl/bin/cp/utils.c#2 edit .. //depot/projects/soc2008/trasz_nfs4acl/bin/mv/mv.c#3 edit Differences ... ==== //depot/projects/soc2008/trasz_nfs4acl/TODO#32 (text+ko) ==== @@ -2,7 +2,7 @@ - Make setfacl(1) error messages more user friendly. -- Add support for NFS4 ACLs to cp(1), mv(1) and tar(1). +- Add support for NFS4 ACLs to tar(1). - Clean up #defines. For example, make VREAD_NAMED_ATTRS equal to ACL_READ_NAMED_ATTRS, so there is no need for translation ==== //depot/projects/soc2008/trasz_nfs4acl/bin/cp/utils.c#2 (text+ko) ==== @@ -211,7 +211,6 @@ rval = 1; } } - (void)close(from_fd); /* * Don't remove the target even after an error. The target might @@ -231,6 +230,9 @@ rval = 1; } } + + (void)close(from_fd); + return (rval); } @@ -351,21 +353,52 @@ int preserve_fd_acls(int source_fd, int dest_fd) { - struct acl *aclp; acl_t acl; + acl_type_t source_type, dest_type; + int source_acl_supported = 0, dest_acl_supported = 0; + + if (fpathconf(source_fd, _PC_ACL_EXTENDED) == 1) { + source_acl_supported = 1; + source_type = ACL_TYPE_ACCESS; + } + + if (fpathconf(source_fd, _PC_EXTENDED_SECURITY_NP) == 1) { + source_acl_supported = 1; + source_type = ACL_TYPE_NFS4; + } + + if (fpathconf(dest_fd, _PC_ACL_EXTENDED) == 1) { + dest_acl_supported = 1; + dest_type = ACL_TYPE_ACCESS; + } + + if (fpathconf(dest_fd, _PC_EXTENDED_SECURITY_NP) == 1) { + dest_acl_supported = 1; + dest_type = ACL_TYPE_NFS4; + } - if (fpathconf(source_fd, _PC_ACL_EXTENDED) != 1 || - fpathconf(dest_fd, _PC_ACL_EXTENDED) != 1) + if (!source_acl_supported || !dest_acl_supported) return (0); - acl = acl_get_fd(source_fd); + + acl = acl_get_fd_np(source_fd, source_type); if (acl == NULL) { warn("failed to get acl entries while setting %s", to.p_path); return (1); } - aclp = &acl->ats_acl; - if (aclp->acl_cnt == 3) + + if (acl_is_trivial_np(acl)) + return (0); + + if (source_type != dest_type) { + warnx("ACL brand of source is %s, but destination is %s; " + "ACL not copied", + source_type == ACL_TYPE_NFS4 ? "NFS4" : "POSIX", + dest_type == ACL_TYPE_NFS4 ? "NFS4" : "POSIX"); + return (0); - if (acl_set_fd(dest_fd, acl) < 0) { + } + + if (acl_set_fd_np(dest_fd, acl, dest_type) < 0) { warn("failed to set acl entries for %s", to.p_path); return (1); } @@ -379,10 +412,41 @@ int (*aclsetf)(const char *, acl_type_t, acl_t); struct acl *aclp; acl_t acl; + acl_type_t source_type, dest_type; + int source_acl_supported = 0, dest_acl_supported = 0; + + if (pathconf(source_dir, _PC_ACL_EXTENDED) == 1) { + source_acl_supported = 1; + source_type = ACL_TYPE_ACCESS; + } + + if (pathconf(source_dir, _PC_EXTENDED_SECURITY_NP) == 1) { + source_acl_supported = 1; + source_type = ACL_TYPE_NFS4; + } + + if (pathconf(dest_dir, _PC_ACL_EXTENDED) == 1) { + dest_acl_supported = 1; + dest_type = ACL_TYPE_ACCESS; + } + + if (pathconf(dest_dir, _PC_EXTENDED_SECURITY_NP) == 1) { + dest_acl_supported = 1; + dest_type = ACL_TYPE_NFS4; + } + + if (!source_acl_supported || !dest_acl_supported) + return (0); + + if (source_type != dest_type) { + warnx("ACL brand of source is %s, but destination is %s; " + "ACL not copied", + source_type == ACL_TYPE_NFS4 ? "NFS4" : "POSIX", + dest_type == ACL_TYPE_NFS4 ? "NFS4" : "POSIX"); - if (pathconf(source_dir, _PC_ACL_EXTENDED) != 1 || - pathconf(dest_dir, _PC_ACL_EXTENDED) != 1) return (0); + } + /* * If the file is a link we will not follow it */ @@ -393,31 +457,35 @@ aclgetf = acl_get_file; aclsetf = acl_set_file; } - /* - * Even if there is no ACL_TYPE_DEFAULT entry here, a zero - * size ACL will be returned. So it is not safe to simply - * check the pointer to see if the default ACL is present. - */ - acl = aclgetf(source_dir, ACL_TYPE_DEFAULT); - if (acl == NULL) { - warn("failed to get default acl entries on %s", - source_dir); - return (1); + + if (source_type != ACL_TYPE_NFS4) { + /* + * Even if there is no ACL_TYPE_DEFAULT entry here, a zero + * size ACL will be returned. So it is not safe to simply + * check the pointer to see if the default ACL is present. + */ + acl = aclgetf(source_dir, ACL_TYPE_DEFAULT); + if (acl == NULL) { + warn("failed to get default acl entries on %s", + source_dir); + return (1); + } + aclp = &acl->ats_acl; + if (aclp->acl_cnt != 0 && aclsetf(dest_dir, + ACL_TYPE_DEFAULT, acl) < 0) { + warn("failed to set default acl entries on %s", + dest_dir); + return (1); + } } - aclp = &acl->ats_acl; - if (aclp->acl_cnt != 0 && aclsetf(dest_dir, - ACL_TYPE_DEFAULT, acl) < 0) { - warn("failed to set default acl entries on %s", - dest_dir); - return (1); - } - acl = aclgetf(source_dir, ACL_TYPE_ACCESS); + + acl = aclgetf(source_dir, source_type); if (acl == NULL) { warn("failed to get acl entries on %s", source_dir); return (1); } aclp = &acl->ats_acl; - if (aclsetf(dest_dir, ACL_TYPE_ACCESS, acl) < 0) { + if (aclsetf(dest_dir, dest_type, acl) < 0) { warn("failed to set acl entries on %s", dest_dir); return (1); } ==== //depot/projects/soc2008/trasz_nfs4acl/bin/mv/mv.c#3 (text+ko) ==== @@ -74,6 +74,8 @@ static int do_move(const char *, const char *); static int fastcopy(const char *, const char *, struct stat *); static void usage(void); +static int preserve_fd_acls(int source_fd, int dest_fd, const char *source_path, + const char *dest_path); int main(int argc, char *argv[]) @@ -260,7 +262,6 @@ struct timeval tval[2]; static u_int blen; static char *bp; - acl_t acl; mode_t oldmode; int nread, from_fd, to_fd; @@ -316,15 +317,8 @@ * for dest_file, then its ACLs shall reflect the ACLs of the * source_file. */ - if (fpathconf(to_fd, _PC_ACL_EXTENDED) == 1 && - fpathconf(from_fd, _PC_ACL_EXTENDED) == 1) { - acl = acl_get_fd(from_fd); - if (acl == NULL) - warn("failed to get acl entries while setting %s", - from); - else if (acl_set_fd(to_fd, acl) < 0) - warn("failed to set acl entries for %s", to); - } + preserve_fd_acls(from_fd, to_fd, from, to); + (void)close(from_fd); if (fchmod(to_fd, sbp->st_mode)) warn("%s: set mode (was: 0%03o)", to, oldmode); @@ -438,6 +432,62 @@ return (0); } +static int +preserve_fd_acls(int source_fd, int dest_fd, const char *source_path, + const char *dest_path) +{ + acl_t acl; + acl_type_t source_type, dest_type; + int source_acl_supported = 0, dest_acl_supported = 0; + + if (fpathconf(source_fd, _PC_ACL_EXTENDED) == 1) { + source_acl_supported = 1; + source_type = ACL_TYPE_ACCESS; + } + + if (fpathconf(source_fd, _PC_EXTENDED_SECURITY_NP) == 1) { + source_acl_supported = 1; + source_type = ACL_TYPE_NFS4; + } + + if (fpathconf(dest_fd, _PC_ACL_EXTENDED) == 1) { + dest_acl_supported = 1; + dest_type = ACL_TYPE_ACCESS; + } + + if (fpathconf(dest_fd, _PC_EXTENDED_SECURITY_NP) == 1) { + dest_acl_supported = 1; + dest_type = ACL_TYPE_NFS4; + } + + if (!source_acl_supported || !dest_acl_supported) + return (0); + + acl = acl_get_fd_np(source_fd, source_type); + if (acl == NULL) { + warn("failed to get acl entries while setting %s", source_path); + return (1); + } + + if (acl_is_trivial_np(acl)) + return (0); + + if (source_type != dest_type) { + warnx("ACL brand of source is %s, but destination is %s; " + "ACL not copied", + source_type == ACL_TYPE_NFS4 ? "NFS4" : "POSIX", + dest_type == ACL_TYPE_NFS4 ? "NFS4" : "POSIX"); + + return (0); + } + + if (acl_set_fd_np(dest_fd, acl, dest_type) < 0) { + warn("failed to set acl entries for %s", dest_path); + return (1); + } + return (0); +} + static void usage(void) {