Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sudo-project
GitHub Repository: sudo-project/sudo
Path: blob/main/include/sudo_plugin.h
1532 views
1
/*
2
* SPDX-License-Identifier: ISC
3
*
4
* Copyright (c) 2009-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
#ifndef SUDO_PLUGIN_H
20
#define SUDO_PLUGIN_H
21
22
/* API version major/minor */
23
#define SUDO_API_VERSION_MAJOR 1
24
#define SUDO_API_VERSION_MINOR 22
25
#define SUDO_API_MKVERSION(x, y) (((x) << 16) | (y))
26
#define SUDO_API_VERSION SUDO_API_MKVERSION(SUDO_API_VERSION_MAJOR, SUDO_API_VERSION_MINOR)
27
28
/* Getters and setters for plugin API versions */
29
#define SUDO_API_VERSION_GET_MAJOR(v) ((v) >> 16)
30
#define SUDO_API_VERSION_GET_MINOR(v) ((v) & 0xffffU)
31
#define SUDO_API_VERSION_SET_MAJOR(vp, n) do { \
32
*(vp) = (*(vp) & 0x0000ffffU) | ((n) << 16); \
33
} while(0)
34
#define SUDO_API_VERSION_SET_MINOR(vp, n) do { \
35
*(vp) = (*(vp) & 0xffff0000U) | (n); \
36
} while(0)
37
38
/* "plugin type" for the sudo front end, as passed to an audit plugin */
39
#define SUDO_FRONT_END 0
40
41
/* Conversation function types and defines */
42
struct sudo_conv_message {
43
#define SUDO_CONV_PROMPT_ECHO_OFF 0x0001 /* do not echo user input */
44
#define SUDO_CONV_PROMPT_ECHO_ON 0x0002 /* echo user input */
45
#define SUDO_CONV_ERROR_MSG 0x0003 /* error message */
46
#define SUDO_CONV_INFO_MSG 0x0004 /* informational message */
47
#define SUDO_CONV_PROMPT_MASK 0x0005 /* mask user input */
48
#define SUDO_CONV_PROMPT_ECHO_OK 0x1000 /* flag: allow echo if no tty */
49
#define SUDO_CONV_PREFER_TTY 0x2000 /* flag: use tty if possible */
50
int msg_type;
51
int timeout;
52
const char *msg;
53
};
54
55
/*
56
* Maximum length of a reply (not including the trailing NUL) when
57
* conversing with the user. In practical terms, this is the longest
58
* password sudo will support. This means that a buffer of size
59
* SUDO_CONV_REPL_MAX+1 is guaranteed to be able to hold any reply
60
* from the conversation function.
61
*/
62
#define SUDO_CONV_REPL_MAX 1023
63
64
struct sudo_conv_reply {
65
char *reply;
66
};
67
68
/* Conversation callback API version major/minor */
69
#define SUDO_CONV_CALLBACK_VERSION_MAJOR 1
70
#define SUDO_CONV_CALLBACK_VERSION_MINOR 0
71
#define SUDO_CONV_CALLBACK_VERSION SUDO_API_MKVERSION(SUDO_CONV_CALLBACK_VERSION_MAJOR, SUDO_CONV_CALLBACK_VERSION_MINOR)
72
73
/*
74
* Callback struct to be passed to the conversation function.
75
* Can be used to perform operations on suspend/resume such
76
* as dropping/acquiring locks.
77
*/
78
typedef int (*sudo_conv_callback_fn_t)(int signo, void *closure);
79
struct sudo_conv_callback {
80
unsigned int version;
81
void *closure;
82
sudo_conv_callback_fn_t on_suspend;
83
sudo_conv_callback_fn_t on_resume;
84
};
85
86
typedef int (*sudo_conv_t)(int num_msgs, const struct sudo_conv_message msgs[],
87
struct sudo_conv_reply replies[], struct sudo_conv_callback *callback);
88
typedef int (*sudo_printf_t)(int msg_type, const char * restrict fmt, ...);
89
90
/*
91
* Hooks allow a plugin to hook into specific sudo and/or libc functions.
92
*/
93
94
#if defined(__GNUC__) && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 4) || __GNUC__ > 4)
95
# pragma GCC diagnostic ignored "-Wstrict-prototypes"
96
#endif
97
98
/* Hook functions typedefs. */
99
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 202311L)
100
typedef int (*sudo_hook_fn_t)(...);
101
#else
102
typedef int (*sudo_hook_fn_t)();
103
#endif
104
typedef int (*sudo_hook_fn_setenv_t)(const char *name, const char *value, int overwrite, void *closure);
105
typedef int (*sudo_hook_fn_putenv_t)(char *string, void *closure);
106
typedef int (*sudo_hook_fn_getenv_t)(const char *name, char **value, void *closure);
107
typedef int (*sudo_hook_fn_unsetenv_t)(const char *name, void *closure);
108
109
/* Hook structure definition. */
110
struct sudo_hook {
111
unsigned int hook_version;
112
unsigned int hook_type;
113
sudo_hook_fn_t hook_fn;
114
void *closure;
115
};
116
117
/* Hook API version major/minor */
118
#define SUDO_HOOK_VERSION_MAJOR 1
119
#define SUDO_HOOK_VERSION_MINOR 0
120
#define SUDO_HOOK_VERSION SUDO_API_MKVERSION(SUDO_HOOK_VERSION_MAJOR, SUDO_HOOK_VERSION_MINOR)
121
122
/*
123
* Hook function return values.
124
*/
125
#define SUDO_HOOK_RET_ERROR -1 /* error */
126
#define SUDO_HOOK_RET_NEXT 0 /* go to the next hook in the list */
127
#define SUDO_HOOK_RET_STOP 1 /* stop hook processing for this type */
128
129
/*
130
* Hooks for setenv/unsetenv/putenv/getenv.
131
* This allows the plugin to be notified when a PAM module modifies
132
* the environment so it can update the copy of the environment that
133
* is passed to execve().
134
*/
135
#define SUDO_HOOK_SETENV 1
136
#define SUDO_HOOK_UNSETENV 2
137
#define SUDO_HOOK_PUTENV 3
138
#define SUDO_HOOK_GETENV 4
139
140
/*
141
* Plugin interface to sudo's main event loop.
142
*/
143
typedef void (*sudo_plugin_ev_callback_t)(int fd, int what, void *closure);
144
145
struct timespec;
146
struct sudo_plugin_event {
147
int (*set)(struct sudo_plugin_event *pev, int fd, int events, sudo_plugin_ev_callback_t callback, void *closure);
148
int (*add)(struct sudo_plugin_event *pev, struct timespec *timeout);
149
int (*del)(struct sudo_plugin_event *pev);
150
int (*pending)(struct sudo_plugin_event *pev, int events, struct timespec *ts);
151
int (*fd)(struct sudo_plugin_event *pev);
152
void (*setbase)(struct sudo_plugin_event *pev, void *base);
153
void (*loopbreak)(struct sudo_plugin_event *pev);
154
void (*free)(struct sudo_plugin_event *pev);
155
/* actually larger... */
156
};
157
158
/* Sudo plugin Event types */
159
#define SUDO_PLUGIN_EV_TIMEOUT 0x01 /* fire after timeout */
160
#define SUDO_PLUGIN_EV_READ 0x02 /* fire when readable */
161
#define SUDO_PLUGIN_EV_WRITE 0x04 /* fire when writable */
162
#define SUDO_PLUGIN_EV_PERSIST 0x08 /* persist until deleted */
163
#define SUDO_PLUGIN_EV_SIGNAL 0x10 /* fire on signal receipt */
164
165
/* Policy plugin type and defines. */
166
struct passwd;
167
struct policy_plugin {
168
#define SUDO_POLICY_PLUGIN 1
169
unsigned int type; /* always SUDO_POLICY_PLUGIN */
170
unsigned int version; /* always SUDO_API_VERSION */
171
int (*open)(unsigned int version, sudo_conv_t conversation,
172
sudo_printf_t sudo_plugin_printf, char * const settings[],
173
char * const user_info[], char * const user_env[],
174
char * const plugin_options[], const char **errstr);
175
void (*close)(int exit_status, int error); /* wait status or error */
176
int (*show_version)(int verbose);
177
int (*check_policy)(int argc, char * const argv[],
178
char *env_add[], char **command_info[],
179
char **argv_out[], char **user_env_out[], const char **errstr);
180
int (*list)(int argc, char * const argv[], int verbose,
181
const char *user, const char **errstr);
182
int (*validate)(const char **errstr);
183
void (*invalidate)(int rmcred);
184
int (*init_session)(struct passwd *pwd, char **user_env_out[],
185
const char **errstr);
186
void (*register_hooks)(int version, int (*register_hook)(struct sudo_hook *hook));
187
void (*deregister_hooks)(int version, int (*deregister_hook)(struct sudo_hook *hook));
188
struct sudo_plugin_event * (*event_alloc)(void);
189
};
190
191
/* I/O plugin type and defines. */
192
struct io_plugin {
193
#define SUDO_IO_PLUGIN 2
194
unsigned int type; /* always SUDO_IO_PLUGIN */
195
unsigned int version; /* always SUDO_API_VERSION */
196
int (*open)(unsigned int version, sudo_conv_t conversation,
197
sudo_printf_t sudo_plugin_printf, char * const settings[],
198
char * const user_info[], char * const command_info[],
199
int argc, char * const argv[], char * const user_env[],
200
char * const plugin_options[], const char **errstr);
201
void (*close)(int exit_status, int error); /* wait status or error */
202
int (*show_version)(int verbose);
203
int (*log_ttyin)(const char *buf, unsigned int len, const char **errstr);
204
int (*log_ttyout)(const char *buf, unsigned int len, const char **errstr);
205
int (*log_stdin)(const char *buf, unsigned int len, const char **errstr);
206
int (*log_stdout)(const char *buf, unsigned int len, const char **errstr);
207
int (*log_stderr)(const char *buf, unsigned int len, const char **errstr);
208
void (*register_hooks)(int version,
209
int (*register_hook)(struct sudo_hook *hook));
210
void (*deregister_hooks)(int version,
211
int (*deregister_hook)(struct sudo_hook *hook));
212
int (*change_winsize)(unsigned int line, unsigned int cols,
213
const char **errstr);
214
int (*log_suspend)(int signo, const char **errstr);
215
struct sudo_plugin_event * (*event_alloc)(void);
216
};
217
218
/* Differ audit plugin close status types. */
219
#define SUDO_PLUGIN_NO_STATUS 0
220
#define SUDO_PLUGIN_WAIT_STATUS 1
221
#define SUDO_PLUGIN_EXEC_ERROR 2
222
#define SUDO_PLUGIN_SUDO_ERROR 3
223
224
/* Audit plugin type and defines */
225
struct audit_plugin {
226
#define SUDO_AUDIT_PLUGIN 3
227
unsigned int type; /* always SUDO_AUDIT_PLUGIN */
228
unsigned int version; /* always SUDO_API_VERSION */
229
int (*open)(unsigned int version, sudo_conv_t conversation,
230
sudo_printf_t sudo_plugin_printf, char * const settings[],
231
char * const user_info[], int submit_optind,
232
char * const submit_argv[], char * const submit_envp[],
233
char * const plugin_options[], const char **errstr);
234
void (*close)(int status_type, int status);
235
int (*accept)(const char *plugin_name, unsigned int plugin_type,
236
char * const command_info[], char * const run_argv[],
237
char * const run_envp[], const char **errstr);
238
int (*reject)(const char *plugin_name, unsigned int plugin_type,
239
const char *audit_msg, char * const command_info[],
240
const char **errstr);
241
int (*error)(const char *plugin_name, unsigned int plugin_type,
242
const char *audit_msg, char * const command_info[],
243
const char **errstr);
244
int (*show_version)(int verbose);
245
void (*register_hooks)(int version, int (*register_hook)(struct sudo_hook *hook));
246
void (*deregister_hooks)(int version, int (*deregister_hook)(struct sudo_hook *hook));
247
struct sudo_plugin_event * (*event_alloc)(void);
248
};
249
250
/* Approval plugin type and defines */
251
struct approval_plugin {
252
#define SUDO_APPROVAL_PLUGIN 4
253
unsigned int type; /* always SUDO_APPROVAL_PLUGIN */
254
unsigned int version; /* always SUDO_API_VERSION */
255
int (*open)(unsigned int version, sudo_conv_t conversation,
256
sudo_printf_t sudo_plugin_printf, char * const settings[],
257
char * const user_info[], int submit_optind,
258
char * const submit_argv[], char * const submit_envp[],
259
char * const plugin_options[], const char **errstr);
260
void (*close)(void);
261
int (*check)(char * const command_info[], char * const run_argv[],
262
char * const run_envp[], const char **errstr);
263
int (*show_version)(int verbose);
264
};
265
266
/* Sudoers group plugin version major/minor */
267
#define GROUP_API_VERSION_MAJOR 1
268
#define GROUP_API_VERSION_MINOR 0
269
#define GROUP_API_VERSION SUDO_API_MKVERSION(GROUP_API_VERSION_MAJOR, GROUP_API_VERSION_MINOR)
270
271
/* Getters and setters for group version (for source compat only) */
272
#define GROUP_API_VERSION_GET_MAJOR(v) SUDO_API_VERSION_GET_MAJOR(v)
273
#define GROUP_API_VERSION_GET_MINOR(v) SUDO_API_VERSION_GET_MINOR(v)
274
#define GROUP_API_VERSION_SET_MAJOR(vp, n) SUDO_API_VERSION_SET_MAJOR(vp, n)
275
#define GROUP_API_VERSION_SET_MINOR(vp, n) SUDO_API_VERSION_SET_MINOR(vp, n)
276
277
/*
278
* version: for compatibility checking
279
* group_init: return 1 on success, 0 if unconfigured, -1 on error.
280
* group_cleanup: called to clean up resources used by provider
281
* user_in_group: returns 1 if user is in group, 0 if not.
282
* note that pwd may be NULL if the user is not in passwd.
283
*/
284
struct sudoers_group_plugin {
285
unsigned int version;
286
int (*init)(int version, sudo_printf_t sudo_plugin_printf,
287
char *const argv[]);
288
void (*cleanup)(void);
289
int (*query)(const char *user, const char *group, const struct passwd *pwd);
290
};
291
292
#endif /* SUDO_PLUGIN_H */
293
294