1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
|
//go:build linux && cgo
package idmap
import (
"fmt"
"strconv"
"strings"
)
// ParseRawIdmap parses an IDMAP string.
func ParseRawIdmap(value string) ([]IdmapEntry, error) {
getRange := func(r string) (int64, int64, error) {
entries := strings.Split(r, "-")
if len(entries) > 2 {
return -1, -1, fmt.Errorf("Invalid ID Map range %q", r)
}
base, err := strconv.ParseInt(entries[0], 10, 64)
if err != nil {
return -1, -1, err
}
size := int64(1)
if len(entries) > 1 {
size, err = strconv.ParseInt(entries[1], 10, 64)
if err != nil {
return -1, -1, err
}
size -= base
size++
}
return base, size, nil
}
ret := IdmapSet{}
for _, line := range strings.Split(value, "\n") {
if line == "" {
continue
}
entries := strings.Split(line, " ")
if len(entries) != 3 {
return nil, fmt.Errorf("Invalid ID map line %q", line)
}
outsideBase, outsideSize, err := getRange(entries[1])
if err != nil {
return nil, err
}
insideBase, insideSize, err := getRange(entries[2])
if err != nil {
return nil, err
}
if insideSize != outsideSize {
return nil, fmt.Errorf("The ID map ranges are of different sizes %q", line)
}
entry := IdmapEntry{
Hostid: outsideBase,
Nsid: insideBase,
Maprange: insideSize,
}
switch entries[0] {
case "both":
entry.Isuid = true
entry.Isgid = true
err := ret.AddSafe(entry)
if err != nil {
return nil, err
}
case "uid":
entry.Isuid = true
err := ret.AddSafe(entry)
if err != nil {
return nil, err
}
case "gid":
entry.Isgid = true
err := ret.AddSafe(entry)
if err != nil {
return nil, err
}
default:
return nil, fmt.Errorf("Invalid ID map type %q", line)
}
}
return ret.Idmap, nil
}
|