1 /*
2 * SPDX-License-Identifier: ISC
3 *
4 * Copyright (c) 2014-2015 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 /*
20 * This is an open source non-commercial project. Dear PVS-Studio, please check it.
21 * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
22 */
23
24 #include <config.h>
25
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29
30 #include "sudoers.h"
31
32 static int sudoers_debug_instance = SUDO_DEBUG_INSTANCE_INITIALIZER;
33 static unsigned int sudoers_debug_refcnt;
34
35 static const char *const sudoers_subsystem_names[] = {
36 "alias",
37 "audit",
38 "auth",
39 "defaults",
40 "env",
41 "event",
42 "ldap",
43 "logging",
44 "main",
45 "match",
46 "netif",
47 "nss",
48 "parser",
49 "perms",
50 "plugin",
51 "rbtree",
52 "sssd",
53 "util",
54 NULL
55 };
56
57 #define NUM_SUBSYSTEMS (nitems(sudoers_subsystem_names) - 1)
58
59 /* Subsystem IDs assigned at registration time. */
60 unsigned int sudoers_subsystem_ids[NUM_SUBSYSTEMS];
61
62 /*
63 * Parse the "filename flags,..." debug_flags entry and insert a new
64 * sudo_debug_file struct into debug_files.
65 */
66 bool
sudoers_debug_parse_flags(struct sudo_conf_debug_file_list * debug_files,const char * entry)67 sudoers_debug_parse_flags(struct sudo_conf_debug_file_list *debug_files,
68 const char *entry)
69 {
70 /* Already initialized? */
71 if (sudoers_debug_instance != SUDO_DEBUG_INSTANCE_INITIALIZER)
72 return true;
73
74 return sudo_debug_parse_flags(debug_files, entry) != -1;
75 }
76
77 /*
78 * Register the specified debug files and program with the
79 * debug subsystem, freeing the debug list when done.
80 * Sets the active debug instance as a side effect.
81 */
82 bool
sudoers_debug_register(const char * program,struct sudo_conf_debug_file_list * debug_files)83 sudoers_debug_register(const char *program,
84 struct sudo_conf_debug_file_list *debug_files)
85 {
86 int instance = sudoers_debug_instance;
87 struct sudo_debug_file *debug_file, *debug_next;
88
89 /* Setup debugging if indicated. */
90 if (debug_files != NULL && !TAILQ_EMPTY(debug_files)) {
91 if (program != NULL) {
92 instance = sudo_debug_register(program, sudoers_subsystem_names,
93 sudoers_subsystem_ids, debug_files, -1);
94 }
95 TAILQ_FOREACH_SAFE(debug_file, debug_files, entries, debug_next) {
96 TAILQ_REMOVE(debug_files, debug_file, entries);
97 free(debug_file->debug_file);
98 free(debug_file->debug_flags);
99 free(debug_file);
100 }
101 }
102
103 switch (instance) {
104 case SUDO_DEBUG_INSTANCE_ERROR:
105 return false;
106 case SUDO_DEBUG_INSTANCE_INITIALIZER:
107 /* Nothing to do */
108 break;
109 default:
110 /* New debug instance or additional reference on existing one. */
111 sudoers_debug_instance = instance;
112 sudo_debug_set_active_instance(sudoers_debug_instance);
113 sudoers_debug_refcnt++;
114 break;
115 }
116
117 return true;
118 }
119
120 /*
121 * Deregister sudoers_debug_instance if it is registered.
122 */
123 void
sudoers_debug_deregister(void)124 sudoers_debug_deregister(void)
125 {
126 debug_decl(sudoers_debug_deregister, SUDOERS_DEBUG_PLUGIN);
127
128 if (sudoers_debug_refcnt != 0) {
129 sudo_debug_exit(__func__, __FILE__, __LINE__, sudo_debug_subsys);
130 if (--sudoers_debug_refcnt == 0) {
131 if (sudo_debug_deregister(sudoers_debug_instance) < 1)
132 sudoers_debug_instance = SUDO_DEBUG_INSTANCE_INITIALIZER;
133 }
134 }
135 }
136