Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sudo-project
GitHub Repository: sudo-project/sudo
Path: blob/main/plugins/sudoers/fmtsudoers_cvt.c
3921 views
1
/*
2
* SPDX-License-Identifier: ISC
3
*
4
* Copyright (c) 2004-2005, 2007-2021, 2023 Todd C. Miller <[email protected]>
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
#include <string.h>
24
#include <time.h>
25
26
#include <sudoers.h>
27
#include <sudo_lbuf.h>
28
#include <gram.h>
29
30
/*
31
* Write a privilege to lbuf in sudoers format.
32
*/
33
bool
34
sudoers_format_privilege(struct sudo_lbuf *lbuf,
35
const struct sudoers_parse_tree *parse_tree, const struct privilege *priv,
36
bool expand_aliases)
37
{
38
const struct cmndspec *cs, *prev_cs;
39
const struct member *m;
40
struct cmndtag tags;
41
debug_decl(sudoers_format_privilege, SUDOERS_DEBUG_UTIL);
42
43
/* Convert per-privilege defaults to tags. */
44
sudoers_defaults_list_to_tags(&priv->defaults, &tags);
45
46
/* Print hosts list. */
47
TAILQ_FOREACH(m, &priv->hostlist, entries) {
48
if (m != TAILQ_FIRST(&priv->hostlist))
49
sudo_lbuf_append(lbuf, ", ");
50
sudoers_format_member(lbuf, parse_tree, m, ", ",
51
expand_aliases ? HOSTALIAS : UNSPEC);
52
}
53
54
/* Print commands. */
55
sudo_lbuf_append(lbuf, " = ");
56
prev_cs = NULL;
57
TAILQ_FOREACH(cs, &priv->cmndlist, entries) {
58
if (prev_cs == NULL || RUNAS_CHANGED(cs, prev_cs)) {
59
if (cs != TAILQ_FIRST(&priv->cmndlist))
60
sudo_lbuf_append(lbuf, ", ");
61
if (cs->runasuserlist != NULL || cs->runasgrouplist != NULL)
62
sudo_lbuf_append(lbuf, "(");
63
if (cs->runasuserlist != NULL) {
64
TAILQ_FOREACH(m, cs->runasuserlist, entries) {
65
if (m != TAILQ_FIRST(cs->runasuserlist))
66
sudo_lbuf_append(lbuf, ", ");
67
sudoers_format_member(lbuf, parse_tree, m, ", ",
68
expand_aliases ? RUNASALIAS : UNSPEC);
69
}
70
}
71
if (cs->runasgrouplist != NULL) {
72
sudo_lbuf_append(lbuf, " : ");
73
TAILQ_FOREACH(m, cs->runasgrouplist, entries) {
74
if (m != TAILQ_FIRST(cs->runasgrouplist))
75
sudo_lbuf_append(lbuf, ", ");
76
sudoers_format_member(lbuf, parse_tree, m, ", ",
77
expand_aliases ? RUNASALIAS : UNSPEC);
78
}
79
}
80
if (cs->runasuserlist != NULL || cs->runasgrouplist != NULL)
81
sudo_lbuf_append(lbuf, ") ");
82
} else if (cs != TAILQ_FIRST(&priv->cmndlist)) {
83
sudo_lbuf_append(lbuf, ", ");
84
}
85
sudoers_format_cmndspec(lbuf, parse_tree, cs, prev_cs, tags,
86
expand_aliases);
87
prev_cs = cs;
88
}
89
90
debug_return_bool(!sudo_lbuf_error(lbuf));
91
}
92
93
/*
94
* Write a userspec to lbuf in sudoers format.
95
*/
96
bool
97
sudoers_format_userspec(struct sudo_lbuf *lbuf,
98
const struct sudoers_parse_tree *parse_tree,
99
const struct userspec *us, bool expand_aliases)
100
{
101
const struct sudoers_comment *comment;
102
const struct privilege *priv;
103
const struct member *m;
104
debug_decl(sudoers_format_userspec, SUDOERS_DEBUG_UTIL);
105
106
/* Print comments (if any). */
107
STAILQ_FOREACH(comment, &us->comments, entries) {
108
sudo_lbuf_append(lbuf, "# %s\n", comment->str);
109
}
110
111
/* Print users list. */
112
TAILQ_FOREACH(m, &us->users, entries) {
113
if (m != TAILQ_FIRST(&us->users))
114
sudo_lbuf_append(lbuf, ", ");
115
sudoers_format_member(lbuf, parse_tree, m, ", ",
116
expand_aliases ? USERALIAS : UNSPEC);
117
}
118
119
TAILQ_FOREACH(priv, &us->privileges, entries) {
120
if (priv != TAILQ_FIRST(&us->privileges))
121
sudo_lbuf_append(lbuf, " : ");
122
else
123
sudo_lbuf_append(lbuf, " ");
124
if (!sudoers_format_privilege(lbuf, parse_tree, priv, expand_aliases))
125
break;
126
}
127
sudo_lbuf_append(lbuf, "\n");
128
129
debug_return_bool(!sudo_lbuf_error(lbuf));
130
}
131
132
/*
133
* Write a userspec_list to lbuf in sudoers format.
134
*/
135
bool
136
sudoers_format_userspecs(struct sudo_lbuf *lbuf,
137
const struct sudoers_parse_tree *parse_tree, const char *separator,
138
bool expand_aliases, bool flush)
139
{
140
const struct userspec *us;
141
debug_decl(sudoers_format_userspecs, SUDOERS_DEBUG_UTIL);
142
143
TAILQ_FOREACH(us, &parse_tree->userspecs, entries) {
144
if (separator != NULL && us != TAILQ_FIRST(&parse_tree->userspecs))
145
sudo_lbuf_append(lbuf, "%s", separator);
146
if (!sudoers_format_userspec(lbuf, parse_tree, us, expand_aliases))
147
break;
148
sudo_lbuf_print(lbuf);
149
}
150
151
debug_return_bool(!sudo_lbuf_error(lbuf));
152
}
153
154
/*
155
* Format and append a defaults line to the specified lbuf.
156
* If next, is specified, it must point to the next defaults
157
* entry in the list; this is used to print multiple defaults
158
* entries with the same binding on a single line.
159
*/
160
bool
161
sudoers_format_default_line(struct sudo_lbuf *lbuf,
162
const struct sudoers_parse_tree *parse_tree, const struct defaults *d,
163
struct defaults **next, bool expand_aliases)
164
{
165
const struct member *m;
166
short alias_type;
167
debug_decl(sudoers_format_default_line, SUDOERS_DEBUG_UTIL);
168
169
/* Print Defaults type and binding (if present) */
170
switch (d->type) {
171
case DEFAULTS_HOST:
172
sudo_lbuf_append(lbuf, "Defaults@");
173
alias_type = expand_aliases ? HOSTALIAS : UNSPEC;
174
break;
175
case DEFAULTS_USER:
176
sudo_lbuf_append(lbuf, "Defaults:");
177
alias_type = expand_aliases ? USERALIAS : UNSPEC;
178
break;
179
case DEFAULTS_RUNAS:
180
sudo_lbuf_append(lbuf, "Defaults>");
181
alias_type = expand_aliases ? RUNASALIAS : UNSPEC;
182
break;
183
case DEFAULTS_CMND:
184
sudo_lbuf_append(lbuf, "Defaults!");
185
alias_type = expand_aliases ? CMNDALIAS : UNSPEC;
186
break;
187
default:
188
sudo_lbuf_append(lbuf, "Defaults");
189
alias_type = UNSPEC;
190
break;
191
}
192
TAILQ_FOREACH(m, &d->binding->members, entries) {
193
if (m != TAILQ_FIRST(&d->binding->members))
194
sudo_lbuf_append(lbuf, ", ");
195
sudoers_format_member(lbuf, parse_tree, m, ", ", alias_type);
196
}
197
198
sudo_lbuf_append(lbuf, " ");
199
sudoers_format_default(lbuf, d);
200
201
if (next != NULL) {
202
/* Merge Defaults with the same binding, there may be multiple. */
203
struct defaults *n;
204
while ((n = TAILQ_NEXT(d, entries)) && d->binding == n->binding) {
205
sudo_lbuf_append(lbuf, ", ");
206
sudoers_format_default(lbuf, n);
207
d = n;
208
}
209
*next = n;
210
}
211
sudo_lbuf_append(lbuf, "\n");
212
213
debug_return_bool(!sudo_lbuf_error(lbuf));
214
}
215
216