123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105 |
- package dockerfile // import "github.com/docker/docker/builder/dockerfile"
- import (
- "bytes"
- "context"
- "os"
- "path/filepath"
- "strings"
- "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"
- "golang.org/x/sys/windows"
- )
- func parseChownFlag(ctx context.Context, builder *Builder, state *dispatchState, chown, ctrRootPath string, identityMapping idtools.IdentityMapping) (idtools.Identity, error) {
- if builder.options.Platform == "windows" {
- return getAccountIdentity(ctx, builder, chown, ctrRootPath, state)
- }
- return identityMapping.RootPair(), nil
- }
- func getAccountIdentity(ctx context.Context, 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 {
- return idtools.Identity{SID: sid.String()}, 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) {
- return idtools.Identity{SID: sid.String()}, nil
- }
- // Check if the account name is one unique to containers.
- if strings.EqualFold(accountName, "ContainerAdministrator") {
- return idtools.Identity{SID: idtools.ContainerAdministratorSidString}, nil
- } else if strings.EqualFold(accountName, "ContainerUser") {
- return idtools.Identity{SID: idtools.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(ctx, builder, accountName, state)
- }
- func lookupNTAccount(ctx context.Context, 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(ctx, runConfig, hostConfig)
- if err != nil {
- return idtools.Identity{}, err
- }
- stdout := new(bytes.Buffer)
- stderr := new(bytes.Buffer)
- if err := builder.containerManager.Run(ctx, 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
- }
|