Merge "vdl: Remove rpc.BindOpt from generated code."
diff --git a/cmd/vrun/vrun.go b/cmd/vrun/vrun.go
index e604d9f..4bdafd1 100644
--- a/cmd/vrun/vrun.go
+++ b/cmd/vrun/vrun.go
@@ -6,6 +6,7 @@
import (
"os"
+ "os/exec"
"path/filepath"
"syscall"
"time"
@@ -126,7 +127,12 @@
}
conn.Close()
}
- err := syscall.Exec(cmd[0], cmd, os.Environ())
+ p, err := exec.LookPath(cmd[0])
+ if err != nil {
+ vlog.Errorf("Couldn't find %q", cmd[0])
+ return err
+ }
+ err = syscall.Exec(p, cmd, os.Environ())
vlog.Errorf("Couldn't exec %s.", cmd[0])
return err
}
diff --git a/services/mgmt/lib/acls/hierarchical_authorizer.go b/services/mgmt/lib/acls/hierarchical_authorizer.go
index 142b59d..5b5e921 100644
--- a/services/mgmt/lib/acls/hierarchical_authorizer.go
+++ b/services/mgmt/lib/acls/hierarchical_authorizer.go
@@ -9,13 +9,15 @@
"v.io/v23/security"
"v.io/v23/security/access"
"v.io/x/lib/vlog"
+
+ "v.io/x/ref/profiles/internal/rpc"
)
-// hierarchicalAuthorizer manages a pair of authorizers for two-level
-// inheritance of AccessLists.
+// hierarchicalAuthorizer contains the state needed to implement
+// hierarchical authorization in the Authorize method.
type hierarchicalAuthorizer struct {
- child security.Authorizer
- rootAccessList access.AccessList
+ rootDir, childDir string
+ get TAMGetter
}
// TAMGetter defines an abstract interface that a customer of
@@ -38,48 +40,55 @@
return rootAuth, nil
}
-// NewHierarchicalAuthorizer creates a new hierarchicalAuthorizer
+// NewHierarchicalAuthorizer creates a new hierarchicalAuthorizer: one
+// that implements a "root" like concept: admin rights at the root of
+// a server can invoke RPCs regardless of permissions set on child objects.
func NewHierarchicalAuthorizer(rootDir, childDir string, get TAMGetter) (security.Authorizer, error) {
- rootTam, intentionallyEmpty, err := get.TAMForPath(rootDir)
- if err != nil {
- return nil, err
- } else if intentionallyEmpty {
- vlog.VI(2).Infof("TAMForPath(%s) is intentionally empty", rootDir)
- return nil, nil
- }
-
- // We are at the root so exit early.
- if rootDir == childDir {
- return mkRootAuth(rootTam)
- }
-
- // This is not fatal: the childDir may not exist if we are invoking
- // a Create() method so we only use the root AccessList.
- childTam, intentionallyEmpty, err := get.TAMForPath(childDir)
- if err != nil {
- return nil, err
- } else if intentionallyEmpty {
- return mkRootAuth(rootTam)
- }
-
- childAuth, err := access.PermissionsAuthorizer(childTam, access.TypicalTagType())
- if err != nil {
- vlog.Errorf("Successfully obtained an AccessList from the filesystem but PermissionsAuthorizer couldn't use it: %v", err)
- return nil, err
- }
-
return &hierarchicalAuthorizer{
- child: childAuth,
- rootAccessList: rootTam[string(access.Admin)],
+ rootDir: rootDir,
+ childDir: childDir,
+ get: get,
}, nil
}
-// Authorize provides two-levels of authorization. Admin permission
-// on the root provides a "superuser"-like power for administering the
-// server using an instance of hierarchicalAuthorizer. Otherwise, the
-// default permissions of the named path apply.
func (ha *hierarchicalAuthorizer) Authorize(ctx *context.T) error {
- childErr := ha.child.Authorize(ctx)
+ rootPerms, intentionallyEmpty, err := ha.get.TAMForPath(ha.rootDir)
+ if err != nil {
+ return err
+ } else if intentionallyEmpty {
+ vlog.VI(2).Infof("TAMForPath(%s) is intentionally empty", ha.rootDir)
+ return defaultAuthorizer(ctx)
+ }
+
+ // We are at the root so exit early.
+ if ha.rootDir == ha.childDir {
+ a, err := mkRootAuth(rootPerms)
+ if err != nil {
+ return err
+ }
+ return a.Authorize(ctx)
+ }
+
+ // This is not fatal: the childDir may not exist if we are invoking
+ // a Create() method so we only use the root Permissions.
+ childPerms, intentionallyEmpty, err := ha.get.TAMForPath(ha.childDir)
+ if err != nil {
+ return err
+ } else if intentionallyEmpty {
+ a, err := mkRootAuth(rootPerms)
+ if err != nil {
+ return err
+ }
+ return a.Authorize(ctx)
+ }
+
+ childAuth, err := access.PermissionsAuthorizer(childPerms, access.TypicalTagType())
+ if err != nil {
+ vlog.Errorf("Successfully obtained a Permissions from the filesystem but PermissionsAuthorizer couldn't use it: %v", err)
+ return err
+ }
+
+ childErr := childAuth.Authorize(ctx)
if childErr == nil {
return nil
}
@@ -87,9 +96,35 @@
// Maybe the invoking principal can invoke this method because
// it has root permissions.
names, _ := security.RemoteBlessingNames(ctx)
- if len(names) > 0 && ha.rootAccessList.Includes(names...) {
+ if len(names) > 0 && rootPerms[string(access.Admin)].Includes(names...) {
return nil
}
return childErr
}
+
+// defaultAuthorizer implements an authorization policy that requires one end
+// of the RPC to have a blessing that makes it a delegate of the other.
+// TODO(rjkroege): Remove this when the defaultAuthorizer becomes public.
+func defaultAuthorizer(ctx *context.T) error {
+ var (
+ localNames = security.LocalBlessingNames(ctx)
+ remoteNames, remoteErr = security.RemoteBlessingNames(ctx)
+ )
+ // Authorize if any element in localNames is a "delegate of" (i.e., has been
+ // blessed by) any element in remoteNames, OR vice-versa.
+ for _, l := range localNames {
+ if security.BlessingPattern(l).MatchedBy(remoteNames...) {
+ // l is a delegate of an element in remote.
+ return nil
+ }
+ }
+ for _, r := range remoteNames {
+ if security.BlessingPattern(r).MatchedBy(localNames...) {
+ // r is a delegate of an element in localNames.
+ return nil
+ }
+ }
+
+ return rpc.NewErrInvalidBlessings(nil, remoteNames, remoteErr, localNames)
+}