root/src/utils/noit_security.c

Revision 670f01e50c4bf8c2e20f6be14acc73b631d91163, 4.8 kB (checked in by Theo Schlossnagle <jesus@omniti.com>, 4 years ago)

fixes logfile ownership if -u/-g is specified, refs #205

  • Property mode set to 100644
Line 
1 /*
2  * Copyright (c) 2005-2009, OmniTI Computer Consulting, Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met:
8  *
9  *    * Redistributions of source code must retain the above copyright
10  *      notice, this list of conditions and the following disclaimer.
11  *    * Redistributions in binary form must reproduce the above
12  *      copyright notice, this list of conditions and the following
13  *      disclaimer in the documentation and/or other materials provided
14  *      with the distribution.
15  *    * Neither the name OmniTI Computer Consulting, Inc. nor the names
16  *      of its contributors may be used to endorse or promote products
17  *      derived from this software without specific prior written
18  *      permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32
33 #include "noit_defines.h"
34
35 #include <stdio.h>
36 #include <unistd.h>
37 #include <sys/time.h>
38 #include <pwd.h>
39 #include <grp.h>
40 #include <errno.h>
41
42 #include "noit_config.h"
43 #include "utils/noit_log.h"
44 #include "utils/noit_security.h"
45
46 #define BAIL(a...) do { noitL(noit_error, a); return -1; } while(0)
47
48 int
49 noit_security_chroot(const char *path) {
50   if(chroot(path)) BAIL("chroot: %s\n", strerror(errno));
51   if(chdir("/")) BAIL("chdir: %s\n", strerror(errno));
52   return 0;
53 }
54
55 static inline int isinteger(const char *user) {
56   const char *cp = user;
57   while(*cp) {
58     switch(cp == user) {
59       case 0:
60         if(*cp < '0' || *cp > '9') return 0;
61         break;
62       default:
63         if(*cp != '-' && (*cp < '0' || *cp > '9')) return 0;
64     }
65     cp++;
66   }
67   return (cp != user);
68 }
69 static struct passwd *
70 __getpwnam_r(const char *user, struct passwd *pw,
71              char *buf, size_t len) {
72 #ifdef HAVE_GETPWNAM_R_POSIX
73   struct passwd *r;
74   if(0 == getpwnam_r(user, pw, buf, len, &r)) return r;
75   return NULL;
76 #else
77 #if HAVE_GETPWNAM_R
78   return getpwnam_r(user, pw, buf, len);
79 #else
80   return getpwnam(user);
81 #endif
82 #endif
83 }
84 static struct group *
85 __getgrnam_r(const char *group, struct group *gr,
86              char *buf, size_t len) {
87 #ifdef HAVE_GETGRNAM_R_POSIX
88   struct group *r;
89   if(0 == getgrnam_r(group, gr, buf, len, &r)) return r;
90   return NULL;
91 #else
92 #ifdef HAVE_GETGRNAM_R
93   return getgrnam_r(group, gr, buf, len);
94 #else
95   return getgrnam(group);
96 #endif
97 #endif
98 }
99
100 int
101 noit_security_usergroup(const char *user, const char *group, noit_boolean eff) {
102   static long pwnam_buflen = 0;
103   static long grnam_buflen = 0;
104   uid_t uid = 0;
105   gid_t gid = 0;
106
107   if(pwnam_buflen == 0)
108 #ifdef _SC_GETPW_R_SIZE_MAX
109     pwnam_buflen = sysconf(_SC_GETPW_R_SIZE_MAX);
110 #else
111     pwnam_buflen = 100; /* This shouldn't be used, so size is not important. */
112 #endif
113   if(grnam_buflen == 0)
114 #ifdef _SC_GETGR_R_SIZE_MAX
115     grnam_buflen = sysconf(_SC_GETGR_R_SIZE_MAX);
116 #else
117     grnam_buflen = 100;
118 #endif
119
120   if(user) {
121     if(isinteger(user)) uid = atoi(user);
122     else {
123       struct passwd *pw, _pw;
124       char *buf;
125       if(NULL == (buf = alloca(pwnam_buflen))) BAIL("alloca failed\n");
126       if(NULL == (pw = __getpwnam_r(user, &_pw, buf, pwnam_buflen)))
127         BAIL("Cannot find user '%s'\n", user);
128       uid = pw->pw_uid;
129     }
130   }
131
132   if(group) {
133     if(isinteger(group)) gid = atoi(group);
134     else {
135       struct group *gr, _gr;
136       char *buf;
137       if(NULL == (buf = alloca(grnam_buflen))) BAIL("alloca failed\n");
138       if(NULL == (gr = __getgrnam_r(user, &_gr, buf, grnam_buflen)))
139         BAIL("Cannot find group '%s'\n", user);
140       gid = gr->gr_gid;
141     }
142   }
143
144   if(group) {
145     if(!eff && gid == 0) BAIL("Cannot use this function to setgid(0)\n");
146     if((eff ? setegid(gid) : setgid(gid)) != 0)
147       BAIL("setgid(%d) failed: %s\n", (int)gid, strerror(errno));
148   }
149   if(user) {
150     if(!eff && uid == 0) BAIL("Cannot use this function to setuid(0)\n");
151     if((eff ? seteuid(uid) : setuid(uid)) != 0)
152       BAIL("setgid(%d) failed: %s\n", (int)gid, strerror(errno));
153     if(!eff && setuid(0) == 0)
154       BAIL("setuid(0) worked, and it shouldn't have.\n");
155     if(!eff && setgid(0) == 0)
156       BAIL("setgid(0) worked, and it shouldn't have.\n");
157   }
158   return 0;
159 }
Note: See TracBrowser for help on using the browser.