summaryrefslogtreecommitdiffstats
path: root/framework/src/suricata/src/util-privs.c
diff options
context:
space:
mode:
authorAshlee Young <ashlee@onosfw.com>2015-09-09 22:21:41 -0700
committerAshlee Young <ashlee@onosfw.com>2015-09-09 22:21:41 -0700
commit8879b125d26e8db1a5633de5a9c692eb2d1c4f83 (patch)
treec7259d85a991b83dfa85ab2e339360669fc1f58e /framework/src/suricata/src/util-privs.c
parent13d05bc8458758ee39cb829098241e89616717ee (diff)
suricata checkin based on commit id a4bce14770beee46a537eda3c3f6e8e8565d5d0a
Change-Id: I9a214fa0ee95e58fc640e50bd604dac7f42db48f
Diffstat (limited to 'framework/src/suricata/src/util-privs.c')
-rw-r--r--framework/src/suricata/src/util-privs.c246
1 files changed, 246 insertions, 0 deletions
diff --git a/framework/src/suricata/src/util-privs.c b/framework/src/suricata/src/util-privs.c
new file mode 100644
index 00000000..635247c3
--- /dev/null
+++ b/framework/src/suricata/src/util-privs.c
@@ -0,0 +1,246 @@
+/* Copyright (C) 2007-2010 Open Information Security Foundation
+ *
+ * You can copy, redistribute or modify this Program under the terms of
+ * the GNU General Public License version 2 as published by the Free
+ * Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/**
+ * \file
+ *
+ * \author Gurvinder Singh <gurvindersinghdahiya@gmail.com>
+ *
+ * File to drop the engine capabilities using libcap-ng by
+ * Steve Grubb
+ */
+
+#ifndef OS_WIN32
+
+#include <grp.h>
+#include <pwd.h>
+#include "util-debug.h"
+#include "suricata-common.h"
+#include "suricata.h"
+
+#ifdef HAVE_LIBCAP_NG
+
+#include <cap-ng.h>
+#ifdef HAVE_SYS_PRCTL_H
+#include <sys/prctl.h>
+#endif
+#include "threadvars.h"
+#include "util-cpu.h"
+#include "util-privs.h"
+#include "runmodes.h"
+
+/** flag indicating if we'll be using caps */
+extern int sc_set_caps;
+
+/** our current runmode */
+extern int run_mode;
+
+/**
+ * \brief Drop all the previliges of the given thread
+ */
+void SCDropAllCaps()
+{
+ capng_clear(CAPNG_SELECT_BOTH);
+ if (capng_apply(CAPNG_SELECT_BOTH) < 0) {
+ SCLogError(SC_ERR_CHANGING_CAPS_FAILED, "failed in dropping the caps");
+ exit(EXIT_FAILURE);
+ }
+}
+
+/**
+ * \brief Drop the previliges of the main thread
+ */
+void SCDropMainThreadCaps(uint32_t userid, uint32_t groupid)
+{
+ if (sc_set_caps == FALSE)
+ return;
+
+ capng_clear(CAPNG_SELECT_BOTH);
+
+ switch (run_mode) {
+ case RUNMODE_PCAP_DEV:
+ case RUNMODE_AFP_DEV:
+ capng_updatev(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED,
+ CAP_NET_RAW, /* needed for pcap live mode */
+ -1);
+ break;
+ case RUNMODE_PFRING:
+ capng_updatev(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED,
+ CAP_NET_ADMIN, CAP_NET_RAW,
+ -1);
+ break;
+ case RUNMODE_NFQ:
+ capng_updatev(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED,
+ CAP_NET_ADMIN, /* needed for nfqueue inline mode */
+ -1);
+ break;
+ }
+
+ if (capng_change_id(userid, groupid, CAPNG_DROP_SUPP_GRP |
+ CAPNG_CLEAR_BOUNDING) < 0)
+ {
+ SCLogError(SC_ERR_CHANGING_CAPS_FAILED, "capng_change_id for main thread"
+ " failed");
+ exit(EXIT_FAILURE);
+ }
+
+ SCLogInfo("dropped the caps for main thread");
+}
+
+void SCDropCaps(ThreadVars *tv)
+{
+#if 0
+ capng_clear(CAPNG_SELECT_BOTH);
+ capng_apply(CAPNG_SELECT_BOTH);
+ if (tv->cap_flags & SC_CAP_IPC_LOCK) {
+ capng_update(CAPNG_ADD, (capng_type_t) (CAPNG_EFFECTIVE | CAPNG_PERMITTED), CAP_IPC_LOCK);
+ capng_apply(CAPNG_SELECT_CAPS);
+ SCLogDebug("For thread \"%s\" CAP_IPC_LOCK has been set", tv->name);
+ }
+ if (tv->cap_flags & SC_CAP_NET_ADMIN) {
+ capng_update(CAPNG_ADD, (capng_type_t) (CAPNG_EFFECTIVE | CAPNG_PERMITTED), CAP_NET_ADMIN);
+ capng_apply(CAPNG_SELECT_CAPS);
+ SCLogDebug("For thread \"%s\" CAP_NET_ADMIN has been set", tv->name);
+ }
+ if (tv->cap_flags & SC_CAP_NET_BIND_SERVICE) {
+ capng_update(CAPNG_ADD, (capng_type_t) (CAPNG_EFFECTIVE | CAPNG_PERMITTED), CAP_NET_BIND_SERVICE);
+ capng_apply(CAPNG_SELECT_CAPS);
+ SCLogDebug("For thread \"%s\" CAP_NET_BIND_SERVICE has been set", tv->name);
+ }
+ if (tv->cap_flags & SC_CAP_NET_BROADCAST) {
+ capng_update(CAPNG_ADD, (capng_type_t) (CAPNG_EFFECTIVE | CAPNG_PERMITTED), CAP_NET_BROADCAST);
+ capng_apply(CAPNG_SELECT_CAPS);
+ SCLogDebug("For thread \"%s\" CAP_NET_BROADCAST has been set", tv->name);
+ }
+ if (tv->cap_flags & SC_CAP_NET_RAW) {
+ capng_update(CAPNG_ADD, (capng_type_t) (CAPNG_EFFECTIVE | CAPNG_PERMITTED), CAP_NET_RAW);
+ capng_apply(CAPNG_SELECT_CAPS);
+ SCLogDebug("For thread \"%s\" CAP_NET_RAW has been set", tv->name);
+ }
+ if (tv->cap_flags & SC_CAP_SYS_ADMIN) {
+ capng_update(CAPNG_ADD, (capng_type_t) (CAPNG_EFFECTIVE | CAPNG_PERMITTED), CAP_SYS_ADMIN);
+ capng_apply(CAPNG_SELECT_CAPS);
+ SCLogDebug("For thread \"%s\" CAP_SYS_ADMIN has been set", tv->name);
+ }
+ if (tv->cap_flags & SC_CAP_SYS_RAW_IO) {
+ capng_update(CAPNG_ADD, (capng_type_t) (CAPNG_EFFECTIVE | CAPNG_PERMITTED), CAP_SYS_RAWIO);
+ capng_apply(CAPNG_SELECT_CAPS);
+ SCLogDebug("For thread \"%s\" CAP_SYS_RAWIO has been set", tv->name);
+ }
+#endif
+}
+
+#endif /* HAVE_LIBCAP_NG */
+
+/**
+ * \brief Function to get the user and group ID from the specified user name
+ *
+ * \param user_name pointer to the given user name
+ * \param uid pointer to the user id in which result will be stored
+ * \param gid pointer to the group id in which result will be stored
+ *
+ * \retval upon success it return 0
+ */
+int SCGetUserID(char *user_name, char *group_name, uint32_t *uid, uint32_t *gid)
+{
+ uint32_t userid = 0;
+ uint32_t groupid = 0;
+ struct passwd *pw;
+
+ /* Get the user ID */
+ if (isdigit((unsigned char)user_name[0]) != 0) {
+ userid = atoi(user_name);
+ pw = getpwuid(userid);
+ if (pw == NULL) {
+ SCLogError(SC_ERR_UID_FAILED, "unable to get the user ID, "
+ "check if user exist!!");
+ exit(EXIT_FAILURE);
+ }
+ } else {
+ pw = getpwnam(user_name);
+ if (pw == NULL) {
+ SCLogError(SC_ERR_UID_FAILED, "unable to get the user ID, "
+ "check if user exist!!");
+ exit(EXIT_FAILURE);
+ }
+ userid = pw->pw_uid;
+ }
+
+ /* Get the group ID */
+ if (group_name != NULL) {
+ struct group *gp;
+
+ if (isdigit((unsigned char)group_name[0]) != 0) {
+ groupid = atoi(group_name);
+ } else {
+ gp = getgrnam(group_name);
+ if (gp == NULL) {
+ SCLogError(SC_ERR_GID_FAILED, "unable to get the group"
+ " ID, check if group exist!!");
+ exit(EXIT_FAILURE);
+ }
+ groupid = gp->gr_gid;
+ }
+ } else {
+ groupid = pw->pw_gid;
+ }
+
+ /* close the group database */
+ endgrent();
+ /* close the user database */
+ endpwent();
+
+ *uid = userid;
+ *gid = groupid;
+
+ return 0;
+}
+
+/**
+ * \brief Function to get the group ID from the specified group name
+ *
+ * \param group_name pointer to the given group name
+ * \param gid pointer to the group id in which result will be stored
+ *
+ * \retval upon success it return 0
+ */
+int SCGetGroupID(char *group_name, uint32_t *gid)
+{
+ uint32_t grpid = 0;
+ struct group *gp;
+
+ /* Get the group ID */
+ if (isdigit((unsigned char)group_name[0]) != 0) {
+ grpid = atoi(group_name);
+ } else {
+ gp = getgrnam(group_name);
+ if (gp == NULL) {
+ SCLogError(SC_ERR_GID_FAILED, "unable to get the group ID,"
+ " check if group exist!!");
+ exit(EXIT_FAILURE);
+ }
+ grpid = gp->gr_gid;
+ }
+
+ /* close the group database */
+ endgrent();
+
+ *gid = grpid;
+
+ return 0;
+}
+#endif /* OS_WIN32 */