You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by jf...@apache.org on 2002/02/26 22:31:49 UTC

cvs commit: jakarta-commons-sandbox/daemon/src/native/unix/native Makefile.in jsvc-unix.c

jfclere     02/02/26 13:31:49

  Modified:    daemon/src/native/unix/native Makefile.in jsvc-unix.c
  Log:
  The setuid/setgid in Linux only applies on the current thread therefore it
  must be done before starting the JVM.
  Note the prctl and syscall to handle the capabilities.
  
  Revision  Changes    Path
  1.3       +2 -1      jakarta-commons-sandbox/daemon/src/native/unix/native/Makefile.in
  
  Index: Makefile.in
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/daemon/src/native/unix/native/Makefile.in,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- Makefile.in	19 Feb 2002 02:44:14 -0000	1.2
  +++ Makefile.in	26 Feb 2002 21:31:48 -0000	1.3
  @@ -56,7 +56,7 @@
   # ========================================================================= #
   
   # @author  Pier Fumagalli <ma...@eng.sun.com>
  -# @version $Id: Makefile.in,v 1.2 2002/02/19 02:44:14 remm Exp $
  +# @version $Id: Makefile.in,v 1.3 2002/02/26 21:31:48 jfclere Exp $
   
   include ../Makedefs
   
  @@ -78,6 +78,7 @@
   	ranlib libservice.a
   
   jsvc: jsvc-unix.o libservice.a
  +	mkdir -p ../../../../dist
   	$(CC) $(LDFLAGS) jsvc-unix.o libservice.a -o ../../../../dist/jsvc
   
   clean:
  
  
  
  1.2       +99 -17    jakarta-commons-sandbox/daemon/src/native/unix/native/jsvc-unix.c
  
  Index: jsvc-unix.c
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/daemon/src/native/unix/native/jsvc-unix.c,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- jsvc-unix.c	18 Feb 2002 21:15:42 -0000	1.1
  +++ jsvc-unix.c	26 Feb 2002 21:31:48 -0000	1.2
  @@ -55,7 +55,7 @@
    *                                                                           *
    * ========================================================================= */
   
  -/* @version $Id: jsvc-unix.c,v 1.1 2002/02/18 21:15:42 remm Exp $ */
  +/* @version $Id: jsvc-unix.c,v 1.2 2002/02/26 21:31:48 jfclere Exp $ */
   #include "jsvc.h"
   
   #include <signal.h>
  @@ -63,6 +63,12 @@
   #include <sys/types.h>
   #include <sys/wait.h>
   #include <pwd.h>
  +#ifdef OS_LINUX
  +#include <sys/prctl.h>
  +#include <sys/syscall.h>
  +#define _LINUX_FS_H 
  +#include <linux/capability.h>
  +#endif
   
   extern char **environ;
   
  @@ -116,6 +122,84 @@
       }
   }
   
  +/* user and group */
  +static int set_user_group(char *user, int uid, int gid)
  +{
  +    if (user!=NULL) {
  +        if (setgid(gid)!=0) {
  +            log_error("Cannot set group id for user '%s'",user);
  +            return(-1);
  +        }
  +        if (setuid(uid)!=0) {
  +            log_error("Cannot set user id for user '%s'",user);
  +            return(-1);
  +        }
  +        log_debug("user changed to '%s'",user);
  +    }
  +    return(0);
  +}
  +/* Set linux capability, user and group */
  +#ifdef OS_LINUX
  +/* CAPSALL is to allow to read/write at any location */
  +#define CAPSALL (1 << CAP_NET_BIND_SERVICE)+ \
  +                (1 << CAP_SETUID)+ \
  +                (1 << CAP_SETGID)+ \
  +                (1 << CAP_DAC_READ_SEARCH)+ \
  +                (1 << CAP_DAC_OVERRIDE)
  +#define CAPSMAX (1 << CAP_NET_BIND_SERVICE)+ \
  +                (1 << CAP_DAC_READ_SEARCH)+ \
  +                (1 << CAP_DAC_OVERRIDE)
  +/* That a more reasonable configuration */
  +#define CAPS    (1 << CAP_NET_BIND_SERVICE)+ \
  +                (1 << CAP_SETUID)+ \
  +                (1 << CAP_SETGID)
  +/* probably the only one Java could use */
  +#define CAPSMIN (1 << CAP_NET_BIND_SERVICE)
  +static int set_caps(int caps)
  +{
  +    struct __user_cap_header_struct caphead;
  +    struct __user_cap_data_struct cap;
  + 
  +    memset(&caphead, 0, sizeof caphead);
  +    caphead.version = _LINUX_CAPABILITY_VERSION;
  +    caphead.pid = 0;
  +    memset(&cap, 0, sizeof cap);
  +    cap.effective = caps;
  +    cap.permitted = caps;
  +    cap.inheritable = caps;
  +    if (syscall(__NR_capset, &caphead, &cap) < 0) {
  +        log_error("syscall failed in set_caps");
  +        return(-1);
  +    }
  +    return(0);
  +}
  +static int linuxset_user_group(char *user, int uid, int gid)
  +{
  +    /* set capabilities enough for binding port 80 setuid/getuid */
  +    if (set_caps(CAPS)!=0)
  +        return(-1);
  +
  +    /* make sure they are kept after setuid */ 
  +    if (prctl(PR_SET_KEEPCAPS,1,0,0,0) < 0) {
  +        log_error("prctl failed in linuxset_user_group");
  +        return(-1);
  +    }
  +
  +    /* set setuid/getuid */
  +    if (set_user_group(user,uid,gid)!=0) {
  +        log_error("set_user_group failed in linuxset_user_group");
  +        return(-1);
  +    }
  +
  +    /* set capability to binding port 80 read conf */
  +    if (set_caps(CAPSMIN)!=0)
  +        return(-1);
  +
  +    return(0);
  +}
  +#endif
  +
  +
   static bool checkuser(char *user, uid_t *uid, gid_t *gid) {
       struct passwd *pwds=NULL;
       int status=0;
  @@ -142,14 +226,8 @@
   
       /* If we're in the child process, let's validate */
       if (pid==0) {
  -        if (setgid(*gid)!=0) {
  -            log_error("Cannot set group id for user '%s'",user);
  +        if (set_user_group(user,*uid,*gid)!=0)
               exit(1);
  -        }
  -        if (setuid(*uid)!=0) {
  -            log_error("Cannot set user id for user '%s'",user);
  -            exit(1);
  -        }
           /* If we got here we switched user/group */
           exit(0);
       }
  @@ -203,6 +281,11 @@
           log_error("Cannot open PID file %s, PID is %d",args->pidf,pidn);
       }
   
  +#ifdef OS_LINUX
  +    /* setuid()/setgid() only apply the current thread so we must do it now */
  +    if (linuxset_user_group(args->user,uid,gid)!=0)
  +            return(4);
  +#endif
       /* Initialize the Java VM */
       if (java_init(args,data)!=true) return(1);
   
  @@ -224,16 +307,15 @@
       if (java_load(args)!=true) return(3);
   
       /* Downgrade user */
  -    if (args->user!=NULL) {
  -        if (setgid(gid)!=0) {
  -            log_error("Cannot set group id for user '%s'",args->user);
  -            return(4);
  -        }
  -        if (setuid(uid)!=0) {
  -            log_error("Cannot set user id for user '%s'",args->user);
  -            return(4);
  -        }
  +#ifdef OS_LINUX
  +    if (set_caps(0)!=0) {
  +        log_debug("set_caps (0) failed");
  +        return(4);
       }
  +#else
  +    if (set_user_group(args->user,uid,gid)!=0)
  +        return(4);
  +#endif
   
       /* Start the service */
       if (java_start()!=true) return(5);
  
  
  

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>