• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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