Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
srohatgi01
GitHub Repository: srohatgi01/cups
Path: blob/master/scheduler/cups-exec.c
1090 views
1
/*
2
* Sandbox helper for CUPS.
3
*
4
* Copyright © 2021-2022 by OpenPrinting.
5
* Copyright © 2007-2014 by Apple Inc.
6
*
7
* Licensed under Apache License v2.0. See the file "LICENSE" for more
8
* information.
9
*
10
* Usage:
11
*
12
* cups-exec /path/to/profile [-u UID] [-g GID] [-n NICE] /path/to/program argv0 argv1 ... argvN
13
*/
14
15
/*
16
* Include necessary headers...
17
*/
18
19
#include <cups/string-private.h>
20
#include <cups/file.h>
21
#include <unistd.h>
22
#include <fcntl.h>
23
#include <grp.h>
24
#include <sys/stat.h>
25
#ifdef HAVE_SANDBOX_H
26
# include <sandbox.h>
27
# ifndef SANDBOX_NAMED_EXTERNAL
28
# define SANDBOX_NAMED_EXTERNAL 0x0003
29
# endif /* !SANDBOX_NAMED_EXTERNAL */
30
# pragma GCC diagnostic ignored "-Wdeprecated-declarations"
31
#endif /* HAVE_SANDBOX_H */
32
33
34
/*
35
* Local functions...
36
*/
37
38
static void usage(void) _CUPS_NORETURN;
39
40
41
/*
42
* 'main()' - Apply sandbox profile and execute program.
43
*/
44
45
int /* O - Exit status */
46
main(int argc, /* I - Number of command-line args */
47
char *argv[]) /* I - Command-line arguments */
48
{
49
int i; /* Looping var */
50
const char *opt; /* Current option character */
51
uid_t uid = getuid(); /* UID */
52
gid_t gid = getgid(); /* GID */
53
int niceval = 0; /* Nice value */
54
#ifdef HAVE_SANDBOX_H
55
char *sandbox_error = NULL; /* Sandbox error, if any */
56
#endif /* HAVE_SANDBOX_H */
57
58
59
/*
60
* Parse command-line...
61
*/
62
63
for (i = 1; i < argc; i ++)
64
{
65
if (argv[i][0] == '-')
66
{
67
for (opt = argv[i] + 1; *opt; opt ++)
68
{
69
switch (*opt)
70
{
71
case 'g' : /* -g gid */
72
i ++;
73
if (i >= argc)
74
usage();
75
76
gid = (gid_t)strtoul(argv[i], NULL, 10);
77
break;
78
79
case 'n' : /* -n nice-value */
80
i ++;
81
if (i >= argc)
82
usage();
83
84
niceval = atoi(argv[i]);
85
break;
86
87
case 'u' : /* -g gid */
88
i ++;
89
if (i >= argc)
90
usage();
91
92
uid = (uid_t)strtoul(argv[i], NULL, 10);
93
break;
94
95
default :
96
fprintf(stderr, "cups-exec: Unknown option '-%c'.\n", *opt);
97
usage();
98
}
99
}
100
}
101
else
102
break;
103
}
104
105
/*
106
* Check that we have enough arguments...
107
*/
108
109
if ((i + 3) > argc)
110
{
111
fputs("cups-exec: Insufficient arguments.\n", stderr);
112
usage();
113
}
114
115
/*
116
* Make sure side and back channel FDs are non-blocking...
117
*/
118
119
fcntl(3, F_SETFL, O_NDELAY);
120
fcntl(4, F_SETFL, O_NDELAY);
121
122
/*
123
* Change UID, GID, and nice value...
124
*/
125
126
if (uid)
127
nice(niceval);
128
129
if (!getuid())
130
{
131
if (setgid(gid))
132
exit(errno + 100);
133
134
# if CUPS_SNAP
135
if (setgroups(0, NULL))
136
# else
137
if (setgroups(1, &gid))
138
# endif /* CUPS_SNAP */
139
exit(errno + 100);
140
141
if (uid && setuid(uid))
142
exit(errno + 100);
143
}
144
145
umask(077);
146
147
#ifdef HAVE_SANDBOX_H
148
/*
149
* Run in a separate security profile...
150
*/
151
152
if (strcmp(argv[i], "none") &&
153
sandbox_init(argv[i], SANDBOX_NAMED_EXTERNAL, &sandbox_error))
154
{
155
cups_file_t *fp; /* File */
156
char line[1024]; /* Line from file */
157
unsigned linenum = 0; /* Line number in file */
158
159
fprintf(stderr, "DEBUG: sandbox_init failed: %s (%s)\n", sandbox_error,
160
strerror(errno));
161
sandbox_free_error(sandbox_error);
162
163
if ((fp = cupsFileOpen(argv[i], "r")) != NULL)
164
{
165
while (cupsFileGets(fp, line, sizeof(line)))
166
{
167
linenum ++;
168
fprintf(stderr, "DEBUG: %4u %s\n", linenum, line);
169
}
170
cupsFileClose(fp);
171
}
172
173
return (100 + EINVAL);
174
}
175
#endif /* HAVE_SANDBOX_H */
176
177
/*
178
* Execute the program...
179
*/
180
181
execv(argv[i + 1], argv + i + 2);
182
183
/*
184
* If we get here, execv() failed...
185
*/
186
187
fprintf(stderr, "DEBUG: execv failed: %s\n", strerror(errno));
188
return (errno + 100);
189
}
190
191
192
/*
193
* 'usage()' - Show program usage.
194
*/
195
196
static void
197
usage(void)
198
{
199
fputs("Usage: cups-exec [-g gid] [-n nice-value] [-u uid] /path/to/profile /path/to/program argv0 argv1 ... argvN\n", stderr);
200
exit(1);
201
}
202
203