Skip to content

Set does not support negating a node in /etc/sudoers #81

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
robertlich opened this issue Jun 28, 2024 · 3 comments
Open

Set does not support negating a node in /etc/sudoers #81

robertlich opened this issue Jun 28, 2024 · 3 comments
Labels
bug Something isn't working

Comments

@robertlich
Copy link

robertlich commented Jun 28, 2024

Describe the Bug

Running this block to configure my sudo_accounts

  augeas { 'sudo_accounts':
    context => '/files/etc/sudoers',
    changes => [
      #Create a command alias for switching a user
      "set Cmnd_Alias/alias/name ELEVATING",
      "set Cmnd_Alias/alias/command[1] /bin/su",
      "set Cmnd_Alias/alias/command[2] /bin/usr/su",
      "set spec[user = '%wheel']/user %wheel",
      #Allow the wheel group to run all commands without a password, excepting the ELEVATING commands
      "set spec[user = '%wheel']/host_group/host ALL",
      "set spec[user = '%wheel']/host_group/command[1] ALL",
      "set spec[user = '%wheel']/host_group/command[1]/runas_user ALL",
      "set spec[user = '%wheel']/host_group/command[1]/tag NOPASSWD",
      "set spec[user = '%wheel']/host_group/command[2] ELEVATING",
      **"set spec[user = '%wheel']/host_group/command[2]/negate"],**
      "clear spec[user = '%wheel']/host_group/command[2]/negate"],
    onlyif => "match spec/user[.='%wheel'][../host_group/command/tag='NOPASSWD'] size == 0",
  }

Results in an error that I am missing the second argument for set.

Expected Behavior

Using the same augtool executable to run:

set /files/etc/sudoers/spec[3]/host_group/command/negate

Will result in the command on that line being negated.

In this particular example it turns:

%wheel ALL=(ALL) NOPASSWD : ALL , ELEVATING
=>
%wheel ALL=(ALL) NOPASSWD : ALL , !ELEVATING

Notably if I were to try to just use:

"set spec[user = '%wheel']/host_group/command[2] !ELEVATING",

in the puppet code above, that also fails. So I'm left with no options for set to negate a command in the sudoers file, which doesn't match the actual behaviour of augtool.

I am able to get around this by using:

"clear spec[user = '%wheel']/host_group/command[2]/negate"

But that's a little unintuitive.

Steps to Reproduce

I have provided the steps to reproduce as part of the above.

Environment

  • Puppet v7.30.0
  • augtool 1.14.1
  • Rocky 8.9
  • having a hard time determining what version of puppetlabs-augeas_core is in this version of puppet
@robertlich robertlich added the bug Something isn't working label Jun 28, 2024
@AriaXLi
Copy link
Contributor

AriaXLi commented Oct 29, 2024

@robertlich Thank you for filing this issue. Is it possible you're running with system augtool and perhaps it is using a different set of lenses than we ship in puppet-agent?

@robertlich
Copy link
Author

@robertlich Thank you for filing this issue. Is it possible you're running with system augtool and perhaps it is using a different set of lenses than we ship in puppet-agent?

I don't _ think _ so, we don't have augtool installed elsewhere on the system that I could find.

@joshcooper
Copy link
Contributor

We were able to reproduce this using puppet-agent 8.11.0 and the above manifest. The augeas provider rejects set commands that don't specify a value https://github.com/puppetlabs/puppetlabs-augeas_core/blob/0f3c5c9aaa7bd7d6a7643edaef77cc62bc84cdd3/lib/puppet/provider/augeas/augeas.rb#L141C1-L141C11

It seems possible to special case negate for the set command

- raise(_('missing string argument %{narg} for %{cmd}') % { narg: narg, cmd: cmd }) unless argline[-1]
+ if !argline[-1] && cmd == 'set' && line.end_with?('/negate')
+   Puppet.debug(_('negating %{arg}') % {arg: args.last[-1]})
+ elsif !argline[-1]
+   raise(_('missing string argument %{narg} for %{cmd}') % { narg: narg, cmd: cmd })
+ end
[root@5bcff36555f0 ~]# rm -f /etc/sudoers 
[root@5bcff36555f0 ~]# cat manifest.pp 
augeas { 'sudo_accounts':
  context => '/files/etc/sudoers',
  changes => [
    #Create a command alias for switching a user
    "set Cmnd_Alias/alias/name ELEVATING",
    "set Cmnd_Alias/alias/command[1] /bin/su",
    "set Cmnd_Alias/alias/command[2] /bin/usr/su",
    "set spec[user = '%wheel']/user %wheel",
    #Allow the wheel group to run all commands without a password, excepting the ELEVATING commands
    "set spec[user = '%wheel']/host_group/host ALL",
    "set spec[user = '%wheel']/host_group/command[1] ALL",
    "set spec[user = '%wheel']/host_group/command[1]/runas_user ALL",
    "set spec[user = '%wheel']/host_group/command[1]/tag NOPASSWD",
    "set spec[user = '%wheel']/host_group/command[2] ELEVATING",
    "set spec[user = '%wheel']/host_group/command[2]/negate"
  ],
  onlyif => "match spec/user[.='%wheel'][../host_group/command/tag='NOPASSWD'] size == 0",
}
[root@5bcff36555f0 ~]# puppet apply manifest.pp 
Notice: Compiled catalog for 5bcff36555f0 in environment production in 0.04 seconds
Notice: /Stage[main]/Main/Augeas[sudo_accounts]/returns: executed successfully
Notice: Applied catalog in 0.30 seconds
[root@5bcff36555f0 ~]# cat /etc/sudoers 
Cmnd_Alias ELEVATING = /bin/su , /bin/usr/su
%wheel ALL = (ALL) NOPASSWD : ALL , !ELEVATING

However, puppet doesn't correct cases where only ! is missing

[root@5bcff36555f0 ~]# cat /etc/sudoers 
Cmnd_Alias ELEVATING = /bin/su , /bin/usr/su
%wheel ALL = (ALL) NOPASSWD : ALL , ELEVATING
[root@5bcff36555f0 ~]# puppet apply manifest.pp 
Notice: Compiled catalog for 5bcff36555f0 in environment production in 0.02 seconds
Notice: Applied catalog in 0.28 seconds

Also can negate be used in other places besides set?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants