]> granicus.if.org Git - sudo/blob - plugins/sudoers/sudoers_debug.c
Add SPDX-License-Identifier to files.
[sudo] / plugins / sudoers / sudoers_debug.c
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 <sys/types.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #ifdef HAVE_STDBOOL_H
30 # include <stdbool.h>
31 #else
32 # include "compat/stdbool.h"
33 #endif
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_STRINGS_H */
40 #include <unistd.h>
41 #include <ctype.h>
42
43 #include "sudoers.h"
44
45 static int sudoers_debug_instance = SUDO_DEBUG_INSTANCE_INITIALIZER;
46
47 static const char *const sudoers_subsystem_names[] = {
48     "alias",
49     "audit",
50     "auth",
51     "defaults",
52     "env",
53     "event",
54     "ldap",
55     "logging",
56     "main",
57     "match",
58     "netif",
59     "nss",
60     "parser",
61     "perms",
62     "plugin",
63     "rbtree",
64     "sssd",
65     "util",
66     NULL
67 };
68
69 #define NUM_SUBSYSTEMS  (nitems(sudoers_subsystem_names) - 1)
70
71 /* Subsystem IDs assigned at registration time. */
72 unsigned int sudoers_subsystem_ids[NUM_SUBSYSTEMS];
73
74 /*
75  * Parse the "filename flags,..." debug_flags entry and insert a new
76  * sudo_debug_file struct into debug_files.
77  */
78 bool
79 sudoers_debug_parse_flags(struct sudo_conf_debug_file_list *debug_files,
80     const char *entry)
81 {
82     struct sudo_debug_file *debug_file;
83     const char *filename, *flags;
84     size_t namelen;
85
86     /* Already initialized? */
87     if (sudoers_debug_instance != SUDO_DEBUG_INSTANCE_INITIALIZER)
88         return true;
89
90     /* Only process new-style debug flags: filename flags,... */
91     filename = entry;
92     if (*filename != '/' || (flags = strpbrk(filename, " \t")) == NULL)
93         return true;
94     namelen = (size_t)(flags - filename);
95     while (isblank((unsigned char)*flags))
96         flags++;
97     if (*flags != '\0') {
98         if ((debug_file = calloc(1, sizeof(*debug_file))) == NULL)
99             goto oom;
100         if ((debug_file->debug_file = strndup(filename, namelen)) == NULL)
101             goto oom;
102         if ((debug_file->debug_flags = strdup(flags)) == NULL)
103             goto oom;
104         TAILQ_INSERT_TAIL(debug_files, debug_file, entries);
105     }
106     return true;
107 oom:
108     if (debug_file != NULL) {
109         free(debug_file->debug_file);
110         free(debug_file->debug_flags);
111         free(debug_file);
112     }
113     sudo_warnx_nodebug(U_("%s: %s"), "sudoers_debug_parse_flags",
114         U_("unable to allocate memory"));
115     return false;
116 }
117
118 /*
119  * Register the specified debug files and program with the
120  * debug subsystem, freeing the debug list when done.
121  * Sets the active debug instance as a side effect.
122  */
123 bool
124 sudoers_debug_register(const char *program,
125     struct sudo_conf_debug_file_list *debug_files)
126 {
127     struct sudo_debug_file *debug_file, *debug_next;
128
129     /* Already initialized? */
130     if (sudoers_debug_instance != SUDO_DEBUG_INSTANCE_INITIALIZER) {
131         sudo_debug_set_active_instance(sudoers_debug_instance);
132     }
133
134     /* Setup debugging if indicated. */
135     if (debug_files != NULL && !TAILQ_EMPTY(debug_files)) {
136         if (program != NULL) {
137             sudoers_debug_instance = sudo_debug_register(program,
138                 sudoers_subsystem_names, sudoers_subsystem_ids, debug_files);
139             if (sudoers_debug_instance == SUDO_DEBUG_INSTANCE_ERROR)
140                 return false;
141         }
142         TAILQ_FOREACH_SAFE(debug_file, debug_files, entries, debug_next) {
143             TAILQ_REMOVE(debug_files, debug_file, entries);
144             free(debug_file->debug_file);
145             free(debug_file->debug_flags);
146             free(debug_file);
147         }
148     }
149     return true;
150 }
151
152 /*
153  * Deregister sudoers_debug_instance if it is registered.
154  */
155 void
156 sudoers_debug_deregister(void)
157 {
158     debug_decl(sudoers_debug_deregister, SUDOERS_DEBUG_PLUGIN)
159     if (sudoers_debug_instance != SUDO_DEBUG_INSTANCE_INITIALIZER) {
160         sudo_debug_exit(__func__, __FILE__, __LINE__, sudo_debug_subsys);
161         sudo_debug_deregister(sudoers_debug_instance);
162         sudoers_debug_instance = SUDO_DEBUG_INSTANCE_INITIALIZER;
163     }
164 }