diff options
-rw-r--r-- | .SRCINFO | 70 | ||||
-rw-r--r-- | 0001-libmount-don-t-use-symfollow-for-helpers-on-user-mounts.patch | 3277 | ||||
-rw-r--r-- | 60-rfkill.rules | 1 | ||||
-rw-r--r-- | PKGBUILD | 185 | ||||
-rw-r--r-- | pam-common | 6 | ||||
-rw-r--r-- | pam-login | 7 | ||||
-rw-r--r-- | pam-runuser | 4 | ||||
-rw-r--r-- | pam-su | 9 | ||||
-rw-r--r-- | util-linux.sysusers | 3 |
9 files changed, 3562 insertions, 0 deletions
diff --git a/.SRCINFO b/.SRCINFO new file mode 100644 index 000000000000..7bd544b7b968 --- /dev/null +++ b/.SRCINFO @@ -0,0 +1,70 @@ +pkgbase = util-linux-nosystemd-minimal-git + pkgdesc = Miscellaneous system utilities for Linux + pkgver = 2.36.1 + pkgrel = 1 + url = https://www.kernel.org/pub/linux/utils/util-linux + arch = x86_64 + license = GPL2 + makedepends = python + makedepends = libcap-ng + makedepends = libxcrypt + options = strip + source = git+https://github.com/karelzak/util-linux.git + source = pam-login + source = pam-common + source = pam-runuser + source = pam-su + source = 60-rfkill.rules + source = util-linux.sysusers + source = 0001-libmount-don-t-use-symfollow-for-helpers-on-user-mounts.patch + sha256sums = SKIP + sha256sums = SKIP + sha256sums = SKIP + sha256sums = SKIP + sha256sums = SKIP + sha256sums = SKIP + sha256sums = SKIP + sha256sums = SKIP + +pkgname = util-linux-nosystemd-minimal-git + groups = base + groups = base-devel + depends = pam + depends = shadow + depends = coreutils + depends = libutil-linux + depends = libeudev + depends = libcap-ng + depends = libxcrypt + depends = libcrypt.so + depends = libmagic.so + depends = libncursesw.so + depends = libreadline.so + optdepends = python: python bindings to libmount + optdepends = words: default dictionary for look + provides = rfkill + provides = util-linux + conflicts = rfkill + conflicts = util-linux + replaces = rfkill + backup = etc/pam.d/chfn + backup = etc/pam.d/chsh + backup = etc/pam.d/login + backup = etc/pam.d/runuser + backup = etc/pam.d/runuser-l + backup = etc/pam.d/su + backup = etc/pam.d/su-l + +pkgname = util-linux-libs-nosystemd-minimal-git + pkgdesc = util-linux runtime libraries + provides = util-linux-libs + provides = libutil-linux + provides = libblkid.so + provides = libfdisk.so + provides = libmount.so + provides = libsmartcols.so + provides = libuuid.so + conflicts = libutil-linux + conflicts = util-linux-libs + replaces = libutil-linux + diff --git a/0001-libmount-don-t-use-symfollow-for-helpers-on-user-mounts.patch b/0001-libmount-don-t-use-symfollow-for-helpers-on-user-mounts.patch new file mode 100644 index 000000000000..a4377ece4dfd --- /dev/null +++ b/0001-libmount-don-t-use-symfollow-for-helpers-on-user-mounts.patch @@ -0,0 +1,3277 @@ +diff -Nuar -uar a/libmount/src/context_mount.c b/libmount/src/context_mount.c +--- a/libmount/src/context_mount.c 2020-11-13 22:00:15.000000000 +1100 ++++ b/libmount/src/context_mount.c 2020-12-21 12:32:20.836075130 +1100 +@@ -38,37 +38,37 @@ + */ + struct libmnt_addmount *mnt_new_addmount(void) + { +- struct libmnt_addmount *ad = calloc(1, sizeof(*ad)); +- if (!ad) +- return NULL; ++ struct libmnt_addmount *ad = calloc(1, sizeof(*ad)); ++ if (!ad) ++ return NULL; + +- INIT_LIST_HEAD(&ad->mounts); +- return ad; ++ INIT_LIST_HEAD(&ad->mounts); ++ return ad; + } + + void mnt_free_addmount(struct libmnt_addmount *ad) + { +- if (!ad) +- return; +- list_del(&ad->mounts); +- free(ad); ++ if (!ad) ++ return; ++ list_del(&ad->mounts); ++ free(ad); + } + + static int mnt_context_append_additional_mount(struct libmnt_context *cxt, +- struct libmnt_addmount *ad) ++ struct libmnt_addmount *ad) + { +- assert(cxt); +- assert(ad); ++ assert(cxt); ++ assert(ad); + +- if (!list_empty(&ad->mounts)) +- return -EINVAL; ++ if (!list_empty(&ad->mounts)) ++ return -EINVAL; + +- DBG(CXT, ul_debugobj(cxt, +- "mount: add additional flag: 0x%08lx", +- ad->mountflags)); ++ DBG(CXT, ul_debugobj(cxt, ++ "mount: add additional flag: 0x%08lx", ++ ad->mountflags)); + +- list_add_tail(&ad->mounts, &cxt->addmounts); +- return 0; ++ list_add_tail(&ad->mounts, &cxt->addmounts); ++ return 0; + } + + /* +@@ -77,60 +77,60 @@ + */ + static int init_propagation(struct libmnt_context *cxt) + { +- char *name; +- char *opts = (char *) mnt_fs_get_vfs_options(cxt->fs); +- size_t namesz; +- struct libmnt_optmap const *maps[1]; +- int rec_count = 0; ++ char *name; ++ char *opts = (char *) mnt_fs_get_vfs_options(cxt->fs); ++ size_t namesz; ++ struct libmnt_optmap const *maps[1]; ++ int rec_count = 0; + +- if (!opts) +- return 0; ++ if (!opts) ++ return 0; + +- DBG(CXT, ul_debugobj(cxt, "mount: initialize additional propagation mounts")); ++ DBG(CXT, ul_debugobj(cxt, "mount: initialize additional propagation mounts")); + +- maps[0] = mnt_get_builtin_optmap(MNT_LINUX_MAP); ++ maps[0] = mnt_get_builtin_optmap(MNT_LINUX_MAP); + +- while (!mnt_optstr_next_option(&opts, &name, &namesz, NULL, NULL)) { +- const struct libmnt_optmap *ent; +- struct libmnt_addmount *ad; +- int rc; ++ while (!mnt_optstr_next_option(&opts, &name, &namesz, NULL, NULL)) { ++ const struct libmnt_optmap *ent; ++ struct libmnt_addmount *ad; ++ int rc; + +- if (!mnt_optmap_get_entry(maps, 1, name, namesz, &ent) || !ent) +- continue; ++ if (!mnt_optmap_get_entry(maps, 1, name, namesz, &ent) || !ent) ++ continue; + +- DBG(CXT, ul_debugobj(cxt, " checking %s", ent->name)); ++ DBG(CXT, ul_debugobj(cxt, " checking %s", ent->name)); + +- /* Note that MS_REC may be used for more flags, so we have to keep +- * track about number of recursive options to keep the MS_REC in the +- * mountflags if necessary. +- */ +- if (ent->id & MS_REC) +- rec_count++; ++ /* Note that MS_REC may be used for more flags, so we have to keep ++ * track about number of recursive options to keep the MS_REC in the ++ * mountflags if necessary. ++ */ ++ if (ent->id & MS_REC) ++ rec_count++; + +- if (!(ent->id & MS_PROPAGATION)) +- continue; ++ if (!(ent->id & MS_PROPAGATION)) ++ continue; + +- ad = mnt_new_addmount(); +- if (!ad) +- return -ENOMEM; ++ ad = mnt_new_addmount(); ++ if (!ad) ++ return -ENOMEM; + +- ad->mountflags = ent->id; +- DBG(CXT, ul_debugobj(cxt, " adding extra mount(2) call for %s", ent->name)); +- rc = mnt_context_append_additional_mount(cxt, ad); +- if (rc) +- return rc; ++ ad->mountflags = ent->id; ++ DBG(CXT, ul_debugobj(cxt, " adding extra mount(2) call for %s", ent->name)); ++ rc = mnt_context_append_additional_mount(cxt, ad); ++ if (rc) ++ return rc; + +- DBG(CXT, ul_debugobj(cxt, " removing %s from primary mount(2) call", ent->name)); +- cxt->mountflags &= ~ent->id; ++ DBG(CXT, ul_debugobj(cxt, " removing %s from primary mount(2) call", ent->name)); ++ cxt->mountflags &= ~ent->id; + +- if (ent->id & MS_REC) +- rec_count--; +- } ++ if (ent->id & MS_REC) ++ rec_count--; ++ } + +- if (rec_count) +- cxt->mountflags |= MS_REC; ++ if (rec_count) ++ cxt->mountflags |= MS_REC; + +- return 0; ++ return 0; + } + + /* +@@ -139,50 +139,50 @@ + */ + static int init_bind_remount(struct libmnt_context *cxt) + { +- struct libmnt_addmount *ad; +- int rc; ++ struct libmnt_addmount *ad; ++ int rc; + +- assert(cxt); +- assert(cxt->mountflags & MS_BIND); +- assert(!(cxt->mountflags & MS_REMOUNT)); ++ assert(cxt); ++ assert(cxt->mountflags & MS_BIND); ++ assert(!(cxt->mountflags & MS_REMOUNT)); + +- DBG(CXT, ul_debugobj(cxt, "mount: initialize additional ro,bind mount")); ++ DBG(CXT, ul_debugobj(cxt, "mount: initialize additional ro,bind mount")); + +- ad = mnt_new_addmount(); +- if (!ad) +- return -ENOMEM; ++ ad = mnt_new_addmount(); ++ if (!ad) ++ return -ENOMEM; + +- ad->mountflags = cxt->mountflags; +- ad->mountflags |= (MS_REMOUNT | MS_BIND); ++ ad->mountflags = cxt->mountflags; ++ ad->mountflags |= (MS_REMOUNT | MS_BIND); + +- rc = mnt_context_append_additional_mount(cxt, ad); +- if (rc) +- return rc; ++ rc = mnt_context_append_additional_mount(cxt, ad); ++ if (rc) ++ return rc; + +- return 0; ++ return 0; + } + + #if defined(HAVE_LIBSELINUX) || defined(HAVE_SMACK) + struct libmnt_optname { +- const char *name; +- size_t namesz; ++ const char *name; ++ size_t namesz; + }; + +-#define DEF_OPTNAME(n) { .name = n, .namesz = sizeof(n) - 1 } +-#define DEF_OPTNAME_LAST { .name = NULL } ++#define DEF_OPTNAME(n) { .name = n, .namesz = sizeof(n) - 1 } ++#define DEF_OPTNAME_LAST { .name = NULL } + + static int is_option(const char *name, size_t namesz, +- const struct libmnt_optname *names) ++ const struct libmnt_optname *names) + { +- const struct libmnt_optname *p; ++ const struct libmnt_optname *p; + +- for (p = names; p && p->name; p++) { +- if (p->namesz == namesz +- && strncmp(name, p->name, namesz) == 0) +- return 1; +- } ++ for (p = names; p && p->name; p++) { ++ if (p->namesz == namesz ++ && strncmp(name, p->name, namesz) == 0) ++ return 1; ++ } + +- return 0; ++ return 0; + } + #endif /* HAVE_LIBSELINUX || HAVE_SMACK */ + +@@ -191,194 +191,194 @@ + */ + static int fix_optstr(struct libmnt_context *cxt) + { +- int rc = 0; +- struct libmnt_ns *ns_old; +- char *next; +- char *name, *val; +- size_t namesz, valsz; +- struct libmnt_fs *fs; ++ int rc = 0; ++ struct libmnt_ns *ns_old; ++ char *next; ++ char *name, *val; ++ size_t namesz, valsz; ++ struct libmnt_fs *fs; + #ifdef HAVE_LIBSELINUX +- int se_fix = 0, se_rem = 0; +- static const struct libmnt_optname selinux_options[] = { +- DEF_OPTNAME("context"), +- DEF_OPTNAME("fscontext"), +- DEF_OPTNAME("defcontext"), +- DEF_OPTNAME("rootcontext"), +- DEF_OPTNAME("seclabel"), +- DEF_OPTNAME_LAST +- }; ++ int se_fix = 0, se_rem = 0; ++ static const struct libmnt_optname selinux_options[] = { ++ DEF_OPTNAME("context"), ++ DEF_OPTNAME("fscontext"), ++ DEF_OPTNAME("defcontext"), ++ DEF_OPTNAME("rootcontext"), ++ DEF_OPTNAME("seclabel"), ++ DEF_OPTNAME_LAST ++ }; + #endif + #ifdef HAVE_SMACK +- int sm_rem = 0; +- static const struct libmnt_optname smack_options[] = { +- DEF_OPTNAME("smackfsdef"), +- DEF_OPTNAME("smackfsfloor"), +- DEF_OPTNAME("smackfshat"), +- DEF_OPTNAME("smackfsroot"), +- DEF_OPTNAME("smackfstransmute"), +- DEF_OPTNAME_LAST +- }; ++ int sm_rem = 0; ++ static const struct libmnt_optname smack_options[] = { ++ DEF_OPTNAME("smackfsdef"), ++ DEF_OPTNAME("smackfsfloor"), ++ DEF_OPTNAME("smackfshat"), ++ DEF_OPTNAME("smackfsroot"), ++ DEF_OPTNAME("smackfstransmute"), ++ DEF_OPTNAME_LAST ++ }; + #endif +- assert(cxt); +- assert((cxt->flags & MNT_FL_MOUNTFLAGS_MERGED)); ++ assert(cxt); ++ assert((cxt->flags & MNT_FL_MOUNTFLAGS_MERGED)); + +- if (!cxt->fs || (cxt->flags & MNT_FL_MOUNTOPTS_FIXED)) +- return 0; ++ if (!cxt->fs || (cxt->flags & MNT_FL_MOUNTOPTS_FIXED)) ++ return 0; + +- fs = cxt->fs; ++ fs = cxt->fs; + +- DBG(CXT, ul_debugobj(cxt, "mount: fixing options, current " +- "vfs: '%s' fs: '%s' user: '%s', optstr: '%s'", +- fs->vfs_optstr, fs->fs_optstr, fs->user_optstr, fs->optstr)); +- +- /* +- * The "user" options is our business (so we can modify the option), +- * the exception is command line for /sbin/mount.<type> helpers. Let's +- * save the original user=<name> to call the helpers with an unchanged +- * "user" setting. +- */ +- if (cxt->user_mountflags & MNT_MS_USER) { +- if (!mnt_optstr_get_option(fs->user_optstr, +- "user", &val, &valsz) && val) { +- cxt->orig_user = strndup(val, valsz); +- if (!cxt->orig_user) { +- rc = -ENOMEM; +- goto done; +- } +- } +- cxt->flags |= MNT_FL_SAVED_USER; +- } +- +- /* +- * Sync mount options with mount flags +- */ +- DBG(CXT, ul_debugobj(cxt, "mount: fixing vfs optstr")); +- rc = mnt_optstr_apply_flags(&fs->vfs_optstr, cxt->mountflags, +- mnt_get_builtin_optmap(MNT_LINUX_MAP)); +- if (rc) +- goto done; +- +- DBG(CXT, ul_debugobj(cxt, "mount: fixing user optstr")); +- rc = mnt_optstr_apply_flags(&fs->user_optstr, cxt->user_mountflags, +- mnt_get_builtin_optmap(MNT_USERSPACE_MAP)); +- if (rc) +- goto done; +- +- if (fs->vfs_optstr && *fs->vfs_optstr == '\0') { +- free(fs->vfs_optstr); +- fs->vfs_optstr = NULL; +- } +- if (fs->user_optstr && *fs->user_optstr == '\0') { +- free(fs->user_optstr); +- fs->user_optstr = NULL; +- } +- if (cxt->mountflags & MS_PROPAGATION) { +- rc = init_propagation(cxt); +- if (rc) +- return rc; +- } +- if ((cxt->mountflags & MS_BIND) +- && (cxt->mountflags & MNT_BIND_SETTABLE) +- && !(cxt->mountflags & MS_REMOUNT)) { +- rc = init_bind_remount(cxt); +- if (rc) +- return rc; +- } ++ DBG(CXT, ul_debugobj(cxt, "mount: fixing options, current " ++ "vfs: '%s' fs: '%s' user: '%s', optstr: '%s'", ++ fs->vfs_optstr, fs->fs_optstr, fs->user_optstr, fs->optstr)); ++ ++ /* ++ * The "user" options is our business (so we can modify the option), ++ * the exception is command line for /sbin/mount.<type> helpers. Let's ++ * save the original user=<name> to call the helpers with an unchanged ++ * "user" setting. ++ */ ++ if (cxt->user_mountflags & MNT_MS_USER) { ++ if (!mnt_optstr_get_option(fs->user_optstr, ++ "user", &val, &valsz) && val) { ++ cxt->orig_user = strndup(val, valsz); ++ if (!cxt->orig_user) { ++ rc = -ENOMEM; ++ goto done; ++ } ++ } ++ cxt->flags |= MNT_FL_SAVED_USER; ++ } ++ ++ /* ++ * Sync mount options with mount flags ++ */ ++ DBG(CXT, ul_debugobj(cxt, "mount: fixing vfs optstr")); ++ rc = mnt_optstr_apply_flags(&fs->vfs_optstr, cxt->mountflags, ++ mnt_get_builtin_optmap(MNT_LINUX_MAP)); ++ if (rc) ++ goto done; ++ ++ DBG(CXT, ul_debugobj(cxt, "mount: fixing user optstr")); ++ rc = mnt_optstr_apply_flags(&fs->user_optstr, cxt->user_mountflags, ++ mnt_get_builtin_optmap(MNT_USERSPACE_MAP)); ++ if (rc) ++ goto done; ++ ++ if (fs->vfs_optstr && *fs->vfs_optstr == '\0') { ++ free(fs->vfs_optstr); ++ fs->vfs_optstr = NULL; ++ } ++ if (fs->user_optstr && *fs->user_optstr == '\0') { ++ free(fs->user_optstr); ++ fs->user_optstr = NULL; ++ } ++ if (cxt->mountflags & MS_PROPAGATION) { ++ rc = init_propagation(cxt); ++ if (rc) ++ return rc; ++ } ++ if ((cxt->mountflags & MS_BIND) ++ && (cxt->mountflags & MNT_BIND_SETTABLE) ++ && !(cxt->mountflags & MS_REMOUNT)) { ++ rc = init_bind_remount(cxt); ++ if (rc) ++ return rc; ++ } + +- next = fs->fs_optstr; ++ next = fs->fs_optstr; + + #ifdef HAVE_LIBSELINUX +- if (!is_selinux_enabled()) +- /* Always remove SELinux garbage if SELinux disabled */ +- se_rem = 1; +- else if (cxt->mountflags & MS_REMOUNT) +- /* +- * Linux kernel < 2.6.39 does not support remount operation +- * with any selinux specific mount options. +- * +- * Kernel 2.6.39 commits: ff36fe2c845cab2102e4826c1ffa0a6ebf487c65 +- * 026eb167ae77244458fa4b4b9fc171209c079ba7 +- * fix this odd behavior, so we don't have to care about it in +- * userspace. +- */ +- se_rem = get_linux_version() < KERNEL_VERSION(2, 6, 39); +- else +- /* For normal mount, contexts are translated */ +- se_fix = 1; +- +- if (!se_rem) { +- /* de-duplicate SELinux options */ +- const struct libmnt_optname *p; +- for (p = selinux_options; p && p->name; p++) +- mnt_optstr_deduplicate_option(&fs->fs_optstr, p->name); +- } ++ if (!is_selinux_enabled()) ++ /* Always remove SELinux garbage if SELinux disabled */ ++ se_rem = 1; ++ else if (cxt->mountflags & MS_REMOUNT) ++ /* ++ * Linux kernel < 2.6.39 does not support remount operation ++ * with any selinux specific mount options. ++ * ++ * Kernel 2.6.39 commits: ff36fe2c845cab2102e4826c1ffa0a6ebf487c65 ++ * 026eb167ae77244458fa4b4b9fc171209c079ba7 ++ * fix this odd behavior, so we don't have to care about it in ++ * userspace. ++ */ ++ se_rem = get_linux_version() < KERNEL_VERSION(2, 6, 39); ++ else ++ /* For normal mount, contexts are translated */ ++ se_fix = 1; ++ ++ if (!se_rem) { ++ /* de-duplicate SELinux options */ ++ const struct libmnt_optname *p; ++ for (p = selinux_options; p && p->name; p++) ++ mnt_optstr_deduplicate_option(&fs->fs_optstr, p->name); ++ } + #endif + #ifdef HAVE_SMACK +- if (access("/sys/fs/smackfs", F_OK) != 0) +- sm_rem = 1; ++ if (access("/sys/fs/smackfs", F_OK) != 0) ++ sm_rem = 1; + #endif +- while (!mnt_optstr_next_option(&next, &name, &namesz, &val, &valsz)) { ++ while (!mnt_optstr_next_option(&next, &name, &namesz, &val, &valsz)) { + +- if (namesz == 3 && !strncmp(name, "uid", 3)) +- rc = mnt_optstr_fix_uid(&fs->fs_optstr, val, valsz, &next); +- else if (namesz == 3 && !strncmp(name, "gid", 3)) +- rc = mnt_optstr_fix_gid(&fs->fs_optstr, val, valsz, &next); ++ if (namesz == 3 && !strncmp(name, "uid", 3)) ++ rc = mnt_optstr_fix_uid(&fs->fs_optstr, val, valsz, &next); ++ else if (namesz == 3 && !strncmp(name, "gid", 3)) ++ rc = mnt_optstr_fix_gid(&fs->fs_optstr, val, valsz, &next); + #ifdef HAVE_LIBSELINUX +- else if ((se_rem || se_fix) +- && is_option(name, namesz, selinux_options)) { ++ else if ((se_rem || se_fix) ++ && is_option(name, namesz, selinux_options)) { + +- if (se_rem) { +- /* remove context= option */ +- next = name; +- rc = mnt_optstr_remove_option_at(&fs->fs_optstr, +- name, +- val ? val + valsz : +- name + namesz); +- } else if (se_fix && val && valsz) +- /* translate selinux contexts */ +- rc = mnt_optstr_fix_secontext(&fs->fs_optstr, +- val, valsz, &next); +- } ++ if (se_rem) { ++ /* remove context= option */ ++ next = name; ++ rc = mnt_optstr_remove_option_at(&fs->fs_optstr, ++ name, ++ val ? val + valsz : ++ name + namesz); ++ } else if (se_fix && val && valsz) ++ /* translate selinux contexts */ ++ rc = mnt_optstr_fix_secontext(&fs->fs_optstr, ++ val, valsz, &next); ++ } + #endif + #ifdef HAVE_SMACK +- else if (sm_rem && is_option(name, namesz, smack_options)) { ++ else if (sm_rem && is_option(name, namesz, smack_options)) { + +- next = name; +- rc = mnt_optstr_remove_option_at(&fs->fs_optstr, +- name, +- val ? val + valsz : name + namesz); +- } ++ next = name; ++ rc = mnt_optstr_remove_option_at(&fs->fs_optstr, ++ name, ++ val ? val + valsz : name + namesz); ++ } + #endif +- if (rc) +- goto done; +- } +- +- +- if (!rc && mnt_context_is_restricted(cxt) && (cxt->user_mountflags & MNT_MS_USER)) { +- ns_old = mnt_context_switch_origin_ns(cxt); +- if (!ns_old) +- return -MNT_ERR_NAMESPACE; +- +- rc = mnt_optstr_fix_user(&fs->user_optstr); +- +- if (!mnt_context_switch_ns(cxt, ns_old)) +- return -MNT_ERR_NAMESPACE; +- } +- +- /* refresh merged optstr */ +- free(fs->optstr); +- fs->optstr = NULL; +- fs->optstr = mnt_fs_strdup_options(fs); ++ if (rc) ++ goto done; ++ } ++ ++ ++ if (!rc && mnt_context_is_restricted(cxt) && (cxt->user_mountflags & MNT_MS_USER)) { ++ ns_old = mnt_context_switch_origin_ns(cxt); ++ if (!ns_old) ++ return -MNT_ERR_NAMESPACE; ++ ++ rc = mnt_optstr_fix_user(&fs->user_optstr); ++ ++ if (!mnt_context_switch_ns(cxt, ns_old)) ++ return -MNT_ERR_NAMESPACE; ++ } ++ ++ /* refresh merged optstr */ ++ free(fs->optstr); ++ fs->optstr = NULL; ++ fs->optstr = mnt_fs_strdup_options(fs); + done: +- cxt->flags |= MNT_FL_MOUNTOPTS_FIXED; ++ cxt->flags |= MNT_FL_MOUNTOPTS_FIXED; + +- DBG(CXT, ul_debugobj(cxt, "fixed options [rc=%d]: " +- "vfs: '%s' fs: '%s' user: '%s', optstr: '%s'", rc, +- fs->vfs_optstr, fs->fs_optstr, fs->user_optstr, fs->optstr)); +- +- if (rc) +- rc = -MNT_ERR_MOUNTOPT; +- return rc; ++ DBG(CXT, ul_debugobj(cxt, "fixed options [rc=%d]: " ++ "vfs: '%s' fs: '%s' user: '%s', optstr: '%s'", rc, ++ fs->vfs_optstr, fs->fs_optstr, fs->user_optstr, fs->optstr)); ++ ++ if (rc) ++ rc = -MNT_ERR_MOUNTOPT; ++ return rc; + } + + /* +@@ -387,74 +387,74 @@ + */ + static int generate_helper_optstr(struct libmnt_context *cxt, char **optstr) + { +- struct libmnt_optmap const *maps[2]; +- char *next, *name, *val; +- size_t namesz, valsz; +- int rc = 0; +- +- assert(cxt); +- assert(cxt->fs); +- assert(optstr); +- +- DBG(CXT, ul_debugobj(cxt, "mount: generate helper mount options")); +- +- *optstr = mnt_fs_strdup_options(cxt->fs); +- if (!*optstr) +- return -ENOMEM; +- +- if ((cxt->user_mountflags & MNT_MS_USER) || +- (cxt->user_mountflags & MNT_MS_USERS)) { +- /* +- * This is unnecessary for real user-mounts as mount.<type> +- * helpers always have to follow fstab rather than mount +- * options on the command line. +- * +- * However, if you call mount.<type> as root, then the helper follows +- * the command line. If there is (for example) "user,exec" in fstab, +- * then we have to manually append the "exec" back to the options +- * string, because there is nothing like MS_EXEC (we only have +- * MS_NOEXEC in mount flags and we don't care about the original +- * mount string in libmount for VFS options). +- */ +- if (!(cxt->mountflags & MS_NOEXEC)) +- mnt_optstr_append_option(optstr, "exec", NULL); +- if (!(cxt->mountflags & MS_NOSUID)) +- mnt_optstr_append_option(optstr, "suid", NULL); +- if (!(cxt->mountflags & MS_NODEV)) +- mnt_optstr_append_option(optstr, "dev", NULL); +- if (!(cxt->mountflags & MS_NOSYMFOLLOW)) +- mnt_optstr_append_option(optstr, "symfollow", NULL); +- } +- +- +- if (cxt->flags & MNT_FL_SAVED_USER) +- rc = mnt_optstr_set_option(optstr, "user", cxt->orig_user); +- if (rc) +- goto err; +- +- /* remove userspace options with MNT_NOHLPS flag */ +- maps[0] = mnt_get_builtin_optmap(MNT_USERSPACE_MAP); +- maps[1] = mnt_get_builtin_optmap(MNT_LINUX_MAP); +- next = *optstr; +- +- while (!mnt_optstr_next_option(&next, &name, &namesz, &val, &valsz)) { +- const struct libmnt_optmap *ent; +- +- mnt_optmap_get_entry(maps, 2, name, namesz, &ent); +- if (ent && ent->id && (ent->mask & MNT_NOHLPS)) { +- next = name; +- rc = mnt_optstr_remove_option_at(optstr, name, +- val ? val + valsz : name + namesz); +- if (rc) +- goto err; +- } +- } ++ struct libmnt_optmap const *maps[2]; ++ char *next, *name, *val; ++ size_t namesz, valsz; ++ int rc = 0; ++ ++ assert(cxt); ++ assert(cxt->fs); ++ assert(optstr); ++ ++ DBG(CXT, ul_debugobj(cxt, "mount: generate helper mount options")); ++ ++ *optstr = mnt_fs_strdup_options(cxt->fs); ++ if (!*optstr) ++ return -ENOMEM; ++ ++ if ((cxt->user_mountflags & MNT_MS_USER) || ++ (cxt->user_mountflags & MNT_MS_USERS)) { ++ /* ++ * This is unnecessary for real user-mounts as mount.<type> ++ * helpers always have to follow fstab rather than mount ++ * options on the command line. ++ * ++ * However, if you call mount.<type> as root, then the helper follows ++ * the command line. If there is (for example) "user,exec" in fstab, ++ * then we have to manually append the "exec" back to the options ++ * string, because there is nothing like MS_EXEC (we only have ++ * MS_NOEXEC in mount flags and we don't care about the original ++ * mount string in libmount for VFS options). ++ * ++ * This use-case makes sense for MS_SECURE flags only (see +++ * mnt_optstr_get_flags() and mnt_context_merge_mflags()). ++ */ ++ if (!(cxt->mountflags & MS_NOEXEC)) ++ mnt_optstr_append_option(optstr, "exec", NULL); ++ if (!(cxt->mountflags & MS_NOSUID)) ++ mnt_optstr_append_option(optstr, "suid", NULL); ++ if (!(cxt->mountflags & MS_NODEV)) ++ mnt_optstr_append_option(optstr, "dev", NULL); ++ } ++ ++ if (cxt->flags & MNT_FL_SAVED_USER) ++ rc = mnt_optstr_set_option(optstr, "user", cxt->orig_user); ++ if (rc) ++ goto err; ++ ++ /* remove userspace options with MNT_NOHLPS flag */ ++ maps[0] = mnt_get_builtin_optmap(MNT_USERSPACE_MAP); ++ maps[1] = mnt_get_builtin_optmap(MNT_LINUX_MAP); ++ next = *optstr; ++ ++ while (!mnt_optstr_next_option(&next, &name, &namesz, &val, &valsz)) { ++ const struct libmnt_optmap *ent; ++ ++ mnt_optmap_get_entry(maps, 2, name, namesz, &ent); ++ if (ent && ent->id && (ent->mask & MNT_NOHLPS)) { ++ next = name; ++ rc = mnt_optstr_remove_option_at(optstr, name, ++ val ? val + valsz : name + namesz); ++ if (rc) ++ goto err; ++ } ++ } + +- return rc; ++ return rc; + err: +- free(*optstr); +- *optstr = NULL; +- return rc; ++ free(*optstr); ++ *optstr = NULL; ++ return rc; + } + + /* +@@ -466,95 +466,95 @@ + */ + static int evaluate_permissions(struct libmnt_context *cxt) + { +- unsigned long u_flags = 0; ++ unsigned long u_flags = 0; + +- assert(cxt); +- assert((cxt->flags & MNT_FL_MOUNTFLAGS_MERGED)); ++ assert(cxt); ++ assert((cxt->flags & MNT_FL_MOUNTFLAGS_MERGED)); + +- if (!cxt->fs) +- return 0; ++ if (!cxt->fs) ++ return 0; + +- DBG(CXT, ul_debugobj(cxt, "mount: evaluating permissions")); +- +- mnt_context_get_user_mflags(cxt, &u_flags); +- +- if (!mnt_context_is_restricted(cxt)) { +- /* +- * superuser mount +- */ +- cxt->user_mountflags &= ~MNT_MS_OWNER; +- cxt->user_mountflags &= ~MNT_MS_GROUP; +- } else { +- /* +- * user mount +- */ +- if (!mnt_context_tab_applied(cxt)) +- { +- DBG(CXT, ul_debugobj(cxt, "perms: fstab not applied, ignore user mount")); +- return -EPERM; +- } +- +- /* +- * MS_OWNERSECURE and MS_SECURE mount options are already +- * applied by mnt_optstr_get_flags() in mnt_context_merge_mflags() +- * if "user" (but no user=<name> !) options is set. +- * +- * Let's ignore all user=<name> (if <name> is set) requests. +- */ +- if (cxt->user_mountflags & MNT_MS_USER) { +- size_t valsz = 0; +- +- if (!mnt_optstr_get_option(cxt->fs->user_optstr, +- "user", NULL, &valsz) && valsz) { +- +- DBG(CXT, ul_debugobj(cxt, "perms: user=<name> detected, ignore")); +- cxt->user_mountflags &= ~MNT_MS_USER; +- } +- } +- +- /* +- * MS_OWNER: Allow owners to mount when fstab contains the +- * owner option. Note that this should never be used in a high +- * security environment, but may be useful to give people at +- * the console the possibility of mounting a floppy. MS_GROUP: +- * Allow members of device group to mount. (Martin Dickopp) +- */ +- if (u_flags & (MNT_MS_OWNER | MNT_MS_GROUP)) { +- struct stat sb; +- struct libmnt_cache *cache = NULL; +- char *xsrc = NULL; +- const char *srcpath = mnt_fs_get_srcpath(cxt->fs); +- +- if (!srcpath) { /* Ah... source is TAG */ +- cache = mnt_context_get_cache(cxt); +- xsrc = mnt_resolve_spec( +- mnt_context_get_source(cxt), +- cache); +- srcpath = xsrc; +- } +- if (!srcpath) { +- DBG(CXT, ul_debugobj(cxt, "perms: src undefined")); +- return -EPERM; +- } +- +- if (strncmp(srcpath, "/dev/", 5) == 0 && +- stat(srcpath, &sb) == 0 && +- (((u_flags & MNT_MS_OWNER) && getuid() == sb.st_uid) || +- ((u_flags & MNT_MS_GROUP) && mnt_in_group(sb.st_gid)))) +- +- cxt->user_mountflags |= MNT_MS_USER; +- +- if (!cache) +- free(xsrc); +- } +- +- if (!(cxt->user_mountflags & (MNT_MS_USER | MNT_MS_USERS))) { +- DBG(CXT, ul_debugobj(cxt, "permissions evaluation ends with -EPERMS")); +- return -EPERM; +- } +- } ++ DBG(CXT, ul_debugobj(cxt, "mount: evaluating permissions")); ++ ++ mnt_context_get_user_mflags(cxt, &u_flags); ++ ++ if (!mnt_context_is_restricted(cxt)) { ++ /* ++ * superuser mount ++ */ ++ cxt->user_mountflags &= ~MNT_MS_OWNER; ++ cxt->user_mountflags &= ~MNT_MS_GROUP; ++ } else { ++ /* ++ * user mount ++ */ ++ if (!mnt_context_tab_applied(cxt)) ++ { ++ DBG(CXT, ul_debugobj(cxt, "perms: fstab not applied, ignore user mount")); ++ return -EPERM; ++ } ++ ++ /* ++ * MS_OWNERSECURE and MS_SECURE mount options are already ++ * applied by mnt_optstr_get_flags() in mnt_context_merge_mflags() ++ * if "user" (but no user=<name> !) options is set. ++ * ++ * Let's ignore all user=<name> (if <name> is set) requests. ++ */ ++ if (cxt->user_mountflags & MNT_MS_USER) { ++ size_t valsz = 0; ++ ++ if (!mnt_optstr_get_option(cxt->fs->user_optstr, ++ "user", NULL, &valsz) && valsz) { ++ ++ DBG(CXT, ul_debugobj(cxt, "perms: user=<name> detected, ignore")); ++ cxt->user_mountflags &= ~MNT_MS_USER; ++ } ++ } ++ ++ /* ++ * MS_OWNER: Allow owners to mount when fstab contains the ++ * owner option. Note that this should never be used in a high ++ * security environment, but may be useful to give people at ++ * the console the possibility of mounting a floppy. MS_GROUP: ++ * Allow members of device group to mount. (Martin Dickopp) ++ */ ++ if (u_flags & (MNT_MS_OWNER | MNT_MS_GROUP)) { ++ struct stat sb; ++ struct libmnt_cache *cache = NULL; ++ char *xsrc = NULL; ++ const char *srcpath = mnt_fs_get_srcpath(cxt->fs); ++ ++ if (!srcpath) { /* Ah... source is TAG */ ++ cache = mnt_context_get_cache(cxt); ++ xsrc = mnt_resolve_spec( ++ mnt_context_get_source(cxt), ++ cache); ++ srcpath = xsrc; ++ } ++ if (!srcpath) { ++ DBG(CXT, ul_debugobj(cxt, "perms: src undefined")); ++ return -EPERM; ++ } ++ ++ if (strncmp(srcpath, "/dev/", 5) == 0 && ++ stat(srcpath, &sb) == 0 && ++ (((u_flags & MNT_MS_OWNER) && getuid() == sb.st_uid) || ++ ((u_flags & MNT_MS_GROUP) && mnt_in_group(sb.st_gid)))) ++ ++ cxt->user_mountflags |= MNT_MS_USER; ++ ++ if (!cache) ++ free(xsrc); ++ } ++ ++ if (!(cxt->user_mountflags & (MNT_MS_USER | MNT_MS_USERS))) { ++ DBG(CXT, ul_debugobj(cxt, "permissions evaluation ends with -EPERMS")); ++ return -EPERM; ++ } ++ } + +- return 0; ++ return 0; + } + + /* +@@ -568,191 +568,191 @@ + */ + int mnt_context_mount_setopt(struct libmnt_context *cxt, int c, char *arg) + { +- int rc = -EINVAL; ++ int rc = -EINVAL; + +- assert(cxt); +- assert(cxt->action == MNT_ACT_MOUNT); ++ assert(cxt); ++ assert(cxt->action == MNT_ACT_MOUNT); + +- switch(c) { +- case 'f': +- rc = mnt_context_enable_fake(cxt, TRUE); +- break; +- case 'n': +- rc = mnt_context_disable_mtab(cxt, TRUE); +- break; +- case 'r': +- rc = mnt_context_append_options(cxt, "ro"); +- break; +- case 'v': +- rc = mnt_context_enable_verbose(cxt, TRUE); +- break; +- case 'w': +- rc = mnt_context_append_options(cxt, "rw"); +- break; +- case 'o': +- if (arg) +- rc = mnt_context_append_options(cxt, arg); +- break; +- case 's': +- rc = mnt_context_enable_sloppy(cxt, TRUE); +- break; +- case 't': +- if (arg) +- rc = mnt_context_set_fstype(cxt, arg); +- break; +- case 'N': +- if (arg) +- rc = mnt_context_set_target_ns(cxt, arg); +- break; +- default: +- return 1; +- } ++ switch(c) { ++ case 'f': ++ rc = mnt_context_enable_fake(cxt, TRUE); ++ break; ++ case 'n': ++ rc = mnt_context_disable_mtab(cxt, TRUE); ++ break; ++ case 'r': ++ rc = mnt_context_append_options(cxt, "ro"); ++ break; ++ case 'v': ++ rc = mnt_context_enable_verbose(cxt, TRUE); ++ break; ++ case 'w': ++ rc = mnt_context_append_options(cxt, "rw"); ++ break; ++ case 'o': ++ if (arg) ++ rc = mnt_context_append_options(cxt, arg); ++ break; ++ case 's': ++ rc = mnt_context_enable_sloppy(cxt, TRUE); ++ break; ++ case 't': ++ if (arg) ++ rc = mnt_context_set_fstype(cxt, arg); ++ break; ++ case 'N': ++ if (arg) ++ rc = mnt_context_set_target_ns(cxt, arg); ++ break; ++ default: ++ return 1; ++ } + +- return rc; ++ return rc; + } + + static int exec_helper(struct libmnt_context *cxt) + { +- char *o = NULL, *namespace = NULL; +- struct libmnt_ns *ns_tgt = mnt_context_get_target_ns(cxt); +- int rc; +- pid_t pid; +- +- assert(cxt); +- assert(cxt->fs); +- assert(cxt->helper); +- assert((cxt->flags & MNT_FL_MOUNTFLAGS_MERGED)); +- +- DBG(CXT, ul_debugobj(cxt, "mount: executing helper %s", cxt->helper)); +- +- rc = generate_helper_optstr(cxt, &o); +- if (rc) +- return -EINVAL; +- +- if (ns_tgt->fd != -1 +- && asprintf(&namespace, "/proc/%i/fd/%i", +- getpid(), ns_tgt->fd) == -1) { +- free(o); +- return -ENOMEM; +- } +- +- DBG_FLUSH; +- +- pid = fork(); +- switch (pid) { +- case 0: +- { +- const char *args[14], *type; +- int i = 0; +- +- if (setgid(getgid()) < 0) +- _exit(EXIT_FAILURE); +- +- if (setuid(getuid()) < 0) +- _exit(EXIT_FAILURE); +- +- if (!mnt_context_switch_origin_ns(cxt)) +- _exit(EXIT_FAILURE); +- +- type = mnt_fs_get_fstype(cxt->fs); +- +- args[i++] = cxt->helper; /* 1 */ +- args[i++] = mnt_fs_get_srcpath(cxt->fs);/* 2 */ +- args[i++] = mnt_fs_get_target(cxt->fs); /* 3 */ +- +- if (mnt_context_is_sloppy(cxt)) +- args[i++] = "-s"; /* 4 */ +- if (mnt_context_is_fake(cxt)) +- args[i++] = "-f"; /* 5 */ +- if (mnt_context_is_nomtab(cxt)) +- args[i++] = "-n"; /* 6 */ +- if (mnt_context_is_verbose(cxt)) +- args[i++] = "-v"; /* 7 */ +- if (o) { +- args[i++] = "-o"; /* 8 */ +- args[i++] = o; /* 9 */ +- } +- if (type +- && strchr(type, '.') +- && !endswith(cxt->helper, type)) { +- args[i++] = "-t"; /* 10 */ +- args[i++] = type; /* 11 */ +- } +- if (namespace) { +- args[i++] = "-N"; /* 11 */ +- args[i++] = namespace; /* 12 */ +- } +- args[i] = NULL; /* 13 */ +- for (i = 0; args[i]; i++) +- DBG(CXT, ul_debugobj(cxt, "argv[%d] = \"%s\"", +- i, args[i])); +- DBG_FLUSH; +- execv(cxt->helper, (char * const *) args); +- _exit(EXIT_FAILURE); +- } +- default: +- { +- int st; +- +- if (waitpid(pid, &st, 0) == (pid_t) -1) { +- cxt->helper_status = -1; +- rc = -errno; +- } else { +- cxt->helper_status = WIFEXITED(st) ? WEXITSTATUS(st) : -1; +- cxt->helper_exec_status = rc = 0; +- } +- DBG(CXT, ul_debugobj(cxt, "%s executed [status=%d, rc=%d%s]", +- cxt->helper, +- cxt->helper_status, rc, +- rc ? " waitpid failed" : "")); +- break; +- } +- +- case -1: +- cxt->helper_exec_status = rc = -errno; +- DBG(CXT, ul_debugobj(cxt, "fork() failed")); +- break; +- } ++ char *o = NULL, *namespace = NULL; ++ struct libmnt_ns *ns_tgt = mnt_context_get_target_ns(cxt); ++ int rc; ++ pid_t pid; ++ ++ assert(cxt); ++ assert(cxt->fs); ++ assert(cxt->helper); ++ assert((cxt->flags & MNT_FL_MOUNTFLAGS_MERGED)); ++ ++ DBG(CXT, ul_debugobj(cxt, "mount: executing helper %s", cxt->helper)); ++ ++ rc = generate_helper_optstr(cxt, &o); ++ if (rc) ++ return -EINVAL; ++ ++ if (ns_tgt->fd != -1 ++ && asprintf(&namespace, "/proc/%i/fd/%i", ++ getpid(), ns_tgt->fd) == -1) { ++ free(o); ++ return -ENOMEM; ++ } ++ ++ DBG_FLUSH; ++ ++ pid = fork(); ++ switch (pid) { ++ case 0: ++ { ++ const char *args[14], *type; ++ int i = 0; ++ ++ if (setgid(getgid()) < 0) ++ _exit(EXIT_FAILURE); ++ ++ if (setuid(getuid()) < 0) ++ _exit(EXIT_FAILURE); ++ ++ if (!mnt_context_switch_origin_ns(cxt)) ++ _exit(EXIT_FAILURE); ++ ++ type = mnt_fs_get_fstype(cxt->fs); ++ ++ args[i++] = cxt->helper; /* 1 */ ++ args[i++] = mnt_fs_get_srcpath(cxt->fs);/* 2 */ ++ args[i++] = mnt_fs_get_target(cxt->fs); /* 3 */ ++ ++ if (mnt_context_is_sloppy(cxt)) ++ args[i++] = "-s"; /* 4 */ ++ if (mnt_context_is_fake(cxt)) ++ args[i++] = "-f"; /* 5 */ ++ if (mnt_context_is_nomtab(cxt)) ++ args[i++] = "-n"; /* 6 */ ++ if (mnt_context_is_verbose(cxt)) ++ args[i++] = "-v"; /* 7 */ ++ if (o) { ++ args[i++] = "-o"; /* 8 */ ++ args[i++] = o; /* 9 */ ++ } ++ if (type ++ && strchr(type, '.') ++ && !endswith(cxt->helper, type)) { ++ args[i++] = "-t"; /* 10 */ ++ args[i++] = type; /* 11 */ ++ } ++ if (namespace) { ++ args[i++] = "-N"; /* 11 */ ++ args[i++] = namespace; /* 12 */ ++ } ++ args[i] = NULL; /* 13 */ ++ for (i = 0; args[i]; i++) ++ DBG(CXT, ul_debugobj(cxt, "argv[%d] = \"%s\"", ++ i, args[i])); ++ DBG_FLUSH; ++ execv(cxt->helper, (char * const *) args); ++ _exit(EXIT_FAILURE); ++ } ++ default: ++ { ++ int st; ++ ++ if (waitpid(pid, &st, 0) == (pid_t) -1) { ++ cxt->helper_status = -1; ++ rc = -errno; ++ } else { ++ cxt->helper_status = WIFEXITED(st) ? WEXITSTATUS(st) : -1; ++ cxt->helper_exec_status = rc = 0; ++ } ++ DBG(CXT, ul_debugobj(cxt, "%s executed [status=%d, rc=%d%s]", ++ cxt->helper, ++ cxt->helper_status, rc, ++ rc ? " waitpid failed" : "")); ++ break; ++ } ++ ++ case -1: ++ cxt->helper_exec_status = rc = -errno; ++ DBG(CXT, ul_debugobj(cxt, "fork() failed")); ++ break; ++ } + +- free(o); +- return rc; ++ free(o); ++ return rc; + } + + static int do_mount_additional(struct libmnt_context *cxt, +- const char *target, +- unsigned long flags, +- int *syserr) +-{ +- struct list_head *p; +- +- assert(cxt); +- assert(target); +- +- if (syserr) +- *syserr = 0; +- +- list_for_each(p, &cxt->addmounts) { +- int rc; +- struct libmnt_addmount *ad = +- list_entry(p, struct libmnt_addmount, mounts); +- +- DBG(CXT, ul_debugobj(cxt, "mount(2) changing flag: 0x%08lx %s", +- ad->mountflags, +- ad->mountflags & MS_REC ? " (recursive)" : "")); +- +- rc = mount("none", target, NULL, +- ad->mountflags | (flags & MS_SILENT), NULL); +- if (rc) { +- if (syserr) +- *syserr = -errno; +- DBG(CXT, ul_debugobj(cxt, +- "mount(2) failed [errno=%d %m]", +- errno)); +- return rc; +- } +- } ++ const char *target, ++ unsigned long flags, ++ int *syserr) ++{ ++ struct list_head *p; ++ ++ assert(cxt); ++ assert(target); ++ ++ if (syserr) ++ *syserr = 0; ++ ++ list_for_each(p, &cxt->addmounts) { ++ int rc; ++ struct libmnt_addmount *ad = ++ list_entry(p, struct libmnt_addmount, mounts); ++ ++ DBG(CXT, ul_debugobj(cxt, "mount(2) changing flag: 0x%08lx %s", ++ ad->mountflags, ++ ad->mountflags & MS_REC ? " (recursive)" : "")); ++ ++ rc = mount("none", target, NULL, ++ ad->mountflags | (flags & MS_SILENT), NULL); ++ if (rc) { ++ if (syserr) ++ *syserr = -errno; ++ DBG(CXT, ul_debugobj(cxt, ++ "mount(2) failed [errno=%d %m]", ++ errno)); ++ return rc; ++ } ++ } + +- return 0; ++ return 0; + } + + /* +@@ -765,193 +765,193 @@ + */ + static int do_mount(struct libmnt_context *cxt, const char *try_type) + { +- int rc = 0; +- const char *src, *target, *type; +- unsigned long flags; +- +- assert(cxt); +- assert(cxt->fs); +- assert((cxt->flags & MNT_FL_MOUNTFLAGS_MERGED)); +- +- if (try_type && !cxt->helper) { +- rc = mnt_context_prepare_helper(cxt, "mount", try_type); +- if (rc) +- return rc; +- } +- +- flags = cxt->mountflags; +- src = mnt_fs_get_srcpath(cxt->fs); +- target = mnt_fs_get_target(cxt->fs); +- +- if (cxt->helper) { +- rc = exec_helper(cxt); +- +- if (mnt_context_helper_executed(cxt) +- && mnt_context_get_helper_status(cxt) == 0 +- && !list_empty(&cxt->addmounts) +- && do_mount_additional(cxt, target, flags, NULL)) +- +- return -MNT_ERR_APPLYFLAGS; +- return rc; +- } +- +- if (!target) +- return -EINVAL; +- if (!src) { +- /* unnecessary, should be already resolved in +- * mnt_context_prepare_srcpath(), but to be sure... */ +- DBG(CXT, ul_debugobj(cxt, "WARNING: source is NULL -- using \"none\"!")); +- src = "none"; +- } +- type = try_type ? : mnt_fs_get_fstype(cxt->fs); +- +- if (try_type) +- flags |= MS_SILENT; +- +- DBG(CXT, ul_debugobj(cxt, "%smount(2) " +- "[source=%s, target=%s, type=%s, " +- " mountflags=0x%08lx, mountdata=%s]", +- mnt_context_is_fake(cxt) ? "(FAKE) " : "", +- src, target, type, +- flags, cxt->mountdata ? "yes" : "<none>")); +- +- if (mnt_context_is_fake(cxt)) { +- /* +- * fake +- */ +- cxt->syscall_status = 0; +- +- } else if (mnt_context_propagation_only(cxt)) { +- /* +- * propagation flags *only* +- */ +- if (do_mount_additional(cxt, target, flags, &cxt->syscall_status)) +- return -MNT_ERR_APPLYFLAGS; +- } else { +- /* +- * regular mount +- */ +- if (mount(src, target, type, flags, cxt->mountdata)) { +- cxt->syscall_status = -errno; +- DBG(CXT, ul_debugobj(cxt, "mount(2) failed [errno=%d %m]", +- -cxt->syscall_status)); +- return -cxt->syscall_status; +- } +- DBG(CXT, ul_debugobj(cxt, " success")); +- cxt->syscall_status = 0; +- +- /* +- * additional mounts for extra propagation flags +- */ +- if (!list_empty(&cxt->addmounts) +- && do_mount_additional(cxt, target, flags, NULL)) { +- +- /* TODO: call umount? */ +- return -MNT_ERR_APPLYFLAGS; +- } +- } +- +- if (try_type && cxt->update) { +- struct libmnt_fs *fs = mnt_update_get_fs(cxt->update); +- if (fs) +- rc = mnt_fs_set_fstype(fs, try_type); +- } ++ int rc = 0; ++ const char *src, *target, *type; ++ unsigned long flags; ++ ++ assert(cxt); ++ assert(cxt->fs); ++ assert((cxt->flags & MNT_FL_MOUNTFLAGS_MERGED)); ++ ++ if (try_type && !cxt->helper) { ++ rc = mnt_context_prepare_helper(cxt, "mount", try_type); ++ if (rc) ++ return rc; ++ } ++ ++ flags = cxt->mountflags; ++ src = mnt_fs_get_srcpath(cxt->fs); ++ target = mnt_fs_get_target(cxt->fs); ++ ++ if (cxt->helper) { ++ rc = exec_helper(cxt); ++ ++ if (mnt_context_helper_executed(cxt) ++ && mnt_context_get_helper_status(cxt) == 0 ++ && !list_empty(&cxt->addmounts) ++ && do_mount_additional(cxt, target, flags, NULL)) ++ ++ return -MNT_ERR_APPLYFLAGS; ++ return rc; ++ } ++ ++ if (!target) ++ return -EINVAL; ++ if (!src) { ++ /* unnecessary, should be already resolved in ++ * mnt_context_prepare_srcpath(), but to be sure... */ ++ DBG(CXT, ul_debugobj(cxt, "WARNING: source is NULL -- using \"none\"!")); ++ src = "none"; ++ } ++ type = try_type ? : mnt_fs_get_fstype(cxt->fs); ++ ++ if (try_type) ++ flags |= MS_SILENT; ++ ++ DBG(CXT, ul_debugobj(cxt, "%smount(2) " ++ "[source=%s, target=%s, type=%s, " ++ " mountflags=0x%08lx, mountdata=%s]", ++ mnt_context_is_fake(cxt) ? "(FAKE) " : "", ++ src, target, type, ++ flags, cxt->mountdata ? "yes" : "<none>")); ++ ++ if (mnt_context_is_fake(cxt)) { ++ /* ++ * fake ++ */ ++ cxt->syscall_status = 0; ++ ++ } else if (mnt_context_propagation_only(cxt)) { ++ /* ++ * propagation flags *only* ++ */ ++ if (do_mount_additional(cxt, target, flags, &cxt->syscall_status)) ++ return -MNT_ERR_APPLYFLAGS; ++ } else { ++ /* ++ * regular mount ++ */ ++ if (mount(src, target, type, flags, cxt->mountdata)) { ++ cxt->syscall_status = -errno; ++ DBG(CXT, ul_debugobj(cxt, "mount(2) failed [errno=%d %m]", ++ -cxt->syscall_status)); ++ return -cxt->syscall_status; ++ } ++ DBG(CXT, ul_debugobj(cxt, " success")); ++ cxt->syscall_status = 0; ++ ++ /* ++ * additional mounts for extra propagation flags ++ */ ++ if (!list_empty(&cxt->addmounts) ++ && do_mount_additional(cxt, target, flags, NULL)) { ++ ++ /* TODO: call umount? */ ++ return -MNT_ERR_APPLYFLAGS; ++ } ++ } ++ ++ if (try_type && cxt->update) { ++ struct libmnt_fs *fs = mnt_update_get_fs(cxt->update); ++ if (fs) ++ rc = mnt_fs_set_fstype(fs, try_type); ++ } + +- return rc; ++ return rc; + } + + /* try mount(2) for all items in comma separated list of the filesystem @types */ + static int do_mount_by_types(struct libmnt_context *cxt, const char *types) + { +- int rc = -EINVAL; +- char *p, *p0; ++ int rc = -EINVAL; ++ char *p, *p0; + +- assert(cxt); +- assert((cxt->flags & MNT_FL_MOUNTFLAGS_MERGED)); ++ assert(cxt); ++ assert((cxt->flags & MNT_FL_MOUNTFLAGS_MERGED)); + +- DBG(CXT, ul_debugobj(cxt, "trying to mount by FS list '%s'", types)); ++ DBG(CXT, ul_debugobj(cxt, "trying to mount by FS list '%s'", types)); + +- p0 = p = strdup(types); +- if (!p) +- return -ENOMEM; +- do { +- char *autotype = NULL; +- char *end = strchr(p, ','); +- +- if (end) +- *end = '\0'; +- +- DBG(CXT, ul_debugobj(cxt, "-->trying '%s'", p)); +- +- /* Let's support things like "udf,iso9660,auto" */ +- if (strcmp(p, "auto") == 0) { +- rc = mnt_context_guess_srcpath_fstype(cxt, &autotype); +- if (rc) { +- DBG(CXT, ul_debugobj(cxt, "failed to guess FS type [rc=%d]", rc)); +- free(p0); +- free(autotype); +- return rc; +- } +- p = autotype; +- DBG(CXT, ul_debugobj(cxt, " --> '%s'", p)); +- } +- +- if (p) +- rc = do_mount(cxt, p); +- p = end ? end + 1 : NULL; +- free(autotype); +- } while (!mnt_context_get_status(cxt) && p); ++ p0 = p = strdup(types); ++ if (!p) ++ return -ENOMEM; ++ do { ++ char *autotype = NULL; ++ char *end = strchr(p, ','); ++ ++ if (end) ++ *end = '\0'; ++ ++ DBG(CXT, ul_debugobj(cxt, "-->trying '%s'", p)); ++ ++ /* Let's support things like "udf,iso9660,auto" */ ++ if (strcmp(p, "auto") == 0) { ++ rc = mnt_context_guess_srcpath_fstype(cxt, &autotype); ++ if (rc) { ++ DBG(CXT, ul_debugobj(cxt, "failed to guess FS type [rc=%d]", rc)); ++ free(p0); ++ free(autotype); ++ return rc; ++ } ++ p = autotype; ++ DBG(CXT, ul_debugobj(cxt, " --> '%s'", p)); ++ } ++ ++ if (p) ++ rc = do_mount(cxt, p); ++ p = end ? end + 1 : NULL; ++ free(autotype); ++ } while (!mnt_context_get_status(cxt) && p); + +- free(p0); +- return rc; ++ free(p0); ++ return rc; + } + + + static int do_mount_by_pattern(struct libmnt_context *cxt, const char *pattern) + { +- int neg = pattern && strncmp(pattern, "no", 2) == 0; +- int rc = -EINVAL; +- char **filesystems, **fp; +- struct libmnt_ns *ns_old; +- +- assert(cxt); +- assert((cxt->flags & MNT_FL_MOUNTFLAGS_MERGED)); +- +- /* +- * Use the pattern as list of the filesystems +- */ +- if (!neg && pattern) { +- DBG(CXT, ul_debugobj(cxt, "use FS pattern as FS list")); +- return do_mount_by_types(cxt, pattern); +- } +- +- DBG(CXT, ul_debugobj(cxt, "trying to mount by FS pattern '%s'", pattern)); +- +- /* +- * Apply pattern to /etc/filesystems and /proc/filesystems +- */ +- ns_old = mnt_context_switch_origin_ns(cxt); +- if (!ns_old) +- return -MNT_ERR_NAMESPACE; +- rc = mnt_get_filesystems(&filesystems, neg ? pattern : NULL); +- if (!mnt_context_switch_ns(cxt, ns_old)) +- return -MNT_ERR_NAMESPACE; +- if (rc) +- return rc; +- +- if (filesystems == NULL) +- return -MNT_ERR_NOFSTYPE; +- +- for (fp = filesystems; *fp; fp++) { +- rc = do_mount(cxt, *fp); +- if (mnt_context_get_status(cxt)) +- break; +- if (mnt_context_get_syscall_errno(cxt) != EINVAL && +- mnt_context_get_syscall_errno(cxt) != ENODEV) +- break; +- } +- mnt_free_filesystems(filesystems); +- return rc; ++ int neg = pattern && strncmp(pattern, "no", 2) == 0; ++ int rc = -EINVAL; ++ char **filesystems, **fp; ++ struct libmnt_ns *ns_old; ++ ++ assert(cxt); ++ assert((cxt->flags & MNT_FL_MOUNTFLAGS_MERGED)); ++ ++ /* ++ * Use the pattern as list of the filesystems ++ */ ++ if (!neg && pattern) { ++ DBG(CXT, ul_debugobj(cxt, "use FS pattern as FS list")); ++ return do_mount_by_types(cxt, pattern); ++ } ++ ++ DBG(CXT, ul_debugobj(cxt, "trying to mount by FS pattern '%s'", pattern)); ++ ++ /* ++ * Apply pattern to /etc/filesystems and /proc/filesystems ++ */ ++ ns_old = mnt_context_switch_origin_ns(cxt); ++ if (!ns_old) ++ return -MNT_ERR_NAMESPACE; ++ rc = mnt_get_filesystems(&filesystems, neg ? pattern : NULL); ++ if (!mnt_context_switch_ns(cxt, ns_old)) ++ return -MNT_ERR_NAMESPACE; ++ if (rc) ++ return rc; ++ ++ if (filesystems == NULL) ++ return -MNT_ERR_NOFSTYPE; ++ ++ for (fp = filesystems; *fp; fp++) { ++ rc = do_mount(cxt, *fp); ++ if (mnt_context_get_status(cxt)) ++ break; ++ if (mnt_context_get_syscall_errno(cxt) != EINVAL && ++ mnt_context_get_syscall_errno(cxt) != ENODEV) ++ break; ++ } ++ mnt_free_filesystems(filesystems); ++ return rc; + } + + /** +@@ -964,53 +964,53 @@ + */ + int mnt_context_prepare_mount(struct libmnt_context *cxt) + { +- int rc = -EINVAL; +- struct libmnt_ns *ns_old; ++ int rc = -EINVAL; ++ struct libmnt_ns *ns_old; + +- if (!cxt || !cxt->fs || mnt_fs_is_swaparea(cxt->fs)) +- return -EINVAL; +- if (!mnt_fs_get_source(cxt->fs) && !mnt_fs_get_target(cxt->fs)) +- return -EINVAL; +- if (cxt->flags & MNT_FL_PREPARED) +- return 0; +- +- assert(cxt->helper_exec_status == 1); +- assert(cxt->syscall_status == 1); +- +- cxt->action = MNT_ACT_MOUNT; +- +- ns_old = mnt_context_switch_target_ns(cxt); +- if (!ns_old) +- return -MNT_ERR_NAMESPACE; +- +- DBG(CXT, ul_debugobj(cxt, "mount: preparing")); +- +- rc = mnt_context_apply_fstab(cxt); +- if (!rc) +- rc = mnt_context_merge_mflags(cxt); +- if (!rc) +- rc = evaluate_permissions(cxt); +- if (!rc) +- rc = fix_optstr(cxt); +- if (!rc) +- rc = mnt_context_prepare_srcpath(cxt); +- if (!rc) +- rc = mnt_context_guess_fstype(cxt); +- if (!rc) +- rc = mnt_context_prepare_target(cxt); +- if (!rc) +- rc = mnt_context_prepare_helper(cxt, "mount", NULL); +- if (rc) { +- DBG(CXT, ul_debugobj(cxt, "mount: preparing failed")); +- goto end; +- } +- cxt->flags |= MNT_FL_PREPARED; ++ if (!cxt || !cxt->fs || mnt_fs_is_swaparea(cxt->fs)) ++ return -EINVAL; ++ if (!mnt_fs_get_source(cxt->fs) && !mnt_fs_get_target(cxt->fs)) ++ return -EINVAL; ++ if (cxt->flags & MNT_FL_PREPARED) ++ return 0; ++ ++ assert(cxt->helper_exec_status == 1); ++ assert(cxt->syscall_status == 1); ++ ++ cxt->action = MNT_ACT_MOUNT; ++ ++ ns_old = mnt_context_switch_target_ns(cxt); ++ if (!ns_old) ++ return -MNT_ERR_NAMESPACE; ++ ++ DBG(CXT, ul_debugobj(cxt, "mount: preparing")); ++ ++ rc = mnt_context_apply_fstab(cxt); ++ if (!rc) ++ rc = mnt_context_merge_mflags(cxt); ++ if (!rc) ++ rc = evaluate_permissions(cxt); ++ if (!rc) ++ rc = fix_optstr(cxt); ++ if (!rc) ++ rc = mnt_context_prepare_srcpath(cxt); ++ if (!rc) ++ rc = mnt_context_guess_fstype(cxt); ++ if (!rc) ++ rc = mnt_context_prepare_target(cxt); ++ if (!rc) ++ rc = mnt_context_prepare_helper(cxt, "mount", NULL); ++ if (rc) { ++ DBG(CXT, ul_debugobj(cxt, "mount: preparing failed")); ++ goto end; ++ } ++ cxt->flags |= MNT_FL_PREPARED; + + end: +- if (!mnt_context_switch_ns(cxt, ns_old)) +- return -MNT_ERR_NAMESPACE; ++ if (!mnt_context_switch_ns(cxt, ns_old)) ++ return -MNT_ERR_NAMESPACE; + +- return rc; ++ return rc; + } + + /** +@@ -1038,87 +1038,87 @@ + */ + int mnt_context_do_mount(struct libmnt_context *cxt) + { +- const char *type; +- int res; +- struct libmnt_ns *ns_old; +- +- assert(cxt); +- assert(cxt->fs); +- assert(cxt->helper_exec_status == 1); +- assert(cxt->syscall_status == 1); +- assert((cxt->flags & MNT_FL_MOUNTFLAGS_MERGED)); +- assert((cxt->flags & MNT_FL_PREPARED)); +- assert((cxt->action == MNT_ACT_MOUNT)); +- +- DBG(CXT, ul_debugobj(cxt, "mount: do mount")); +- +- if (!(cxt->flags & MNT_FL_MOUNTDATA)) +- cxt->mountdata = (char *) mnt_fs_get_fs_options(cxt->fs); +- +- ns_old = mnt_context_switch_target_ns(cxt); +- if (!ns_old) +- return -MNT_ERR_NAMESPACE; +- +- type = mnt_fs_get_fstype(cxt->fs); +- if (type) { +- if (strchr(type, ',')) +- /* this only happens if fstab contains a list of filesystems */ +- res = do_mount_by_types(cxt, type); +- else +- res = do_mount(cxt, NULL); +- } else +- res = do_mount_by_pattern(cxt, cxt->fstype_pattern); ++ const char *type; ++ int res; ++ struct libmnt_ns *ns_old; ++ ++ assert(cxt); ++ assert(cxt->fs); ++ assert(cxt->helper_exec_status == 1); ++ assert(cxt->syscall_status == 1); ++ assert((cxt->flags & MNT_FL_MOUNTFLAGS_MERGED)); ++ assert((cxt->flags & MNT_FL_PREPARED)); ++ assert((cxt->action == MNT_ACT_MOUNT)); ++ ++ DBG(CXT, ul_debugobj(cxt, "mount: do mount")); ++ ++ if (!(cxt->flags & MNT_FL_MOUNTDATA)) ++ cxt->mountdata = (char *) mnt_fs_get_fs_options(cxt->fs); ++ ++ ns_old = mnt_context_switch_target_ns(cxt); ++ if (!ns_old) ++ return -MNT_ERR_NAMESPACE; ++ ++ type = mnt_fs_get_fstype(cxt->fs); ++ if (type) { ++ if (strchr(type, ',')) ++ /* this only happens if fstab contains a list of filesystems */ ++ res = do_mount_by_types(cxt, type); ++ else ++ res = do_mount(cxt, NULL); ++ } else ++ res = do_mount_by_pattern(cxt, cxt->fstype_pattern); + + #ifdef USE_LIBMOUNT_SUPPORT_MTAB +- if (mnt_context_get_status(cxt) +- && !mnt_context_is_fake(cxt) +- && !cxt->helper +- && mnt_context_mtab_writable(cxt)) { +- +- int is_rdonly = -1; +- +- DBG(CXT, ul_debugobj(cxt, "checking for RDONLY mismatch")); +- +- /* +- * Mounted by mount(2), do some post-mount checks +- * +- * Kernel can be used to use MS_RDONLY for bind mounts, but the +- * read-only request could be silently ignored. Check it to +- * avoid 'ro' in mtab and 'rw' in /proc/mounts. +- */ +- if ((cxt->mountflags & MS_BIND) +- && (cxt->mountflags & MS_RDONLY)) { +- +- if (is_rdonly < 0) +- is_rdonly = mnt_is_readonly(mnt_context_get_target(cxt)); +- if (!is_rdonly) +- mnt_context_set_mflags(cxt, cxt->mountflags & ~MS_RDONLY); +- } +- +- +- /* Kernel can silently add MS_RDONLY flag when mounting file +- * system that does not have write support. Check this to avoid +- * 'ro' in /proc/mounts and 'rw' in mtab. +- */ +- if (!(cxt->mountflags & (MS_RDONLY | MS_MOVE)) +- && !mnt_context_propagation_only(cxt)) { +- +- if (is_rdonly < 0) +- is_rdonly = mnt_is_readonly(mnt_context_get_target(cxt)); +- if (is_rdonly) +- mnt_context_set_mflags(cxt, cxt->mountflags | MS_RDONLY); +- } +- } ++ if (mnt_context_get_status(cxt) ++ && !mnt_context_is_fake(cxt) ++ && !cxt->helper ++ && mnt_context_mtab_writable(cxt)) { ++ ++ int is_rdonly = -1; ++ ++ DBG(CXT, ul_debugobj(cxt, "checking for RDONLY mismatch")); ++ ++ /* ++ * Mounted by mount(2), do some post-mount checks ++ * ++ * Kernel can be used to use MS_RDONLY for bind mounts, but the ++ * read-only request could be silently ignored. Check it to ++ * avoid 'ro' in mtab and 'rw' in /proc/mounts. ++ */ ++ if ((cxt->mountflags & MS_BIND) ++ && (cxt->mountflags & MS_RDONLY)) { ++ ++ if (is_rdonly < 0) ++ is_rdonly = mnt_is_readonly(mnt_context_get_target(cxt)); ++ if (!is_rdonly) ++ mnt_context_set_mflags(cxt, cxt->mountflags & ~MS_RDONLY); ++ } ++ ++ ++ /* Kernel can silently add MS_RDONLY flag when mounting file ++ * system that does not have write support. Check this to avoid ++ * 'ro' in /proc/mounts and 'rw' in mtab. ++ */ ++ if (!(cxt->mountflags & (MS_RDONLY | MS_MOVE)) ++ && !mnt_context_propagation_only(cxt)) { ++ ++ if (is_rdonly < 0) ++ is_rdonly = mnt_is_readonly(mnt_context_get_target(cxt)); ++ if (is_rdonly) ++ mnt_context_set_mflags(cxt, cxt->mountflags | MS_RDONLY); ++ } ++ } + #endif + +- /* Cleanup will be immediate on failure, and deferred to umount on success */ +- if (mnt_context_is_veritydev(cxt)) +- mnt_context_deferred_delete_veritydev(cxt); ++ /* Cleanup will be immediate on failure, and deferred to umount on success */ ++ if (mnt_context_is_veritydev(cxt)) ++ mnt_context_deferred_delete_veritydev(cxt); + +- if (!mnt_context_switch_ns(cxt, ns_old)) +- return -MNT_ERR_NAMESPACE; ++ if (!mnt_context_switch_ns(cxt, ns_old)) ++ return -MNT_ERR_NAMESPACE; + +- return res; ++ return res; + } + + /* +@@ -1128,27 +1128,27 @@ + */ + static struct libmnt_fs *get_already_mounted_source(struct libmnt_context *cxt) + { +- const char *src; +- struct libmnt_table *tb; ++ const char *src; ++ struct libmnt_table *tb; + +- assert(cxt); ++ assert(cxt); + +- src = mnt_fs_get_srcpath(cxt->fs); ++ src = mnt_fs_get_srcpath(cxt->fs); + +- if (src && mnt_context_get_mtab(cxt, &tb) == 0) { +- struct libmnt_iter itr; +- struct libmnt_fs *fs; +- +- mnt_reset_iter(&itr, MNT_ITER_FORWARD); +- while (mnt_table_next_fs(tb, &itr, &fs) == 0) { +- const char *s = mnt_fs_get_srcpath(fs), +- *t = mnt_fs_get_target(fs); +- +- if (t && s && mnt_fs_streq_srcpath(fs, src)) +- return fs; +- } +- } +- return NULL; ++ if (src && mnt_context_get_mtab(cxt, &tb) == 0) { ++ struct libmnt_iter itr; ++ struct libmnt_fs *fs; ++ ++ mnt_reset_iter(&itr, MNT_ITER_FORWARD); ++ while (mnt_table_next_fs(tb, &itr, &fs) == 0) { ++ const char *s = mnt_fs_get_srcpath(fs), ++ *t = mnt_fs_get_target(fs); ++ ++ if (t && s && mnt_fs_streq_srcpath(fs, src)) ++ return fs; ++ } ++ } ++ return NULL; + } + + /* +@@ -1157,10 +1157,10 @@ + */ + static int is_source_already_rdonly(struct libmnt_context *cxt) + { +- struct libmnt_fs *fs = get_already_mounted_source(cxt); +- const char *opts = fs ? mnt_fs_get_fs_options(fs) : NULL; ++ struct libmnt_fs *fs = get_already_mounted_source(cxt); ++ const char *opts = fs ? mnt_fs_get_fs_options(fs) : NULL; + +- return opts && mnt_optstr_get_option(opts, "ro", NULL, NULL) == 0; ++ return opts && mnt_optstr_get_option(opts, "ro", NULL, NULL) == 0; + } + + /** +@@ -1174,17 +1174,17 @@ + */ + int mnt_context_finalize_mount(struct libmnt_context *cxt) + { +- int rc; ++ int rc; + +- assert(cxt); +- assert(cxt->fs); +- assert((cxt->flags & MNT_FL_MOUNTFLAGS_MERGED)); +- assert((cxt->flags & MNT_FL_PREPARED)); +- +- rc = mnt_context_prepare_update(cxt); +- if (!rc) +- rc = mnt_context_update_tabs(cxt); +- return rc; ++ assert(cxt); ++ assert(cxt->fs); ++ assert((cxt->flags & MNT_FL_MOUNTFLAGS_MERGED)); ++ assert((cxt->flags & MNT_FL_PREPARED)); ++ ++ rc = mnt_context_prepare_update(cxt); ++ if (!rc) ++ rc = mnt_context_update_tabs(cxt); ++ return rc; + } + + /** +@@ -1195,9 +1195,9 @@ + * + * This is similar to: + * +- * mnt_context_prepare_mount(cxt); +- * mnt_context_do_mount(cxt); +- * mnt_context_finalize_mount(cxt); ++ * mnt_context_prepare_mount(cxt); ++ * mnt_context_do_mount(cxt); ++ * mnt_context_finalize_mount(cxt); + * + * See also mnt_context_disable_helpers(). + * +@@ -1232,7 +1232,7 @@ + * rc = mnt_context_get_excode(cxt, rc, buf, sizeof(buf)); + * if (buf) + * warnx(_("%s: %s"), mnt_context_get_target(cxt), buf); +- * return rc; // MNT_EX_* ++ * return rc; // MNT_EX_* + * </programlisting> + * </informalexample> + * +@@ -1242,58 +1242,58 @@ + */ + int mnt_context_mount(struct libmnt_context *cxt) + { +- int rc; +- struct libmnt_ns *ns_old; ++ int rc; ++ struct libmnt_ns *ns_old; + +- assert(cxt); +- assert(cxt->fs); +- assert(cxt->helper_exec_status == 1); +- assert(cxt->syscall_status == 1); +- +- ns_old = mnt_context_switch_target_ns(cxt); +- if (!ns_old) +- return -MNT_ERR_NAMESPACE; ++ assert(cxt); ++ assert(cxt->fs); ++ assert(cxt->helper_exec_status == 1); ++ assert(cxt->syscall_status == 1); ++ ++ ns_old = mnt_context_switch_target_ns(cxt); ++ if (!ns_old) ++ return -MNT_ERR_NAMESPACE; + + again: +- rc = mnt_context_prepare_mount(cxt); +- if (!rc) +- rc = mnt_context_prepare_update(cxt); +- if (!rc) +- rc = mnt_context_do_mount(cxt); +- if (!rc) +- rc = mnt_context_update_tabs(cxt); +- +- /* +- * Read-only device or already read-only mounted FS. +- * Try mount the filesystem read-only. +- */ +- if ((rc == -EROFS && !mnt_context_syscall_called(cxt)) /* before syscall; rdonly loopdev */ +- || mnt_context_get_syscall_errno(cxt) == EROFS /* syscall failed with EROFS */ +- || mnt_context_get_syscall_errno(cxt) == EACCES /* syscall failed with EACCES */ +- || (mnt_context_get_syscall_errno(cxt) == EBUSY /* already ro-mounted FS */ +- && is_source_already_rdonly(cxt))) +- { +- unsigned long mflags = 0; +- +- mnt_context_get_mflags(cxt, &mflags); +- +- if (!(mflags & MS_RDONLY) /* not yet RDONLY */ +- && !(mflags & MS_REMOUNT) /* not remount */ +- && !(mflags & MS_BIND) /* not bin mount */ +- && !mnt_context_is_rwonly_mount(cxt)) { /* no explicit read-write */ +- +- assert(!(cxt->flags & MNT_FL_FORCED_RDONLY)); +- DBG(CXT, ul_debugobj(cxt, "write-protected source, trying RDONLY.")); +- +- mnt_context_reset_status(cxt); +- mnt_context_set_mflags(cxt, mflags | MS_RDONLY); +- cxt->flags |= MNT_FL_FORCED_RDONLY; +- goto again; +- } +- } +- if (!mnt_context_switch_ns(cxt, ns_old)) +- return -MNT_ERR_NAMESPACE; +- return rc; ++ rc = mnt_context_prepare_mount(cxt); ++ if (!rc) ++ rc = mnt_context_prepare_update(cxt); ++ if (!rc) ++ rc = mnt_context_do_mount(cxt); ++ if (!rc) ++ rc = mnt_context_update_tabs(cxt); ++ ++ /* ++ * Read-only device or already read-only mounted FS. ++ * Try mount the filesystem read-only. ++ */ ++ if ((rc == -EROFS && !mnt_context_syscall_called(cxt)) /* before syscall; rdonly loopdev */ ++ || mnt_context_get_syscall_errno(cxt) == EROFS /* syscall failed with EROFS */ ++ || mnt_context_get_syscall_errno(cxt) == EACCES /* syscall failed with EACCES */ ++ || (mnt_context_get_syscall_errno(cxt) == EBUSY /* already ro-mounted FS */ ++ && is_source_already_rdonly(cxt))) ++ { ++ unsigned long mflags = 0; ++ ++ mnt_context_get_mflags(cxt, &mflags); ++ ++ if (!(mflags & MS_RDONLY) /* not yet RDONLY */ ++ && !(mflags & MS_REMOUNT) /* not remount */ ++ && !(mflags & MS_BIND) /* not bin mount */ ++ && !mnt_context_is_rwonly_mount(cxt)) { /* no explicit read-write */ ++ ++ assert(!(cxt->flags & MNT_FL_FORCED_RDONLY)); ++ DBG(CXT, ul_debugobj(cxt, "write-protected source, trying RDONLY.")); ++ ++ mnt_context_reset_status(cxt); ++ mnt_context_set_mflags(cxt, mflags | MS_RDONLY); ++ cxt->flags |= MNT_FL_FORCED_RDONLY; ++ goto again; ++ } ++ } ++ if (!mnt_context_switch_ns(cxt, ns_old)) ++ return -MNT_ERR_NAMESPACE; ++ return rc; + } + + /** +@@ -1308,8 +1308,8 @@ + * mnt_context_get_fstab()). See also mnt_context_set_fstab(). + * + * You can filter out filesystems by: +- * mnt_context_set_options_pattern() to simulate mount -a -O pattern +- * mnt_context_set_fstype_pattern() to simulate mount -a -t pattern ++ * mnt_context_set_options_pattern() to simulate mount -a -O pattern ++ * mnt_context_set_fstype_pattern() to simulate mount -a -t pattern + * + * If the filesystem is already mounted or does not match defined criteria, + * then the mnt_context_next_mount() function returns zero, but the @ignored is +@@ -1328,129 +1328,129 @@ + * 1 at the end of the list. + */ + int mnt_context_next_mount(struct libmnt_context *cxt, +- struct libmnt_iter *itr, +- struct libmnt_fs **fs, +- int *mntrc, +- int *ignored) +-{ +- struct libmnt_table *fstab, *mtab; +- const char *o, *tgt; +- int rc, mounted = 0; +- +- if (ignored) +- *ignored = 0; +- if (mntrc) +- *mntrc = 0; +- +- if (!cxt || !fs || !itr) +- return -EINVAL; +- +- rc = mnt_context_get_fstab(cxt, &fstab); +- if (rc) +- return rc; +- +- rc = mnt_table_next_fs(fstab, itr, fs); +- if (rc != 0) +- return rc; /* more filesystems (or error) */ +- +- o = mnt_fs_get_user_options(*fs); +- tgt = mnt_fs_get_target(*fs); +- +- DBG(CXT, ul_debugobj(cxt, "next-mount: trying %s", tgt)); +- +- /* ignore swap */ +- if (mnt_fs_is_swaparea(*fs) || +- +- /* ignore root filesystem */ +- (tgt && (strcmp(tgt, "/") == 0 || strcmp(tgt, "root") == 0)) || +- +- /* ignore noauto filesystems */ +- (o && mnt_optstr_get_option(o, "noauto", NULL, NULL) == 0) || +- +- /* ignore filesystems which don't match options patterns */ +- (cxt->fstype_pattern && !mnt_fs_match_fstype(*fs, +- cxt->fstype_pattern)) || +- +- /* ignore filesystems which don't match type patterns */ +- (cxt->optstr_pattern && !mnt_fs_match_options(*fs, +- cxt->optstr_pattern))) { +- if (ignored) +- *ignored = 1; +- DBG(CXT, ul_debugobj(cxt, "next-mount: not-match " +- "[fstype: %s, t-pattern: %s, options: %s, O-pattern: %s]", +- mnt_fs_get_fstype(*fs), +- cxt->fstype_pattern, +- mnt_fs_get_options(*fs), +- cxt->optstr_pattern)); +- return 0; +- } +- +- /* ignore already mounted filesystems */ +- rc = mnt_context_is_fs_mounted(cxt, *fs, &mounted); +- if (rc) +- return rc; +- if (mounted) { +- if (ignored) +- *ignored = 2; +- return 0; +- } +- +- /* Save mount options, etc. -- this is effective for the first +- * mnt_context_next_mount() call only. Make sure that cxt has not set +- * source, target or fstype. +- */ +- if (!mnt_context_has_template(cxt)) { +- mnt_context_set_source(cxt, NULL); +- mnt_context_set_target(cxt, NULL); +- mnt_context_set_fstype(cxt, NULL); +- mnt_context_save_template(cxt); +- } +- +- /* reset context, but protect mtab */ +- mtab = cxt->mtab; +- cxt->mtab = NULL; +- mnt_reset_context(cxt); +- cxt->mtab = mtab; +- +- if (mnt_context_is_fork(cxt)) { +- rc = mnt_fork_context(cxt); +- if (rc) +- return rc; /* fork error */ +- +- if (mnt_context_is_parent(cxt)) { +- return 0; /* parent */ +- } +- } +- +- /* +- * child or non-forked +- */ +- +- /* copy stuff from fstab to context */ +- rc = mnt_context_apply_fs(cxt, *fs); +- if (!rc) { +- /* +- * "-t <pattern>" is used to filter out fstab entries, but for ordinary +- * mount operation -t means "-t <type>". We have to zeroize the pattern +- * to avoid misinterpretation. +- */ +- char *pattern = cxt->fstype_pattern; +- cxt->fstype_pattern = NULL; +- +- rc = mnt_context_mount(cxt); +- +- cxt->fstype_pattern = pattern; +- +- if (mntrc) +- *mntrc = rc; +- } +- +- if (mnt_context_is_child(cxt)) { +- DBG(CXT, ul_debugobj(cxt, "next-mount: child exit [rc=%d]", rc)); +- DBG_FLUSH; +- _exit(rc); +- } +- return 0; ++ struct libmnt_iter *itr, ++ struct libmnt_fs **fs, ++ int *mntrc, ++ int *ignored) ++{ ++ struct libmnt_table *fstab, *mtab; ++ const char *o, *tgt; ++ int rc, mounted = 0; ++ ++ if (ignored) ++ *ignored = 0; ++ if (mntrc) ++ *mntrc = 0; ++ ++ if (!cxt || !fs || !itr) ++ return -EINVAL; ++ ++ rc = mnt_context_get_fstab(cxt, &fstab); ++ if (rc) ++ return rc; ++ ++ rc = mnt_table_next_fs(fstab, itr, fs); ++ if (rc != 0) ++ return rc; /* more filesystems (or error) */ ++ ++ o = mnt_fs_get_user_options(*fs); ++ tgt = mnt_fs_get_target(*fs); ++ ++ DBG(CXT, ul_debugobj(cxt, "next-mount: trying %s", tgt)); ++ ++ /* ignore swap */ ++ if (mnt_fs_is_swaparea(*fs) || ++ ++ /* ignore root filesystem */ ++ (tgt && (strcmp(tgt, "/") == 0 || strcmp(tgt, "root") == 0)) || ++ ++ /* ignore noauto filesystems */ ++ (o && mnt_optstr_get_option(o, "noauto", NULL, NULL) == 0) || ++ ++ /* ignore filesystems which don't match options patterns */ ++ (cxt->fstype_pattern && !mnt_fs_match_fstype(*fs, ++ cxt->fstype_pattern)) || ++ ++ /* ignore filesystems which don't match type patterns */ ++ (cxt->optstr_pattern && !mnt_fs_match_options(*fs, ++ cxt->optstr_pattern))) { ++ if (ignored) ++ *ignored = 1; ++ DBG(CXT, ul_debugobj(cxt, "next-mount: not-match " ++ "[fstype: %s, t-pattern: %s, options: %s, O-pattern: %s]", ++ mnt_fs_get_fstype(*fs), ++ cxt->fstype_pattern, ++ mnt_fs_get_options(*fs), ++ cxt->optstr_pattern)); ++ return 0; ++ } ++ ++ /* ignore already mounted filesystems */ ++ rc = mnt_context_is_fs_mounted(cxt, *fs, &mounted); ++ if (rc) ++ return rc; ++ if (mounted) { ++ if (ignored) ++ *ignored = 2; ++ return 0; ++ } ++ ++ /* Save mount options, etc. -- this is effective for the first ++ * mnt_context_next_mount() call only. Make sure that cxt has not set ++ * source, target or fstype. ++ */ ++ if (!mnt_context_has_template(cxt)) { ++ mnt_context_set_source(cxt, NULL); ++ mnt_context_set_target(cxt, NULL); ++ mnt_context_set_fstype(cxt, NULL); ++ mnt_context_save_template(cxt); ++ } ++ ++ /* reset context, but protect mtab */ ++ mtab = cxt->mtab; ++ cxt->mtab = NULL; ++ mnt_reset_context(cxt); ++ cxt->mtab = mtab; ++ ++ if (mnt_context_is_fork(cxt)) { ++ rc = mnt_fork_context(cxt); ++ if (rc) ++ return rc; /* fork error */ ++ ++ if (mnt_context_is_parent(cxt)) { ++ return 0; /* parent */ ++ } ++ } ++ ++ /* ++ * child or non-forked ++ */ ++ ++ /* copy stuff from fstab to context */ ++ rc = mnt_context_apply_fs(cxt, *fs); ++ if (!rc) { ++ /* ++ * "-t <pattern>" is used to filter out fstab entries, but for ordinary ++ * mount operation -t means "-t <type>". We have to zeroize the pattern ++ * to avoid misinterpretation. ++ */ ++ char *pattern = cxt->fstype_pattern; ++ cxt->fstype_pattern = NULL; ++ ++ rc = mnt_context_mount(cxt); ++ ++ cxt->fstype_pattern = pattern; ++ ++ if (mntrc) ++ *mntrc = rc; ++ } ++ ++ if (mnt_context_is_child(cxt)) { ++ DBG(CXT, ul_debugobj(cxt, "next-mount: child exit [rc=%d]", rc)); ++ DBG_FLUSH; ++ _exit(rc); ++ } ++ return 0; + } + + +@@ -1466,8 +1466,8 @@ + * mnt_context_get_mtab()). + * + * You can filter out filesystems by: +- * mnt_context_set_options_pattern() to simulate mount -a -O pattern +- * mnt_context_set_fstype_pattern() to simulate mount -a -t pattern ++ * mnt_context_set_options_pattern() to simulate mount -a -O pattern ++ * mnt_context_set_fstype_pattern() to simulate mount -a -t pattern + * + * If the filesystem does not match defined criteria, then the + * mnt_context_next_remount() function returns zero, but the @ignored is +@@ -1492,89 +1492,89 @@ + * Since: 2.34 + */ + int mnt_context_next_remount(struct libmnt_context *cxt, +- struct libmnt_iter *itr, +- struct libmnt_fs **fs, +- int *mntrc, +- int *ignored) +-{ +- struct libmnt_table *mtab; +- const char *tgt; +- int rc; +- +- if (ignored) +- *ignored = 0; +- if (mntrc) +- *mntrc = 0; +- +- if (!cxt || !fs || !itr) +- return -EINVAL; +- +- rc = mnt_context_get_mtab(cxt, &mtab); +- if (rc) +- return rc; +- +- rc = mnt_table_next_fs(mtab, itr, fs); +- if (rc != 0) +- return rc; /* more filesystems (or error) */ +- +- tgt = mnt_fs_get_target(*fs); +- +- DBG(CXT, ul_debugobj(cxt, "next-remount: trying %s", tgt)); +- +- /* ignore filesystems which don't match options patterns */ +- if ((cxt->fstype_pattern && !mnt_fs_match_fstype(*fs, +- cxt->fstype_pattern)) || +- +- /* ignore filesystems which don't match type patterns */ +- (cxt->optstr_pattern && !mnt_fs_match_options(*fs, +- cxt->optstr_pattern))) { +- if (ignored) +- *ignored = 1; +- DBG(CXT, ul_debugobj(cxt, "next-remount: not-match " +- "[fstype: %s, t-pattern: %s, options: %s, O-pattern: %s]", +- mnt_fs_get_fstype(*fs), +- cxt->fstype_pattern, +- mnt_fs_get_options(*fs), +- cxt->optstr_pattern)); +- return 0; +- } +- +- /* Save mount options, etc. -- this is effective for the first +- * mnt_context_next_remount() call only. Make sure that cxt has not set +- * source, target or fstype. +- */ +- if (!mnt_context_has_template(cxt)) { +- mnt_context_set_source(cxt, NULL); +- mnt_context_set_target(cxt, NULL); +- mnt_context_set_fstype(cxt, NULL); +- mnt_context_save_template(cxt); +- } +- +- /* restore original, but protect mtab */ +- cxt->mtab = NULL; +- mnt_reset_context(cxt); +- cxt->mtab = mtab; +- +- rc = mnt_context_set_target(cxt, tgt); +- if (!rc) { +- /* +- * "-t <pattern>" is used to filter out fstab entries, but for ordinary +- * mount operation -t means "-t <type>". We have to zeroize the pattern +- * to avoid misinterpretation. +- */ +- char *pattern = cxt->fstype_pattern; +- cxt->fstype_pattern = NULL; +- +- rc = mnt_context_mount(cxt); +- +- cxt->fstype_pattern = pattern; +- +- if (mntrc) +- *mntrc = rc; +- rc = 0; +- } ++ struct libmnt_iter *itr, ++ struct libmnt_fs **fs, ++ int *mntrc, ++ int *ignored) ++{ ++ struct libmnt_table *mtab; ++ const char *tgt; ++ int rc; ++ ++ if (ignored) ++ *ignored = 0; ++ if (mntrc) ++ *mntrc = 0; ++ ++ if (!cxt || !fs || !itr) ++ return -EINVAL; ++ ++ rc = mnt_context_get_mtab(cxt, &mtab); ++ if (rc) ++ return rc; ++ ++ rc = mnt_table_next_fs(mtab, itr, fs); ++ if (rc != 0) ++ return rc; /* more filesystems (or error) */ ++ ++ tgt = mnt_fs_get_target(*fs); ++ ++ DBG(CXT, ul_debugobj(cxt, "next-remount: trying %s", tgt)); ++ ++ /* ignore filesystems which don't match options patterns */ ++ if ((cxt->fstype_pattern && !mnt_fs_match_fstype(*fs, ++ cxt->fstype_pattern)) || ++ ++ /* ignore filesystems which don't match type patterns */ ++ (cxt->optstr_pattern && !mnt_fs_match_options(*fs, ++ cxt->optstr_pattern))) { ++ if (ignored) ++ *ignored = 1; ++ DBG(CXT, ul_debugobj(cxt, "next-remount: not-match " ++ "[fstype: %s, t-pattern: %s, options: %s, O-pattern: %s]", ++ mnt_fs_get_fstype(*fs), ++ cxt->fstype_pattern, ++ mnt_fs_get_options(*fs), ++ cxt->optstr_pattern)); ++ return 0; ++ } ++ ++ /* Save mount options, etc. -- this is effective for the first ++ * mnt_context_next_remount() call only. Make sure that cxt has not set ++ * source, target or fstype. ++ */ ++ if (!mnt_context_has_template(cxt)) { ++ mnt_context_set_source(cxt, NULL); ++ mnt_context_set_target(cxt, NULL); ++ mnt_context_set_fstype(cxt, NULL); ++ mnt_context_save_template(cxt); ++ } ++ ++ /* restore original, but protect mtab */ ++ cxt->mtab = NULL; ++ mnt_reset_context(cxt); ++ cxt->mtab = mtab; ++ ++ rc = mnt_context_set_target(cxt, tgt); ++ if (!rc) { ++ /* ++ * "-t <pattern>" is used to filter out fstab entries, but for ordinary ++ * mount operation -t means "-t <type>". We have to zeroize the pattern ++ * to avoid misinterpretation. ++ */ ++ char *pattern = cxt->fstype_pattern; ++ cxt->fstype_pattern = NULL; ++ ++ rc = mnt_context_mount(cxt); ++ ++ cxt->fstype_pattern = pattern; ++ ++ if (mntrc) ++ *mntrc = rc; ++ rc = 0; ++ } + +- return rc; ++ return rc; + } + + /* +@@ -1582,354 +1582,354 @@ + */ + static int is_shared_tree(struct libmnt_context *cxt, const char *dir) + { +- struct libmnt_table *tb = NULL; +- struct libmnt_fs *fs; +- unsigned long mflags = 0; +- char *mnt = NULL, *p; +- int rc = 0; +- struct libmnt_ns *ns_old; +- +- ns_old = mnt_context_switch_target_ns(cxt); +- if (!ns_old) +- return -MNT_ERR_NAMESPACE; +- +- if (!dir) +- return 0; +- if (mnt_context_get_mtab(cxt, &tb) || !tb) +- goto done; +- +- mnt = strdup(dir); +- if (!mnt) +- goto done; +- p = strrchr(mnt, '/'); +- if (!p) +- goto done; +- if (p > mnt) +- *p = '\0'; +- fs = mnt_table_find_mountpoint(tb, mnt, MNT_ITER_BACKWARD); +- +- rc = fs && mnt_fs_is_kernel(fs) +- && mnt_fs_get_propagation(fs, &mflags) == 0 +- && (mflags & MS_SHARED); ++ struct libmnt_table *tb = NULL; ++ struct libmnt_fs *fs; ++ unsigned long mflags = 0; ++ char *mnt = NULL, *p; ++ int rc = 0; ++ struct libmnt_ns *ns_old; ++ ++ ns_old = mnt_context_switch_target_ns(cxt); ++ if (!ns_old) ++ return -MNT_ERR_NAMESPACE; ++ ++ if (!dir) ++ return 0; ++ if (mnt_context_get_mtab(cxt, &tb) || !tb) ++ goto done; ++ ++ mnt = strdup(dir); ++ if (!mnt) ++ goto done; ++ p = strrchr(mnt, '/'); ++ if (!p) ++ goto done; ++ if (p > mnt) ++ *p = '\0'; ++ fs = mnt_table_find_mountpoint(tb, mnt, MNT_ITER_BACKWARD); ++ ++ rc = fs && mnt_fs_is_kernel(fs) ++ && mnt_fs_get_propagation(fs, &mflags) == 0 ++ && (mflags & MS_SHARED); + done: +- free(mnt); +- if (!mnt_context_switch_ns(cxt, ns_old)) +- return -MNT_ERR_NAMESPACE; +- return rc; ++ free(mnt); ++ if (!mnt_context_switch_ns(cxt, ns_old)) ++ return -MNT_ERR_NAMESPACE; ++ return rc; + } + + int mnt_context_get_mount_excode( +- struct libmnt_context *cxt, +- int rc, +- char *buf, +- size_t bufsz) +-{ +- int syserr; +- struct stat st; +- unsigned long uflags = 0, mflags = 0; +- +- int restricted = mnt_context_is_restricted(cxt); +- const char *tgt = mnt_context_get_target(cxt); +- const char *src = mnt_context_get_source(cxt); +- +- if (mnt_context_helper_executed(cxt)) { +- /* +- * /sbin/mount.<type> called, return status +- */ +- if (rc == -MNT_ERR_APPLYFLAGS && buf) +- snprintf(buf, bufsz, _("WARNING: failed to apply propagation flags")); +- +- return mnt_context_get_helper_status(cxt); +- } +- +- if (rc == 0 && mnt_context_get_status(cxt) == 1) { +- /* +- * Libmount success && syscall success. +- */ +- if (buf && mnt_context_forced_rdonly(cxt)) +- snprintf(buf, bufsz, _("WARNING: source write-protected, mounted read-only")); +- return MNT_EX_SUCCESS; +- } +- +- mnt_context_get_mflags(cxt, &mflags); /* mount(2) flags */ +- mnt_context_get_user_mflags(cxt, &uflags); /* userspace flags */ +- +- if (!mnt_context_syscall_called(cxt)) { +- /* +- * libmount errors (extra library checks) +- */ +- switch (rc) { +- case -EPERM: +- if (buf) +- snprintf(buf, bufsz, _("operation permitted for root only")); +- return MNT_EX_USAGE; +- case -EBUSY: +- if (buf) +- snprintf(buf, bufsz, _("%s is already mounted"), src); +- return MNT_EX_USAGE; +- case -MNT_ERR_NOFSTAB: +- if (!buf) +- return MNT_EX_USAGE; +- if (mnt_context_is_swapmatch(cxt)) +- snprintf(buf, bufsz, _("can't find in %s"), +- mnt_get_fstab_path()); +- else if (tgt) +- snprintf(buf, bufsz, _("can't find mount point in %s"), +- mnt_get_fstab_path()); +- else if (src) +- snprintf(buf, bufsz, _("can't find mount source %s in %s"), +- src, mnt_get_fstab_path()); +- return MNT_EX_USAGE; +- case -MNT_ERR_AMBIFS: +- if (buf) +- snprintf(buf, bufsz, _("more filesystems detected on %s; use -t <type> or wipefs(8)"), src); +- return MNT_EX_USAGE; +- case -MNT_ERR_NOFSTYPE: +- if (buf) +- snprintf(buf, bufsz, restricted ? +- _("failed to determine filesystem type") : +- _("no filesystem type specified")); +- return MNT_EX_USAGE; +- case -MNT_ERR_NOSOURCE: +- if (uflags & MNT_MS_NOFAIL) +- return MNT_EX_SUCCESS; +- if (buf) { +- if (src) +- snprintf(buf, bufsz, _("can't find %s"), src); +- else +- snprintf(buf, bufsz, _("no mount source specified")); +- } +- return MNT_EX_USAGE; +- case -MNT_ERR_MOUNTOPT: +- if (buf) +- snprintf(buf, bufsz, errno ? +- _("failed to parse mount options: %m") : +- _("failed to parse mount options")); +- return MNT_EX_USAGE; +- case -MNT_ERR_LOOPDEV: +- if (buf) +- snprintf(buf, bufsz, _("failed to setup loop device for %s"), src); +- return MNT_EX_FAIL; +- case -MNT_ERR_LOOPOVERLAP: +- if (buf) +- snprintf(buf, bufsz, _("overlapping loop device exists for %s"), src); +- return MNT_EX_FAIL; +- case -MNT_ERR_LOCK: +- if (buf) +- snprintf(buf, bufsz, _("locking failed")); +- return MNT_EX_FILEIO; +- case -MNT_ERR_NAMESPACE: +- if (buf) +- snprintf(buf, bufsz, _("failed to switch namespace")); +- return MNT_EX_SYSERR; +- default: +- return mnt_context_get_generic_excode(rc, buf, bufsz, _("mount failed: %m")); +- } +- +- } else if (mnt_context_get_syscall_errno(cxt) == 0) { +- /* +- * mount(2) syscall success, but something else failed +- * (probably error in mtab processing). +- */ +- if (rc == -MNT_ERR_LOCK) { +- if (buf) +- snprintf(buf, bufsz, _("filesystem was mounted, but failed to update userspace mount table")); +- return MNT_EX_FILEIO; +- } +- +- if (rc == -MNT_ERR_NAMESPACE) { +- if (buf) +- snprintf(buf, bufsz, _("filesystem was mounted, but failed to switch namespace back")); +- return MNT_EX_SYSERR; +- +- } +- +- if (rc < 0) +- return mnt_context_get_generic_excode(rc, buf, bufsz, +- _("filesystem was mounted, but any subsequent operation failed: %m")); +- +- return MNT_EX_SOFTWARE; /* internal error */ +- +- } +- +- /* +- * mount(2) errors +- */ +- syserr = mnt_context_get_syscall_errno(cxt); +- +- +- switch(syserr) { +- case EPERM: +- if (!buf) +- break; +- if (geteuid() == 0) { +- if (mnt_stat_mountpoint(tgt, &st) || !S_ISDIR(st.st_mode)) +- snprintf(buf, bufsz, _("mount point is not a directory")); +- else +- snprintf(buf, bufsz, _("permission denied")); +- } else +- snprintf(buf, bufsz, _("must be superuser to use mount")); +- break; +- +- case EBUSY: +- if (!buf) +- break; +- if (mflags & MS_REMOUNT) { +- snprintf(buf, bufsz, _("mount point is busy")); +- break; +- } +- if (src) { +- struct libmnt_fs *fs = get_already_mounted_source(cxt); +- +- if (fs && mnt_fs_get_target(fs)) +- snprintf(buf, bufsz, _("%s already mounted on %s"), +- src, mnt_fs_get_target(fs)); +- } +- if (!*buf) +- snprintf(buf, bufsz, _("%s already mounted or mount point busy"), src); +- break; +- case ENOENT: +- if (tgt && mnt_lstat_mountpoint(tgt, &st)) { +- if (buf) +- snprintf(buf, bufsz, _("mount point does not exist")); +- } else if (tgt && mnt_stat_mountpoint(tgt, &st)) { +- if (buf) +- snprintf(buf, bufsz, _("mount point is a symbolic link to nowhere")); +- } else if (src && stat(src, &st)) { +- if (uflags & MNT_MS_NOFAIL) +- return MNT_EX_SUCCESS; +- if (buf) +- snprintf(buf, bufsz, _("special device %s does not exist"), src); +- } else if (buf) { +- errno = syserr; +- snprintf(buf, bufsz, _("mount(2) system call failed: %m")); +- } +- break; +- +- case ENOTDIR: +- if (mnt_stat_mountpoint(tgt, &st) || ! S_ISDIR(st.st_mode)) { +- if (buf) +- snprintf(buf, bufsz, _("mount point is not a directory")); +- } else if (src && stat(src, &st) && errno == ENOTDIR) { +- if (uflags & MNT_MS_NOFAIL) +- return MNT_EX_SUCCESS; +- if (buf) +- snprintf(buf, bufsz, _("special device %s does not exist " +- "(a path prefix is not a directory)"), src); +- } else if (buf) { +- errno = syserr; +- snprintf(buf, bufsz, _("mount(2) system call failed: %m")); +- } +- break; +- +- case EINVAL: +- if (!buf) +- break; +- if (mflags & MS_REMOUNT) +- snprintf(buf, bufsz, _("mount point not mounted or bad option")); +- else if (rc == -MNT_ERR_APPLYFLAGS) +- snprintf(buf, bufsz, _("not mount point or bad option")); +- else if ((mflags & MS_MOVE) && is_shared_tree(cxt, src)) +- snprintf(buf, bufsz, +- _("bad option; moving a mount " +- "residing under a shared mount is unsupported")); +- else if (mnt_fs_is_netfs(mnt_context_get_fs(cxt))) +- snprintf(buf, bufsz, +- _("bad option; for several filesystems (e.g. nfs, cifs) " +- "you might need a /sbin/mount.<type> helper program")); +- else +- snprintf(buf, bufsz, +- _("wrong fs type, bad option, bad superblock on %s, " +- "missing codepage or helper program, or other error"), +- src); +- break; +- +- case EMFILE: +- if (buf) +- snprintf(buf, bufsz, _("mount table full")); +- break; +- +- case EIO: +- if (buf) +- snprintf(buf, bufsz, _("can't read superblock on %s"), src); +- break; +- +- case ENODEV: +- if (!buf) +- break; +- if (mnt_context_get_fstype(cxt)) +- snprintf(buf, bufsz, _("unknown filesystem type '%s'"), +- mnt_context_get_fstype(cxt)); +- else +- snprintf(buf, bufsz, _("unknown filesystem type")); +- break; +- +- case ENOTBLK: +- if (uflags & MNT_MS_NOFAIL) +- return MNT_EX_SUCCESS; +- if (!buf) +- break; +- if (src && stat(src, &st)) +- snprintf(buf, bufsz, _("%s is not a block device, and stat(2) fails?"), src); +- else if (src && S_ISBLK(st.st_mode)) +- snprintf(buf, bufsz, +- _("the kernel does not recognize %s as a block device; " +- "maybe \"modprobe driver\" is necessary"), src); +- else if (src && S_ISREG(st.st_mode)) +- snprintf(buf, bufsz, _("%s is not a block device; try \"-o loop\""), src); +- else +- snprintf(buf, bufsz, _("%s is not a block device"), src); +- break; +- +- case ENXIO: +- if (uflags & MNT_MS_NOFAIL) +- return MNT_EX_SUCCESS; +- if (buf) +- snprintf(buf, bufsz, _("%s is not a valid block device"), src); +- break; +- +- case EACCES: +- case EROFS: +- if (!buf) +- break; +- if (mflags & MS_RDONLY) +- snprintf(buf, bufsz, _("cannot mount %s read-only"), src); +- else if (mnt_context_is_rwonly_mount(cxt)) +- snprintf(buf, bufsz, _("%s is write-protected but explicit read-write mode requested"), src); +- else if (mflags & MS_REMOUNT) +- snprintf(buf, bufsz, _("cannot remount %s read-write, is write-protected"), src); +- else if (mflags & MS_BIND) +- snprintf(buf, bufsz, _("bind %s failed"), src); +- else { +- errno = syserr; +- snprintf(buf, bufsz, _("mount(2) system call failed: %m")); +- } +- break; +- +- case ENOMEDIUM: +- if (uflags & MNT_MS_NOFAIL) +- return MNT_EX_SUCCESS; +- if (buf) +- snprintf(buf, bufsz, _("no medium found on %s"), src); +- break; +- +- case EBADMSG: +- /* Bad CRC for classic filesystems (e.g. extN or XFS) */ +- if (buf && src && stat(src, &st) == 0 +- && (S_ISBLK(st.st_mode) || S_ISREG(st.st_mode))) { +- snprintf(buf, bufsz, _("cannot mount; probably corrupted filesystem on %s"), src); +- break; +- } +- /* fallthrough */ +- +- default: +- if (buf) { +- errno = syserr; +- snprintf(buf, bufsz, _("mount(2) system call failed: %m")); +- } +- break; +- } ++ struct libmnt_context *cxt, ++ int rc, ++ char *buf, ++ size_t bufsz) ++{ ++ int syserr; ++ struct stat st; ++ unsigned long uflags = 0, mflags = 0; ++ ++ int restricted = mnt_context_is_restricted(cxt); ++ const char *tgt = mnt_context_get_target(cxt); ++ const char *src = mnt_context_get_source(cxt); ++ ++ if (mnt_context_helper_executed(cxt)) { ++ /* ++ * /sbin/mount.<type> called, return status ++ */ ++ if (rc == -MNT_ERR_APPLYFLAGS && buf) ++ snprintf(buf, bufsz, _("WARNING: failed to apply propagation flags")); ++ ++ return mnt_context_get_helper_status(cxt); ++ } ++ ++ if (rc == 0 && mnt_context_get_status(cxt) == 1) { ++ /* ++ * Libmount success && syscall success. ++ */ ++ if (buf && mnt_context_forced_rdonly(cxt)) ++ snprintf(buf, bufsz, _("WARNING: source write-protected, mounted read-only")); ++ return MNT_EX_SUCCESS; ++ } ++ ++ mnt_context_get_mflags(cxt, &mflags); /* mount(2) flags */ ++ mnt_context_get_user_mflags(cxt, &uflags); /* userspace flags */ ++ ++ if (!mnt_context_syscall_called(cxt)) { ++ /* ++ * libmount errors (extra library checks) ++ */ ++ switch (rc) { ++ case -EPERM: ++ if (buf) ++ snprintf(buf, bufsz, _("operation permitted for root only")); ++ return MNT_EX_USAGE; ++ case -EBUSY: ++ if (buf) ++ snprintf(buf, bufsz, _("%s is already mounted"), src); ++ return MNT_EX_USAGE; ++ case -MNT_ERR_NOFSTAB: ++ if (!buf) ++ return MNT_EX_USAGE; ++ if (mnt_context_is_swapmatch(cxt)) ++ snprintf(buf, bufsz, _("can't find in %s"), ++ mnt_get_fstab_path()); ++ else if (tgt) ++ snprintf(buf, bufsz, _("can't find mount point in %s"), ++ mnt_get_fstab_path()); ++ else if (src) ++ snprintf(buf, bufsz, _("can't find mount source %s in %s"), ++ src, mnt_get_fstab_path()); ++ return MNT_EX_USAGE; ++ case -MNT_ERR_AMBIFS: ++ if (buf) ++ snprintf(buf, bufsz, _("more filesystems detected on %s; use -t <type> or wipefs(8)"), src); ++ return MNT_EX_USAGE; ++ case -MNT_ERR_NOFSTYPE: ++ if (buf) ++ snprintf(buf, bufsz, restricted ? ++ _("failed to determine filesystem type") : ++ _("no filesystem type specified")); ++ return MNT_EX_USAGE; ++ case -MNT_ERR_NOSOURCE: ++ if (uflags & MNT_MS_NOFAIL) ++ return MNT_EX_SUCCESS; ++ if (buf) { ++ if (src) ++ snprintf(buf, bufsz, _("can't find %s"), src); ++ else ++ snprintf(buf, bufsz, _("no mount source specified")); ++ } ++ return MNT_EX_USAGE; ++ case -MNT_ERR_MOUNTOPT: ++ if (buf) ++ snprintf(buf, bufsz, errno ? ++ _("failed to parse mount options: %m") : ++ _("failed to parse mount options")); ++ return MNT_EX_USAGE; ++ case -MNT_ERR_LOOPDEV: ++ if (buf) ++ snprintf(buf, bufsz, _("failed to setup loop device for %s"), src); ++ return MNT_EX_FAIL; ++ case -MNT_ERR_LOOPOVERLAP: ++ if (buf) ++ snprintf(buf, bufsz, _("overlapping loop device exists for %s"), src); ++ return MNT_EX_FAIL; ++ case -MNT_ERR_LOCK: ++ if (buf) ++ snprintf(buf, bufsz, _("locking failed")); ++ return MNT_EX_FILEIO; ++ case -MNT_ERR_NAMESPACE: ++ if (buf) ++ snprintf(buf, bufsz, _("failed to switch namespace")); ++ return MNT_EX_SYSERR; ++ default: ++ return mnt_context_get_generic_excode(rc, buf, bufsz, _("mount failed: %m")); ++ } ++ ++ } else if (mnt_context_get_syscall_errno(cxt) == 0) { ++ /* ++ * mount(2) syscall success, but something else failed ++ * (probably error in mtab processing). ++ */ ++ if (rc == -MNT_ERR_LOCK) { ++ if (buf) ++ snprintf(buf, bufsz, _("filesystem was mounted, but failed to update userspace mount table")); ++ return MNT_EX_FILEIO; ++ } ++ ++ if (rc == -MNT_ERR_NAMESPACE) { ++ if (buf) ++ snprintf(buf, bufsz, _("filesystem was mounted, but failed to switch namespace back")); ++ return MNT_EX_SYSERR; ++ ++ } ++ ++ if (rc < 0) ++ return mnt_context_get_generic_excode(rc, buf, bufsz, ++ _("filesystem was mounted, but any subsequent operation failed: %m")); ++ ++ return MNT_EX_SOFTWARE; /* internal error */ ++ ++ } ++ ++ /* ++ * mount(2) errors ++ */ ++ syserr = mnt_context_get_syscall_errno(cxt); ++ ++ ++ switch(syserr) { ++ case EPERM: ++ if (!buf) ++ break; ++ if (geteuid() == 0) { ++ if (mnt_stat_mountpoint(tgt, &st) || !S_ISDIR(st.st_mode)) ++ snprintf(buf, bufsz, _("mount point is not a directory")); ++ else ++ snprintf(buf, bufsz, _("permission denied")); ++ } else ++ snprintf(buf, bufsz, _("must be superuser to use mount")); ++ break; ++ ++ case EBUSY: ++ if (!buf) ++ break; ++ if (mflags & MS_REMOUNT) { ++ snprintf(buf, bufsz, _("mount point is busy")); ++ break; ++ } ++ if (src) { ++ struct libmnt_fs *fs = get_already_mounted_source(cxt); ++ ++ if (fs && mnt_fs_get_target(fs)) ++ snprintf(buf, bufsz, _("%s already mounted on %s"), ++ src, mnt_fs_get_target(fs)); ++ } ++ if (!*buf) ++ snprintf(buf, bufsz, _("%s already mounted or mount point busy"), src); ++ break; ++ case ENOENT: ++ if (tgt && mnt_lstat_mountpoint(tgt, &st)) { ++ if (buf) ++ snprintf(buf, bufsz, _("mount point does not exist")); ++ } else if (tgt && mnt_stat_mountpoint(tgt, &st)) { ++ if (buf) ++ snprintf(buf, bufsz, _("mount point is a symbolic link to nowhere")); ++ } else if (src && stat(src, &st)) { ++ if (uflags & MNT_MS_NOFAIL) ++ return MNT_EX_SUCCESS; ++ if (buf) ++ snprintf(buf, bufsz, _("special device %s does not exist"), src); ++ } else if (buf) { ++ errno = syserr; ++ snprintf(buf, bufsz, _("mount(2) system call failed: %m")); ++ } ++ break; ++ ++ case ENOTDIR: ++ if (mnt_stat_mountpoint(tgt, &st) || ! S_ISDIR(st.st_mode)) { ++ if (buf) ++ snprintf(buf, bufsz, _("mount point is not a directory")); ++ } else if (src && stat(src, &st) && errno == ENOTDIR) { ++ if (uflags & MNT_MS_NOFAIL) ++ return MNT_EX_SUCCESS; ++ if (buf) ++ snprintf(buf, bufsz, _("special device %s does not exist " ++ "(a path prefix is not a directory)"), src); ++ } else if (buf) { ++ errno = syserr; ++ snprintf(buf, bufsz, _("mount(2) system call failed: %m")); ++ } ++ break; ++ ++ case EINVAL: ++ if (!buf) ++ break; ++ if (mflags & MS_REMOUNT) ++ snprintf(buf, bufsz, _("mount point not mounted or bad option")); ++ else if (rc == -MNT_ERR_APPLYFLAGS) ++ snprintf(buf, bufsz, _("not mount point or bad option")); ++ else if ((mflags & MS_MOVE) && is_shared_tree(cxt, src)) ++ snprintf(buf, bufsz, ++ _("bad option; moving a mount " ++ "residing under a shared mount is unsupported")); ++ else if (mnt_fs_is_netfs(mnt_context_get_fs(cxt))) ++ snprintf(buf, bufsz, ++ _("bad option; for several filesystems (e.g. nfs, cifs) " ++ "you might need a /sbin/mount.<type> helper program")); ++ else ++ snprintf(buf, bufsz, ++ _("wrong fs type, bad option, bad superblock on %s, " ++ "missing codepage or helper program, or other error"), ++ src); ++ break; ++ ++ case EMFILE: ++ if (buf) ++ snprintf(buf, bufsz, _("mount table full")); ++ break; ++ ++ case EIO: ++ if (buf) ++ snprintf(buf, bufsz, _("can't read superblock on %s"), src); ++ break; ++ ++ case ENODEV: ++ if (!buf) ++ break; ++ if (mnt_context_get_fstype(cxt)) ++ snprintf(buf, bufsz, _("unknown filesystem type '%s'"), ++ mnt_context_get_fstype(cxt)); ++ else ++ snprintf(buf, bufsz, _("unknown filesystem type")); ++ break; ++ ++ case ENOTBLK: ++ if (uflags & MNT_MS_NOFAIL) ++ return MNT_EX_SUCCESS; ++ if (!buf) ++ break; ++ if (src && stat(src, &st)) ++ snprintf(buf, bufsz, _("%s is not a block device, and stat(2) fails?"), src); ++ else if (src && S_ISBLK(st.st_mode)) ++ snprintf(buf, bufsz, ++ _("the kernel does not recognize %s as a block device; " ++ "maybe \"modprobe driver\" is necessary"), src); ++ else if (src && S_ISREG(st.st_mode)) ++ snprintf(buf, bufsz, _("%s is not a block device; try \"-o loop\""), src); ++ else ++ snprintf(buf, bufsz, _("%s is not a block device"), src); ++ break; ++ ++ case ENXIO: ++ if (uflags & MNT_MS_NOFAIL) ++ return MNT_EX_SUCCESS; ++ if (buf) ++ snprintf(buf, bufsz, _("%s is not a valid block device"), src); ++ break; ++ ++ case EACCES: ++ case EROFS: ++ if (!buf) ++ break; ++ if (mflags & MS_RDONLY) ++ snprintf(buf, bufsz, _("cannot mount %s read-only"), src); ++ else if (mnt_context_is_rwonly_mount(cxt)) ++ snprintf(buf, bufsz, _("%s is write-protected but explicit read-write mode requested"), src); ++ else if (mflags & MS_REMOUNT) ++ snprintf(buf, bufsz, _("cannot remount %s read-write, is write-protected"), src); ++ else if (mflags & MS_BIND) ++ snprintf(buf, bufsz, _("bind %s failed"), src); ++ else { ++ errno = syserr; ++ snprintf(buf, bufsz, _("mount(2) system call failed: %m")); ++ } ++ break; ++ ++ case ENOMEDIUM: ++ if (uflags & MNT_MS_NOFAIL) ++ return MNT_EX_SUCCESS; ++ if (buf) ++ snprintf(buf, bufsz, _("no medium found on %s"), src); ++ break; ++ ++ case EBADMSG: ++ /* Bad CRC for classic filesystems (e.g. extN or XFS) */ ++ if (buf && src && stat(src, &st) == 0 ++ && (S_ISBLK(st.st_mode) || S_ISREG(st.st_mode))) { ++ snprintf(buf, bufsz, _("cannot mount; probably corrupted filesystem on %s"), src); ++ break; ++ } ++ /* fallthrough */ ++ ++ default: ++ if (buf) { ++ errno = syserr; ++ snprintf(buf, bufsz, _("mount(2) system call failed: %m")); ++ } ++ break; ++ } + +- return MNT_EX_FAIL; ++ return MNT_EX_FAIL; + } + diff --git a/60-rfkill.rules b/60-rfkill.rules new file mode 100644 index 000000000000..bc98a3bef78a --- /dev/null +++ b/60-rfkill.rules @@ -0,0 +1 @@ +KERNEL=="rfkill", GROUP="rfkill", MODE="0664" diff --git a/PKGBUILD b/PKGBUILD new file mode 100644 index 000000000000..d9a5e96478fd --- /dev/null +++ b/PKGBUILD @@ -0,0 +1,185 @@ +# Maintainer : Vincent Grande <shoober420@gmail.com> +# Contributor : Eric Vidal <eric@obarun.org> +# Contributor : Jean-Michel T.Dydak <jean-michel@obarun.org> +# Obarun PkgSrc : https://framagit.org/pkg/obcore/util-linux/ +#---------------- +# Contributor : Tom Gundersen <teg@jklm.no> +# Contributor : Dave Reisner <dreisner@archlinux.org> +# Contributor : judd <jvinet@zeroflux.org> +# Arch PkrSrc : https://www.archlinux.org/packages/core/x86_64/util-linux/ +#--------------------------------------------------------------------------- +# Website : https://www.kernel.org/pub/linux/utils/util-linux/ +#--------------------------------------------------------------------------- +#--DESCRIPTION-------------------------------------------------------------- + +pkgname=(util-linux-nosystemd-minimal-git util-linux-libs-nosystemd-minimal-git) + +pkgdesc="Miscellaneous system utilities for Linux" + +pkgver=2.36.1 +pkgrel=1 + +url='https://www.kernel.org/pub/linux/utils/util-linux' + +source=("git+https://github.com/karelzak/util-linux.git" + 'pam-login' + 'pam-common' + 'pam-runuser' + 'pam-su' + '60-rfkill.rules' + 'util-linux.sysusers' + '0001-libmount-don-t-use-symfollow-for-helpers-on-user-mounts.patch') + +#--BUILD CONFIGURATION------------------------------------------------------ + +options=( + 'strip') + +makedepends=( + 'python' + 'libcap-ng' + 'libxcrypt') + +#--BUILD PREPARATION-------------------------------------------------------- + +pkgver() { + cd util-linux + git describe --tags | sed 's/-/+/g' +} + +prepare() { + cd "$pkgbase-$pkgver" + + patch -Np1 < ../0001-libmount-don-t-use-symfollow-for-helpers-on-user-mounts.patch +} + +#--BUILD CONTROL------------------------------------------------------------ + +path=( + --prefix=/usr + --libdir=/usr/lib + --bindir=/usr/bin + --sbindir=/usr/bin + --localstatedir=/var +) + +flags=( + --enable-usrdir-path + --enable-fs-paths-default=/usr/bin:/usr/local/bin + --enable-raw + --enable-vipw + --enable-newgrp + --enable-chfn-chsh + --enable-write + --enable-mesg + --with-python=3 + --disable-hardlink + --with-systemdsystemunitdir=no + --with-systemd=no + --with-selinux=no + --with-audit=no +) + +#--BUILD-------------------------------------------------------------------- + +build() { + cd util-linux + + ./autogen.sh + ./configure "${path[@]}" "${flags[@]}" + make +} + +#--CHECK-------------------------------------------------------------------- + + +#--PACKAGE------------------------------------------------------------------ + +package_util-linux-nosystemd-minimal-git() { + conflicts=('rfkill' 'util-linux') + provides=('rfkill' 'util-linux') + replaces=('rfkill') + depends=( + 'pam' + 'shadow' + 'coreutils' + 'libutil-linux' + 'libeudev' + 'libcap-ng' + 'libxcrypt' + 'libcrypt.so' + 'libmagic.so' + 'libncursesw.so' + 'libreadline.so' + ) + optdepends=('python: python bindings to libmount' + 'words: default dictionary for look') + groups=('base' 'base-devel') + backup=(etc/pam.d/chfn + etc/pam.d/chsh + etc/pam.d/login + etc/pam.d/runuser + etc/pam.d/runuser-l + etc/pam.d/su + etc/pam.d/su-l) + + cd util-linux + + make DESTDIR="$pkgdir" install + + ## setuid chfn and chsh + chmod 4755 "$pkgdir"/usr/bin/{newgrp,ch{sh,fn}} + + ## install PAM files for login-utils + install -Dm 0644 "$srcdir/pam-common" "$pkgdir/etc/pam.d/chfn" + install -m 0644 "$srcdir/pam-common" "$pkgdir/etc/pam.d/chsh" + install -m 0644 "$srcdir/pam-login" "$pkgdir/etc/pam.d/login" + install -m 0644 "$srcdir/pam-runuser" "$pkgdir/etc/pam.d/runuser" + install -m 0644 "$srcdir/pam-runuser" "$pkgdir/etc/pam.d/runuser-l" + install -m 0644 "$srcdir/pam-su" "$pkgdir/etc/pam.d/su" + install -m 0644 "$srcdir/pam-su" "$pkgdir/etc/pam.d/su-l" + + ## adjust for usrmove + ## TODO(dreisner): fix configure.ac upstream so that this isn't needed + cd "$pkgdir" + mv usr/sbin/* usr/bin + rmdir usr/sbin + + ### runtime libs are shipped as part of util-linux-libs + rm "$pkgdir"/usr/lib/lib*.{a,so}* + + ### install pacopts applysys + install -Dm 0644 "$srcdir/util-linux.sysusers" \ + "$pkgdir/usr/lib/sysusers.d/util-linux.conf" + + install -Dm 0644 "$srcdir/60-rfkill.rules" \ + "$pkgdir/usr/lib/udev/rules.d/60-rfkill.rules" +} + +package_util-linux-libs-nosystemd-minimal-git() { + pkgdesc="util-linux runtime libraries" + provides=('util-linux-libs' 'libutil-linux' 'libblkid.so' 'libfdisk.so' 'libmount.so' 'libsmartcols.so' 'libuuid.so') + conflicts=('libutil-linux' 'util-linux-libs') + replaces=('libutil-linux') + + make -C util-linux DESTDIR="$pkgdir" install-usrlib_execLTLIBRARIES +} + +#--INSTALL CONFIGURATION---------------------------------------------------- + +arch=('x86_64') + +#--SECURITY AND LICENCE----------------------------------------------------- + +license=('GPL2') + +#validpgpkeys=('B0C64D14301CC6EFAEDF60E4E4B71D5EEC39C284') # Karel Zak + +sha256sums=('SKIP' + 'SKIP' + 'SKIP' + 'SKIP' + 'SKIP' + 'SKIP' + 'SKIP' + 'SKIP') diff --git a/pam-common b/pam-common new file mode 100644 index 000000000000..a7bf8a4a5b08 --- /dev/null +++ b/pam-common @@ -0,0 +1,6 @@ +#%PAM-1.0 +auth sufficient pam_rootok.so +auth required pam_unix.so +account required pam_unix.so +session required pam_unix.so +password required pam_permit.so diff --git a/pam-login b/pam-login new file mode 100644 index 000000000000..1960d9497c08 --- /dev/null +++ b/pam-login @@ -0,0 +1,7 @@ +#%PAM-1.0 + +auth required pam_securetty.so +auth requisite pam_nologin.so +auth include system-local-login +account include system-local-login +session include system-local-login diff --git a/pam-runuser b/pam-runuser new file mode 100644 index 000000000000..2eba78acdb23 --- /dev/null +++ b/pam-runuser @@ -0,0 +1,4 @@ +#%PAM-1.0 + +auth sufficient pam_rootok.so +session include system-login diff --git a/pam-su b/pam-su new file mode 100644 index 000000000000..cf15f40f1ae7 --- /dev/null +++ b/pam-su @@ -0,0 +1,9 @@ +#%PAM-1.0 +auth sufficient pam_rootok.so +# Uncomment the following line to implicitly trust users in the "wheel" group. +#auth sufficient pam_wheel.so trust use_uid +# Uncomment the following line to require a user to be in the "wheel" group. +#auth required pam_wheel.so use_uid +auth required pam_unix.so +account required pam_unix.so +session required pam_unix.so diff --git a/util-linux.sysusers b/util-linux.sysusers new file mode 100644 index 000000000000..56411a85231d --- /dev/null +++ b/util-linux.sysusers @@ -0,0 +1,3 @@ +u uuidd 68 +g rfkill - - - + |