github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/sql/sqlbase/privilege.go (about)

     1  // Copyright 2015 The Cockroach Authors.
     2  //
     3  // Use of this software is governed by the Business Source License
     4  // included in the file licenses/BSL.txt.
     5  //
     6  // As of the Change Date specified in that file, in accordance with
     7  // the Business Source License, use of this software will be governed
     8  // by the Apache License, Version 2.0, included in the file
     9  // licenses/APL.txt.
    10  
    11  package sqlbase
    12  
    13  import (
    14  	"fmt"
    15  	"sort"
    16  	"strings"
    17  
    18  	"github.com/cockroachdb/cockroach/pkg/security"
    19  	"github.com/cockroachdb/cockroach/pkg/sql/privilege"
    20  )
    21  
    22  func isPrivilegeSet(bits uint32, priv privilege.Kind) bool {
    23  	return bits&priv.Mask() != 0
    24  }
    25  
    26  // findUserIndex looks for a given user and returns its
    27  // index in the User array if found. Returns -1 otherwise.
    28  func (p PrivilegeDescriptor) findUserIndex(user string) int {
    29  	idx := sort.Search(len(p.Users), func(i int) bool {
    30  		return p.Users[i].User >= user
    31  	})
    32  	if idx < len(p.Users) && p.Users[idx].User == user {
    33  		return idx
    34  	}
    35  	return -1
    36  }
    37  
    38  // findUser looks for a specific user in the list.
    39  // Returns (nil, false) if not found, or (obj, true) if found.
    40  func (p PrivilegeDescriptor) findUser(user string) (*UserPrivileges, bool) {
    41  	idx := p.findUserIndex(user)
    42  	if idx == -1 {
    43  		return nil, false
    44  	}
    45  	return &p.Users[idx], true
    46  }
    47  
    48  // findOrCreateUser looks for a specific user in the list, creating it if needed.
    49  func (p *PrivilegeDescriptor) findOrCreateUser(user string) *UserPrivileges {
    50  	idx := sort.Search(len(p.Users), func(i int) bool {
    51  		return p.Users[i].User >= user
    52  	})
    53  	if idx == len(p.Users) {
    54  		// Not found but should be inserted at the end.
    55  		p.Users = append(p.Users, UserPrivileges{User: user})
    56  	} else if p.Users[idx].User == user {
    57  		// Found.
    58  	} else {
    59  		// New element to be inserted at idx.
    60  		p.Users = append(p.Users, UserPrivileges{})
    61  		copy(p.Users[idx+1:], p.Users[idx:])
    62  		p.Users[idx] = UserPrivileges{User: user}
    63  	}
    64  	return &p.Users[idx]
    65  }
    66  
    67  // removeUser looks for a given user in the list and removes it if present.
    68  func (p *PrivilegeDescriptor) removeUser(user string) {
    69  	idx := p.findUserIndex(user)
    70  	if idx == -1 {
    71  		// Not found.
    72  		return
    73  	}
    74  	p.Users = append(p.Users[:idx], p.Users[idx+1:]...)
    75  }
    76  
    77  // NewCustomSuperuserPrivilegeDescriptor returns a privilege descriptor for the root user
    78  // and the admin role with specified privileges.
    79  func NewCustomSuperuserPrivilegeDescriptor(priv privilege.List) *PrivilegeDescriptor {
    80  	return &PrivilegeDescriptor{
    81  		Users: []UserPrivileges{
    82  			{
    83  				User:       AdminRole,
    84  				Privileges: priv.ToBitField(),
    85  			},
    86  			{
    87  				User:       security.RootUser,
    88  				Privileges: priv.ToBitField(),
    89  			},
    90  		},
    91  	}
    92  }
    93  
    94  // NewPrivilegeDescriptor returns a privilege descriptor for the given
    95  // user with the specified list of privileges.
    96  func NewPrivilegeDescriptor(user string, priv privilege.List) *PrivilegeDescriptor {
    97  	return &PrivilegeDescriptor{
    98  		Users: []UserPrivileges{
    99  			{
   100  				User:       user,
   101  				Privileges: priv.ToBitField(),
   102  			},
   103  		},
   104  	}
   105  }
   106  
   107  // DefaultSuperuserPrivileges is the list of privileges for super users
   108  // on non-system objects.
   109  var DefaultSuperuserPrivileges = privilege.List{privilege.ALL}
   110  
   111  // NewDefaultPrivilegeDescriptor returns a privilege descriptor
   112  // with ALL privileges for the root user and admin role.
   113  func NewDefaultPrivilegeDescriptor() *PrivilegeDescriptor {
   114  	return NewCustomSuperuserPrivilegeDescriptor(DefaultSuperuserPrivileges)
   115  }
   116  
   117  // Grant adds new privileges to this descriptor for a given list of users.
   118  // TODO(marc): if all privileges other than ALL are set, should we collapse
   119  // them into ALL?
   120  func (p *PrivilegeDescriptor) Grant(user string, privList privilege.List) {
   121  	userPriv := p.findOrCreateUser(user)
   122  	if isPrivilegeSet(userPriv.Privileges, privilege.ALL) {
   123  		// User already has 'ALL' privilege: no-op.
   124  		return
   125  	}
   126  
   127  	bits := privList.ToBitField()
   128  	if isPrivilegeSet(bits, privilege.ALL) {
   129  		// Granting 'ALL' privilege: overwrite.
   130  		// TODO(marc): the grammar does not allow it, but we should
   131  		// check if other privileges are being specified and error out.
   132  		userPriv.Privileges = privilege.ALL.Mask()
   133  		return
   134  	}
   135  	userPriv.Privileges |= bits
   136  }
   137  
   138  // Revoke removes privileges from this descriptor for a given list of users.
   139  func (p *PrivilegeDescriptor) Revoke(user string, privList privilege.List) {
   140  	userPriv, ok := p.findUser(user)
   141  	if !ok || userPriv.Privileges == 0 {
   142  		// Removing privileges from a user without privileges is a no-op.
   143  		return
   144  	}
   145  
   146  	bits := privList.ToBitField()
   147  	if isPrivilegeSet(bits, privilege.ALL) {
   148  		// Revoking 'ALL' privilege: remove user.
   149  		// TODO(marc): the grammar does not allow it, but we should
   150  		// check if other privileges are being specified and error out.
   151  		p.removeUser(user)
   152  		return
   153  	}
   154  
   155  	if isPrivilegeSet(userPriv.Privileges, privilege.ALL) {
   156  		// User has 'ALL' privilege. Remove it and set
   157  		// all other privileges one.
   158  		userPriv.Privileges = 0
   159  		for _, v := range privilege.ByValue {
   160  			if v != privilege.ALL {
   161  				userPriv.Privileges |= v.Mask()
   162  			}
   163  		}
   164  	}
   165  
   166  	// One doesn't see "AND NOT" very often.
   167  	userPriv.Privileges &^= bits
   168  
   169  	if userPriv.Privileges == 0 {
   170  		p.removeUser(user)
   171  	}
   172  }
   173  
   174  // MaybeFixPrivileges fixes the privilege descriptor if needed, including:
   175  // * adding default privileges for the "admin" role
   176  // * fixing default privileges for the "root" user
   177  // * fixing maximum privileges for users.
   178  // Returns true if the privilege descriptor was modified.
   179  func (p *PrivilegeDescriptor) MaybeFixPrivileges(id ID) bool {
   180  	allowedPrivilegesBits := privilege.ALL.Mask()
   181  	if IsReservedID(id) {
   182  		// System databases and tables have custom maximum allowed privileges.
   183  		allowedPrivilegesBits = SystemAllowedPrivileges[id].ToBitField()
   184  	}
   185  
   186  	var modified bool
   187  
   188  	fixSuperUser := func(user string) {
   189  		privs := p.findOrCreateUser(user)
   190  		if privs.Privileges != allowedPrivilegesBits {
   191  			privs.Privileges = allowedPrivilegesBits
   192  			modified = true
   193  		}
   194  	}
   195  
   196  	// Check "root" user and "admin" role.
   197  	fixSuperUser(security.RootUser)
   198  	fixSuperUser(AdminRole)
   199  
   200  	if isPrivilegeSet(allowedPrivilegesBits, privilege.ALL) {
   201  		// ALL privileges allowed, we can skip regular users.
   202  		return modified
   203  	}
   204  
   205  	for i := range p.Users {
   206  		// Users is a slice of values, we need pointers to make them mutable.
   207  		u := &p.Users[i]
   208  		if u.User == security.RootUser || u.User == AdminRole {
   209  			// we've already checked super users.
   210  			continue
   211  		}
   212  
   213  		if (u.Privileges &^ allowedPrivilegesBits) != 0 {
   214  			// User has disallowed privileges: bitwise AND with allowed privileges.
   215  			u.Privileges &= allowedPrivilegesBits
   216  			modified = true
   217  		}
   218  	}
   219  
   220  	return modified
   221  }
   222  
   223  // Validate is called when writing a database or table descriptor.
   224  // It takes the descriptor ID which is used to determine if
   225  // it belongs to a system descriptor, in which case the maximum
   226  // set of allowed privileges is looked up and applied.
   227  func (p PrivilegeDescriptor) Validate(id ID) error {
   228  	allowedPrivileges := privilege.List{privilege.ALL}
   229  	if IsReservedID(id) {
   230  		var ok bool
   231  		allowedPrivileges, ok = SystemAllowedPrivileges[id]
   232  		if !ok {
   233  			return fmt.Errorf("no allowed privileges found for system object with ID=%d", id)
   234  		}
   235  	}
   236  
   237  	// Check "root" user.
   238  	if err := p.validateRequiredSuperuser(id, allowedPrivileges, security.RootUser); err != nil {
   239  		return err
   240  	}
   241  
   242  	// We expect an "admin" role. Check that it has desired superuser permissions.
   243  	if err := p.validateRequiredSuperuser(id, allowedPrivileges, AdminRole); err != nil {
   244  		return err
   245  	}
   246  
   247  	allowedPrivilegesBits := allowedPrivileges.ToBitField()
   248  	if isPrivilegeSet(allowedPrivilegesBits, privilege.ALL) {
   249  		// ALL privileges allowed, we can skip regular users.
   250  		return nil
   251  	}
   252  
   253  	// For all non-super users, privileges must not exceed the allowed privileges.
   254  	for _, u := range p.Users {
   255  		if u.User == security.RootUser || u.User == AdminRole {
   256  			// We've already checked super users.
   257  			continue
   258  		}
   259  
   260  		if remaining := u.Privileges &^ allowedPrivilegesBits; remaining != 0 {
   261  			return fmt.Errorf("user %s must not have %s privileges on system object with ID=%d",
   262  				u.User, privilege.ListFromBitField(remaining), id)
   263  		}
   264  	}
   265  
   266  	return nil
   267  }
   268  
   269  func (p PrivilegeDescriptor) validateRequiredSuperuser(
   270  	id ID, allowedPrivileges privilege.List, user string,
   271  ) error {
   272  	superPriv, ok := p.findUser(user)
   273  	if !ok {
   274  		return fmt.Errorf("user %s does not have privileges over system object with ID=%d", user, id)
   275  	}
   276  
   277  	// The super users must match the allowed privilege set exactly.
   278  	if superPriv.Privileges != allowedPrivileges.ToBitField() {
   279  		return fmt.Errorf("user %s must have exactly %s privileges on system object with ID=%d",
   280  			user, allowedPrivileges, id)
   281  	}
   282  
   283  	return nil
   284  }
   285  
   286  // UserPrivilegeString is a pair of strings describing the
   287  // privileges for a given user.
   288  type UserPrivilegeString struct {
   289  	User       string
   290  	Privileges []string
   291  }
   292  
   293  // PrivilegeString returns a string of comma-separted privilege names.
   294  func (u UserPrivilegeString) PrivilegeString() string {
   295  	return strings.Join(u.Privileges, ",")
   296  }
   297  
   298  // Show returns the list of {username, privileges} sorted by username.
   299  // 'privileges' is a string of comma-separated sorted privilege names.
   300  func (p PrivilegeDescriptor) Show() []UserPrivilegeString {
   301  	ret := make([]UserPrivilegeString, 0, len(p.Users))
   302  	for _, userPriv := range p.Users {
   303  		ret = append(ret, UserPrivilegeString{
   304  			User:       userPriv.User,
   305  			Privileges: privilege.ListFromBitField(userPriv.Privileges).SortedNames(),
   306  		})
   307  	}
   308  	return ret
   309  }
   310  
   311  // CheckPrivilege returns true if 'user' has 'privilege' on this descriptor.
   312  func (p PrivilegeDescriptor) CheckPrivilege(user string, priv privilege.Kind) bool {
   313  	userPriv, ok := p.findUser(user)
   314  	if !ok {
   315  		// User "node" has all privileges.
   316  		return user == security.NodeUser
   317  	}
   318  	// ALL is always good.
   319  	if isPrivilegeSet(userPriv.Privileges, privilege.ALL) {
   320  		return true
   321  	}
   322  	return isPrivilegeSet(userPriv.Privileges, priv)
   323  }
   324  
   325  // AnyPrivilege returns true if 'user' has any privilege on this descriptor.
   326  func (p PrivilegeDescriptor) AnyPrivilege(user string) bool {
   327  	userPriv, ok := p.findUser(user)
   328  	if !ok {
   329  		return false
   330  	}
   331  	return userPriv.Privileges != 0
   332  }