commit 0e1aff215dab990f2aa8e179495be96780774131 Author: Jacob Welsh AuthorDate: Fri Apr 26 21:36:32 2024 +0000 Commit: Jacob Welsh CommitDate: Fri Apr 26 21:43:41 2024 +0000 busybox/archival: implement tar --same-owner as default only for root, & related changes. Now that we properly report failure to chmod, non-root extraction no longer spews permission errors, and as an added bonus no longer hammers on passwd/group database lookups. Rename related getopt constants for consistency. Since I had to dig up its meaning anyway, make better use of opt_complementary to set the --same-owner and --same-permissions pairs properly (so later options override earlier ones). diff --git a/base/busybox/archival/tar.c b/base/busybox/archival/tar.c index f1cdbc5..62ae895 100644 --- a/base/busybox/archival/tar.c +++ b/base/busybox/archival/tar.c @@ -810,6 +810,7 @@ static llist_t *append_file_list_to_list(llist_t *list) //usage: IF_FEATURE_TAR_NOPRESERVE_TIME( //usage: "\n -m Don't restore mtime" //usage: ) +//usage: "\n --same-owner Restore owner and group (default for superuser)" //usage: "\n -o,--no-same-owner Don't restore owner and group" //usage: "\n -p,--same-permissions Restore file permissions (default for superuser)" //usage: "\n --no-same-permissions Don't restore file permissions" @@ -847,10 +848,11 @@ enum { IF_FEATURE_TAR_NOPRESERVE_TIME(OPTBIT_NOPRESERVE_TIME,) #if ENABLE_FEATURE_TAR_LONG_OPTIONS OPTBIT_STERILIZE, + OPTBIT_SAME_OWNER, OPTBIT_NORECURSION, IF_FEATURE_TAR_TO_COMMAND(OPTBIT_2COMMAND ,) OPTBIT_NUMERIC_OWNER, - OPTBIT_NOPRESERVE_PERM, + OPTBIT_NOSAME_PERM, OPTBIT_OVERWRITE, #endif OPT_TEST = 1 << 0, // t @@ -858,8 +860,8 @@ enum { OPT_BASEDIR = 1 << 2, // C OPT_TARNAME = 1 << 3, // f OPT_2STDOUT = 1 << 4, // O - OPT_NOPRESERVE_OWNER = 1 << 5, // o == no-same-owner - OPT_P = 1 << 6, // p + OPT_NOSAME_OWNER = 1 << 5, // o == no-same-owner + OPT_SAME_PERM = 1 << 6, // p == same-permissions OPT_VERBOSE = 1 << 7, // v OPT_KEEP_OLD = 1 << 8, // k OPT_CREATE = IF_FEATURE_TAR_CREATE( (1 << OPTBIT_CREATE )) + 0, // c @@ -873,10 +875,11 @@ enum { OPT_COMPRESS = IF_FEATURE_SEAMLESS_Z( (1 << OPTBIT_COMPRESS )) + 0, // Z OPT_NOPRESERVE_TIME = IF_FEATURE_TAR_NOPRESERVE_TIME((1 << OPTBIT_NOPRESERVE_TIME)) + 0, // m OPT_STERILIZE = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_STERILIZE )) + 0, // sterilize + OPT_SAME_OWNER = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_SAME_OWNER )) + 0, // same-owner OPT_NORECURSION = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NORECURSION )) + 0, // no-recursion OPT_2COMMAND = IF_FEATURE_TAR_TO_COMMAND( (1 << OPTBIT_2COMMAND )) + 0, // to-command OPT_NUMERIC_OWNER = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NUMERIC_OWNER )) + 0, // numeric-owner - OPT_NOPRESERVE_PERM = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NOPRESERVE_PERM)) + 0, // no-same-permissions + OPT_NOSAME_PERM = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NOSAME_PERM )) + 0, // no-same-permissions OPT_OVERWRITE = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_OVERWRITE )) + 0, // overwrite OPT_ANY_COMPRESS = (OPT_BZIP2 | OPT_LZMA | OPT_GZIP | OPT_XZ | OPT_COMPRESS), @@ -922,6 +925,7 @@ static const char tar_longopts[] ALIGN1 = "touch\0" No_argument "m" # endif "sterilize\0" No_argument "\x80" + "same-owner\0" No_argument "\x81" "no-recursion\0" No_argument "\xfa" # if ENABLE_FEATURE_TAR_TO_COMMAND "to-command\0" Required_argument "\xfb" @@ -962,8 +966,12 @@ int tar_main(int argc UNUSED_PARAM, char **argv) opt_complementary = "--:" // first arg is options "tt:vv:" // count -t,-v IF_FEATURE_TAR_FROM("X::T::") // cumulative lists -#if ENABLE_FEATURE_TAR_LONG_OPTIONS && ENABLE_FEATURE_TAR_FROM +#if ENABLE_FEATURE_TAR_LONG_OPTIONS +# if ENABLE_FEATURE_TAR_FROM "\xff::" // cumulative lists for --exclude +# endif + "\x81-o:o-\x81:" // [no-]same-owner mutually override + "p-\xfd:\xfd-p:" // [no-]same-permissions mutually override #endif IF_FEATURE_TAR_CREATE("c:") "t:x:" // at least one of these is reqd IF_FEATURE_TAR_CREATE("c--tx:t--cx:x--ct") // mutually exclusive @@ -1044,10 +1052,10 @@ int tar_main(int argc UNUSED_PARAM, char **argv) if (opt & OPT_NUMERIC_OWNER) tar_handle->ah_flags |= ARCHIVE_NUMERIC_OWNER; - if (opt & OPT_NOPRESERVE_OWNER) + if (opt & OPT_NOSAME_OWNER || (!(opt & OPT_SAME_OWNER) && getuid() != 0)) tar_handle->ah_flags |= ARCHIVE_DONT_RESTORE_OWNER; - if (opt & OPT_NOPRESERVE_PERM || (!(opt & OPT_P) && getuid() != 0)) + if (opt & OPT_NOSAME_PERM || (!(opt & OPT_SAME_PERM) && getuid() != 0)) tar_handle->ah_flags |= ARCHIVE_DONT_RESTORE_PERM; if (opt & OPT_OVERWRITE) {