Propagate access path for SSH commands
Pass the right access path for the commands executed in Git because of an incoming SSH connection: - GIT for all Git/SSH commands - SSH_COMMAND for everything else Allow to honour force push ACL (and potentially other operations) because of the correct propagation of the original identity with the right access path. Previously the code was setting the access path on SshScope.Context which is stored in the ThreadLocal context of the receiving SSH command, which is different from the other thread that execute the action. Bug: Issue 9823 Change-Id: I2b9e1369e53a000457d4571ecf5e6d7ddf843827
This commit is contained in:
@@ -68,7 +68,8 @@ public abstract class AbstractGitCommand extends BaseCommand {
|
||||
Project project = projectControl.getProjectState().getProject();
|
||||
return project.getNameKey();
|
||||
}
|
||||
});
|
||||
},
|
||||
AccessPath.GIT);
|
||||
} finally {
|
||||
sshScope.set(old);
|
||||
}
|
||||
@@ -80,7 +81,6 @@ public abstract class AbstractGitCommand extends BaseCommand {
|
||||
session,
|
||||
session.getRemoteAddress(),
|
||||
userFactory.create(session.getRemoteAddress(), user.getAccountId()));
|
||||
n.setAccessPath(AccessPath.GIT);
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ import com.google.gerrit.common.Nullable;
|
||||
import com.google.gerrit.common.TimeUtil;
|
||||
import com.google.gerrit.extensions.annotations.PluginName;
|
||||
import com.google.gerrit.reviewdb.client.Project;
|
||||
import com.google.gerrit.server.AccessPath;
|
||||
import com.google.gerrit.server.CurrentUser;
|
||||
import com.google.gerrit.server.IdentifiedUser;
|
||||
import com.google.gerrit.server.RequestCleanup;
|
||||
@@ -256,15 +257,17 @@ public abstract class BaseCommand implements Command {
|
||||
* </pre>
|
||||
*
|
||||
* @param thunk the runnable to execute on the thread, performing the command's logic.
|
||||
* @param accessPath the path used by the end user for running the SSH command
|
||||
*/
|
||||
protected void startThread(final Runnable thunk) {
|
||||
protected void startThread(final Runnable thunk, AccessPath accessPath) {
|
||||
startThread(
|
||||
new CommandRunnable() {
|
||||
@Override
|
||||
public void run() throws Exception {
|
||||
thunk.run();
|
||||
}
|
||||
});
|
||||
},
|
||||
accessPath);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -284,9 +287,10 @@ public abstract class BaseCommand implements Command {
|
||||
* non-zero exit code, and the stack trace is logged.
|
||||
*
|
||||
* @param thunk the runnable to execute on the thread, performing the command's logic.
|
||||
* @param accessPath the path used by the end user for running the SSH command
|
||||
*/
|
||||
protected void startThread(final CommandRunnable thunk) {
|
||||
final TaskThunk tt = new TaskThunk(thunk);
|
||||
protected void startThread(final CommandRunnable thunk, AccessPath accessPath) {
|
||||
final TaskThunk tt = new TaskThunk(thunk, accessPath);
|
||||
|
||||
if (isAdminHighPriorityCommand() && user.getCapabilities().canAdministrateServer()) {
|
||||
// Admin commands should not block the main work threads (there
|
||||
@@ -414,11 +418,13 @@ public abstract class BaseCommand implements Command {
|
||||
private final class TaskThunk implements CancelableRunnable, ProjectRunnable {
|
||||
private final CommandRunnable thunk;
|
||||
private final String taskName;
|
||||
private final AccessPath accessPath;
|
||||
private Project.NameKey projectName;
|
||||
|
||||
private TaskThunk(final CommandRunnable thunk) {
|
||||
private TaskThunk(final CommandRunnable thunk, AccessPath accessPath) {
|
||||
this.thunk = thunk;
|
||||
this.taskName = getTaskName();
|
||||
this.accessPath = accessPath;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -439,6 +445,7 @@ public abstract class BaseCommand implements Command {
|
||||
final Thread thisThread = Thread.currentThread();
|
||||
final String thisName = thisThread.getName();
|
||||
int rc = 0;
|
||||
context.getSession().setAccessPath(accessPath);
|
||||
final Context old = sshScope.set(context);
|
||||
try {
|
||||
context.started = TimeUtil.nowMs();
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
package com.google.gerrit.sshd;
|
||||
|
||||
import com.google.gerrit.server.AccessPath;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import org.apache.sshd.server.Environment;
|
||||
@@ -38,7 +39,8 @@ public abstract class SshCommand extends BaseCommand {
|
||||
stderr.flush();
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
AccessPath.SSH_COMMAND);
|
||||
}
|
||||
|
||||
protected abstract void run() throws UnloggedFailure, Failure, Exception;
|
||||
|
||||
@@ -24,6 +24,7 @@ package com.google.gerrit.sshd.commands;
|
||||
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
|
||||
import com.google.gerrit.server.AccessPath;
|
||||
import com.google.gerrit.server.tools.ToolsCatalog;
|
||||
import com.google.gerrit.server.tools.ToolsCatalog.Entry;
|
||||
import com.google.gerrit.sshd.BaseCommand;
|
||||
@@ -88,7 +89,8 @@ final class ScpCommand extends BaseCommand {
|
||||
public void run() {
|
||||
runImp();
|
||||
}
|
||||
});
|
||||
},
|
||||
AccessPath.SSH_COMMAND);
|
||||
}
|
||||
|
||||
private void runImp() {
|
||||
|
||||
Reference in New Issue
Block a user