Beispiel #1
0
jint
Java_com_caucho_bootjni_JniProcess_waitpid(JNIEnv *env,
					   jobject obj,
					   jint pid,
					   jboolean is_block)
{
  int status = 0;
  int result;

#ifdef WIN32
  return -1;
#else
  if (pid < 0) {
    resin_printf_exception(env, "java/lang/IllegalArgumentException",
			   "invalid pid");
    return -1;
  }

  result = waitpid(pid, &status, is_block ? 0 : WNOHANG);

  if (result == 0)
    return -1;
  
  if (result < 0) {
    resin_printf_exception(env, "java/lang/IllegalArgumentException",
			   "invalid result %d", result);
    return -1;
  }

  return WEXITSTATUS(status);
#endif
}
static struct sockaddr_in *
lookup_addr(JNIEnv *env, char *addr_name, int port,
	    char *buffer, int *p_family, int *p_protocol,
	    int *p_sin_length)
{
  struct addrinfo hints;
  struct addrinfo *addr;
  struct sockaddr_in *sin;
  int sin_length;
  char port_name[16];
  
  memset(&hints, 0, sizeof(hints));

  hints.ai_socktype = SOCK_STREAM;
  hints.ai_family = PF_UNSPEC;
  hints.ai_flags = AI_NUMERICHOST;

  sprintf(port_name, "%d", port);

  if (getaddrinfo(addr_name, port_name, &hints, &addr)) {
    resin_printf_exception(env, "java/net/SocketException", "can't find address %s", addr_name);
    return 0;
  }

  *p_family = addr->ai_family;
  *p_protocol = addr->ai_protocol;
  sin_length = addr->ai_addrlen;
  memcpy(buffer, addr->ai_addr, sin_length);
  sin = (struct sockaddr_in *) buffer;
  freeaddrinfo(addr);

  *p_sin_length = sin_length;

  return sin;
}
Beispiel #3
0
static int
write_exception_status(connection_t *conn, int error)
{
  if (error == EAGAIN || error == EWOULDBLOCK || error == EINTR) {
    if (conn->jni_env) {
      resin_printf_exception(conn->jni_env, "com/caucho/vfs/ClientDisconnectException",
			     "timeout fd=%d errno=%d\n", conn->fd, error);
    }
    
    return TIMEOUT_EXN;
  }
  else if (error == EPIPE || error == ECONNRESET) {
    if (conn->jni_env) {
      resin_printf_exception(conn->jni_env, "com/caucho/vfs/ClientDisconnectException",
			     "Client disconnect fd=%d errno=%d\n",
			     conn->fd, error);
    }
    
    return DISCONNECT_EXN;
  }
  else {
    return -1;
  }
}
Beispiel #4
0
jboolean
Java_com_caucho_bootjni_JniProcess_exec(JNIEnv *env,
				     jobject obj,
				     jobjectArray j_argv,
				     jobjectArray j_envp,
				     jstring j_chroot,
				     jstring j_pwd,
				     jstring j_user,
				     jstring j_group)
{
  char **argv;
  char **envp;
  char chroot_path[4096];
  char pwd[4096];
  char user[256];
  char group[256];
  int uid = -1;
  int gid = -1;
  int len;
  int i;
  int pipe_fds[2];
  int pid;
  jclass c_jni_process;
  jfieldID f_stdoutFd;
  jfieldID f_pid;

#ifdef WIN32
  if (1) return -1;
#endif /* WIN32 */
  
  user[0] = 0;
  group[0] = 0;
  chroot_path[0] = 0;
  
  if (! j_argv) {
    resin_printf_exception(env, "java/lang/NullPointerException", "argv");
    return 0;
  }
  
  if (! j_envp) {
    resin_printf_exception(env, "java/lang/NullPointerException", "argv");
    return 0;
  }
  
  if (! j_pwd) {
    resin_printf_exception(env, "java/lang/NullPointerException", "pwd");
    return 0;
  }

  c_jni_process = (*env)->FindClass(env, "com/caucho/bootjni/JniProcess");

  if (! c_jni_process) {
    resin_printf_exception(env, "java/lang/NullPointerException", "can't load JniProcess");
    return 0;
  }

  f_stdoutFd = (*env)->GetFieldID(env, c_jni_process, "_stdoutFd", "I");

  if (! f_stdoutFd) {
    resin_printf_exception(env, "java/lang/NullPointerException", "can't load field");
    return 0;
  }

  f_pid = (*env)->GetFieldID(env, c_jni_process, "_pid", "I");

  if (! f_pid) {
    resin_printf_exception(env, "java/lang/NullPointerException", "can't load field");
    return 0;
  }

  len = (*env)->GetArrayLength(env, j_argv);
  argv = malloc((len + 1) * sizeof(char*));
  argv[len] = 0;
  
  for (i = 0; i < len; i++) {
    jstring j_string;

    j_string = (*env)->GetObjectArrayElement(env, j_argv, i);

    if (j_string) {
      int strlen = (*env)->GetStringUTFLength(env, j_string);
      
      argv[i] = (char *) malloc(strlen + 1);
    
      argv[i] = get_utf8(env, j_string, argv[i], strlen + 1);
    }
  }

  len = (*env)->GetArrayLength(env, j_envp);
  envp = malloc((len + 1) * sizeof(char*));
  envp[len] = 0;
  
  for (i = 0; i < len; i++) {
    jstring j_string;

    j_string = (*env)->GetObjectArrayElement(env, j_envp, i);

    if (j_string) {
      int strlen = (*env)->GetStringUTFLength(env, j_string);
      
      envp[i] = (char *) malloc(strlen + 1);
    
      envp[i] = get_utf8(env, j_string, envp[i], strlen + 1);
    }
  }

  if (j_chroot) {
    int strlen = (*env)->GetStringUTFLength(env, j_chroot);

    get_utf8(env, j_chroot, chroot_path, strlen + 1);
  }
  else
    chroot_path[0] = 0;

  if (j_pwd) {
    int strlen = (*env)->GetStringUTFLength(env, j_pwd);

    get_utf8(env, j_pwd, pwd, strlen + 1);
  }

#ifndef WIN32
  if (j_user) {
    struct passwd *passwd;
    int strlen = (*env)->GetStringUTFLength(env, j_user);

    get_utf8(env, j_user, user, strlen + 1);

    passwd = getpwnam(user);

    if (! passwd) {
      resin_printf_exception(env, "java/lang/IllegalArgumentException",
			     "%s is an unknown user", user);
      return 0;
    }
    
    uid = passwd->pw_uid;
    gid = passwd->pw_gid;
  }
  
  if (j_group) {
    struct group *group_ent;
    int strlen = (*env)->GetStringUTFLength(env, j_group);

    get_utf8(env, j_group, group, strlen + 1);

    group_ent = getgrnam(group);

    if (! group_ent) {
      resin_printf_exception(env, "java/lang/IllegalArgumentException",
			     "%s is an unknown group", group);
      return 0;
    }
    
    gid = group_ent->gr_gid;
  }
  
  pipe(pipe_fds);

  pid = fork();

  if (pid > 0) {
    close(pipe_fds[1]);

    (*env)->SetIntField(env, obj, f_stdoutFd, pipe_fds[0]);
    (*env)->SetIntField(env, obj, f_pid, pid);
    
    return 1;
  }
  else if (pid < 0) {
    close(pipe_fds[0]);
    close(pipe_fds[1]);
    
    resin_printf_exception(env, "java/lang/NullPointerException",
			   "can't fork");
    return 0;
  }

  close(pipe_fds[0]);

  /*
  if (fork())
    exit(0);
  
  setsid();
  */

#ifndef WIN32  
  if (chroot_path[0]) {
    chroot(chroot_path);
  }
#endif

  if (gid >= 0)
    setregid(gid, gid);
  
  if (uid >= 0) {
    setreuid(uid, uid);

    if (getuid() != uid) {
      fprintf(stderr, "Can't setuid to %d, received %d\n", uid, getuid());
      exit(1);
    }
  }
  
  chdir(pwd);
#endif

  dup2(pipe_fds[1], 1);
  dup2(pipe_fds[1], 2);

  for (i = 0; envp[i]; i++)
    putenv(envp[i]);

  execvp(argv[0], argv);

  fprintf(stderr, "exec failed %s -> %d\n", argv[0], errno);
  exit(1);
  
  return -1;
}
Beispiel #5
0
JNIEXPORT jint JNICALL
Java_com_caucho_server_boot_ResinBoot_execDaemon(JNIEnv *env,
        jobject obj,
        jobjectArray j_argv,
        jobjectArray j_envp,
        jstring j_pwd)
{
    char **argv;
    char **envp;
    char *pwd;
    int len;
    int i;

    if (! j_argv)
        resin_printf_exception(env, "java/lang/NullPointerException", "argv");
    if (! j_envp)
        resin_printf_exception(env, "java/lang/NullPointerException", "argv");
    if (! j_pwd)
        resin_printf_exception(env, "java/lang/NullPointerException", "pwd");

#ifdef WIN32
    resin_printf_exception(env, "java/lang/UnsupportedOperationException", "win32");
#else
    len = (*env)->GetArrayLength(env, j_argv);
    argv = malloc((len + 1) * sizeof(char*));
    argv[len] = 0;

    for (i = 0; i < len; i++) {
        jstring j_string;

        j_string = (*env)->GetObjectArrayElement(env, j_argv, i);

        if (j_string) {
            int strlen = (*env)->GetStringUTFLength(env, j_string);

            argv[i] = (char *) malloc(strlen + 1);

            argv[i] = get_utf8(env, j_string, argv[i], strlen + 1);
        }
    }

    len = (*env)->GetArrayLength(env, j_envp);
    envp = malloc((len + 1) * sizeof(char*));
    envp[len] = 0;

    for (i = 0; i < len; i++) {
        jstring j_string;

        j_string = (*env)->GetObjectArrayElement(env, j_envp, i);

        if (j_string) {
            int strlen = (*env)->GetStringUTFLength(env, j_string);

            envp[i] = (char *) malloc(strlen + 1);

            envp[i] = get_utf8(env, j_string, envp[i], strlen + 1);
        }
    }

    {
        int strlen = (*env)->GetStringUTFLength(env, j_pwd);
        char *pwd;

        pwd = (char *) malloc(strlen + 1);
        pwd = get_utf8(env, j_pwd, pwd, strlen + 1);

        chdir(pwd);
    }

    if (fork())
        return 1;

    if (fork())
        exit(0);

#ifndef WIN32
    setsid();
#endif /* WIN32 */

    execve(argv[0], argv, envp);

    fprintf(stderr, "exec failed %s -> %d\n", argv[0], errno);
    exit(1);
#endif
    return -1;
}