summaryrefslogtreecommitdiff
path: root/openbsd-compat
diff options
context:
space:
mode:
Diffstat (limited to 'openbsd-compat')
-rw-r--r--openbsd-compat/bsd-misc.c8
-rw-r--r--openbsd-compat/bsd-misc.h4
-rw-r--r--openbsd-compat/bsd-poll.h4
-rw-r--r--openbsd-compat/glob.c1
-rw-r--r--openbsd-compat/glob.h8
-rw-r--r--openbsd-compat/openbsd-compat.h1
-rw-r--r--openbsd-compat/port-solaris.c136
-rw-r--r--openbsd-compat/port-solaris.h6
-rw-r--r--openbsd-compat/realpath.c61
9 files changed, 208 insertions, 21 deletions
diff --git a/openbsd-compat/bsd-misc.c b/openbsd-compat/bsd-misc.c
index f7be415ec..2a788e47f 100644
--- a/openbsd-compat/bsd-misc.c
+++ b/openbsd-compat/bsd-misc.c
@@ -276,3 +276,11 @@ getpgid(pid_t pid)
276 return -1; 276 return -1;
277} 277}
278#endif 278#endif
279
280#ifndef HAVE_PLEDGE
281int
282pledge(const char *promises, const char *paths[])
283{
284 return 0;
285}
286#endif
diff --git a/openbsd-compat/bsd-misc.h b/openbsd-compat/bsd-misc.h
index ff347a24b..0d81d1735 100644
--- a/openbsd-compat/bsd-misc.h
+++ b/openbsd-compat/bsd-misc.h
@@ -122,4 +122,8 @@ pid_t getpgid(pid_t);
122# define krb5_free_error_message(a,b) do { } while(0) 122# define krb5_free_error_message(a,b) do { } while(0)
123#endif 123#endif
124 124
125#ifndef HAVE_PLEDGE
126int pledge(const char *promises, const char *paths[]);
127#endif
128
125#endif /* _BSD_MISC_H */ 129#endif /* _BSD_MISC_H */
diff --git a/openbsd-compat/bsd-poll.h b/openbsd-compat/bsd-poll.h
index dcbb9ca40..17945f5b4 100644
--- a/openbsd-compat/bsd-poll.h
+++ b/openbsd-compat/bsd-poll.h
@@ -42,11 +42,11 @@ typedef unsigned int nfds_t;
42#define POLLIN 0x0001 42#define POLLIN 0x0001
43#define POLLOUT 0x0004 43#define POLLOUT 0x0004
44#define POLLERR 0x0008 44#define POLLERR 0x0008
45#define POLLHUP 0x0010
46#define POLLNVAL 0x0020
45#if 0 47#if 0
46/* the following are currently not implemented */ 48/* the following are currently not implemented */
47#define POLLPRI 0x0002 49#define POLLPRI 0x0002
48#define POLLHUP 0x0010
49#define POLLNVAL 0x0020
50#define POLLRDNORM 0x0040 50#define POLLRDNORM 0x0040
51#define POLLNORM POLLRDNORM 51#define POLLNORM POLLRDNORM
52#define POLLWRNORM POLLOUT 52#define POLLWRNORM POLLOUT
diff --git a/openbsd-compat/glob.c b/openbsd-compat/glob.c
index 742b4b954..7c97e67f5 100644
--- a/openbsd-compat/glob.c
+++ b/openbsd-compat/glob.c
@@ -59,6 +59,7 @@
59 */ 59 */
60 60
61#include "includes.h" 61#include "includes.h"
62#include "glob.h"
62 63
63#include <sys/types.h> 64#include <sys/types.h>
64#include <sys/stat.h> 65#include <sys/stat.h>
diff --git a/openbsd-compat/glob.h b/openbsd-compat/glob.h
index f8a7fa5ff..f069a05dc 100644
--- a/openbsd-compat/glob.h
+++ b/openbsd-compat/glob.h
@@ -42,11 +42,15 @@
42 !defined(HAVE_DECL_GLOB_NOMATCH) || HAVE_DECL_GLOB_NOMATCH == 0 || \ 42 !defined(HAVE_DECL_GLOB_NOMATCH) || HAVE_DECL_GLOB_NOMATCH == 0 || \
43 defined(BROKEN_GLOB) 43 defined(BROKEN_GLOB)
44 44
45#ifndef _GLOB_H_ 45#ifndef _COMPAT_GLOB_H_
46#define _GLOB_H_ 46#define _COMPAT_GLOB_H_
47 47
48#include <sys/stat.h> 48#include <sys/stat.h>
49 49
50# define glob_t _ssh_compat_glob_t
51# define glob(a, b, c, d) _ssh__compat_glob(a, b, c, d)
52# define globfree(a) _ssh__compat_globfree(a)
53
50struct stat; 54struct stat;
51typedef struct { 55typedef struct {
52 int gl_pathc; /* Count of total paths so far. */ 56 int gl_pathc; /* Count of total paths so far. */
diff --git a/openbsd-compat/openbsd-compat.h b/openbsd-compat/openbsd-compat.h
index 1ff7114ef..8cc8a11b7 100644
--- a/openbsd-compat/openbsd-compat.h
+++ b/openbsd-compat/openbsd-compat.h
@@ -39,7 +39,6 @@
39/* OpenBSD function replacements */ 39/* OpenBSD function replacements */
40#include "base64.h" 40#include "base64.h"
41#include "sigact.h" 41#include "sigact.h"
42#include "glob.h"
43#include "readpassphrase.h" 42#include "readpassphrase.h"
44#include "vis.h" 43#include "vis.h"
45#include "getrrsetbyname.h" 44#include "getrrsetbyname.h"
diff --git a/openbsd-compat/port-solaris.c b/openbsd-compat/port-solaris.c
index 25382f1c9..e36e412d7 100644
--- a/openbsd-compat/port-solaris.c
+++ b/openbsd-compat/port-solaris.c
@@ -227,3 +227,139 @@ solaris_set_default_project(struct passwd *pw)
227 } 227 }
228} 228}
229#endif /* USE_SOLARIS_PROJECTS */ 229#endif /* USE_SOLARIS_PROJECTS */
230
231#ifdef USE_SOLARIS_PRIVS
232# ifdef HAVE_PRIV_H
233# include <priv.h>
234# endif
235
236priv_set_t *
237solaris_basic_privset(void)
238{
239 priv_set_t *pset;
240
241#ifdef HAVE_PRIV_BASICSET
242 if ((pset = priv_allocset()) == NULL) {
243 error("priv_allocset: %s", strerror(errno));
244 return NULL;
245 }
246 priv_basicset(pset);
247#else
248 if ((pset = priv_str_to_set("basic", ",", NULL)) == NULL) {
249 error("priv_str_to_set: %s", strerror(errno));
250 return NULL;
251 }
252#endif
253 return pset;
254}
255
256void
257solaris_drop_privs_pinfo_net_fork_exec(void)
258{
259 priv_set_t *pset = NULL, *npset = NULL;
260
261 /*
262 * Note: this variant avoids dropping DAC filesystem rights, in case
263 * the process calling it is running as root and should have the
264 * ability to read/write/chown any file on the system.
265 *
266 * We start with the basic set, then *add* the DAC rights to it while
267 * taking away other parts of BASIC we don't need. Then we intersect
268 * this with our existing PERMITTED set. In this way we keep any
269 * DAC rights we had before, while otherwise reducing ourselves to
270 * the minimum set of privileges we need to proceed.
271 *
272 * This also means we drop any other parts of "root" that we don't
273 * need (e.g. the ability to kill any process, create new device nodes
274 * etc etc).
275 */
276
277 if ((pset = priv_allocset()) == NULL)
278 fatal("priv_allocset: %s", strerror(errno));
279 if ((npset = solaris_basic_privset()) == NULL)
280 fatal("solaris_basic_privset: %s", strerror(errno));
281
282 if (priv_addset(npset, PRIV_FILE_CHOWN) != 0 ||
283 priv_addset(npset, PRIV_FILE_DAC_READ) != 0 ||
284 priv_addset(npset, PRIV_FILE_DAC_SEARCH) != 0 ||
285 priv_addset(npset, PRIV_FILE_DAC_WRITE) != 0 ||
286 priv_addset(npset, PRIV_FILE_OWNER) != 0)
287 fatal("priv_addset: %s", strerror(errno));
288
289 if (priv_delset(npset, PRIV_FILE_LINK_ANY) != 0 ||
290#ifdef PRIV_NET_ACCESS
291 priv_delset(npset, PRIV_NET_ACCESS) != 0 ||
292#endif
293 priv_delset(npset, PRIV_PROC_EXEC) != 0 ||
294 priv_delset(npset, PRIV_PROC_FORK) != 0 ||
295 priv_delset(npset, PRIV_PROC_INFO) != 0 ||
296 priv_delset(npset, PRIV_PROC_SESSION) != 0)
297 fatal("priv_delset: %s", strerror(errno));
298
299 if (getppriv(PRIV_PERMITTED, pset) != 0)
300 fatal("getppriv: %s", strerror(errno));
301
302 priv_intersect(pset, npset);
303
304 if (setppriv(PRIV_SET, PRIV_PERMITTED, npset) != 0 ||
305 setppriv(PRIV_SET, PRIV_LIMIT, npset) != 0 ||
306 setppriv(PRIV_SET, PRIV_INHERITABLE, npset) != 0)
307 fatal("setppriv: %s", strerror(errno));
308
309 priv_freeset(pset);
310 priv_freeset(npset);
311}
312
313void
314solaris_drop_privs_root_pinfo_net(void)
315{
316 priv_set_t *pset = NULL;
317
318 /* Start with "basic" and drop everything we don't need. */
319 if ((pset = solaris_basic_privset()) == NULL)
320 fatal("solaris_basic_privset: %s", strerror(errno));
321
322 if (priv_delset(pset, PRIV_FILE_LINK_ANY) != 0 ||
323#ifdef PRIV_NET_ACCESS
324 priv_delset(pset, PRIV_NET_ACCESS) != 0 ||
325#endif
326 priv_delset(pset, PRIV_PROC_INFO) != 0 ||
327 priv_delset(pset, PRIV_PROC_SESSION) != 0)
328 fatal("priv_delset: %s", strerror(errno));
329
330 if (setppriv(PRIV_SET, PRIV_PERMITTED, pset) != 0 ||
331 setppriv(PRIV_SET, PRIV_LIMIT, pset) != 0 ||
332 setppriv(PRIV_SET, PRIV_INHERITABLE, pset) != 0)
333 fatal("setppriv: %s", strerror(errno));
334
335 priv_freeset(pset);
336}
337
338void
339solaris_drop_privs_root_pinfo_net_exec(void)
340{
341 priv_set_t *pset = NULL;
342
343
344 /* Start with "basic" and drop everything we don't need. */
345 if ((pset = solaris_basic_privset()) == NULL)
346 fatal("solaris_basic_privset: %s", strerror(errno));
347
348 if (priv_delset(pset, PRIV_FILE_LINK_ANY) != 0 ||
349#ifdef PRIV_NET_ACCESS
350 priv_delset(pset, PRIV_NET_ACCESS) != 0 ||
351#endif
352 priv_delset(pset, PRIV_PROC_EXEC) != 0 ||
353 priv_delset(pset, PRIV_PROC_INFO) != 0 ||
354 priv_delset(pset, PRIV_PROC_SESSION) != 0)
355 fatal("priv_delset: %s", strerror(errno));
356
357 if (setppriv(PRIV_SET, PRIV_PERMITTED, pset) != 0 ||
358 setppriv(PRIV_SET, PRIV_LIMIT, pset) != 0 ||
359 setppriv(PRIV_SET, PRIV_INHERITABLE, pset) != 0)
360 fatal("setppriv: %s", strerror(errno));
361
362 priv_freeset(pset);
363}
364
365#endif
diff --git a/openbsd-compat/port-solaris.h b/openbsd-compat/port-solaris.h
index cd442e78b..3a41ea8cd 100644
--- a/openbsd-compat/port-solaris.h
+++ b/openbsd-compat/port-solaris.h
@@ -26,5 +26,11 @@ void solaris_contract_pre_fork(void);
26void solaris_contract_post_fork_child(void); 26void solaris_contract_post_fork_child(void);
27void solaris_contract_post_fork_parent(pid_t pid); 27void solaris_contract_post_fork_parent(pid_t pid);
28void solaris_set_default_project(struct passwd *); 28void solaris_set_default_project(struct passwd *);
29# ifdef USE_SOLARIS_PRIVS
30priv_set_t *solaris_basic_privset(void);
31void solaris_drop_privs_pinfo_net_fork_exec(void);
32void solaris_drop_privs_root_pinfo_net(void);
33void solaris_drop_privs_root_pinfo_net_exec(void);
34# endif /* USE_SOLARIS_PRIVS */
29 35
30#endif 36#endif
diff --git a/openbsd-compat/realpath.c b/openbsd-compat/realpath.c
index ba4cea938..a2f090e55 100644
--- a/openbsd-compat/realpath.c
+++ b/openbsd-compat/realpath.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: realpath.c,v 1.13 2005/08/08 08:05:37 espie Exp $ */ 1/* $OpenBSD: realpath.c,v 1.20 2015/10/13 20:55:37 millert Exp $ */
2/* 2/*
3 * Copyright (c) 2003 Constantin S. Svintsoff <kostik@iclub.nsu.ru> 3 * Copyright (c) 2003 Constantin S. Svintsoff <kostik@iclub.nsu.ru>
4 * 4 *
@@ -42,6 +42,13 @@
42#include <stddef.h> 42#include <stddef.h>
43#include <string.h> 43#include <string.h>
44#include <unistd.h> 44#include <unistd.h>
45#include <limits.h>
46
47#ifndef SYMLOOP_MAX
48# define SYMLOOP_MAX 32
49#endif
50
51/* A slightly modified copy of this file exists in libexec/ld.so */
45 52
46/* 53/*
47 * char *realpath(const char *path, char resolved[PATH_MAX]); 54 * char *realpath(const char *path, char resolved[PATH_MAX]);
@@ -51,16 +58,30 @@
51 * in which case the path which caused trouble is left in (resolved). 58 * in which case the path which caused trouble is left in (resolved).
52 */ 59 */
53char * 60char *
54realpath(const char *path, char resolved[PATH_MAX]) 61realpath(const char *path, char *resolved)
55{ 62{
56 struct stat sb; 63 struct stat sb;
57 char *p, *q, *s; 64 char *p, *q, *s;
58 size_t left_len, resolved_len; 65 size_t left_len, resolved_len;
59 unsigned symlinks; 66 unsigned symlinks;
60 int serrno, slen; 67 int serrno, slen, mem_allocated;
61 char left[PATH_MAX], next_token[PATH_MAX], symlink[PATH_MAX]; 68 char left[PATH_MAX], next_token[PATH_MAX], symlink[PATH_MAX];
62 69
70 if (path[0] == '\0') {
71 errno = ENOENT;
72 return (NULL);
73 }
74
63 serrno = errno; 75 serrno = errno;
76
77 if (resolved == NULL) {
78 resolved = malloc(PATH_MAX);
79 if (resolved == NULL)
80 return (NULL);
81 mem_allocated = 1;
82 } else
83 mem_allocated = 0;
84
64 symlinks = 0; 85 symlinks = 0;
65 if (path[0] == '/') { 86 if (path[0] == '/') {
66 resolved[0] = '/'; 87 resolved[0] = '/';
@@ -71,7 +92,10 @@ realpath(const char *path, char resolved[PATH_MAX])
71 left_len = strlcpy(left, path + 1, sizeof(left)); 92 left_len = strlcpy(left, path + 1, sizeof(left));
72 } else { 93 } else {
73 if (getcwd(resolved, PATH_MAX) == NULL) { 94 if (getcwd(resolved, PATH_MAX) == NULL) {
74 strlcpy(resolved, ".", PATH_MAX); 95 if (mem_allocated)
96 free(resolved);
97 else
98 strlcpy(resolved, ".", PATH_MAX);
75 return (NULL); 99 return (NULL);
76 } 100 }
77 resolved_len = strlen(resolved); 101 resolved_len = strlen(resolved);
@@ -79,7 +103,7 @@ realpath(const char *path, char resolved[PATH_MAX])
79 } 103 }
80 if (left_len >= sizeof(left) || resolved_len >= PATH_MAX) { 104 if (left_len >= sizeof(left) || resolved_len >= PATH_MAX) {
81 errno = ENAMETOOLONG; 105 errno = ENAMETOOLONG;
82 return (NULL); 106 goto err;
83 } 107 }
84 108
85 /* 109 /*
@@ -94,7 +118,7 @@ realpath(const char *path, char resolved[PATH_MAX])
94 s = p ? p : left + left_len; 118 s = p ? p : left + left_len;
95 if (s - left >= (ptrdiff_t)sizeof(next_token)) { 119 if (s - left >= (ptrdiff_t)sizeof(next_token)) {
96 errno = ENAMETOOLONG; 120 errno = ENAMETOOLONG;
97 return (NULL); 121 goto err;
98 } 122 }
99 memcpy(next_token, left, s - left); 123 memcpy(next_token, left, s - left);
100 next_token[s - left] = '\0'; 124 next_token[s - left] = '\0';
@@ -104,7 +128,7 @@ realpath(const char *path, char resolved[PATH_MAX])
104 if (resolved[resolved_len - 1] != '/') { 128 if (resolved[resolved_len - 1] != '/') {
105 if (resolved_len + 1 >= PATH_MAX) { 129 if (resolved_len + 1 >= PATH_MAX) {
106 errno = ENAMETOOLONG; 130 errno = ENAMETOOLONG;
107 return (NULL); 131 goto err;
108 } 132 }
109 resolved[resolved_len++] = '/'; 133 resolved[resolved_len++] = '/';
110 resolved[resolved_len] = '\0'; 134 resolved[resolved_len] = '\0';
@@ -135,23 +159,23 @@ realpath(const char *path, char resolved[PATH_MAX])
135 resolved_len = strlcat(resolved, next_token, PATH_MAX); 159 resolved_len = strlcat(resolved, next_token, PATH_MAX);
136 if (resolved_len >= PATH_MAX) { 160 if (resolved_len >= PATH_MAX) {
137 errno = ENAMETOOLONG; 161 errno = ENAMETOOLONG;
138 return (NULL); 162 goto err;
139 } 163 }
140 if (lstat(resolved, &sb) != 0) { 164 if (lstat(resolved, &sb) != 0) {
141 if (errno == ENOENT && p == NULL) { 165 if (errno == ENOENT && p == NULL) {
142 errno = serrno; 166 errno = serrno;
143 return (resolved); 167 return (resolved);
144 } 168 }
145 return (NULL); 169 goto err;
146 } 170 }
147 if (S_ISLNK(sb.st_mode)) { 171 if (S_ISLNK(sb.st_mode)) {
148 if (symlinks++ > MAXSYMLINKS) { 172 if (symlinks++ > SYMLOOP_MAX) {
149 errno = ELOOP; 173 errno = ELOOP;
150 return (NULL); 174 goto err;
151 } 175 }
152 slen = readlink(resolved, symlink, sizeof(symlink) - 1); 176 slen = readlink(resolved, symlink, sizeof(symlink) - 1);
153 if (slen < 0) 177 if (slen < 0)
154 return (NULL); 178 goto err;
155 symlink[slen] = '\0'; 179 symlink[slen] = '\0';
156 if (symlink[0] == '/') { 180 if (symlink[0] == '/') {
157 resolved[1] = 0; 181 resolved[1] = 0;
@@ -174,15 +198,15 @@ realpath(const char *path, char resolved[PATH_MAX])
174 if (slen + 1 >= 198 if (slen + 1 >=
175 (ptrdiff_t)sizeof(symlink)) { 199 (ptrdiff_t)sizeof(symlink)) {
176 errno = ENAMETOOLONG; 200 errno = ENAMETOOLONG;
177 return (NULL); 201 goto err;
178 } 202 }
179 symlink[slen] = '/'; 203 symlink[slen] = '/';
180 symlink[slen + 1] = 0; 204 symlink[slen + 1] = 0;
181 } 205 }
182 left_len = strlcat(symlink, left, sizeof(left)); 206 left_len = strlcat(symlink, left, sizeof(symlink));
183 if (left_len >= sizeof(left)) { 207 if (left_len >= sizeof(symlink)) {
184 errno = ENAMETOOLONG; 208 errno = ENAMETOOLONG;
185 return (NULL); 209 goto err;
186 } 210 }
187 } 211 }
188 left_len = strlcpy(left, symlink, sizeof(left)); 212 left_len = strlcpy(left, symlink, sizeof(left));
@@ -196,5 +220,10 @@ realpath(const char *path, char resolved[PATH_MAX])
196 if (resolved_len > 1 && resolved[resolved_len - 1] == '/') 220 if (resolved_len > 1 && resolved[resolved_len - 1] == '/')
197 resolved[resolved_len - 1] = '\0'; 221 resolved[resolved_len - 1] = '\0';
198 return (resolved); 222 return (resolved);
223
224err:
225 if (mem_allocated)
226 free(resolved);
227 return (NULL);
199} 228}
200#endif /* !defined(HAVE_REALPATH) || defined(BROKEN_REALPATH) */ 229#endif /* !defined(HAVE_REALPATH) || defined(BROKEN_REALPATH) */