This fixes bsdcpio's -R option to accept numeric
user or group Ids as well as user or group names. In particular, this fixes freesbie2, which uses -R 0:0 to copy a bunch of files so that the result will be owned by root. Also fixes a related bug that mixed-up the uid and gid specified by -R when in passthrough mode. Thanks to Dominique Goncalves for reporting this regression. Approved by: re (kib)
This commit is contained in:
parent
7ce4ab7ff8
commit
49230574bc
@ -268,16 +268,36 @@ cpio_getopt(struct cpio *cpio)
|
||||
* Parse the argument to the -R or --owner flag.
|
||||
*
|
||||
* The format is one of the following:
|
||||
* <user> - Override user but not group
|
||||
* <user>: - Override both, group is user's default group
|
||||
* <user>:<group> - Override both
|
||||
* :<group> - Override group but not user
|
||||
* <username|uid> - Override user but not group
|
||||
* <username>: - Override both, group is user's default group
|
||||
* <uid>: - Override user but not group
|
||||
* <username|uid>:<groupname|gid> - Override both
|
||||
* :<groupname|gid> - Override group but not user
|
||||
*
|
||||
* Where uid/gid are decimal representations and groupname/username
|
||||
* are names to be looked up in system database. Note that
|
||||
* uid/gid parsing takes priority over username/groupname lookup,
|
||||
* so this won't do a lookup for usernames or group names that
|
||||
* consist entirely of digits.
|
||||
*
|
||||
* A period can be used instead of the colon.
|
||||
*
|
||||
* Sets uid/gid as appropriate, -1 indicates uid/gid not specified.
|
||||
* Sets uid/gid return as appropriate, -1 indicates uid/gid not specified.
|
||||
*
|
||||
*/
|
||||
static int
|
||||
decimal_parse(const char *p)
|
||||
{
|
||||
/* TODO: guard against overflow. */
|
||||
int n = 0;
|
||||
for (; *p != '\0'; ++p) {
|
||||
if (*p < '0' || *p > '9')
|
||||
return (-1);
|
||||
n = n * 10 + *p - '0';
|
||||
}
|
||||
return (n);
|
||||
}
|
||||
|
||||
int
|
||||
owner_parse(const char *spec, int *uid, int *gid)
|
||||
{
|
||||
@ -318,24 +338,34 @@ owner_parse(const char *spec, int *uid, int *gid)
|
||||
}
|
||||
memcpy(user, u, ue - u);
|
||||
user[ue - u] = '\0';
|
||||
pwent = getpwnam(user);
|
||||
if (pwent == NULL) {
|
||||
cpio_warnc(errno, "Couldn't lookup user ``%s''", user);
|
||||
return (1);
|
||||
*uid = decimal_parse(user);
|
||||
if (*uid < 0) {
|
||||
/* Couldn't parse as integer, try username lookup. */
|
||||
pwent = getpwnam(user);
|
||||
if (pwent == NULL) {
|
||||
cpio_warnc(errno,
|
||||
"Couldn't lookup user ``%s''", user);
|
||||
return (1);
|
||||
}
|
||||
*uid = pwent->pw_uid;
|
||||
if (*ue != '\0' && *g == '\0')
|
||||
*gid = pwent->pw_gid;
|
||||
}
|
||||
free(user);
|
||||
*uid = pwent->pw_uid;
|
||||
if (*ue != '\0' && *g == '\0')
|
||||
*gid = pwent->pw_gid;
|
||||
}
|
||||
if (*g != '\0') {
|
||||
struct group *grp;
|
||||
grp = getgrnam(g);
|
||||
if (grp != NULL)
|
||||
*gid = grp->gr_gid;
|
||||
else {
|
||||
cpio_warnc(errno, "Couldn't look up group ``%s''", g);
|
||||
return (1);
|
||||
*gid = decimal_parse(g);
|
||||
if (*gid < 0) {
|
||||
/* Couldn't parse int, try group name lookup. */
|
||||
struct group *grp;
|
||||
grp = getgrnam(g);
|
||||
if (grp != NULL)
|
||||
*gid = grp->gr_gid;
|
||||
else {
|
||||
cpio_warnc(errno,
|
||||
"Couldn't look up group ``%s''", g);
|
||||
return (1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return (0);
|
||||
|
@ -575,7 +575,7 @@ file_to_archive(struct cpio *cpio, const char *srcpath)
|
||||
if (cpio->uid_override >= 0)
|
||||
st.st_uid = cpio->uid_override;
|
||||
if (cpio->gid_override >= 0)
|
||||
st.st_gid = cpio->uid_override;
|
||||
st.st_gid = cpio->gid_override;
|
||||
archive_entry_copy_stat(entry, &st);
|
||||
|
||||
#if !defined(_WIN32) || defined(__CYGWIN__)
|
||||
|
Loading…
Reference in New Issue
Block a user