/src/sudo/lib/iolog/iolog_legacy.c
Line | Count | Source |
1 | | /* |
2 | | * SPDX-License-Identifier: ISC |
3 | | * |
4 | | * Copyright (c) 2009-2020 Todd C. Miller <Todd.Miller@sudo.ws> |
5 | | * |
6 | | * Permission to use, copy, modify, and distribute this software for any |
7 | | * purpose with or without fee is hereby granted, provided that the above |
8 | | * copyright notice and this permission notice appear in all copies. |
9 | | * |
10 | | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
11 | | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
12 | | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
13 | | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
14 | | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
15 | | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
16 | | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
17 | | */ |
18 | | |
19 | | #include <config.h> |
20 | | |
21 | | #include <stdio.h> |
22 | | #include <stdlib.h> |
23 | | #ifdef HAVE_STDBOOL_H |
24 | | # include <stdbool.h> |
25 | | #else |
26 | | # include <compat/stdbool.h> |
27 | | #endif /* HAVE_STDBOOL_H */ |
28 | | #include <string.h> |
29 | | #include <signal.h> |
30 | | #include <limits.h> |
31 | | #include <time.h> |
32 | | |
33 | | #include <sudo_compat.h> |
34 | | #include <sudo_debug.h> |
35 | | #include <sudo_eventlog.h> |
36 | | #include <sudo_fatal.h> |
37 | | #include <sudo_gettext.h> |
38 | | #include <sudo_iolog.h> |
39 | | #include <sudo_util.h> |
40 | | |
41 | | bool |
42 | | iolog_parse_loginfo_legacy(FILE *fp, const char *iolog_dir, |
43 | | struct eventlog *evlog) |
44 | 392 | { |
45 | 392 | char *buf = NULL, *cp, *ep; |
46 | 392 | const char *errstr; |
47 | 392 | size_t bufsize = 0, cwdsize = 0, cmdsize = 0; |
48 | 392 | bool ret = false; |
49 | 392 | debug_decl(iolog_parse_loginfo_legacy, SUDO_DEBUG_UTIL); |
50 | | |
51 | | /* |
52 | | * Info file has three lines: |
53 | | * 1) a log info line |
54 | | * 2) cwd |
55 | | * 3) command with args |
56 | | */ |
57 | 392 | if (getdelim(&buf, &bufsize, '\n', fp) == -1 || |
58 | 392 | getdelim(&evlog->cwd, &cwdsize, '\n', fp) == -1 || |
59 | 370 | getdelim(&evlog->command, &cmdsize, '\n', fp) == -1) { |
60 | 42 | sudo_warn(U_("%s: invalid log file"), iolog_dir); |
61 | 42 | goto done; |
62 | 42 | } |
63 | | |
64 | | /* Strip the newline from the cwd and command. */ |
65 | 350 | evlog->cwd[strcspn(evlog->cwd, "\n")] = '\0'; |
66 | 350 | evlog->command[strcspn(evlog->command, "\n")] = '\0'; |
67 | | |
68 | | /* |
69 | | * Crack the log line (lines and cols not present in old versions). |
70 | | * timestamp:user:runas_user:runas_group:tty:lines:cols |
71 | | * XXX - probably better to use strtok and switch on the state. |
72 | | */ |
73 | 350 | buf[strcspn(buf, "\n")] = '\0'; |
74 | 350 | cp = buf; |
75 | | |
76 | | /* timestamp */ |
77 | 350 | if ((ep = strchr(cp, ':')) == NULL) { |
78 | 19 | sudo_warn(U_("%s: time stamp field is missing"), iolog_dir); |
79 | 19 | goto done; |
80 | 19 | } |
81 | 331 | *ep = '\0'; |
82 | 331 | evlog->event_time.tv_sec = |
83 | 331 | (time_t)sudo_strtonum(cp, 0, TIME_T_MAX, &errstr); |
84 | 331 | if (errstr != NULL) { |
85 | 111 | sudo_warn(U_("%s: time stamp %s: %s"), iolog_dir, cp, errstr); |
86 | 111 | goto done; |
87 | 111 | } |
88 | | |
89 | | /* submit user */ |
90 | 220 | cp = ep + 1; |
91 | 220 | if ((ep = strchr(cp, ':')) == NULL) { |
92 | 135 | sudo_warn(U_("%s: user field is missing"), iolog_dir); |
93 | 135 | goto done; |
94 | 135 | } |
95 | 85 | if ((evlog->submituser = strndup(cp, (size_t)(ep - cp))) == NULL) { |
96 | 0 | sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory")); |
97 | 0 | goto done; |
98 | 0 | } |
99 | | |
100 | | /* runas user */ |
101 | 85 | cp = ep + 1; |
102 | 85 | if ((ep = strchr(cp, ':')) == NULL) { |
103 | 1 | sudo_warn(U_("%s: runas user field is missing"), iolog_dir); |
104 | 1 | goto done; |
105 | 1 | } |
106 | 84 | if ((evlog->runuser = strndup(cp, (size_t)(ep - cp))) == NULL) { |
107 | 0 | sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory")); |
108 | 0 | goto done; |
109 | 0 | } |
110 | | |
111 | | /* runas group */ |
112 | 84 | cp = ep + 1; |
113 | 84 | if ((ep = strchr(cp, ':')) == NULL) { |
114 | 1 | sudo_warn(U_("%s: runas group field is missing"), iolog_dir); |
115 | 1 | goto done; |
116 | 1 | } |
117 | 83 | if (cp != ep) { |
118 | 1 | if ((evlog->rungroup = strndup(cp, (size_t)(ep - cp))) == NULL) { |
119 | 0 | sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory")); |
120 | 0 | goto done; |
121 | 0 | } |
122 | 1 | } |
123 | | |
124 | | /* tty, followed by optional lines + cols */ |
125 | 83 | cp = ep + 1; |
126 | 83 | if ((ep = strchr(cp, ':')) == NULL) { |
127 | | /* just the tty */ |
128 | 2 | if ((evlog->ttyname = strdup(cp)) == NULL) { |
129 | 0 | sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory")); |
130 | 0 | goto done; |
131 | 0 | } |
132 | 81 | } else { |
133 | | /* tty followed by lines + cols */ |
134 | 81 | if ((evlog->ttyname = strndup(cp, (size_t)(ep - cp))) == NULL) { |
135 | 0 | sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory")); |
136 | 0 | goto done; |
137 | 0 | } |
138 | 81 | cp = ep + 1; |
139 | | /* need to NULL out separator to use sudo_strtonum() */ |
140 | | /* XXX - use sudo_strtonumx */ |
141 | 81 | if ((ep = strchr(cp, ':')) != NULL) { |
142 | 12 | *ep = '\0'; |
143 | 12 | } |
144 | 81 | evlog->lines = (int)sudo_strtonum(cp, 1, INT_MAX, &errstr); |
145 | 81 | if (errstr != NULL) { |
146 | 56 | sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO, |
147 | 56 | "%s: tty lines %s: %s", iolog_dir, cp, errstr); |
148 | 56 | } |
149 | 81 | if (ep != NULL) { |
150 | 12 | cp = ep + 1; |
151 | 12 | evlog->columns = (int)sudo_strtonum(cp, 1, INT_MAX, &errstr); |
152 | 12 | if (errstr != NULL) { |
153 | 8 | sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO, |
154 | 8 | "%s: tty cols %s: %s", iolog_dir, cp, errstr); |
155 | 8 | } |
156 | 12 | } |
157 | 81 | } |
158 | | |
159 | 83 | ret = true; |
160 | | |
161 | 392 | done: |
162 | 392 | free(buf); |
163 | | debug_return_bool(ret); |
164 | 392 | } |