Convert runAs to PermissionBackend

Change-Id: Ia08189d864388b45c7f11b41cc835fda57d7e03d
This commit is contained in:
Shawn Pearce
2017-02-19 20:45:19 -08:00
committed by David Pursehouse
parent f4e84de1ae
commit f49c2a87ab
3 changed files with 35 additions and 11 deletions

View File

@@ -19,11 +19,15 @@ import static javax.servlet.http.HttpServletResponse.SC_FORBIDDEN;
import static javax.servlet.http.HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
import com.google.gerrit.extensions.registration.DynamicItem;
import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.account.AccountResolver;
import com.google.gerrit.server.config.AuthConfig;
import com.google.gerrit.server.permissions.GlobalPermission;
import com.google.gerrit.server.permissions.PermissionBackend;
import com.google.gerrit.server.permissions.PermissionBackendException;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import com.google.inject.Provider;
@@ -57,6 +61,7 @@ class RunAsFilter implements Filter {
private final Provider<ReviewDb> db;
private final boolean enabled;
private final DynamicItem<WebSession> session;
private final PermissionBackend permissionBackend;
private final AccountResolver accountResolver;
@Inject
@@ -64,10 +69,12 @@ class RunAsFilter implements Filter {
Provider<ReviewDb> db,
AuthConfig config,
DynamicItem<WebSession> session,
PermissionBackend permissionBackend,
AccountResolver accountResolver) {
this.db = db;
this.enabled = config.isRunAsEnabled();
this.session = session;
this.permissionBackend = permissionBackend;
this.accountResolver = accountResolver;
}
@@ -85,12 +92,20 @@ class RunAsFilter implements Filter {
}
CurrentUser self = session.get().getUser();
if (!self.getCapabilities().canRunAs()
try {
if (!self.isIdentifiedUser()) {
// Always disallow for anonymous users, even if permitted by the ACL,
// because that would be crazy.
|| !self.isIdentifiedUser()) {
throw new AuthException("denied");
}
permissionBackend.user(self).check(GlobalPermission.RUN_AS);
} catch (AuthException e) {
replyError(req, res, SC_FORBIDDEN, "not permitted to use " + RUN_AS, null);
return;
} catch (PermissionBackendException e) {
log.warn("cannot check runAs", e);
replyError(req, res, SC_INTERNAL_SERVER_ERROR, RUN_AS + " unavailable", null);
return;
}
Account target;

View File

@@ -112,11 +112,6 @@ public class CapabilityControl {
return canPerform(GlobalCapability.ACCESS_DATABASE);
}
/** @return true if the user can impersonate another user. */
public boolean canRunAs() {
return canPerform(GlobalCapability.RUN_AS);
}
/** @return which priority queue the user's tasks should be submitted to. */
public QueueProvider.QueueType getQueueType() {
// If a non-generic group (that is not Anonymous Users or Registered Users)
@@ -245,8 +240,6 @@ public class CapabilityControl {
return canMaintainServer();
case MODIFY_ACCOUNT:
return canModifyAccount();
case RUN_AS:
return canRunAs();
case VIEW_ALL_ACCOUNTS:
return canViewAllAccounts();
case VIEW_QUEUE:
@@ -265,6 +258,9 @@ public class CapabilityControl {
case VIEW_CONNECTIONS:
case VIEW_PLUGINS:
return canPerform(perm.permissionName()) || canAdministrateServer();
case RUN_AS:
return canPerform(perm.permissionName());
}
throw new PermissionBackendException(perm + " unsupported");
}

View File

@@ -18,11 +18,15 @@ import static java.nio.charset.StandardCharsets.UTF_8;
import com.google.common.base.Throwables;
import com.google.common.util.concurrent.Atomics;
import com.google.gerrit.extensions.restapi.AuthException;
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.server.permissions.GlobalPermission;
import com.google.gerrit.server.permissions.PermissionBackend;
import com.google.gerrit.server.permissions.PermissionBackendException;
import com.google.gerrit.sshd.SshScope.Context;
import com.google.inject.Inject;
import java.io.IOException;
@@ -45,6 +49,7 @@ import org.kohsuke.args4j.Option;
public final class SuExec extends BaseCommand {
private final SshScope sshScope;
private final DispatchCommandProvider dispatcher;
private final PermissionBackend permissionBackend;
private boolean enableRunAs;
private CurrentUser caller;
@@ -67,6 +72,7 @@ public final class SuExec extends BaseCommand {
SuExec(
final SshScope sshScope,
@CommandName(Commands.ROOT) final DispatchCommandProvider dispatcher,
PermissionBackend permissionBackend,
final CurrentUser caller,
final SshSession session,
final IdentifiedUser.GenericFactory userFactory,
@@ -74,6 +80,7 @@ public final class SuExec extends BaseCommand {
AuthConfig config) {
this.sshScope = sshScope;
this.dispatcher = dispatcher;
this.permissionBackend = permissionBackend;
this.caller = caller;
this.session = session;
this.userFactory = userFactory;
@@ -115,8 +122,14 @@ public final class SuExec extends BaseCommand {
// OK.
} else if (!enableRunAs) {
throw die("suexec disabled by auth.enableRunAs = false");
} else if (!caller.getCapabilities().canRunAs()) {
} else {
try {
permissionBackend.user(caller).check(GlobalPermission.RUN_AS);
} catch (AuthException e) {
throw die("suexec not permitted");
} catch (PermissionBackendException e) {
throw die("suexec not available: " + e);
}
}
}