2
* Copyright (C) 2009 International Business Machines
3
* Author(s): Tyler Hicks <tyhicks@linux.vnet.ibm.com>
5
* This program is free software; you can redistribute it and/or
6
* modify it under the terms of the GNU General Public License as
7
* published by the Free Software Foundation; either version 2 of the
8
* License, or (at your option) any later version.
10
* This program is distributed in the hope that it will be useful, but
11
* WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
* General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
31
fprintf(stderr, "\teCryptfs umount helper\n\tusage: "
32
"umount [ecryptfs mount point]\n"
38
* Parses a string of mount options, searching for an option name, and returns
39
* a pointer to the option value. For example, if name was "ecryptfs_sig=",
40
* it would set value to a string containing the sig, up to the first
41
* comma or NULL character in the mount options. Name must end with an = sign.
42
* value must be freed by the caller.
44
static int get_mount_opt_value(char *mnt_opts, char *name, char **value)
46
char *name_start, *val_start, *val_stop;
47
size_t name_len, val_len;
50
name_len = strlen(name);
51
if (name[name_len - 1] != '=') {
56
name_start = strstr(mnt_opts, name);
62
val_start = name_start + name_len;
63
val_stop = strstr(val_start, ",");
65
val_stop = mnt_opts + strlen(mnt_opts);
67
val_len = val_stop - val_start;
68
*value = malloc(val_len + 1);
73
memcpy(*value, val_start, val_len);
74
(*value)[val_len] = '\0';
79
static int unlink_keys_from_keyring(const char *mnt_point)
81
struct mntent *mntent;
83
char *fekek_sig = NULL, *fnek_sig = NULL;
84
int fekek_fail = 0, fnek_fail = 0;
87
file = setmntent("/etc/mtab", "r");
92
while ((mntent = getmntent(file))) {
93
if (strcmp("ecryptfs", mntent->mnt_type))
95
if (strcmp(mnt_point, mntent->mnt_dir))
103
if (!hasmntopt(mntent, "ecryptfs_unlink_sigs")) {
107
rc = get_mount_opt_value(mntent->mnt_opts, "ecryptfs_sig=", &fekek_sig);
109
fekek_fail = ecryptfs_remove_auth_tok_from_keyring(fekek_sig);
110
if (fekek_fail == ENOKEY)
113
fprintf(stderr, "Failed to remove fekek with sig [%s] "
114
"from keyring: %s\n", fekek_sig,
115
strerror(fekek_fail));
119
if (!get_mount_opt_value(mntent->mnt_opts,
120
"ecryptfs_fnek_sig=", &fnek_sig)
121
&& strcmp(fekek_sig, fnek_sig)) {
122
fnek_fail = ecryptfs_remove_auth_tok_from_keyring(fnek_sig);
123
if (fnek_fail == ENOKEY)
126
fprintf(stderr, "Failed to remove fnek with sig [%s] "
127
"from keyring: %s\n", fnek_sig,
128
strerror(fnek_fail));
136
return (fekek_fail ? fekek_fail : (fnek_fail ? fnek_fail : rc));
139
static int construct_umount_args(int argc, char **argv, char ***new_argv)
141
int new_argc = argc + 1;
144
*new_argv = malloc(sizeof(char *) * (new_argc + 1));
149
(*new_argv)[0] = "umount";
150
(*new_argv)[1] = "-i";
151
for (i = 2; i < new_argc; i++)
152
(*new_argv)[i] = argv[i - 1];
153
(*new_argv)[i] = NULL;
159
#define UMOUNT_PATH "/bin/umount"
160
int main(int argc, char **argv)
168
if (unlink_keys_from_keyring(argv[1]))
169
fprintf(stderr, "Could not unlink the key(s) from your keying. "
170
"Please use `keyctl unlink` if you wish to remove the "
171
"key(s). Proceeding with umount.\n");
172
rc = construct_umount_args(argc, argv, &new_argv);
174
fprintf(stderr, "Failed to construct umount arguments: %s\n",
178
rc = execv(UMOUNT_PATH, new_argv);
181
fprintf(stderr, "Failed to execute %s: %m\n", UMOUNT_PATH);