1 /*
2 * Copyright (c) 2021 Todd C. Miller <Todd.Miller@sudo.ws>
3 *
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17 #include <config.h>
18
19 #include <sys/types.h>
20 #include <sys/socket.h>
21 #include <netinet/in.h>
22 #include <arpa/inet.h>
23
24 #include <stdarg.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #if defined(HAVE_STDINT_H)
28 # include <stdint.h>
29 #elif defined(HAVE_INTTYPES_H)
30 # include <inttypes.h>
31 #endif
32 #include <errno.h>
33 #include <fcntl.h>
34 #include <netdb.h>
35 #include <unistd.h>
36 #include <string.h>
37 #ifndef HAVE_GETADDRINFO
38 # include "compat/getaddrinfo.h"
39 #endif
40
41 #include "sudoers.h"
42 #include "interfaces.h"
43
44 extern char **environ;
45 extern sudo_dso_public struct policy_plugin sudoers_policy;
46
47 const char *path_plugin_dir = _PATH_SUDO_PLUGIN_DIR;
48 char *audit_msg;
49
50 static int pass;
51
52 static FILE *
open_data(const uint8_t * data,size_t size)53 open_data(const uint8_t *data, size_t size)
54 {
55 #ifdef HAVE_FMEMOPEN
56 /* Operate in-memory. */
57 return fmemopen((void *)data, size, "r");
58 #else
59 char tempfile[] = "/tmp/sudoers.XXXXXX";
60 size_t nwritten;
61 int fd;
62
63 /* Use (unlinked) temporary file. */
64 fd = mkstemp(tempfile);
65 if (fd == -1)
66 return NULL;
67 unlink(tempfile);
68 nwritten = write(fd, data, size);
69 if (nwritten != size) {
70 close(fd);
71 return NULL;
72 }
73 lseek(fd, 0, SEEK_SET);
74 return fdopen(fd, "r");
75 #endif
76 }
77
78 /*
79 * Array that gets resized as needed.
80 */
81 struct dynamic_array {
82 char **entries;
83 size_t len;
84 size_t size;
85 };
86
87 static void
free_strvec(char ** vec)88 free_strvec(char **vec)
89 {
90 int i;
91
92 for (i = 0; vec[i] != NULL; i++)
93 free(vec[i]);
94 }
95
96 static void
free_dynamic_array(struct dynamic_array * arr)97 free_dynamic_array(struct dynamic_array *arr)
98 {
99 if (arr->entries != NULL) {
100 free_strvec(arr->entries);
101 free(arr->entries);
102 }
103 memset(arr, 0, sizeof(*arr));
104 }
105
106 static bool
push(struct dynamic_array * arr,const char * entry)107 push(struct dynamic_array *arr, const char *entry)
108 {
109 char *copy = NULL;
110
111 if (entry != NULL) {
112 if ((copy = strdup(entry)) == NULL)
113 return false;
114 }
115
116 if (arr->len + (entry != NULL) >= arr->size) {
117 char **tmp = reallocarray(arr->entries, arr->size + 128, sizeof(char *));
118 if (tmp == NULL) {
119 free(copy);
120 return false;
121 }
122 arr->entries = tmp;
123 arr->size += 128;
124 }
125 if (copy != NULL)
126 arr->entries[arr->len++] = copy;
127 arr->entries[arr->len] = NULL;
128
129 return true;
130 }
131
132 static int
fuzz_conversation(int num_msgs,const struct sudo_conv_message msgs[],struct sudo_conv_reply replies[],struct sudo_conv_callback * callback)133 fuzz_conversation(int num_msgs, const struct sudo_conv_message msgs[],
134 struct sudo_conv_reply replies[], struct sudo_conv_callback *callback)
135 {
136 return 0;
137 }
138
139 static int
fuzz_printf(int msg_type,const char * fmt,...)140 fuzz_printf(int msg_type, const char *fmt, ...)
141 {
142 return 0;
143 }
144
145 int
fuzz_hook_stub(struct sudo_hook * hook)146 fuzz_hook_stub(struct sudo_hook *hook)
147 {
148 return 0;
149 }
150
151 /*
152 * The fuzzing environment may not have DNS available, this may result
153 * in long delays that cause a timeout when fuzzing. This getaddrinfo()
154 * can look up "localhost" and returns an error for anything else.
155 */
156 #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
157 int
158 # ifdef HAVE_GETADDRINFO
getaddrinfo(const char * nodename,const char * servname,const struct addrinfo * hints,struct addrinfo ** res)159 getaddrinfo(
160 # else
161 sudo_getaddrinfo(
162 # endif
163 const char *nodename, const char *servname,
164 const struct addrinfo *hints, struct addrinfo **res)
165 {
166 struct addrinfo *ai;
167 struct in_addr addr;
168
169 /* Stub getaddrinfo(3) to avoid a DNS timeout in CIfuzz. */
170 if (strcmp(nodename, "localhost") != 0 || servname != NULL)
171 return EAI_FAIL;
172
173 /* Hard-code localhost. */
174 ai = calloc(1, sizeof(*ai) + sizeof(struct sockaddr_in));
175 if (ai == NULL)
176 return EAI_MEMORY;
177 ai->ai_canonname = strdup("localhost");
178 if (ai == NULL) {
179 free(ai);
180 return EAI_MEMORY;
181 }
182 ai->ai_family = AF_INET;
183 ai->ai_protocol = IPPROTO_TCP;
184 ai->ai_addrlen = sizeof(struct sockaddr_in);
185 ai->ai_addr = (struct sockaddr *)(ai + 1);
186 inet_pton(AF_INET, "127.0.0.1", &addr);
187 ((struct sockaddr_in *)ai->ai_addr)->sin_family = AF_INET;
188 ((struct sockaddr_in *)ai->ai_addr)->sin_addr = addr;
189 *res = ai;
190 return 0;
191 }
192
193 void
194 # ifdef HAVE_GETADDRINFO
freeaddrinfo(struct addrinfo * ai)195 freeaddrinfo(struct addrinfo *ai)
196 # else
197 sudo_freeaddrinfo(struct addrinfo *ai)
198 # endif
199 {
200 struct addrinfo *next;
201
202 while (ai != NULL) {
203 next = ai->ai_next;
204 free(ai->ai_canonname);
205 free(ai);
206 ai = next;
207 }
208 }
209 #endif /* FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */
210
211 enum fuzz_policy_pass {
212 PASS_NONE,
213 PASS_VERSION,
214 PASS_CHECK_LOG_LOCAL,
215 PASS_CHECK_LOG_REMOTE,
216 PASS_CHECK_NOT_FOUND,
217 PASS_CHECK_NOT_FOUND_DOT,
218 PASS_LIST,
219 PASS_LIST_OTHER,
220 PASS_LIST_CHECK,
221 PASS_VALIDATE,
222 PASS_INVALIDATE
223 };
224
225 int
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)226 LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
227 {
228 struct dynamic_array plugin_args = { NULL };
229 struct dynamic_array settings = { NULL };
230 struct dynamic_array user_info = { NULL };
231 struct dynamic_array argv = { NULL };
232 struct dynamic_array env_add = { NULL };
233 char **command_info = NULL, **argv_out = NULL, **user_env_out = NULL;
234 const char *errstr = NULL;
235 const int num_passes = 10;
236 char *line = NULL;
237 size_t linesize = 0;
238 ssize_t linelen;
239 int res = 1;
240 FILE *fp;
241
242 fp = open_data(data, size);
243 if (fp == NULL)
244 return 0;
245
246 setprogname("fuzz_policy");
247 sudoers_debug_register(getprogname(), NULL);
248
249 /* user_info and settings must be non-NULL (even if empty). */
250 push(&user_info, NULL);
251 push(&settings, NULL);
252
253 /* Iterate over each line of data. */
254 while ((linelen = getdelim(&line, &linesize, '\n', fp)) != -1) {
255 if (line[linelen - 1] == '\n')
256 line[linelen - 1] = '\0';
257
258 /* Skip comments and blank lines. */
259 if (line[0] == '#' || line[0] == '\0')
260 continue;
261
262 /* plugin args */
263 if (strncmp(line, "error_recovery=", sizeof("error_recovery=") - 1) == 0) {
264 push(&plugin_args, line);
265 continue;
266 }
267 if (strncmp(line, "sudoers_file=", sizeof("sudoers_file=") - 1) == 0) {
268 push(&plugin_args, line);
269 continue;
270 }
271 if (strncmp(line, "sudoers_mode=", sizeof("sudoers_mode=") - 1) == 0) {
272 push(&plugin_args, line);
273 continue;
274 }
275 if (strncmp(line, "sudoers_gid=", sizeof("sudoers_gid=") - 1) == 0) {
276 push(&plugin_args, line);
277 continue;
278 }
279 if (strncmp(line, "sudoers_uid=", sizeof("sudoers_uid=") - 1) == 0) {
280 push(&plugin_args, line);
281 continue;
282 }
283 if (strncmp(line, "ldap_conf=", sizeof("ldap_conf=") - 1) == 0) {
284 push(&plugin_args, line);
285 continue;
286 }
287 if (strncmp(line, "ldap_secret=", sizeof("ldap_secret=") - 1) == 0) {
288 push(&plugin_args, line);
289 continue;
290 }
291
292 /* user info */
293 if (strncmp(line, "user=", sizeof("user=") - 1) == 0) {
294 push(&user_info, line);
295 continue;
296 }
297 if (strncmp(line, "uid=", sizeof("uid=") - 1) == 0) {
298 push(&user_info, line);
299 continue;
300 }
301 if (strncmp(line, "gid=", sizeof("gid=") - 1) == 0) {
302 push(&user_info, line);
303 continue;
304 }
305 if (strncmp(line, "groups=", sizeof("groups=") - 1) == 0) {
306 push(&user_info, line);
307 continue;
308 }
309 if (strncmp(line, "cwd=", sizeof("cwd=") - 1) == 0) {
310 push(&user_info, line);
311 continue;
312 }
313 if (strncmp(line, "tty=", sizeof("tty=") - 1) == 0) {
314 push(&user_info, line);
315 continue;
316 }
317 if (strncmp(line, "host=", sizeof("host=") - 1) == 0) {
318 push(&user_info, line);
319 continue;
320 }
321 if (strncmp(line, "lines=", sizeof("lines=") - 1) == 0) {
322 push(&user_info, line);
323 continue;
324 }
325 if (strncmp(line, "cols=", sizeof("cols=") - 1) == 0) {
326 push(&user_info, line);
327 continue;
328 }
329 if (strncmp(line, "sid=", sizeof("sid=") - 1) == 0) {
330 push(&user_info, line);
331 continue;
332 }
333 if (strncmp(line, "umask=", sizeof("umask=") - 1) == 0) {
334 push(&user_info, line);
335 continue;
336 }
337 if (strncmp(line, "rlimit_", sizeof("rlimit_") - 1) == 0) {
338 push(&user_info, line);
339 continue;
340 }
341
342 /* First argv entry is the command, the rest are args. */
343 if (strncmp(line, "argv=", sizeof("argv=") - 1) == 0) {
344 push(&argv, line);
345 continue;
346 }
347
348 /* Additional environment variables to add. */
349 if (strncmp(line, "env=", sizeof("env=") - 1) == 0) {
350 push(&env_add, line);
351 continue;
352 }
353
354 /* Treat anything else as a setting. */
355 push(&settings, line);
356 }
357 fclose(fp);
358 free(line);
359 line = NULL;
360
361 /* Exercise code paths that use KRB5CCNAME and SUDO_PROMPT. */
362 putenv("KRB5CCNAME=/tmp/krb5cc_123456");
363 putenv("SUDO_PROMPT=[sudo] password for %p: ");
364
365 sudoers_policy.register_hooks(SUDO_API_VERSION, fuzz_hook_stub);
366
367 for (pass = 1; res == 1 && pass <= num_passes; pass++) {
368 /* Call policy open function */
369 res = sudoers_policy.open(SUDO_API_VERSION, fuzz_conversation,
370 fuzz_printf, settings.entries, user_info.entries, environ,
371 plugin_args.entries, &errstr);
372 if (res == 1) {
373 if (argv.len == 0) {
374 /* Must have a command to check. */
375 push(&argv, "/usr/bin/id");
376 }
377
378 switch (pass) {
379 case PASS_NONE:
380 break;
381 case PASS_VERSION:
382 /* sudo -V */
383 sudoers_policy.show_version(true);
384 break;
385 case PASS_CHECK_LOG_LOCAL: {
386 /* sudo command w/ local I/O logging (MODE_RUN) */
387 sudoers_policy.check_policy(argv.len, argv.entries,
388 env_add.entries, &command_info, &argv_out, &user_env_out,
389 &errstr);
390 /* call check_policy() again to check for leaks. */
391 sudoers_policy.check_policy(argv.len, argv.entries,
392 env_add.entries, &command_info, &argv_out, &user_env_out,
393 &errstr);
394 /* sudo_auth_begin_session() is stubbed out below. */
395 sudoers_policy.init_session(NULL, NULL, NULL);
396 break;
397 }
398 case PASS_CHECK_LOG_REMOTE:
399 /* sudo command w/ remote I/O logging (MODE_RUN) */
400 sudoers_policy.check_policy(argv.len, argv.entries,
401 env_add.entries, &command_info, &argv_out, &user_env_out,
402 &errstr);
403 /* call check_policy() again to check for leaks. */
404 sudoers_policy.check_policy(argv.len, argv.entries,
405 env_add.entries, &command_info, &argv_out, &user_env_out,
406 &errstr);
407 /* sudo_auth_begin_session() is stubbed out below. */
408 sudoers_policy.init_session(NULL, NULL, NULL);
409 break;
410 case PASS_CHECK_NOT_FOUND:
411 /* sudo command (not found) */
412 sudoers_policy.check_policy(argv.len, argv.entries,
413 env_add.entries, &command_info, &argv_out, &user_env_out,
414 &errstr);
415 /* sudo_auth_begin_session() is stubbed out below. */
416 sudoers_policy.init_session(NULL, NULL, NULL);
417 break;
418 case PASS_CHECK_NOT_FOUND_DOT:
419 /* sudo command (found but in cwd) */
420 sudoers_policy.check_policy(argv.len, argv.entries,
421 env_add.entries, &command_info, &argv_out, &user_env_out,
422 &errstr);
423 /* call check_policy() again to check for leaks. */
424 sudoers_policy.check_policy(argv.len, argv.entries,
425 env_add.entries, &command_info, &argv_out, &user_env_out,
426 &errstr);
427 /* sudo_auth_begin_session() is stubbed out below. */
428 sudoers_policy.init_session(NULL, NULL, NULL);
429 break;
430 case PASS_LIST:
431 /* sudo -l (MODE_LIST) */
432 sudoers_policy.list(0, NULL, false, NULL, &errstr);
433 /* call list() again to check for leaks. */
434 sudoers_policy.list(0, NULL, false, NULL, &errstr);
435 break;
436 case PASS_LIST_OTHER:
437 /* sudo -l -U root (MODE_LIST) */
438 sudoers_policy.list(0, NULL, false, "root", &errstr);
439 /* call list() again to check for leaks. */
440 sudoers_policy.list(0, NULL, false, "root", &errstr);
441 break;
442 case PASS_LIST_CHECK:
443 /* sudo -l command (MODE_CHECK) */
444 sudoers_policy.list(argv.len, argv.entries, false, NULL,
445 &errstr);
446 /* call list() again to check for leaks. */
447 sudoers_policy.list(argv.len, argv.entries, false, NULL,
448 &errstr);
449 break;
450 case PASS_VALIDATE:
451 /* sudo -v (MODE_VALIDATE) */
452 sudoers_policy.validate(&errstr);
453 /* call validate() again to check for leaks. */
454 sudoers_policy.validate(&errstr);
455 break;
456 case PASS_INVALIDATE:
457 /* sudo -k */
458 sudoers_policy.invalidate(false);
459 /* call invalidate() again to check for leaks. */
460 sudoers_policy.invalidate(false);
461 break;
462 }
463 }
464
465 /* Free resources. */
466 if (sudoers_policy.close != NULL)
467 sudoers_policy.close(0, 0);
468 else
469 sudoers_cleanup();
470
471 /* Call a second time to free old env pointer. */
472 env_init(NULL);
473 }
474
475 sudoers_policy.deregister_hooks(SUDO_API_VERSION, fuzz_hook_stub);
476 sudoers_gc_run();
477
478 free_dynamic_array(&plugin_args);
479 free_dynamic_array(&settings);
480 free_dynamic_array(&user_info);
481 free_dynamic_array(&argv);
482 free_dynamic_array(&env_add);
483
484 sudoers_debug_deregister();
485
486 fflush(stdout);
487
488 return 0;
489 }
490
491 /* STUB */
492 bool
user_is_exempt(void)493 user_is_exempt(void)
494 {
495 return false;
496 }
497
498 /* STUB */
499 bool
set_interfaces(const char * ai)500 set_interfaces(const char *ai)
501 {
502 return true;
503 }
504
505 /* STUB */
506 void
dump_interfaces(const char * ai)507 dump_interfaces(const char *ai)
508 {
509 return;
510 }
511
512 /* STUB */
513 void
dump_auth_methods(void)514 dump_auth_methods(void)
515 {
516 return;
517 }
518
519 /* STUB */
520 int
sudo_auth_begin_session(struct passwd * pw,char ** user_env[])521 sudo_auth_begin_session(struct passwd *pw, char **user_env[])
522 {
523 return 1;
524 }
525
526 /* STUB */
527 int
sudo_auth_end_session(struct passwd * pw)528 sudo_auth_end_session(struct passwd *pw)
529 {
530 return 1;
531 }
532
533 /* STUB */
534 bool
sudo_auth_needs_end_session(void)535 sudo_auth_needs_end_session(void)
536 {
537 return false;
538 }
539
540 /* STUB */
541 int
timestamp_remove(bool unlink_it)542 timestamp_remove(bool unlink_it)
543 {
544 return true;
545 }
546
547 /* STUB */
548 int
create_admin_success_flag(void)549 create_admin_success_flag(void)
550 {
551 return true;
552 }
553
554 /* STUB */
555 static int
sudo_file_open(struct sudo_nss * nss)556 sudo_file_open(struct sudo_nss *nss)
557 {
558 return 0;
559 }
560
561 /* STUB */
562 static int
sudo_file_close(struct sudo_nss * nss)563 sudo_file_close(struct sudo_nss *nss)
564 {
565 return 0;
566 }
567
568 /* STUB */
569 static struct sudoers_parse_tree *
sudo_file_parse(struct sudo_nss * nss)570 sudo_file_parse(struct sudo_nss *nss)
571 {
572 static struct sudoers_parse_tree parse_tree;
573
574 return &parse_tree;
575 }
576
577 /* STUB */
578 static int
sudo_file_query(struct sudo_nss * nss,struct passwd * pw)579 sudo_file_query(struct sudo_nss *nss, struct passwd *pw)
580 {
581 return 0;
582 }
583
584 /* STUB */
585 static int
sudo_file_getdefs(struct sudo_nss * nss)586 sudo_file_getdefs(struct sudo_nss *nss)
587 {
588 /* Set some Defaults */
589 set_default("log_input", NULL, true, "sudoers", 1, 1, false);
590 set_default("log_output", NULL, true, "sudoers", 1, 1, false);
591 set_default("env_file", "/dev/null", true, "sudoers", 1, 1, false);
592 set_default("restricted_env_file", "/dev/null", true, "sudoers", 1, 1, false);
593 set_default("exempt_group", "sudo", true, "sudoers", 1, 1, false);
594 set_default("runchroot", "/", true, "sudoers", 1, 1, false);
595 set_default("runcwd", "~", true, "sudoers", 1, 1, false);
596 set_default("fqdn", NULL, true, "sudoers", 1, 1, false);
597 set_default("runas_default", "root", true, "sudoers", 1, 1, false);
598 set_default("tty_tickets", NULL, true, "sudoers", 1, 1, false);
599 set_default("umask", "022", true, "sudoers", 1, 1, false);
600 set_default("logfile", "/var/log/sudo", true, "sudoers", 1, 1, false);
601 set_default("syslog", "auth", true, "sudoers", 1, 1, false);
602 set_default("syslog_goodpri", "notice", true, "sudoers", 1, 1, false);
603 set_default("syslog_badpri", "alert", true, "sudoers", 1, 1, false);
604 set_default("syslog_maxlen", "2048", true, "sudoers", 1, 1, false);
605 set_default("loglinelen", "0", true, "sudoers", 1, 1, false);
606 set_default("log_year", NULL, true, "sudoers", 1, 1, false);
607 set_default("log_host", NULL, true, "sudoers", 1, 1, false);
608 set_default("mailerpath", NULL, false, "sudoers", 1, 1, false);
609 set_default("mailerflags", "-t", true, "sudoers", 1, 1, false);
610 set_default("mailto", "root@localhost", true, "sudoers", 1, 1, false);
611 set_default("mailfrom", "sudo@sudo.ws", true, "sudoers", 1, 1, false);
612 set_default("mailsub", "Someone has been naughty on %h", true, "sudoers", 1, 1, false);
613 set_default("timestampowner", "#0", true, "sudoers", 1, 1, false);
614 set_default("compress_io", NULL, true, "sudoers", 1, 1, false);
615 set_default("iolog_flush", NULL, true, "sudoers", 1, 1, false);
616 set_default("iolog_flush", NULL, true, "sudoers", 1, 1, false);
617 set_default("maxseq", "2176782336", true, "sudoers", 1, 1, false);
618 set_default("sudoedit_checkdir", NULL, false, "sudoers", 1, 1, false);
619 set_default("sudoedit_follow", NULL, true, "sudoers", 1, 1, false);
620 set_default("ignore_iolog_errors", NULL, true, "sudoers", 1, 1, false);
621 set_default("ignore_iolog_errors", NULL, true, "sudoers", 1, 1, false);
622 set_default("noexec", NULL, true, "sudoers", 1, 1, false);
623 set_default("exec_background", NULL, true, "sudoers", 1, 1, false);
624 set_default("use_pty", NULL, true, "sudoers", 1, 1, false);
625 set_default("utmp_runas", NULL, true, "sudoers", 1, 1, false);
626 set_default("iolog_mode", "0640", true, "sudoers", 1, 1, false);
627 set_default("iolog_user", NULL, false, "sudoers", 1, 1, false);
628 set_default("iolog_group", NULL, false, "sudoers", 1, 1, false);
629 if (pass != PASS_CHECK_LOG_LOCAL) {
630 set_default("log_servers", "localhost", true, "sudoers", 1, 1, false);
631 set_default("log_server_timeout", "30", true, "sudoers", 1, 1, false);
632 set_default("log_server_cabundle", "/etc/ssl/cacert.pem", true, "sudoers", 1, 1, false);
633 set_default("log_server_peer_cert", "/etc/ssl/localhost.crt", true, "sudoers", 1, 1, false);
634 set_default("log_server_peer_key", "/etc/ssl/private/localhost.key", true, "sudoers", 1, 1, false);
635 }
636
637 return 0;
638 }
639
640 static struct sudo_nss sudo_nss_file = {
641 { NULL, NULL },
642 sudo_file_open,
643 sudo_file_close,
644 sudo_file_parse,
645 sudo_file_query,
646 sudo_file_getdefs
647 };
648
649 struct sudo_nss_list *
sudo_read_nss(void)650 sudo_read_nss(void)
651 {
652 static struct sudo_nss_list snl = TAILQ_HEAD_INITIALIZER(snl);
653
654 if (TAILQ_EMPTY(&snl))
655 TAILQ_INSERT_TAIL(&snl, &sudo_nss_file, entries);
656
657 return &snl;
658 }
659
660 /* STUB */
661 int
check_user(int validated,int mode)662 check_user(int validated, int mode)
663 {
664 return true;
665 }
666
667 /* STUB */
668 bool
check_user_shell(const struct passwd * pw)669 check_user_shell(const struct passwd *pw)
670 {
671 return true;
672 }
673
674 /* STUB */
675 void
group_plugin_unload(void)676 group_plugin_unload(void)
677 {
678 return;
679 }
680
681 bool
log_warning(int flags,const char * fmt,...)682 log_warning(int flags, const char *fmt, ...)
683 {
684 va_list ap;
685
686 /* Just display on stderr. */
687 va_start(ap, fmt);
688 sudo_vwarn_nodebug(fmt, ap);
689 va_end(ap);
690
691 return true;
692 }
693
694 bool
log_warningx(int flags,const char * fmt,...)695 log_warningx(int flags, const char *fmt, ...)
696 {
697 va_list ap;
698
699 /* Just display on stderr. */
700 va_start(ap, fmt);
701 sudo_vwarnx_nodebug(fmt, ap);
702 va_end(ap);
703
704 return true;
705 }
706
707 bool
gai_log_warning(int flags,int errnum,const char * fmt,...)708 gai_log_warning(int flags, int errnum, const char *fmt, ...)
709 {
710 va_list ap;
711
712 /* Note: ignores errnum */
713 va_start(ap, fmt);
714 sudo_vwarnx_nodebug(fmt, ap);
715 va_end(ap);
716
717 return true;
718 }
719
720 /* STUB */
721 bool
log_denial(int status,bool inform_user)722 log_denial(int status, bool inform_user)
723 {
724 return true;
725 }
726
727 /* STUB */
728 bool
log_failure(int status,int flags)729 log_failure(int status, int flags)
730 {
731 return true;
732 }
733
734 /* STUB */
735 bool
log_exit_status(int exit_status)736 log_exit_status(int exit_status)
737 {
738 return true;
739 }
740
741 /* STUB */
742 int
audit_failure(char * const argv[],char const * const fmt,...)743 audit_failure(char *const argv[], char const *const fmt, ...)
744 {
745 return 0;
746 }
747
748 /* STUB */
749 int
sudoers_lookup(struct sudo_nss_list * snl,struct passwd * pw,int * cmnd_status,int pwflag)750 sudoers_lookup(struct sudo_nss_list *snl, struct passwd *pw, int *cmnd_status,
751 int pwflag)
752 {
753 return VALIDATE_SUCCESS;
754 }
755
756 /* STUB */
757 int
display_cmnd(struct sudo_nss_list * snl,struct passwd * pw)758 display_cmnd(struct sudo_nss_list *snl, struct passwd *pw)
759 {
760 return true;
761 }
762
763 /* STUB */
764 int
display_privs(struct sudo_nss_list * snl,struct passwd * pw,bool verbose)765 display_privs(struct sudo_nss_list *snl, struct passwd *pw, bool verbose)
766 {
767 return true;
768 }
769
770 /* STUB */
771 int
find_path(const char * infile,char ** outfile,struct stat * sbp,const char * path,const char * runchroot,int ignore_dot,char * const * allowlist)772 find_path(const char *infile, char **outfile, struct stat *sbp,
773 const char *path, const char *runchroot, int ignore_dot,
774 char * const *allowlist)
775 {
776 switch (pass) {
777 case PASS_CHECK_NOT_FOUND:
778 return NOT_FOUND;
779 case PASS_CHECK_NOT_FOUND_DOT:
780 return NOT_FOUND_DOT;
781 default:
782 if (infile[0] == '/') {
783 *outfile = strdup(infile);
784 } else {
785 if (asprintf(outfile, "/usr/bin/%s", infile) == -1)
786 *outfile = NULL;
787 }
788 if (*outfile == NULL)
789 return NOT_FOUND_ERROR;
790 return FOUND;
791 }
792 }
793
794 /* STUB */
795 bool
expand_iolog_path(const char * inpath,char * path,size_t pathlen,const struct iolog_path_escape * escapes,void * closure)796 expand_iolog_path(const char *inpath, char *path, size_t pathlen,
797 const struct iolog_path_escape *escapes, void *closure)
798 {
799 return strlcpy(path, inpath, pathlen) < pathlen;
800 }
801
802 /* STUB */
803 bool
iolog_nextid(char * iolog_dir,char sessid[7])804 iolog_nextid(char *iolog_dir, char sessid[7])
805 {
806 strlcpy(sessid, "000001", 7);
807 return true;
808 }
809
810 /* STUB */
811 bool
cb_maxseq(const union sudo_defs_val * sd_un)812 cb_maxseq(const union sudo_defs_val *sd_un)
813 {
814 return true;
815 }
816
817 /* STUB */
818 bool
cb_iolog_user(const union sudo_defs_val * sd_un)819 cb_iolog_user(const union sudo_defs_val *sd_un)
820 {
821 return true;
822 }
823
824 /* STUB */
825 bool
cb_iolog_group(const union sudo_defs_val * sd_un)826 cb_iolog_group(const union sudo_defs_val *sd_un)
827 {
828 return true;
829 }
830
831 /* STUB */
832 bool
cb_iolog_mode(const union sudo_defs_val * sd_un)833 cb_iolog_mode(const union sudo_defs_val *sd_un)
834 {
835 return true;
836 }
837
838 /* STUB */
839 bool
cb_group_plugin(const union sudo_defs_val * sd_un)840 cb_group_plugin(const union sudo_defs_val *sd_un)
841 {
842 return true;
843 }
844