Pluggable Authentication Module configuration

This module provides parsing for PAM configuration files. PamConf is a parser for /etc/pam.conf files. Sample input is provided in the examples.

PamConf - file /etc/pam.conf

Sample file data:

#%PAM-1.0
vsftpd      auth        required    pam_securetty.so
vsftpd      auth        requisite   pam_unix.so nullok
vsftpd      auth        sufficient  pam_nologin.so
vsftpd      account     optional    pam_unix.so
other       password    include     pam_cracklib.so retry=3 logging=verbose
other       password    required    pam_unix.so shadow nullok use_authtok
other       session     required    pam_unix.so

Examples

>>> type(pam_conf)
<class 'insights.parsers.pam.PamConf'>
>>> len(pam_conf)
7
>>> pam_conf[0].service
'vsftpd'
>>> pam_conf[0].interface
'auth'
>>> pam_conf[0].control_flags
[ControlFlag(flag='required', value=None)]
>>> pam_conf[0].module_name
'pam_securetty.so'
>>> pam_conf[0].module_args is None
True
>>> pam_conf.file_path
'/etc/pam.conf'

PamDConf - used for specific PAM configuration files

PamDConf is a base class for the creation of parsers for /etc/pam.d service specific configuration files.

Sample file from /etc/pam.d/sshd:

#%PAM-1.0
auth       required     pam_sepermit.so
auth       substack     password-auth
auth       include      postlogin
# Used with polkit to reauthorize users in remote sessions
-auth      optional     pam_reauthorize.so prepare
account    required     pam_nologin.so
account    include      password-auth
password   include      password-auth
# pam_selinux.so close should be the first session rule
session    required     pam_selinux.so close
session    required     pam_loginuid.so
# pam_selinux.so open should only be followed by sessions to be executed in the user context
session    required     pam_selinux.so open env_params
session    required     pam_namespace.so
session    optional     pam_keyinit.so force revoke
session    include      password-auth
session    include      postlogin
# Used with polkit to reauthorize users in remote sessions
-session   optional     pam_reauthorize.so prepare

Examples

>>> type(pamd_conf)
<class 'insights.parsers.pam.PamDConf'>
>>> len(pamd_conf)
15
>>> pamd_conf[0]._errors == [] # No errors in parsing
True
>>> pamd_conf[0].service
'sshd'
>>> pamd_conf[0].interface
'auth'
>>> pamd_conf[0].control_flags
[ControlFlag(flag='required', value=None)]
>>> pamd_conf[0].module_name
'pam_sepermit.so'
>>> pamd_conf[0].module_args is None
True
>>> pamd_conf.file_path
'/etc/pam.d/sshd'
>>> pamd_conf[3].module_name
'pam_reauthorize.so'
>>> pamd_conf[3].ignored_if_module_not_found
True

Normal use of the PamDConf class is to subclass it for a parser. In insights/specs/default.py:

pam_sshd = simple_file("etc/pam.d/sshd")

In the parser module (e.g. insights/parsers/pam_sshd.py):

from insights import parser
from insights.parsers.pam import PamDConf
from insights.specs import Specs

@parser(Specs.pam_sshd)
class PamSSHD(PamDConf):
    pass

References

http://www.linux-pam.org/Linux-PAM-html/Linux-PAM_SAG.html

class insights.parsers.pam.PamConf(context)[source]

Bases: PamDConf

Base class for parsing pam config file /etc/pam.conf.

Based on the PamDConf parser class, but the service must be given as the first element of the line, rather than assumed from the file name.

parse_content(content)[source]

This method must be implemented by classes based on this class.

class insights.parsers.pam.PamConfEntry(line, pamd_conf=False, service=None)[source]

Bases: object

Contains information from one PAM configuration line.

Parses a single line of either a /etc/pam.conf file or a service specific /etc/pam.d conf file. The difference is that for /etc/pam.conf, the service name is the first column of the input line. If a service specific conf file then the service name is not present in the line and must be provided as the service parameter as well as setting the pamd_conf to True.

Parameters:
  • line (str) -- One line of the pam conf info.

  • pamd_config (boolean) -- If this is set to False then line will be parsed as a line from the etc/pam.conf file, if True then the line will be parsed as a line from a service specific etc/pam.d/ conf file. Default is True.

  • service (str) -- If pamd_conf is True then the name of the service file must be provided since it is not present in line.

service

The service name (taken from the line or from the file name if not parsing pam.conf)

Type:

str

interface

The type clause - should be one of 'account', 'auth', 'password' or 'session'.  If the line was invalid this is set to ``None.

Type:

str

ignored_if_module_not_found

If the type clause is preceded by '-', then this is set to True and it indicates that PAM would skip this line rather than reporting an error if the given module is not found.

Type:

bool

control_flags

A list of ControlFlag named tuples. If the control flag was one of 'required', 'requisite', 'sufficient', 'optional', 'include', or 'substack', then this is the only flag in the list and its value is set to True. If the control flag started with [, then the list inside the square brackets is interpreted as a list of key=value tuples.

Type:

list

_control_raw

the raw control flag string before parsing, for reference.

Type:

str

module_name

the PAM module name (including the ‘.so’)

Type:

str

module_args

the PAM module arguments, if any. This is not parsed.

Type:

str

_full_line

The original line in the PAM configuration.

Type:

str

_errors

A list of parsing errors detected in this line.

Type:

list

Examples

>>> pam_conf_line = 'vsftpd      auth        requisite   pam_unix.so nullok'
>>> entry = PamConfEntry(pam_conf_line)
>>> entry.service
'vsftpd'
>>> entry.control_flags[0].flag
'requisite'
>>> entry.module_args
'nullok'
>>> pamd_conf_line = '''
... auth        [success=2 default=ok]  pam_debug.so auth=perm_denied cred=success
... '''.strip()
>>> entry = PamConfEntry(pamd_conf_line, pamd_conf=True, service='vsftpd')
>>> entry.service
'vsftpd'
>>> entry.control_flags
[ControlFlag(flag='success', value='2'), ControlFlag(flag='default', value='ok')]
>>> entry.module_args
'auth=perm_denied cred=success'
Raises:

ValueError -- If pamd_conf is True and service name is not provided, or if the line doesn’t contain any module information.

ControlFlag

A named tuple with the ‘flag’ and ‘value’ properties, used to store information about the control flags in a PAM configuration line.

class ControlFlag(flag, value)

Bases: tuple

flag
value
class insights.parsers.pam.PamDConf(context)[source]

Bases: Parser

Base class for parsing files in /etc/pam.d

Derive from this class for parsers of files in the /etc/pam.d directory. Parses each line of the conf file into a list of PamConfEntry. Configuration file format is:

module_interface    control_flag    module_name module_arguments
Sample input::
>>> pam_sshd = '''
... auth        required    pam_securetty.so
... auth        requisite   pam_unix.so nullok
... auth        sufficient  pam_nologin.so
... auth        [success=2 default=ok]  pam_debug.so auth=perm_denied cred=success
... account     optional    pam_unix.so
... password    include     pam_cracklib.so retry=3 logging=verbose
... password    required    pam_unix.so shadow nullok use_authtok
... '''
>>> from insights.tests import context_wrap
>>> class YourPamDConf(PamDConf):  # A trivial example
...     pass
>>> conf = YourPamDConf(context_wrap(pam_sshd, path='/etc/pam.d/sshd'))

The service property of each PamConfEntry is set to the complete path name of the PAM config file.

data

List containing a PamConfEntry object for each line of the conf file in the same order as lines appear in the file.

Type:

list

Examples

>>> conf[0].module_name  # Can be used like a list of objects
'pam_securetty.so'
>>> account_rows = list(conf.search(interface='account'))
>>> len(account_rows)
1
>>> account_rows[0].interface
'account'
>>> account_rows[0].module_name
'pam_unix.so'
>>> account_rows[0].control_flags
[ControlFlag(flag='optional', value=None)]
parse_content(content)[source]

This method must be implemented by classes based on this class.

search(**kwargs)[source]

Search the pam.d configuration file by keyword. This is provided by the insights.parsers.keyword_search() function - see its documentation for more information.

Searching on the list of PAM configuration entries is exactly like they were dictionaries instead of objects with properties. In addition, the ‘control_flags’ property becomes a dictionary of keywords and values, so that ‘control_flags__contains’ allows searching for a particular control flag.

Returns:

A list of PamConfEntry objects that match the given search criteria.

Return type:

(list)