diff -u ecryptfs-utils-53/debian/changelog ecryptfs-utils-53/debian/changelog --- ecryptfs-utils-53/debian/changelog +++ ecryptfs-utils-53/debian/changelog @@ -1,3 +1,18 @@ +ecryptfs-utils (53-1ubuntu10) intrepid; urgency=low + + [Dustin Kirkland] + * debian/patches/45-mount_private_counter.dpatch: implement a counter to + track mounts/unmounts of the private directory; unmount if the + counter is 0; allow a -f override to force unmount. LP: #259293. + + [Steve Langasek] + * debian/patches/50-error-on-empty-password.dpatch: return + PAM_AUTHTOK_RECOVER_ERR from the password changing module if we + didn't get a password from the other modules in the stack, instead + of returning success. LP: #272232. + + -- Dustin Kirkland Fri, 17 Oct 2008 01:00:12 -0500 + ecryptfs-utils (53-1ubuntu9) intrepid; urgency=low * debian/patches/35-silence_useless_mount_messages.dpatch: silence error diff -u ecryptfs-utils-53/debian/patches/00list ecryptfs-utils-53/debian/patches/00list --- ecryptfs-utils-53/debian/patches/00list +++ ecryptfs-utils-53/debian/patches/00list @@ -7,0 +8,2 @@ +45-mount_private_counter.dpatch +50-error-on-empty-password.dpatch only in patch2: unchanged: --- ecryptfs-utils-53.orig/debian/patches/45-mount_private_counter.dpatch +++ ecryptfs-utils-53/debian/patches/45-mount_private_counter.dpatch @@ -0,0 +1,187 @@ +#!/bin/sh /usr/share/dpatch/dpatch-run +# 45-mount_private_counter.dpatch +# Dustin Kirkland +# +# Implement a mount/unmount counter, update the manpage + +@DPATCH@ + +--- ecryptfs-utils-53/doc/manpage/umount.ecryptfs_private.1 2008-07-23 11:17:30.000000000 -0500 ++++ ecryptfs-utils-53/doc/manpage/umount.ecryptfs_private.1 2008-10-16 23:08:23.057270798 -0500 +@@ -3,7 +3,13 @@ + umount.ecryptfs_private \- eCryptfs private unmount helper. + + .SH SYNOPSIS +-\fBumount.ecryptfs_private\fP ++\fBumount.ecryptfs_private\fP [\-f] ++ ++.SH OPTIONS ++Options available for the \fBumount.ecryptfs_private\fP command: ++.TP ++.B \-f ++Force the unmount, ignoring the value of the mount counter in \fI/tmp/ecryptfs-USERNAME-Private\fP + + .SH DESCRIPTION + \fBumount.ecryptfs_private\fP is a mount helper utility for non-root users to unmount a cryptographically mounted private directory, ~/Private. +@@ -12,6 +18,7 @@ If, and only if: + - the private mount passphrase is in their kernel keyring, and + - the current user owns both ~/.Private and ~/Private, and + - ~/.Private is currently mounted on ~/Private ++ - the mount counter is 0 (counter is ignored if \-f option is used) + + This program will: + - unmount ~/Private +@@ -27,6 +34,8 @@ The system administrator can add the pam + + \fI~/.ecryptfs/Private.sig\fP - file containing signature of mountpoint passphrase + ++\fI/tmp/ecryptfs-USERNAME-Private\fP - file containing the mount counter, incremented on each mount, decremented on each unmount ++ + .SH SEE ALSO + .PD 0 + .TP +--- ecryptfs-utils-53/src/utils/mount.ecryptfs_private.c 2008-10-16 22:52:50.545866066 -0500 ++++ ecryptfs-utils-53/src/utils/mount.ecryptfs_private.c 2008-10-16 23:24:33.756948619 -0500 +@@ -25,6 +25,7 @@ + */ + + ++#include + #include + #include + #include +@@ -254,6 +255,87 @@ int update_mtab(char *dev, char *mnt, ch + } + + ++int bump_counter(char *u, int delta) { ++/* Maintain a mount counter ++ * increment on delta = 1 ++ * decrement on delta = -1 ++ * remove the counter file on delta = 0 ++ * return the updated count, negative on error ++ */ ++ char *f; ++ FILE *fh; ++ struct stat s; ++ mode_t m; ++ int count; ++ /* We expect /tmp to exist, be writeable by the user, ++ * and for this file to be cleared on boot */ ++ if ( ++ asprintf(&f, "/tmp/%s-%s-%s", FSTYPE, u, PRIVATE_DIR) < 0 ++ ) { ++ perror("asprintf"); ++ return -1; ++ } ++ if (delta == 0) { ++ /* Try to remove the counter file */ ++ return unlink(f); ++ } ++ if (stat(f, &s) == 0) { ++ /* If the counter file exists, open for reading/writing */ ++ fh = fopen(f, "r+"); ++ } else { ++ /* If the counter file does not exist, create for writing */ ++ m = umask(0177); ++ fh = fopen(f, "w+"); ++ umask(m); ++ } ++ if (fh == NULL) { ++ perror("fopen"); ++ return -1; ++ } ++ /* Lock the file for reading/writing */ ++ if (flock(fileno(fh), LOCK_EX) != 0) { ++ perror("flock"); ++ return -1; ++ } ++ rewind(fh); ++ /* Read the count from file, default to 0 */ ++ if (fscanf(fh, "%d\n", &count) != 1) { ++ count = 0; ++ } ++ /* Increment/decrement the counter */ ++ count += delta; ++ if (count < 0) { ++ /* Don't set a count less than 0 */ ++ count = 0; ++ } ++ /* Write the count to file */ ++ rewind(fh); ++ fprintf(fh, "%d\n", count); ++ /* Unlock the file */ ++ if (flock(fileno(fh), LOCK_UN) != 0) { ++ perror("flock"); ++ } ++ return count; ++} ++ ++ ++int increment(char *u) { ++/* Bump counter up */ ++ return bump_counter(u, 1); ++} ++ ++ ++int decrement(char *u) { ++/* Bump counter down */ ++ return bump_counter(u, -1); ++} ++ ++int zero(char *u) { ++/* Remove the counter file */ ++ return bump_counter(u, 0); ++} ++ ++ + /* This program is a setuid-executable allowing a non-privileged user to mount + * and unmount an ecryptfs private directory. This program is necessary to + * keep from adding such entries to /etc/fstab. +@@ -289,7 +371,7 @@ int update_mtab(char *dev, char *mnt, ch + * c) updating /etc/mtab + */ + int main(int argc, char *argv[]) { +- int uid, rc, mounting; ++ int uid, rc, mounting, force; + struct passwd *pwd; + char *dev, *mnt, *opt; + char *sig; +@@ -321,6 +403,12 @@ int main(int argc, char *argv[]) { + mounting = 1; + } else { + mounting = 0; ++ /* Determine if unmounting is forced */ ++ if (argv[1] != NULL && strncmp(argv[1], "-f", 2) == 0) { ++ force = 1; ++ } else { ++ force = 0; ++ } + } + + /* Fetch signature from file */ +@@ -355,6 +443,8 @@ int main(int argc, char *argv[]) { + } + + if (mounting == 1) { ++ /* Increment mount counter, errors non-fatal */ ++ increment(pwd->pw_name); + /* Mounting, so exit if already mounted */ + if (is_mounted(dev, mnt, sig, mounting) == 1) { + /* fputs("Already mounted\n", stderr); */ +@@ -380,6 +470,15 @@ int main(int argc, char *argv[]) { + return 1; + } + } else { ++ /* Decrement counter, exiting if >0, and non-forced unmount */ ++ if (decrement(pwd->pw_name) > 0 && force != 1) { ++ fputs("Sessions still open, not unmounting\n", stderr); ++ return 1; ++ } ++ /* If we have made it here, zero the counter, ++ * as we are going to unmount. ++ */ ++ zero(pwd->pw_name); + /* Unmounting, so exit if not mounted */ + if (is_mounted(dev, mnt, sig, mounting) == 0) { + /* fputs("Not currently mounted\n", stderr); */ only in patch2: unchanged: --- ecryptfs-utils-53.orig/debian/patches/50-error-on-empty-password.dpatch +++ ecryptfs-utils-53/debian/patches/50-error-on-empty-password.dpatch @@ -0,0 +1,42 @@ +#!/bin/sh /usr/share/dpatch/dpatch-run +# 50-error-on-empty-password.dpatch +# Steve Langasek +# +# Return PAM_AUTHTOK_RECOVER_ERR from pam_sm_chauthtok() if we didn't receive +# a password from earlier modules in the stack + +@DPATCH@ +--- ecryptfs-utils-53/src/pam_ecryptfs/pam_ecryptfs.c 2008-10-17 00:46:22.053831882 -0500 ++++ ecryptfs-utils-53/src/pam_ecryptfs/pam_ecryptfs.c 2008-10-17 00:48:12.121213631 -0500 +@@ -357,6 +357,18 @@ PAM_EXTERN int pam_sm_chauthtok(pam_hand + seteuid(saved_uid); + goto out; + } ++ /* On the first pass, do nothing except check that we have a password */ ++ if ((flags & PAM_PRELIM_CHECK)) { ++ if (!old_passphrase) ++ { ++ syslog(LOG_WARNING, "eCryptfs PAM passphrase change " ++ "module retrieved a NULL passphrase; nothing to " ++ "do\n"); ++ rc = PAM_AUTHTOK_RECOVER_ERR; ++ } ++ seteuid(saved_uid); ++ goto out; ++ } + if ((rc = pam_get_item(pamh, PAM_AUTHTOK, + (const void **)&new_passphrase)) + != PAM_SUCCESS) { +@@ -366,10 +378,11 @@ PAM_EXTERN int pam_sm_chauthtok(pam_hand + goto out; + } + seteuid(saved_uid); +- if (!old_passphrase || !new_passphrase) { ++ if (!old_passphrase || !new_passphrase || *new_passphrase == '\0') { + syslog(LOG_WARNING, "eCryptfs PAM passphrase change module " + "retrieved at least one NULL passphrase; nothing to " + "do\n"); ++ rc = PAM_AUTHTOK_RECOVER_ERR; + goto out; + } + if ((rc = asprintf(&wrapped_pw_filename, "%s/.ecryptfs/%s", homedir,