suexec: Honor Run As capability like HTTP REST API
This makes the behavior of the two APIs more consistent. suexec is still allowed for the magical "Gerrit Code Review" PeerDaemonUser, but is now also permitted if the Run As capability has been granted. Change-Id: I9acd6467d9e02084519b30e0c4a3d08065e74484
This commit is contained in:
@@ -19,6 +19,7 @@ import com.google.gerrit.reviewdb.client.Account;
|
||||
import com.google.gerrit.server.CurrentUser;
|
||||
import com.google.gerrit.server.IdentifiedUser;
|
||||
import com.google.gerrit.server.PeerDaemonUser;
|
||||
import com.google.gerrit.server.config.AuthConfig;
|
||||
import com.google.gerrit.sshd.SshScope.Context;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
@@ -45,6 +46,7 @@ public final class SuExec extends BaseCommand {
|
||||
private final SshScope sshScope;
|
||||
private final DispatchCommandProvider dispatcher;
|
||||
|
||||
private boolean enableRunAs;
|
||||
private Provider<CurrentUser> caller;
|
||||
private Provider<SshSession> session;
|
||||
private IdentifiedUser.GenericFactory userFactory;
|
||||
@@ -66,36 +68,34 @@ public final class SuExec extends BaseCommand {
|
||||
@CommandName(Commands.ROOT) final DispatchCommandProvider dispatcher,
|
||||
final Provider<CurrentUser> caller, final Provider<SshSession> session,
|
||||
final IdentifiedUser.GenericFactory userFactory,
|
||||
final SshScope.Context callingContext) {
|
||||
final SshScope.Context callingContext,
|
||||
AuthConfig config) {
|
||||
this.sshScope = sshScope;
|
||||
this.dispatcher = dispatcher;
|
||||
this.caller = caller;
|
||||
this.session = session;
|
||||
this.userFactory = userFactory;
|
||||
this.callingContext = callingContext;
|
||||
this.enableRunAs = config.isRunAsEnabled();
|
||||
atomicCmd = Atomics.newReference();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(Environment env) throws IOException {
|
||||
try {
|
||||
if (caller.get() instanceof PeerDaemonUser) {
|
||||
parseCommandLine();
|
||||
checkCanRunAs();
|
||||
parseCommandLine();
|
||||
|
||||
final Context ctx = callingContext.subContext(newSession(), join(args));
|
||||
final Context old = sshScope.set(ctx);
|
||||
try {
|
||||
final BaseCommand cmd = dispatcher.get();
|
||||
cmd.setArguments(args.toArray(new String[args.size()]));
|
||||
provideStateTo(cmd);
|
||||
atomicCmd.set(cmd);
|
||||
cmd.start(env);
|
||||
} finally {
|
||||
sshScope.set(old);
|
||||
}
|
||||
|
||||
} else {
|
||||
throw new UnloggedFailure(1, "fatal: Not a peer daemon");
|
||||
final Context ctx = callingContext.subContext(newSession(), join(args));
|
||||
final Context old = sshScope.set(ctx);
|
||||
try {
|
||||
final BaseCommand cmd = dispatcher.get();
|
||||
cmd.setArguments(args.toArray(new String[args.size()]));
|
||||
provideStateTo(cmd);
|
||||
atomicCmd.set(cmd);
|
||||
cmd.start(env);
|
||||
} finally {
|
||||
sshScope.set(old);
|
||||
}
|
||||
} catch (UnloggedFailure e) {
|
||||
String msg = e.getMessage();
|
||||
@@ -108,6 +108,17 @@ public final class SuExec extends BaseCommand {
|
||||
}
|
||||
}
|
||||
|
||||
private void checkCanRunAs() throws UnloggedFailure {
|
||||
if (caller.get() instanceof PeerDaemonUser) {
|
||||
// OK.
|
||||
} else if (!enableRunAs) {
|
||||
throw new UnloggedFailure(1,
|
||||
"fatal: suexec disabled by auth.enableRunAs = false");
|
||||
} else if (!caller.get().getCapabilities().canRunAs()) {
|
||||
throw new UnloggedFailure(1, "fatal: suexec not permitted");
|
||||
}
|
||||
}
|
||||
|
||||
private SshSession newSession() {
|
||||
final SocketAddress peer;
|
||||
if (peerAddress == null) {
|
||||
|
||||
Reference in New Issue
Block a user