Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add of pam type/provider with doc and unit tests
- Loading branch information
Showing
8 changed files
with
538 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
## pam provider | ||
|
||
This is a custom type and provider supplied by `augeasproviders`. | ||
|
||
### manage simple entry | ||
|
||
pam { "Set sss entry to system-auth auth": | ||
ensure => present, | ||
service => 'system-auth', | ||
type => 'auth', | ||
control => 'sufficient', | ||
module => 'pam_sss.so', | ||
arguments => 'use_first_pass', | ||
position => 'before module pam_deny.so', | ||
} | ||
|
||
### manage same entry but with Augeas xpath | ||
|
||
pam { "Set sss entry to system-auth auth": | ||
ensure => present, | ||
service => 'system-auth', | ||
type => 'auth', | ||
control => 'sufficient', | ||
module => 'pam_sss.so', | ||
arguments => 'use_first_pass', | ||
position => 'before *[type="auth" and module="pam_deny.so"]', | ||
} | ||
|
||
### delete entry | ||
|
||
pam { "Remove sss auth entry from system-auth": | ||
ensure => absent, | ||
service => 'system-auth', | ||
type => 'auth', | ||
module => 'pam_sss.so', | ||
} | ||
|
||
### delete all references to module in file | ||
|
||
pam { "Remove all pam_sss.so from system-auth": | ||
ensure => absent, | ||
service => 'system-auth', | ||
module => 'pam_sss.so', | ||
} | ||
|
||
### manage entry in another pam service | ||
|
||
pam { "Set cracklib limits in password-auth": | ||
ensure => present, | ||
service => 'password-auth', | ||
type => 'password', | ||
module => 'pam_cracklib.so', | ||
arguments => ['try_first_pass','retry=3', 'minlen=10'], | ||
} | ||
|
||
### manage entry like previous but in classic pam.conf | ||
|
||
pam { "Set cracklib limits in password-auth": | ||
ensure => present, | ||
service => 'password-auth', | ||
type => 'password', | ||
module => 'pam_cracklib.so', | ||
arguments => ['try_first_pass','retry=3', 'minlen=10'], | ||
target => '/etc/pam.conf', | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
# Alternative Augeas-based providers for Puppet | ||
# | ||
# Copyright (c) 2012 Greg Swift | ||
# Licensed under the Apache License, Version 2.0 | ||
|
||
require File.dirname(__FILE__) + '/../../../augeasproviders/provider' | ||
|
||
Puppet::Type.type(:pam).provide(:augeas) do | ||
desc "Uses Augeas API to update an pam parameter" | ||
|
||
include AugeasProviders::Provider | ||
|
||
# Boolean is the key because they either do or do not provide a | ||
# value for control to work against. Module doesn't work against | ||
# control | ||
PAM_POSITION_ALIASES = { | ||
true => { 'first' => "*[type='%s' and control='%s'][1]", | ||
'last' => "*[type='%s' and control='%s'][last()]", | ||
'module' => "*[type='%s' and module='%s'][1]", }, | ||
false => { 'first' => "*[type='%s'][1]", | ||
'last' => "*[type='%s'][last()]", }, | ||
} | ||
|
||
confine :feature => :augeas | ||
|
||
default_file { '/etc/pam.d/system-auth' } | ||
|
||
def target(resource = nil) | ||
if resource and resource[:service] | ||
"/etc/pam.d/#{resource[:service]}".chomp('/') | ||
else | ||
super | ||
end | ||
end | ||
|
||
lens do |resource| | ||
target(resource) == '/etc/pam.conf' ? 'pamconf.lns' : 'pam.lns' | ||
end | ||
|
||
resource_path do |resource| | ||
service = resource[:service] | ||
type = resource[:type] | ||
mod = resource[:module] | ||
if target == '/etc/pam.conf' | ||
"$target/*[service='#{service}' and type='#{type}' and module='#{mod}']" | ||
else | ||
"$target/*[type='#{type}' and module='#{mod}']" | ||
end | ||
end | ||
|
||
def self.instances | ||
augopen do |aug| | ||
resources = [] | ||
aug.match("$target/*[label()!='#comment']").each do |spath| | ||
optional = aug.match("#{spath}/optional").empty?.to_s.to_sym | ||
type = aug.get("#{spath}/type") | ||
control = aug.get("#{spath}/control") | ||
mod = aug.get("#{spath}/module") | ||
arguments = aug.match("#{spath}/argument").map { |p| aug.get(p) } | ||
entry = {:ensure => :present, | ||
:optional => optional, | ||
:type => type, | ||
:control => control, | ||
:module => mod, | ||
:arguments => arguments} | ||
if target == '/etc/pam.conf' | ||
entry[:service] = aug.get("#{spath}/service") | ||
end | ||
resources << new(entry) | ||
end | ||
resources | ||
end | ||
end | ||
|
||
define_aug_method!(:create) do |aug, resource| | ||
path = '01' | ||
entry_path = "$target/#{path}" | ||
# we pull type, control, and position out because we actually | ||
# work with those values, not just reference them in the set section | ||
# type comes to us as a symbol, so needs to be converted to a string | ||
type = resource[:type].to_s | ||
control = resource[:control] | ||
position = resource[:position] | ||
placement, identifier, value = position.split(/ /) | ||
key = !!value | ||
if PAM_POSITION_ALIASES[key].has_key?(identifier) | ||
expr = PAM_POSITION_ALIASES[key][identifier] | ||
expr = key ? expr % [type, value] : expr % [type] | ||
else | ||
# if the identifier is not in the mapping | ||
# we assume that its an xpath and so | ||
# join everything after the placement | ||
identifier = position.split(/ /)[1..-1].join(" ") | ||
expr = identifier | ||
end | ||
aug.insert("$target/#{expr}", path, placement == 'before') | ||
if resource[:optional] == :true | ||
aug.touch("#{entry_path}/optional") | ||
end | ||
if target == '/etc/pam.conf' | ||
aug.set("#{entry_path}/service", resource[:service]) | ||
end | ||
aug.set("#{entry_path}/type", type) | ||
aug.set("#{entry_path}/control", control) | ||
aug.set("#{entry_path}/module", resource[:module]) | ||
resource[:arguments].each do |argument| | ||
aug.set("#{entry_path}/argument[last()+1]", argument) | ||
end | ||
end | ||
|
||
define_aug_method(:optional) do |aug, resource| | ||
aug.match("$resource/optional").empty?.to_s.to_sym | ||
end | ||
|
||
define_aug_method!(:optional=) do |aug, resource, value| | ||
if resource[:optional] == :true | ||
if aug.match("$resource/optional").empty? | ||
aug.clear("$resource/optional") | ||
end | ||
else | ||
aug.rm("$resource/optional") | ||
end | ||
end | ||
|
||
attr_aug_accessor(:control) | ||
|
||
attr_aug_accessor(:arguments, :type => :array, :label => 'argument') | ||
|
||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
# Manages settings in PAM service files | ||
# | ||
# Copyright (c) 2012 Greg Swift | ||
# Licensed under the Apache License, Version 2.0 | ||
|
||
require File.dirname(__FILE__) + '/../../augeasproviders/type' | ||
|
||
Puppet::Type.newtype(:pam) do | ||
@doc = "Manages settings in an PAM service files. | ||
The resource name is a descriptive string only due to the non-uniqueness of any single paramter." | ||
|
||
extend AugeasProviders::Type | ||
|
||
positionable | ||
|
||
def munge_boolean(value) | ||
case value | ||
when true, "true", :true | ||
:true | ||
when false, "false", :false | ||
:false | ||
else | ||
fail("munge_boolean only takes booleans") | ||
end | ||
end | ||
|
||
newparam(:name) do | ||
desc "The name of the resource, has no bearing on anything" | ||
isnamevar | ||
end | ||
|
||
newparam(:service) do | ||
desc "The PAM service this entry will be placed in. Typically this is the same as the | ||
filename under /etc/pam.d" | ||
end | ||
|
||
newparam(:type) do | ||
desc "The PAM service type of the setting: account, auth, password, session." | ||
newvalues(:account, :auth, :password, :session) | ||
end | ||
|
||
newparam(:module) do | ||
desc "The name of the specific PAM module to load." | ||
end | ||
|
||
newproperty(:optional, :boolean => true) do | ||
desc "Whether failure to load the module will break things" | ||
|
||
newvalue(:true) | ||
newvalue(:false) | ||
|
||
munge do |value| | ||
@resource.munge_boolean(value) | ||
end | ||
end | ||
|
||
newproperty(:arguments, :array_matching => :all) do | ||
desc "Arguments to assign for the module." | ||
end | ||
|
||
newproperty(:control) do | ||
desc "Simple or complex definition of the module's behavior on failure." | ||
end | ||
|
||
newparam(:position) do | ||
desc "A three part text field that providers the placement position of an entry. | ||
The field consists of `placement identifier value` | ||
Placement can be either `before` or `after` | ||
Identifier can be either `first`, `last`, `module`, or an Augeas xpath | ||
Value is matched as follows: | ||
With `first` and `last` match `value` to the `control` field, can be blank for absolute positioning. | ||
With `module` matches the `module` field of the associated line, can not be blank. | ||
With an Augeas xpath this field will be ignored, and should be blank. | ||
" | ||
defaultto('before last') | ||
validate do |value| | ||
placement, identifier, val = value.split(/ /) | ||
unless ['before', 'after'].include? placement | ||
raise ArgumentError, "%s is not a valid placement in position" % placement | ||
end | ||
# Don't do validation of the second field because we are supporting xpath | ||
# and thats hard to validate | ||
# unless ['first', 'last', 'module'].include? identifier or identifier =~ // | ||
# raise ArgumentError, "%s is not a valid identifier in position" % indentifier | ||
# end | ||
if val.nil? and identifier == 'module' | ||
raise ArgumentError, "Value must be set if you are matching on module" | ||
end | ||
end | ||
end | ||
|
||
newparam(:target) do | ||
desc "The file in which to store the settings, defaults to `/etc/pam.d/{service}`." | ||
end | ||
|
||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
#%PAM-1.0 | ||
# This file is auto-generated. | ||
# User changes will be destroyed the next time authconfig is run. | ||
auth | ||
auth sufficient pam_unix.so nullok try_first_pass | ||
auth requisite pam_succeed_if.so uid >= 1000 quiet_success | ||
auth sufficient pam_sss.so use_first_pass | ||
auth required pam_deny.so | ||
|
||
account required pam_unix.so broken_shadow | ||
account sufficient pam_localuser.so | ||
account sufficient pam_succeed_if.so uid < 1000 quiet | ||
account [default=bad success=ok user_unknown=ignore] pam_sss.so | ||
account required pam_permit.so | ||
|
||
password requisite pam_pwquality.so try_first_pass retry=3 type= | ||
password sufficient pam_unix.so sha512 shadow nullok try_first_pass use_authtok | ||
password sufficient pam_sss.so use_authtok | ||
password required pam_deny.so | ||
|
||
session optional pam_keyinit.so revoke | ||
session required pam_limits.so | ||
-session optional pam_systemd.so | ||
session optional pam_mkhomedir.so | ||
session [success=1 default=ignore] pam_succeed_if.so service in crond quiet use_uid | ||
session required pam_unix.so | ||
session optional pam_sss.so |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
#%PAM-1.0 | ||
# This file is auto-generated. | ||
# User changes will be destroyed the next time authconfig is run. | ||
auth required pam_env.so | ||
auth sufficient pam_unix.so nullok try_first_pass | ||
auth requisite pam_succeed_if.so uid >= 1000 quiet_success | ||
auth sufficient pam_sss.so use_first_pass | ||
auth required pam_deny.so | ||
|
||
account required pam_unix.so broken_shadow | ||
account sufficient pam_localuser.so | ||
account sufficient pam_succeed_if.so uid < 1000 quiet | ||
account [default=bad success=ok user_unknown=ignore] pam_sss.so | ||
account required pam_permit.so | ||
|
||
password requisite pam_pwquality.so try_first_pass retry=3 type= | ||
password sufficient pam_unix.so sha512 shadow nullok try_first_pass use_authtok | ||
password sufficient pam_sss.so use_authtok | ||
password required pam_deny.so | ||
|
||
session optional pam_keyinit.so revoke | ||
session required pam_limits.so | ||
-session optional pam_systemd.so | ||
session optional pam_mkhomedir.so | ||
session [success=1 default=ignore] pam_succeed_if.so service in crond quiet use_uid | ||
session required pam_unix.so | ||
session optional pam_sss.so |
Oops, something went wrong.