Beispiel #1
0
func (zd *Dir) canRead(ai *auth.Info) bool {
	if ai==nil || ai.Uid=="elf" {
		return zd.mode&0444 != 0
	}
	uid := zd.d["Uid"]
	if uid=="" || ai.Uid==uid {
		return zd.mode&0444 != 0
	}
	if ai.InGroup(zd.d["Gid"]) {
		return zd.mode&0044 != 0
	}
	return zd.mode&0004 != 0
}
Beispiel #2
0
func (zd *Dir) canExec(ai *auth.Info) bool {
	if ai==nil || ai.Uid=="elf" {
		return zd.mode&0111 != 0
	}
	uid := zd.d["Uid"]
	if uid=="" || ai.Uid==uid || ai.Uid=="elf" {
		return zd.mode&0111 != 0
	}
	if ai.InGroup(zd.d["Gid"]) {
		return zd.mode&0011 != 0
	}
	return zd.mode&0001 != 0
}
Beispiel #3
0
// To check with 0111 | 0222 | 0444.
func (d Dir) Can(ai *auth.Info, what int) bool {
	if d == nil {
		return true
	}
	mode := int(d.Mode())
	if ai.InGroup(d["Uid"]) {
		return mode&what != 0
	}

	if ai.InGroup(d["Gid"]) {
		return mode&what&077 != 0
	}

	return mode&what&07 != 0
}
Beispiel #4
0
func (zd *Dir) canWstat(ai *auth.Info, nd zx.Dir) error {
	isowner := ai==nil || zd.d["Uid"]=="" || zd.d["Uid"]==ai.Uid
	canwrite := zd.canWrite(ai)
	for k, v := range nd {
		if v==zd.d[k] || ai!=nil && ai.Uid=="elf" {
			continue // no change really
		}
		switch k {
		case "mode":
			if !isowner {
				return fmt.Errorf("mode: %s", dbg.ErrPerm)
			}
		case "mtime", "size":
			if !canwrite {
				return fmt.Errorf("mtime: %s", dbg.ErrPerm)
			}
		case "type", "name", "Wuid":
			return fmt.Errorf("%s: %s", k, dbg.ErrPerm)
		case "Uid":
			if !ai.InGroup("sys") {
				return fmt.Errorf("%s: %s", k, dbg.ErrPerm)
			}
		case "Gid":
			if !ai.InGroup(v) && !ai.InGroup("sys") {
				return fmt.Errorf("%s: %s", k, dbg.ErrPerm)
			}
		default:
			if len(k)>0 && k[0]>='A' && k[0]<='Z' &&
				!canwrite && !isowner {
				return fmt.Errorf("mtime: %s", dbg.ErrPerm)
			}
		}
	}
	return nil
}
Beispiel #5
0
// can this auth info do this wstat to this file?
// If ai is nil, owner's role is assumed.
// path, addr, type, wuid, and name are never updated
// so they are ignored.
// Only the owner can udpate the mode
// Updating the size is ok if CanPut(), and it's ignored for directories.
// The owner can update the group or the owner if it's a
// member of the target owner/group.
// The owner and group members may update other attributes
func (d Dir) CanWstat(ai *auth.Info, nd Dir) error {
	if ai == nil && nd["size"] != "" && d["type"] == "d" {
		return fmt.Errorf("size: %s", ErrIsDir)
	}
	if len(d) == 0 || len(nd) == 0 || ai == nil {
		return nil
	}
	isowner := ai.InGroup(d["uid"])
	for k, v := range nd {
		if d[k] == v {
			continue
		}
		switch k {
		case "path", "addr", "type", "wuid", "name":
			// ignored
		case "mode":
			if !isowner {
				return fmt.Errorf("mode: %s", ErrPerm)
			}
		case "size":
			if !d.CanPut(ai) {
				return fmt.Errorf("size: %s", ErrPerm)
			}
		case "uid", "gid":
			if !isowner || (!ai.InGroup(v) && !ai.InGroup("elf")) {
				return fmt.Errorf("%s: %s", k, ErrPerm)
			}
		case "mtime":
			fallthrough
		default:
			if !isowner && !ai.InGroup(d["gid"]) {
				return fmt.Errorf("size: %s", ErrPerm)
			}

		}
	}
	return nil
}
Beispiel #6
0
// can this wstat be performed?
// If ai is nil, owner's role is assumed.
// Use this to check that it look fine even under no permission checking.
// The user can set only mode, mtime, size, and attrs starting with Upper runes but
// for Wuid.
// Attributes that the user can't set are ignored.
// However if there are only attributes that the user can't set and they try to
// change the value, an error is granted.
// Mode can be changed only by the owner
// mtime can be changed by the owner and anyone with write permissions.
// size can be changed by anyone with write permissions.
// uid/gid can be changed only by the owner if also a member of the target id or elf.
// Other usr attrs can be changed only by the owner and anyone with write permissions.
func (d Dir) CanWstat(ai *auth.Info, nd Dir) error {
	if d == nil || nd == nil {
		return nil
	}
	isowner := ai.InGroup(d["Uid"])
	some := false
	somecant := ""
	for k, v := range nd {
		if !IsUsr(k) {
			if v == "" {
				return fmt.Errorf("%s: %s", k, errCantRemove)
			}
			somecant = k
			continue
		}
		if k == "size" && d["type"] == "d" && v != d[k] {
			somecant = k
			continue
		}
		some = true
		if v == d[k] {
			continue // no change really
		}
		switch k {
		case "mode":
			if v == "" {
				return fmt.Errorf("mode: %s", errCantRemove)
			}
			if !isowner {
				return fmt.Errorf("mode: %s", dbg.ErrPerm)
			}
		case "size":
			if v == "" {
				return fmt.Errorf("%s: %s", k, errCantRemove)
			}
			if !d.CanWrite(ai) {
				return fmt.Errorf("%s: %s", k, dbg.ErrPerm)
			}
		case "Uid", "Gid":
			if v == "" {
				return fmt.Errorf("%s: %s", k, errCantRemove)
			}
			if !isowner || (!ai.InGroup(v) && !ai.InGroup("elf")) {
				return fmt.Errorf("%s: %s", k, dbg.ErrPerm)
			}
		case "mtime":
			if v == "" {
				return fmt.Errorf("%s: %s", k, errCantRemove)
			}
			fallthrough
		default:
			if !isowner && !d.CanWrite(ai) {
				return fmt.Errorf("%s: %s", k, dbg.ErrPerm)
			}
		}
	}
	if !some && somecant != "" {
		return fmt.Errorf("%s: %s", somecant, dbg.ErrPerm)
	}
	return nil
}