github.com/rumpl/bof@v23.0.0-rc.2+incompatible/builder/dockerfile/internals_windows.go (about) 1 package dockerfile // import "github.com/docker/docker/builder/dockerfile" 2 3 import ( 4 "bytes" 5 "os" 6 "path/filepath" 7 "strings" 8 9 "github.com/containerd/containerd/platforms" 10 "github.com/docker/docker/api/types/container" 11 "github.com/docker/docker/api/types/mount" 12 "github.com/docker/docker/pkg/idtools" 13 "github.com/docker/docker/pkg/jsonmessage" 14 "golang.org/x/sys/windows" 15 ) 16 17 func parseChownFlag(builder *Builder, state *dispatchState, chown, ctrRootPath string, identityMapping idtools.IdentityMapping) (idtools.Identity, error) { 18 if builder.options.Platform == "windows" { 19 return getAccountIdentity(builder, chown, ctrRootPath, state) 20 } 21 22 return identityMapping.RootPair(), nil 23 } 24 25 func getAccountIdentity(builder *Builder, accountName string, ctrRootPath string, state *dispatchState) (idtools.Identity, error) { 26 // If this is potentially a string SID then attempt to convert it to verify 27 // this, otherwise continue looking for the account. 28 if strings.HasPrefix(accountName, "S-") || strings.HasPrefix(accountName, "s-") { 29 sid, err := windows.StringToSid(accountName) 30 31 if err == nil { 32 return idtools.Identity{SID: sid.String()}, nil 33 } 34 } 35 36 // Attempt to obtain the SID using the name. 37 sid, _, accType, err := windows.LookupSID("", accountName) 38 39 // If this is a SID that is built-in and hence the same across all systems then use that. 40 if err == nil && (accType == windows.SidTypeAlias || accType == windows.SidTypeWellKnownGroup) { 41 return idtools.Identity{SID: sid.String()}, nil 42 } 43 44 // Check if the account name is one unique to containers. 45 if strings.EqualFold(accountName, "ContainerAdministrator") { 46 return idtools.Identity{SID: idtools.ContainerAdministratorSidString}, nil 47 48 } else if strings.EqualFold(accountName, "ContainerUser") { 49 return idtools.Identity{SID: idtools.ContainerUserSidString}, nil 50 } 51 52 // All other lookups failed, so therefore determine if the account in 53 // question exists in the container and if so, obtain its SID. 54 return lookupNTAccount(builder, accountName, state) 55 } 56 57 func lookupNTAccount(builder *Builder, accountName string, state *dispatchState) (idtools.Identity, error) { 58 59 source, _ := filepath.Split(os.Args[0]) 60 61 target := "C:\\Docker" 62 targetExecutable := target + "\\containerutility.exe" 63 64 optionsPlatform, err := platforms.Parse(builder.options.Platform) 65 if err != nil { 66 return idtools.Identity{}, err 67 } 68 69 runConfig := copyRunConfig(state.runConfig, 70 withCmdCommentString("internal run to obtain NT account information.", optionsPlatform.OS)) 71 72 runConfig.Cmd = []string{targetExecutable, "getaccountsid", accountName} 73 74 hostConfig := &container.HostConfig{Mounts: []mount.Mount{ 75 { 76 Type: mount.TypeBind, 77 Source: source, 78 Target: target, 79 ReadOnly: true, 80 }, 81 }, 82 } 83 84 container, err := builder.containerManager.Create(runConfig, hostConfig) 85 if err != nil { 86 return idtools.Identity{}, err 87 } 88 89 stdout := new(bytes.Buffer) 90 stderr := new(bytes.Buffer) 91 92 if err := builder.containerManager.Run(builder.clientCtx, container.ID, stdout, stderr); err != nil { 93 if err, ok := err.(*statusCodeError); ok { 94 return idtools.Identity{}, &jsonmessage.JSONError{ 95 Message: stderr.String(), 96 Code: err.StatusCode(), 97 } 98 } 99 return idtools.Identity{}, err 100 } 101 102 accountSid := stdout.String() 103 104 return idtools.Identity{SID: accountSid}, nil 105 }