src/util.c: shut up gcc warnings
[vlock.git] / src / auth-shadow.c
blob9b1891184698921c8fe72fd74d5d4ee5152796c6
1 /* auth-shadow.c -- shadow authentification routine for vlock,
2 * the VT locking program for linux
4 * This program is copyright (C) 2007 Frank Benkstein, and is free
5 * software which is freely distributable under the terms of the
6 * GNU General Public License version 2, included as the file COPYING in this
7 * distribution. It is NOT public domain software, and any
8 * redistribution not permitted by the GNU General Public License is
9 * expressly forbidden without prior written permission from
10 * the author.
14 /* for crypt() */
15 #define _XOPEN_SOURCE
17 #ifndef __FreeBSD__
18 /* for asprintf() */
19 #define _GNU_SOURCE
20 #endif
22 #include <stdbool.h>
23 #include <unistd.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <errno.h>
29 #include <sys/mman.h>
31 #include <shadow.h>
33 #include "auth.h"
34 #include "prompt.h"
36 GQuark vlock_auth_error_quark(void)
38 return g_quark_from_static_string("vlock-auth-shadow-error-quark");
41 bool auth(const char *user, struct timespec *timeout, GError **error)
43 char *pwd;
44 char *cryptpw;
45 char *msg;
46 struct spwd *spw;
47 int result = false;
49 g_return_val_if_fail(error == NULL || *error == NULL, false);
51 /* format the prompt */
52 if (asprintf(&msg, "%s's Password: ", user) < 0) {
53 g_propagate_error(error,
54 g_error_new_literal(
55 VLOCK_AUTH_ERROR,
56 VLOCK_AUTH_ERROR_FAILED,
57 g_strerror(errno)));
58 return false;
61 if ((pwd = prompt_echo_off(msg, timeout, error)) == NULL)
62 goto prompt_error;
64 errno = 0;
66 /* get the shadow password */
67 if ((spw = getspnam(user)) == NULL) {
68 if (errno == 0)
69 goto auth_error;
71 g_set_error(error,
72 VLOCK_AUTH_ERROR,
73 VLOCK_AUTH_ERROR_FAILED,
74 "Could not get shadow record: %s",
75 g_strerror(errno));
76 goto shadow_error;
79 /* hash the password */
80 if ((cryptpw = crypt(pwd, spw->sp_pwdp)) == NULL) {
81 g_set_error(error,
82 VLOCK_AUTH_ERROR,
83 VLOCK_AUTH_ERROR_FAILED,
84 "crypt() failed: %s",
85 g_strerror(errno));
86 goto shadow_error;
89 result = (strcmp(cryptpw, spw->sp_pwdp) == 0);
91 if (!result) {
92 auth_error:
93 sleep(1);
94 g_propagate_error(error,
95 g_error_new_literal(
96 VLOCK_AUTH_ERROR,
97 VLOCK_AUTH_ERROR_DENIED,
98 "Authentication failure"));
101 shadow_error:
102 /* deallocate shadow resources */
103 endspent();
105 /* free the password */
106 free(pwd);
108 prompt_error:
109 /* free the prompt */
110 free(msg);
112 g_assert(result || error != NULL);
114 return result;