1 /*
2 * util.c - routeup/tlsdated utility functions
3 * Copyright (c) 2012 The Chromium Authors. All rights reserved.
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8 #include "config.h"
9
10 #include <grp.h>
11 #include <pwd.h>
12 #include <stdarg.h>
13 #include <stdio.h>
14 #include <sys/types.h>
15 #if !_PLAN9_SOURCE
16 #include <syslog.h>
17 #endif
18 #include <unistd.h>
19
20 #include "src/util.h"
21
22 /** helper function to print message and die */
23 void
die(const char * fmt,...)24 die (const char *fmt, ...)
25 {
26 va_list ap;
27
28 va_start(ap, fmt);
29 vfprintf(stderr, fmt, ap);
30 va_end(ap);
31 exit(1);
32 }
33
34 /** helper function for 'verbose' output */
35 void
verb(const char * fmt,...)36 verb (const char *fmt, ...)
37 {
38 va_list ap;
39
40 if (! verbose) return;
41 va_start(ap, fmt);
42 vfprintf(stderr, fmt, ap);
43 va_end(ap);
44 }
45
46 #if !_PLAN9_SOURCE
logat(int isverbose,const char * fmt,...)47 void API logat(int isverbose, const char *fmt, ...)
48 {
49 if (isverbose && !verbose)
50 return;
51 va_list ap;
52 va_start(ap, fmt);
53 vfprintf(stderr, fmt, ap);
54 fprintf(stderr, "\n");
55 va_end(ap);
56 va_start(ap, fmt);
57 vsyslog(LOG_INFO, fmt, ap);
58 va_end(ap);
59 }
60 #endif
61
62
63 void
drop_privs_to(const char * user,const char * group,const char ** supp_groups)64 drop_privs_to (const char *user, const char *group, const char **supp_groups)
65 {
66 #if !_PLAN9_SOURCE
67
68 uid_t uid;
69 gid_t gid;
70 struct passwd *pw;
71 struct group *gr;
72
73 /* TODO(garnold) Implement supplementary group support. */
74 if (supp_groups)
75 die ("Supplementary groups not supported\n");
76
77 if (0 != getuid ())
78 return; /* not running as root to begin with; should (!) be harmless to continue
79 without dropping to 'nobody' (setting time will fail in the end) */
80 pw = getpwnam(user);
81 gr = getgrnam(group);
82 if (NULL == pw)
83 die ("Failed to obtain UID for `%s'\n", user);
84 if (NULL == gr)
85 die ("Failed to obtain GID for `%s'\n", group);
86 uid = pw->pw_uid;
87 if (0 == uid)
88 die ("UID for `%s' is 0, refusing to run SSL\n", user);
89 gid = pw->pw_gid;
90 if (0 == gid || 0 == gr->gr_gid)
91 die ("GID for `%s' is 0, refusing to run SSL\n", user);
92 if (pw->pw_gid != gr->gr_gid)
93 die ("GID for `%s' is not `%s' as expected, refusing to run SSL\n",
94 user, group);
95
96 if (0 != initgroups((const char *)user, gr->gr_gid))
97 die ("Unable to initgroups for `%s' in group `%s' as expected\n",
98 user, group);
99
100 #ifdef HAVE_SETRESGID
101 if (0 != setresgid (gid, gid, gid))
102 die ("Failed to setresgid: %s\n", strerror (errno));
103 #else
104 if (0 != (setgid (gid) | setegid (gid)))
105 die ("Failed to setgid: %s\n", strerror (errno));
106 #endif
107 #ifdef HAVE_SETRESUID
108 if (0 != setresuid (uid, uid, uid))
109 die ("Failed to setresuid: %s\n", strerror (errno));
110 #else
111 if (0 != (setuid (uid) | seteuid (uid)))
112 die ("Failed to setuid: %s\n", strerror (errno));
113 #endif
114 #endif /* !_PLAN9_SOURCE */
115 }
116
117