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 "util-cpu.h"
44 #include "runmodes.h"
45 
46 /** flag indicating if we'll be using caps */
47 extern int sc_set_caps;
48 
49 /** our current runmode */
50 extern int run_mode;
51 
52 /**
53  * \brief Drop the previliges of the main thread
54  */
55 void SCDropMainThreadCaps(uint32_t userid, uint32_t groupid)
56 {
57  if (sc_set_caps == FALSE)
58  return;
59 
60  capng_clear(CAPNG_SELECT_BOTH);
61 
62  switch (run_mode) {
63  case RUNMODE_PCAP_DEV:
64  case RUNMODE_AFP_DEV:
65  capng_updatev(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED,
66  CAP_NET_RAW, /* needed for pcap live mode */
67  CAP_SYS_NICE,
68  CAP_NET_ADMIN,
69  -1);
70  break;
71  case RUNMODE_PFRING:
72  capng_updatev(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED,
73  CAP_NET_ADMIN, CAP_NET_RAW, CAP_SYS_NICE,
74  -1);
75  break;
76  case RUNMODE_NFLOG:
77  case RUNMODE_NFQ:
78  capng_updatev(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED,
79  CAP_NET_ADMIN, /* needed for nflog and nfqueue inline mode */
80  CAP_SYS_NICE,
81  -1);
82  break;
83  }
84 
85  if (capng_change_id(userid, groupid, CAPNG_DROP_SUPP_GRP |
86  CAPNG_CLEAR_BOUNDING) < 0)
87  {
88  FatalError(SC_ERR_FATAL, "capng_change_id for main thread"
89  " failed");
90  }
91 
92  SCLogInfo("dropped the caps for main thread");
93 }
94 
96 {
97 #if 0
98  capng_clear(CAPNG_SELECT_BOTH);
99  capng_apply(CAPNG_SELECT_BOTH);
100  if (tv->cap_flags & SC_CAP_IPC_LOCK) {
101  capng_update(CAPNG_ADD, (capng_type_t) (CAPNG_EFFECTIVE | CAPNG_PERMITTED), CAP_IPC_LOCK);
102  capng_apply(CAPNG_SELECT_CAPS);
103  SCLogDebug("For thread \"%s\" CAP_IPC_LOCK has been set", tv->name);
104  }
105  if (tv->cap_flags & SC_CAP_NET_ADMIN) {
106  capng_update(CAPNG_ADD, (capng_type_t) (CAPNG_EFFECTIVE | CAPNG_PERMITTED), CAP_NET_ADMIN);
107  capng_apply(CAPNG_SELECT_CAPS);
108  SCLogDebug("For thread \"%s\" CAP_NET_ADMIN has been set", tv->name);
109  }
111  capng_update(CAPNG_ADD, (capng_type_t) (CAPNG_EFFECTIVE | CAPNG_PERMITTED), CAP_NET_BIND_SERVICE);
112  capng_apply(CAPNG_SELECT_CAPS);
113  SCLogDebug("For thread \"%s\" CAP_NET_BIND_SERVICE has been set", tv->name);
114  }
116  capng_update(CAPNG_ADD, (capng_type_t) (CAPNG_EFFECTIVE | CAPNG_PERMITTED), CAP_NET_BROADCAST);
117  capng_apply(CAPNG_SELECT_CAPS);
118  SCLogDebug("For thread \"%s\" CAP_NET_BROADCAST has been set", tv->name);
119  }
120  if (tv->cap_flags & SC_CAP_NET_RAW) {
121  capng_update(CAPNG_ADD, (capng_type_t) (CAPNG_EFFECTIVE | CAPNG_PERMITTED), CAP_NET_RAW);
122  capng_apply(CAPNG_SELECT_CAPS);
123  SCLogDebug("For thread \"%s\" CAP_NET_RAW has been set", tv->name);
124  }
125  if (tv->cap_flags & SC_CAP_SYS_ADMIN) {
126  capng_update(CAPNG_ADD, (capng_type_t) (CAPNG_EFFECTIVE | CAPNG_PERMITTED), CAP_SYS_ADMIN);
127  capng_apply(CAPNG_SELECT_CAPS);
128  SCLogDebug("For thread \"%s\" CAP_SYS_ADMIN has been set", tv->name);
129  }
130  if (tv->cap_flags & SC_CAP_SYS_RAW_IO) {
131  capng_update(CAPNG_ADD, (capng_type_t) (CAPNG_EFFECTIVE | CAPNG_PERMITTED), CAP_SYS_RAWIO);
132  capng_apply(CAPNG_SELECT_CAPS);
133  SCLogDebug("For thread \"%s\" CAP_SYS_RAWIO has been set", tv->name);
134  }
135 #endif
136 }
137 
138 #endif /* HAVE_LIBCAP_NG */
139 
140 /**
141  * \brief Function to get the user and group ID from the specified user name
142  *
143  * \param user_name pointer to the given user name
144  * \param uid pointer to the user id in which result will be stored
145  * \param gid pointer to the group id in which result will be stored
146  *
147  * \retval upon success it return 0
148  */
149 int SCGetUserID(const char *user_name, const char *group_name, uint32_t *uid, uint32_t *gid)
150 {
151  uint32_t userid = 0;
152  uint32_t groupid = 0;
153  struct passwd *pw;
154 
155  /* Get the user ID */
156  if (isdigit((unsigned char)user_name[0]) != 0) {
157  if (ByteExtractStringUint32(&userid, 10, 0, (const char *)user_name) < 0) {
158  FatalError(SC_ERR_UID_FAILED, "invalid user id value: '%s'", user_name);
159  }
160  pw = getpwuid(userid);
161  if (pw == NULL) {
162  FatalError(SC_ERR_FATAL, "unable to get the user ID, "
163  "check if user exist!!");
164  }
165  } else {
166  pw = getpwnam(user_name);
167  if (pw == NULL) {
168  FatalError(SC_ERR_FATAL, "unable to get the user ID, "
169  "check if user exist!!");
170  }
171  userid = pw->pw_uid;
172  }
173 
174  /* Get the group ID */
175  if (group_name != NULL) {
176  struct group *gp;
177 
178  if (isdigit((unsigned char)group_name[0]) != 0) {
179  if (ByteExtractStringUint32(&groupid, 10, 0, (const char *)group_name) < 0) {
180  FatalError(SC_ERR_GID_FAILED, "invalid group id: '%s'", group_name);
181  }
182  } else {
183  gp = getgrnam(group_name);
184  if (gp == NULL) {
185  FatalError(SC_ERR_FATAL, "unable to get the group"
186  " ID, check if group exist!!");
187  }
188  groupid = gp->gr_gid;
189  }
190  } else {
191  groupid = pw->pw_gid;
192  }
193 
194  /* close the group database */
195  endgrent();
196  /* close the user database */
197  endpwent();
198 
199  *uid = userid;
200  *gid = groupid;
201 
202  return 0;
203 }
204 
205 /**
206  * \brief Function to get the group ID from the specified group name
207  *
208  * \param group_name pointer to the given group name
209  * \param gid pointer to the group id in which result will be stored
210  *
211  * \retval upon success it return 0
212  */
213 int SCGetGroupID(const char *group_name, uint32_t *gid)
214 {
215  uint32_t grpid = 0;
216  struct group *gp;
217 
218  /* Get the group ID */
219  if (isdigit((unsigned char)group_name[0]) != 0) {
220  if (ByteExtractStringUint32(&grpid, 10, 0, (const char *)group_name) < 0) {
221  FatalError(SC_ERR_GID_FAILED, "invalid group id: '%s'", group_name);
222  }
223  } else {
224  gp = getgrnam(group_name);
225  if (gp == NULL) {
226  FatalError(SC_ERR_FATAL, "unable to get the group ID,"
227  " check if group exist!!");
228  }
229  grpid = gp->gr_gid;
230  }
231 
232  /* close the group database */
233  endgrent();
234 
235  *gid = grpid;
236 
237  return 0;
238 }
239 
240 #ifdef __OpenBSD__
241 int SCPledge(void)
242 {
243  int ret = pledge("stdio rpath wpath cpath fattr unix dns bpf", NULL);
244 
245  if (ret != 0) {
246  SCLogError(SC_ERR_PLEDGE_FAILED, "unable to pledge,"
247  " check permissions!! ret=%i errno=%i", ret, errno);
248  exit(EXIT_FAILURE);
249  }
250 
251  return 0;
252 }
253 #endif /* __OpenBSD__ */
254 #endif /* OS_WIN32 */
util-byte.h
ThreadVars_::name
char name[16]
Definition: threadvars.h:65
SC_ERR_GID_FAILED
@ SC_ERR_GID_FAILED
Definition: util-error.h:188
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:298
RUNMODE_NFLOG
@ RUNMODE_NFLOG
Definition: runmodes.h:33
SCGetUserID
int 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:149
RUNMODE_PCAP_DEV
@ RUNMODE_PCAP_DEV
Definition: runmodes.h:29
SCPledge
#define SCPledge(...)
Definition: util-privs.h:100
util-privs.h
SCDropCaps
#define SCDropCaps(...)
Definition: util-privs.h:37
SC_CAP_NET_BROADCAST
#define SC_CAP_NET_BROADCAST
Definition: util-privs.h:34
ThreadVars_::cap_flags
uint8_t cap_flags
Definition: threadvars.h:81
SC_CAP_NET_BIND_SERVICE
#define SC_CAP_NET_BIND_SERVICE
Definition: util-privs.h:33
SC_ERR_UID_FAILED
@ SC_ERR_UID_FAILED
Definition: util-error.h:187
util-debug.h
util-cpu.h
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:58
SC_ERR_PLEDGE_FAILED
@ SC_ERR_PLEDGE_FAILED
Definition: util-error.h:352
SC_CAP_IPC_LOCK
#define SC_CAP_IPC_LOCK
Definition: util-privs.h:30
SC_CAP_NET_ADMIN
#define SC_CAP_NET_ADMIN
Definition: util-privs.h:31
SCGetGroupID
int SCGetGroupID(const char *group_name, uint32_t *gid)
Function to get the group ID from the specified group name.
Definition: util-privs.c:213
FALSE
#define FALSE
Definition: suricata-common.h:34
SC_CAP_SYS_ADMIN
#define SC_CAP_SYS_ADMIN
Definition: util-privs.h:28
ByteExtractStringUint32
int ByteExtractStringUint32(uint32_t *res, int base, uint16_t len, const char *str)
Definition: util-byte.c:239
SCDropMainThreadCaps
#define SCDropMainThreadCaps(...)
Definition: util-privs.h:38
runmodes.h
SCLogInfo
#define SCLogInfo(...)
Macro used to log INFORMATIONAL messages.
Definition: util-debug.h:217
SC_CAP_SYS_RAW_IO
#define SC_CAP_SYS_RAW_IO
Definition: util-privs.h:29
RUNMODE_PFRING
@ RUNMODE_PFRING
Definition: runmodes.h:31
group
uint8_t group
Definition: app-layer-dnp3.h:0
suricata-common.h
run_mode
int run_mode
Definition: suricata.c:201
SCLogError
#define SCLogError(err_code,...)
Macro used to log ERROR messages.
Definition: util-debug.h:257
FatalError
#define FatalError(x,...)
Definition: util-debug.h:532
tv
ThreadVars * tv
Definition: fuzz_decodepcapfile.c:29
threadvars.h
RUNMODE_NFQ
@ RUNMODE_NFQ
Definition: runmodes.h:32
SC_ERR_FATAL
@ SC_ERR_FATAL
Definition: util-error.h:203
suricata.h
sc_set_caps
int sc_set_caps
Definition: suricata.c:218
RUNMODE_AFP_DEV
@ RUNMODE_AFP_DEV
Definition: runmodes.h:37
SC_CAP_NET_RAW
#define SC_CAP_NET_RAW
Definition: util-privs.h:32