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 <grp.h>
30 #include <pwd.h>
31 #include "suricata-common.h"
32 #include "util-debug.h"
33 #include "suricata.h"
34 
35 #include "util-privs.h"
36 
37 #ifdef HAVE_LIBCAP_NG
38 
39 #include <cap-ng.h>
40 #ifdef HAVE_SYS_PRCTL_H
41 #include <sys/prctl.h>
42 #endif
43 #include "threadvars.h"
44 #include "util-cpu.h"
45 #include "runmodes.h"
46 
47 /** flag indicating if we'll be using caps */
48 extern int sc_set_caps;
49 
50 /** our current runmode */
51 extern int run_mode;
52 
53 /**
54  * \brief Drop the previliges of the main thread
55  */
56 void SCDropMainThreadCaps(uint32_t userid, uint32_t groupid)
57 {
58  if (sc_set_caps == FALSE)
59  return;
60 
61  capng_clear(CAPNG_SELECT_BOTH);
62 
63  switch (run_mode) {
64  case RUNMODE_PCAP_DEV:
65  case RUNMODE_AFP_DEV:
66  capng_updatev(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED,
67  CAP_NET_RAW, /* needed for pcap live mode */
68  CAP_SYS_NICE,
69  CAP_NET_ADMIN,
70  -1);
71  break;
72  case RUNMODE_PFRING:
73  capng_updatev(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED,
74  CAP_NET_ADMIN, CAP_NET_RAW, CAP_SYS_NICE,
75  -1);
76  break;
77  case RUNMODE_NFQ:
78  capng_updatev(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED,
79  CAP_NET_ADMIN, /* needed for 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  SCLogError(SC_ERR_CHANGING_CAPS_FAILED, "capng_change_id for main thread"
89  " failed");
90  exit(EXIT_FAILURE);
91  }
92 
93  SCLogInfo("dropped the caps for main thread");
94 }
95 
96 void SCDropCaps(ThreadVars *tv)
97 {
98 #if 0
99  capng_clear(CAPNG_SELECT_BOTH);
100  capng_apply(CAPNG_SELECT_BOTH);
101  if (tv->cap_flags & SC_CAP_IPC_LOCK) {
102  capng_update(CAPNG_ADD, (capng_type_t) (CAPNG_EFFECTIVE | CAPNG_PERMITTED), CAP_IPC_LOCK);
103  capng_apply(CAPNG_SELECT_CAPS);
104  SCLogDebug("For thread \"%s\" CAP_IPC_LOCK has been set", tv->name);
105  }
106  if (tv->cap_flags & SC_CAP_NET_ADMIN) {
107  capng_update(CAPNG_ADD, (capng_type_t) (CAPNG_EFFECTIVE | CAPNG_PERMITTED), CAP_NET_ADMIN);
108  capng_apply(CAPNG_SELECT_CAPS);
109  SCLogDebug("For thread \"%s\" CAP_NET_ADMIN has been set", tv->name);
110  }
112  capng_update(CAPNG_ADD, (capng_type_t) (CAPNG_EFFECTIVE | CAPNG_PERMITTED), CAP_NET_BIND_SERVICE);
113  capng_apply(CAPNG_SELECT_CAPS);
114  SCLogDebug("For thread \"%s\" CAP_NET_BIND_SERVICE has been set", tv->name);
115  }
116  if (tv->cap_flags & SC_CAP_NET_BROADCAST) {
117  capng_update(CAPNG_ADD, (capng_type_t) (CAPNG_EFFECTIVE | CAPNG_PERMITTED), CAP_NET_BROADCAST);
118  capng_apply(CAPNG_SELECT_CAPS);
119  SCLogDebug("For thread \"%s\" CAP_NET_BROADCAST has been set", tv->name);
120  }
121  if (tv->cap_flags & SC_CAP_NET_RAW) {
122  capng_update(CAPNG_ADD, (capng_type_t) (CAPNG_EFFECTIVE | CAPNG_PERMITTED), CAP_NET_RAW);
123  capng_apply(CAPNG_SELECT_CAPS);
124  SCLogDebug("For thread \"%s\" CAP_NET_RAW has been set", tv->name);
125  }
126  if (tv->cap_flags & SC_CAP_SYS_ADMIN) {
127  capng_update(CAPNG_ADD, (capng_type_t) (CAPNG_EFFECTIVE | CAPNG_PERMITTED), CAP_SYS_ADMIN);
128  capng_apply(CAPNG_SELECT_CAPS);
129  SCLogDebug("For thread \"%s\" CAP_SYS_ADMIN has been set", tv->name);
130  }
131  if (tv->cap_flags & SC_CAP_SYS_RAW_IO) {
132  capng_update(CAPNG_ADD, (capng_type_t) (CAPNG_EFFECTIVE | CAPNG_PERMITTED), CAP_SYS_RAWIO);
133  capng_apply(CAPNG_SELECT_CAPS);
134  SCLogDebug("For thread \"%s\" CAP_SYS_RAWIO has been set", tv->name);
135  }
136 #endif
137 }
138 
139 #endif /* HAVE_LIBCAP_NG */
140 
141 /**
142  * \brief Function to get the user and group ID from the specified user name
143  *
144  * \param user_name pointer to the given user name
145  * \param uid pointer to the user id in which result will be stored
146  * \param gid pointer to the group id in which result will be stored
147  *
148  * \retval upon success it return 0
149  */
150 int SCGetUserID(const char *user_name, const char *group_name, uint32_t *uid, uint32_t *gid)
151 {
152  uint32_t userid = 0;
153  uint32_t groupid = 0;
154  struct passwd *pw;
155 
156  /* Get the user ID */
157  if (isdigit((unsigned char)user_name[0]) != 0) {
158  userid = atoi(user_name);
159  pw = getpwuid(userid);
160  if (pw == NULL) {
161  SCLogError(SC_ERR_UID_FAILED, "unable to get the user ID, "
162  "check if user exist!!");
163  exit(EXIT_FAILURE);
164  }
165  } else {
166  pw = getpwnam(user_name);
167  if (pw == NULL) {
168  SCLogError(SC_ERR_UID_FAILED, "unable to get the user ID, "
169  "check if user exist!!");
170  exit(EXIT_FAILURE);
171  }
172  userid = pw->pw_uid;
173  }
174 
175  /* Get the group ID */
176  if (group_name != NULL) {
177  struct group *gp;
178 
179  if (isdigit((unsigned char)group_name[0]) != 0) {
180  groupid = atoi(group_name);
181  } else {
182  gp = getgrnam(group_name);
183  if (gp == NULL) {
184  SCLogError(SC_ERR_GID_FAILED, "unable to get the group"
185  " ID, check if group exist!!");
186  exit(EXIT_FAILURE);
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  grpid = atoi(group_name);
221  } else {
222  gp = getgrnam(group_name);
223  if (gp == NULL) {
224  SCLogError(SC_ERR_GID_FAILED, "unable to get the group ID,"
225  " check if group exist!!");
226  exit(EXIT_FAILURE);
227  }
228  grpid = gp->gr_gid;
229  }
230 
231  /* close the group database */
232  endgrent();
233 
234  *gid = grpid;
235 
236  return 0;
237 }
238 #endif /* OS_WIN32 */
#define SCDropCaps(...)
Definition: util-privs.h:37
#define SCLogDebug(...)
Definition: util-debug.h:335
#define SC_CAP_NET_BROADCAST
Definition: util-privs.h:34
#define FALSE
#define SC_CAP_NET_ADMIN
Definition: util-privs.h:31
#define SC_CAP_NET_BIND_SERVICE
Definition: util-privs.h:33
#define SC_CAP_SYS_RAW_IO
Definition: util-privs.h:29
#define SCLogError(err_code,...)
Macro used to log ERROR messages.
Definition: util-debug.h:294
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:150
uint8_t group
#define SCDropMainThreadCaps(...)
Definition: util-privs.h:38
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
#define SC_CAP_NET_RAW
Definition: util-privs.h:32
#define SCLogInfo(...)
Macro used to log INFORMATIONAL messages.
Definition: util-debug.h:254
#define SC_CAP_IPC_LOCK
Definition: util-privs.h:30
#define SC_CAP_SYS_ADMIN
Definition: util-privs.h:28
char name[16]
Definition: threadvars.h:59
int sc_set_caps
Definition: suricata.c:221
int run_mode
Definition: suricata.c:204
Per thread variable structure.
Definition: threadvars.h:57
uint8_t cap_flags
Definition: threadvars.h:109