github.com/hustcat/docker@v1.3.3-0.20160314103604-901c67a8eeab/daemon/execdriver/utils_unix.go (about) 1 // +build !windows 2 3 package execdriver 4 5 import ( 6 "fmt" 7 "strings" 8 9 "github.com/docker/docker/pkg/stringutils" 10 "github.com/syndtr/gocapability/capability" 11 ) 12 13 var capabilityList Capabilities 14 15 func init() { 16 last := capability.CAP_LAST_CAP 17 // hack for RHEL6 which has no /proc/sys/kernel/cap_last_cap 18 if last == capability.Cap(63) { 19 last = capability.CAP_BLOCK_SUSPEND 20 } 21 for _, cap := range capability.List() { 22 if cap > last { 23 continue 24 } 25 capabilityList = append(capabilityList, 26 &CapabilityMapping{ 27 Key: strings.ToUpper(cap.String()), 28 Value: cap, 29 }, 30 ) 31 } 32 } 33 34 type ( 35 // CapabilityMapping maps linux capability name to its value of capability.Cap type 36 // Capabilities is one of the security systems in Linux Security Module (LSM) 37 // framework provided by the kernel. 38 // For more details on capabilities, see http://man7.org/linux/man-pages/man7/capabilities.7.html 39 CapabilityMapping struct { 40 Key string `json:"key,omitempty"` 41 Value capability.Cap `json:"value,omitempty"` 42 } 43 // Capabilities contains all CapabilityMapping 44 Capabilities []*CapabilityMapping 45 ) 46 47 // String returns <key> of CapabilityMapping 48 func (c *CapabilityMapping) String() string { 49 return c.Key 50 } 51 52 // GetCapability returns CapabilityMapping which contains specific key 53 func GetCapability(key string) *CapabilityMapping { 54 for _, capp := range capabilityList { 55 if capp.Key == key { 56 cpy := *capp 57 return &cpy 58 } 59 } 60 return nil 61 } 62 63 // GetAllCapabilities returns all of the capabilities 64 func GetAllCapabilities() []string { 65 output := make([]string, len(capabilityList)) 66 for i, capability := range capabilityList { 67 output[i] = capability.String() 68 } 69 return output 70 } 71 72 // TweakCapabilities can tweak capabilities by adding or dropping capabilities 73 // based on the basics capabilities. 74 func TweakCapabilities(basics, adds, drops []string) ([]string, error) { 75 var ( 76 newCaps []string 77 allCaps = GetAllCapabilities() 78 ) 79 80 // look for invalid cap in the drop list 81 for _, cap := range drops { 82 if strings.ToLower(cap) == "all" { 83 continue 84 } 85 if !stringutils.InSlice(allCaps, cap) { 86 return nil, fmt.Errorf("Unknown capability drop: %q", cap) 87 } 88 } 89 90 // handle --cap-add=all 91 if stringutils.InSlice(adds, "all") { 92 basics = allCaps 93 } 94 95 if !stringutils.InSlice(drops, "all") { 96 for _, cap := range basics { 97 // skip `all` already handled above 98 if strings.ToLower(cap) == "all" { 99 continue 100 } 101 102 // if we don't drop `all`, add back all the non-dropped caps 103 if !stringutils.InSlice(drops, cap) { 104 newCaps = append(newCaps, strings.ToUpper(cap)) 105 } 106 } 107 } 108 109 for _, cap := range adds { 110 // skip `all` already handled above 111 if strings.ToLower(cap) == "all" { 112 continue 113 } 114 115 if !stringutils.InSlice(allCaps, cap) { 116 return nil, fmt.Errorf("Unknown capability to add: %q", cap) 117 } 118 119 // add cap if not already in the list 120 if !stringutils.InSlice(newCaps, cap) { 121 newCaps = append(newCaps, strings.ToUpper(cap)) 122 } 123 } 124 return newCaps, nil 125 }