Merge "services/device/device: Make it an error to operate on the null set."
diff --git a/services/mounttable/mounttablelib/mounttable.go b/services/mounttable/mounttablelib/mounttable.go
index 52e3e96..56e0974 100644
--- a/services/mounttable/mounttablelib/mounttable.go
+++ b/services/mounttable/mounttablelib/mounttable.go
@@ -29,7 +29,7 @@
 
 // NOTE(caprita): this was doubled from 1000 on 8/7/2015 to recover from crashes
 // due to hitting this in production.  We should revisit.
-const defaultMaxNodesPerUser = 2000
+const defaultMaxNodesPerUser = 1000
 
 var (
 	errMalformedAddress = verror.Register(pkgPath+".errMalformedAddress", verror.NoRetry, "{1:}{2:} malformed address {3} for mounted server {4}{:_}")
@@ -103,6 +103,21 @@
 	creator             string
 }
 
+type callContext struct {
+	ctx          *context.T
+	call         security.Call
+	self         bool                        // true if client and server are the same.
+	rbn          []string                    // remote blessing names to avoid authenticating on every check.
+	rejected     []security.RejectedBlessing // rejected remote blessing names.
+	create       bool                        // true if we are to create traversed nodes.
+	creatorSet   bool                        // true if the creator string is already set.
+	creator      string
+	ignorePerms  bool
+	ignoreLimits bool
+}
+
+const createMissingNodes = true
+
 const templateVar = "%%"
 
 // NewMountTableDispatcher creates a new server that uses the AccessLists specified in
@@ -203,29 +218,28 @@
 }
 
 // satisfies returns no error if the ctx + n.vPerms satisfies the associated one of the required Tags.
-func (n *node) satisfies(mt *mountTable, ctx *context.T, call security.Call, tags []mounttable.Tag) error {
-	// No AccessLists means everything (for now).
-	if ctx == nil || call == nil || tags == nil || n.vPerms == nil {
+func (n *node) satisfies(mt *mountTable, cc *callContext, tags []mounttable.Tag) error {
+	// Nothing to check.
+	if cc.ignorePerms || tags == nil || n.vPerms == nil {
 		return nil
 	}
 	// "Self-RPCs" are always authorized.
-	if l, r := call.LocalBlessings().PublicKey(), call.RemoteBlessings().PublicKey(); l != nil && reflect.DeepEqual(l, r) {
+	if cc.self {
 		return nil
 	}
 	// Match client's blessings against the AccessLists.
-	blessings, invalidB := security.RemoteBlessingNames(ctx, call)
 	for _, tag := range tags {
-		if al, exists := n.vPerms.AccessListForTag(string(tag)); exists && al.Includes(blessings...) {
+		if al, exists := n.vPerms.AccessListForTag(string(tag)); exists && al.Includes(cc.rbn...) {
 			return nil
 		}
 	}
-	if mt.superUsers.Includes(blessings...) {
+	if mt.superUsers.Includes(cc.rbn...) {
 		return nil
 	}
-	if len(invalidB) > 0 {
-		return verror.New(verror.ErrNoAccess, ctx, blessings, invalidB)
+	if len(cc.rejected) > 0 {
+		return verror.New(verror.ErrNoAccess, cc.ctx, cc.rbn, cc.rejected)
 	}
-	return verror.New(verror.ErrNoAccess, ctx, blessings)
+	return verror.New(verror.ErrNoAccess, cc.ctx, cc.rbn)
 }
 
 func expand(al *access.AccessList, name string) *access.AccessList {
@@ -241,32 +255,31 @@
 
 // satisfiesTemplate returns no error if the ctx + n.permsTemplate satisfies the associated one of
 // the required Tags.
-func (n *node) satisfiesTemplate(ctx *context.T, call security.Call, tags []mounttable.Tag, name string) error {
-	if n.permsTemplate == nil {
+func (n *node) satisfiesTemplate(cc *callContext, tags []mounttable.Tag, name string) error {
+	// If no template, ignore.
+	if cc.ignorePerms || n.permsTemplate == nil {
 		return nil
 	}
 	// Match client's blessings against the AccessLists.
-	blessings, invalidB := security.RemoteBlessingNames(ctx, call)
 	for _, tag := range tags {
-		if al, exists := n.permsTemplate[string(tag)]; exists && expand(&al, name).Includes(blessings...) {
+		if al, exists := n.permsTemplate[string(tag)]; exists && expand(&al, name).Includes(cc.rbn...) {
 			return nil
 		}
 	}
-	return verror.New(verror.ErrNoAccess, ctx, blessings, invalidB)
+	return verror.New(verror.ErrNoAccess, cc.ctx, cc.rbn, cc.rejected)
 }
 
 // CopyPermissions copies one node's permissions to another and adds the clients blessings as
 // patterns to the Admin tag.
-func CopyPermissions(ctx *context.T, call security.Call, cur *node) *VersionedPermissions {
+func CopyPermissions(cc *callContext, cur *node) *VersionedPermissions {
 	if cur.vPerms == nil {
 		return nil
 	}
 	vPerms := cur.vPerms.Copy()
-	if ctx == nil || call == nil {
+	if cc.rbn == nil {
 		return vPerms
 	}
-	blessings, _ := security.RemoteBlessingNames(ctx, call)
-	for _, b := range blessings {
+	for _, b := range cc.rbn {
 		vPerms.Add(security.BlessingPattern(b), string(mounttable.Admin))
 	}
 	vPerms.P.Normalize()
@@ -287,19 +300,17 @@
 // while following the path, return that node and any remaining elems.
 //
 // If it returns a node, both the node and its parent are locked.
-func (mt *mountTable) traverse(ctx *context.T, call security.Call, elems []string, create bool) (*node, []string, error) {
+func (mt *mountTable) traverse(cc *callContext, elems []string) (*node, []string, error) {
 	// Invariant is that the current node and its parent are both locked.
 	cur := mt.root
 	cur.parent.Lock()
 	cur.Lock()
 	for i, e := range elems {
-		ctx.VI(2).Infof("satisfying %v %v", elems[0:i], *cur)
-		if call != nil {
-			if err := cur.satisfies(mt, ctx, call, traverseTags); err != nil {
-				cur.parent.Unlock()
-				cur.Unlock()
-				return nil, nil, err
-			}
+		cc.ctx.VI(2).Infof("satisfying %v %v", elems[0:i], *cur)
+		if err := cur.satisfies(mt, cc, traverseTags); err != nil {
+			cur.parent.Unlock()
+			cur.Unlock()
+			return nil, nil, err
 		}
 		// If we hit another mount table, we're done.
 		if cur.mount.isActive(mt) {
@@ -313,37 +324,35 @@
 			cur.Lock()
 			continue
 		}
-		if !create {
+		if !cc.create {
 			cur.parent.Unlock()
 			cur.Unlock()
 			return nil, nil, nil
 		}
 		// Create a new node and keep recursing.
 		cur.parent.Unlock()
-		if err := cur.satisfies(mt, ctx, call, createTags); err != nil {
+		if err := cur.satisfies(mt, cc, createTags); err != nil {
 			cur.Unlock()
 			return nil, nil, err
 		}
-		if call != nil {
-			if err := cur.satisfiesTemplate(ctx, call, createTags, e); err != nil {
-				cur.Unlock()
-				return nil, nil, err
-			}
+		if err := cur.satisfiesTemplate(cc, createTags, e); err != nil {
+			cur.Unlock()
+			return nil, nil, err
 		}
 		// Obey account limits.
-		creator, err := mt.debit(ctx, call)
-		if err != nil {
+		var err error
+		if err = mt.debit(cc); err != nil {
 			cur.Unlock()
 			return nil, nil, err
 		}
 		// At this point cur is still locked, OK to use and change it.
 		next := mt.newNode()
-		next.creator = creator
+		next.creator = cc.creator
 		next.parent = cur
 		if cur.permsTemplate != nil {
 			next.vPerms = createVersionedPermissionsFromTemplate(cur.permsTemplate, e)
 		} else {
-			next.vPerms = CopyPermissions(ctx, call, cur)
+			next.vPerms = CopyPermissions(cc, cur)
 		}
 		if cur.children == nil {
 			cur.children = make(map[string]*node)
@@ -360,8 +369,8 @@
 // findNode finds a node in the table and optionally creates a path to it.
 //
 // If a node is found, on return it and its parent are locked.
-func (mt *mountTable) findNode(ctx *context.T, call security.Call, elems []string, create bool, tags, ptags []mounttable.Tag) (*node, error) {
-	n, nelems, err := mt.traverse(ctx, call, elems, create)
+func (mt *mountTable) findNode(cc *callContext, elems []string, tags, ptags []mounttable.Tag) (*node, error) {
+	n, nelems, err := mt.traverse(cc, elems)
 	if err != nil {
 		return nil, err
 	}
@@ -374,13 +383,13 @@
 		return nil, nil
 	}
 	// Either the node has to satisfy tags or the parent has to satisfy ptags.
-	if err := n.satisfies(mt, ctx, call, tags); err != nil {
+	if err := n.satisfies(mt, cc, tags); err != nil {
 		if ptags == nil {
 			n.parent.Unlock()
 			n.Unlock()
 			return nil, err
 		}
-		if err := n.parent.satisfies(mt, ctx, call, ptags); err != nil {
+		if err := n.parent.satisfies(mt, cc, ptags); err != nil {
 			n.parent.Unlock()
 			n.Unlock()
 			return nil, err
@@ -393,8 +402,8 @@
 // any elements remaining of the path.
 //
 // If a mountpoint is found, on return it and its parent are locked.
-func (mt *mountTable) findMountPoint(ctx *context.T, call security.Call, elems []string) (*node, []string, error) {
-	n, nelems, err := mt.traverse(ctx, call, elems, false)
+func (mt *mountTable) findMountPoint(cc *callContext, elems []string) (*node, []string, error) {
+	n, nelems, err := mt.traverse(cc, elems)
 	if err != nil {
 		return nil, nil, err
 	}
@@ -402,7 +411,7 @@
 		return nil, nil, nil
 	}
 	// If we can't resolve it, we can't use it.
-	if err := n.satisfies(mt, ctx, call, resolveTags); err != nil {
+	if err := n.satisfies(mt, cc, resolveTags); err != nil {
 		n.parent.Unlock()
 		n.Unlock()
 		return nil, nil, err
@@ -414,7 +423,7 @@
 		// If we removed the node, see if we can remove any of its
 		// ascendants.
 		if removed && len(elems) > 0 {
-			mt.removeUselessRecursive(ctx, elems[:len(elems)-1])
+			mt.removeUselessRecursive(cc, elems[:len(elems)-1])
 		}
 		return nil, nil, nil
 	}
@@ -431,9 +440,10 @@
 // in the mount entry is the name relative to the server's root.
 func (ms *mountContext) ResolveStep(ctx *context.T, call rpc.ServerCall) (entry naming.MountEntry, err error) {
 	ctx.VI(2).Infof("ResolveStep %q", ms.name)
+	cc := newCallContext(ctx, call.Security(), !createMissingNodes)
 	mt := ms.mt
 	// Find the next mount point for the name.
-	n, elems, werr := mt.findMountPoint(ctx, call.Security(), ms.elems)
+	n, elems, werr := mt.findMountPoint(cc, ms.elems)
 	if werr != nil {
 		err = werr
 		return
@@ -477,6 +487,7 @@
 
 // Mount a server onto the name in the receiver.
 func (ms *mountContext) Mount(ctx *context.T, call rpc.ServerCall, server string, ttlsecs uint32, flags naming.MountFlag) error {
+	cc := newCallContext(ctx, call.Security(), createMissingNodes)
 	mt := ms.mt
 	if ttlsecs == 0 {
 		ttlsecs = 10 * 365 * 24 * 60 * 60 // a really long time
@@ -494,7 +505,7 @@
 	}
 
 	// Find/create node in namespace and add the mount.
-	n, werr := mt.findNode(ctx, call.Security(), ms.elems, true, mountTags, nil)
+	n, werr := mt.findNode(cc, ms.elems, mountTags, nil)
 	if werr != nil {
 		return werr
 	}
@@ -562,9 +573,9 @@
 }
 
 // removeUselessRecursive removes any useless nodes on the tail of the path.
-func (mt *mountTable) removeUselessRecursive(ctx *context.T, elems []string) {
+func (mt *mountTable) removeUselessRecursive(cc *callContext, elems []string) {
 	for i := len(elems); i > 0; i-- {
-		n, nelems, _ := mt.traverse(ctx, nil, elems[:i], false)
+		n, nelems, _ := mt.traverse(cc, elems[:i])
 		if n == nil {
 			break
 		}
@@ -586,8 +597,9 @@
 // server is removed.
 func (ms *mountContext) Unmount(ctx *context.T, call rpc.ServerCall, server string) error {
 	ctx.VI(2).Infof("*********************Unmount %q, %s", ms.name, server)
+	cc := newCallContext(ctx, call.Security(), !createMissingNodes)
 	mt := ms.mt
-	n, err := mt.findNode(ctx, call.Security(), ms.elems, false, mountTags, nil)
+	n, err := mt.findNode(cc, ms.elems, mountTags, nil)
 	if err != nil {
 		return err
 	}
@@ -607,7 +619,7 @@
 	if removed {
 		// If we removed the node, see if we can also remove
 		// any of its ascendants.
-		mt.removeUselessRecursive(ctx, ms.elems[:len(ms.elems)-1])
+		mt.removeUselessRecursive(cc, ms.elems[:len(ms.elems)-1])
 	}
 	return nil
 }
@@ -615,6 +627,7 @@
 // Delete removes the receiver.  If all is true, any subtree is also removed.
 func (ms *mountContext) Delete(ctx *context.T, call rpc.ServerCall, deleteSubTree bool) error {
 	ctx.VI(2).Infof("*********************Delete %q, %v", ms.name, deleteSubTree)
+	cc := newCallContext(ctx, call.Security(), !createMissingNodes)
 	if len(ms.elems) == 0 {
 		// We can't delete the root.
 		return verror.New(errCantDeleteRoot, ctx)
@@ -622,7 +635,7 @@
 	mt := ms.mt
 	// Find and lock the parent node and parent node.  Either the node or its parent has
 	// to satisfy removeTags.
-	n, err := mt.findNode(ctx, call.Security(), ms.elems, false, removeTags, removeTags)
+	n, err := mt.findNode(cc, ms.elems, removeTags, removeTags)
 	if err != nil {
 		return err
 	}
@@ -648,13 +661,13 @@
 }
 
 // globStep is called with n and n.parent locked.  Returns with both unlocked.
-func (mt *mountTable) globStep(ctx *context.T, call security.Call, n *node, name string, pattern *glob.Glob, gCall rpc.GlobServerCall) {
-	if shouldAbort(ctx) {
+func (mt *mountTable) globStep(cc *callContext, n *node, name string, pattern *glob.Glob, gCall rpc.GlobServerCall) {
+	if shouldAbort(cc) {
 		n.parent.Unlock()
 		n.Unlock()
 		return
 	}
-	ctx.VI(2).Infof("globStep(%s, %s)", name, pattern)
+	cc.ctx.VI(2).Infof("globStep(%s, %s)", name, pattern)
 
 	// Globing is the lowest priority so we give up the cpu often.
 	runtime.Gosched()
@@ -673,7 +686,7 @@
 			Name: name,
 		}
 		// Only fill in the mount info if we can resolve this name.
-		if err := n.satisfies(mt, ctx, call, resolveTags); err == nil {
+		if err := n.satisfies(mt, cc, resolveTags); err == nil {
 			me.Servers = m.servers.copyToSlice()
 			me.ServesMountTable = n.mount.mt
 			me.IsLeaf = n.mount.leaf
@@ -691,8 +704,8 @@
 		// - we have Read or Admin access to the directory or
 		// - we have Resolve or Create access to the directory and the
 		//    next element in the pattern is a fixed string.
-		if err := n.satisfies(mt, ctx, call, globTags); err != nil {
-			if err := n.satisfies(mt, ctx, call, traverseTags); err != nil {
+		if err := n.satisfies(mt, cc, globTags); err != nil {
+			if err := n.satisfies(mt, cc, traverseTags); err != nil {
 				goto out
 			}
 			fixed, _ := pattern.SplitFixedElements()
@@ -712,7 +725,7 @@
 		// Recurse through the children.
 		matcher, suffix := pattern.Head(), pattern.Tail()
 		for k, c := range children {
-			if shouldAbort(ctx) {
+			if shouldAbort(cc) {
 				n.Unlock()
 				return
 			}
@@ -720,11 +733,11 @@
 			if matcher.Match(k) {
 				c.Lock()
 				// If child allows any access show it.  Otherwise, skip.
-				if err := c.satisfies(mt, ctx, call, allTags); err != nil {
+				if err := c.satisfies(mt, cc, allTags); err != nil {
 					c.Unlock()
 					continue
 				}
-				mt.globStep(ctx, call, c, naming.Join(name, k), suffix, gCall)
+				mt.globStep(cc, c, naming.Join(name, k), suffix, gCall)
 				n.Lock()
 			}
 		}
@@ -745,7 +758,7 @@
 
 	// To see anything, one has to have some access to the node.  Don't need the parent lock anymore.
 	n.parent.Unlock()
-	if err := n.satisfies(mt, ctx, call, allTags); err != nil {
+	if err := n.satisfies(mt, cc, allTags); err != nil {
 		n.Unlock()
 		return
 	}
@@ -768,11 +781,11 @@
 // c/d and a/b.
 func (ms *mountContext) Glob__(ctx *context.T, call rpc.GlobServerCall, g *glob.Glob) error {
 	ctx.VI(2).Infof("mt.Glob %v", ms.elems)
-	scall := call.Security()
+	cc := newCallContext(ctx, call.Security(), !createMissingNodes)
 
 	mt := ms.mt
 	// If there was an access error, just ignore the entry, i.e., make it invisible.
-	n, err := mt.findNode(ctx, scall, ms.elems, false, nil, nil)
+	n, err := mt.findNode(cc, ms.elems, nil, nil)
 	if err != nil {
 		return nil
 	}
@@ -780,15 +793,15 @@
 	// don't need to evaluate the glob expression. Send a partially resolved
 	// name back to the client.
 	if n == nil {
-		ms.linkToLeaf(ctx, scall, call)
+		ms.linkToLeaf(cc, call)
 		return nil
 	}
-	mt.globStep(ctx, scall, n, "", g, call)
+	mt.globStep(cc, n, "", g, call)
 	return nil
 }
 
-func (ms *mountContext) linkToLeaf(ctx *context.T, sCall security.Call, gCall rpc.GlobServerCall) {
-	n, elems, err := ms.mt.findMountPoint(ctx, sCall, ms.elems)
+func (ms *mountContext) linkToLeaf(cc *callContext, gCall rpc.GlobServerCall) {
+	n, elems, err := ms.mt.findMountPoint(cc, ms.elems)
 	if err != nil || n == nil {
 		return
 	}
@@ -803,10 +816,11 @@
 
 func (ms *mountContext) SetPermissions(ctx *context.T, call rpc.ServerCall, perms access.Permissions, version string) error {
 	ctx.VI(2).Infof("SetPermissions %q", ms.name)
+	cc := newCallContext(ctx, call.Security(), createMissingNodes)
 	mt := ms.mt
 
 	// Find/create node in namespace and add the mount.
-	n, err := mt.findNode(ctx, call.Security(), ms.elems, true, setTags, nil)
+	n, err := mt.findNode(cc, ms.elems, setTags, nil)
 	if err != nil {
 		return err
 	}
@@ -819,16 +833,15 @@
 
 	// If the caller is trying to add a Permission that they are no longer Admin in,
 	// retain the caller's blessings that were in Admin to prevent them from locking themselves out.
-	bnames, _ := security.RemoteBlessingNames(ctx, call.Security())
-	if al, ok := perms[string(mounttable.Admin)]; !ok || !al.Includes(bnames...) {
+	if al, ok := perms[string(mounttable.Admin)]; !ok || !al.Includes(cc.rbn...) {
 		_, oldPerms := n.vPerms.Get()
 		if oldPerms == nil {
-			for _, bname := range bnames {
+			for _, bname := range cc.rbn {
 				perms.Add(security.BlessingPattern(bname), string(mounttable.Admin))
 			}
 		} else {
 			oldAl := oldPerms[string(mounttable.Admin)]
-			for _, bname := range bnames {
+			for _, bname := range cc.rbn {
 				if oldAl.Includes(bname) {
 					perms.Add(security.BlessingPattern(bname), string(mounttable.Admin))
 				}
@@ -849,10 +862,11 @@
 
 func (ms *mountContext) GetPermissions(ctx *context.T, call rpc.ServerCall) (access.Permissions, string, error) {
 	ctx.VI(2).Infof("GetPermissions %q", ms.name)
+	cc := newCallContext(ctx, call.Security(), !createMissingNodes)
 	mt := ms.mt
 
 	// Find node in namespace and add the mount.
-	n, err := mt.findNode(ctx, call.Security(), ms.elems, false, getTags, nil)
+	n, err := mt.findNode(cc, ms.elems, getTags, nil)
 	if err != nil {
 		return nil, "", err
 	}
@@ -871,24 +885,39 @@
 }
 
 // debit user for node creation.
-func (mt *mountTable) debit(ctx *context.T, call security.Call) (string, error) {
-	creator := mt.pickCreator(ctx, call)
-	count, ok := mt.perUserNodeCounter.Incr(creator, 1).(int64)
+func (mt *mountTable) debit(cc *callContext) error {
+	// Cache any creator we pick so that we don't do it again.
+	if !cc.creatorSet {
+		cc.creator = mt.pickCreator(cc.ctx, cc.call)
+		cc.creatorSet = true
+	}
+	count, ok := mt.perUserNodeCounter.Incr(cc.creator, 1).(int64)
 	if !ok {
-		return "", verror.New(errTooManyNodes, ctx)
+		return verror.New(errTooManyNodes, cc.ctx)
 	}
-	if count > mt.maxNodesPerUser {
-		mt.perUserNodeCounter.Incr(creator, -1)
-		return "", verror.New(errTooManyNodes, ctx)
+	if count > mt.maxNodesPerUser && !cc.ignoreLimits {
+		mt.perUserNodeCounter.Incr(cc.creator, -1)
+		return verror.New(errTooManyNodes, cc.ctx)
 	}
-	return creator, nil
+	return nil
 }
 
-func shouldAbort(ctx *context.T) bool {
+func shouldAbort(cc *callContext) bool {
 	select {
-	case <-ctx.Done():
+	case <-cc.ctx.Done():
 		return true
 	default:
 		return false
 	}
 }
+
+func newCallContext(ctx *context.T, call security.Call, create bool) *callContext {
+	cc := &callContext{ctx: ctx, call: call, create: create}
+	if call != nil {
+		if l, r := cc.call.LocalBlessings().PublicKey(), cc.call.RemoteBlessings().PublicKey(); l != nil && reflect.DeepEqual(l, r) {
+			cc.self = true
+		}
+		cc.rbn, cc.rejected = security.RemoteBlessingNames(ctx, call)
+	}
+	return cc
+}
diff --git a/services/mounttable/mounttablelib/persistentstore.go b/services/mounttable/mounttablelib/persistentstore.go
index 3132e59..18c9af5 100644
--- a/services/mounttable/mounttablelib/persistentstore.go
+++ b/services/mounttable/mounttablelib/persistentstore.go
@@ -123,6 +123,12 @@
 	ctx.VI(2).Infof("parseLogFile(%s)", f.Name())
 	mt := s.mt
 	decoder := json.NewDecoder(f)
+	cc := &callContext{ctx: ctx,
+		creatorSet:   true,
+		create:       true,
+		ignorePerms:  true,
+		ignoreLimits: true,
+	}
 	for {
 		var e storeElement
 		if err := decoder.Decode(&e); err != nil {
@@ -133,9 +139,12 @@
 		}
 
 		elems := strings.Split(e.N, "/")
-		n, err := mt.findNode(ctx, nil, elems, true, nil, nil)
-		if n != nil || err == nil {
-			n.creator = e.C
+		cc.creator = e.C
+		n, err := mt.findNode(cc, elems, nil, nil)
+		if n == nil {
+			continue
+		}
+		if err == nil {
 			if e.D {
 				mt.deleteNode(n.parent, elems[len(elems)-1])
 				ctx.VI(2).Infof("deleted %s", e.N)
diff --git a/services/mounttable/mounttablelib/versionedpermissions.go b/services/mounttable/mounttablelib/versionedpermissions.go
index 1c6759a..da884c4 100644
--- a/services/mounttable/mounttablelib/versionedpermissions.go
+++ b/services/mounttable/mounttablelib/versionedpermissions.go
@@ -108,6 +108,12 @@
 			}
 			return err
 		}
+		cc := &callContext{ctx: ctx,
+			creatorSet:   true,
+			create:       true,
+			ignorePerms:  true,
+			ignoreLimits: true,
+		}
 		// Sort the map shortest key first.  That way configs for nodes higher up in the
 		// name tree happen first ensuring that lower nodes correctly inherit permissions.
 		var keys []string
@@ -142,7 +148,8 @@
 			}
 
 			// Create name and add the Permissions map to it.
-			n, err := mt.findNode(ctx, nil, elems, true, nil, nil)
+			cc.creator = mt.pickCreator(ctx, nil)
+			n, err := mt.findNode(cc, elems, nil, nil)
 			if err != nil {
 				ctx.Errorf("skipping node for %v; error: %v", elems, err)
 			}