suricata
util-privs.c
Go to the documentation of this file.
1/* Copyright (C) 2007-2010 Open Information Security Foundation
2 *
3 * You can copy, redistribute or modify this Program under the terms of
4 * the GNU General Public License version 2 as published by the Free
5 * Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * version 2 along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 */
17
18/**
19 * \file
20 *
21 * \author Gurvinder Singh <gurvindersinghdahiya@gmail.com>
22 *
23 * File to drop the engine capabilities using libcap-ng by
24 * Steve Grubb
25 */
26
27#ifndef OS_WIN32
28
29#include "suricata-common.h"
30#include "util-debug.h"
31#include "suricata.h"
32
33#include "util-privs.h"
34#include "util-byte.h"
35
36#ifdef HAVE_LIBCAP_NG
37
38#include <cap-ng.h>
39#ifdef HAVE_SYS_PRCTL_H
40#include <sys/prctl.h>
41#endif
42#include "threadvars.h"
43#include "runmodes.h"
44
45/** flag indicating if we'll be using caps */
46extern bool sc_set_caps;
47
48/**
49 * \brief Drop the privileges of the main thread
50 */
51void SCDropMainThreadCaps(uint32_t userid, uint32_t groupid)
52{
53 if (!sc_set_caps)
54 return;
55
56 capng_clear(CAPNG_SELECT_BOTH);
57
58 switch (SCRunmodeGet()) {
60 case RUNMODE_AFP_DEV:
62 capng_updatev(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED,
63 CAP_NET_RAW, /* needed for pcap live mode */
64 CAP_SYS_NICE,
65 CAP_NET_ADMIN,
66 -1);
67 break;
68 case RUNMODE_NFLOG:
69 case RUNMODE_NFQ:
70 capng_updatev(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED,
71 CAP_NET_ADMIN, /* needed for nflog and nfqueue inline mode */
72 CAP_SYS_NICE,
73 -1);
74 break;
75 default:
76 break;
77 }
78
79 if (capng_change_id(userid, groupid, CAPNG_DROP_SUPP_GRP |
80 CAPNG_CLEAR_BOUNDING) < 0)
81 {
82 FatalError("capng_change_id for main thread"
83 " failed");
84 }
85
86 SCLogInfo("dropped the caps for main thread");
87}
88
90{
91#if 0
92 capng_clear(CAPNG_SELECT_BOTH);
93 capng_apply(CAPNG_SELECT_BOTH);
95 capng_update(CAPNG_ADD, (capng_type_t) (CAPNG_EFFECTIVE | CAPNG_PERMITTED), CAP_IPC_LOCK);
96 capng_apply(CAPNG_SELECT_CAPS);
97 SCLogDebug("For thread \"%s\" CAP_IPC_LOCK has been set", tv->name);
98 }
100 capng_update(CAPNG_ADD, (capng_type_t) (CAPNG_EFFECTIVE | CAPNG_PERMITTED), CAP_NET_ADMIN);
101 capng_apply(CAPNG_SELECT_CAPS);
102 SCLogDebug("For thread \"%s\" CAP_NET_ADMIN has been set", tv->name);
103 }
105 capng_update(CAPNG_ADD, (capng_type_t) (CAPNG_EFFECTIVE | CAPNG_PERMITTED), CAP_NET_BIND_SERVICE);
106 capng_apply(CAPNG_SELECT_CAPS);
107 SCLogDebug("For thread \"%s\" CAP_NET_BIND_SERVICE has been set", tv->name);
108 }
110 capng_update(CAPNG_ADD, (capng_type_t) (CAPNG_EFFECTIVE | CAPNG_PERMITTED), CAP_NET_BROADCAST);
111 capng_apply(CAPNG_SELECT_CAPS);
112 SCLogDebug("For thread \"%s\" CAP_NET_BROADCAST has been set", tv->name);
113 }
114 if (tv->cap_flags & SC_CAP_NET_RAW) {
115 capng_update(CAPNG_ADD, (capng_type_t) (CAPNG_EFFECTIVE | CAPNG_PERMITTED), CAP_NET_RAW);
116 capng_apply(CAPNG_SELECT_CAPS);
117 SCLogDebug("For thread \"%s\" CAP_NET_RAW has been set", tv->name);
118 }
120 capng_update(CAPNG_ADD, (capng_type_t) (CAPNG_EFFECTIVE | CAPNG_PERMITTED), CAP_SYS_ADMIN);
121 capng_apply(CAPNG_SELECT_CAPS);
122 SCLogDebug("For thread \"%s\" CAP_SYS_ADMIN has been set", tv->name);
123 }
125 capng_update(CAPNG_ADD, (capng_type_t) (CAPNG_EFFECTIVE | CAPNG_PERMITTED), CAP_SYS_RAWIO);
126 capng_apply(CAPNG_SELECT_CAPS);
127 SCLogDebug("For thread \"%s\" CAP_SYS_RAWIO has been set", tv->name);
128 }
129#endif
130}
131
132#endif /* HAVE_LIBCAP_NG */
133
134/**
135 * \brief Function to get the user and group ID from the specified user name
136 *
137 * \param user_name pointer to the given user name
138 * \param uid pointer to the user id in which result will be stored
139 * \param gid pointer to the group id in which result will be stored
140 *
141 * \retval FatalError on a failure
142 */
143void SCGetUserID(const char *user_name, const char *group_name, uint32_t *uid, uint32_t *gid)
144{
145 uint32_t userid = 0;
146 uint32_t groupid = 0;
147 struct passwd *pw;
148
149 if (user_name == NULL || strlen(user_name) == 0) {
150 FatalError("no user name was provided - ensure it is specified either in the configuration "
151 "file (run-as.user) or in command-line arguments (--user)");
152 }
153
154 /* Get the user ID */
155 if (isdigit((unsigned char)user_name[0]) != 0) {
156 if (ByteExtractStringUint32(&userid, 10, 0, (const char *)user_name) < 0) {
157 FatalError("invalid user id value: '%s'", user_name);
158 }
159 pw = getpwuid(userid);
160 if (pw == NULL) {
161 FatalError("unable to get the user ID, "
162 "check if user exist!!");
163 }
164 } else {
165 pw = getpwnam(user_name);
166 if (pw == NULL) {
167 FatalError("unable to get the user ID, "
168 "check if user exist!!");
169 }
170 userid = pw->pw_uid;
171 }
172
173 /* Get the group ID */
174 if (group_name != NULL) {
175 struct group *gp;
176
177 if (isdigit((unsigned char)group_name[0]) != 0) {
178 if (ByteExtractStringUint32(&groupid, 10, 0, (const char *)group_name) < 0) {
179 FatalError("invalid group id: '%s'", group_name);
180 }
181 } else {
182 gp = getgrnam(group_name);
183 if (gp == NULL) {
184 FatalError("unable to get the group"
185 " ID, check if group exist!!");
186 }
187 groupid = gp->gr_gid;
188 }
189 } else {
190 groupid = pw->pw_gid;
191 }
192
193 /* close the group database */
194 endgrent();
195 /* close the user database */
196 endpwent();
197
198 *uid = userid;
199 *gid = groupid;
200}
201
202/**
203 * \brief Function to get the group ID from the specified group name
204 *
205 * \param group_name pointer to the given group name
206 * \param gid pointer to the group id in which result will be stored
207 *
208 * \retval FatalError on a failure
209 */
210void SCGetGroupID(const char *group_name, uint32_t *gid)
211{
212 uint32_t grpid = 0;
213 struct group *gp;
214
215 if (group_name == NULL || strlen(group_name) == 0) {
216 FatalError("no group name was provided - ensure it is specified either in the "
217 "configuration file (run-as.group) or in command-line arguments (--group)");
218 }
219
220 /* Get the group ID */
221 if (isdigit((unsigned char)group_name[0]) != 0) {
222 if (ByteExtractStringUint32(&grpid, 10, 0, (const char *)group_name) < 0) {
223 FatalError("invalid group id: '%s'", group_name);
224 }
225 } else {
226 gp = getgrnam(group_name);
227 if (gp == NULL) {
228 FatalError("unable to get the group ID,"
229 " check if group exist!!");
230 }
231 grpid = gp->gr_gid;
232 }
233
234 /* close the group database */
235 endgrent();
236
237 *gid = grpid;
238}
239
240#ifdef __OpenBSD__
241int SCPledge(void)
242{
243 int ret = pledge("stdio rpath wpath cpath fattr unix dns bpf", NULL);
244
245 if (ret != 0) {
246 SCLogError("unable to pledge,"
247 " check permissions!! ret=%i errno=%i",
248 ret, errno);
249 exit(EXIT_FAILURE);
250 }
251
252 return 0;
253}
254#endif /* __OpenBSD__ */
255#endif /* OS_WIN32 */
uint8_t group
bool sc_set_caps
Definition suricata.c:189
ThreadVars * tv
@ RUNMODE_NFLOG
Definition runmodes.h:32
@ RUNMODE_NFQ
Definition runmodes.h:31
@ RUNMODE_AFP_DEV
Definition runmodes.h:36
@ RUNMODE_AFXDP_DEV
Definition runmodes.h:37
@ RUNMODE_PCAP_DEV
Definition runmodes.h:29
Per thread variable structure.
Definition threadvars.h:58
uint8_t cap_flags
Definition threadvars.h:81
char name[16]
Definition threadvars.h:65
SCRunMode SCRunmodeGet(void)
Get the current run mode.
Definition suricata.c:279
int ByteExtractStringUint32(uint32_t *res, int base, size_t len, const char *str)
Definition util-byte.c:239
#define FatalError(...)
Definition util-debug.h:510
#define SCLogDebug(...)
Definition util-debug.h:275
#define SCLogInfo(...)
Macro used to log INFORMATIONAL messages.
Definition util-debug.h:225
#define SCLogError(...)
Macro used to log ERROR messages.
Definition util-debug.h:267
void SCGetGroupID(const char *group_name, uint32_t *gid)
Function to get the group ID from the specified group name.
Definition util-privs.c:210
void SCGetUserID(const char *user_name, const char *group_name, uint32_t *uid, uint32_t *gid)
Function to get the user and group ID from the specified user name.
Definition util-privs.c:143
#define SC_CAP_NET_RAW
Definition util-privs.h:32
#define SC_CAP_IPC_LOCK
Definition util-privs.h:30
#define SCDropCaps(...)
Definition util-privs.h:89
#define SC_CAP_NET_ADMIN
Definition util-privs.h:31
#define SC_CAP_NET_BROADCAST
Definition util-privs.h:34
#define SC_CAP_SYS_RAW_IO
Definition util-privs.h:29
#define SC_CAP_NET_BIND_SERVICE
Definition util-privs.h:33
#define SCPledge(...)
Definition util-privs.h:99
#define SC_CAP_SYS_ADMIN
Definition util-privs.h:28
#define SCDropMainThreadCaps(...)
Definition util-privs.h:90