Start adding POSIX 1.e draft file capability support for real
- Parse %caps() from spec filelists, making best-guess verification of capability string sanity by passing to cap_from_text() - The posix draft specifies capability export presentation through cap_copy_ext() which would be fine, except that we don't have support for arrays of binary data. So we simply store the textual representation of the capabilities in a string array which we do have. - Only add capability tag on packages which actually have capabilities to avoid unnecessary header bloat. - Add a new rpmlib() dependency for file capabilities, packages relying on file capabilities wont work correctly unless the capabilities are set. To be fully correct, support for on-filesystem file capabilities should be checked at runtime, as this depends on kernel versions and such...
This commit is contained in:
parent
daf28d3bf4
commit
a792c55ffa
|
@ -68,6 +68,7 @@ typedef struct FileListRec_s {
|
|||
specdFlags specdFlags; /* which attributes have been explicitly specified. */
|
||||
rpmVerifyFlags verifyFlags;
|
||||
char *langs; /* XXX locales separated with | */
|
||||
char *caps;
|
||||
} * FileListRec;
|
||||
|
||||
/**
|
||||
|
@ -116,6 +117,8 @@ typedef struct FileList_s {
|
|||
rpmVerifyFlags defVerifyFlags;
|
||||
int nLangs;
|
||||
char ** currentLangs;
|
||||
int haveCaps;
|
||||
char *currentCaps;
|
||||
ARGV_t docDirs;
|
||||
|
||||
FileListRec fileList;
|
||||
|
@ -756,6 +759,74 @@ exit:
|
|||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse %caps from file manifest.
|
||||
* @param buf current spec file line
|
||||
* @param fl package file tree walk data
|
||||
* @return RPMRC_OK on success
|
||||
*/
|
||||
static rpmRC parseForCaps(const char * buf, FileList fl)
|
||||
{
|
||||
char *p, *pe, *q = NULL;
|
||||
const char *name;
|
||||
rpmRC rc = RPMRC_FAIL;
|
||||
|
||||
if ((p = strstr(buf, (name = "%caps"))) == NULL)
|
||||
return RPMRC_OK;
|
||||
|
||||
/* Erase "%caps" token. */
|
||||
for (pe = p; (pe-p) < strlen(name); pe++)
|
||||
*pe = ' ';
|
||||
SKIPSPACE(pe);
|
||||
if (*pe != '(')
|
||||
return RPMRC_OK;
|
||||
|
||||
/* Bracket %caps args */
|
||||
*pe++ = ' ';
|
||||
for (p = pe; *pe && *pe != ')'; pe++)
|
||||
{};
|
||||
|
||||
if (*pe == '\0') {
|
||||
rpmlog(RPMLOG_ERR, _("Missing ')' in %s(%s\n"), name, p);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Localize. Erase parsed string. */
|
||||
q = xmalloc((pe-p) + 1);
|
||||
rstrlcpy(q, p, (pe-p) + 1);
|
||||
while (p <= pe)
|
||||
*p++ = ' ';
|
||||
|
||||
#if WITH_CAP
|
||||
{
|
||||
char *captxt = NULL;
|
||||
cap_t fcaps = cap_from_text(q);
|
||||
if (fcaps == NULL) {
|
||||
rpmlog(RPMLOG_ERR, _("Invalid capability: %s\n"), q);
|
||||
goto exit;
|
||||
}
|
||||
/* run our string through cap_to_text() to get libcap presentation */
|
||||
captxt = cap_to_text(fcaps, NULL);
|
||||
fl->currentCaps = xstrdup(captxt);
|
||||
fl->haveCaps = 1;
|
||||
cap_free(captxt);
|
||||
cap_free(fcaps);
|
||||
}
|
||||
#else
|
||||
rpmlog(RPMLOG_ERR, _("File capability support not built in\n"));
|
||||
goto exit;
|
||||
#endif
|
||||
|
||||
rc = RPMRC_OK;
|
||||
|
||||
exit:
|
||||
free(q);
|
||||
if (rc != RPMRC_OK) {
|
||||
fl->processingFailed = 1;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
/**
|
||||
*/
|
||||
static VFA_t virtualFileAttributes[] = {
|
||||
|
@ -1112,6 +1183,10 @@ static void genCpioListAndHeader(FileList fl,
|
|||
}
|
||||
|
||||
headerPutString(h, RPMTAG_FILELANGS, flp->langs);
|
||||
|
||||
if (fl->haveCaps) {
|
||||
headerPutString(h, RPMTAG_FILECAPS, flp->caps);
|
||||
}
|
||||
|
||||
buf[0] = '\0';
|
||||
if (S_ISREG(flp->fl_mode))
|
||||
|
@ -1162,6 +1237,10 @@ static void genCpioListAndHeader(FileList fl,
|
|||
rpmlibNeedsFeature(h, "FileDigests", "4.4.90-1");
|
||||
}
|
||||
|
||||
if (fl->haveCaps) {
|
||||
rpmlibNeedsFeature(h, "FileCaps", "4.6.1-1");
|
||||
}
|
||||
|
||||
if (_addDotSlash)
|
||||
(void) rpmlibNeedsFeature(h, "PayloadFilesHavePrefix", "4.0-1");
|
||||
|
||||
|
@ -1274,6 +1353,7 @@ static FileListRec freeFileList(FileListRec fileList,
|
|||
fileList[count].diskPath = _free(fileList[count].diskPath);
|
||||
fileList[count].cpioPath = _free(fileList[count].cpioPath);
|
||||
fileList[count].langs = _free(fileList[count].langs);
|
||||
fileList[count].caps = _free(fileList[count].caps);
|
||||
}
|
||||
fileList = _free(fileList);
|
||||
return NULL;
|
||||
|
@ -1435,6 +1515,12 @@ static rpmRC addFile(FileList fl, const char * diskPath,
|
|||
flp->langs = xstrdup("");
|
||||
}
|
||||
|
||||
if (fl->currentCaps) {
|
||||
flp->caps = fl->currentCaps;
|
||||
} else {
|
||||
flp->caps = xstrdup("");
|
||||
}
|
||||
|
||||
flp->flags = fl->currentFlags;
|
||||
flp->specdFlags = fl->currentSpecdFlags;
|
||||
flp->verifyFlags = fl->currentVerifyFlags;
|
||||
|
@ -1764,6 +1850,8 @@ static rpmRC processPackageFiles(rpmSpec spec, Package pkg,
|
|||
fl.defVerifyFlags = RPMVERIFY_ALL;
|
||||
fl.nLangs = 0;
|
||||
fl.currentLangs = NULL;
|
||||
fl.haveCaps = 0;
|
||||
fl.currentCaps = NULL;
|
||||
|
||||
fl.currentSpecdFlags = 0;
|
||||
fl.defSpecdFlags = 0;
|
||||
|
@ -1813,6 +1901,7 @@ static rpmRC processPackageFiles(rpmSpec spec, Package pkg,
|
|||
fl.currentLangs = _free(fl.currentLangs);
|
||||
}
|
||||
fl.nLangs = 0;
|
||||
fl.currentCaps = NULL;
|
||||
|
||||
dupAttrRec(&fl.def_ar, &fl.cur_ar);
|
||||
|
||||
|
@ -1826,6 +1915,8 @@ static rpmRC processPackageFiles(rpmSpec spec, Package pkg,
|
|||
continue;
|
||||
if (parseForLang(buf, &fl))
|
||||
continue;
|
||||
if (parseForCaps(buf, &fl))
|
||||
continue;
|
||||
if (parseForSimple(spec, pkg, buf, &fl, &fileName))
|
||||
continue;
|
||||
if (fileName == NULL)
|
||||
|
|
|
@ -1034,6 +1034,11 @@ static const struct rpmlibProvides_s rpmlibProvides[] = {
|
|||
{ "rpmlib(FileDigests)", "4.4.90-1",
|
||||
( RPMSENSE_EQUAL),
|
||||
N_("file checksum digest algorithm is per package configurable") },
|
||||
#ifdef WITH_CAP
|
||||
{ "rpmlib(FileCaps)", "4.6.1-1",
|
||||
( RPMSENSE_EQUAL),
|
||||
N_("support for POSIX.1e file capabilities") },
|
||||
#endif
|
||||
{ NULL, NULL, 0, NULL }
|
||||
};
|
||||
|
||||
|
|
|
@ -280,6 +280,7 @@ typedef enum rpmTag_e {
|
|||
RPMTAG_ORIGFILENAMES = 5007, /* s[] extension */
|
||||
RPMTAG_LONGFILESIZES = 5008, /* l[] */
|
||||
RPMTAG_LONGSIZE = 5009, /* l */
|
||||
RPMTAG_FILECAPS = 5010, /* s[] */
|
||||
|
||||
RPMTAG_FIRSTFREE_TAG /*!< internal */
|
||||
} rpmTag;
|
||||
|
|
Loading…
Reference in New Issue