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 }