capabilities support
[platform/upstream/libwebsockets.git] / lib / lws-plat-unix.c
index 3566e62..ae73dfc 100644 (file)
@@ -114,11 +114,14 @@ _lws_plat_service_tsi(struct lws_context *context, int timeout_ms, int tsi)
 
        pt = &context->pt[tsi];
 
+       lws_stats_atomic_bump(context, pt, LWSSTATS_C_SERVICE_ENTRY, 1);
+
        if (timeout_ms < 0)
                goto faked_service;
 
        lws_libev_run(context, tsi);
        lws_libuv_run(context, tsi);
+       lws_libevent_run(context, tsi);
 
        if (!context->service_tid_detected) {
                struct lws _lws;
@@ -276,9 +279,29 @@ lws_plat_set_socket_options(struct lws_vhost *vhost, int fd)
        return 0;
 }
 
+#if defined(LWS_HAVE_SYS_CAPABILITY_H) && defined(LWS_HAVE_LIBCAP)
+static void
+_lws_plat_apply_caps(int mode, cap_value_t *cv, int count)
+{
+       cap_t caps = cap_get_proc();
+
+       if (!count)
+               return;
+
+       cap_set_flag(caps, mode, count, cv, CAP_SET);
+       cap_set_proc(caps);
+       prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0);
+       cap_free(caps);
+}
+#endif
+
 LWS_VISIBLE void
 lws_plat_drop_app_privileges(struct lws_context_creation_info *info)
 {
+#if defined(LWS_HAVE_SYS_CAPABILITY_H) && defined(LWS_HAVE_LIBCAP)
+       int n;
+#endif
+
        if (info->gid != -1)
                if (setgid(info->gid))
                        lwsl_warn("setgid: %s\n", strerror(LWS_ERRNO));
@@ -287,11 +310,25 @@ lws_plat_drop_app_privileges(struct lws_context_creation_info *info)
                struct passwd *p = getpwuid(info->uid);
 
                if (p) {
+
+#if defined(LWS_HAVE_SYS_CAPABILITY_H) && defined(LWS_HAVE_LIBCAP)
+                       _lws_plat_apply_caps(CAP_PERMITTED, info->caps, info->count_caps);
+#endif
+
                        initgroups(p->pw_name, info->gid);
                        if (setuid(info->uid))
                                lwsl_warn("setuid: %s\n", strerror(LWS_ERRNO));
                        else
                                lwsl_notice("Set privs to user '%s'\n", p->pw_name);
+
+#if defined(LWS_HAVE_SYS_CAPABILITY_H) && defined(LWS_HAVE_LIBCAP)
+                       _lws_plat_apply_caps(CAP_EFFECTIVE, info->caps, info->count_caps);
+
+                       if (info->count_caps)
+                               for (n = 0; n < info->count_caps; n++)
+                                       lwsl_notice("   RETAINING CAPABILITY %d\n", (int)info->caps[n]);
+#endif
+
                } else
                        lwsl_warn("getpwuid: unable to find uid %d", info->uid);
        }
@@ -573,6 +610,7 @@ lws_plat_insert_socket_into_fds(struct lws_context *context, struct lws *wsi)
 
        lws_libev_io(wsi, LWS_EV_START | LWS_EV_READ);
        lws_libuv_io(wsi, LWS_EV_START | LWS_EV_READ);
+       lws_libevent_io(wsi, LWS_EV_START | LWS_EV_READ);
 
        pt->fds[pt->fds_count++].revents = 0;
 }
@@ -585,6 +623,7 @@ lws_plat_delete_socket_from_fds(struct lws_context *context,
 
        lws_libev_io(wsi, LWS_EV_STOP | LWS_EV_READ | LWS_EV_WRITE);
        lws_libuv_io(wsi, LWS_EV_STOP | LWS_EV_READ | LWS_EV_WRITE);
+       lws_libevent_io(wsi, LWS_EV_STOP | LWS_EV_READ | LWS_EV_WRITE);
 
        pt->fds_count--;
 }
@@ -611,6 +650,12 @@ lws_plat_inet_ntop(int af, const void *src, char *dst, int cnt)
        return inet_ntop(af, src, dst, cnt);
 }
 
+LWS_VISIBLE int
+lws_plat_inet_pton(int af, const char *src, void *dst)
+{
+       return inet_pton(af, src, dst);
+}
+
 LWS_VISIBLE lws_fop_fd_t
 _lws_plat_file_open(const struct lws_plat_file_ops *fops, const char *filename,
                    const char *vpath, lws_fop_flags_t *flags)
@@ -742,7 +787,8 @@ lws_plat_init(struct lws_context *context,
        }
 
        if (!lws_libev_init_fd_table(context) &&
-           !lws_libuv_init_fd_table(context)) {
+           !lws_libuv_init_fd_table(context) &&
+           !lws_libevent_init_fd_table(context)) {
                /* otherwise libev handled it instead */
 
                while (n--) {