Annotation of embedaddon/sudo/plugins/sudoers/auth/bsdauth.c, revision 1.1.1.5
1.1 misho 1: /*
1.1.1.3 misho 2: * Copyright (c) 2000-2005, 2007-2008, 2010-2013
1.1 misho 3: * Todd C. Miller <Todd.Miller@courtesan.com>
4: *
5: * Permission to use, copy, modify, and distribute this software for any
6: * purpose with or without fee is hereby granted, provided that the above
7: * copyright notice and this permission notice appear in all copies.
8: *
9: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15: * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16: *
17: * Sponsored in part by the Defense Advanced Research Projects
18: * Agency (DARPA) and Air Force Research Laboratory, Air Force
19: * Materiel Command, USAF, under agreement number F39502-99-1-0512.
20: */
21:
22: #include <config.h>
23:
24: #include <sys/types.h>
25: #include <stdio.h>
26: #ifdef STDC_HEADERS
27: # include <stdlib.h>
28: # include <stddef.h>
29: #else
30: # ifdef HAVE_STDLIB_H
31: # include <stdlib.h>
32: # endif
33: #endif /* STDC_HEADERS */
34: #ifdef HAVE_STRING_H
35: # include <string.h>
36: #endif /* HAVE_STRING_H */
37: #ifdef HAVE_STRINGS_H
38: # include <strings.h>
39: #endif /* HAVE_STRING_H */
40: #ifdef HAVE_UNISTD_H
41: # include <unistd.h>
42: #endif /* HAVE_UNISTD_H */
43: #include <ctype.h>
44: #include <pwd.h>
45: #include <signal.h>
46:
47: #include <login_cap.h>
48: #include <bsd_auth.h>
49:
50: #include "sudoers.h"
51: #include "sudo_auth.h"
52:
1.1.1.2 misho 53: # ifndef LOGIN_DEFROOTCLASS
54: # define LOGIN_DEFROOTCLASS "daemon"
55: # endif
56:
57: struct bsdauth_state {
58: auth_session_t *as;
59: login_cap_t *lc;
60: };
1.1 misho 61:
62: int
63: bsdauth_init(struct passwd *pw, sudo_auth *auth)
64: {
1.1.1.2 misho 65: static struct bsdauth_state state;
66: debug_decl(bsdauth_init, SUDO_DEBUG_AUTH)
1.1 misho 67:
1.1.1.2 misho 68: /* Get login class based on auth user, which may not be invoking user. */
69: if (pw->pw_class && *pw->pw_class)
70: state.lc = login_getclass(pw->pw_class);
71: else
72: state.lc = login_getclass(pw->pw_uid ? LOGIN_DEFCLASS : LOGIN_DEFROOTCLASS);
73: if (state.lc == NULL) {
1.1.1.3 misho 74: log_warning(USE_ERRNO|NO_MAIL,
75: N_("unable to get login class for user %s"), pw->pw_name);
1.1.1.2 misho 76: debug_return_int(AUTH_FATAL);
77: }
78:
79: if ((state.as = auth_open()) == NULL) {
1.1.1.3 misho 80: log_warning(USE_ERRNO|NO_MAIL,
81: N_("unable to begin bsd authentication"));
1.1.1.2 misho 82: login_close(state.lc);
83: debug_return_int(AUTH_FATAL);
1.1 misho 84: }
85:
86: /* XXX - maybe sanity check the auth style earlier? */
1.1.1.2 misho 87: login_style = login_getstyle(state.lc, login_style, "auth-sudo");
1.1 misho 88: if (login_style == NULL) {
1.1.1.3 misho 89: log_warning(NO_MAIL, N_("invalid authentication type"));
1.1.1.2 misho 90: auth_close(state.as);
91: login_close(state.lc);
92: debug_return_int(AUTH_FATAL);
1.1 misho 93: }
94:
1.1.1.2 misho 95: if (auth_setitem(state.as, AUTHV_STYLE, login_style) < 0 ||
96: auth_setitem(state.as, AUTHV_NAME, pw->pw_name) < 0 ||
97: auth_setitem(state.as, AUTHV_CLASS, login_class) < 0) {
1.1.1.4 misho 98: log_warning(NO_MAIL, N_("unable to initialize BSD authentication"));
1.1.1.2 misho 99: auth_close(state.as);
100: login_close(state.lc);
101: debug_return_int(AUTH_FATAL);
1.1 misho 102: }
103:
1.1.1.2 misho 104: auth->data = (void *) &state;
105: debug_return_int(AUTH_SUCCESS);
1.1 misho 106: }
107:
108: int
109: bsdauth_verify(struct passwd *pw, char *prompt, sudo_auth *auth)
110: {
111: char *pass;
112: char *s;
113: size_t len;
114: int authok = 0;
115: sigaction_t sa, osa;
1.1.1.2 misho 116: auth_session_t *as = ((struct bsdauth_state *) auth->data)->as;
117: debug_decl(bsdauth_verify, SUDO_DEBUG_AUTH)
1.1 misho 118:
119: /* save old signal handler */
120: sigemptyset(&sa.sa_mask);
121: sa.sa_flags = SA_RESTART;
122: sa.sa_handler = SIG_DFL;
123: (void) sigaction(SIGCHLD, &sa, &osa);
124:
125: /*
126: * If there is a challenge then print that instead of the normal
127: * prompt. If the user just hits return we prompt again with echo
128: * turned on, which is useful for challenge/response things like
129: * S/Key.
130: */
131: if ((s = auth_challenge(as)) == NULL) {
132: pass = auth_getpass(prompt, def_passwd_timeout * 60, SUDO_CONV_PROMPT_ECHO_OFF);
133: } else {
134: pass = auth_getpass(prompt, def_passwd_timeout * 60, SUDO_CONV_PROMPT_ECHO_OFF);
135: if (pass && *pass == '\0') {
136: if ((prompt = strrchr(s, '\n')))
137: prompt++;
138: else
139: prompt = s;
140:
141: /*
142: * Append '[echo on]' to the last line of the challenge and
143: * reprompt with echo turned on.
144: */
145: len = strlen(prompt) - 1;
146: while (isspace(prompt[len]) || prompt[len] == ':')
147: prompt[len--] = '\0';
148: easprintf(&s, "%s [echo on]: ", prompt);
149: pass = auth_getpass(prompt, def_passwd_timeout * 60,
150: SUDO_CONV_PROMPT_ECHO_ON);
151: free(s);
152: }
153: }
154:
155: if (pass) {
156: authok = auth_userresponse(as, pass, 1);
1.1.1.4 misho 157: memset_s(pass, SUDO_CONV_REPL_MAX, 0, strlen(pass));
1.1 misho 158: }
159:
160: /* restore old signal handler */
161: (void) sigaction(SIGCHLD, &osa, NULL);
162:
163: if (authok)
1.1.1.2 misho 164: debug_return_int(AUTH_SUCCESS);
1.1 misho 165:
166: if (!pass)
1.1.1.2 misho 167: debug_return_int(AUTH_INTR);
1.1 misho 168:
169: if ((s = auth_getvalue(as, "errormsg")) != NULL)
1.1.1.3 misho 170: log_warning(NO_MAIL, "%s", s);
1.1.1.2 misho 171: debug_return_int(AUTH_FAILURE);
1.1 misho 172: }
173:
174: int
175: bsdauth_cleanup(struct passwd *pw, sudo_auth *auth)
176: {
1.1.1.2 misho 177: struct bsdauth_state *state = auth->data;
178: debug_decl(bsdauth_cleanup, SUDO_DEBUG_AUTH)
1.1 misho 179:
1.1.1.2 misho 180: if (state != NULL) {
181: auth_close(state->as);
182: login_close(state->lc);
183: }
1.1 misho 184:
1.1.1.2 misho 185: debug_return_int(AUTH_SUCCESS);
1.1 misho 186: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>