diff --git a/src/audit.c b/src/audit.c index 296684f..d6a66b7 100644 --- a/src/audit.c +++ b/src/audit.c @@ -38,6 +38,8 @@ static int audit_file(struct apk_database *db, struct apk_db_file *dbf, if (S_ISLNK(fi.mode) && dbf->csum.type == APK_CHECKSUM_NONE) return 0; + /* FIXME: check uid/gid/mode; but they are not in DB */ + return 1; } @@ -74,8 +76,10 @@ static int audit_directory(apk_hash_item item, void *ctx) continue; if (S_ISDIR(fi.mode)) { - if (apk_db_dir_query(db, APK_BLOB_STR(tmp)) != NULL) + if (apk_db_dir_query(db, APK_BLOB_STR(tmp)) != NULL) { + /* FIXME: check uid/gid/mode */ continue; + } reason = 'D'; } else { diff --git a/src/database.c b/src/database.c index 1ced84f..ec92197 100644 --- a/src/database.c +++ b/src/database.c @@ -220,6 +220,13 @@ struct apk_name *apk_db_get_name(struct apk_database *db, apk_blob_t name) static void apk_db_dir_mkdir(struct apk_database *db, struct apk_db_dir *dir) { + if (apk_flags & APK_SIMULATE) + return; + + /* Don't mess with root, as no package provides it directly */ + if (dir->namelen == 0) + return; + if ((dir->refs == 1) || (fchmodat(db->root_fd, dir->name, dir->mode, AT_SYMLINK_NOFOLLOW) != 0 && errno == ENOENT)) @@ -363,19 +370,14 @@ static void apk_db_dir_apply_diri_permissions(struct apk_db_dir_instance *diri) { struct apk_db_dir *dir = diri->dir; - if (diri->uid < dir->uid) { + if (diri->uid < dir->uid || + (diri->uid == dir->uid && diri->gid < dir->gid)) { dir->uid = diri->uid; - dir->mode = (dir->mode & ~S_IRWXU) | (diri->mode & S_IRWXU); - } else if (diri->uid == dir->uid) { - dir->mode |= diri->mode & S_IRWXU; - } - if (diri->gid < dir->gid) { dir->gid = diri->gid; - dir->mode = (dir->mode & ~S_IRWXG) | (diri->mode & S_IRWXG); - } else if (diri->gid == dir->gid) { - dir->mode |= diri->mode & S_IRWXG; + dir->mode = diri->mode; + } else if (diri->uid == dir->uid && diri->gid == dir->gid) { + dir->mode &= diri->mode; } - dir->mode |= diri->mode & S_IRWXO; } static void apk_db_diri_set(struct apk_db_dir_instance *diri, mode_t mode, diff --git a/src/fix.c b/src/fix.c index 4798ebe..e3fea11 100644 --- a/src/fix.c +++ b/src/fix.c @@ -21,6 +21,7 @@ struct fix_ctx { unsigned short solver_flags; int fix_depends : 1; + int fix_directory_permissions : 1; }; static int fix_parse(void *pctx, struct apk_db_options *dbopts, @@ -37,12 +38,22 @@ static int fix_parse(void *pctx, struct apk_db_options *dbopts, case 'r': ctx->solver_flags |= APK_SOLVERF_REINSTALL; break; + case 0x10000: + ctx->fix_directory_permissions = 1; + break; default: return -1; } return 0; } +static int mark_recalculate(apk_hash_item item, void *ctx) +{ + struct apk_db_dir *dir = (struct apk_db_dir *) item; + dir->flags |= APK_DBDIRF_RECALC_MODE; + return 0; +} + static int fix_main(void *pctx, struct apk_database *db, int argc, char **argv) { struct fix_ctx *ctx = (struct fix_ctx *) pctx; @@ -53,6 +64,9 @@ static int fix_main(void *pctx, struct apk_database *db, int argc, char **argv) if (!ctx->solver_flags) ctx->solver_flags = APK_SOLVERF_REINSTALL; + if (ctx->fix_directory_permissions) + apk_hash_foreach(&db->installed.dirs, mark_recalculate, db); + for (i = 0; i < argc; i++) { pkg = NULL; if (strstr(argv[i], ".apk") != NULL) { @@ -95,6 +109,7 @@ static struct apk_option fix_options[] = { { 'd', "depends", "Fix all dependencies too" }, { 'u', "upgrade", "Upgrade package if possible" }, { 'r', "reinstall", "Reinstall the package" }, + { 0x10000, "directory-permissions", "Reset all directory permissions" }, }; static struct apk_applet apk_fix = {