2018-02-05 16:05:59 -05:00
|
|
|
package dockerfile // import "github.com/docker/docker/builder/dockerfile"
|
2018-01-12 20:57:50 -05:00
|
|
|
|
2017-11-16 01:20:33 -05:00
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"os"
|
|
|
|
"path/filepath"
|
|
|
|
"strings"
|
2018-01-12 20:57:50 -05:00
|
|
|
|
2017-11-16 01:20:33 -05:00
|
|
|
"github.com/containerd/containerd/platforms"
|
|
|
|
"github.com/docker/docker/api/types/container"
|
|
|
|
"github.com/docker/docker/api/types/mount"
|
|
|
|
"github.com/docker/docker/pkg/idtools"
|
|
|
|
"github.com/docker/docker/pkg/jsonmessage"
|
|
|
|
"github.com/docker/docker/pkg/system"
|
|
|
|
"github.com/pkg/errors"
|
|
|
|
"golang.org/x/sys/windows"
|
|
|
|
)
|
|
|
|
|
|
|
|
func parseChownFlag(builder *Builder, state *dispatchState, chown, ctrRootPath string, identityMapping *idtools.IdentityMapping) (idtools.Identity, error) {
|
|
|
|
if builder.options.Platform == "windows" {
|
|
|
|
return getAccountIdentity(builder, chown, ctrRootPath, state)
|
|
|
|
}
|
|
|
|
|
|
|
|
return identityMapping.RootPair(), nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func getAccountIdentity(builder *Builder, accountName string, ctrRootPath string, state *dispatchState) (idtools.Identity, error) {
|
|
|
|
// If this is potentially a string SID then attempt to convert it to verify
|
|
|
|
// this, otherwise continue looking for the account.
|
|
|
|
if strings.HasPrefix(accountName, "S-") || strings.HasPrefix(accountName, "s-") {
|
|
|
|
sid, err := windows.StringToSid(accountName)
|
|
|
|
|
|
|
|
if err == nil {
|
|
|
|
accountSid, err := sid.String()
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return idtools.Identity{SID: ""}, errors.Wrapf(err, "error converting SID to string")
|
|
|
|
}
|
|
|
|
|
|
|
|
return idtools.Identity{SID: accountSid}, nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Attempt to obtain the SID using the name.
|
|
|
|
sid, _, accType, err := windows.LookupSID("", accountName)
|
|
|
|
|
|
|
|
// If this is a SID that is built-in and hence the same across all systems then use that.
|
|
|
|
if err == nil && (accType == windows.SidTypeAlias || accType == windows.SidTypeWellKnownGroup) {
|
|
|
|
accountSid, err := sid.String()
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return idtools.Identity{SID: ""}, errors.Wrapf(err, "error converting SID to string")
|
|
|
|
}
|
|
|
|
|
|
|
|
return idtools.Identity{SID: accountSid}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check if the account name is one unique to containers.
|
|
|
|
if strings.EqualFold(accountName, "ContainerAdministrator") {
|
|
|
|
return idtools.Identity{SID: system.ContainerAdministratorSidString}, nil
|
|
|
|
|
|
|
|
} else if strings.EqualFold(accountName, "ContainerUser") {
|
|
|
|
return idtools.Identity{SID: system.ContainerUserSidString}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// All other lookups failed, so therefore determine if the account in
|
|
|
|
// question exists in the container and if so, obtain its SID.
|
|
|
|
return lookupNTAccount(builder, accountName, state)
|
|
|
|
}
|
|
|
|
|
|
|
|
func lookupNTAccount(builder *Builder, accountName string, state *dispatchState) (idtools.Identity, error) {
|
|
|
|
|
|
|
|
source, _ := filepath.Split(os.Args[0])
|
|
|
|
|
|
|
|
target := "C:\\Docker"
|
|
|
|
targetExecutable := target + "\\containerutility.exe"
|
|
|
|
|
|
|
|
optionsPlatform, err := platforms.Parse(builder.options.Platform)
|
|
|
|
if err != nil {
|
|
|
|
return idtools.Identity{}, err
|
|
|
|
}
|
|
|
|
|
|
|
|
runConfig := copyRunConfig(state.runConfig,
|
|
|
|
withCmdCommentString("internal run to obtain NT account information.", optionsPlatform.OS))
|
|
|
|
|
|
|
|
runConfig.Cmd = []string{targetExecutable, "getaccountsid", accountName}
|
|
|
|
|
|
|
|
hostConfig := &container.HostConfig{Mounts: []mount.Mount{
|
|
|
|
{
|
|
|
|
Type: mount.TypeBind,
|
|
|
|
Source: source,
|
|
|
|
Target: target,
|
|
|
|
ReadOnly: true,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
container, err := builder.containerManager.Create(runConfig, hostConfig)
|
|
|
|
if err != nil {
|
|
|
|
return idtools.Identity{}, err
|
|
|
|
}
|
|
|
|
|
|
|
|
stdout := new(bytes.Buffer)
|
|
|
|
stderr := new(bytes.Buffer)
|
|
|
|
|
|
|
|
if err := builder.containerManager.Run(builder.clientCtx, container.ID, stdout, stderr); err != nil {
|
|
|
|
if err, ok := err.(*statusCodeError); ok {
|
|
|
|
return idtools.Identity{}, &jsonmessage.JSONError{
|
|
|
|
Message: stderr.String(),
|
|
|
|
Code: err.StatusCode(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return idtools.Identity{}, err
|
|
|
|
}
|
|
|
|
|
|
|
|
accountSid := stdout.String()
|
|
|
|
|
|
|
|
return idtools.Identity{SID: accountSid}, nil
|
2018-01-12 20:57:50 -05:00
|
|
|
}
|