Annotation of embedaddon/sudo/plugins/sudoers/check.c, revision 1.1.1.4
1.1 misho 1: /*
1.1.1.4 ! misho 2: * Copyright (c) 1993-1996,1998-2005, 2007-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 <sys/time.h>
26: #include <stdio.h>
27: #ifdef STDC_HEADERS
28: # include <stdlib.h>
29: # include <stddef.h>
30: #else
31: # ifdef HAVE_STDLIB_H
32: # include <stdlib.h>
33: # endif
34: #endif /* STDC_HEADERS */
35: #ifdef HAVE_STRING_H
36: # include <string.h>
37: #endif /* HAVE_STRING_H */
38: #ifdef HAVE_STRINGS_H
39: # include <strings.h>
40: #endif /* HAVE_STRINGS_H */
41: #ifdef HAVE_UNISTD_H
42: # include <unistd.h>
43: #endif /* HAVE_UNISTD_H */
44: #if TIME_WITH_SYS_TIME
45: # include <time.h>
46: #endif
47: #include <errno.h>
48: #include <fcntl.h>
49: #include <pwd.h>
50: #include <grp.h>
51:
52: #include "sudoers.h"
1.1.1.4 ! misho 53: #include "check.h"
1.1 misho 54:
1.1.1.4 ! misho 55: static bool display_lecture(int);
! 56: static struct passwd *get_authpw(void);
1.1 misho 57:
58: /*
1.1.1.4 ! misho 59: * Returns true if the user successfully authenticates, false if not
! 60: * or -1 on error.
1.1 misho 61: */
1.1.1.4 ! misho 62: static int
! 63: check_user_interactive(int validated, int mode, struct passwd *auth_pw)
! 64: {
! 65: int status, rval = true;
! 66: debug_decl(check_user_interactive, SUDO_DEBUG_AUTH)
! 67:
! 68: /* Always need a password when -k was specified with the command. */
! 69: if (ISSET(mode, MODE_IGNORE_TICKET))
! 70: SET(validated, FLAG_CHECK_USER);
! 71:
! 72: if (build_timestamp(auth_pw) == -1) {
! 73: rval = -1;
! 74: goto done;
! 75: }
! 76:
! 77: status = timestamp_status(auth_pw);
! 78:
! 79: if (status != TS_CURRENT || ISSET(validated, FLAG_CHECK_USER)) {
! 80: char *prompt;
! 81: bool lectured;
! 82:
! 83: /* Bail out if we are non-interactive and a password is required */
! 84: if (ISSET(mode, MODE_NONINTERACTIVE)) {
! 85: validated |= FLAG_NON_INTERACTIVE;
! 86: log_auth_failure(validated, 0);
! 87: rval = -1;
! 88: goto done;
! 89: }
! 90:
! 91: /* XXX - should not lecture if askpass helper is being used. */
! 92: lectured = display_lecture(status);
! 93:
! 94: /* Expand any escapes in the prompt. */
! 95: prompt = expand_prompt(user_prompt ? user_prompt : def_passprompt,
! 96: user_name, user_shost);
! 97:
! 98: rval = verify_user(auth_pw, prompt, validated);
! 99: if (rval == true && lectured)
! 100: set_lectured();
! 101: efree(prompt);
! 102: }
! 103: /* Only update timestamp if user was validated. */
! 104: if (rval == true && ISSET(validated, VALIDATE_OK) &&
! 105: !ISSET(mode, MODE_IGNORE_TICKET) && status != TS_ERROR)
! 106: update_timestamp(auth_pw);
! 107: done:
! 108: debug_return_bool(rval);
! 109: }
1.1 misho 110:
111: /*
1.1.1.3 misho 112: * Returns true if the user successfully authenticates, false if not
113: * or -1 on error.
1.1 misho 114: */
115: int
116: check_user(int validated, int mode)
117: {
118: struct passwd *auth_pw;
1.1.1.4 ! misho 119: int rval = true;
1.1.1.2 misho 120: debug_decl(check_user, SUDO_DEBUG_AUTH)
1.1 misho 121:
122: /*
123: * Init authentication system regardless of whether we need a password.
124: * Required for proper PAM session support.
125: */
126: auth_pw = get_authpw();
127: if (sudo_auth_init(auth_pw) == -1) {
128: rval = -1;
129: goto done;
130: }
131:
1.1.1.3 misho 132: /*
133: * Don't prompt for the root passwd or if the user is exempt.
134: * If the user is not changing uid/gid, no need for a password.
135: */
136: if (!def_authenticate || user_uid == 0 || user_is_exempt())
1.1 misho 137: goto done;
1.1.1.3 misho 138: if (user_uid == runas_pw->pw_uid &&
139: (!runas_gr || user_in_group(sudo_user.pw, runas_gr->gr_name))) {
140: #ifdef HAVE_SELINUX
141: if (user_role == NULL && user_type == NULL)
142: #endif
143: #ifdef HAVE_PRIV_SET
144: if (runas_privs == NULL && runas_limitprivs == NULL)
145: #endif
146: goto done;
147: }
148:
1.1.1.4 ! misho 149: rval = check_user_interactive(validated, mode, auth_pw);
1.1 misho 150:
151: done:
152: sudo_auth_cleanup(auth_pw);
1.1.1.3 misho 153: sudo_pw_delref(auth_pw);
1.1 misho 154:
1.1.1.2 misho 155: debug_return_bool(rval);
1.1 misho 156: }
157:
158: /*
1.1.1.4 ! misho 159: * Display sudo lecture (standard or custom).
! 160: * Returns true if the user was lectured, else false.
1.1 misho 161: */
1.1.1.4 ! misho 162: static bool
! 163: display_lecture(int status)
1.1 misho 164: {
165: FILE *fp;
166: char buf[BUFSIZ];
167: ssize_t nread;
168: struct sudo_conv_message msg;
169: struct sudo_conv_reply repl;
1.1.1.2 misho 170: debug_decl(lecture, SUDO_DEBUG_AUTH)
1.1 misho 171:
172: if (def_lecture == never ||
1.1.1.4 ! misho 173: (def_lecture == once && already_lectured(status)))
! 174: debug_return_bool(false);
1.1 misho 175:
176: memset(&msg, 0, sizeof(msg));
177: memset(&repl, 0, sizeof(repl));
178:
179: if (def_lecture_file && (fp = fopen(def_lecture_file, "r")) != NULL) {
180: while ((nread = fread(buf, sizeof(char), sizeof(buf) - 1, fp)) != 0) {
1.1.1.2 misho 181: buf[nread] = '\0';
1.1 misho 182: msg.msg_type = SUDO_CONV_ERROR_MSG;
183: msg.msg = buf;
184: sudo_conv(1, &msg, &repl);
185: }
186: fclose(fp);
187: } else {
188: msg.msg_type = SUDO_CONV_ERROR_MSG;
1.1.1.4 ! misho 189: msg.msg = _("\n"
! 190: "We trust you have received the usual lecture from the local System\n"
! 191: "Administrator. It usually boils down to these three things:\n\n"
! 192: " #1) Respect the privacy of others.\n"
! 193: " #2) Think before you type.\n"
! 194: " #3) With great power comes great responsibility.\n\n");
1.1 misho 195: sudo_conv(1, &msg, &repl);
196: }
1.1.1.4 ! misho 197: debug_return_bool(true);
1.1 misho 198: }
199:
200: /*
201: * Checks if the user is exempt from supplying a password.
202: */
1.1.1.2 misho 203: bool
1.1 misho 204: user_is_exempt(void)
205: {
1.1.1.2 misho 206: bool rval = false;
207: debug_decl(user_is_exempt, SUDO_DEBUG_AUTH)
208:
209: if (def_exempt_group)
210: rval = user_in_group(sudo_user.pw, def_exempt_group);
211: debug_return_bool(rval);
1.1 misho 212: }
213:
214: /*
215: * Get passwd entry for the user we are going to authenticate as.
216: * By default, this is the user invoking sudo. In the most common
217: * case, this matches sudo_user.pw or runas_pw.
218: */
219: static struct passwd *
220: get_authpw(void)
221: {
222: struct passwd *pw;
1.1.1.2 misho 223: debug_decl(get_authpw, SUDO_DEBUG_AUTH)
1.1 misho 224:
225: if (def_rootpw) {
226: if ((pw = sudo_getpwuid(ROOT_UID)) == NULL)
1.1.1.4 ! misho 227: log_fatal(0, N_("unknown uid: %u"), ROOT_UID);
1.1 misho 228: } else if (def_runaspw) {
229: if ((pw = sudo_getpwnam(def_runas_default)) == NULL)
1.1.1.4 ! misho 230: log_fatal(0, N_("unknown user: %s"), def_runas_default);
1.1 misho 231: } else if (def_targetpw) {
232: if (runas_pw->pw_name == NULL)
1.1.1.4 ! misho 233: log_fatal(NO_MAIL|MSG_ONLY, N_("unknown uid: %u"),
1.1 misho 234: (unsigned int) runas_pw->pw_uid);
1.1.1.3 misho 235: sudo_pw_addref(runas_pw);
1.1 misho 236: pw = runas_pw;
237: } else {
1.1.1.3 misho 238: sudo_pw_addref(sudo_user.pw);
1.1 misho 239: pw = sudo_user.pw;
240: }
241:
1.1.1.2 misho 242: debug_return_ptr(pw);
1.1 misho 243: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>