示例#1
0
// Validate is called when writing a database or table descriptor.
// It takes the descriptor ID which is used to determine if
// it belongs to a system descriptor, in which case the maximum
// set of allowed privileges is looked up and applied.
func (p PrivilegeDescriptor) Validate(id ID) error {
	userPriv, ok := p.findUser(security.RootUser)
	if !ok {
		return fmt.Errorf("user %s does not have privileges", security.RootUser)
	}
	if IsSystemConfigID(id) {
		// System databases and tables have custom maximum allowed privileges.
		objectPrivileges, ok := SystemConfigAllowedPrivileges[id]
		if !ok {
			return fmt.Errorf("no allowed privileges found for system object with ID=%d", id)
		}

		// The root user must have all the allowed privileges.
		allowedPrivileges := objectPrivileges.ToBitField()
		if userPriv.Privileges&allowedPrivileges != allowedPrivileges {
			return fmt.Errorf("user %s must have %s privileges on system objects",
				security.RootUser, privilege.ListFromBitField(allowedPrivileges))
		}

		// For all users (root included), no other privileges must be granted.
		for _, u := range p.Users {
			if remaining := u.Privileges &^ allowedPrivileges; remaining != 0 {
				return fmt.Errorf("user %s must not have %s privileges on system objects",
					u.User, privilege.ListFromBitField(remaining))
			}
		}
	} else if !isPrivilegeSet(userPriv.Privileges, privilege.ALL) {
		// Non-system databases and tables must preserve ALL
		// privileges for the root user.
		return fmt.Errorf("user %s does not have ALL privileges", security.RootUser)
	}
	return nil
}
示例#2
0
// Show returns the list of {username, privileges} sorted by username.
// 'privileges' is a string of comma-separated sorted privilege names.
func (p PrivilegeDescriptor) Show() []UserPrivilegeString {
	ret := make([]UserPrivilegeString, 0, len(p.Users))
	for _, userPriv := range p.Users {
		ret = append(ret, UserPrivilegeString{
			User:       userPriv.User,
			Privileges: privilege.ListFromBitField(userPriv.Privileges).SortedNames(),
		})
	}
	return ret
}
示例#3
0
func TestPrivilegeDecode(t *testing.T) {
	defer leaktest.AfterTest(t)()
	testCases := []struct {
		raw              uint32
		privileges       privilege.List
		stringer, sorted string
	}{
		{0, privilege.List{}, "", ""},
		// We avoid 0 as a privilege value even though we use 1 << privValue.
		{1, privilege.List{}, "", ""},
		{2, privilege.List{privilege.ALL}, "ALL", "ALL"},
		{10, privilege.List{privilege.ALL, privilege.DROP}, "ALL, DROP", "ALL,DROP"},
		{144, privilege.List{privilege.GRANT, privilege.DELETE}, "GRANT, DELETE", "DELETE,GRANT"},
		{2047,
			privilege.List{privilege.ALL, privilege.CREATE, privilege.DROP, privilege.GRANT,
				privilege.SELECT, privilege.INSERT, privilege.DELETE, privilege.UPDATE},
			"ALL, CREATE, DROP, GRANT, SELECT, INSERT, DELETE, UPDATE",
			"ALL,CREATE,DELETE,DROP,GRANT,INSERT,SELECT,UPDATE",
		},
	}

	for _, tc := range testCases {
		pl := privilege.ListFromBitField(tc.raw)
		if len(pl) != len(tc.privileges) {
			t.Fatalf("%+v: wrong privilege list from raw: %+v", tc, pl)
		}
		for i := 0; i < len(pl); i++ {
			if pl[i] != tc.privileges[i] {
				t.Fatalf("%+v: wrong privilege list from raw: %+v", tc, pl)
			}
		}
		if pl.String() != tc.stringer {
			t.Fatalf("%+v: wrong String() output: %q", tc, pl.String())
		}
		if pl.SortedString() != tc.sorted {
			t.Fatalf("%+v: wrong SortedString() output: %q", tc, pl.SortedString())
		}
	}
}