1 /* auth-pam.c -- PAM 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
13 * The conversation function (conversation) was inspired by/copied from
14 * openpam's openpam_ttyconv.c:
16 * Copyright (c) 2002-2003 Networks Associates Technology, Inc.
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions
21 * 1. Redistributions of source code must retain the above copyright
22 * notice, this list of conditions and the following disclaimer.
23 * 2. Redistributions in binary form must reproduce the above copyright
24 * notice, this list of conditions and the following disclaimer in the
25 * documentation and/or other materials provided with the distribution.
26 * 3. The name of the author may not be used to endorse or promote
27 * products derived from this software without specific prior written
30 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
31 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
32 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
33 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
34 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
35 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
36 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
37 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
38 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
39 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
49 #include <security/pam_appl.h>
54 static int conversation(int num_msg
, const struct pam_message
**msg
, struct
55 pam_response
**resp
, void *appdata_ptr
)
57 struct pam_response
*aresp
;
58 struct timespec
*timeout
= appdata_ptr
;
60 if (num_msg
<= 0 || num_msg
> PAM_MAX_NUM_MSG
)
63 if ((aresp
= calloc((size_t) num_msg
, sizeof *aresp
)) == NULL
)
66 for (int i
= 0; i
< num_msg
; i
++) {
67 switch (msg
[i
]->msg_style
) {
68 case PAM_PROMPT_ECHO_OFF
:
69 aresp
[i
].resp
= prompt_echo_off(msg
[i
]->msg
, timeout
);
70 if (aresp
[i
].resp
== NULL
)
73 case PAM_PROMPT_ECHO_ON
:
74 aresp
[i
].resp
= prompt(msg
[i
]->msg
, timeout
);
75 if (aresp
[i
].resp
== NULL
)
81 size_t msg_len
= strlen(msg
[i
]->msg
);
82 (void) fputs(msg
[i
]->msg
, stderr
);
83 if (msg_len
> 0 && msg
[i
]->msg
[msg_len
- 1] != '\n')
84 (void) fputc('\n', stderr
);
96 for (int i
= 0; i
< num_msg
; ++i
) {
97 if (aresp
[i
].resp
!= NULL
) {
98 memset(aresp
[i
].resp
, 0, strlen(aresp
[i
].resp
));
103 memset(aresp
, 0, num_msg
* sizeof *aresp
);
110 bool auth(const char *user
, struct timespec
*timeout
)
115 struct pam_conv pamc
= {
116 .conv
= conversation
,
117 .appdata_ptr
= timeout
,
121 pam_status
= pam_start("vlock", user
, &pamc
, &pamh
);
123 if (pam_status
!= PAM_SUCCESS
) {
124 fprintf(stderr
, "vlock-auth: %s\n", pam_strerror(pamh
, pam_status
));
128 /* put the username before the password prompt */
129 fprintf(stderr
, "%s's ", user
);
131 /* authenticate the user */
132 pam_status
= pam_authenticate(pamh
, 0);
134 if (pam_status
!= PAM_SUCCESS
) {
135 fprintf(stderr
, "vlock-auth: %s\n", pam_strerror(pamh
, pam_status
));
140 pam_end_status
= pam_end(pamh
, pam_status
);
142 if (pam_end_status
!= PAM_SUCCESS
) {
143 fprintf(stderr
, "vlock-auth: %s\n", pam_strerror(pamh
, pam_end_status
));
146 return (pam_status
== PAM_SUCCESS
);