31
31
#include <unistd.h>
33
33
#include <syslog.h>
36
35
#include <sys/types.h>
37
36
#include <sys/wait.h>
38
37
#include <sys/types.h>
39
38
#include <sys/stat.h>
40
#include <sys/fsuid.h>
43
40
#include <security/pam_modules.h>
44
#include <security/pam_ext.h>
45
41
#include "../include/ecryptfs.h"
47
43
#define PRIVATE_DIR "Private"
49
/* returns: 0 if file does not exist, 1 if it exists, <0 for error */
50
static int file_exists_dotecryptfs(const char *homedir, char *filename)
55
if (asprintf(&file_path, "%s/.ecryptfs/%s", homedir, filename) == -1)
57
if (stat(file_path, &s) != 0) {
68
static int wrap_passphrase_if_necessary(const char *username, uid_t uid, char *wrapped_pw_filename, char *passphrase, char *salt)
70
char *unwrapped_pw_filename = NULL;
74
rc = asprintf(&unwrapped_pw_filename, "/dev/shm/.ecryptfs-%s", username);
76
syslog(LOG_ERR, "pam_ecryptfs: Unable to allocate memory\n");
79
/* If /dev/shm/.ecryptfs-$USER exists and owned by the user
80
and ~/.ecryptfs/wrapped-passphrase does not exist
81
and a passphrase is set:
82
wrap the unwrapped passphrase file */
83
if (stat(unwrapped_pw_filename, &s) == 0 && (s.st_uid == uid) &&
84
stat(wrapped_pw_filename, &s) != 0 &&
85
passphrase != NULL && *passphrase != '\0' &&
86
username != NULL && *username != '\0') {
88
rc = ecryptfs_wrap_passphrase_file(wrapped_pw_filename, passphrase, salt, unwrapped_pw_filename);
90
syslog(LOG_ERR, "pam_ecryptfs: Error wrapping cleartext password; " "rc = [%d]\n", rc);
45
static void error(const char *msg)
47
syslog(LOG_ERR, "errno = [%i]; strerror = [%m]\n", errno);
50
syslog(LOG_ERR, "%s: Requested key not available\n", msg);
54
syslog(LOG_ERR, "%s: Key has expired\n", msg);
58
syslog(LOG_ERR, "%s: Key has been revoked\n", msg);
62
syslog(LOG_ERR, "%s: Key was rejected by service\n", msg);
65
syslog(LOG_ERR, "%s: Unknown key error\n", msg);
97
70
PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc,
100
uid_t uid = 0, oeuid = 0;
101
long ngroups_max = sysconf(_SC_NGROUPS_MAX);
102
gid_t gid = 0, oegid = 0, groups[ngroups_max+1];
104
74
char *homedir = NULL;
105
76
const char *username;
106
77
char *passphrase = NULL;
107
78
char salt[ECRYPTFS_SALT_SIZE];
108
79
char salt_hex[ECRYPTFS_SALT_SIZE_HEX];
109
char *auth_tok_sig = NULL;
110
char *private_mnt = NULL;
111
81
pid_t child_pid, tmp_pid;
84
syslog(LOG_INFO, "%s: Called\n", __FUNCTION__);
114
85
rc = pam_get_user(pamh, &username, NULL);
115
86
if (rc == PAM_SUCCESS) {
116
87
struct passwd *pwd;
89
syslog(LOG_INFO, "%s: username = [%s]\n", __FUNCTION__,
118
91
pwd = getpwnam(username);
120
93
uid = pwd->pw_uid;
122
94
homedir = pwd->pw_dir;
125
syslog(LOG_ERR, "pam_ecryptfs: Error getting passwd info for user [%s]; rc = [%ld]\n", username, rc);
131
if ((ngids = getgroups(sizeof(groups)/sizeof(gid_t), groups)) < 0) {
132
syslog(LOG_ERR, "pam_ecryptfs: geteuid error");
136
if (setegid(gid) < 0 || setgroups(1, &gid) < 0 || seteuid(uid) < 0) {
137
syslog(LOG_ERR, "pam_ecryptfs: seteuid error");
141
if (!file_exists_dotecryptfs(homedir, "auto-mount"))
143
private_mnt = ecryptfs_fetch_private_mnt(homedir);
144
if (ecryptfs_private_is_mounted(NULL, private_mnt, NULL, 1)) {
145
syslog(LOG_DEBUG, "pam_ecryptfs: %s: %s is already mounted\n", __FUNCTION__, homedir);
146
/* If private/home is already mounted, then we can skip
147
costly loading of keys */
150
if(file_exists_dotecryptfs(homedir, "wrapping-independent") == 1)
151
rc = pam_prompt(pamh, PAM_PROMPT_ECHO_OFF, &passphrase, "Encryption passphrase: ");
153
rc = pam_get_item(pamh, PAM_AUTHTOK, (const void **)&passphrase);
97
syslog(LOG_ERR, "Error getting passwd info for user [%s]; "
98
"rc = [%ld]\n", username, rc);
101
saved_uid = geteuid();
103
rc = pam_get_item(pamh, PAM_AUTHTOK, (const void **)&passphrase);
154
105
if (rc != PAM_SUCCESS) {
155
syslog(LOG_ERR, "pam_ecryptfs: Error retrieving passphrase; rc = [%ld]\n",
106
syslog(LOG_ERR, "Error retrieving passphrase; rc = [%ld]\n",
159
110
auth_tok_sig = malloc(ECRYPTFS_SIG_SIZE_HEX + 1);
160
111
if (!auth_tok_sig) {
162
syslog(LOG_ERR, "pam_ecryptfs: Out of memory\n");
113
syslog(LOG_ERR, "Out of memory\n");
165
116
rc = ecryptfs_read_salt_hex_from_rc(salt_hex);
118
syslog(LOG_WARNING, "%s\n", ECRYPTFS_WARN_DEFAULT_SALT);
167
119
from_hex(salt, ECRYPTFS_DEFAULT_SALT_HEX, ECRYPTFS_SALT_SIZE);
169
121
from_hex(salt, salt_hex, ECRYPTFS_SALT_SIZE);
170
122
if ((child_pid = fork()) == 0) {
171
/* temp regain uid 0 to drop privs */
173
/* setgroups() already called */
174
if (setgid(gid) < 0 || setuid(uid) < 0)
177
124
if (passphrase == NULL) {
178
syslog(LOG_ERR, "pam_ecryptfs: NULL passphrase; aborting\n");
125
syslog(LOG_ERR, "NULL passphrase; aborting\n");
182
129
if ((rc = ecryptfs_validate_keyring())) {
183
syslog(LOG_WARNING, "pam_ecryptfs: Cannot validate keyring integrity\n");
131
"Cannot validate keyring integrity\n");
187
135
&& (memcmp(argv[0], "unwrap\0", 7) == 0)) {
188
136
char *wrapped_pw_filename;
191
139
&wrapped_pw_filename, "%s/.ecryptfs/%s",
193
141
ECRYPTFS_DEFAULT_WRAPPED_PASSPHRASE_FILENAME);
195
syslog(LOG_ERR, "pam_ecryptfs: Unable to allocate memory\n");
143
syslog(LOG_ERR, "Unable to allocate memory\n");
199
if (wrap_passphrase_if_necessary(username, uid, wrapped_pw_filename, passphrase, salt) == 0) {
200
syslog(LOG_DEBUG, "pam_ecryptfs: Passphrase file wrapped");
204
147
rc = ecryptfs_insert_wrapped_passphrase_into_keyring(
205
148
auth_tok_sig, wrapped_pw_filename, passphrase,
312
255
if ((pid = fork()) < 0) {
313
syslog(LOG_ERR, "pam_ecryptfs: Error setting up private mount");
256
syslog(LOG_ERR, "Error setting up private mount");
317
260
if (mount == 1) {
318
if ((asprintf(&recorded,
319
"%s/.ecryptfs/.wrapped-passphrase.recorded",
320
pwd->pw_dir) < 0) || recorded == NULL) {
321
syslog(LOG_ERR, "pam_ecryptfs: Error allocating memory for recorded name");
324
if (stat(recorded, &s) != 0 && stat("/usr/share/ecryptfs-utils/ecryptfs-record-passphrase", &s) == 0) {
325
/* User has not recorded their passphrase */
326
unlink("/var/lib/update-notifier/user.d/ecryptfs-record-passphrase");
327
symlink("/usr/share/ecryptfs-utils/ecryptfs-record-passphrase", "/var/lib/update-notifier/user.d/ecryptfs-record-passphrase");
328
fd = open("/var/lib/update-notifier/dpkg-run-stamp", O_WRONLY|O_CREAT|O_NONBLOCK, 0666);
332
261
if (stat(autofile, &s) != 0) {
333
262
/* User does not want to auto-mount */
334
syslog(LOG_DEBUG, "pam_ecryptfs: Skipping automatic eCryptfs mount");
264
"Skipping automatic eCryptfs mount");
338
if (setgroups(1, &pwd->pw_gid) < 0 || setgid(pwd->pw_gid) < 0)
340
267
/* run mount.ecryptfs_private as the user */
341
if (setresuid(pwd->pw_uid, pwd->pw_uid, pwd->pw_uid) < 0)
343
execl("/sbin/mount.ecryptfs_private",
268
setresuid(pwd->pw_uid, pwd->pw_uid, pwd->pw_uid);
269
execl("/sbin/mount.ecryptfs_private",
344
270
"mount.ecryptfs_private", NULL);
346
272
if (stat(autofile, &s) != 0) {
347
273
/* User does not want to auto-unmount */
348
syslog(LOG_DEBUG, "pam_ecryptfs: Skipping automatic eCryptfs unmount");
275
"Skipping automatic eCryptfs unmount");
352
if (setgroups(1, &pwd->pw_gid) < 0 || setgid(pwd->pw_gid) < 0)
354
278
/* run umount.ecryptfs_private as the user */
355
if (setresuid(pwd->pw_uid, pwd->pw_uid, pwd->pw_uid) < 0)
357
execl("/sbin/umount.ecryptfs_private",
279
setresuid(pwd->pw_uid, pwd->pw_uid, pwd->pw_uid);
280
execl("/sbin/umount.ecryptfs_private",
358
281
"umount.ecryptfs_private", NULL);
363
285
waitpid(pid, &rc, 0);
287
"Mount of private directory return code [%d]", rc);
416
342
pwd = getpwnam(username);
418
344
uid = pwd->pw_uid;
420
345
homedir = pwd->pw_dir;
423
syslog(LOG_ERR, "pam_ecryptfs: Error getting passwd info for user [%s]; rc = [%d]\n", username, rc);
429
if ((ngids = getgroups(sizeof(groups)/sizeof(gid_t), groups)) < 0) {
430
syslog(LOG_ERR, "pam_ecryptfs: geteuid error");
434
if (setegid(gid) < 0 || setgroups(1, &gid) < 0 || seteuid(uid) < 0) {
435
syslog(LOG_ERR, "pam_ecryptfs: seteuid error");
349
syslog(LOG_ERR, "Error getting passwd info for user [%s]; "
350
"rc = [%ld]\n", username, rc);
353
saved_uid = geteuid();
439
355
if ((rc = pam_get_item(pamh, PAM_OLDAUTHTOK,
440
356
(const void **)&old_passphrase))
441
357
!= PAM_SUCCESS) {
442
syslog(LOG_ERR, "pam_ecryptfs: Error retrieving old passphrase; rc = [%d]\n", rc);
358
syslog(LOG_ERR, "Error retrieving old passphrase; rc = [%d]\n",
445
363
/* On the first pass, do nothing except check that we have a password */
446
364
if ((flags & PAM_PRELIM_CHECK)) {
447
365
if (!old_passphrase)
449
syslog(LOG_WARNING, "pam_ecryptfs: PAM passphrase change module retrieved a NULL passphrase; nothing to do\n");
367
syslog(LOG_WARNING, "eCryptfs PAM passphrase change "
368
"module retrieved a NULL passphrase; nothing to "
450
370
rc = PAM_AUTHTOK_RECOVER_ERR;
454
375
if ((rc = pam_get_item(pamh, PAM_AUTHTOK,
455
376
(const void **)&new_passphrase))
456
377
!= PAM_SUCCESS) {
457
syslog(LOG_ERR, "pam_ecryptfs: Error retrieving new passphrase; rc = [%d]\n", rc);
378
syslog(LOG_ERR, "Error retrieving new passphrase; rc = [%d]\n",
460
383
if ((rc = asprintf(&wrapped_pw_filename, "%s/.ecryptfs/%s", homedir,
461
384
ECRYPTFS_DEFAULT_WRAPPED_PASSPHRASE_FILENAME))
463
syslog(LOG_ERR, "pam_ecryptfs: Unable to allocate memory\n");
386
syslog(LOG_ERR, "Unable to allocate memory\n");
390
rc = asprintf(&unwrapped_pw_filename, "/dev/shm/.ecryptfs-%s", name);
392
syslog(LOG_ERR, "Unable to allocate memory\n");
467
396
if ((rc = ecryptfs_read_salt_hex_from_rc(salt_hex))) {
397
syslog(LOG_WARNING, "%s\n", ECRYPTFS_WARN_DEFAULT_SALT);
468
398
from_hex(salt, ECRYPTFS_DEFAULT_SALT_HEX, ECRYPTFS_SALT_SIZE);
470
400
from_hex(salt, salt_hex, ECRYPTFS_SALT_SIZE);
472
if (wrap_passphrase_if_necessary(username, uid, wrapped_pw_filename, new_passphrase, salt) == 0) {
473
syslog(LOG_DEBUG, "pam_ecryptfs: Passphrase file wrapped");
402
/* If /dev/shm/.ecryptfs-$USER exists and owned by the user
403
and ~/.ecryptfs/wrapped-passphrase does not exist
404
and a new_passphrase is set:
405
wrap the unwrapped passphrase file */
406
if (stat(unwrapped_pw_filename, &s) == 0 && (s.st_uid == uid) &&
407
stat(wrapped_pw_filename, &s) != 0 &&
408
new_passphrase != NULL && *new_passphrase != '\0' &&
409
name != NULL && *name != '\0') {
411
rc = ecryptfs_wrap_passphrase_file(wrapped_pw_filename,
412
new_passphrase, salt, unwrapped_pw_filename);
415
"Error wrapping cleartext password; "
478
421
if (!old_passphrase || !new_passphrase || *new_passphrase == '\0') {
479
syslog(LOG_WARNING, "pam_ecryptfs: PAM passphrase change module retrieved at least one NULL passphrase; nothing to do\n");
422
syslog(LOG_WARNING, "eCryptfs PAM passphrase change module "
423
"retrieved at least one NULL passphrase; nothing to "
480
425
rc = PAM_AUTHTOK_RECOVER_ERR;
484
429
if ((child_pid = fork()) == 0) {
485
430
char passphrase[ECRYPTFS_MAX_PASSWORD_LENGTH + 1];
487
/* temp regain uid 0 to drop privs */
489
/* setgroups() already called */
490
if (setgid(gid) < 0 || setuid(uid) < 0)
493
433
if ((rc = ecryptfs_unwrap_passphrase(passphrase,
494
434
wrapped_pw_filename,
495
435
old_passphrase, salt))) {
496
syslog(LOG_ERR, "pam_ecryptfs: Error attempting to unwrap passphrase; rc = [%d]\n", rc);
436
syslog(LOG_ERR, "Error attempting to unwrap "
437
"passphrase; rc = [%d]\n", rc);
499
440
if ((rc = ecryptfs_wrap_passphrase(wrapped_pw_filename,
500
441
new_passphrase, salt,
502
syslog(LOG_ERR, "pam_ecryptfs: Error attempting to wrap passphrase; rc = [%d]", rc);
443
syslog(LOG_ERR, "Error attempting to wrap passphrase; "
508
450
if ((tmp_pid = waitpid(child_pid, NULL, 0)) == -1)
509
syslog(LOG_WARNING, "pam_ecryptfs: waitpid() returned with error condition\n");
452
"waitpid() returned with error condition\n");
510
453
free(wrapped_pw_filename);
515
setgroups(ngids, groups);