]> git.ipfire.org Git - thirdparty/util-linux.git/blob - login-utils/auth.c
hwclock: free temporary variable before return
[thirdparty/util-linux.git] / login-utils / auth.c
1 /*
2 * auth.c -- PAM authorization code, common between chsh and chfn
3 * (c) 2012 by Cody Maloney <cmaloney@theoreticalchaos.com>
4 *
5 * this program is free software. you can redistribute it and
6 * modify it under the terms of the gnu general public license.
7 * there is no warranty.
8 *
9 */
10
11 #include <security/pam_appl.h>
12 #ifdef HAVE_SECURITY_PAM_MISC_H
13 # include <security/pam_misc.h>
14 #elif defined(HAVE_SECURITY_OPENPAM_H)
15 # include <security/openpam.h>
16 #endif
17
18 #include "c.h"
19 #include "auth.h"
20
21 static int pam_fail_check(pam_handle_t *pamh, int retcode)
22 {
23 if (retcode == PAM_SUCCESS)
24 return 0;
25 warnx("%s", pam_strerror(pamh, retcode));
26 pam_end(pamh, retcode);
27 return 1;
28 }
29
30 int auth_pam(const char *service_name, uid_t uid, const char *username)
31 {
32 if (uid != 0) {
33 pam_handle_t *pamh = NULL;
34 #ifdef HAVE_SECURITY_PAM_MISC_H
35 struct pam_conv conv = { misc_conv, NULL };
36 #elif defined(HAVE_SECURITY_OPENPAM_H)
37 struct pam_conv conv = { openpam_ttyconv, NULL };
38 #endif
39 int retcode;
40
41 retcode = pam_start(service_name, username, &conv, &pamh);
42 if (pam_fail_check(pamh, retcode))
43 return FALSE;
44
45 retcode = pam_authenticate(pamh, 0);
46 if (pam_fail_check(pamh, retcode))
47 return FALSE;
48
49 retcode = pam_acct_mgmt(pamh, 0);
50 if (retcode == PAM_NEW_AUTHTOK_REQD)
51 retcode =
52 pam_chauthtok(pamh, PAM_CHANGE_EXPIRED_AUTHTOK);
53 if (pam_fail_check(pamh, retcode))
54 return FALSE;
55
56 retcode = pam_setcred(pamh, 0);
57 if (pam_fail_check(pamh, retcode))
58 return FALSE;
59
60 pam_end(pamh, 0);
61 /* no need to establish a session; this isn't a
62 * session-oriented activity... */
63 }
64 return TRUE;
65 }