Use utab if mtab is a symbolic link
This commit is contained in:
@ -37,6 +37,7 @@ AM_CFLAGS = -Wall -Werror=format-security \
|
||||
-fstack-protector --param=ssp-buffer-size=4
|
||||
DEFS = -DPROGRAM_NAME=\"mount.davfs\" \
|
||||
-DDAV_SYS_CONF_DIR=\"$(pkgsysconfdir)\" \
|
||||
-DDAV_LOCALSTATE_DIR=\"$(dav_localstatedir)\" \
|
||||
-DDAV_SYS_RUN=\"$(pkglocalstatedir)\" \
|
||||
-DDAV_SYS_CACHE=\"$(pkgsyscachedir)\" \
|
||||
-DDAV_SECRETS=\"secrets\" \
|
||||
|
@ -28,10 +28,15 @@
|
||||
/* These Macros will be defined by the command line option -D of the
|
||||
preprocessor:
|
||||
|
||||
The name of the program.
|
||||
The name of the program, usually mount.davfs.
|
||||
DPROGRAM_NAME
|
||||
|
||||
The directory to store the PID-file.
|
||||
The system directory that holds runtime status information, usually
|
||||
/var/run or /run.
|
||||
DAV_LOCALSTATE_DIR
|
||||
|
||||
The directory to store the PID-file, usually /var/run/mount.davfs
|
||||
or /run/mount.davfs.
|
||||
DAV_SYS_RUN
|
||||
|
||||
The directory for translated messages (gettext).
|
||||
@ -45,13 +50,15 @@
|
||||
/* These Macros will be defined by the command line option -D of the
|
||||
preprocessor:
|
||||
|
||||
The directory where the system wide configuration file is located.
|
||||
The directory where the system wide configuration file is located,
|
||||
usually either /etc/davfs2 or /urs/local/etc/davfs2.
|
||||
DAV_SYS_CONF_DIR
|
||||
|
||||
The name of the configuration file.
|
||||
The name of the configuration file, usually davfs2.conf.
|
||||
DAV_CONFIG
|
||||
|
||||
The directory where the template of the configuration file is located.
|
||||
The directory where the template of the configuration file is located
|
||||
usually either /usr/share/davfs2 or /usr/local/share/davfs2.
|
||||
DAV_DATA_DIR
|
||||
|
||||
*/
|
||||
@ -63,11 +70,11 @@
|
||||
/* These Macros will be defined by the command line option -D of the
|
||||
preprocessor:
|
||||
|
||||
The program will run as this user if invoked by root.
|
||||
The program will run as this user if invoked by root, usually davfs2.
|
||||
May be overridden by system config file.
|
||||
DAV_USER
|
||||
|
||||
The program will belong to this group.
|
||||
The program will belong to this group, usually davfs2.
|
||||
May be overridden by system config file.
|
||||
DAV_GROUP
|
||||
*/
|
||||
@ -79,6 +86,20 @@
|
||||
/* File system type to be used with 'mount -t' and fstab. */
|
||||
#define DAV_FS_TYPE "davfs"
|
||||
|
||||
/* If _PATH_MOUNTED (the mtab file) is a symbolic link (to /proc/mounts)
|
||||
some information required for umount is missing (e.g. the option
|
||||
user=<name of the mounting user|) and in the case of davfs2 the file
|
||||
system type will not be davfs but that of the kernel file system
|
||||
(fuse or coda). Newer versions of the mount program will store this
|
||||
information in the utab-file /var/run/mount/utab or /run/mount/utab.
|
||||
davfs2 will do the same. */
|
||||
|
||||
/* The subdirectory of DAV_LOCALSTATE_DIR where the utab-file is placed. */
|
||||
#define DAV_UTAB_DIR "mount"
|
||||
|
||||
/* The name of the utab-file. */
|
||||
#define DAV_UTAB "utab"
|
||||
|
||||
/* The file davfs reads mtab entries from. If not available it will
|
||||
use _PATH_MOUNTED. */
|
||||
#define DAV_MOUNTS "/proc/mounts"
|
||||
|
@ -59,6 +59,9 @@
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_FILE_H
|
||||
#include <sys/file.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_MOUNT_H
|
||||
#include <sys/mount.h>
|
||||
#endif
|
||||
@ -455,14 +458,36 @@ check_dirs(dav_args *args)
|
||||
struct stat st;
|
||||
char *fname;
|
||||
|
||||
if (lstat(_PATH_MOUNTED, &st) != 0)
|
||||
error(EXIT_FAILURE, errno, _("can't access file %s"), _PATH_MOUNTED);
|
||||
int mtab_is_link = S_ISLNK(st.st_mode);
|
||||
|
||||
if (stat(DAV_MOUNTS, &st) == 0) {
|
||||
mounts = DAV_MOUNTS;
|
||||
args->use_utab = mtab_is_link;
|
||||
} else {
|
||||
mounts = _PATH_MOUNTED;
|
||||
}
|
||||
if (debug)
|
||||
syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG), "mounts in: %s", mounts);
|
||||
|
||||
if (!args->use_utab) {
|
||||
char *utab_dir = xasprintf("%s/%s", DAV_LOCALSTATE_DIR, DAV_UTAB_DIR);
|
||||
if (stat(utab_dir, &st) != 0) {
|
||||
gain_privileges(args);
|
||||
if (mkdir(utab_dir, S_IRWXU | S_IRGRP | S_IXGRP
|
||||
| S_IROTH | S_IXOTH) != 0) {
|
||||
syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG), " and %s/%s",
|
||||
utab_dir, DAV_UTAB);
|
||||
}else {
|
||||
error(0, errno, _("can't create directory %s"),
|
||||
utab_dir);
|
||||
}
|
||||
release_privileges(args);
|
||||
}
|
||||
free(utab_dir);
|
||||
}
|
||||
|
||||
gain_privileges(args);
|
||||
if (stat(DAV_SYS_RUN, &st) != 0) {
|
||||
if (mkdir(DAV_SYS_RUN, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH | S_ISVTX)
|
||||
@ -1171,42 +1196,101 @@ termination_handler(int signo)
|
||||
|
||||
|
||||
/* Adds an entry to _PATH_MOUNTED for the mounted file system.
|
||||
If _PATH_MOUNTED is a symbolic link to /proc/mounts it will write an
|
||||
entry into /var/run/mount/utab instead.
|
||||
If this fails a warning will be printed, but this will not stop mounting. */
|
||||
static void
|
||||
write_mtab_entry(const dav_args *args)
|
||||
{
|
||||
struct mntent mntent;
|
||||
mntent.mnt_fsname = url;
|
||||
mntent.mnt_dir = mpoint;
|
||||
mntent.mnt_type = DAV_FS_TYPE;
|
||||
mntent.mnt_opts = xasprintf("%s%s%s%s%s%s",
|
||||
(args->mopts & MS_RDONLY) ? "ro" : "rw",
|
||||
(args->mopts & MS_NOSUID) ? ",nosuid" : "",
|
||||
(args->mopts & MS_NOEXEC) ? ",noexec" : "",
|
||||
(args->mopts & MS_NODEV) ? ",nodev" : "",
|
||||
(args->netdev) ? ",_netdev" : "",
|
||||
(args->add_mopts != NULL) ? args->add_mopts : "");
|
||||
mntent. mnt_freq = 0;
|
||||
mntent. mnt_passno = 0;
|
||||
mntent.mnt_opts = NULL;
|
||||
char *utab_line = NULL;
|
||||
char *tab_file = NULL;
|
||||
char *lock_file = NULL;
|
||||
|
||||
if (!args->privileged) {
|
||||
char *opts = mntent.mnt_opts;
|
||||
mntent.mnt_opts = xasprintf("%s,user=%s", opts, args->uid_name);
|
||||
free(opts);
|
||||
if (args->use_utab) {
|
||||
utab_line = xasprintf("SRC=%s TARGET=%s ROOT=/ OPTS=%s%s%shelper=%s\n",
|
||||
url, mpoint,
|
||||
(!args->privileged) ? "user=" : "",
|
||||
(!args->privileged) ? args->uid_name : "",
|
||||
(!args->privileged) ? "," : "",
|
||||
DAV_FS_TYPE);
|
||||
tab_file = xasprintf("%s/%s/%s", DAV_LOCALSTATE_DIR, DAV_UTAB_DIR,
|
||||
DAV_UTAB);
|
||||
lock_file = xasprintf("%s,lock", tab_file);
|
||||
|
||||
} else {
|
||||
mntent.mnt_fsname = url;
|
||||
mntent.mnt_dir = mpoint;
|
||||
mntent.mnt_type = DAV_FS_TYPE;
|
||||
mntent.mnt_opts = xasprintf("%s%s%s%s%s%s%s%s",
|
||||
(args->mopts & MS_RDONLY) ? "ro" : "rw",
|
||||
(args->mopts & MS_NOSUID) ? ",nosuid" : "",
|
||||
(args->mopts & MS_NOEXEC) ? ",noexec" : "",
|
||||
(args->mopts & MS_NODEV) ? ",nodev" : "",
|
||||
(args->netdev) ? ",_netdev" : "",
|
||||
(args->add_mopts != NULL) ? args->add_mopts : "",
|
||||
(!args->privileged) ? ",user=" : "",
|
||||
(!args->privileged) ? args->uid_name : "");
|
||||
mntent. mnt_freq = 0;
|
||||
mntent. mnt_passno = 0;
|
||||
tab_file = xstrdup(_PATH_MOUNTED);
|
||||
lock_file = xasprintf("%s~", tab_file);
|
||||
}
|
||||
|
||||
sigset_t oldset;
|
||||
sigemptyset(&oldset);
|
||||
sigset_t newset;
|
||||
sigfillset(&newset);
|
||||
sigprocmask(SIG_BLOCK, &newset, &oldset);
|
||||
|
||||
gain_privileges(args);
|
||||
FILE *mtab = setmntent(_PATH_MOUNTED, "a");
|
||||
if (mtab) {
|
||||
addmntent(mtab, &mntent);
|
||||
endmntent(mtab);
|
||||
} else {
|
||||
error(0, 0, _("Warning: can't write entry into mtab, but will mount "
|
||||
"the file system anyway"));
|
||||
|
||||
int ld = open(lock_file, O_RDONLY | O_CREAT,
|
||||
S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
|
||||
if (!ld)
|
||||
error(EXIT_FAILURE, errno, _("can't create file %s"), lock_file);
|
||||
while (flock(ld, LOCK_EX) != 0) {
|
||||
if (errno == EAGAIN || errno == EINTR)
|
||||
continue;
|
||||
error(EXIT_FAILURE, errno, _("can't lock file %s"), lock_file);
|
||||
}
|
||||
|
||||
FILE *tab = NULL;
|
||||
if (args->use_utab) {
|
||||
tab = fopen(tab_file, "a");
|
||||
} else {
|
||||
tab = setmntent(tab_file, "a");
|
||||
}
|
||||
int err = 0;
|
||||
if (tab) {
|
||||
if (args->use_utab) {
|
||||
if (fputs(utab_line, tab) == EOF)
|
||||
err = 1;
|
||||
fclose(tab);
|
||||
} else {
|
||||
if (addmntent(tab, &mntent) != 0)
|
||||
err = 1;
|
||||
endmntent(tab);
|
||||
}
|
||||
}
|
||||
if (!tab || err)
|
||||
error(0, 0, _("Warning: can't write entry into %s, but will mount "
|
||||
"the file system anyway"), tab_file);
|
||||
|
||||
close(ld);
|
||||
remove(lock_file);
|
||||
release_privileges(args);
|
||||
|
||||
free(mntent.mnt_opts);
|
||||
sigprocmask(SIG_SETMASK, &oldset, NULL);
|
||||
if (lock_file)
|
||||
free(lock_file);
|
||||
if (tab_file)
|
||||
free(tab_file);
|
||||
if (utab_line)
|
||||
free(utab_line);
|
||||
if (mntent.mnt_opts)
|
||||
free(mntent.mnt_opts);
|
||||
}
|
||||
|
||||
|
||||
|
@ -52,6 +52,7 @@ typedef struct {
|
||||
int netdev; /* Command line */
|
||||
unsigned long int mopts; /* Command line */
|
||||
char *add_mopts;
|
||||
int use_utab;
|
||||
size_t buf_size; /* User config file, system config file */
|
||||
/* File mode */
|
||||
uid_t fsuid; /* Command line */
|
||||
|
@ -128,7 +128,7 @@ main(int argc, char *argv[])
|
||||
if (!mpoint)
|
||||
mpoint = argv[optind];
|
||||
if (!mpoint || *mpoint != '/')
|
||||
error(EXIT_FAILURE, 0, _("can't determine mount point"));
|
||||
error(EXIT_FAILURE, errno, _("can't determine mount point"));
|
||||
|
||||
char *m = mpoint;
|
||||
while (*m == '/')
|
||||
|
Reference in New Issue
Block a user