mirror of
https://github.com/containers/podman.git
synced 2025-05-21 17:16:22 +08:00
Merge pull request #12664 from cdoern/noManagePasswd
Podman run --passwd
This commit is contained in:
@ -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 {
|
||||||
|
@ -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).
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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.
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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")))
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
Reference in New Issue
Block a user