go 实战 (类unix)鉴权系统核心

2023年 9月 7日 76.6k 0

go 实战 (类unix)鉴权系统核心

截屏2023-09-07 14.14.45.png
Linux上查看user组成,这里uid和gid是独立的,我们这里写的微核心就直接uid和gid绑定了,如果你想隔离user和group也可设立为和linux同款

截屏2023-09-07 14.55.04.png
还有一个容易被忽略的概念是执行者,例如上面这张截图,执行id这个命令的用户就是cho。
上代码。权限码仍然是4读,2写,1执行
再看这张截图,d代表类型为目录,r代表读(4),w代表可写(2),x代表可执行的(1),-代表没有权限(0),一共会有9位,每3位为一组(3位数字相加就为权限数字),每一组代表不同作用域,分别是(本用户,同组,其它),这里权限数字就为755,第一个cho为所属用户名,第二个cho为所属用户组

截屏2023-09-07 15.05.45.png

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
}

相关文章

服务器端口转发,带你了解服务器端口转发
服务器开放端口,服务器开放端口的步骤
产品推荐:7月受欢迎AI容器镜像来了,有Qwen系列大模型镜像
如何使用 WinGet 下载 Microsoft Store 应用
百度搜索:蓝易云 – 熟悉ubuntu apt-get命令详解
百度搜索:蓝易云 – 域名解析成功但ping不通解决方案

发布评论