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