go 实战 (类unix)鉴权系统核心
Linux上查看user组成,这里uid和gid是独立的,我们这里写的微核心就直接uid和gid绑定了,如果你想隔离user和group也可设立为和linux同款
还有一个容易被忽略的概念是执行者,例如上面这张截图,执行id这个命令的用户就是cho。
上代码。权限码仍然是4读,2写,1执行
再看这张截图,d代表类型为目录,r代表读(4),w代表可写(2),x代表可执行的(1),-代表没有权限(0),一共会有9位,每3位为一组(3位数字相加就为权限数字),每一组代表不同作用域,分别是(本用户,同组,其它),这里权限数字就为755,第一个cho为所属用户名,第二个cho为所属用户组
package permsys
import (
"fmt"
)
type User struct {
Uid uint32
Name string
}
type Group struct {
Users map[uint32]*User
}
type Perm struct {
OwnerId uint32
GroupId uint32
PermInfo [3]uint8
}
var groupmap = make(map[uint32]*Group)
var userlist = []User{}
var abandoned_user = make(map[uint32]struct{})
//获得执行权限码,先验证是否管理员组,由于这里uid和gid关联了,就没有单独的sudo(wheel)组了
func GetPerm(user *User, perm *Perm) uint8 {
if isroot(user.Uid) { //it's root group,return all permission
return 7
}
if user.Uid == perm.OwnerId {//用户本户返回第一组权限码
return perm.PermInfo[0]
} else if grp, ok := groupmap[perm.GroupId]; ok {
for _, usr := range grp.Users {
if usr.Uid == user.Uid {//同组用户,返回第二组权限码
return perm.PermInfo[1]
}
}
}
//其它用户,返回第三组权限码
return perm.PermInfo[2]
}
//对鉴权系统的操作就要涉及操纵者了(避免普通用户能对整套系统进行操作!),如果不是管理员组的用户将无法操作
func AddUser(usr *User, name string) {
if !isroot(usr.Uid) {
fmt.Printf("[error] Permission Denied Adduser %dn", usr.Uid)
return
}
uid := uint32(len(userlist))
userlist = append(userlist, User{uid, name})
groupmap[uid] = &Group{map[uint32]*User{uid: &userlist[uid]}}
}
//验证用户是否为管理员组的
func isroot(uid uint32) bool {
if uid == 0 {
return true
}
for _, usr := range groupmap[0].Users {
if usr.Uid == uid {
return true
}
}
return false
}
func isingroup(uid, gid uint32) bool {
if ptr, ok := groupmap[gid]; ok {
for _, usrptr := range ptr.Users {
if usrptr.Uid == uid {
return true
}
}
}
return false
}
//只有管理员有权限更改用户到指定组
func (s *User) AddUserToGroup(uid, gid uint32) error {
var err error
if _, ok := abandoned_user[uid]; ok || uid >= uint32(len(userlist)) {
err = fmt.Errorf("user %d is not existed", uid)
return err
} else if !isroot(s.Uid) {
err = fmt.Errorf("Permission Denied")
} else {
if usrptr, ok := groupmap[gid]; ok {
if _, ok := usrptr.Users[uid]; !ok {
usrptr.Users[uid] = &userlist[uid]
} else {
return fmt.Errorf("user already in group")
}
} else {
err = fmt.Errorf("group don't existed")
}
}
return err
}
func (s *User) GetPerm(perm *Perm) uint8 {
return GetPerm(s, perm)
}
//将用户从组中剥离,同样需要管理员权限
func (s *User) RemoveUserFromGroup(uid, gid uint32) error {
var err error
if isroot(s.Uid) || s.Uid == gid {
if _, ok := groupmap[gid]; ok {
if _, ok = groupmap[gid].Users[uid]; ok {
delete(groupmap[gid].Users, uid)
} else {
err = fmt.Errorf("user not in group")
}
} else {
err = fmt.Errorf("group don't existed")
}
} else {
err = fmt.Errorf("Permission Denied")
}
return err
}
//根据权限码生成权限实例
func CreatePerm(usr *User, mod string) (Perm, error) {
perm := Perm{OwnerId: usr.Uid, GroupId: usr.Uid}
if len(mod) != 3 {
return perm, fmt.Errorf("mod is invalid")
}
for i := 0; i 7{
return perm, fmt.Errorf("%d is not correct", perm.PermInfo[i])
}
}
return perm, nil
}
//删除用户,需要管理员权限
func DelUser(usr *User, uid uint32) error {
var err error
if isroot(usr.Uid) && uid != 0 {
if _, ok := abandoned_user[uid]; !ok && uid < uint32(len(userlist)) {
abandoned_user[uid] = struct{}{}
} else {
err = fmt.Errorf("User is Invalid")
}
} else {
err = fmt.Errorf("Permission Denied")
}
return err
}