Merge pull request #12664 from cdoern/noManagePasswd

Podman run --passwd
This commit is contained in:
OpenShift Merge Robot
2021-12-22 12:09:56 +01:00
committed by GitHub
14 changed files with 70 additions and 16 deletions

View File

@ -83,6 +83,9 @@ func runFlags(cmd *cobra.Command) {
_ = cmd.RegisterFlagCompletionFunc(gpuFlagName, completion.AutocompleteNone) _ = cmd.RegisterFlagCompletionFunc(gpuFlagName, completion.AutocompleteNone)
_ = flags.MarkHidden("gpus") _ = flags.MarkHidden("gpus")
passwdFlagName := "passwd"
flags.BoolVar(&runOpts.Passwd, passwdFlagName, true, "add entries to /etc/passwd and /etc/group")
if registry.IsRemote() { if registry.IsRemote() {
_ = flags.MarkHidden("preserve-fds") _ = flags.MarkHidden("preserve-fds")
_ = flags.MarkHidden("conmon-pidfile") _ = flags.MarkHidden("conmon-pidfile")
@ -191,6 +194,7 @@ func run(cmd *cobra.Command, args []string) error {
return err return err
} }
s.RawImageName = rawImageName s.RawImageName = rawImageName
s.Passwd = &runOpts.Passwd
runOpts.Spec = s runOpts.Spec = s
if _, err := createPodIfNecessary(cmd, s, cliVals.Net); err != nil { if _, err := createPodIfNecessary(cmd, s, cliVals.Net); err != nil {

View File

@ -762,6 +762,11 @@ Tune the host's OOM preferences for containers (accepts values from **-1000** to
#### **--os**=*OS* #### **--os**=*OS*
Override the OS, defaults to hosts, of the image to be pulled. For example, `windows`. Override the OS, defaults to hosts, of the image to be pulled. For example, `windows`.
#### **--passwd**
Allow Podman to add entries to /etc/passwd and /etc/group when used in conjunction with the --user option.
This is used to override the Podman provided user setup in favor of entrypoint configurations such as libnss-extrausers.
#### **--personality**=*persona* #### **--personality**=*persona*
Personality sets the execution domain via Linux personality(2). Personality sets the execution domain via Linux personality(2).

View File

@ -163,6 +163,8 @@ type ContainerRootFSConfig struct {
// Volatile specifies whether the container storage can be optimized // Volatile specifies whether the container storage can be optimized
// at the cost of not syncing all the dirty files in memory. // at the cost of not syncing all the dirty files in memory.
Volatile bool `json:"volatile,omitempty"` Volatile bool `json:"volatile,omitempty"`
// Passwd allows to user to override podman's passwd/group file setup
Passwd *bool `json:"passwd,omitempty"`
} }
// ContainerSecurityConfig is an embedded sub-config providing security configuration // ContainerSecurityConfig is an embedded sub-config providing security configuration

View File

@ -377,6 +377,8 @@ func (c *Container) generateInspectContainerConfig(spec *spec.Spec) *define.Insp
ctrConfig.Umask = c.config.Umask ctrConfig.Umask = c.config.Umask
} }
ctrConfig.Passwd = c.config.Passwd
return ctrConfig return ctrConfig
} }

View File

@ -1767,21 +1767,23 @@ func (c *Container) makeBindMounts() error {
// SHM is always added when we mount the container // SHM is always added when we mount the container
c.state.BindMounts["/dev/shm"] = c.config.ShmDir c.state.BindMounts["/dev/shm"] = c.config.ShmDir
newPasswd, newGroup, err := c.generatePasswdAndGroup() if c.config.Passwd != nil && *c.config.Passwd {
if err != nil { newPasswd, newGroup, err := c.generatePasswdAndGroup()
return errors.Wrapf(err, "error creating temporary passwd file for container %s", c.ID()) if err != nil {
} return errors.Wrapf(err, "error creating temporary passwd file for container %s", c.ID())
if newPasswd != "" { }
// Make /etc/passwd if newPasswd != "" {
// If it already exists, delete so we can recreate // Make /etc/passwd
delete(c.state.BindMounts, "/etc/passwd") // If it already exists, delete so we can recreate
c.state.BindMounts["/etc/passwd"] = newPasswd delete(c.state.BindMounts, "/etc/passwd")
} c.state.BindMounts["/etc/passwd"] = newPasswd
if newGroup != "" { }
// Make /etc/group if newGroup != "" {
// If it already exists, delete so we can recreate // Make /etc/group
delete(c.state.BindMounts, "/etc/group") // If it already exists, delete so we can recreate
c.state.BindMounts["/etc/group"] = newGroup delete(c.state.BindMounts, "/etc/group")
c.state.BindMounts["/etc/group"] = newGroup
}
} }
// Make /etc/hostname // Make /etc/hostname

View File

@ -68,6 +68,8 @@ type InspectContainerConfig struct {
Timeout uint `json:"Timeout"` Timeout uint `json:"Timeout"`
// StopTimeout is time before container is stopped when calling stop // StopTimeout is time before container is stopped when calling stop
StopTimeout uint `json:"StopTimeout"` StopTimeout uint `json:"StopTimeout"`
// Passwd determines whether or not podman can add entries to /etc/passwd and /etc/group
Passwd *bool `json:"Passwd,omitempty"`
} }
// InspectRestartPolicy holds information about the container's restart policy. // InspectRestartPolicy holds information about the container's restart policy.

View File

@ -1794,6 +1794,17 @@ func WithHostDevice(dev []specs.LinuxDevice) CtrCreateOption {
} }
} }
// WithSelectedPasswordManagement makes it so that the container either does or does not setup /etc/passwd or /etc/group
func WithSelectedPasswordManagement(passwd *bool) CtrCreateOption {
return func(c *Container) error {
if c.valid {
return define.ErrCtrFinalized
}
c.config.Passwd = passwd
return nil
}
}
// Pod Creation Options // Pod Creation Options
// WithPodCreateCommand adds the full command plus arguments of the current // WithPodCreateCommand adds the full command plus arguments of the current

View File

@ -19,11 +19,15 @@ import (
func CreateContainer(w http.ResponseWriter, r *http.Request) { func CreateContainer(w http.ResponseWriter, r *http.Request) {
runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime) runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
var sg specgen.SpecGenerator var sg specgen.SpecGenerator
if err := json.NewDecoder(r.Body).Decode(&sg); err != nil { if err := json.NewDecoder(r.Body).Decode(&sg); err != nil {
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "Decode()")) utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "Decode()"))
return return
} }
if sg.Passwd == nil {
t := true
sg.Passwd = &t
}
warn, err := generate.CompleteSpec(r.Context(), runtime, &sg) warn, err := generate.CompleteSpec(r.Context(), runtime, &sg)
if err != nil { if err != nil {
utils.InternalServerError(w, err) utils.InternalServerError(w, err)

View File

@ -341,6 +341,7 @@ type ContainerRunOptions struct {
Rm bool Rm bool
SigProxy bool SigProxy bool
Spec *specgen.SpecGenerator Spec *specgen.SpecGenerator
Passwd bool
} }
// ContainerRunReport describes the results of running // ContainerRunReport describes the results of running

View File

@ -927,6 +927,7 @@ func (ic *ContainerEngine) ContainerRun(ctx context.Context, opts entities.Conta
for _, w := range warn { for _, w := range warn {
fmt.Fprintf(os.Stderr, "%s\n", w) fmt.Fprintf(os.Stderr, "%s\n", w)
} }
rtSpec, spec, optsN, err := generate.MakeContainer(ctx, ic.Libpod, opts.Spec) rtSpec, spec, optsN, err := generate.MakeContainer(ctx, ic.Libpod, opts.Spec)
if err != nil { if err != nil {
return nil, err return nil, err

View File

@ -489,5 +489,8 @@ func createContainerOptions(ctx context.Context, rt *libpod.Runtime, s *specgen.
if s.PidFile != "" { if s.PidFile != "" {
options = append(options, libpod.WithPidFile(s.PidFile)) options = append(options, libpod.WithPidFile(s.PidFile))
} }
options = append(options, libpod.WithSelectedPasswordManagement(s.Passwd))
return options, nil return options, nil
} }

View File

@ -201,6 +201,8 @@ type ContainerBasicConfig struct {
// UnsetEnvAll unsets all default environment variables from the image or from buildin // UnsetEnvAll unsets all default environment variables from the image or from buildin
// Optional. // Optional.
UnsetEnvAll bool `json:"unsetenvall,omitempty"` UnsetEnvAll bool `json:"unsetenvall,omitempty"`
// Passwd is a container run option that determines if we are validating users/groups before running the container
Passwd *bool `json:"manage_password,omitempty"`
} }
// ContainerStorageConfig contains information on the storage configuration of a // ContainerStorageConfig contains information on the storage configuration of a

View File

@ -698,6 +698,9 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *entities.ContainerCreateOptions
// Initcontainers // Initcontainers
s.InitContainerType = c.InitContainerType s.InitContainerType = c.InitContainerType
t := true
s.Passwd = &t
return nil return nil
} }

View File

@ -125,4 +125,16 @@ USER 1000`, ALPINE)
Expect(session).Should(Exit(0)) Expect(session).Should(Exit(0))
Expect(session.OutputToString()).To(Not(ContainSubstring("/etc/group"))) Expect(session.OutputToString()).To(Not(ContainSubstring("/etc/group")))
}) })
It("podman run --no-manage-passwd flag", func() {
run := podmanTest.Podman([]string{"run", "--user", "1234:1234", ALPINE, "cat", "/etc/passwd"})
run.WaitWithDefaultTimeout()
Expect(run).Should(Exit(0))
Expect(run.OutputToString()).To(ContainSubstring("1234:1234"))
run = podmanTest.Podman([]string{"run", "--passwd=false", "--user", "1234:1234", ALPINE, "cat", "/etc/passwd"})
run.WaitWithDefaultTimeout()
Expect(run).Should(Exit(0))
Expect(run.OutputToString()).NotTo((ContainSubstring("1234:1234")))
})
}) })