github.com/guilhermebr/docker@v1.4.2-0.20150428121140-67da055cebca/daemon/execdriver/utils.go (about)

     1  package execdriver
     2  
     3  import (
     4  	"fmt"
     5  	"strings"
     6  
     7  	"github.com/docker/docker/pkg/stringutils"
     8  	"github.com/syndtr/gocapability/capability"
     9  )
    10  
    11  var capabilityList = Capabilities{
    12  	{Key: "SETPCAP", Value: capability.CAP_SETPCAP},
    13  	{Key: "SYS_MODULE", Value: capability.CAP_SYS_MODULE},
    14  	{Key: "SYS_RAWIO", Value: capability.CAP_SYS_RAWIO},
    15  	{Key: "SYS_PACCT", Value: capability.CAP_SYS_PACCT},
    16  	{Key: "SYS_ADMIN", Value: capability.CAP_SYS_ADMIN},
    17  	{Key: "SYS_NICE", Value: capability.CAP_SYS_NICE},
    18  	{Key: "SYS_RESOURCE", Value: capability.CAP_SYS_RESOURCE},
    19  	{Key: "SYS_TIME", Value: capability.CAP_SYS_TIME},
    20  	{Key: "SYS_TTY_CONFIG", Value: capability.CAP_SYS_TTY_CONFIG},
    21  	{Key: "MKNOD", Value: capability.CAP_MKNOD},
    22  	{Key: "AUDIT_WRITE", Value: capability.CAP_AUDIT_WRITE},
    23  	{Key: "AUDIT_CONTROL", Value: capability.CAP_AUDIT_CONTROL},
    24  	{Key: "MAC_OVERRIDE", Value: capability.CAP_MAC_OVERRIDE},
    25  	{Key: "MAC_ADMIN", Value: capability.CAP_MAC_ADMIN},
    26  	{Key: "NET_ADMIN", Value: capability.CAP_NET_ADMIN},
    27  	{Key: "SYSLOG", Value: capability.CAP_SYSLOG},
    28  	{Key: "CHOWN", Value: capability.CAP_CHOWN},
    29  	{Key: "NET_RAW", Value: capability.CAP_NET_RAW},
    30  	{Key: "DAC_OVERRIDE", Value: capability.CAP_DAC_OVERRIDE},
    31  	{Key: "FOWNER", Value: capability.CAP_FOWNER},
    32  	{Key: "DAC_READ_SEARCH", Value: capability.CAP_DAC_READ_SEARCH},
    33  	{Key: "FSETID", Value: capability.CAP_FSETID},
    34  	{Key: "KILL", Value: capability.CAP_KILL},
    35  	{Key: "SETGID", Value: capability.CAP_SETGID},
    36  	{Key: "SETUID", Value: capability.CAP_SETUID},
    37  	{Key: "LINUX_IMMUTABLE", Value: capability.CAP_LINUX_IMMUTABLE},
    38  	{Key: "NET_BIND_SERVICE", Value: capability.CAP_NET_BIND_SERVICE},
    39  	{Key: "NET_BROADCAST", Value: capability.CAP_NET_BROADCAST},
    40  	{Key: "IPC_LOCK", Value: capability.CAP_IPC_LOCK},
    41  	{Key: "IPC_OWNER", Value: capability.CAP_IPC_OWNER},
    42  	{Key: "SYS_CHROOT", Value: capability.CAP_SYS_CHROOT},
    43  	{Key: "SYS_PTRACE", Value: capability.CAP_SYS_PTRACE},
    44  	{Key: "SYS_BOOT", Value: capability.CAP_SYS_BOOT},
    45  	{Key: "LEASE", Value: capability.CAP_LEASE},
    46  	{Key: "SETFCAP", Value: capability.CAP_SETFCAP},
    47  	{Key: "WAKE_ALARM", Value: capability.CAP_WAKE_ALARM},
    48  	{Key: "BLOCK_SUSPEND", Value: capability.CAP_BLOCK_SUSPEND},
    49  }
    50  
    51  type (
    52  	CapabilityMapping struct {
    53  		Key   string         `json:"key,omitempty"`
    54  		Value capability.Cap `json:"value,omitempty"`
    55  	}
    56  	Capabilities []*CapabilityMapping
    57  )
    58  
    59  func (c *CapabilityMapping) String() string {
    60  	return c.Key
    61  }
    62  
    63  func GetCapability(key string) *CapabilityMapping {
    64  	for _, capp := range capabilityList {
    65  		if capp.Key == key {
    66  			cpy := *capp
    67  			return &cpy
    68  		}
    69  	}
    70  	return nil
    71  }
    72  
    73  func GetAllCapabilities() []string {
    74  	output := make([]string, len(capabilityList))
    75  	for i, capability := range capabilityList {
    76  		output[i] = capability.String()
    77  	}
    78  	return output
    79  }
    80  
    81  func TweakCapabilities(basics, adds, drops []string) ([]string, error) {
    82  	var (
    83  		newCaps []string
    84  		allCaps = GetAllCapabilities()
    85  	)
    86  
    87  	// look for invalid cap in the drop list
    88  	for _, cap := range drops {
    89  		if strings.ToLower(cap) == "all" {
    90  			continue
    91  		}
    92  		if !stringutils.InSlice(allCaps, cap) {
    93  			return nil, fmt.Errorf("Unknown capability drop: %q", cap)
    94  		}
    95  	}
    96  
    97  	// handle --cap-add=all
    98  	if stringutils.InSlice(adds, "all") {
    99  		basics = allCaps
   100  	}
   101  
   102  	if !stringutils.InSlice(drops, "all") {
   103  		for _, cap := range basics {
   104  			// skip `all` aready handled above
   105  			if strings.ToLower(cap) == "all" {
   106  				continue
   107  			}
   108  
   109  			// if we don't drop `all`, add back all the non-dropped caps
   110  			if !stringutils.InSlice(drops, cap) {
   111  				newCaps = append(newCaps, strings.ToUpper(cap))
   112  			}
   113  		}
   114  	}
   115  
   116  	for _, cap := range adds {
   117  		// skip `all` aready handled above
   118  		if strings.ToLower(cap) == "all" {
   119  			continue
   120  		}
   121  
   122  		if !stringutils.InSlice(allCaps, cap) {
   123  			return nil, fmt.Errorf("Unknown capability to add: %q", cap)
   124  		}
   125  
   126  		// add cap if not already in the list
   127  		if !stringutils.InSlice(newCaps, cap) {
   128  			newCaps = append(newCaps, strings.ToUpper(cap))
   129  		}
   130  	}
   131  
   132  	return newCaps, nil
   133  }