On Wed, Oct 29, 2003 at 06:24:35PM -0800, Guy Harris wrote:

> >On the todo list I've to change drop_priv to use the libcap packaged
> >instead of capget/capset..
> 
> ...and update the configure scripts so that it'll automatically figure 
> out whether to use the capability bits - "config.h" and "Makefile" are 
> files generated by the configure script.

Ok... Now I've a patch also for configure.in and Makefile.am.
The capability support is by default off.
If enabled, via configure command line  --enable-linux-capab, the
sys/capability.h must exist.

The capab.c now use the library libcap, so it not tied to a specific
kernel. If needed I can put back the code to use the non portable
capset/capget, and add a configure switch or something similar....

....comments are welcome! :)

-- 
Ciao,
 Emanuele
Index: configure.in
===================================================================
RCS file: /usr/src/build/cvsroot/ethereal/configure.in,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.1.2.3
diff -u -u -r1.1.1.1 -r1.1.1.1.2.3
--- configure.in        8 Sep 2003 03:13:14 -0000       1.1.1.1
+++ configure.in        1 Nov 2003 15:07:46 -0000       1.1.1.1.2.3
@@ -525,6 +525,26 @@
 
 AM_CONDITIONAL(SETUID_INSTALL, test x$enable_setuid_install = xyes)
 
+dnl Linux Capabilities
+AC_ARG_ENABLE(linux-capab,
+[  --enable-linux-capab [default=no (Needs 
libcap!)]],enable_linux_capab=$enableval,enable_linux_capab=no)
+
+AC_MSG_CHECKING(whether to use linux capability )
+if test "x$enable_linux_capab" = "xno" ; then
+       AC_MSG_RESULT(no)
+else
+       AC_MSG_RESULT(yes)
+       AC_CHECK_HEADERS(sys/capability.h)
+       if test "x$ac_cv_header_sys_capability_h" = "xyes" ; then
+               AC_DEFINE(ENABLE_LINUX_CAPABILITIES, 1, [Define to use Linux 
Capabilities ] )
+               LIBS="$LIBS -lcap"
+       else
+               enable_linux_capab=no
+       fi
+fi
+AM_CONDITIONAL(ENABLE_LINUX_CAPABILITIES, test x$enable_linux_capab = xyes)
+
+
 dnl Checks for header files.
 AC_HEADER_STDC
 AC_CHECK_HEADERS(fcntl.h sys/ioctl.h sys/time.h unistd.h stdarg.h netdb.h)
@@ -853,6 +873,7 @@
 echo "                      Build dftest : $enable_dftest"
 echo ""
 echo "                    Install setuid : $setuid_message"
+echo "                 Linux capabilities: $enable_linux_capab"
 echo "                       Use plugins : $have_plugins"
 echo "               Use GTK+ v2 library : $enable_gtk2"
 if test "x$enable_gtk2" = "xyes" ; then
Index: Makefile.am
===================================================================
RCS file: /usr/src/build/cvsroot/ethereal/Makefile.am,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.1.2.1
diff -u -u -r1.1.1.1 -r1.1.1.1.2.1
--- Makefile.am 6 Sep 2003 23:22:34 -0000       1.1.1.1
+++ Makefile.am 1 Nov 2003 08:26:50 -0000       1.1.1.1.2.1
@@ -806,6 +806,10 @@
        summary.h      \
        ui_util.h
 
+if ENABLE_LINUX_CAPABILITIES
+ethereal_SOURCES+= capab.c
+endif
+
 EXTRA_ethereal_SOURCES = \
        snprintf.c      \
        snprintf.h      \
@@ -888,6 +892,10 @@
        tethereal-tap-register.c \
        register.c     \
        tethereal.c
+
+if ENABLE_LINUX_CAPABILITIES
+tethereal_SOURCES+= capab.c
+endif
 
 # Additional libs that I know how to build. These will be
 # linked into the tethereal executable.
Index: tethereal.c
===================================================================
RCS file: /usr/src/build/cvsroot/ethereal/tethereal.c,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.1.2.1
diff -u -u -r1.1.1.1 -r1.1.1.1.2.1
--- tethereal.c 8 Sep 2003 03:11:33 -0000       1.1.1.1
+++ tethereal.c 1 Nov 2003 08:26:51 -0000       1.1.1.1.2.1
@@ -68,6 +68,10 @@
 #include "getopt.h"
 #endif
 
+#ifdef ENABLE_LINUX_CAPABILITIES
+void drop_priv();
+#endif
+
 #include <glib.h>
 #include <epan/epan.h>
 #include <epan/filesystem.h>
@@ -798,6 +802,9 @@
   char                 badopt;
   ethereal_tap_list *tli;
 
+#ifdef ENABLE_LINUX_CAPABILITIES
+  drop_priv();
+#endif
   /* Register all dissectors; we must do this before checking for the
      "-G" flag, as the "-G" flag dumps information registered by the
      dissectors, and we must do it before we read the preferences, in
Index: gtk/main.c
===================================================================
RCS file: /usr/src/build/cvsroot/ethereal/gtk/main.c,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.1.2.1
diff -u -u -r1.1.1.1 -r1.1.1.1.2.1
--- gtk/main.c  5 Sep 2003 02:10:25 -0000       1.1.1.1
+++ gtk/main.c  1 Nov 2003 08:26:55 -0000       1.1.1.1.2.1
@@ -68,6 +68,10 @@
 #include "getopt.h"
 #endif
 
+#ifdef ENABLE_LINUX_CAPABILITIES
+void drop_priv();
+#endif
+
 #ifdef WIN32 /* Needed for console I/O */
 #include <fcntl.h>
 #include <conio.h>
@@ -1546,6 +1550,9 @@
   char optstring[sizeof(OPTSTRING_INIT) + sizeof(OPTSTRING_CHILD) - 1] =
     OPTSTRING_INIT;
 
+#ifdef ENABLE_LINUX_CAPABILITIES
+  drop_priv();
+#endif
   ethereal_path = argv[0];
 
 #ifdef WIN32
/* capab.c
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * 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
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 */

#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>

#include <unistd.h>

#include <sys/capability.h>
#include <sys/prctl.h>

/* #define DEBUG_CAPABILITIES */

#ifdef DEBUG_CAPABILITIES
struct _cap_struct {
            struct __user_cap_header_struct head;
                    struct __user_cap_data_struct set;
};

void
debug_print_priv(char *text)
{
        cap_t cap;
        struct _cap_struct *c;
        char *s;
        int p;

        int uid,euid,suid;
        int gid,egid,sgid;
        getresuid( &uid, &euid, &suid );
        getresgid( &gid, &egid, &sgid );

        printf("===\n%s\n",text);
        if( (cap = cap_get_proc()) == NULL ) {
                perror("cap_get_proc():");
                exit(1);
        }
        c = cap;
        s=cap_to_text(cap, NULL );
        if( ( p=prctl( PR_GET_KEEPCAPS, 0,0,0,0 ) ) < 0 ) 
                perror( "prctl:" );
        else 
                printf("KEEPCAPS: %d\n",p );
        printf("uid: %d, euid: %d, suid: %d\ngid: %d. egid: %d, sgid: %d\n", 
uid,euid,suid, gid,egid,sgid );
        printf("Caps: %s\n", s );

        printf("  effective = 0x%08x, permitted = 0x%08x, inheritable = 0x%08x\n",
                        c->set.effective, c->set.permitted, c->set.inheritable);

        cap_free(s);
        printf("===\n\n");
}

#else
#define debug_print_priv( x ) 
#endif /* DEBUG_CAPABILITIES */

void
drop_priv()
{

        uid_t euid, uid;
        cap_t cap;

        euid = geteuid();
        uid = getuid();

        debug_print_priv("Before:");

        if (euid != 0) 
                return;

        if( prctl( PR_SET_KEEPCAPS, 1,0,0,0 ) < 0 ) 
                perror( "prctl:" );

        cap=cap_from_text( "cap_net_admin,cap_net_raw=pi" );
        if( cap_set_proc( cap ) < 0 ){
                perror("cap_set_proc(): ");
        }


        debug_print_priv("After cap_set_proc:");

        if (euid != uid) {
                if (setresuid(uid,uid,uid) < 0) {
                        perror("setresuid()");
                        exit(1);
                }
        }

        debug_print_priv("After setresuid:");

        cap=cap_from_text( "cap_net_admin,cap_net_raw=epi" );
        if( cap_set_proc( cap ) < 0 ){
                perror("cap_set_proc(): ");
        }

        debug_print_priv("After cap_set:");

}

Reply via email to