Beispiel #1
0
    VirtualChannel start(TaskListener listener, String rootPassword)
        throws IOException, InterruptedException {
      final int uid = LIBC.geteuid();

      if (uid == 0) // already running as root
      return newLocalChannel();

      String javaExe = System.getProperty("java.home") + "/bin/java";
      File slaveJar = Which.jarFile(Launcher.class);

      ArgumentListBuilder args = new ArgumentListBuilder().add(javaExe);
      if (slaveJar.isFile()) args.add("-jar").add(slaveJar);
      else // in production code this never happens, but during debugging this is convenientud
      args.add("-cp").add(slaveJar).add(hudson.remoting.Launcher.class.getName());

      if (rootPassword == null) {
        // try sudo, in the hope that the user has the permission to do so without password
        return new LocalLauncher(listener)
            .launchChannel(
                args.prepend(sudoExe()).toCommandArray(),
                listener.getLogger(),
                null,
                Collections.<String, String>emptyMap());
      } else {
        // try sudo with the given password. Also run in pfexec so that we can elevate the
        // privileges
        Process proc = sudoWithPass(args);
        return Channels.forProcess(
            args.toStringWithQuote(), Computer.threadPoolForRemoting, proc, listener.getLogger());
      }
    }
Beispiel #2
0
  /**
   * Returns a {@link VirtualChannel} that's connected to the privilege-escalated environment.
   *
   * @param listener What this method is doing (such as what process it's invoking) will be sent
   *     here.
   * @return Never null. This may represent a channel to a separate JVM, or just {@link
   *     LocalChannel}. Close this channel and the SU environment will be shut down.
   */
  public static VirtualChannel start(
      final TaskListener listener, final String rootUsername, final String rootPassword)
      throws IOException, InterruptedException {
    if (File.pathSeparatorChar == ';') // on Windows
    return newLocalChannel(); // TODO: perhaps use RunAs to run as an Administrator?

    String os = Util.fixNull(System.getProperty("os.name"));
    if (os.equals("Linux"))
      return new UnixSu() {
        protected String sudoExe() {
          return "sudo";
        }

        protected Process sudoWithPass(ArgumentListBuilder args) throws IOException {
          args.prepend(sudoExe(), "-S");
          listener.getLogger().println("$ " + Util.join(args.toList(), " "));
          ProcessBuilder pb = new ProcessBuilder(args.toCommandArray());
          Process p = pb.start();
          // TODO: use -p to detect prompt
          // TODO: detect if the password didn't work
          PrintStream ps = new PrintStream(p.getOutputStream());
          ps.println(rootPassword);
          ps.println(rootPassword);
          ps.println(rootPassword);
          return p;
        }
      }.start(listener, rootPassword);

    if (os.equals("SunOS"))
      return new UnixSu() {
        protected String sudoExe() {
          return "/usr/bin/pfexec";
        }

        protected Process sudoWithPass(ArgumentListBuilder args) throws IOException {
          listener.getLogger().println("Running with embedded_su");
          ProcessBuilder pb = new ProcessBuilder(args.prepend(sudoExe()).toCommandArray());
          return EmbeddedSu.startWithSu(rootUsername, rootPassword, pb);
        }
        // in solaris, pfexec never asks for a password, so username==null means
        // we won't be using password. this helps disambiguate empty password
      }.start(listener, rootUsername == null ? null : rootPassword);

    // TODO: Mac?

    // unsupported platform, take a chance
    return newLocalChannel();
  }